<commit_before>/* @flow */

import { MailComposer }               from 'mailcomposer'
import { chain }                      from 'ramda'
import randomstring                   from 'randomstring'
import uuid                           from 'uuid'
import moment                         from 'moment'
import { objectContent, parseMidUri } from './activity'

import type { ReadStream }                  from 'fs'
import type { Activity }                    from './activity'
import type { Address, Message, MessageId } from './notmuch'

export type ComposerAttachment = {
  cid:                string,
  contents:           string | Buffer,
  contentDisposition: string,
  contentType:        string,
}

export type Burger = [ActivityId, Activity, ComposerAttachment[]]

export type ActivityId = string

export type Draft = {
  activities:  Burger[],
  from:        Address,
  to:          Address[],
  cc?:         Address[],
  inReplyTo?:  MessageId,
  references?: MessageId[],
  subject?:    string,
  fallback?:   string,
}

export {
  assemble,
}

function assemble({ activities, from, to, cc, inReplyTo, references, subject, fallback }: Draft): ReadStream {
  var comp = new MailComposer()
  comp.setMessageOption({
    from: convertAddress(comp, from),
    to:   to.map(convertAddress.bind(null, comp)).join(', '),
    body: withFooter(fallback || fallbackContent(activities)),
  })
  if (subject) {
    comp.setMessageOption({ subject })
  }
  if (cc) {
    comp.setMessageOption({ cc: cc.map(convertAddress.bind(null, comp)).join(', ') })
  }
  if (inReplyTo) {
    comp.setMessageOption({ inReplyTo })
  }
  if (references) {
    comp.setMessageOption({ references })
  }

  comp.addHeader('Message-ID', `<${uuid.v4()}@${from.address.split('@')[1]}>`)
  comp.addHeader('Date', moment().format('dd, D MMM YYYY HH:mm:ss ZZ'))

  activities.forEach(([activityId, activity, attachments]) => {
    var parsed = parseMidUri(activityId)
    if (!parsed || !parsed.partId) { throw "No part Id for activity" }
    var { partId } = parsed
    comp.addAttachment({
      cid: partId,
      contents: JSON.stringify(activity),
      contentEncoding: 'quoted-printable',
      contentType: 'application/activity+json',
    })
    attachments.forEach(a => comp.addAttachment(a))
  })

  comp.streamMessage()
  return comp
}

// TODO: specific fallback behavior for each verb and object type
function fallbackContent(acts: Burger[]): string {
  var contents  = chain(([_, __, attachments]) => attachments, acts)
  var textParts = contents.filter(c => c.contentType === 'text/plain')
  var text      = textParts.length > 0 ? textParts[0].contents.toString('utf8') : ''
  return text
}

function withFooter(body: string): string {
  return body + "\n\n---\nThis message is best viewed with Poodle <https://github.com/hallettj/poodle>."
}

// It seems that the MailComposer#convertAddress method mutates the input
// object. This wrapper produces a defensive copy.
function convertAddress(comp: MailComposer, addr: Address): string {
  return comp.convertAddress(Object.assign({}, addr))
}
<commit_msg>Fixes error due to missing support for `Object.assign()`<commit_after>/* @flow */

import { MailComposer }               from 'mailcomposer'
import { chain }                      from 'ramda'
import randomstring                   from 'randomstring'
import uuid                           from 'uuid'
import moment                         from 'moment'
import objectAssign                   from 'object-assign'
import { objectContent, parseMidUri } from './activity'

import type { ReadStream }                  from 'fs'
import type { Activity }                    from './activity'
import type { Address, Message, MessageId } from './notmuch'

export type ComposerAttachment = {
  cid:                string,
  contents:           string | Buffer,
  contentDisposition: string,
  contentType:        string,
}

export type Burger = [ActivityId, Activity, ComposerAttachment[]]

export type ActivityId = string

export type Draft = {
  activities:  Burger[],
  from:        Address,
  to:          Address[],
  cc?:         Address[],
  inReplyTo?:  MessageId,
  references?: MessageId[],
  subject?:    string,
  fallback?:   string,
}

export {
  assemble,
}

function assemble({ activities, from, to, cc, inReplyTo, references, subject, fallback }: Draft): ReadStream {
  var comp = new MailComposer()
  comp.setMessageOption({
    from: convertAddress(comp, from),
    to:   to.map(convertAddress.bind(null, comp)).join(', '),
    body: withFooter(fallback || fallbackContent(activities)),
  })
  if (subject) {
    comp.setMessageOption({ subject })
  }
  if (cc) {
    comp.setMessageOption({ cc: cc.map(convertAddress.bind(null, comp)).join(', ') })
  }
  if (inReplyTo) {
    comp.setMessageOption({ inReplyTo })
  }
  if (references) {
    comp.setMessageOption({ references })
  }

  comp.addHeader('Message-ID', `<${uuid.v4()}@${from.address.split('@')[1]}>`)
  comp.addHeader('Date', moment().format('dd, D MMM YYYY HH:mm:ss ZZ'))

  activities.forEach(([activityId, activity, attachments]) => {
    var parsed = parseMidUri(activityId)
    if (!parsed || !parsed.partId) { throw "No part Id for activity" }
    var { partId } = parsed
    comp.addAttachment({
      cid: partId,
      contents: JSON.stringify(activity),
      contentEncoding: 'quoted-printable',
      contentType: 'application/activity+json',
    })
    attachments.forEach(a => comp.addAttachment(a))
  })

  comp.streamMessage()
  return comp
}

// TODO: specific fallback behavior for each verb and object type
function fallbackContent(acts: Burger[]): string {
  var contents  = chain(([_, __, attachments]) => attachments, acts)
  var textParts = contents.filter(c => c.contentType === 'text/plain')
  var text      = textParts.length > 0 ? textParts[0].contents.toString('utf8') : ''
  return text
}

function withFooter(body: string): string {
  return body + "\n\n---\nThis message is best viewed with Poodle <https://github.com/hallettj/poodle>."
}

// It seems that the MailComposer#convertAddress method mutates the input
// object. This wrapper produces a defensive copy.
function convertAddress(comp: MailComposer, addr: Address): string {
  return comp.convertAddress(objectAssign({}, addr))
}
<|endoftext|>


<commit_before>const webglCanvas = document.body.appendChild(document.createElement('canvas'))
const fit = require('canvas-fit')
const regl = require('../regl')({
  canvas: webglCanvas,
  extensions: 'oes_texture_float'
})
const mat4 = require('gl-mat4')
const camera = require('canvas-orbit-camera')(webglCanvas)
window.addEventListener('resize', fit(webglCanvas), false)
const bunny = require('bunny')
const normals = require('angle-normals')

// configure intial camera view.
camera.rotate([0.0, 0.0], [0.0, -0.4])
camera.zoom(50.0)

var lightPos = [0.0, 30.0, 0.0]

const CUBE_MAP_SIZE = 1024
const shadowFbo = regl.framebufferCube({
  radius: CUBE_MAP_SIZE,
  colorFormat: 'rgba',
  colorType: 'float'
})

const planeElements = []
var planePosition = []
var planeNormal = []

planePosition.push([-0.5, 0.0, -0.5])
planePosition.push([+0.5, 0.0, -0.5])
planePosition.push([-0.5, 0.0, +0.5])
planePosition.push([+0.5, 0.0, +0.5])

planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])

planeElements.push([3, 1, 0])
planeElements.push([0, 2, 3])

var boxPosition = [
  // side faces
  [-0.5, +0.5, +0.5], [+0.5, +0.5, +0.5], [+0.5, -0.5, +0.5], [-0.5, -0.5, +0.5], // positive z face.
  [+0.5, +0.5, +0.5], [+0.5, +0.5, -0.5], [+0.5, -0.5, -0.5], [+0.5, -0.5, +0.5], // positive x face
  [+0.5, +0.5, -0.5], [-0.5, +0.5, -0.5], [-0.5, -0.5, -0.5], [+0.5, -0.5, -0.5], // negative z face
  [-0.5, +0.5, -0.5], [-0.5, +0.5, +0.5], [-0.5, -0.5, +0.5], [-0.5, -0.5, -0.5], // negative x face.
  [-0.5, +0.5, -0.5], [+0.5, +0.5, -0.5], [+0.5, +0.5, +0.5], [-0.5, +0.5, +0.5],  // top face
  [-0.5, -0.5, -0.5], [+0.5, -0.5, -0.5], [+0.5, -0.5, +0.5], [-0.5, -0.5, +0.5]  // bottom face
]

const boxElements = [
  [2, 1, 0], [2, 0, 3],
  [6, 5, 4], [6, 4, 7],
  [10, 9, 8], [10, 8, 11],
  [14, 13, 12], [14, 12, 15],
  [18, 17, 16], [18, 16, 19],
  [20, 21, 22], [23, 20, 22]
]

// all the normals of a single block.
var boxNormal = [
  // side faces
  [0.0, 0.0, +1.0], [0.0, 0.0, +1.0], [0.0, 0.0, +1.0], [0.0, 0.0, +1.0],
  [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0],
  [0.0, 0.0, -1.0], [0.0, 0.0, -1.0], [0.0, 0.0, -1.0], [0.0, 0.0, -1.0],
  [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0],
  // top
  [0.0, +1.0, 0.0], [0.0, +1.0, 0.0], [0.0, +1.0, 0.0], [0.0, +1.0, 0.0],
  // bottom
  [0.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, -1.0, 0.0]
]

// This call encapsulates the common state between `drawNormal` and `drawDepth`
const globalScope = regl({
  uniforms: {
    lightPos: lightPos
  }
})

// render point-light shadows into a cubemap
const drawDepth = regl({
  uniforms: {
    projection: mat4.perspective([], Math.PI / 2.0, 1.0, 0.25, 70.0),
    view: function (context, props, batchId) {
      switch (batchId) {
        case 0: // +x
          return mat4.lookAt([], lightPos, [lightPos[0] + 1.0, lightPos[1], lightPos[2]], [0.0, -1.0, 0.0])
        case 1: // -x
          return mat4.lookAt([], lightPos, [lightPos[0] - 1.0, lightPos[1], lightPos[2]], [0.0, -1.0, 0.0])
        case 2: // +y
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1] + 1.0, lightPos[2]], [0.0, 0.0, 1.0])
        case 3: // -y
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1] - 1.0, lightPos[2]], [0.0, 0.0, -1.0])
        case 4: // +z
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1], lightPos[2] + 1.0], [0.0, -1.0, 0.0])
        case 5: // -z
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1], lightPos[2] - 1.0], [0.0, -1.0, 0.0])
      }
    }
  },

  frag: `
  precision mediump float;

  varying vec3 vPosition;

  uniform vec3 lightPos;

  void main () {
    gl_FragColor = vec4(vec3(distance(vPosition, lightPos)), 1.0);
  }`,

  vert: `
  precision mediump float;

  attribute vec3 position;

  varying vec3 vPosition;

  uniform mat4 projection, view, model;

  void main() {
    vec4 p = model * vec4(position, 1.0);
    vPosition = p.xyz;
    gl_Position = projection * view * p;
  }`,

  framebuffer: function (context, props, batchId) {
    return shadowFbo.faces[batchId]
  }
})

// render the object with lighting, using the previously rendered cubemap
// to render the shadows.
const drawNormal = regl({
  uniforms: {
    view: () => camera.view(),
    projection: ({viewportWidth, viewportHeight}) =>
      mat4.perspective([],
                       Math.PI / 4,
                       viewportWidth / viewportHeight,
                       0.01,
                       1000),
    shadowCube: shadowFbo.color[0]
  },
  frag: `
  precision mediump float;

  varying vec3 vNormal;
  varying vec3 vPosition;

  uniform float ambientLightAmount;
  uniform float diffuseLightAmount;
  uniform vec3 color;
  uniform vec3 lightPos;
  uniform samplerCube shadowCube;

  void main () {
    // do ambient and diffuse lighting.
    vec3 lightDir = normalize(lightPos - vPosition);
    vec3 ambient = ambientLightAmount * color;
    float cosTheta = dot(vNormal, lightDir);
    vec3 diffuse = diffuseLightAmount * color * clamp(cosTheta , 0.0, 1.0 );

    vec3 texCoord = (vPosition - lightPos);
    float visibility = 0.0;

    // do soft shadows:
    for (int x = 0; x < 2; x++) {
      for (int y = 0; y < 2; y++) {
        for (int z = 0; z < 2; z++) {
          float bias = 0.3;
          vec4 env = textureCube(shadowCube, texCoord + vec3(x,y,z) * vec3(0.1) );
          visibility += (env.x+bias) < (distance(vPosition, lightPos)) ? 0.0 : 1.0;
        }
      }
    }
    visibility *= 1.0 / 8.0;

    gl_FragColor = vec4((ambient * visibility + diffuse), 1.0);
  }`,
  vert: `
  precision mediump float;

  attribute vec3 position;
  attribute vec3 normal;

  varying vec3 vPosition;
  varying vec3 vNormal;

  uniform mat4 projection, view, model;

  void main() {
    vec4 worldSpacePosition = model * vec4(position, 1);

    vPosition = worldSpacePosition.xyz;
    vNormal = normal;

    gl_Position = projection * view * worldSpacePosition;
  }`
})

function Mesh (elements, position, normal) {
  this.elements = elements
  this.position = position
  this.normal = normal
}

Mesh.prototype.draw = regl({
  uniforms: {
    model: (_, props, batchId) => {
      var m = mat4.identity([])

      mat4.translate(m, m, props.translate)

      var s = props.scale
      mat4.scale(m, m, [s, s, s])
      return m
    },
    ambientLightAmount: 0.3,
    diffuseLightAmount: 0.7,
    color: regl.prop('color')
  },
  attributes: {
    position: regl.this('position'),
    normal: regl.this('normal')
  },
  elements: regl.this('elements'),
  cull: {
    enable: true
  }
})

var bunnyMesh = new Mesh(bunny.cells, bunny.positions, normals(bunny.cells, bunny.positions))
var boxMesh = new Mesh(boxElements, boxPosition, boxNormal)
var planeMesh = new Mesh(planeElements, planePosition, planeNormal)

regl.frame(({tick}) => {
  var drawMeshes = () => {
    regl.clear({
      color: [0, 0, 0, 255],
      depth: 1
    })
    var i
    var theta
    var R
    var r, g, b
    var phi0 = 0.01 * tick

    var phi1 = -0.006 * tick

    for (i = 0; i < 1.0; i += 0.1) {
      theta = Math.PI * 2 * i
      R = 20.0

      r = ((Math.abs(23232 * i * i + 100212) % 255) / 255) * 0.4 + 0.3
      g = ((Math.abs(32278 * i + 213) % 255) / 255) * 0.4 + 0.15
      b = ((Math.abs(3112 * i * i * i + 2137 + i) % 255) / 255) * 0.05 + 0.05

      bunnyMesh.draw({scale: 0.7, translate: [R * Math.cos(theta + phi0), 3.0, R * Math.sin(theta + phi0)], color: [r, g, b]})
    }

    for (i = 0; i < 1.0; i += 0.15) {
      theta = Math.PI * 2 * i
      R = 35

      r = ((Math.abs(23232 * i * i + 100212) % 255) / 255) * 0.4 + 0.05
      g = ((Math.abs(32278 * i + 213) % 255) / 255) * 0.3 + 0.4
      b = ((Math.abs(3112 * i * i * i + 2137 + i) % 255) / 255) * 0.4 + 0.4

      boxMesh.draw({scale: 4.2, translate: [R * Math.cos(theta + phi1), 9.0, R * Math.sin(theta + phi1)], color: [r, g, b]})
    }

    planeMesh.draw({scale: 130.0, translate: [0.0, 0.0, 0.0], color: [1.0, 1.0, 1.0]})
  }

  globalScope(() => {
    drawDepth(6, () => {
      drawMeshes()
    })

    drawNormal(() => {
      drawMeshes()
    })
  })

  camera.tick()
})
<commit_msg>example/point-light-shadow.js: Add explanatory comment to the  beginning of the example<commit_after>/*
  This example shows how you can render shadows for point-lights using `regl.framebufferCube`

  You can read more about shadows for point-lights here:
  http://http.developer.nvidia.com/GPUGems/gpugems_ch12.html
  http://learnopengl.com/#!Advanced-Lighting/Shadows/Point-Shadows
*/

const webglCanvas = document.body.appendChild(document.createElement('canvas'))
const fit = require('canvas-fit')
const regl = require('../regl')({
  canvas: webglCanvas,
  extensions: 'oes_texture_float'
})
const mat4 = require('gl-mat4')
const camera = require('canvas-orbit-camera')(webglCanvas)
window.addEventListener('resize', fit(webglCanvas), false)
const bunny = require('bunny')
const normals = require('angle-normals')

// configure intial camera view.
camera.rotate([0.0, 0.0], [0.0, -0.4])
camera.zoom(50.0)

var lightPos = [0.0, 30.0, 0.0]

const CUBE_MAP_SIZE = 1024
const shadowFbo = regl.framebufferCube({
  radius: CUBE_MAP_SIZE,
  colorFormat: 'rgba',
  colorType: 'float'
})

const planeElements = []
var planePosition = []
var planeNormal = []

planePosition.push([-0.5, 0.0, -0.5])
planePosition.push([+0.5, 0.0, -0.5])
planePosition.push([-0.5, 0.0, +0.5])
planePosition.push([+0.5, 0.0, +0.5])

planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])
planeNormal.push([0.0, 1.0, 0.0])

planeElements.push([3, 1, 0])
planeElements.push([0, 2, 3])

var boxPosition = [
  // side faces
  [-0.5, +0.5, +0.5], [+0.5, +0.5, +0.5], [+0.5, -0.5, +0.5], [-0.5, -0.5, +0.5], // positive z face.
  [+0.5, +0.5, +0.5], [+0.5, +0.5, -0.5], [+0.5, -0.5, -0.5], [+0.5, -0.5, +0.5], // positive x face
  [+0.5, +0.5, -0.5], [-0.5, +0.5, -0.5], [-0.5, -0.5, -0.5], [+0.5, -0.5, -0.5], // negative z face
  [-0.5, +0.5, -0.5], [-0.5, +0.5, +0.5], [-0.5, -0.5, +0.5], [-0.5, -0.5, -0.5], // negative x face.
  [-0.5, +0.5, -0.5], [+0.5, +0.5, -0.5], [+0.5, +0.5, +0.5], [-0.5, +0.5, +0.5],  // top face
  [-0.5, -0.5, -0.5], [+0.5, -0.5, -0.5], [+0.5, -0.5, +0.5], [-0.5, -0.5, +0.5]  // bottom face
]

const boxElements = [
  [2, 1, 0], [2, 0, 3],
  [6, 5, 4], [6, 4, 7],
  [10, 9, 8], [10, 8, 11],
  [14, 13, 12], [14, 12, 15],
  [18, 17, 16], [18, 16, 19],
  [20, 21, 22], [23, 20, 22]
]

// all the normals of a single block.
var boxNormal = [
  // side faces
  [0.0, 0.0, +1.0], [0.0, 0.0, +1.0], [0.0, 0.0, +1.0], [0.0, 0.0, +1.0],
  [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0], [+1.0, 0.0, 0.0],
  [0.0, 0.0, -1.0], [0.0, 0.0, -1.0], [0.0, 0.0, -1.0], [0.0, 0.0, -1.0],
  [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0], [-1.0, 0.0, 0.0],
  // top
  [0.0, +1.0, 0.0], [0.0, +1.0, 0.0], [0.0, +1.0, 0.0], [0.0, +1.0, 0.0],
  // bottom
  [0.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, -1.0, 0.0]
]

// This call encapsulates the common state between `drawNormal` and `drawDepth`
const globalScope = regl({
  uniforms: {
    lightPos: lightPos
  }
})

// render point-light shadows into a cubemap
const drawDepth = regl({
  uniforms: {
    projection: mat4.perspective([], Math.PI / 2.0, 1.0, 0.25, 70.0),
    view: function (context, props, batchId) {
      switch (batchId) {
        case 0: // +x
          return mat4.lookAt([], lightPos, [lightPos[0] + 1.0, lightPos[1], lightPos[2]], [0.0, -1.0, 0.0])
        case 1: // -x
          return mat4.lookAt([], lightPos, [lightPos[0] - 1.0, lightPos[1], lightPos[2]], [0.0, -1.0, 0.0])
        case 2: // +y
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1] + 1.0, lightPos[2]], [0.0, 0.0, 1.0])
        case 3: // -y
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1] - 1.0, lightPos[2]], [0.0, 0.0, -1.0])
        case 4: // +z
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1], lightPos[2] + 1.0], [0.0, -1.0, 0.0])
        case 5: // -z
          return mat4.lookAt([], lightPos, [lightPos[0], lightPos[1], lightPos[2] - 1.0], [0.0, -1.0, 0.0])
      }
    }
  },

  frag: `
  precision mediump float;

  varying vec3 vPosition;

  uniform vec3 lightPos;

  void main () {
    gl_FragColor = vec4(vec3(distance(vPosition, lightPos)), 1.0);
  }`,

  vert: `
  precision mediump float;

  attribute vec3 position;

  varying vec3 vPosition;

  uniform mat4 projection, view, model;

  void main() {
    vec4 p = model * vec4(position, 1.0);
    vPosition = p.xyz;
    gl_Position = projection * view * p;
  }`,

  framebuffer: function (context, props, batchId) {
    return shadowFbo.faces[batchId]
  }
})

// render the object with lighting, using the previously rendered cubemap
// to render the shadows.
const drawNormal = regl({
  uniforms: {
    view: () => camera.view(),
    projection: ({viewportWidth, viewportHeight}) =>
      mat4.perspective([],
                       Math.PI / 4,
                       viewportWidth / viewportHeight,
                       0.01,
                       1000),
    shadowCube: shadowFbo.color[0]
  },
  frag: `
  precision mediump float;

  varying vec3 vNormal;
  varying vec3 vPosition;

  uniform float ambientLightAmount;
  uniform float diffuseLightAmount;
  uniform vec3 color;
  uniform vec3 lightPos;
  uniform samplerCube shadowCube;

  void main () {
    // do ambient and diffuse lighting.
    vec3 lightDir = normalize(lightPos - vPosition);
    vec3 ambient = ambientLightAmount * color;
    float cosTheta = dot(vNormal, lightDir);
    vec3 diffuse = diffuseLightAmount * color * clamp(cosTheta , 0.0, 1.0 );

    vec3 texCoord = (vPosition - lightPos);
    float visibility = 0.0;

    // do soft shadows:
    for (int x = 0; x < 2; x++) {
      for (int y = 0; y < 2; y++) {
        for (int z = 0; z < 2; z++) {
          float bias = 0.3;
          vec4 env = textureCube(shadowCube, texCoord + vec3(x,y,z) * vec3(0.1) );
          visibility += (env.x+bias) < (distance(vPosition, lightPos)) ? 0.0 : 1.0;
        }
      }
    }
    visibility *= 1.0 / 8.0;

    gl_FragColor = vec4((ambient * visibility + diffuse), 1.0);
  }`,
  vert: `
  precision mediump float;

  attribute vec3 position;
  attribute vec3 normal;

  varying vec3 vPosition;
  varying vec3 vNormal;

  uniform mat4 projection, view, model;

  void main() {
    vec4 worldSpacePosition = model * vec4(position, 1);

    vPosition = worldSpacePosition.xyz;
    vNormal = normal;

    gl_Position = projection * view * worldSpacePosition;
  }`
})

function Mesh (elements, position, normal) {
  this.elements = elements
  this.position = position
  this.normal = normal
}

Mesh.prototype.draw = regl({
  uniforms: {
    model: (_, props, batchId) => {
      var m = mat4.identity([])

      mat4.translate(m, m, props.translate)

      var s = props.scale
      mat4.scale(m, m, [s, s, s])
      return m
    },
    ambientLightAmount: 0.3,
    diffuseLightAmount: 0.7,
    color: regl.prop('color')
  },
  attributes: {
    position: regl.this('position'),
    normal: regl.this('normal')
  },
  elements: regl.this('elements'),
  cull: {
    enable: true
  }
})

var bunnyMesh = new Mesh(bunny.cells, bunny.positions, normals(bunny.cells, bunny.positions))
var boxMesh = new Mesh(boxElements, boxPosition, boxNormal)
var planeMesh = new Mesh(planeElements, planePosition, planeNormal)

regl.frame(({tick}) => {
  var drawMeshes = () => {
    regl.clear({
      color: [0, 0, 0, 255],
      depth: 1
    })
    var i
    var theta
    var R
    var r, g, b
    var phi0 = 0.01 * tick

    var phi1 = -0.006 * tick

    for (i = 0; i < 1.0; i += 0.1) {
      theta = Math.PI * 2 * i
      R = 20.0

      r = ((Math.abs(23232 * i * i + 100212) % 255) / 255) * 0.4 + 0.3
      g = ((Math.abs(32278 * i + 213) % 255) / 255) * 0.4 + 0.15
      b = ((Math.abs(3112 * i * i * i + 2137 + i) % 255) / 255) * 0.05 + 0.05

      bunnyMesh.draw({scale: 0.7, translate: [R * Math.cos(theta + phi0), 3.0, R * Math.sin(theta + phi0)], color: [r, g, b]})
    }

    for (i = 0; i < 1.0; i += 0.15) {
      theta = Math.PI * 2 * i
      R = 35

      r = ((Math.abs(23232 * i * i + 100212) % 255) / 255) * 0.4 + 0.05
      g = ((Math.abs(32278 * i + 213) % 255) / 255) * 0.3 + 0.4
      b = ((Math.abs(3112 * i * i * i + 2137 + i) % 255) / 255) * 0.4 + 0.4

      boxMesh.draw({scale: 4.2, translate: [R * Math.cos(theta + phi1), 9.0, R * Math.sin(theta + phi1)], color: [r, g, b]})
    }

    planeMesh.draw({scale: 130.0, translate: [0.0, 0.0, 0.0], color: [1.0, 1.0, 1.0]})
  }

  globalScope(() => {
    drawDepth(6, () => {
      drawMeshes()
    })

    drawNormal(() => {
      drawMeshes()
    })
  })

  camera.tick()
})
<|endoftext|>


<commit_before>import React from 'react';
import {graphql} from 'gatsby';
import Layout from '../components/Layout';
import {Box, Heading, Text} from 'grommet';
import _ from 'lodash';

const logs = [
  {date: '2018-09-05', content: 'add page source link'},
  {date: '2018-09-04', content: 'add tag cloud'},
  {date: '2018-08-14', content: 'build blog with gatsby/grommet'},
];

const Index = props => {
  return (
    <Layout>
      <Box direction="column" pad="xlarge" width="xlarge">
        <Text>This is my personal blog for technical things.</Text>

        <Heading level={3}>History:</Heading>

        {logs.map((log, key) => {
          return (
            <Box
              key={key}
              direction="row"
              justify="start"
              align="start"
              gap="medium">
              <Heading level={4} margin="none">
                {log.date} :
              </Heading>
              <Text>{log.content}</Text>
            </Box>
          );
        })}
      </Box>
    </Layout>
  );
};

export default Index;
<commit_msg>update<commit_after>import React from 'react';
import {graphql} from 'gatsby';
import Layout from '../components/Layout';
import {Box, Heading, Text} from 'grommet';
import {styled} from 'styled-components';
import _ from 'lodash';

const logs = [
  {date: '2018-09-05', content: 'add page source link'},
  {date: '2018-09-04', content: 'add tag cloud'},
  {date: '2018-08-14', content: 'build blog with gatsby/grommet'},
];

const Index = props => {
  return (
    <Layout>
      <Box direction="column" pad="xlarge" width="xlarge">
        <Text>This is my personal blog for technical things.</Text>
        <Heading level={3}>Features:</Heading>
        <Box margin={{left: 'medium'}}>
          <Text>Build with gatsbyjs/grommet/styled-components</Text>
          <Text>TOC of series</Text>
          <Text>Tag cloud</Text>
          <Text>MathJax enabled</Text>
        </Box>
        <Heading level={3}>History:</Heading>
        <Box margin={{left: 'medium'}}>
          {logs.map((log, key) => {
            return (
              <Box
                key={key}
                direction="row"
                justify="start"
                align="start"
                gap="medium">
                <Heading level={4} margin="none">
                  {log.date} :
                </Heading>
                <Text>{log.content}</Text>
              </Box>
            );
          })}
        </Box>
      </Box>
    </Layout>
  );
};

export default Index;
<|endoftext|>


<commit_before>/**
 * @jsx React.DOM
 */

/* Requiring dependencies for demo purposes, this should be done only when required */
var React = require('React');
var jquery = require('../vendor/jquery-2.1.0.js');
var UnderScore = require('underscore/underscore.js');
var Backbone = require('backbone/backbone.js');
var Reactbone = require('../patch/react.backbone.js');

var SiteBoilerPlate = require('../views/core/SiteBoilerPlate.js');
var Skeleton = require('../views/Skeleton/Skeleton.js');
var ProfileCards = require('../views/ProfileCards/ProfileCards.js');
var Router = require('../routes/Routes.js');

var index = React.createClass({
  componentDidMount: function() {
    /**
     * This runs on the client side. Add Jquery and Underscore to the window.
     * Initialize Backbone app once the dependencies are set up.
     */
  },

  render: function() {
    return (
      <SiteBoilerPlate>
        <Skeleton>
          <ProfileCards items={["profile-card", "profile-card extra"]} />
        </Skeleton>
      </SiteBoilerPlate>
    );
  }
});

module.exports = index;
<commit_msg>Add backbone and it's dependencies using componentDidMount<commit_after>/**
 * @jsx React.DOM
 */

/* Requiring dependencies for demo purposes, this should be done only when required */
var React = require('React');
var SiteBoilerPlate = require('../views/core/SiteBoilerPlate.js');
var Skeleton = require('../views/Skeleton/Skeleton.js');
var ProfileCards = require('../views/ProfileCards/ProfileCards.js');
var Router = require('../routes/Routes.js');

var index = React.createClass({
  componentDidMount: function() {
    /**
     * This runs on the client side. Add Jquery and Underscore to the window.
     * Initialize Backbone app once the dependencies are set up.
     */

     window._ = require('underscore/underscore.js')({});
     window.jQuery = require('../../bower_components/jquery/jquery.js');
     window.Backbone = require('backbone/backbone.js');
     var reactbackbone = require('../../bower_components/react.backbone/react.backbone.js');
  },

  render: function() {
    return (
      <SiteBoilerPlate>
        <Skeleton>
          <ProfileCards items={["profile-card", "profile-card extra"]} />
        </Skeleton>
      </SiteBoilerPlate>
    );
  }
});

module.exports = index;
<|endoftext|>


<commit_before>import React from "react"
import Link from "gatsby-link"
import get from "lodash/get"
import Helmet from "react-helmet"
import include from "underscore.string/include"

import Bio from "../components/Bio"
import { rhythm } from "../utils/typography"

class BlogIndex extends React.Component {
  render() {
    // console.log("props", this.props)
    const pageLinks = []
    const siteTitle = get(this, "props.data.site.siteMetadata.title")
    const posts = get(this, "props.data.allMarkdownRemark.edges")
    posts.forEach(post => {
      if (post.node.path !== "/404/") {
        const title = get(post, "node.frontmatter.title") || post.node.path
        pageLinks.push(

            <Link style={{ boxShadow: "none" }} to={post.node.fields.slug}>
              {post.node.frontmatter.title}
            </Link>

        )
      }
    })

    return (

        <Helmet title={get(this, "props.data.site.siteMetadata.title")} />
        <Bio />

          {pageLinks}

    )
  }
}

BlogIndex.propTypes = {
  route: React.PropTypes.object,
}

export default BlogIndex

export const pageQuery = graphql`
query IndexQuery {
  site {
    siteMetadata {
      title
    }
  }
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
        frontmatter {
          title
        }
      }
    }
  }
}
`
<commit_msg>remove bio from home page<commit_after>import React from "react"
import Link from "gatsby-link"
import get from "lodash/get"
import Helmet from "react-helmet"
import include from "underscore.string/include"

import Bio from "../components/Bio"
import { rhythm } from "../utils/typography"

class BlogIndex extends React.Component {
  render() {
    // console.log("props", this.props)
    const pageLinks = []
    const siteTitle = get(this, "props.data.site.siteMetadata.title")
    const posts = get(this, "props.data.allMarkdownRemark.edges")
    posts.forEach(post => {
      if (post.node.path !== "/404/") {
        const title = get(post, "node.frontmatter.title") || post.node.path
        pageLinks.push(

            <Link style={{ boxShadow: "none" }} to={post.node.fields.slug}>
              {post.node.frontmatter.title}
            </Link>

        )
      }
    })

    return (

        <Helmet title={get(this, "props.data.site.siteMetadata.title")} />

          {pageLinks}

    )
  }
}

BlogIndex.propTypes = {
  route: React.PropTypes.object,
}

export default BlogIndex

export const pageQuery = graphql`
query IndexQuery {
  site {
    siteMetadata {
      title
    }
  }
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
        frontmatter {
          title
        }
      }
    }
  }
}
`
<|endoftext|>


<commit_before>// displays security suggestion depending on information found in the model
const printMsgTxt = require('../helpers/printMsgTxt.js')

// contains the attribute/connection patterns and the suggestions
const list = {
  s0: {
    concept: 'device',
    layer: 'perception',
    suggestion: 'devices in the perception layer require physical security.'
  },
  s1: {
    concept: 'network connection',
    description: 'wireless',
    suggestion:
      'wireless connections are subject to information disclosure attacks. Use encrypted protocols.'
  }
}

module.exports = function suggestion (cy) {
  // fade out all the nodes
  cy.elements().addClass('faded')

  let s0nodes = []
  let s1nodes = []
  cy.nodes().map(node => {
    let nodeData = node.data().asto

    // s0 suggestion
    if (
      nodeData.concept === list.s0.concept &&
      nodeData.layer === list.s0.layer
    ) {
      node.removeClass('faded')
      node.addClass('attention')
      s0nodes.push(node.data().id)
    }
    // s1 suggestion
    if (
      nodeData.concept === list.s1.concept &&
      nodeData.description === list.s1.description
    ) {
      node.removeClass('faded')
      node.addClass('attention')
      s1nodes.push(node.data().id)
    }
  })
  // s0 suggestion
  printMsgTxt(`${s0nodes}: ${list.s0.suggestion}`)
  // s1 suggestion
  printMsgTxt(`${s1nodes}: ${list.s1.suggestion}`)
}
<commit_msg>code cleanup<commit_after>// displays security suggestion depending on information found in the model
const printMsgTxt = require('../helpers/printMsgTxt.js')

// contains the attribute/connection patterns and the suggestions
const list = {
  s0: {
    concept: 'device',
    layer: 'perception',
    suggestion: 'devices in the perception layer require physical security.'
  },
  s1: {
    concept: 'network connection',
    description: 'wireless',
    suggestion:
      'wireless connections are subject to information disclosure attacks. Use encrypted protocols.'
  }
}

module.exports = function suggestion (cy) {
  // fade out all the nodes
  cy.elements().addClass('faded')

  let s0nodes = []
  let s1nodes = []
  cy.nodes().map(node => {
    let nodeData = node.data().asto
    let nodeID = node.data().id

    // s0 suggestion
    if (
      nodeData.concept === list.s0.concept &&
      nodeData.layer === list.s0.layer
    ) {
      node.removeClass('faded')
      node.addClass('attention')
      s0nodes.push(nodeID)
    }
    // s1 suggestion
    if (
      nodeData.concept === list.s1.concept &&
      nodeData.description === list.s1.description
    ) {
      node.removeClass('faded')
      node.addClass('attention')
      s1nodes.push(nodeID)
    }
  })
  // s0 suggestion
  printMsgTxt(`${s0nodes}: ${list.s0.suggestion}`)
  // s1 suggestion
  printMsgTxt(`${s1nodes}: ${list.s1.suggestion}`)
}
<|endoftext|>


<commit_before>import React from 'react';

import { Tags } from '../components/Tags';
import JobList from '../components/JobList';
import { Loading } from '../components/Loading';
import { RegularHeader } from '../components/SlideHeader';

const CompanyInfo = ({company}) => (

{company.title}

SmartEtailing provides website, marketing and data solutions
                    to help independent bicycle retailers, cycling suppliers
                    and cycling brands sell more product in-store and online.

)

const Company = ({...props}) => (

    <RegularHeader {...props}/>

    <CompanyInfo company={props.company}/>
    {!props.jobs ? <Loading/> :

            <Tags {...props}
             />
            <JobList
                {...props}
                company={props.company.company}
            />

    }

)

export { Company }<commit_msg>frontend: company page cleanup<commit_after>import React from 'react';

import { Tags } from '../components/Tags';
import JobList from '../components/JobList';
import { Loading } from '../components/Loading';
import { RegularHeader } from '../components/SlideHeader';

const CompanyInfo = ({company}) => (

{company.title}

            {company.logo ?
                <img alt={`${company.title} logo`} className="company-logo" src={company.logo}/>
                :

{company.title}

            }
            {company.details &&

                    {company.details.numEmployees &&
👨💼 {company.details.numEmployees} Employees
}
                    {company.details.founded &&
📅 Founded {company.details.founded}
}
                    {company.details.headquarters &&
🏢 Headquarters: {company.details.headquarters}
}
                    {company.details.industry &&
🏭 {company.details.industry}
}

            }

        {company.about &&

                {company.about}

        }

)

const Company = ({...props}) => (

    <RegularHeader {...props}/>

    <CompanyInfo company={props.company}/>
    {!props.jobs ? <Loading/> :

            <Tags {...props}
             />
            <JobList
                {...props}
                company={props.company.company}
            />

    }

)

export { Company }<|endoftext|>


<commit_before>Object.size = function(obj, t) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    for (key in obj) {
        if (obj[key].deleted == true && t) size--;
    }
    return size;
};

if (!HTMLCanvasElement.prototype.toBlob) {
	Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
		value: function (callback, type, quality) {
			var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
			len = binStr.length,
			arr = new Uint8Array(len);
			for (var i=0; i<len; i++ ) {
				arr[i] = binStr.charCodeAt(i);
			}
			callback( new Blob( [arr], {type: type || 'image/png'} ) );
		}
	});
}

var updateInterval = 10000;
var jsonOld = [];
var model = OpenSprites.models.AssetList($("#collections .main-inner .content"));

function update() {
    $.getJSON(OpenSprites.domain + '/site-api/stuff.php?userid=' + OpenSprites.view.user.id + '&_=' + new Date, function(result) {
        if(JSON.stringify(result) !== JSON.stringify(jsonOld)) {
            jsonOld = result;
            processAjax(result);
        } else if(Object.size(result, true) === 0) {
            $('#collections .main-inner .heading').text("Uploads (None)");
        }

        setTimeout(update, updateInterval);
    });
}

function processAjax(json) {
    $('#collections .main-inner .heading').text('Uploads (' + json.length + ')');
    model.loadJson(json);
}

update();

// blurred background

/**
 * By Ken Fyrstenberg
 *
 * drawImageProp(context, image [, x, y, width, height [,offsetX, offsetY]])
 *
 * If image and context are only arguments rectangle will equal canvas
*/
function drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {

    if (arguments.length === 2) {
        x = y = 0;
        w = ctx.canvas.width;
        h = ctx.canvas.height;
    }

    // default offset is center
    offsetX = typeof offsetX === "number" ? offsetX : 0.5;
    offsetY = typeof offsetY === "number" ? offsetY : 0.5;

    // keep bounds [0.0, 1.0]
    if (offsetX < 0) offsetX = 0;
    if (offsetY < 0) offsetY = 0;
    if (offsetX > 1) offsetX = 1;
    if (offsetY > 1) offsetY = 1;

    var iw = img.width,
        ih = img.height,
        r = Math.min(w / iw, h / ih),
        nw = iw * r,   // new prop. width
        nh = ih * r,   // new prop. height
        cx, cy, cw, ch, ar = 1;

    // decide which gap to fill
    if (nw < w) ar = w / nw;
    if (nh < h) ar = h / nh;
    nw *= ar;
    nh *= ar;

    // calc source rectangle
    cw = iw / (nw / w);
    ch = ih / (nh / h);

    cx = (iw - cw) * offsetX;
    cy = (ih - ch) * offsetY;

    // make sure source rectangle is valid
    if (cx < 0) cx = 0;
    if (cy < 0) cy = 0;
    if (cw > iw) cw = iw;
    if (ch > ih) ch = ih;

    // fill image in dest. rectangle
    ctx.drawImage(img, cx, cy, cw, ch,  x, y, w, h);
}

function drawBg(){
	var canvas = document.getElementsByTagName('canvas');
	try {
        canvas = canvas[0];
		var context = canvas.getContext("2d");
		var img = new Image();
		img.onload = function() {
			drawImageProp(context, img);
			stackBlurCanvasRGB(canvas, 0, 0, canvas.width, canvas.height, 10);
		}
		img.src = "/uploads/avatar_blur.php?userid=" + OpenSprites.view.user.id;
	} catch(e) {}
}

drawBg();
$(window).resize(drawBg);

$('.modal.edit-profile input#bg').change(function() {
	var val = $(".modal.edit-profile input#bg").is(":checked");
	if(val) {
		$('.modal.edit-profile #bg_true').hide();
	} else {
		$('.modal.edit-profile #bg_true').show();
	}
});

$("#settings").click(function() {
	$("#aboutme").val(OpenSprites.view.user.profile.about);
	$("#text-location").val(OpenSprites.view.user.profile.location);
	if(OpenSprites.view.user.profile.bgcolor == "avatar"){
		$("#bg").prop("checked", true);
		$('.modal.edit-profile #bg_true').hide();
		$("#bgcolor").spectrum({
			color: "rgb(101, 149, 147)",
			showInput: true,
			clickoutFiresChange: true
		});
	} else {
		$("#bgcolor").val(OpenSprites.view.user.profile.bgcolor);
		$("#bgcolor").spectrum({
			color: OpenSprites.view.user.profile.bgcolor
		});
		$("#bg").prop("checked", false);
		$('.modal.edit-profile #bg_true').show();
	}
	$(".modal-overlay, .modal.edit-profile").fadeIn();
});

$('.modal.edit-profile .btn.red').click(function() {
	$(".modal-overlay, .modal.edit-profile").fadeOut();
});

$('.modal.edit-profile .btn.blue').click(function() {
	var thisBtn = $(this);
	thisBtn.text("Loading...").attr("disabled", "disabled");
	$(".modal.edit-profile .error").text("");
    var bg = $("#bgcolor").spectrum("get").toRgbString();
    if($(".modal.edit-profile input#bg").is(":checked")) {
        bg = 'avatar';
    }

    var aboutme = $('#aboutme').val();
    var location = $('#text-location').val();
    $.post("/users/edit.php", {userid: OpenSprites.user.id, about: aboutme, location: location, bgcolor: bg}, function(data){
		thisBtn.text("OK").removeAttr("disabled");
		if(typeof data == "object"){
			OpenSprites.view.user.profile = data;
			parseDesc(data['about']);
			$("#location").text(data['location']);

			if(data['bgcolor'] == "avatar"){
				$("#background-img").fadeOut(700, function(){
					$(this).remove();
					$("body").prepend($("<canvas id='background-img' style='display:none'></canvas>"));
					drawBg();
					$("#background-img").fadeIn();
				});
			} else {
				$("#background-img").fadeOut(700, function(){
					$(this).remove();
					$("body").prepend($("

"));
					$("#background-img").fadeIn();
				});
			}

			$(".modal-overlay, .modal.edit-profile").fadeOut();
		} else {
			$(".modal.edit-profile .error").text("Error: " + data);
		}
	}).fail(function(){
		thisBtn.text("OK").removeAttr("disabled");
		$(".modal.edit-profile .error").text("Sorry, we were unable to update your profile. Try again later.");
	});
});

var mdHints = OpenSprites.models.MdHints($('#aboutme'));

$("#change-image input[type=file]").change(function(e){
	$("#cropper-container > img").cropper("destroy");
	$("#progress-container").text("");
	$("#cropper-container").text("Loading image...");
	$(".modal-overlay, .modal.cropavatar").fadeIn(700, function(){
		if(!window.Blob || !window.File || !window.FormData){
			$("#cropper-container").text("Whoops! Your browser doesn't support what we need to crop your avatar. Upgrade to the latest Firefox/Firefox-derivative or Chrome/Chromium/Opera.");
			return;
		}

		var reader = new FileReader();
		reader.onload = function(e) {
			var img = $("").attr("src", e.target.result);
			$("#cropper-container").html("").append(img);
			img.cropper({
				aspectRatio: 1
			});
		}
		reader.readAsDataURL(e.originalEvent.target.files[0]);
	});
});

$(".modal.cropavatar .btn.blue").click(function(){
	var thisBtn = $(this);
	thisBtn.text("Uploading...").attr("disabled", "disabled");

	var canvas = $("#cropper-container > img").cropper("getCroppedCanvas", {width: 200, height: 200, fillColor: "#000000"});
	canvas.toBlob(function(blob){
		var formData = new FormData();
		formData.append("avatar", blob);
		formData.append("userid", OpenSprites.user.id);
		var avatarToken = Math.round(Math.random() * 100000000000).toString(16);
		formData.append("token", avatarToken);
		document.cookie = "avatarToken=" + avatarToken + "; path=/";

		$(".progress-container").text("Uploading...");

		$.ajax({
			url : "/users/user-avatar.php",
			type : 'POST',
			data : formData,
			async : true,
			xhr : function () {
				var xhr = jQuery.ajaxSettings.xhr();
				if (xhr instanceof window.XMLHttpRequest) {
					xhr.upload.addEventListener("progress", function (evt) {
						if (evt.lengthComputable) {
							var percentComplete = Math.round(evt.loaded * 100 / evt.total);
							$(".progress-container").text("Uploading avatar ("+percentComplete+"%)");
						}
					}, false);
				}
				return xhr;
			},
			success : function (data) {
				thisBtn.text("Set Avatar").removeAttr("disabled");
				try {
					data = JSON.parse(data);
					if(data.status != "success"){
						$(".progress-container").text(data.message);
					} else {
						$(".modal-overlay, .modal.cropavatar").fadeOut();
						$(".user-avatar.x100").attr("src", "http://opensprites.gwiddle.co.uk/forums/uploads/avatars/"+OpenSprites.user.id+".png?_=" + Math.random());
						drawBg();
					}
				} catch(e){
					console.log(data);
					$(".progress-container").text("Whoops! We weren't able to recieve a response from our servers. Try again later");
				}
			},
			error : function (jqXHR, textStatus, errorThrown) {
				$(".progress-container").text("Whoops! We weren't able to upload your avatar. Try again later");
				thisBtn.text("Set Avatar").removeAttr("disabled");
			},
			cache : false,
			contentType : false,
			dataType : "text",
			processData : false
		});
	}, "image/png");
});

$(".modal.cropavatar .btn.red").click(function(){
	$(".modal-overlay, .modal.cropavatar").fadeOut();
});<commit_msg>Fixes<commit_after>Object.size = function(obj, t) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    for (key in obj) {
        if (obj[key].deleted == true && t) size--;
    }
    return size;
};

if (!HTMLCanvasElement.prototype.toBlob) {
	Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
		value: function (callback, type, quality) {
			var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
			len = binStr.length,
			arr = new Uint8Array(len);
			for (var i=0; i<len; i++ ) {
				arr[i] = binStr.charCodeAt(i);
			}
			callback( new Blob( [arr], {type: type || 'image/png'} ) );
		}
	});
}

var updateInterval = 10000;
var jsonOld = [];
var model = OpenSprites.models.AssetList($("#collections .main-inner .content"));

function update() {
    $.getJSON(OpenSprites.domain + '/site-api/stuff.php?userid=' + OpenSprites.view.user.id + '&_=' + new Date, function(result) {
        if(JSON.stringify(result) !== JSON.stringify(jsonOld)) {
            jsonOld = result;
            processAjax(result);
        } else if(Object.size(result, true) === 0) {
            $('#collections .main-inner .heading').text("Uploads (None)");
        }

        setTimeout(update, updateInterval);
    });
}

function processAjax(json) {
    $('#collections .main-inner .heading').text('Uploads (' + json.length + ')');
    model.loadJson(json);
}

update();

// blurred background

/**
 * By Ken Fyrstenberg
 *
 * drawImageProp(context, image [, x, y, width, height [,offsetX, offsetY]])
 *
 * If image and context are only arguments rectangle will equal canvas
*/
function drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {

    if (arguments.length === 2) {
        x = y = 0;
        w = ctx.canvas.width;
        h = ctx.canvas.height;
    }

    // default offset is center
    offsetX = typeof offsetX === "number" ? offsetX : 0.5;
    offsetY = typeof offsetY === "number" ? offsetY : 0.5;

    // keep bounds [0.0, 1.0]
    if (offsetX < 0) offsetX = 0;
    if (offsetY < 0) offsetY = 0;
    if (offsetX > 1) offsetX = 1;
    if (offsetY > 1) offsetY = 1;

    var iw = img.width,
        ih = img.height,
        r = Math.min(w / iw, h / ih),
        nw = iw * r,   // new prop. width
        nh = ih * r,   // new prop. height
        cx, cy, cw, ch, ar = 1;

    // decide which gap to fill
    if (nw < w) ar = w / nw;
    if (nh < h) ar = h / nh;
    nw *= ar;
    nh *= ar;

    // calc source rectangle
    cw = iw / (nw / w);
    ch = ih / (nh / h);

    cx = (iw - cw) * offsetX;
    cy = (ih - ch) * offsetY;

    // make sure source rectangle is valid
    if (cx < 0) cx = 0;
    if (cy < 0) cy = 0;
    if (cw > iw) cw = iw;
    if (ch > ih) ch = ih;

    // fill image in dest. rectangle
    ctx.drawImage(img, cx, cy, cw, ch,  x, y, w, h);
}

function drawBg(){
	var canvas = document.getElementsByTagName('canvas');
	try {
        canvas = canvas[0];
		var context = canvas.getContext("2d");
		var img = new Image();
		img.onload = function() {
			drawImageProp(context, img);
			stackBlurCanvasRGB(canvas, 0, 0, canvas.width, canvas.height, 10);
		}
		img.src = "/uploads/avatar_blur.php?userid=" + OpenSprites.view.user.id;
	} catch(e) {}
}

drawBg();
$(window).resize(drawBg);

$('.modal.edit-profile input#bg').change(function() {
	var val = $(".modal.edit-profile input#bg").is(":checked");
	if(val) {
		$('.modal.edit-profile #bg_true').hide();
	} else {
		$('.modal.edit-profile #bg_true').show();
	}
});

$("#settings").click(function() {
	$("#aboutme").val(OpenSprites.view.user.profile.about);
	$("#text-location").val(OpenSprites.view.user.profile.location);
	if(OpenSprites.view.user.profile.bgcolor == "avatar"){
		$("#bg").prop("checked", true);
		$('.modal.edit-profile #bg_true').hide();
		$("#bgcolor").spectrum({
			color: "rgb(101, 149, 147)",
			showInput: true,
			clickoutFiresChange: true
		});
	} else {
		$("#bgcolor").val(OpenSprites.view.user.profile.bgcolor);
		$("#bgcolor").spectrum({
			color: OpenSprites.view.user.profile.bgcolor
		});
		$("#bg").prop("checked", false);
		$('.modal.edit-profile #bg_true').show();
	}
	$(".modal-overlay, .modal.edit-profile").fadeIn();
});

$('.modal.edit-profile .btn.red').click(function() {
	$(".modal-overlay, .modal.edit-profile").fadeOut();
});

$('.modal.edit-profile .btn.blue').click(function() {
	var thisBtn = $(this);
	thisBtn.text("Loading...").attr("disabled", "disabled");
	$(".modal.edit-profile .error").text("");
    var bg = $("#bgcolor").spectrum("get").toRgbString();
    if($(".modal.edit-profile input#bg").is(":checked")) {
        bg = 'avatar';
    }

    var aboutme = $('#aboutme').val();
    var location = $('#text-location').val();
    $.post("/users/edit.php", {userid: OpenSprites.user.id, about: aboutme, location: location, bgcolor: bg}, function(data){
		thisBtn.text("OK").removeAttr("disabled");
		if(typeof data == "object"){
			OpenSprites.view.user.profile = data;
			parseDesc(data['about']);
			$("#location").text(data['location']);

			if(data['bgcolor'] == "avatar"){
				$("#background-img").fadeOut(700, function(){
					$(this).remove();
					$("body").prepend($("<canvas id='background-img' style='display:none'></canvas>"));
					drawBg();
					$("#background-img").fadeIn();
				});
			} else {
				$("#background-img").fadeOut(700, function(){
					$(this).remove();
					$("body").prepend($("

"));
					$("#background-img").fadeIn();
				});
			}

			$(".modal-overlay, .modal.edit-profile").fadeOut();
		} else {
			$(".modal.edit-profile .error").text("Error: " + data);
		}
	}).fail(function(){
		thisBtn.text("OK").removeAttr("disabled");
		$(".modal.edit-profile .error").text("Sorry, we were unable to update your profile. Try again later.");
	});
});

var mdHints = OpenSprites.models.MdHints($('#aboutme'));

$("#change-image input[type=file]").change(function(e){
	$("#cropper-container > img").cropper("destroy");
	$(".progress-container").text("");
	$("#cropper-container").text("Loading image...");
	$(".modal-overlay, .modal.cropavatar").fadeIn(700, function(){
		if(!window.Blob || !window.File || !window.FormData){
			$("#cropper-container").text("Whoops! Your browser doesn't support what we need to crop your avatar. Upgrade to the latest Firefox/Firefox-derivative or Chrome/Chromium/Opera.");
			return;
		}

		var reader = new FileReader();
		reader.onload = function(e) {
			var img = $("").attr("src", e.target.result);
			$("#cropper-container").html("").append(img);
			img.cropper({
				aspectRatio: 1
			});
		}
		reader.readAsDataURL(e.originalEvent.target.files[0]);
	});
});

$(".modal.cropavatar .btn.blue").click(function(){
	var thisBtn = $(this);
	thisBtn.text("Uploading...").attr("disabled", "disabled");

	var canvas = $("#cropper-container > img").cropper("getCroppedCanvas", {width: 200, height: 200, fillColor: "#000000"});
	canvas.toBlob(function(blob){
		var formData = new FormData();
		formData.append("avatar", blob);
		formData.append("userid", OpenSprites.user.id);
		var avatarToken = Math.round(Math.random() * 100000000000).toString(16);
		formData.append("token", avatarToken);
		document.cookie = "avatarToken=" + avatarToken + "; path=/";

		$(".progress-container").text("Uploading...");

		$.ajax({
			url : "/users/user-avatar.php",
			type : 'POST',
			data : formData,
			async : true,
			xhr : function () {
				var xhr = jQuery.ajaxSettings.xhr();
				if (xhr instanceof window.XMLHttpRequest) {
					xhr.upload.addEventListener("progress", function (evt) {
						if (evt.lengthComputable) {
							var percentComplete = Math.round(evt.loaded * 100 / evt.total);
							$(".progress-container").text("Uploading avatar ("+percentComplete+"%)");
						}
					}, false);
				}
				return xhr;
			},
			success : function (data) {
				thisBtn.text("Set Avatar").removeAttr("disabled");
				try {
					data = JSON.parse(data);
					if(data.status != "success"){
						$(".progress-container").text(data.message);
					} else {
						$(".modal-overlay, .modal.cropavatar").fadeOut();
						$(".user-avatar.x100").attr("src", "http://opensprites.gwiddle.co.uk/forums/uploads/avatars/"+OpenSprites.user.id+".png?_=" + Math.random());
						drawBg();
					}
				} catch(e){
					console.log(data);
					$(".progress-container").text("Whoops! We weren't able to recieve a response from our servers. Try again later");
				}
			},
			error : function (jqXHR, textStatus, errorThrown) {
				$(".progress-container").text("Whoops! We weren't able to upload your avatar. Try again later");
				thisBtn.text("Set Avatar").removeAttr("disabled");
			},
			cache : false,
			contentType : false,
			dataType : "text",
			processData : false
		});
	}, "image/png");
});

$(".modal.cropavatar .btn.red").click(function(){
	$(".modal-overlay, .modal.cropavatar").fadeOut();
});<|endoftext|>


<commit_before>/**
 * Copyright (C) 2014 Glayzzle (BSD3 License)
 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
 * @url http://glayzzle.com
 */

module.exports = function(api, tokens, EOF) {
  return {

    read_expr: function() {
      var expr = this.read_expr_item();
      switch(this.token) {
        // binary operations
        case '|': return ['bin', '|', expr, this.next().read_expr()];
        case '&': return ['bin', '&', expr, this.next().read_expr()];
        case '^': return ['bin', '^', expr, this.next().read_expr()];
        case '.': return ['bin', '.', expr, this.next().read_expr()];
        case '+': return ['bin', '+', expr, this.next().read_expr()];
        case '-': return ['bin', '-', expr, this.next().read_expr()];
        case '*': return ['bin', '*', expr, this.next().read_expr()];
        case '/': return ['bin', '/', expr, this.next().read_expr()];
        case '%': return ['bin', '%', expr, this.next().read_expr()];
        case tokens.T_POW:  return ['bin', '**', expr, this.next().read_expr()];
        case tokens.T_SL:   return ['bin', '<<', expr, this.next().read_expr()];
        case tokens.T_SR:   return ['bin', '>>', expr, this.next().read_expr()];

        // boolean operations
        case tokens.T_BOOLEAN_OR:
        case tokens.T_LOGICAL_OR:   return ['bool', '|', expr, this.next().read_expr()];

        case tokens.T_BOOLEAN_AND:
        case tokens.T_LOGICAL_AND:  return ['bool', '&', expr, this.next().read_expr()];

        case tokens.T_LOGICAL_XOR:      return ['bool', '^', expr, this.next().read_expr()];
        case tokens.T_IS_IDENTICAL:     return ['bool', '=', expr, this.next().read_expr()];
        case tokens.T_IS_NOT_IDENTICAL: return ['bool', '!=', expr, this.next().read_expr()];
        case tokens.T_IS_EQUAL:         return ['bool', '~', expr, this.next().read_expr()];
        case tokens.T_IS_NOT_EQUAL:     return ['bool', '!~', expr, this.next().read_expr()];
        case '<':                       return ['bool', '<', expr, this.next().read_expr()];
        case '>':                       return ['bool', '>', expr, this.next().read_expr()];

        case tokens.T_IS_SMALLER_OR_EQUAL:  return ['bool', '<=', expr, this.next().read_expr()];
        case tokens.T_IS_GREATER_OR_EQUAL:  return ['bool', '>=', expr, this.next().read_expr()];
        case tokens.T_INSTANCEOF:           return ['bool', '?', expr, this.next().read_expr()];

        // extra operations :
        case tokens.T_COALESCE: // php7 : $username = $_GET['user'] ?? 'nobody';
          return ['retif', ['sys', 'isset', expr], expr, this.next().read_expr()];
        case '?':
          var trueArg = null;
          if (this.next().token !== ':') {
            trueArg = this.read_expr();
          }
          this.expect(':').next();
          return ['retif', expr, trueArg, this.read_expr()];
      }
      return expr;
    }

    /**
     * <ebnf>
     * Reads an expression
     *  expr ::= @todo
     * </ebnf>
     */
    ,read_expr_item: function() {

      switch(this.token) {

        case '@':
          return ['silence', this.next().read_expr()];

        case '-':
        case '+':
        case '!':
        case '~':
          return ['unary', this.token, this.next().read_expr()];

        case '(':
          var expr = this.next().read_expr();
          this.expect(')').next();
          return expr;

        case '`':
          var expr = null;
          if (this.next().token === tokens.T_ENCAPSED_AND_WHITESPACE) {
            expr = this.text();
            this.next().expect('`').next();
          } else if (this.token !== '`' ) {
            expr = this.read_encaps_list();
          }
          return ['sys', 'shell', expr];

        case tokens.T_LIST:
          return this.read_assignment_list();

        case tokens.T_CLONE:
          return ['sys', 'clone', this.next().read_expr()];

        case tokens.T_INC:
          var name = this.next().read_variable();
          return ['set', name, ['bin', '+', name, ['number', 1]]];

        case tokens.T_DEC:
          var name = this.next().read_variable();
          return ['set', name, ['bin', '-', name, ['number', 1]]];

        case tokens.T_NEW:
          return this.next().read_new_expr();

        case tokens.T_ISSET:
          this.next().expect('(').next();
          var expr = this.read_variable(true);
          this.expect(')').next();
          return ['sys', 'isset', expr];

        case tokens.T_EMPTY:
          this.next().expect('(').next();
          var expr = this.read_expr();
          this.expect(')').next();
          return ['sys', 'empty', expr];

        case tokens.T_INCLUDE:
          return ['sys', 'include', this.next().read_expr()];

        case tokens.T_INCLUDE_ONCE:
          return ['sys', 'include_once', this.next().read_expr()];

        case tokens.T_REQUIRE:
          return ['sys', 'require', this.next().read_expr()];

        case tokens.T_REQUIRE_ONCE:
          return ['sys', 'require', this.next().read_expr()];

        case tokens.T_EVAL:
          this.next().expect('(').next();
          var expr = this.read_expr();
          this.expect(')').next();
          return ['sys', 'eval', expr];

        case tokens.T_INT_CAST:
          return ['cast', 'int', this.next().read_expr()];

        case tokens.T_DOUBLE_CAST:
          return ['cast', 'double', this.next().read_expr()];

        case tokens.T_STRING_CAST:
          return ['cast', 'string', this.next().read_expr()];

        case tokens.T_ARRAY_CAST:
          return ['cast', 'array', this.next().read_expr()];

        case tokens.T_OBJECT_CAST:
          return ['cast', 'object', this.next().read_expr()];

        case tokens.T_BOOL_CAST:
          return ['cast', 'boolean', this.next().read_expr()];

        case tokens.T_UNSET_CAST:
          return ['sys', 'unset', this.next().read_expr()];

        case tokens.T_EXIT:
          var expr = null;
          if ( this.next().token === '(' ) {
            if (this.next().token !== ')') {
              expr = this.read_expr();
              this.expect(')').next();
            } else {
              this.next();
            }
          }
          return ['sys', 'exit', expr];

        case tokens.T_PRINT:
          return ['sys', 'print', this.next().read_expr()];

        case tokens.T_YIELD:
          var result = ['yield', null, null];
          if (this.next().is('expr')) {
            // reads the yield return value
            result[1] = this.read_expr();
            if (this.token === tokens.T_DOUBLE_ARROW) {
              // reads the yield returned key
              result[2] = this.read_expr();
            }
          }
          return result;

        case tokens.T_FUNCTION:
          // @fixme later - removed static lambda function declarations (colides with static keyword usage)
          return this.read_function(true);

      }

      // SCALAR | VARIABLE
      var expr;
      if (this.is('VARIABLE')) {
        expr = this.read_variable();
        // VARIABLES SPECIFIC OPERATIONS
        switch(this.token) {
          case '=':
            if (this.next().token == '&') {
              if (this.next().token === tokens.T_NEW) {
                return ['link', expr, this.next().read_new_expr()];
              } else {
                return ['link', expr, this.read_variable()];
              }
            } else {
              return [
                'set',
                expr,
                this.token === tokens.T_NEW ?
                  this.next().read_new_expr() : this.read_expr()
              ];
            }
          // operations :
          case tokens.T_PLUS_EQUAL:
            return ['set', expr, ['bin', '+', expr, this.next().read_expr()]];
          case tokens.T_MINUS_EQUAL:
            return ['set', expr, ['bin', '-', expr, this.next().read_expr()]];
          case tokens.T_MUL_EQUAL:
            return ['set', expr, ['bin', '*', expr, this.next().read_expr()]];
          case tokens.T_POW_EQUAL:
            return ['set', expr, ['bin', '**', expr, this.next().read_expr()]];
          case tokens.T_DIV_EQUAL:
            return ['set', expr, ['bin', '/', expr, this.next().read_expr()]];
          case tokens.T_CONCAT_EQUAL:
            // NB : convert as string and add
            return ['set', expr, ['bin', '.', expr, this.next().read_expr()]];
          case tokens.T_MOD_EQUAL:
            return ['set', expr, ['bin', '%', expr, this.next().read_expr()]];
          case tokens.T_AND_EQUAL:
            return ['set', expr, ['bin', '&', expr, this.next().read_expr()]];
          case tokens.T_OR_EQUAL:
            return ['set', expr, ['bin', '|', expr, this.next().read_expr()]];
          case tokens.T_XOR_EQUAL:
            return ['set', expr, ['bin', '^', expr, this.next().read_expr()]];
          case tokens.T_SL_EQUAL:
            return ['set', expr, ['bin', '<<', expr, this.next().read_expr()]];
          case tokens.T_SR_EQUAL:
            return ['set', expr, ['bin', '>>', expr, this.next().read_expr()]];
          case tokens.T_INC:
            this.next();
            return ['post', '+', expr];
          case tokens.T_DEC:
            this.next();
            return ['post', '-', expr];
        }
      } else if (this.is('SCALAR')) {
        expr = this.read_scalar();
      } else {
        this.error('EXPR');
      }

      // returns variable | scalar
      return expr;

    }
    /**
     * <ebnf>
     *    new_expr ::= T_NEW namespace_name function_argument_list
     * </ebnf>
     */
    ,read_new_expr: function() {
      var name = this.read_class_name_reference();
      var args = [];
      if (this.token === '(') {
        args = this.read_function_argument_list();
      }
      return ['new', name, args];
    }
    /**
     * Reads a class name
     * <ebnf>
     * class_name_reference ::= namespace_name | variable
     * </ebnf>
     */
    ,read_class_name_reference: function() {
      if (this.token === '\\' || this.token === tokens.T_STRING) {
        return this.read_namespace_name();
      } else if (this.is('VARIABLE')) {
        return this.read_variable(true);
      } else {
        this.expect([T_STRING, 'VARIABLE']);
      }
    }
    /**
     * <ebnf>
     *   assignment_list ::= T_LIST '(' ((variable? | assignment_list) (',' (variable? | assignment_list))*)? ')' '=' expr
     * </ebnf>
     */
    ,read_assignment_list: function(innerList) {
      var assignList = [];
      this.expect(tokens.T_LIST).next().expect('(').next();
      while(this.token !== ')' && this.token != EOF) {
        if (this.token === tokens.T_LIST) {
          assignList.push(this.read_assignment_list(true));
        } else {
          if (this.token !== ',') {
            assignList.push(this.read_variable());
          } else {
            assignList.push(null);
          }
        }
        if (this.token !== ',') break;
        this.next();
      }
      this.expect(')').next();
      return [
        'list', assignList,
          innerList ?
            false :
            this.expect('=').next().read_expr()
      ];
    }
  };
};<commit_msg>fix t_list and t_isset implementation<commit_after>/**
 * Copyright (C) 2014 Glayzzle (BSD3 License)
 * @authors https://github.com/glayzzle/php-parser/graphs/contributors
 * @url http://glayzzle.com
 */

module.exports = function(api, tokens, EOF) {

  return {

    read_expr: function() {
      var expr = this.read_expr_item();
      switch(this.token) {
        // binary operations
        case '|': return ['bin', '|', expr, this.next().read_expr()];
        case '&': return ['bin', '&', expr, this.next().read_expr()];
        case '^': return ['bin', '^', expr, this.next().read_expr()];
        case '.': return ['bin', '.', expr, this.next().read_expr()];
        case '+': return ['bin', '+', expr, this.next().read_expr()];
        case '-': return ['bin', '-', expr, this.next().read_expr()];
        case '*': return ['bin', '*', expr, this.next().read_expr()];
        case '/': return ['bin', '/', expr, this.next().read_expr()];
        case '%': return ['bin', '%', expr, this.next().read_expr()];
        case tokens.T_POW:  return ['bin', '**', expr, this.next().read_expr()];
        case tokens.T_SL:   return ['bin', '<<', expr, this.next().read_expr()];
        case tokens.T_SR:   return ['bin', '>>', expr, this.next().read_expr()];

        // boolean operations
        case tokens.T_BOOLEAN_OR:
        case tokens.T_LOGICAL_OR:   return ['bool', '|', expr, this.next().read_expr()];

        case tokens.T_BOOLEAN_AND:
        case tokens.T_LOGICAL_AND:  return ['bool', '&', expr, this.next().read_expr()];

        case tokens.T_LOGICAL_XOR:      return ['bool', '^', expr, this.next().read_expr()];
        case tokens.T_IS_IDENTICAL:     return ['bool', '=', expr, this.next().read_expr()];
        case tokens.T_IS_NOT_IDENTICAL: return ['bool', '!=', expr, this.next().read_expr()];
        case tokens.T_IS_EQUAL:         return ['bool', '~', expr, this.next().read_expr()];
        case tokens.T_IS_NOT_EQUAL:     return ['bool', '!~', expr, this.next().read_expr()];
        case '<':                       return ['bool', '<', expr, this.next().read_expr()];
        case '>':                       return ['bool', '>', expr, this.next().read_expr()];

        case tokens.T_IS_SMALLER_OR_EQUAL:  return ['bool', '<=', expr, this.next().read_expr()];
        case tokens.T_IS_GREATER_OR_EQUAL:  return ['bool', '>=', expr, this.next().read_expr()];
        case tokens.T_INSTANCEOF:           return ['bool', '?', expr, this.next().read_expr()];

        // extra operations :
        case tokens.T_COALESCE: // php7 : $username = $_GET['user'] ?? 'nobody';
          return ['retif', ['sys', 'isset', expr], expr, this.next().read_expr()];
        case '?':
          var trueArg = null;
          if (this.next().token !== ':') {
            trueArg = this.read_expr();
          }
          this.expect(':').next();
          return ['retif', expr, trueArg, this.read_expr()];
      }
      return expr;
    }

    /**
     * <ebnf>
     * Reads an expression
     *  expr ::= @todo
     * </ebnf>
     */
    ,read_expr_item: function() {

      switch(this.token) {

        case '@':
          return ['silence', this.next().read_expr()];

        case '-':
        case '+':
        case '!':
        case '~':
          return ['unary', this.token, this.next().read_expr()];

        case '(':
          var expr = this.next().read_expr();
          this.expect(')').next();
          return expr;

        case '`':
          var expr = null;
          if (this.next().token === tokens.T_ENCAPSED_AND_WHITESPACE) {
            expr = this.text();
            this.next().expect('`').next();
          } else if (this.token !== '`' ) {
            expr = this.read_encaps_list();
          }
          return ['sys', 'shell', expr];

        case tokens.T_LIST:
          this.next().expect('(').next();
          var assignList = this.read_assignment_list();
          this.expect(')').next().expect('=').next();
          return [
            'list',
            assignList,
            this.read_expr()
          ];

        case tokens.T_CLONE:
          return ['sys', 'clone', this.next().read_expr()];

        case tokens.T_INC:
          var name = this.next().read_variable();
          return ['set', name, ['bin', '+', name, ['number', 1]]];

        case tokens.T_DEC:
          var name = this.next().read_variable();
          return ['set', name, ['bin', '-', name, ['number', 1]]];

        case tokens.T_NEW:
          return this.next().read_new_expr();

        case tokens.T_ISSET:
          this.next().expect('(').next();
          var expr = this.read_list(this.read_expr, ',');
          this.expect(')').next();
          return ['sys', 'isset', expr];

        case tokens.T_EMPTY:
          this.next().expect('(').next();
          var expr = this.read_expr();
          this.expect(')').next();
          return ['sys', 'empty', expr];

        case tokens.T_INCLUDE:
          return ['sys', 'include', this.next().read_expr()];

        case tokens.T_INCLUDE_ONCE:
          return ['sys', 'include_once', this.next().read_expr()];

        case tokens.T_REQUIRE:
          return ['sys', 'require', this.next().read_expr()];

        case tokens.T_REQUIRE_ONCE:
          return ['sys', 'require', this.next().read_expr()];

        case tokens.T_EVAL:
          this.next().expect('(').next();
          var expr = this.read_expr();
          this.expect(')').next();
          return ['sys', 'eval', expr];

        case tokens.T_INT_CAST:
          return ['cast', 'int', this.next().read_expr()];

        case tokens.T_DOUBLE_CAST:
          return ['cast', 'double', this.next().read_expr()];

        case tokens.T_STRING_CAST:
          return ['cast', 'string', this.next().read_expr()];

        case tokens.T_ARRAY_CAST:
          return ['cast', 'array', this.next().read_expr()];

        case tokens.T_OBJECT_CAST:
          return ['cast', 'object', this.next().read_expr()];

        case tokens.T_BOOL_CAST:
          return ['cast', 'boolean', this.next().read_expr()];

        case tokens.T_UNSET_CAST:
          return ['sys', 'unset', this.next().read_expr()];

        case tokens.T_EXIT:
          var expr = null;
          if ( this.next().token === '(' ) {
            if (this.next().token !== ')') {
              expr = this.read_expr();
              this.expect(')').next();
            } else {
              this.next();
            }
          }
          return ['sys', 'exit', expr];

        case tokens.T_PRINT:
          return ['sys', 'print', this.next().read_expr()];

        case tokens.T_YIELD:
          var result = ['yield', null, null];
          if (this.next().is('expr')) {
            // reads the yield return value
            result[1] = this.read_expr();
            if (this.token === tokens.T_DOUBLE_ARROW) {
              // reads the yield returned key
              result[2] = this.read_expr();
            }
          }
          return result;

        case tokens.T_FUNCTION:
          // @fixme later - removed static lambda function declarations (colides with static keyword usage)
          return this.read_function(true);

      }

      // SCALAR | VARIABLE
      var expr;
      if (this.is('VARIABLE')) {
        expr = this.read_variable();
        // VARIABLES SPECIFIC OPERATIONS
        switch(this.token) {
          case '=':
            if (this.next().token == '&') {
              if (this.next().token === tokens.T_NEW) {
                return ['link', expr, this.next().read_new_expr()];
              } else {
                return ['link', expr, this.read_variable()];
              }
            } else {
              return [
                'set',
                expr,
                this.token === tokens.T_NEW ?
                  this.next().read_new_expr() : this.read_expr()
              ];
            }
          // operations :
          case tokens.T_PLUS_EQUAL:
            return ['set', expr, ['bin', '+', expr, this.next().read_expr()]];
          case tokens.T_MINUS_EQUAL:
            return ['set', expr, ['bin', '-', expr, this.next().read_expr()]];
          case tokens.T_MUL_EQUAL:
            return ['set', expr, ['bin', '*', expr, this.next().read_expr()]];
          case tokens.T_POW_EQUAL:
            return ['set', expr, ['bin', '**', expr, this.next().read_expr()]];
          case tokens.T_DIV_EQUAL:
            return ['set', expr, ['bin', '/', expr, this.next().read_expr()]];
          case tokens.T_CONCAT_EQUAL:
            // NB : convert as string and add
            return ['set', expr, ['bin', '.', expr, this.next().read_expr()]];
          case tokens.T_MOD_EQUAL:
            return ['set', expr, ['bin', '%', expr, this.next().read_expr()]];
          case tokens.T_AND_EQUAL:
            return ['set', expr, ['bin', '&', expr, this.next().read_expr()]];
          case tokens.T_OR_EQUAL:
            return ['set', expr, ['bin', '|', expr, this.next().read_expr()]];
          case tokens.T_XOR_EQUAL:
            return ['set', expr, ['bin', '^', expr, this.next().read_expr()]];
          case tokens.T_SL_EQUAL:
            return ['set', expr, ['bin', '<<', expr, this.next().read_expr()]];
          case tokens.T_SR_EQUAL:
            return ['set', expr, ['bin', '>>', expr, this.next().read_expr()]];
          case tokens.T_INC:
            this.next();
            return ['post', '+', expr];
          case tokens.T_DEC:
            this.next();
            return ['post', '-', expr];
        }
      } else if (this.is('SCALAR')) {
        expr = this.read_scalar();
      } else {
        this.error('EXPR');
      }

      // returns variable | scalar
      return expr;

    }
    /**
     * <ebnf>
     *    new_expr ::= T_NEW namespace_name function_argument_list
     * </ebnf>
     */
    ,read_new_expr: function() {
      var name = this.read_class_name_reference();
      var args = [];
      if (this.token === '(') {
        args = this.read_function_argument_list();
      }
      return ['new', name, args];
    }
    /**
     * Reads a class name
     * <ebnf>
     * class_name_reference ::= namespace_name | variable
     * </ebnf>
     */
    ,read_class_name_reference: function() {
      if (this.token === '\\' || this.token === tokens.T_STRING) {
        return this.read_namespace_name();
      } else if (this.is('VARIABLE')) {
        return this.read_variable(true);
      } else {
        this.expect([T_STRING, 'VARIABLE']);
      }
    }
    /**
     * <ebnf>
     *   assignment_list ::= assignment_list_element (',' assignment_list_element?)*
     * </ebnf>
     */
    ,read_assignment_list: function(innerList) {
      return this.read_list(
        this.read_assignment_list_element, ','
      );
    }
    /**
     * <ebnf>
     *  assignment_list_element ::= (variable | (T_LIST '(' assignment_list ')'))?
     * </ebnf>
     */
    ,read_assignment_list_element: function() {
      var result = null;
      if (this.token === tokens.T_LIST) {
        result = [
          'list',
          this.next().expect('(').next().read_assignment_list(),
          false
        ];
        this.expect(')').next();
      } else if (this.token !== ',') {
        result = this.read_variable();
      }
      return result;
    }
  };
};<|endoftext|>


<commit_before>var Template = require('./templates/seqpeek');
var LineItemTemplate = require("./templates/line_item");

module.exports = Backbone.View.extend({
    className: "row-fluid",
    cancers: [],
    current_subtypes: [],
    hideSelector: false,

    initialize: function (options) {
        _.extend(this, options);
        _.bindAll(this, 'initControls', 'initTypeahead', 'initGraph', 'initCancerSelector');
        _.bindAll(this, 'resetSliders', 'updateGraph', 'reloadModel');

        this.reloadModel = _.throttle(this.reloadModel, 1000);

        $.ajax({ url:"svc/data/lookups/genes", type:"GET", dataType:"text", success:this.initTypeahead });

        if (!this.hideSelector) {
            $.ajax({ url:"svc/data/lookups/cancers", type:"GET", dataType:"text", success:this.initCancerSelector });
        }

        if (this.genes) {
            this.current_gene = this.genes[0];
        }

        this.model.on("load", this.initGraph);

        this.$el.html(Template({ "title": this.current_gene }));

        this.initControls();
    },

    initControls: function () {
        this.$el.find(".slider_scale_width").range_slider_control({ storageId: "slider_scale_width", min: 1000, max: 3000, initialStep: 1500 });
        this.$el.find(".slider_label_width").range_slider_control({ storageId: "slider_label_width", min: 20, max: 200, initialStep: 70 });

        var lastLabelWidth = 70;
        this.$el.find(".slider_label_width").bind("slide-to", function (event, value) {
            lastLabelWidth = value;
        });
    },

    initCancerSelector: function(txt) {
        var cancers = txt.trim().split("\n");

        var selected_cancers = this.cancers;
        _.each(cancers, function(cancer) {
            cancer = cancer.trim();
            if (selected_cancers.indexOf(cancer)) {
                $(".cancer-selector").append(LineItemTemplate({"li_class":"active","a_class":"toggle-active","id":cancer,"label":cancer}));
            } else {
                $(".cancer-selector").append(LineItemTemplate({"a_class":"toggle-active","id":cancer,"label":cancer}));
            }
        });
        $(".cancer-selector").sortable();

        var _this = this;
        $(".cancer-selector").find(".toggle-active").click(function(e) {
            $(e.target).parent().toggleClass("active");
            _this.current_subtypes = $(this).find("li.active a").data("id");
            _.defer(_this.reloadModel);
        });
    },

    initTypeahead:function(txt) {
        var genelist = txt.trim().split("\n");

        var _this = this;
        this.$el.find(".genes-typeahead").typeahead({
            source:function (q, p) {
                p(_.compact(_.flatten(_.map(q.toLowerCase().split(" "), function (qi) {
                    return _.map(genelist, function (geneitem) {
                        if (geneitem.toLowerCase().indexOf(qi) >= 0) return geneitem;
                    });
                }))));
            },
            updater: function(txt) {
                if (_.isEqual(_this.current_gene, txt)) {
                    return _this.current_gene;
                }

                _this.current_gene = txt;
                _this.$el.find(".gene-title").html(_this.current_gene);
                _.defer(_this.reloadModel);
                return "";
            }
        });
    },

    resetSliders: function () {
        this.$el.find(".slider_scale_width").range_slider_control("reset");
        this.$el.find(".slider_label_width").range_slider_control("reset");
    },

    reloadModel: function() {
        if (_.isEmpty(this.current_gene)) return;

        if (_.isEmpty(this.current_subtypes)) {
            this.current_subtypes = _.compact(_.map(this.$el.find(".cancer-selector li.active a"), function(lia) {
                return $(lia).data("id");
            }));
        }

        var mutModel = this.model;
        mutModel.fetch({
            "data": {
                "gene": this.current_gene,
                "cancer": this.current_subtypes
            },
            "traditional": true,
            success: function() {
                mutModel.trigger("load");
            }
        });
    },

    initGraph: function () {
        if (!this.current_gene) {
            return;
        }

        var data = this.model.get("data");

        // Hide protein scale and domains in all but the last subtype
        _.chain(data.cancer_subtypes)
            .initial()
            .each(function(subtype) {
                subtype.layout = {
                    protein_scale_line: {
                        enabled: true,
                        y: 0
                    },
                    protein_scale_ticks: {
                        enabled: false,
                        y: 0
                    },
                    protein_domains: {
                        enabled: false
                    }
                };
            });

        var options = {
            location_tick_height: 25,
            protein_scale_width: 1000,
            protein_scale_y: 40,
            protein_vertical_padding: 10,
            signature_height: 10,
            enable_transitions: true,
            enable_mutation_stems: true,
            mutation_layout: 'all_subtypes',
            mutation_stem_height: 15,
            mutation_stem_stroke_width: 0.5,
            mutation_shape_width: 2,
            mutation_group_padding: 0,
            mutation_colors: {
                Nonsense_Mutation: 'red',
                Silent: 'green',
                Frame_Shift_Del: 'gold',
                Frame_Shift_Ins: 'gold',
                Missense_Mutation: 'blue'
            },
            plot: {
                horizontal_padding: 30,
                vertical_padding: 30
            },

            // initial values based on slider defaults
            scale_width: this.$el.find(".slider_scale_width").range_slider_control("value"),
            band_label_width: this.$el.find(".slider_label_width").range_slider_control("value")
        };

        this.$el.find(".seqpeek-container").seqpeek(data, options);
    },

    updateGraph: function() {
        var data = this.model.get("data");

        this.initGraph();

        var postProcessFn = function(subtypes) {
            _.chain(subtypes)
                .initial()
                .each(function(s) {
                    s.layout = {
                        protein_scale_line: {
                            enabled: true,
                            y: 0
                        },
                        protein_scale_ticks: {
                            enabled: false,
                            y: 0
                        },
                        protein_domains: {
                            enabled: false
                        }
                    };
                });

            _.last(subtypes).layout = {
                protein_scale_line: {
                    enabled: true,
                    y: 0
                },
                protein_scale_ticks: {
                    enabled: true,
                    y: 0
                },
                protein_domains: {
                    enabled: true
                }
            }
        };

        this.$el.find(".seqpeek-container").seqpeek('change_subtypes', data.cancer_subtypes, {
            "subtype_order": this.current_subtypes,
            "post_process_fn": postProcessFn
        });
    }

});
<commit_msg>Removed unnecessary code<commit_after>var Template = require('./templates/seqpeek');
var LineItemTemplate = require("./templates/line_item");

module.exports = Backbone.View.extend({
    cancers: [],
    current_subtypes: [],
    hideSelector: false,

    initialize: function (options) {
        _.extend(this, options);
        _.bindAll(this, 'initControls', 'initGraph', 'initCancerSelector');
        _.bindAll(this, 'updateGraph', 'reloadModel');

        this.reloadModel = _.throttle(this.reloadModel, 1000);

        if (!this.hideSelector) {
            $.ajax({ url:"svc/data/lookups/cancers", type:"GET", dataType:"text", success:this.initCancerSelector });
        }

        if (this.genes) {
            this.current_gene = this.genes[0];
        }

        this.model.on("load", this.initGraph);

        this.$el.html(Template({ "title": this.current_gene }));

        this.initControls();
    },

    initControls: function () {

    },

    initCancerSelector: function(txt) {
        var cancers = txt.trim().split("\n");

        var selected_cancers = this.cancers;
        _.each(cancers, function(cancer) {
            cancer = cancer.trim();
            if (selected_cancers.indexOf(cancer)) {
                $(".cancer-selector").append(LineItemTemplate({"li_class":"active","a_class":"toggle-active","id":cancer,"label":cancer}));
            } else {
                $(".cancer-selector").append(LineItemTemplate({"a_class":"toggle-active","id":cancer,"label":cancer}));
            }
        });
        $(".cancer-selector").sortable();

        var _this = this;
        $(".cancer-selector").find(".toggle-active").click(function(e) {
            $(e.target).parent().toggleClass("active");
            _this.current_subtypes = $(this).find("li.active a").data("id");
            _.defer(_this.reloadModel);
        });
    },

    reloadModel: function() {
        if (_.isEmpty(this.current_gene)) return;

        if (_.isEmpty(this.current_subtypes)) {
            this.current_subtypes = _.compact(_.map(this.$el.find(".cancer-selector li.active a"), function(lia) {
                return $(lia).data("id");
            }));
        }

        var mutModel = this.model;
        mutModel.fetch({
            "data": {
                "gene": this.current_gene,
                "cancer": this.current_subtypes
            },
            "traditional": true,
            success: function() {
                mutModel.trigger("load");
            }
        });
    },

    initGraph: function () {
        if (!this.current_gene) {
            return;
        }

        var data = this.model.get("data");

        // Hide protein scale and domains in all but the last subtype
        _.chain(data.cancer_subtypes)
            .initial()
            .each(function(subtype) {
                subtype.layout = {
                    protein_scale_line: {
                        enabled: true,
                        y: 0
                    },
                    protein_scale_ticks: {
                        enabled: false,
                        y: 0
                    },
                    protein_domains: {
                        enabled: false
                    }
                };
            });

        var options = {
            location_tick_height: 25,
            protein_scale_width: 1000,
            protein_scale_y: 40,
            protein_vertical_padding: 10,
            signature_height: 10,
            enable_transitions: true,
            enable_mutation_stems: true,
            mutation_layout: 'all_subtypes',
            mutation_stem_height: 15,
            mutation_stem_stroke_width: 0.5,
            mutation_shape_width: 2,
            mutation_group_padding: 0,
            mutation_colors: {
                Nonsense_Mutation: 'red',
                Silent: 'green',
                Frame_Shift_Del: 'gold',
                Frame_Shift_Ins: 'gold',
                Missense_Mutation: 'blue'
            },
            plot: {
                horizontal_padding: 30,
                vertical_padding: 30
            },
            band_label_width: 100
        };

        this.$el.find(".seqpeek-container").seqpeek(data, options);
    },

    updateGraph: function() {
        var data = this.model.get("data");

        this.initGraph();

        var postProcessFn = function(subtypes) {
            _.chain(subtypes)
                .initial()
                .each(function(s) {
                    s.layout = {
                        protein_scale_line: {
                            enabled: true,
                            y: 0
                        },
                        protein_scale_ticks: {
                            enabled: false,
                            y: 0
                        },
                        protein_domains: {
                            enabled: false
                        }
                    };
                });

            _.last(subtypes).layout = {
                protein_scale_line: {
                    enabled: true,
                    y: 0
                },
                protein_scale_ticks: {
                    enabled: true,
                    y: 0
                },
                protein_domains: {
                    enabled: true
                }
            }
        };

        this.$el.find(".seqpeek-container").seqpeek('change_subtypes', data.cancer_subtypes, {
            "subtype_order": this.current_subtypes,
            "post_process_fn": postProcessFn
        });
    }

});
<|endoftext|>


<commit_before>// namespace
var App = App || {};

App.HUD = (function () {
    "use strict";

    var fn = function (game) {
        this.game = game;
    };

    fn.prototype.drawBar = function (x, y, maxHealth, healthbarType, opacity) {
        this.left = this.game.add.sprite(x, y, healthbarType + 'Left');
        this.left.fixedToCamera = true;
        this.left.alpha = opacity;
        this.group.add(this.left);

        var midXPos = x + this.left.width;
        this.mid = this.game.add.sprite(midXPos, y, healthbarType + 'Mid');
        this.mid.fixedToCamera = true;
        this.mid.alpha = opacity;
        this.mid.width = maxHealth;
        this.group.add(this.mid);

        var rightXPos = x + this.mid.width + this.left.width;
        this.right = this.game.add.sprite(rightXPos, y, healthbarType + 'Right');
        this.right.fixedToCamera = true;
        this.right.alpha = opacity;
        this.group.add(this.right);
    };

    fn.prototype.loadAssets = function () {
        this.game.load.image('healthbarBgLeft', 'assets/images/hud_elements/barHorizontal_shadow_left.png');
        this.game.load.image('healthbarBgMid', 'assets/images/hud_elements/barHorizontal_shadow_mid.png');
        this.game.load.image('healthbarBgRight', 'assets/images/hud_elements/barHorizontal_shadow_right.png');
        this.game.load.image('healthbarGreenLeft', 'assets/images/hud_elements/barHorizontal_green_left.png');
        this.game.load.image('healthbarGreenMid', 'assets/images/hud_elements/barHorizontal_green_mid.png');
        this.game.load.image('healthbarGreenRight', 'assets/images/hud_elements/barHorizontal_green_right.png');
        this.game.load.image('healthbarYellowLeft', 'assets/images/hud_elements/barHorizontal_yellow_left.png');
        this.game.load.image('healthbarYellowMid', 'assets/images/hud_elements/barHorizontal_yellow_mid.png');
        this.game.load.image('healthbarYellowRight', 'assets/images/hud_elements/barHorizontal_yellow_right.png');
    };

    fn.prototype.displayHUD = function () {
        this.group = this.game.add.group();

        var x_pos = 5;
        var y_pos = 5;
        var MAX_HEALTH = 400;

        // draws the health bar
        this.drawBar(x_pos, y_pos, MAX_HEALTH, 'healthbarBg', 1);
        this.drawBar(x_pos, y_pos, MAX_HEALTH, 'healthbarGreen', 0.5);

        // draws the shield bar
        this.drawBar(x_pos, y_pos + 30, MAX_HEALTH, 'healthbarBg', 1);
        this.drawBar(x_pos, y_pos + 30, MAX_HEALTH, 'healthbarYellow', 0.5);
    };

    return fn;
})();
<commit_msg>now pulling the max health and max energy from the player object<commit_after>// namespace
var App = App || {};

App.HUD = (function () {
    "use strict";

    var fn = function (game) {
        this.game = game;
        this.player = this.game.global.player;
    };

    fn.prototype.drawBar = function (x, y, maxHealth, healthbarType, opacity) {
        this.left = this.game.add.sprite(x, y, healthbarType + 'Left');
        this.left.fixedToCamera = true;
        this.left.alpha = opacity;
        this.group.add(this.left);

        var midXPos = x + this.left.width;
        this.mid = this.game.add.sprite(midXPos, y, healthbarType + 'Mid');
        this.mid.fixedToCamera = true;
        this.mid.alpha = opacity;
        this.mid.width = maxHealth;
        this.group.add(this.mid);

        var rightXPos = x + this.mid.width + this.left.width;
        this.right = this.game.add.sprite(rightXPos, y, healthbarType + 'Right');
        this.right.fixedToCamera = true;
        this.right.alpha = opacity;
        this.group.add(this.right);
    };

    fn.prototype.loadAssets = function () {
        this.game.load.image('healthbarBgLeft', 'assets/images/hud_elements/barHorizontal_shadow_left.png');
        this.game.load.image('healthbarBgMid', 'assets/images/hud_elements/barHorizontal_shadow_mid.png');
        this.game.load.image('healthbarBgRight', 'assets/images/hud_elements/barHorizontal_shadow_right.png');
        this.game.load.image('healthbarGreenLeft', 'assets/images/hud_elements/barHorizontal_green_left.png');
        this.game.load.image('healthbarGreenMid', 'assets/images/hud_elements/barHorizontal_green_mid.png');
        this.game.load.image('healthbarGreenRight', 'assets/images/hud_elements/barHorizontal_green_right.png');
        this.game.load.image('healthbarYellowLeft', 'assets/images/hud_elements/barHorizontal_yellow_left.png');
        this.game.load.image('healthbarYellowMid', 'assets/images/hud_elements/barHorizontal_yellow_mid.png');
        this.game.load.image('healthbarYellowRight', 'assets/images/hud_elements/barHorizontal_yellow_right.png');
    };

    fn.prototype.displayHUD = function () {
        this.group = this.game.add.group();

        var x_pos = 5;
        var y_pos = 5;
        var MAX_HEALTH = this.player.getHullHealth();
        var MAX_ENERGY = this.player.getHullEnergy();

        // draws the health bar
        this.drawBar(x_pos, y_pos, MAX_HEALTH, 'healthbarBg', 1);
        this.drawBar(x_pos, y_pos, MAX_HEALTH, 'healthbarGreen', 0.5);

        // draws the shield bar
        this.drawBar(x_pos, y_pos + 30, MAX_ENERGY, 'healthbarBg', 1);
        this.drawBar(x_pos, y_pos + 30, MAX_ENERGY, 'healthbarYellow', 0.5);
    };

    return fn;
})();
<|endoftext|>