# The global namespace, the `Batman` function will also create also create a new
# instance of Batman.Object and mixin all arguments to it.
Batman = (mixins...) ->
  new Batman.Object(mixins...)

Batman.version = '0.14.1'

Batman.config =
  pathToApp: '/'
  usePushState: true

  pathToHTML: 'html'
  fetchRemoteHTML: true
  cacheViews: false

  minificationErrors: true
  protectFromCSRF: false

(Batman.container = do -> this).Batman = Batman  # I am so, so sorry.

# Support AMD loaders
if typeof define is 'function'
  define 'batman', [], -> Batman

Batman.exportHelpers = (onto) ->
  for k in ['mixin', 'extend', 'unmixin', 'redirect', 'typeOf', 'redirect', 'setImmediate', 'clearImmediate']
    onto["$#{k}"] = Batman[k]
  onto

Batman.exportGlobals = -> Batman.exportHelpers(Batman.container)

# The global namespace, the `Batman` function will also create a new
# instance of Batman.Object and mixin all arguments to it.
Batman = (mixins...) ->
  new Batman.Object(mixins...)

Batman.version = '0.14.1'

Batman.config =
  pathToApp: '/'
  usePushState: true

  pathToHTML: 'html'
  fetchRemoteHTML: true
  cacheViews: false

  minificationErrors: true
  protectFromCSRF: false

(Batman.container = do -> this).Batman = Batman  # I am so, so sorry.

# Support AMD loaders
if typeof define is 'function'
  define 'batman', [], -> Batman

Batman.exportHelpers = (onto) ->
  for k in ['mixin', 'extend', 'unmixin', 'redirect', 'typeOf', 'redirect', 'setImmediate', 'clearImmediate']
    onto["$#{k}"] = Batman[k]
  onto

Batman.exportGlobals = -> Batman.exportHelpers(Batman.container)

Fix a typo the file description

Fix a typo the file description


React = require 'react'

module.exports = React.createClass
  displayName: 'ChooseSubjectSet'

  getInitialState: ->
    subject_sets: []

  componentWillMount: ->
    @props.workflow?.get 'subject_sets', page_size: 40
      .then (subject_sets) =>
        subject_sets.sort (a, b) ->
          return 1 if a.metadata.BOROUGH > b.metadata.BOROUGH
          return -1 if a.metadata.BOROUGH  b.metadata['File prefix']
          return -1 if a.metadata['File prefix']

Choose a report to work on

        {
{subject_set.display_name}
{subject_set.metadata.BOROUGH.replace(' (London, England)', '')}
{subject_set.metadata.Date}
 for subject_set in @state.subject_sets}

  update: (e) ->
    subject_set_id = e.currentTarget.href.split('/').pop()
    @props.onChange subject_set_id

React = require 'react'

module.exports = React.createClass
  displayName: 'ChooseSubjectSet'

  getInitialState: ->
    subject_sets: []

  componentWillMount: ->
    @props.workflow?.get 'subject_sets', page_size: 40
      .then (subject_sets) =>
        subject_sets.sort (a, b) ->
          return 1 if a.metadata.BOROUGH > b.metadata.BOROUGH
          return -1 if a.metadata.BOROUGH  b.metadata['File prefix']
          return -1 if a.metadata['File prefix']

Choose a report to work on

        {
{subject_set.metadata.BOROUGH.replace(' (London, England)', '')}
{subject_set.metadata.Date}
 for subject_set in @state.subject_sets}

  update: (e) ->
    subject_set_id = e.currentTarget.href.split('/').pop()
    @props.onChange subject_set_id

Remove the report ID from the Reports page


kd = require 'kd'
KDCustomHTMLView = kd.CustomHTMLView
KodingSwitch = require 'app/commonviews/kodingswitch'
CustomLinkView = require 'app/customlinkview'
module.exports = class IDEChatHeadWatchItemView extends KDCustomHTMLView

  constructor: (options = {}, data) ->

    options.partial = 'Watch'

    super options, data

    { isWatching, nickname } = @getOptions()

    @addSubView @toggle = new KodingSwitch
      cssClass     : 'tiny'
      defaultValue : isWatching
      callback     : (state) =>
        @getDelegate().setWatchState state, nickname

    @addSubView @info = new CustomLinkView
      title        : ''
      cssClass     : 'info'
      href         : 'http://learn.koding.com/guides/collaboration/#what-does-quot-watch-quot-mode-mean-'
      target       : '_blank'

kd = require 'kd'
KDCustomHTMLView = kd.CustomHTMLView
KodingSwitch = require 'app/commonviews/kodingswitch'
CustomLinkView = require 'app/customlinkview'
module.exports = class IDEChatHeadWatchItemView extends KDCustomHTMLView

  constructor: (options = {}, data) ->

    options.partial ?= 'Watch'

    super options, data

    { isWatching, nickname } = @getOptions()

    @addSubView @toggle = new KodingSwitch
      cssClass     : 'tiny'
      defaultValue : isWatching
      callback     : (state) =>
        @getDelegate().setWatchState state, nickname

    @addSubView @info = new CustomLinkView
      title        : ''
      cssClass     : 'info'
      href         : 'http://learn.koding.com/guides/collaboration/#what-does-quot-watch-quot-mode-mean-'
      target       : '_blank'

Set partial option as default value

Set partial option as default value


{DOMParser} = require 'xmldom'
xpath = require 'xpath'
request = require 'request'

module.exports =
  getTransactions: (cik, type, callback) ->
    baseUrl = process.env.SEC_EDGAR_URL ? 'http://www.sec.gov/cgi-bin/browse-edgar'
    url = "#{baseUrl}?action=getcompany&output=atom&start=0&count=1000&CIK=#{cik}&type=#{type}"

    request url, (error, response, body) ->
      if error?
        callback(error)
      else
        dom = new DOMParser().parseFromString(body)
        cik = parseInt(xpath.select('/feed/company-info/cik/text()', dom))
        transactions = []
        for transaction in xpath.select('//entry/content', dom)
          filingDate = xpath.select('filing-date/text()', transaction).toString()
          date = new Date("#{filingDate} 14:30:00 GMT")
          accessionNumber = xpath.select('accession-nunber/text()', transaction).toString()
          id = accessionNumber.replace(/-/g, '')
          type = xpath.select('filing-type/text()', transaction).toString()
          transactions.push({date, cik, id, type})
        callback(null, transactions)

{DOMParser} = require 'xmldom'
xpath = require 'xpath'
request = require 'request'

module.exports =
  getTransactions: (cik, type, callback) ->
    baseUrl = process.env.SEC_EDGAR_URL ? 'http://www.sec.gov/cgi-bin/browse-edgar'
    url = "#{baseUrl}?action=getcompany&output=atom&start=0&count=1000&CIK=#{cik}&type=#{type}"
    url = "#{url}&owner=only"if parseInt(type) is 4

    request url, (error, response, body) ->
      if error?
        callback(error)
      else
        dom = new DOMParser().parseFromString(body)
        cik = parseInt(xpath.select('/feed/company-info/cik/text()', dom))
        transactions = []
        for transaction in xpath.select('//entry/content', dom)
          filingDate = xpath.select('filing-date/text()', transaction).toString()
          date = new Date("#{filingDate} 14:30:00 GMT")
          accessionNumber = xpath.select('accession-nunber/text()', transaction).toString()
          id = accessionNumber.replace(/-/g, '')
          type = xpath.select('filing-type/text()', transaction).toString()
          transactions.push({date, cik, id, type})
        callback(null, transactions)

Set owner=only on form 4 requests

Set owner=only on form 4 requests


noflo = require "noflo"

class Output extends noflo.Component

    description: "This component receives input on a single inport, and sends the data items directly to console.log"

    constructor: ->
        @inPorts =
            in: new noflo.ArrayPort()

        @outPorts = {}

        @inPorts.in.on "data", (data) ->
            console.log data

exports.getComponent = ->
    new Output()

noflo = require "noflo"
util = require "util"

class Output extends noflo.Component

    description: "This component receives input on a single inport, and sends the data items directly to console.log"

    constructor: ->
        @options =
            showHidden: false
            depth: 2
            colors: false

        @inPorts =
            in: new noflo.ArrayPort()
            options: new noflo.Port()

        @outPorts = {}

        @inPorts.in.on "data", (data) =>
            @log data

        @inPorts.options.on "data", (data) =>
            @setOptions data

    setOptions: (options) ->
        throw "Options is not an object" unless typeof options is "object"
        for own key, value of options
            @options[key] = value

    log: (data) ->
        console.log util.inspect data,
            @options.showHidden, @options.depth, @options.colors

exports.getComponent = ->
    new Output()

Add ability to set output display options.


# See https://atom.io/docs/latest/creating-a-package#menus for more details
'context-menu':
  '.conflicted':
    'Resolve: Current': 'merge-conflicts:accept-current'
    'Resolve: Ours': 'merge-conflicts:accept-ours'
    'Resolve: Theirs': 'merge-conflicts:accept-theirs'
    'Resolve: Ours Then Theirs': 'merge-conflicts:ours-then-theirs'
    'Resolve: Theirs Then Ours': 'merge-conflicts:theirs-then-ours'
  '.merge-conflicts .navigate':
    'Resolve: Entire File Ours': 'merge-conflicts:entire-file-ours'
    'Resolve: Entire File Theirs': 'merge-conflicts:entire-file-theirs'

'menu': [
  {
    'label': 'Packages'
    'submenu': [
      'label': 'Merge Conflicts'
      'submenu': [
        { 'label': 'Detect', 'command': 'merge-conflicts:detect' }
      ]
    ]
  }
]

# See https://atom.io/docs/latest/creating-a-package#menus for more details
'context-menu':
  'atom-text-editor': [{
    label: 'Resolve Conflict',
    submenu: [
      { label: 'Current', command: 'merge-conflicts:accept-current' }
      { label: 'Ours', command: 'merge-conflicts:accept-ours' }
      { label: 'Theirs', command: 'merge-conflicts:accept-theirs' }
      { label: 'Ours Then Theirs', command: 'merge-conflicts:ours-then-theirs' }
      { label: 'Theirs Then Ours', command: 'merge-conflicts:theirs-then-ours' }
    ]
  }]
  '.merge-conflicts .navigate': [
    { label: 'Resolve Entire File Ours', command: 'merge-conflicts:entire-file-ours' }
    { label: 'Resolve Entire File Theirs', command: 'merge-conflicts:entire-file-theirs' }
  ]

'menu': [{
  label: 'Packages'
  submenu: [
    label: 'Merge Conflicts',
    submenu: [{ label: 'Detect', command: 'merge-conflicts:detect' }]
  ]
}]

Rework the context menu entries.

Rework the context menu entries.


Steam.FrameListView = (_) ->
  _items = do nodes$

  activate = (item) ->
    for other in _items()
      if other is item
        other.isActive yes
      else
        other.isActive no

    _.displayFrame item.data

    return

  createItem = (frame) ->
    #TODO replace with type checking
    console.assert isArray frame.column_names
    self =
      data: frame
      title: frame.key
      caption: describeCount frame.column_names.length, 'column'
      cutline: join frame.column_names, ', '
      display: -> activate self
      isActive: node$ no

  displayFrames = (frames) ->
    _items items = map frames, createItem
    activate head items unless isEmpty items

  loadFrames = (opts) ->
    console.assert isDefined opts
    switch opts.type
      when 'all'
        _.requestFrames (error, data) ->
          if error
            #TODO handle errors
          else
            displayFrames data.frames
      when 'compatibleWithModel'
        _.requestModelAndCompatibleFrames opts.modelKey, (error, data) ->
          if error
            #TODO handle errors
          else
            displayFrames (head data.models).compatible_frames
    return

  link$ _.loadFrames, loadFrames

  items: _items
  template: 'frame-list-view'

Steam.FrameListView = (_) ->
  _predicate = node$ type: 'all'
  _items = do nodes$
  _hasItems = lift$ _items, (items) -> items.length > 0

  _canClearPredicate = lift$ _predicate, (predicate) -> predicate.type isnt 'all'
  _predicateCaption = lift$ _predicate, (predicate) ->
    switch predicate.type
      when 'all'
        'Showing\nall frames'
      when 'compatibleWithModel'
        "Showing frames compatible with\n#{predicate.modelKey}"
      else
        ''

  activateItem = (item) ->
    for other in _items()
      if other is item
        other.isActive yes
      else
        other.isActive no

    _.displayFrame item.data

    return

  createItem = (frame) ->
    #TODO replace with type checking
    console.assert isArray frame.column_names
    self =
      data: frame
      title: frame.key
      caption: describeCount frame.column_names.length, 'column'
      cutline: join frame.column_names, ', '
      display: -> activateItem self
      isActive: node$ no

  displayFrames = (frames) ->
    _items items = map frames, createItem
    if isEmpty items
      _.displayEmpty()
    else
      activateItem head items

  apply$ _predicate, (predicate) ->
    console.assert isDefined predicate
    switch predicate.type
      when 'all'
        _.requestFrames (error, data) ->
          if error
            #TODO handle errors
          else
            displayFrames data.frames

      when 'compatibleWithModel'
        _.requestModelAndCompatibleFrames predicate.modelKey, (error, data) ->
          if error
            #TODO handle errors
          else
            displayFrames (head data.models).compatible_frames
    return

  clearPredicate = -> _predicate type: 'all'

  link$ _.loadFrames, _predicate

  items: _items
  predicateCaption: _predicateCaption
  clearPredicate: clearPredicate
  canClearPredicate: _canClearPredicate
  hasItems: _hasItems
  template: 'frame-list-view'

Add filter widget to frames list. PP-8

Add filter widget to frames list.
PP-8


if Meteor.isServer
  CuratorSources = require './curatorSources.coffee'

  PromedPosts = null
  try
    # spaDb = new MongoInternals.RemoteCollectionDriver(process.env.SPA_MONGO_URL)
    # PromedPosts = new Meteor.Collection("posts", { _driver: spaDb })
    PromedPosts = new Meteor.Collection("posts")
  catch e
    console.warn 'Unable to connect to remote SPA mongodb.'

  module.exports = PromedPosts

if Meteor.isServer
  CuratorSources = require './curatorSources.coffee'

  PromedPosts = null
  try
    spaDb = new MongoInternals.RemoteCollectionDriver(process.env.SPA_MONGO_URL)
    PromedPosts = new Meteor.Collection("posts", { _driver: spaDb })
  catch e
    console.warn 'Unable to connect to remote SPA mongodb.'

  module.exports = PromedPosts

Use SPA_MONGO_URL env. variable for remote mongodb.


position_footer = ->
  mFoo = $('#footer')
  if $(document.body).height() + mFoo.outerHeight() < $(window).height() and mFoo.css('position') == 'fixed' or $(document.body).height() < $(window).height() and mFoo.css('position') != 'fixed'
    mFoo.css
      position: 'fixed'
      bottom: '0'
  else
    mFoo.css position: 'relative'
  return

$(document).on 'ready page:load page:restore', ->
  $(window).scroll position_footer
  $(window).resize position_footer

  sleep 30
  $(window).resize()
  return

position_footer = ->
  mFoo = $('#footer')
  if $(document.body).height() + mFoo.outerHeight() < $(window).height() and mFoo.css('position') == 'fixed' or $(document.body).height() < $(window).height() and mFoo.css('position') != 'fixed'
    mFoo.css
      position: 'fixed'
      bottom: '0'
  else
    mFoo.css position: 'relative'
  return

$(document).on 'ready page:load page:restore', ->
  position_footer
  $(window).scroll position_footer
  $(window).resize position_footer
  return

Revert changes made in sticky_footer as it's not working


class window.FactBottomView extends Backbone.Marionette.ItemView
  className: 'fact-bottom'

  template: 'facts/fact_bottom'

  events:
    "click .js-add-to-channel": "showAddToChannel"
    "click .js-start-conversation": "showStartConversation"
    "click .js-open-proxy-link" : "openProxyLink"
    "click .js-arguments-link": "openDiscussionModal"

  templateHelpers: ->
    formatted_time: ->
      if @friendly_time
        # this is relevant in a channel, a fact is then 'posted'
        # or reposted <time> ago
        "Posted #{@friendly_time} ago"
      else
        @created_by_ago

    believe_percentage: @model.opinionPercentage('believe')
    disbelieve_percentage: @model.opinionPercentage('disbelieve')

  showAddToChannel: (e) ->
    e.preventDefault()
    e.stopPropagation()

    FactlinkApp.ModalWindowContainer.show new AddToChannelModalWindowView(model: @model)

  showStartConversation: (e) ->
    e.preventDefault()
    e.stopPropagation()

    FactlinkApp.ModalWindowContainer.show new StartConversationModalWindowView(model: @model)

    mp_track "Factlink: Open share modal"

  openProxyLink: (e) ->
    mp_track "Factlink: Open proxy link",
      site_url: @model.get("fact_url")

  openDiscussionModal: (e) ->
    e.preventDefault()

    FactlinkApp.DiscussionModalOnFrontend.openDiscussion @model.clone()

class window.FactBottomView extends Backbone.Marionette.ItemView
  className: 'fact-bottom'

  template: 'facts/fact_bottom'

  events:
    "click .js-add-to-channel": "showAddToChannel"
    "click .js-start-conversation": "showStartConversation"
    "click .js-open-proxy-link" : "openProxyLink"
    "click .js-arguments-link": "openDiscussionModal"

  templateHelpers: ->
    formatted_time: ->
      if @friendly_time
        # this is relevant in a channel, a fact is then 'posted'
        # or reposted <time> ago
        "Posted #{@friendly_time} ago"
      else
        @created_by_ago

    believe_percentage: @model.opinionPercentage('believe')
    disbelieve_percentage: @model.opinionPercentage('disbelieve')

  showAddToChannel: (e) ->
    e.preventDefault()
    e.stopPropagation()

    FactlinkApp.ModalWindowContainer.show new AddToChannelModalWindowView(model: @model)

  showStartConversation: (e) ->
    e.preventDefault()
    e.stopPropagation()

    FactlinkApp.ModalWindowContainer.show new StartConversationModalWindowView(model: @model)

    mp_track "Factlink: Open share modal"

  openProxyLink: (e) ->
    mp_track "Factlink: Open proxy link",
      site_url: @model.get("fact_url")

  openDiscussionModal: (e) ->
    e.preventDefault()

    if e.metaKey or e.ctrlKey or e.altKey
      window.open @model.get('url'), "_blank"
    else
      FactlinkApp.DiscussionModalOnFrontend.openDiscussion @model.clone()

Handle function keys when clicking on a factrelation


ETahi.NewAdHocTaskOverlayView = ETahi.OverlayView.extend
  templateName: 'overlays/new_adhoc_task_overlay'
  layoutName: 'layouts/new_task_overlay_layout'

ETahi.NewAdHocTaskOverlayView = ETahi.OverlayView.extend
  templateName: 'overlays/new_ad_hoc_task_overlay'
  layoutName: 'layouts/new_task_overlay_layout'

Fix ad hoc template name

Fix ad hoc template name


if Meteor.isServer
	storeType = 'GridFS'

	if Meteor.settings?.public?.avatarStore?.type?
		storeType = Meteor.settings.public.avatarStore.type

	RocketStore = RocketFile[storeType]

	if not RocketStore?
		throw new Error "Invalid RocketStore type [#{storeType}]"

	transformWrite = undefined
	if Meteor.settings?.public?.avatarStore?.size?.height?
		height = Meteor.settings.public.avatarStore.size.height
		width = Meteor.settings.public.avatarStore.size.width
		transformWrite = (file, readStream, writeStream) ->
			RocketFile.gm(readStream, file.fileName).background('#ffffff').resize(width, height).gravity('Center').extent(width, height).stream('jpeg').pipe(writeStream)

	path = "~/uploads"

	if Meteor.settings?.public?.avatarStore?.path?
		path = Meteor.settings.public.avatarStore.path

	@RocketFileAvatarInstance = new RocketFile.GridFS
		name: 'avatars'
		absolutePath: path
		transformWrite: transformWrite

	HTTP.methods
		'/avatar/:username':
			'stream': true
			'get': (data) ->
				this.params.username
				file = RocketFileAvatarInstance.getFileWithReadStream this.params.username

				this.setContentType 'image/jpeg'
				this.addHeader 'Content-Disposition', 'inline'
				this.addHeader 'Content-Length', file.length

				file.readStream.pipe this.createWriteStream()
				return

if Meteor.isServer
	storeType = 'GridFS'

	if Meteor.settings?.public?.avatarStore?.type?
		storeType = Meteor.settings.public.avatarStore.type

	RocketStore = RocketFile[storeType]

	if not RocketStore?
		throw new Error "Invalid RocketStore type [#{storeType}]"

	console.log "Using #{storeType} for Avatar storage".green

	transformWrite = undefined
	if Meteor.settings?.public?.avatarStore?.size?.height?
		height = Meteor.settings.public.avatarStore.size.height
		width = Meteor.settings.public.avatarStore.size.width
		transformWrite = (file, readStream, writeStream) ->
			RocketFile.gm(readStream, file.fileName).background('#ffffff').resize(width, height).gravity('Center').extent(width, height).stream('jpeg').pipe(writeStream)

	path = "~/uploads"

	if Meteor.settings?.public?.avatarStore?.path?
		path = Meteor.settings.public.avatarStore.path

	@RocketFileAvatarInstance = new RocketStore
		name: 'avatars'
		absolutePath: path
		transformWrite: transformWrite

	HTTP.methods
		'/avatar/:username':
			'stream': true
			'get': (data) ->
				this.params.username
				file = RocketFileAvatarInstance.getFileWithReadStream this.params.username

				this.setContentType 'image/jpeg'
				this.addHeader 'Content-Disposition', 'inline'
				this.addHeader 'Content-Length', file.length

				file.readStream.pipe this.createWriteStream()
				return

Fix store reference and log which store is using


OptimistParser = require './optimist_parser'

commands =
  run: "Runs all tests found in /test"
  watch: "Runs all tests in /test and watches for changes"
  help: "Shows this help page"

usage_text = """
                Usage: mycha <command> [options]

                where <command> is one of:
                #{("  #{command_name} - #{command_desc}" for command_name, command_desc of commands).join("\n")}
              """

argv = require('optimist')
  .usage(usage_text)
  .check (argv) ->
    command = argv._[0]
    throw "Missing command." unless command?
    throw "\"#{command}\" is not a valid command." unless commands[command]?
    throw "" if command is 'help'
  .argv

Mycha = require __dirname + '/mycha'
mycha = new Mycha process.cwd()
if argv._[0] is 'run'
  optimist_parser = new OptimistParser argv
  mycha.run optimist_parser.options(),
            optimist_parser.files(),
            (exit_code) -> process.exit exit_code

OptimistParser = require './optimist_parser'

commands =
  run: "Runs all tests found in /test"
  watch: "Runs all tests in /test and watches for changes"
  help: "Shows this help page"

usage_text = """
                Usage: mycha <command> [options]

                where <command> is one of:
                #{("  #{command_name} - #{command_desc}" for command_name, command_desc of commands).join("\n")}
              """

argv = require('optimist')
  .usage(usage_text)
  .check (argv) ->
    command = argv._[0]
    throw "Missing command." unless command?
    throw "\"#{command}\" is not a valid command." unless commands[command]?
    throw "" if command is 'help'
  .argv

Mycha = require __dirname + '/mycha'
mycha = new Mycha process.cwd()
optimist_parser = new OptimistParser argv
if optimist_parser.command() is 'run'
  mycha.run optimist_parser.options(),
            optimist_parser.files(),
            (exit_code) -> process.exit exit_code

Use OptimistParser to determine the command


# FIXME - Move this in a seperate file ~ GG

class VmListItem extends KDListItemView

  click: ->
    @getDelegate().emit 'VMSelected', @getData()

  viewAppended: ->
    JView::viewAppended.call this

  pistachio: ->
    """

        #{@getData()}

    """

class VMSelection extends KDModalView

  constructor:(options={}, data)->

    super
      width           : 300
      title           : "Select VM"
      overlay         : yes
      # cssClass        : KD.utils.curry 'vm-selection', options.cssClass
      draggable       : no
      cancellable     : yes
      appendToDomBody : yes
      delegate        : options.delegate
    , data

    @listController   = new KDListViewController
      view            : new KDListView
        type          : "vm"
        cssClass      : "vm-list"
        itemClass     : VmListItem

  viewAppended:->
    # @unsetClass 'kdmodal'
    @addSubView view = @listController.getView()

    @listController.getListView().on 'VMSelected', (vm)=>
      @emit "VMSelected", vm
      @destroy()

    KD.singleton("vmController").fetchGroupVMs no, (err, vms) =>
      return  if KD.showError err
      @listController.instantiateListItems vms

# FIXME - Move this in a seperate file ~ GG

class VmListItem extends KDListItemView

  click: ->
    @getDelegate().emit 'VMSelected', @getData()

  viewAppended: ->
    JView::viewAppended.call this

  pistachio: ->
    """

        #{@getData()}

    """

class VMSelection extends KDModalView

  constructor:(options={}, data)->

    super
      width           : 300
      title           : "Select VM"
      overlay         : yes
      # cssClass        : KD.utils.curry 'vm-selection', options.cssClass
      draggable       : no
      cancellable     : yes
      appendToDomBody : yes
      delegate        : options.delegate
    , data

    @listController   = new KDListViewController
      view            : new KDListView
        type          : "vm"
        cssClass      : "vm-list"
        itemClass     : VmListItem

  viewAppended:->
    # @unsetClass 'kdmodal'
    @addSubView view = @listController.getView()

    @listController.getListView().on 'VMSelected', (vm)=>
      @emit "VMSelected", vm
      @destroy()

    @listController.instantiateListItems KD.getSingleton('vmController').vms

Revert "terminal: fetch account's group associated VMs in "VM selection" modal"

This reverts commit e0d8381d3efe193093c86cf6f23ee399c2e109f2.


'use strict'

app.factory('uploadService', [
  'routerService',
  (router) ->
    removedAsset: undefined

    # callbacks for ng-flow:

    fileSuccess: (file) ->
      file.store.progress = 1
      file.store.save()
      return

    fileError: (file, message, flow) ->
      file.abort()
      alert("There was an error uploading the file")

    fileProgress: (file) ->
      file.store.progress = file.progress()
      return

    flowOptions:
      target: router.controllers.AssetApi.uploadChunk().url
      method: 'octet'
      chunkSize: 4194304
      simultaneousUploads: 3
      testChunks: false
      chunkRetryInterval: 5000
      permanentErrors: [400, 403, 404, 409, 415, 500, 501]
      successStatuses: [200, 201, 202, 204],
      progressCallbacksInterval: 500
      prioritizeFirstAndLastChunk: true
])

'use strict'

app.factory('uploadService', [
  'routerService', 'messageService'
  (router, messages) ->
    removedAsset: undefined

    # callbacks for ng-flow:

    fileSuccess: (file) ->
      file.store.progress = 1
      file.store.save()
      return

    fileError: (file, message, flow) ->
      file.abort()
      messages.addError
        type: 'red'
        body: message
        owner: this

    fileProgress: (file) ->
      file.store.progress = file.progress()
      return

    flowOptions:
      target: router.controllers.AssetApi.uploadChunk().url
      method: 'octet'
      chunkSize: 4194304
      simultaneousUploads: 3
      testChunks: false
      chunkRetryInterval: 5000
      permanentErrors: [400, 403, 404, 409, 415, 500, 501]
      successStatuses: [200, 201, 202, 204],
      progressCallbacksInterval: 500
      prioritizeFirstAndLastChunk: true
])

Make error use the standard addError function.


React = require 'react'
BS = require 'react-bootstrap'

TeacherContentToggle = React.createClass

  getInitialState: ->
    isShowing: false

  propTypes:
    onChange: React.PropTypes.func.isRequired

  onClick: ->
    isShowing = not @state.isShowing
    @setState({isShowing})
    @props.onChange(isShowing)

  render: ->
    teacherLinkText = if @state.isShowing
      'Hide Teacher Edition'
    else
      'Show Teacher Edition'

    <BS.Button className='btn-sm teacher-edition' onClick={@onClick}>
      {teacherLinkText}
    </BS.Button>

module.exports = TeacherContentToggle

React = require 'react'
BS = require 'react-bootstrap'

TeacherContentToggle = React.createClass

  propTypes:
    onChange: React.PropTypes.func.isRequired
    isShowing: React.PropTypes.bool.isRequired

  onClick: ->
    @props.onChange(not @props.isShowing)

  render: ->
    teacherLinkText = if @props.isShowing
      'Hide Teacher Edition'
    else
      'Show Teacher Edition'

    <BS.NavItem className='teacher-edition' onClick={@onClick}>
      {teacherLinkText}
    </BS.NavItem>

module.exports = TeacherContentToggle

Use property vs state to determine toggled status


d = ->
  console.log arguments...

base = global.wolisconfig.test_url

casper.start base, ->
  this.test.assertHttpStatus 200

casper.run ->
  @test.done()

d = ->
  console.log arguments...

base = global.wolisconfig.test_url

casper.start base, ->
  @test.assertHttpStatus 200

  # check that the index page has expected text
  @test.assertTextExists 'Your first forum'

casper.run ->
  @test.done()

Check that index page is legitimate

Check that index page is legitimate


`import BaseRoute from './_base'`

Route = BaseRoute.extend
  model: ->
    # return the current user as the model if authenticated, otherwise a blank object
    new Ember.RSVP.Promise (resolve, reject) =>
      promise = $.ajax
        url: '/api/me'
        dataType: 'json'
      promise.done (result) =>
        user = Ember.Object.create(result)
        if result.isAnon
          @set 'session.isAnon', true
          @set 'session.currentUser', null
        else
          @set 'session.isAnon', false
          @set 'session.currentUser', user
        resolve(user)
      promise.fail (result) ->
        reject()
  clearSession: ->
    @set 'session.currentUser', undefined
    @set 'session.isAnon', true
    @set 'settings.editMode', false
  actions:
    toggleEditMode: ->
      @toggleProperty 'settings.editMode'
      @send 'flushUpdateQueue'
    flushUpdateQueue: ->
      return unless @get('session.currentUser.isAdmin')
      updateQueue = @get('updateQueue')
      while updateQueue.get('length')
        section = updateQueue.popObject()
        section.save()
    error: (result, transition) ->
      if result.status is 403
        @clearSession()
        @transitionTo 'signout'
`export default Route`

`import BaseRoute from './_base'`
`import ajax from 'ic-ajax'`

Route = BaseRoute.extend
  model: ->
    mePath = '/api/me'

    # return the current user as the model if authenticated, otherwise a blank object
    new Ember.RSVP.Promise (resolve, reject) =>
      ajax
          url: mePath
          dataType: 'json'
        .then (result) =>
            user = Ember.Object.create(result)
            if result.isAnon
              @set 'session.isAnon', true
              @set 'session.currentUser', null
            else
              @set 'session.isAnon', false
              @set 'session.currentUser', user
            resolve(user)
            ajax
              url: mePath
              method: 'post'
          ,
            (result) ->
              reject()
  clearSession: ->
    @set 'session.currentUser', undefined
    @set 'session.isAnon', true
    @set 'settings.editMode', false
  actions:
    toggleEditMode: ->
      @toggleProperty 'settings.editMode'
      @send 'flushUpdateQueue'
    flushUpdateQueue: ->
      return unless @get('session.currentUser.isAdmin')
      updateQueue = @get('updateQueue')
      while updateQueue.get('length')
        section = updateQueue.popObject()
        section.save()
    error: (result, transition) ->
      if result.status is 403
        @clearSession()
        @transitionTo 'signout'
`export default Route`

Sort out ES6 import confusion; add POST to /api/me to record user visit


path = require 'path'

ROOT = process.env.APP_ROOT

express = require 'express'
handlebars = require 'express-handlebars'
bodyParser = require 'body-parser'
morgan = require 'morgan'
favicon = require 'serve-favicon'
mincer = require 'mincer'

## Set up the app
module.exports = app = express()

# Logging
app.use morgan('short')

# Set up handlebars
app.set 'view engine', 'handlebars'
app.engine 'handlebars', handlebars
  defaultLayout: 'main'
  helpers:
    comicUrl: (at) -> "/at/#{at}/"
    xmlDate: (at) -> (new Date(at)).toString()

# View, static, and LESS paths on disk
app.set 'views', path.resolve(ROOT, 'views')
app.use '/static/', express.static(path.resolve(ROOT, 'public'))

# The most important thing of all.The /favicon.ico handler
app.use favicon(path.resolve(ROOT, 'public', 'favicon.ico'))

# Handle assets with mincer.
mincerEnv = new mincer.Environment();
mincerEnv.appendPath path.resolve(ROOT, 'assets')
app.use '/assets', mincer.createServer(mincerEnv)

# Parse JSON
app.use(bodyParser.json(type: '*/json'))

path = require 'path'

ROOT = process.env.APP_ROOT

express = require 'express'
handlebars = require 'express-handlebars'
bodyParser = require 'body-parser'
morgan = require 'morgan'
favicon = require 'serve-favicon'
mincer = require 'mincer'

## Set up the app
module.exports = app = express()

# Logging
app.use morgan('short')

# Set up handlebars
app.set 'view engine', 'handlebars'
app.engine 'handlebars', handlebars
  defaultLayout: 'main'
  helpers:
    comicUrl: (at) -> "/at/#{at}/"
    baseUrl: -> "http://ayp.wtf.cat" # TODO: Switch on development mode
    xmlDate: (at) -> (new Date(parseInt(at))).toString()

# View, static, and LESS paths on disk
app.set 'views', path.resolve(ROOT, 'views')
app.use '/static/', express.static(path.resolve(ROOT, 'public'))

# The most important thing of all.The /favicon.ico handler
app.use favicon(path.resolve(ROOT, 'public', 'favicon.ico'))

# Handle assets with mincer.
mincerEnv = new mincer.Environment();
mincerEnv.appendPath path.resolve(ROOT, 'assets')
app.use '/assets', mincer.createServer(mincerEnv)

# Parse JSON
app.use(bodyParser.json(type: '*/json'))

Fix xmlDate and add baseURL

Fix xmlDate and add baseURL


scrollbarWidth = 0
FactlinkJailRoot.loaded_promise.then ->
  # Create the measurement nod; see http://davidwalsh.name/detect-scrollbar-width
  scrollDiv = document.createElement("div");
  $(scrollDiv).css(
    width: "100px"
    height: "100px"
    overflow: "scroll"
    position: "absolute"
    top: "-9999px"
  )
  document.body.appendChild(scrollDiv)

  scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth

  document.body.removeChild(scrollDiv)
  console.log 'scrollbar width: ', scrollbarWidth

FactlinkJailRoot.on 'modalOpened', ->
  document.documentElement.setAttribute('data-factlink-suppress-scrolling', '')
FactlinkJailRoot.on 'modalClosed', -> document.documentElement.removeAttribute('data-factlink-suppress-scrolling')

scrollbarWidth = 0
FactlinkJailRoot.loaded_promise.then ->
  # Create the measurement nod; see http://davidwalsh.name/detect-scrollbar-width
  scrollDiv = document.createElement("div");
  $(scrollDiv).css(
    width: "100px"
    height: "100px"
    overflow: "scroll"
    position: "absolute"
    top: "-9999px"
  )
  document.body.appendChild(scrollDiv)

  scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth

  document.body.removeChild(scrollDiv)
  console.log 'scrollbar width: ', scrollbarWidth

# To check for scrollbars on the window,  use the slightly unusual window.innerHeight
# rather than  document.documentElement.clientHeight so it works in css compat mode.
window_has_scrollbar = -> window.innerHeight < document.documentElement.scrollHeight
FactlinkJailRoot.on 'modalOpened', ->
  document.documentElement.setAttribute('data-factlink-suppress-scrolling', '')
FactlinkJailRoot.on 'modalClosed', -> document.documentElement.removeAttribute('data-factlink-suppress-scrolling')

Check whether there are currently any scrollbars


Transport = require "../src/redis-transport"
RemoteChannel = require "../src/remote-channel"
helpers = require "./helpers"
{testify,assert,events} = helpers

make = ->

  transport = new Transport
    host: "localhost"
    port: 6379

  transport.events.forward events

  channel = new RemoteChannel
    name: "greeting"
    transport: transport

  channel

testify.test "A remote channel", (context) ->

  context.test "can send and receive events", (context) ->

    sender = make()
    receiver = make()

    listen = receiver.listen()

    listen.on "success", ->

      receiver.receive (message) ->

        context.test "using an 'on' handler", ->
          assert.ok message.content is "Dan"
          receiver.end()

      sender.send content: "Dan"

Transport = require "../src/redis-transport"
RemoteChannel = require "../src/remote-channel"
helpers = require "./helpers"
{testify,assert,events} = helpers

make = ->

  transport = new Transport
    host: "localhost"
    port: 6379

  transport.events.forward events

  channel = new RemoteChannel
    name: "greeting"
    transport: transport

  channel

testify.test "A remote channel", (context) ->

  context.test "can send and receive messages", (context) ->

    sender = make()
    receiver = make()

    listen = receiver.listen()

    listen.on "success", ->

      receiver.receive (message) ->

        context.test "using a recieve handler", ->
          assert.ok message.content is "Dan"
          receiver.end()

      sender.send content: "Dan"

Update the test descriptions to match the tests


# Keybindings require three things to be fully defined: A selector that is
# matched against the focused element, the keystroke and the command to
# execute.
#
# Below is a basic keybinding which registers on all platforms by applying to
# the root workspace element.

# For more detailed documentation see
# https://atom.io/docs/latest/behind-atom-keymaps-in-depth
'atom-text-editor':
  'cmd-alt-enter': 'hydrogen:run'

'atom-workspace':
  'cmd-alt-backspace': 'hydrogen:clear-results'

# Keybindings require three things to be fully defined: A selector that is
# matched against the focused element, the keystroke and the command to
# execute.
#
# Below is a basic keybinding which registers on all platforms by applying to
# the root workspace element.

# For more detailed documentation see
# https://atom.io/docs/latest/behind-atom-keymaps-in-depth
'.platform-darwin atom-text-editor':
  'cmd-alt-enter': 'hydrogen:run'

'.platform-darwin atom-workspace':
  'cmd-alt-backspace': 'hydrogen:clear-results'

'.platform-win32 atom-text-editor, .platform-linux atom-text-editor':
  'ctrl-alt-enter': 'hydrogen:run'

'.platform-win32 atom-workspace, .platform-linux atom-workspace':
  'ctrl-backspace': 'hydrogen:clear-results'

Create keymaps for other platforms.

Create keymaps for other platforms.


# This file uses the Garber-Irish method for allowing "per-page Javascript."
# I'm using the `gistyle` gem to handle the actual implementation of the pattern.

APP.init = ->
  console.log "application"

APP.bikeway_segments =
  init: ->
    $ ->
      console.log "bikeway_segments (controller)"

  index: ->
    $ ->
      console.log "enter bikeway_segments#index"
      $('#segments').dataTable
        sDom: 'ilrptf'  # http://www.datatables.net/ref#sDom
        bProcessing: true
        bServerSide: true
        sAjaxSource: $('#segments').data('source')
        bStateSave: true
        bDeferRender: true
      console.log "exit bikeway_segments#index"

  show: ->
    $ ->
      console.log "enter bikeway_segments#show"
      kmlUrl = $('#map').data('kml-url')
      handler = Gmaps.build('Google')
      opts =
        provider: {}
        internal: { id: 'map' }
      handler.buildMap(opts, ->
        kmls = handler.addKml(
          { url: kmlUrl }
        )
        # handler.bounds.extendWith(markers)
        # handler.fitMapToBounds()
      )
      console.log "exit bikeway_segments#show"

# This file uses the Garber-Irish method for allowing "per-page Javascript."
# I'm using the `gistyle` gem to handle the actual implementation of the pattern.

APP.init = ->
  console.log "application"

APP.bikeway_segments =
  init: ->
    $ ->
      console.log "bikeway_segments (controller)"

  index: ->
    $ ->
      console.log "enter bikeway_segments#index"
      $('#segments').dataTable
        sDom: 'ilrptf'  # http://www.datatables.net/ref#sDom
        bProcessing: true
        bServerSide: true
        sAjaxSource: $('#segments').data('source')
        bStateSave: true
        bDeferRender: true
      console.log "exit bikeway_segments#index"

  show: ->
    $ ->
      console.log "enter bikeway_segments#show"
      kmlUrl = $('#map').data('kml-url')
      handler = Gmaps.build('Google')
      opts =
        # see https://developers.google.com/maps/documentation/javascript/reference?hl=fr#MapOptions
        provider: {
          zoom: 16
        }
        internal: { id: 'map' }
      handler.buildMap(opts, ->
        kmls = handler.addKml(
          { url: kmlUrl }
        )
        # handler.bounds.extendWith(markers)
        # handler.fitMapToBounds()
      )
      console.log "exit bikeway_segments#show"

Set default zoom level to 16

Set default zoom level to 16


shell = require 'shelljs'

'use strict'

module.exports = (grunt) ->

  grunt.initConfig

    pkg: grunt.file.readJSON 'package.json'

    cucumberjs:
      src: './features'

    coffeelint:
      lib:   ['lib/**/*.coffee']
      tests: ['specs/**/*.coffee']

  #
  grunt.registerTask 'default',      ['build_parser', 'test']
  grunt.registerTask 'test',         ['jasmine_node']
  grunt.registerTask 'lint',         ['coffeelint']

  grunt.registerTask 'build_parser', ->
    shell.exec 'pegjs --allowed-start-rules type lib/syntax/parser.pegjs lib/syntax/parser.js'

  grunt.registerTask 'jasmine_node', ->
    shell.exec './node_modules/jasmine-node/bin/jasmine-node --coffee specs/'

  grunt.loadNpmTasks 'grunt-cucumber'
  grunt.loadNpmTasks 'grunt-coffeelint'

shell = require 'shelljs'

'use strict'

module.exports = (grunt) ->

  grunt.initConfig

    pkg: grunt.file.readJSON 'package.json'

    cucumberjs:
      src: './features'

    coffeelint:
      lib:   ['lib/**/*.coffee']
      tests: ['specs/**/*.coffee']

  #
  grunt.registerTask 'default',      ['build_parser', 'test']
  grunt.registerTask 'test',         ['jasmine_node']
  grunt.registerTask 'lint',         ['coffeelint']

  grunt.registerTask 'build_parser', ->
    shell.exec 'pegjs --allowed-start-rules system,type,attribute,heading lib/syntax/parser.pegjs lib/syntax/parser.js'

  grunt.registerTask 'jasmine_node', ->
    shell.exec './node_modules/jasmine-node/bin/jasmine-node --coffee specs/'

  grunt.loadNpmTasks 'grunt-cucumber'
  grunt.loadNpmTasks 'grunt-coffeelint'

Allow system, attribute and heading as grammar start rules.


'menu': [
  {
    'label': 'Packages'
    'submenu': [
      'label': 'Bracket Matcher'
      'submenu': [
        { 'label': 'Go To Matching Bracket', 'command': 'bracket-matcher:go-to-matching-bracket' }
        { 'label': 'Select Inside Brackets', 'command': 'bracket-matcher:select-inside-brackets' }
      ]
    ]
  }
]

'menu': [
  {
    'label': 'Packages'
    'submenu': [
      'label': 'Bracket Matcher'
      'submenu': [
        { 'label': 'Go To Matching Bracket', 'command': 'bracket-matcher:go-to-matching-bracket' }
        { 'label': 'Select Inside Brackets', 'command': 'bracket-matcher:select-inside-brackets' }
        { 'label': 'Remove Brackets from Selection', 'command': 'bracket-matcher:remove-brackets' }
      ]
    ]
  }
]

Add remove-brackets command to menu

Add remove-brackets command to menu


Update Google client secret to fix login - all values set for meta.socrench.us


class Panel
  constructor: (@Linter)->
    @Decorations = []
    @Type = 'file'
  registerView: (View)->
    @View = View
    @View.Model = this
  removeDecorations: ->
    @Decorations.forEach (decoration) ->
      try decoration.destroy()
    @Decorations = []
  render: (Messages)->
    @removeDecorations()
    Messages.forEach (Message) =>
      return unless Message.CurrentFile # A custom property added while creating arrays of them
      return unless Message.Position
      P = Message.Position
      Marker = @Linter.ActiveEditor.markBufferRange [[P[0][0] - 1, P[0][1] - 1], [P[1][0] - 1, P[1][1]]], {invalidate: 'never'}

      @Decorations.push @Linter.ActiveEditor.decorateMarker(
        Marker, type: 'line-number', class: 'line-number-' + Message.Type.toLowerCase()
      )

      @Decorations.push @Linter.ActiveEditor.decorateMarker(
        Marker, type: 'highlight', class: 'highlight-' + Message.Type.toLowerCase()
      )
    @View.render Messages
module.exports = Panel

class Panel
  constructor: (@Linter)->
    @Decorations = []
    @Type = 'file'
  removeDecorations: ->
    return unless @Decorations.length
    @Decorations.forEach (decoration) ->
      try decoration.destroy()
    @Decorations = []
  render: (Messages)->
    @removeDecorations()
    Messages.forEach (Message) =>
      return unless Message.CurrentFile # A custom property added while creating arrays of them
      return unless Message.Position
      P = Message.Position
      Marker = @Linter.ActiveEditor.markBufferRange [[P[0][0] - 1, P[0][1] - 1], [P[1][0] - 1, P[1][1]]], {invalidate: 'never'}

      @Decorations.push @Linter.ActiveEditor.decorateMarker(
        Marker, type: 'line-number', class: 'line-number-' + Message.Type.toLowerCase()
      )

      @Decorations.push @Linter.ActiveEditor.decorateMarker(
        Marker, type: 'highlight', class: 'highlight-' + Message.Type.toLowerCase()
      )
    @View.render Messages
module.exports = Panel

Remove registerView from Panel Model

:fire: Remove registerView from Panel Model


Sprangular.directive 'addressSelection', ->
  restrict: 'E'
  templateUrl: 'addresses/selection.html'
  scope:
    address: '='
    addresses: '='
    countries: '='
    disabled: '=disabledFields'
    submitted: '='
    existingAddress: '='
  controller: ($scope) ->
    $scope.$watch 'addresses', (addresses) ->
      return unless addresses && addresses.length > 0

      found = _.find addresses, (existing) ->
        existing.same($scope.address)

      $scope.toggleExistingAddress() if found

    $scope.$watch 'address.id', (addressId) ->
      return unless addressId
      $scope.lastAddressId = addressId

    $scope.toggleExistingAddress = ->
      $scope.existingAddress = !$scope.existingAddress

      if $scope.existingAddress
        if $scope.lastAddressId
          $scope.address = _.find $scope.addresses, (addr) -> addr.id == $scope.lastAddressId

        $scope.address = $scope.addresses[0] unless $scope.address
      else
        $scope.address = new Sprangular.Address()

  compile: (element, attrs) ->
    attrs.existingAddress = 'false' if attrs.exisitingAddress is undefined

  link: (scope, element, attrs) ->
    attrs.disabled = false unless attrs.disabled?

Sprangular.directive 'addressSelection', ->
  restrict: 'E'
  templateUrl: 'addresses/selection.html'
  scope:
    address: '='
    addresses: '='
    countries: '='
    disabled: '=disabledFields'
    submitted: '='
    existingAddress: '='
  controller: ($scope) ->
    $scope.$watch 'addresses', (addresses) ->
      return unless addresses && addresses.length > 0

      found = _.find addresses, (existing) ->
        existing.same($scope.address)

      $scope.toggleExistingAddress() if found

    $scope.$watch 'address.id', (addressId) ->
      return unless addressId
      $scope.lastAddressId = addressId

    $scope.toggleExistingAddress = ->
      $scope.existingAddress = !$scope.existingAddress

      if $scope.existingAddress
        if $scope.lastAddressId
          $scope.address = _.find $scope.addresses, (addr) -> addr.id == $scope.lastAddressId

        $scope.address = $scope.addresses[0] unless $scope.address
      else
        $scope.address = new Sprangular.Address()

  compile: (element, attrs) ->
    attrs.existingAddress = 'false' if attrs.existingAddress is undefined
    attrs.disabled = 'false' if attrs.disabled is undefined

Fix spelling error & remove link function in address-selection


@CodequestManager.module 'Dashboard', (Dashboard, App, Backbone, Marionette, $, _) ->
  Dashboard.Account = Marionette.ItemView.extend
    template: 'dashboard/account'
    className: ->
      "user-box #{@amountClass()}"

    templateHelpers: ->
      formattedNumber: @formattedNumber()
      formattedBalance: @formattedBalance()

    amountClass: ->
      modifier = if +@model.get('account_balance') > 0 then "positive" else "negative"
      console.log "user-box__amount__#{modifier}"
      "user-box__#{modifier}"

    formattedBalance: ->
      account_balance = @model.get('account_balance')
      if account_balance
        account_balance + " PLN"
      else
        "N/A"

    formattedNumber: ->
      @model.get('account_number') || "Bank Account Number Not Provided"

@CodequestManager.module 'Dashboard', (Dashboard, App, Backbone, Marionette, $, _) ->
  Dashboard.Account = Marionette.ItemView.extend
    template: 'dashboard/account'
    className: ->
      "user-box #{@amountClass()}"

    templateHelpers: ->
      formattedNumber: @formattedNumber()
      formattedBalance: @formattedBalance()

    amountClass: ->
      return unless @model.get('account_balance')
      modifier = if +@model.get('account_balance') > 0 then "positive" else "negative"
      "user-box__#{modifier}"

    formattedBalance: ->
      account_balance = @model.get('account_balance')
      if account_balance
        account_balance + " PLN"
      else
        "N/A"

    formattedNumber: ->
      @model.get('account_number') || "Bank Account Number Not Provided"

Fix CSS class for N/As on Accounts Page

Fix CSS class for N/As on Accounts Page


# Trigger implementation for being told when to poll

Bacon = require 'baconjs'
router = require '../../../router'

module.exports = (config) ->
	bus = new Bacon.Bus

	url = if config.url? then "/repo/poll/#{url}" else '/repo/poll'
	router.api.post url, (req, res) -> bus.push reason: "request from #{req.ip}"

	bus.toEventStream()

# Trigger implementation for being told when to poll

Bacon = require 'baconjs'
router = require '../../../router'

module.exports = (config) ->
	bus = new Bacon.Bus

	url = if config.url? then "/repo/poll/#{url}" else '/repo/poll'
	router.api.post url, (req, res) ->
		bus.push reason: "request from #{req.ip}"
		res.sendStatus 202

	bus.toEventStream()

Make sure `/repo/poll` endpoint sends a response


fs = require 'fs'
path = require 'path'

initialized = false

initSignalHandlers = ->
  if initialized then return
  initialized = true
  process.on 'exit', ->
    for own cachePath, cache of caches
      fs.writeFileSync cachePath, JSON.stringify cache

  process.on 'SIGINT', process.exit
  process.on 'SIGTERM', process.exit
  process.on 'uncaughtException', (e) ->
    # to be safe, remove all cache files
    for own cachePath of caches
      if fs.existsSync(cachePath)
        fs.unlinkSync(cachePath)
    throw e

caches = {}
defaultCachePath = path.join(process.cwd(), '.powerbuild~')

module.exports = (node = true, cachePath = defaultCachePath) ->
  if {}.hasOwnProperty.call(caches, cachePath) and
      (caches[cachePath].node or not node)
    return caches[cachePath]

  initSignalHandlers()

  if fs.existsSync cachePath
    caches[cachePath] = JSON.parse fs.readFileSync cachePath, 'utf8'

  if not caches[cachePath]
    caches[cachePath] =
      processed: {}
      uids: {next: 1, names: {}}
      node: node

  return caches[cachePath]

fs = require 'fs'
path = require 'path'

initialized = false

initSignalHandlers = ->
  if initialized then return
  initialized = true
  process.on 'exit', ->
    for own cachePath, cache of caches
      fs.writeFileSync cachePath, JSON.stringify cache

  process.on 'SIGINT', process.exit
  process.on 'SIGTERM', process.exit
  process.on 'uncaughtException', (e) ->
    # to be safe, remove all cache files
    for own cachePath of caches
      if fs.existsSync(cachePath)
        fs.unlinkSync(cachePath)
    throw e

caches = {}
defaultCachePath = path.join(process.cwd(), '.powerbuild~')

module.exports = (node = true, cachePath = defaultCachePath) ->
  if {}.hasOwnProperty.call(caches, cachePath) and
      caches[cachePath].node == node
    return caches[cachePath]

  initSignalHandlers()

  if not caches[cachePath] and fs.existsSync cachePath
    caches[cachePath] = JSON.parse fs.readFileSync cachePath, 'utf8'

  if caches[cachePath] and caches[cachePath].node != node
    console.error(
      "Warning: Configurations with different values for the 'node' option cannot share the same cache(reseting #{cachePath})")
    delete caches[cachePath]

  if not caches[cachePath]
    caches[cachePath] =
      processed: {}
      uids: {next: 1, names: {}}
      node: node

  return caches[cachePath]

Disable sharing of the same cache for

Disable sharing of the same cache for

configurations with different values of the 'node' option


# Eventful code comes here
# Program state should not be manipulated outside events files

# Initialize the canvas element (size, aspect ratio etc)
canvasInit = () ->
  windowResize()

# Initialize nodes in the scene graph
sceneInit = () ->
  shaderDef =
    type: 'shader',
    id: 'main-shader',
    shaders: [
      stage: 'fragment',
      code: compileGLSL compileASM { type: 'scene', nodes: [] }
    ]
    vars: {}
  (state.scene.findNode 'cube-mat').insert 'node', shaderDef

# Initialize html controls for interacting with mecha
controlsInit = () ->

# Initialize the CSM API (by loading the code from the given url)
apiInit = () ->
  # Get the API code
  state.api.url = ($ "link[rel='api']").attr 'href'
  ($.get encodeURIComponent state.api.url, undefined, undefined, 'text')
    .success (data, textStatus, jqXHR) ->
      state.api.sourceCode = data
      mecha.log "Loaded " + state.api.url
    .error () ->
      mecha.log "Error loading API script"

# Start rendering as soon as possible
canvasInit()
sceneInit()
state.scene.start
  idleFunc: sceneIdle

# Initialize the gui controls and register events once the rest of the document has completely loaded
$ () ->
  apiInit()
  controlsInit()
  registerDOMEvents()
  registerControlEvents()
  state.application.initialized = true

# Eventful code comes here
# Program state should not be manipulated outside events files

# Initialize the canvas element (size, aspect ratio etc)
canvasInit = () ->
  windowResize()

# Initialize nodes in the scene graph
sceneInit = () ->
  compileCSM ($ '#source-code').val(),
    (result) ->
      shaderDef =
        type: 'shader',
        id: 'main-shader',
        shaders: [
          stage: 'fragment',
          code: compileGLSL compileASM result
        ]
        vars: {}
      (state.scene.findNode 'cube-mat').insert 'node', shaderDef

# Initialize html controls for interacting with mecha
controlsInit = () ->

# Initialize the CSM API (by loading the code from the given url)
apiInit = () ->
  # Get the API code
  state.api.url = ($ "link[rel='api']").attr 'href'
  ($.get encodeURIComponent state.api.url, undefined, undefined, 'text')
    .success (data, textStatus, jqXHR) ->
      state.api.sourceCode = data
      mecha.log "Loaded " + state.api.url
    .error () ->
      mecha.log "Error loading API script"

# Start rendering as soon as possible
canvasInit()
sceneInit()
state.scene.start
  idleFunc: sceneIdle

# Initialize the gui controls and register events once the rest of the document has completely loaded
$ () ->
  apiInit()
  controlsInit()
  registerDOMEvents()
  registerControlEvents()
  state.application.initialized = true

Initialize the model with the default code in the source editor


# This is a manifest file that'll be compiled into application.js, which will include all the files
# listed below.
#
# Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
# or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
#
# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
# compiled file.
#
# Read Sprockets README (https:#github.com/sstephenson/sprockets#sprockets-directives) for details
# about supported directives.
#
#= require jquery
#= require jquery_ujs
#= require rails-timeago
#= require jquery-notify
#= require_tree ./shipit
#= require_self

$(document).on 'click', 'a.disabled', (event) ->
  event.preventDefault()

jQuery ->
  $notificationNotice = $('.notifications')

  if $.notifyCheck() == $.NOTIFY_NOT_ALLOWED
    $button = $notificationNotice.find('button')
    $button.on 'click', ->
      $.notifyRequest()
      $notificationNotice.addClass('hidden')
    $notificationNotice.removeClass('hidden')

# This is a manifest file that'll be compiled into application.js, which will include all the files
# listed below.
#
# Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
# or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
#
# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
# compiled file.
#
# Read Sprockets README (https:#github.com/sstephenson/sprockets#sprockets-directives) for details
# about supported directives.
#
#= require jquery
#= require jquery_ujs
#= require rails-timeago
#= require_tree ./shipit
#= require_self

$(document).on 'click', 'a.disabled', (event) ->
  event.preventDefault()

jQuery ->
  $notificationNotice = $('.notifications')

  if $.notifyCheck() == $.NOTIFY_NOT_ALLOWED
    $button = $notificationNotice.find('button')
    $button.on 'click', ->
      $.notifyRequest()
      $notificationNotice.addClass('hidden')
    $notificationNotice.removeClass('hidden')

Revert "Add jQuery notify back in"

Revert "Add jQuery notify back in"

This reverts commit 89bdb2cd13608ec82846d0e7b10f12e2ed176c18.

Conflicts:
	app/assets/javascripts/shipit.js.coffee

Not sure why, but this was breaking a blank app.
We should add it back, once we fix/figure out the problem.


fs = require 'fs-extra'
path = require 'path-extra'

stringify = (str) ->
  return str if typeof str == 'string'
  if str.toString() == '[object Object]'
    str = JSON.stringify str
  else
    str = str.toString()
  return str

module.exports =
  remoteStringify: JSON.stringify
  log: (str) ->
    str = stringify str
    console.log "[INFO] #{str}"
  warn: (str) ->
    str = stringify str
    console.warn "[WARN] #{str}".yellow
  error: (str) ->
    str = stringify str
    console.error "[ERROR] #{str}".bold.red
  setBounds: (options) ->
    global.mainWindow.setBounds options
  getBounds: ->
    global.mainWindow.getBounds()
  capturePageInMainWindow: (rect, scpath, callback) ->
    global.mainWindow.capturePage rect, (image) ->
      try
        buf = image.toPng()
        now = new Date()
        date = "#{now.getFullYear()}-#{now.getMonth() + 1}-#{now.getDate()}T#{now.getHours()}.#{now.getMinutes()}.#{now.getSeconds()}"
        fs.ensureDirSync scpath
        filename = path.join scpath, "#{date}.png"
        fs.writeFile filename, buf, (err) ->
          callback err, filename
      catch e
        callback err

fs = require 'fs-extra'
path = require 'path-extra'

stringify = (str) ->
  return str if typeof str == 'string'
  if str.toString() == '[object Object]'
    str = JSON.stringify str
  else
    str = str.toString()
  return str

module.exports =
  remoteStringify: JSON.stringify
  log: (str) ->
    str = stringify str
    console.log "[INFO] #{str}"
  warn: (str) ->
    str = stringify str
    console.warn "[WARN] #{str}" #.yellow   # colors may not compatible with latest Electron, and make all messages "undefined"
  error: (str) ->
    str = stringify str
    console.error "[ERROR] #{str}" #.bold.red
  setBounds: (options) ->
    global.mainWindow.setBounds options
  getBounds: ->
    global.mainWindow.getBounds()
  capturePageInMainWindow: (rect, scpath, callback) ->
    global.mainWindow.capturePage rect, (image) ->
      try
        buf = image.toPng()
        now = new Date()
        date = "#{now.getFullYear()}-#{now.getMonth() + 1}-#{now.getDate()}T#{now.getHours()}.#{now.getMinutes()}.#{now.getSeconds()}"
        fs.ensureDirSync scpath
        filename = path.join scpath, "#{date}.png"
        fs.writeFile filename, buf, (err) ->
          callback err, filename
      catch e
        callback err

Remove use of colors for now

Remove use of colors for now


module.exports =
class Task
  aborted: false

  constructor: (@path) ->

  start: ->
    throw new Error("Task already started") if @worker?

    @worker = new Worker(require.getPath('task-shell'))
    @worker.onmessage = ({data}) =>
      if @aborted
        @done()
        return

      if data.method and this[data.method]
        this[data.method](data.args...)
      else
        @onMessage(data)
    @startWorker()

  log: -> console.log(arguments...)
  warn: -> console.warn(arguments...)
  error: -> console.error(arguments...)

  startWorker: ->
    @callWorkerMethod 'start'
      globals:
        resourcePath: window.resourcePath
        navigator:
          userAgent: navigator.userAgent
      requirePath: require.getPath('require')
      handlerPath: @path

  started: ->

  onMessage: (message) ->

  callWorkerMethod: (method, args...) ->
    @postMessage({method, args})

  postMessage: (data) ->
    @worker.postMessage(data)

  abort: ->
    @aborted = true

  done: ->
    @abort()
    @worker?.terminate()
    @worker = null

module.exports =
class Task
  aborted: false

  constructor: (@path) ->

  start: ->
    throw new Error("Task already started") if @worker?

    @worker = new Worker(require.getPath('task-shell'))
    @worker.onmessage = ({data}) =>
      if @aborted
        @done()
        return

      if data.method and this[data.method]
        this[data.method](data.args...)
      else
        @onMessage(data)
    @startWorker()

  log: -> console.log(arguments...)
  warn: -> console.warn(arguments...)
  error: -> console.error(arguments...)

  startWorker: ->
    @callWorkerMethod 'start',
      globals:
        resourcePath: window.resourcePath
        navigator:
          userAgent: navigator.userAgent
      requirePath: require.getPath('require')
      handlerPath: @path

  started: ->

  onMessage: (message) ->

  callWorkerMethod: (method, args...) ->
    @postMessage({method, args})

  postMessage: (data) ->
    @worker.postMessage(data)

  abort: ->
    @aborted = true

  done: ->
    @abort()
    @worker?.terminate()
    @worker = null

Add command after first argument

Add command after first argument

This forces the object to be interpreted as the
second argument to the callWorkerMethod function
instead of as the first argument to function returned
from callWorkerMethod.

Closes #338


riot = require('riot')
React = require('react')

LocationInput = React.createClass
  render: -> `(
    <form>
      <input type="text"></input>
      <input type="submit"></input>
    </form>
  )`

ToiletItem = React.createClass
  render: -> `(

{this.props.name}
{this.props.address}

  )`

ToiletList = React.createClass
  getInitialState: ->
    toilets: []
  render: ->
    items = (`(<ToiletItem name={name} address={address} />)` for {address, name} in @state.toilets)
    `(

          {items}

    )`

class ToiletListApp
  constructor: ->
    @locationInput = `<LocationInput />`
    @toiletList = `<ToiletList />`
    riot.observable @
    return

riot = require('riot')
React = require('react')
NCN = require('./ncn')

LocationInput = React.createClass
  render: -> `(
    <form>
      <input type="text"></input>
      <input type="submit"></input>
    </form>
  )`

ToiletItem = React.createClass
  render: -> `(

{this.props.name}
{this.props.address}

  )`

ToiletList = React.createClass
  getInitialState: ->
    toilets: []
  render: ->
    items = (`(<ToiletItem name={name} address={address} />)` for {address, name} in @state.toilets)
    `(

        {items}

    )`

Remove div around toilet list

Remove div around toilet list


mongoose = require('mongoose')
mongoose.connect("mongodb://localhost/nrt_development")
IndicatorData = require('../../models/indicator_data').model
fs = require('fs')

console.log "Yo"
IndicatorData.dataToSeedJSON().then((json)->
  fs.writeFile("./lib/indicator_data.json", json, (err) ->
    if err
      console.error "Error writing indicator data backup:"
      console.error err
      console.error err.stack
    else
      console.log "Wrote indicator data to lib/indicator_data.json"
  )

).fail((err)->
  console.log "Error generating backup indicator data:"
  console.log err
  console.log err.stack
)

mongoose = require('mongoose')
mongoose.connect("mongodb://localhost/nrt_development")
IndicatorData = require('../../models/indicator_data').model
fs = require('fs')

console.log "Backing up Indicator Data"
IndicatorData.dataToSeedJSON().then((json)->
  fs.writeFile("./lib/indicator_data.json", json, (err) ->
    if err
      console.error "Error writing indicator data backup:"
      console.error err
      console.error err.stack
      process.exit(1)
    else
      console.log "Wrote indicator data to lib/indicator_data.json"
      process.exit(0)
  )

).fail((err)->
  console.log "Error generating backup indicator data:"
  console.log err
  console.log err.stack
)

Make backup task exit when finishd

Make backup task exit when finishd


module.exports =
  processResponse: (res) ->
    # Check to see if the contentype is "something/json" or
    # "something/somethingelse+json"
    if res.contentType and (/^.*\/(?:.*\+)?json$/i).test res.contentType
      # If the body hasn't been parsed yet, parse it.
      raw = if typeof res.body is 'string' then res.body else res.text
      res.body = JSON.parse raw if raw

module.exports =
  processResponse: (res) ->
    # Check to see if the contentype is "something/json" or
    # "something/somethingelse+json"
    if res.contentType and (/^.*\/(?:.*\+)?json(;|\z)/i).test res.contentType
      # If the body hasn't been parsed yet, parse it.
      raw = if typeof res.body is 'string' then res.body else res.text
      res.body = JSON.parse raw if raw

Allow more complex contentType fields

Allow more complex contentType fields


should = require 'should'
{join} = require 'path'

# lib stuff
{load, process, applyPolicy, print, create, print} = require '../lib/main'

# sample stuff
jargon = require '../sample/app/domain/auth/jargon'
serviceLocation = join __dirname, '../sample/app/domain/auth/services'
policy = require '../sample/app/domain/auth/policy'

describe 'dependency', ->
  beforeEach (done) ->
    @services = create serviceLocation, jargon, policy
    @sessionId = 'ab23ab23ab23ab23'
    should.exist @services.doSomething
    should.exist @services.helpDoSomething
    done()

  it 'should fail without a dependency load function wired up', (done) ->
    @services.doSomething {@sessionId}, (err) =>
      should.exist err
      err.message.should.equal 'Could not load dependency'
      done()

  it 'should not fail when the dependency load function is specified', (done) ->
    # specify loader, then...
    @services.doSomething {@sessionId}, (err) =>
      should.not.exist err
      done()

should = require 'should'
{join} = require 'path'

# lib stuff
{load, process, applyPolicy, print, create, print} = require '../lib/main'

# sample stuff
jargon = require '../sample/app/domain/auth/jargon'
serviceLocation = join __dirname, '../sample/app/domain/auth/services'
policy = require '../sample/app/domain/auth/policy'

describe 'dependency', ->
  beforeEach (done) ->
    @services = create serviceLocation, jargon, policy
    @sessionId = 'ab23ab23ab23ab23'
    should.exist @services.doSomething
    should.exist @services.helpDoSomething
    done()

  it 'should fail without a dependency load function wired up', (done) ->
    @services.doSomething {@sessionId}, (err) =>
      should.exist err
      err.message.should.equal 'Could not load dependency'
      done()

  it 'should not fail when the dependency load function is specified', (done) ->
    # specify loader, then...
    @services.doSomething {@sessionId}, (err, {result}) =>
      should.not.exist err
      should.exist result
      result.should.equal 'it worked'
      done()

Check result of dependent service

Check result of dependent service


assert = require 'assert'

htmlParse = require '../lib/html-parse'

describe 'HTML Parser', ->
    it 'Extracts HTML classes', ->
        html = """
        <!DOCTYPE html>
        <html class="htmlclass">
            <head>
            </head>
            <body class="bodyclass">
                <div class="class1 class2">
                </div>
            </body>
        </html>
        """

        classes = htmlParse.getClasses(html)
        assert.deepEqual(classes, ['bodyclass', 'class1', 'class2', 'htmlclass'])

    it 'Recognizes classes in Angular.JS ng-class'

Add placeholder test for ng-class.

Add placeholder test for ng-class.


define [
    '../core'
    './base'
], (c, base) ->

    class QueryModel extends base.Model

    class QueryCollection extends base.Collection
        model: QueryModel

        url: ->
            c.session.url('queries')

        initialize: ->
            super
            c.subscribe c.SESSION_OPENED, => @fetch(reset: true)
            c.subscribe c.SESSION_CLOSE, => @reset()

    class SharedQueryCollection extends QueryCollection
        url: ->
            c.session.url('shared_queries')

    { QueryModel, QueryCollection, SharedQueryCollection }

define [
    '../core'
    './base'
], (c, base) ->

    class QueryModel extends base.Model
        url: ->
            c.session.url('queries')

    class QueryCollection extends base.Collection
        model: QueryModel

        url: ->
            c.session.url('queries')

        initialize: ->
            super
            c.subscribe c.SESSION_OPENED, => @fetch(reset: true)
            c.subscribe c.SESSION_CLOSE, => @reset()

    class SharedQueryCollection extends QueryCollection
        url: ->
            c.session.url('shared_queries')

    { QueryModel, QueryCollection, SharedQueryCollection }

Set the url on the QueryModel

Set the url on the QueryModel


module.exports = (Impromptu, register, system) ->
  register 'pwd',
    update: ->
      process.env.PWD

  register 'prettyPwd',
    update: ->
      cwd = process.env.PWD
      if cwd.indexOf(process.env.HOME) == 0
        cwd = '~' + cwd.slice process.env.HOME.length
      cwd

  register 'user',
    update: (done) ->
      Impromptu.exec 'whoami', done

  register 'host',
    update: (done) ->
      Impromptu.exec 'hostname', done

  register 'shortHost',
    update: (done) ->
      system.host (err, host) ->
        done err, host.split('.', 1)[0]

  register 'jobsCount',
    update: ->
      parseInt process.env.IMPROMPTU_JOBS_COUNT, 10

  register 'lastExitCode',
    update: ->
      parseInt process.env.IMPROMPTU_LAST_EXIT_CODE, 10

module.exports = (Impromptu, register, system) ->
  register 'pwd',
    update: ->
      process.env.PWD

  register 'prettyPwd',
    update: ->
      cwd = process.env.PWD
      if cwd.indexOf(process.env.HOME) == 0
        cwd = '~' + cwd.slice process.env.HOME.length
      cwd

  register 'user',
    update: ->
      process.env.USER

  register 'host',
    update: (done) ->
      Impromptu.exec 'hostname', done

  register 'shortHost',
    update: (done) ->
      system.host (err, host) ->
        done err, host.split('.', 1)[0]

  register 'jobsCount',
    update: ->
      parseInt process.env.IMPROMPTU_JOBS_COUNT, 10

  register 'lastExitCode',
    update: ->
      parseInt process.env.IMPROMPTU_LAST_EXIT_CODE, 10

Use the `USER` env var instead of `whoami`

Calling `whoami` will always return the user with which the server was
started, which might or might not be the current user.

For example if we change the user in the middle of a session the prompt
will continue showing the original username.


window.addAddressRow = (count) ->
  newRow = $ """

    Mailing Address

      <input class="form-control" data-guard="different" type="text" value="" name="organization[addresses_attributes][""" + count + """][address]" id="organization_addresses_attributes_""" + count + """_address">

  <input type="hidden" value="" name="organization[addresses_attributes][""" + count + """][id]" id="organization_addresses_attributes_""" + count + """_id">
  """

  $("#organization_info").append newRow

$(document).on "click", "#add-new-address", (event) ->
  event.preventDefault()
  count = $("[id^='organization_addresses_attributes']:text").length
  addAddressRow(count)

window.addAddressRow = (count) ->
  newRow = $ """

    Mailing Address

      <input class="form-control" data-guard="different" type="text" value="" name="organization[addresses_attributes][#{count}][address]" id="organization_addresses_attributes_#{count}_address">

  <input type="hidden" value="" name="organization[addresses_attributes][#{count}][id]" id="organization_addresses_attributes_#{count}_id">
  """

  $("#organization_info").append newRow

$(document).on "click", "#add-new-address", (event) ->
  event.preventDefault()
  count = $("[id^='organization_addresses_attributes']:text").length
  addAddressRow(count)

Change org coffee to string interpolation


@index = (req, res, next) ->
  user = req.user
  { customer, policy } = user.related()
  policy.authenticate(user.get('access_token'))
  customer.authenticate(user.get('access_token'))

  Promise.all [
    user.fetch()
    policy.fetch()
    customer.fetch()
      .catch -> #
  ]
    .then ->
      res.locals.sd.USER = user.toJSON()
      res.locals.sd.POLICY = policy.toJSON()
      res.locals.sd.CUSTOMER = customer.toJSON()

      res.render 'index',
        tab: req.params.tab
        user: user
        policy: policy
        customer: customer

    .catch next

@index = (req, res, next) ->
  user = req.user
  { customer, policy } = user.related()
  policy.authenticate(user.get('access_token'))
  customer.authenticate(user.get('access_token'))

  headers = {
    'X-AUTH-TOKEN': user.get('access_token'),
  }

  Promise.all [
    user.fetch({ headers })
    policy.fetch()
    customer.fetch()
      .catch -> #
  ]
    .then ->
      res.locals.sd.USER = user.toJSON()
      res.locals.sd.POLICY = policy.toJSON()
      res.locals.sd.CUSTOMER = customer.toJSON()

      res.render 'index',
        tab: req.params.tab
        user: user
        policy: policy
        customer: customer

    .catch next

Add headers to settings app

Add headers to settings app


ETahi.RedirectsIfEditable = Em.Mixin.create
  toggleEditable: ->
    @get('controller').send('editableDidChange')

  setupEditableToggle: (->
    @addObserver('controller.model.editable', @, @toggleEditable)
  ).on('didInsertElement')

  teardownEditableToggle: (->
    @removeObserver('controller.model.editable', @, @toggleEditable)
  ).on('willDestroyElement')

ETahi.RedirectsIfEditable = Em.Mixin.create
  editable: Ember.computed.alias('controller.model.editable')

  toggleEditable: ->
    if @get('editable') != @get('lastEditable')
      @set('lastEditable', @get('editable'))
      @get('controller').send('editableDidChange')

  setupEditableToggle: (->
    @set('lastEditable', @get('editable'))
    @addObserver('editable', @, @toggleEditable)
  ).on('didInsertElement')

  teardownEditableToggle: (->
    @removeObserver('editable', @, @toggleEditable)
  ).on('willDestroyElement')

Fix transitions when editable isn’t actually changing


assert = require 'assert'
app = require('remote').require 'app'

describe 'app module', ->
  describe 'app.getVersion()', ->
    it 'returns the version field of package.json', ->
      assert.equal app.getVersion(), '0.1.0'

  describe 'app.setVersion(version)', ->
    it 'overrides the version', ->
      assert.equal app.getVersion(), '0.1.0'
      app.setVersion 'test-version'
      assert.equal app.getVersion(), 'test-version'
      app.setVersion '0.1.0'

  describe 'app.getName()', ->
    it 'returns the name field of package.json', ->
      assert.equal app.getName(), 'Atom Shell Test App'

  describe 'app.setName(name)', ->
    it 'overrides the name', ->
      assert.equal app.getName(), 'Atom Shell Test App'
      app.setName 'test-name'
      assert.equal app.getName(), 'test-name'
      app.setName 'Atom Shell Default App'

assert = require 'assert'
app = require('remote').require 'app'

describe 'app module', ->
  describe 'app.getVersion()', ->
    it 'returns the version field of package.json', ->
      assert.equal app.getVersion(), '0.1.0'

  describe 'app.setVersion(version)', ->
    it 'overrides the version', ->
      assert.equal app.getVersion(), '0.1.0'
      app.setVersion 'test-version'
      assert.equal app.getVersion(), 'test-version'
      app.setVersion '0.1.0'

  describe 'app.getName()', ->
    it 'returns the name field of package.json', ->
      assert.equal app.getName(), 'Atom Shell Test App'

  describe 'app.setName(name)', ->
    it 'overrides the name', ->
      assert.equal app.getName(), 'Atom Shell Test App'
      app.setName 'test-name'
      assert.equal app.getName(), 'test-name'
      app.setName 'Atom Shell Test App'

Fix refreshing the spec window.

Fix refreshing the spec window.


Promise = require 'promise'
Log     = require 'log'
logger  = new Log(process.env.HUBOT_LOG_LEVEL or 'info')

getHttpJson = (robot, url) ->
  logger.debug "Loading", url
  new Promise (resolve, reject) ->
    robot.http(url)
      .header('Accept', 'application/json')
      .get() (err, res, body) ->
        if err
          logger.error e
          reject err
        try
          logger.debug "resolving http request", body
          resolve(JSON.parse(body))
        catch e
          logger.error e
          reject e

module.exports =
  getHttpJson: getHttpJson

Q       = require 'q'
Log     = require 'log'
logger  = new Log(process.env.HUBOT_LOG_LEVEL or 'info')

getHttpJson = (robot, url) ->
  logger.debug "Loading", url
  new Q.Promise (resolve, reject) ->
    robot.http(url)
      .header('Accept', 'application/json')
      .get() (err, res, body) ->
        if err
          logger.error e
          reject err
        try
          logger.debug "resolving http request", body
          resolve(JSON.parse(body))
        catch e
          logger.error e
          reject e

module.exports =
  getHttpJson: getHttpJson

Convert http to Q instead of old promise library.


module.exports =

  activate: (state) ->
    atom.workspaceView.command 'table-edit:demo', ->
      Table = require './table'
      TableView = require './table-view'

      table = new Table
      table.addColumn 'key'
      table.addColumn 'value'
      table.addColumn 'foo'

      for i in [0...100]
        table.addRow [
          "row#{i}"
          i * 100
          if i % 2 is 0 then 'yes' else 'no'
        ]

      tableView = new TableView(table)
      tableView.setRowHeight 20
      tableView.setRowOverdraw 10

      tableView.addClass('demo overlay from-top').height(300)
      atom.workspaceView.append(tableView)

      tableView.on 'core:cancel', -> console.log 'canceled'

  deactivate: ->

  serialize: ->

module.exports =

  activate: (state) ->
    atom.workspaceView.command 'table-edit:demo', ->
      Table = require './table'
      TableView = require './table-view'

      table = new Table
      table.addColumn 'key'
      table.addColumn 'value'
      table.addColumn 'foo'

      for i in [0...100]
        table.addRow [
          "row#{i}"
          i * 100
          if i % 2 is 0 then 'yes' else 'no'
        ]

      tableView = new TableView(table)
      tableView.setRowHeight 20
      tableView.setRowOverdraw 10

      tableView.addClass('demo overlay from-top').height(300)
      atom.workspaceView.append(tableView)

      tableView.on 'core:cancel', -> tableView.destroy()

  deactivate: ->

  serialize: ->

Destroy the demo view on core:cancel

Destroy the demo view on core:cancel


RedisWrapper = require('../../infrastructure/RedisWrapper')
rclient = RedisWrapper.client('sudomode')
logger = require('logger-sharelatex')

TIMEOUT_IN_SECONDS = 60 * 60

module.exports = SudoModeHandler =

	_buildKey: (userId) ->
		"SudoMode:{#{userId}}"

	activateSudoMode: (userId, callback=(err)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		duration = TIMEOUT_IN_SECONDS
		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback

	isSudoModeActive: (userId, callback=(err, isActive)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must not be supplied'))
		rclient.get SudoModeHandler._buildKey(userId), (err, result) ->
			if err?
				return callback(err)
			callback(null, result == '1')

RedisWrapper = require('../../infrastructure/RedisWrapper')
rclient = RedisWrapper.client('sudomode')
logger = require('logger-sharelatex')

TIMEOUT_IN_SECONDS = 60 * 60

module.exports = SudoModeHandler =

	_buildKey: (userId) ->
		"SudoMode:{#{userId}}"

	activateSudoMode: (userId, callback=(err)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must be supplied'))
		duration = TIMEOUT_IN_SECONDS
		logger.log {userId, duration}, "[SudoMode] activating sudo mode for user"
		rclient.set SudoModeHandler._buildKey(userId), '1', 'EX', duration, callback

	isSudoModeActive: (userId, callback=(err, isActive)->) ->
		if !userId?
			return callback(new Error('[SudoMode] user must be supplied'))
		rclient.get SudoModeHandler._buildKey(userId), (err, result) ->
			if err?
				return callback(err)
			callback(null, result == '1')

Fix typo in log message

Fix typo in log message


class Trix.Input
  @events: "keydown keypress drop cut copy paste input".split(" ")
  @keys:
    0x08: "backspace"
    0x0D: "return"

  constructor: (@element, @responder) ->
    for event in @constructor.events
      @element.addEventListener(event, @[event], true)

  keydown: (event) =>
    if keyName = @constructor.keys[event.keyCode]
      if handler = @[keyName]
        handler.call this, event
        event.preventDefault()

  keypress: (event) =>
    if event.which is null
      character = String.fromCharCode event.keyCode
    else if event.which isnt 0 and event.charCode isnt 0
      character = String.fromCharCode event.charCode

    if character
      @responder?.insertString(character)
      event.preventDefault()

  drop: (event) =>
    @logAndCancel(event)

  cut: (event) =>
    @logAndCancel(event)

  copy: (event) =>
    @logAndCancel(event)

  paste: (event) =>
    @logAndCancel(event)

  input: (event) =>
    @responder?.render()
    @logAndCancel(event)

  backspace: (event) =>
    @responder?.deleteBackward()

  return: (event) =>
    @responder?.insertString("\n")

  logAndCancel: (event) =>
    console.log "trapped event:", event
    event.preventDefault()

class Trix.Input
  @events: "keydown keypress drop cut paste input".split(" ")
  @keys:
    0x08: "backspace"
    0x0D: "return"

  constructor: (@element, @responder) ->
    for event in @constructor.events
      @element.addEventListener(event, @[event], true)

  keydown: (event) =>
    if keyName = @constructor.keys[event.keyCode]
      if handler = @[keyName]
        handler.call this, event

  keypress: (event) =>
    return if event.metaKey

    if event.which is null
      character = String.fromCharCode event.keyCode
    else if event.which isnt 0 and event.charCode isnt 0
      character = String.fromCharCode event.charCode

    if character
      @responder?.insertString(character)
      event.preventDefault()

  drop: (event) =>
    @logAndCancel(event)

  cut: (event) =>
    @responder?.deleteBackward()

  paste: (event) =>
    if text = event.clipboardData.getData("text/plain")
      @responder?.insertString(text)
    event.preventDefault()

  input: (event) =>
    @responder?.render()
    @logAndCancel(event)

  backspace: (event) =>
    @responder?.deleteBackward()
    event.preventDefault()

  return: (event) =>
    @responder?.insertString("\n")
    event.preventDefault()

  logAndCancel: (event) =>
    console.log "trapped event:", event
    event.preventDefault()

Support copy, cut, and plain text pastes


angular.module 'keranbeandco.user'
.controller 'login', ($scope, $state, ImprovedUser) ->

  $scope.login = ->
    ImprovedUser.login
      email: $scope.loginEmail
      password: $scope.loginPassword
    .$promise
    .then () ->
      $state.go 'home'

  $scope.createUser = ->
    ImprovedUser.create
      firstName: $scope.createFirstName
      lastName: $scope.createLastName
      email: $scope.createEmail
      password: $scope.createPassword

angular.module 'keranbeandco.user'
.controller 'login', ($scope, $state, ImprovedUser, $mdToast) ->

  $scope.login = ->
    ImprovedUser.login
      email: $scope.loginEmail
      password: $scope.loginPassword
    .$promise
    .then () ->
      $state.go 'home'

  $scope.createUser = ->
    ImprovedUser.create
      firstName: $scope.createFirstName
      lastName: $scope.createLastName
      email: $scope.createEmail
      password: $scope.createPassword
    .$promise
    .then () ->
      $mdToast.showSimple 'Le compte a été créé, vous pouvez maintenant vous connecter !'

Add message when user created

Add message when user created


define (require) ->
  Backbone = require('backbone')
  settings = require('settings')

  # Class to handle loading analytics scripts and wrapping
  # handlers around them so that modules don't have to
  # interact with global variables directly
  return new class AnalyticsHandler
    constructor: () ->
      # Setup temporary analytics.js objects
      # window.GoogleAnalyticsObject = 'ga'
      # window.ga = () -> (window.ga.q ?= []).push(arguments)
      # window.ga.l = 1 * new Date()

      # Initialize analytics.js account
      # window.ga('create', settings.analyticsID, 'auto')

      # ## Setup ga.js
      window._gaq ?= []

      # Asynchronously load analytics.js.
      # require(['https://www.google-analytics.com/analytics.js'])

      # Asynchronously load ga.js
      require(['https://www.google-analytics.com/ga.js'])

    # Wrapper functions to add analytics events
    # ga: () -> window.ga?.apply(@, arguments) # analytics.js
    gaq: () ->
      console.log arguments[0] + ', ' + arguments[1]
      window._gaq?.push(arguments[0], arguments[1]) # ga.js

    # Send the current page to every analytics service
    send: (account) ->
      fragment = Backbone.history.fragment
      if not /^\//.test(fragment) then fragment = '/' + fragment

      # Use the default analytics ID in settings if no account is specified
      account ?= settings.analyticsID

      # @ga('send', 'pageview')
      @gaq(['_setAccount', account], ['_trackPageview', fragment])

define (require) ->
  Backbone = require('backbone')
  settings = require('settings')

  # Class to handle loading analytics scripts and wrapping
  # handlers around them so that modules don't have to
  # interact with global variables directly
  return new class AnalyticsHandler
    constructor: () ->
      # Setup temporary analytics.js objects
      # window.GoogleAnalyticsObject = 'ga'
      # window.ga = () -> (window.ga.q ?= []).push(arguments)
      # window.ga.l = 1 * new Date()

      # Initialize analytics.js account
      # window.ga('create', settings.analyticsID, 'auto')

      # ## Setup ga.js
      window._gaq ?= []

      # Asynchronously load analytics.js.
      # require(['https://www.google-analytics.com/analytics.js'])

      # Asynchronously load ga.js
      require(['https://www.google-analytics.com/ga.js'])

    # Wrapper functions to add analytics events
    # ga: () -> window.ga?.apply(@, arguments) # analytics.js
    gaq: () ->
      window._gaq?.push(arguments[0], arguments[1]) # ga.js

    # Send the current page to every analytics service
    send: (account, fragment = Backbone.history.fragment) ->
      if not /^\//.test(fragment) then fragment = '/' + fragment

      # Use the default analytics ID in settings if no account is specified
      account ?= settings.analyticsID

      # @ga('send', 'pageview')
      @gaq(['_setAccount', account], ['_trackPageview', fragment])

Allow fragment to track to be specified

Allow fragment to track to be specified


_ = require 'underscore'
Backbone = require 'backbone'
{ API_URL } = require('sharify').data

module.exports =
  related: ->
    return @__related__ if @__related__?

    CollectorProfile = require '../../collector_profile.coffee'
    Location = require '../../location.coffee'

    collectorProfile = new CollectorProfile

    location = new Location @get 'location'

    account = new Backbone.Model
    account.url = "#{API_URL}/api/v1/user"
    account.fetch = _.wrap account.fetch, (fetch, options = {}) =>
      options.data = @pick('email')
      fetch.call account, options

    authentications = new Backbone.Collection
    authentications.url = "#{API_URL}/api/v1/me/authentications"

    @__related__ =
      collectorProfile: collectorProfile
      account: account
      location: location
      authentications: authentications

_ = require 'underscore'
Backbone = require 'backbone'
{ API_URL } = require('sharify').data

module.exports =
  related: ->
    return @__related__ if @__related__?

    CollectorProfile = require '../../collector_profile.coffee'
    Location = require '../../location.coffee'

    collectorProfile = new CollectorProfile

    location = new Location @get 'location'

    account = new Backbone.Model
    account.url = "#{API_URL}/api/v1/user"
    account.fetch = _.wrap account.fetch, (fetch, options = {}) =>
      options.data = @pick('email')
      fetch.call account, options

    authentications = new Backbone.Collection
    authentications.url = "#{API_URL}/api/v1/me/authentications"

    creditCards = new Backbone.Collection
    creditCards.url = "#{API_URL}/api/v1/me/credit_cards"

    @__related__ =
      collectorProfile: collectorProfile
      account: account
      location: location
      authentications: authentications
      creditCards: creditCards

Set up a `creditCards` relation on the User


# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$('body.bounties.index').ready ->

    # Added a parser for the my-bounty input fields
    $.fn.dataTable.ext.order['dom-input-numeric'] = (_settings, col) ->
        return this.api().column(col, {order: 'index'}).nodes().map (td, _i) ->
            return $('input#bounty_value', td).val() * 1

    $('#bounties-table').DataTable
        order: [[2, 'desc'], [0, 'asc'], [1, 'asc']]
        columnDefs: [
                targets: ['total-bounty', 'my-bounty']
                orderSequence: ['desc', 'asc']
                render: (data, type, _row, _meta) ->
                    if type is 'display'
                        return data
                    else
                        return data.replace(/[^\d]/g, '')
            ,
                targets: ['my-bounty']
                orderDataType: 'dom-input-numeric'
                type: 'numeric'
        ]
        autoWidth: false
        pagingType: 'full_numbers'
        language: default_pagination_language

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

$('body.bounties.index').ready ->

    # Added a parser for the my-bounty input fields
    $.fn.dataTable.ext.order['dom-input-numeric'] = (_settings, col) ->
        return this.api().column(col, {order: 'index'}).nodes().map (td, _i) ->
            return $('input#bounty_value', td).val() * 1

    $('#bounties-table').DataTable
        order: [[2, 'desc'], [0, 'asc'], [1, 'asc']]
        columnDefs: [
                targets: ['total-bounty', 'my-bounty']
                orderSequence: ['desc', 'asc']
                render: (data, type, _row, _meta) ->
                    if type is 'display'
                        return data
                    else
                        return data.replace(/[^\d]/g, '')
            ,
                targets: ['my-bounty']
                orderDataType: 'dom-input-numeric'
                type: 'numeric'
        ]
        dom: '<"top"f>rt<"bottom"p>'
        autoWidth: false
        pagingType: 'full_numbers'
        language: default_pagination_language

Remove clutter from bounties page

Remove clutter from bounties page


$ ->
  $('span.editable').editable (value, settings) ->
    $span = $(this)
    url = $span.data('url')
    data = {_method: 'PUT'}
    data[$span.data('attribute')] = value
    $.post(url, data)
    value
  , tooltip: 'Click to edit', indicator: 'Saving...', submitdata: {}

#$ ->
#  $('body').on 'click', 'span.editable', ->
#    $this = $(this)
#    value = $this.text()
#    console.log(value)
#    $form = $("<form style='display: inline'><input type='text' value='#{value}' /></form>")
#    $form.on 'submit', (e) ->
#      e.preventDefault()
#      $this = $(this)
#      value = $this.find('input').val()
#      console.log("value: #{value}")
#      $this.replaceWith("#{value}")
#    $this.replaceWith($form)
#    $form.trigger('active')

$ ->
  $('span.editable').editable (value, settings) ->
    $span = $(this)
    data = {_method: 'PUT'}
    data[$span.data('attribute')] = value
    # TODO: We should handle failures and timeouts in POSTing, and make our own "Saving..." indicator.
    $.post($span.data('url'), data)
    value
  , tooltip: 'Click to edit'

Clean up JS for editable.

Clean up JS for editable.


i18n = require("i18next")
_ = require("underscore")
path = require("path")

module.exports =

	setup: (options) ->
		subdomainLang = options?.subdomainLang || {}
		availableLngs = _.pluck(_.values(subdomainLang), "lngCode")
		i18n.init
			resGetPath: path.resolve(__dirname,"../../", "locales/__lng__.json")
			saveMissing: true
			resSetPath: path.resolve(__dirname,"../../", "locales/missing-__lng__.json")
			sendMissingTo: "fallback"
			fallbackLng: options?.defaultLng || "en"
			detectLngFromHeaders: true
			useCookie: false
			preload: availableLngs
			supportedLngs: availableLngs
		setLangBasedOnDomainMiddlewear = (req, res, next) ->

			host = req.headers.host
			if !host?
				return next()
			subdomain = host.slice(0, host.indexOf("."))
			if !subdomain?
				return next()
			lang = options?.subdomainLang?[subdomain]?.lngCode
			if req.originalUrl.indexOf("setLng") == -1 and lang?
				req.i18n.setLng lang
			if req.language != req.lng
				req.showUserOtherLng = req.language
			next()

		expressMiddlewear: i18n.handle
		setLangBasedOnDomainMiddlewear: setLangBasedOnDomainMiddlewear
		i18n: i18n

i18n = require("i18next")
_ = require("underscore")
path = require("path")

module.exports =

	setup: (options) ->
		subdomainLang = options?.subdomainLang || {}
		availableLngs = _.pluck(_.values(subdomainLang), "lngCode")
		i18n.init
			resGetPath: path.resolve(__dirname,"../../", "locales/__lng__.json")
			saveMissing: true
			resSetPath: path.resolve(__dirname,"../../", "locales/missing-__lng__.json")
			sendMissingTo: "fallback"
			fallbackLng: options?.defaultLng || "en"
			detectLngFromHeaders: true
			useCookie: false
			preload: availableLngs
			supportedLngs: availableLngs
		setLangBasedOnDomainMiddlewear = (req, res, next) ->

			host = req.headers.host
			if !host?
				return next()
                              parts = host.split(/[.-]/)
			subdomain = parts[0]
			lang = options?.subdomainLang?[subdomain]?.lngCode
			if req.originalUrl.indexOf("setLng") == -1 and lang?
				req.i18n.setLng lang
			if req.language != req.lng
				req.showUserOtherLng = req.language
			next()

		expressMiddlewear: i18n.handle
		setLangBasedOnDomainMiddlewear: setLangBasedOnDomainMiddlewear
		i18n: i18n

Split language out of domain by - or .

Split language out of domain by - or .


{forwardMethods} = Trix.Helpers

class Trix.Logger
  loggers = {}

  @get: (name) ->
    loggers[name] ?= new Trix.Logger(console)

  forwardMethods ofObject: console, onConstructor: this, toProperty: "console"

  constructor: (@console, enabled) ->
    @disable() unless enabled

  enable: ->
    if @disabledConsole? and not @console?
      @console = @disabledConsole
      delete @disabledConsole

  disable: ->
    if @console?
      @disabledConsole = @console
      delete @console

  group: ->

  groupEnd: ->

  groupCollapsed: ->

  trace: ->

Patch IE's missing logging methods

Patch IE's missing logging methods


module.exports =
  treeView: null

  activate: (rootView, @state) ->
    if state
      @createView().attach() if state.attached
    else if rootView.project.getPath() and not rootView.pathToOpenIsFile
      @createView().attach()

    rootView.command 'tree-view:toggle', => @createView().toggle()
    rootView.command 'tree-view:reveal-active-file', => @createView().revealActiveFile()

  deactivate: ->
    @treeView?.deactivate()
    @treeView = null

  serialize: ->
    if @treeView?
      @treeView.serialize()
    else
      @state

  createView: ->
    unless @treeView?
      TreeView = require 'tree-view/lib/tree-view'
      @treeView = TreeView.activate(@state)
    @treeView

module.exports =
  treeView: null

  activate: (@state) ->
    if state
      @createView().attach() if state.attached
    else if rootView.project.getPath() and not rootView.pathToOpenIsFile
      @createView().attach()

    rootView.command 'tree-view:toggle', => @createView().toggle()
    rootView.command 'tree-view:reveal-active-file', => @createView().revealActiveFile()

  deactivate: ->
    @treeView?.deactivate()
    @treeView = null

  serialize: ->
    if @treeView?
      @treeView.serialize()
    else
      @state

  createView: ->
    unless @treeView?
      TreeView = require 'tree-view/lib/tree-view'
      @treeView = TreeView.activate(@state)
    @treeView

Remove rootView as parameter to activate