Try to pass first failing test

Try to pass first failing test

--- test/spec/test_reactive.coffee
+++ test/spec/test_reactive.coffee
@@ -96,9 +96,8 @@

     it 'should have the right tag', ->
       expect(elt).toBeDefined()
-      expect(elt.is('rect')).toBe(true)
       console.log(elt)
-      expect(elt instanceof SVGElement).toBe(true)
+      expect(elt instanceof SVGRectElement).toBe(true)
     it 'should have the set attributes', ->
       expect(elt.attr('x')).toBe('10')
     it 'should have the given child contents', ->


remove cnxml wrap when abstract exists

remove cnxml wrap when abstract exists

--- src/scripts/models/contents/node.coffee
+++ src/scripts/models/contents/node.coffee
@@ -37,6 +37,10 @@
       # Don't overwrite the title from the book's table of contents
       #if @get('title') then delete response.title
       response.title = @get('title') or response.title
+
+      # extract abstract from cnxml wrapper
+      if response.abstract?
+        response.abstract = $(response.abstract).unwrap().html()

       if response.mediaType is 'application/vnd.org.cnx.collection'
         # Only load the contents once


Added a todo

Added a todo

--- src/server/common/passportConfig.coffee
+++ src/server/common/passportConfig.coffee
@@ -34,6 +34,11 @@

 passport.use new BearerStrategy (accessToken, done) ->
 	db.accessTokens.find accessToken, (err, token) ->
+		### TODO
+		When !token, invalidate the token associated with the user if the user
+		has an active token. Consider logging events like this or even sending
+		an email to the user. "Someone tried to pretend to be you."
+		###
 		if err then	return done err, false, { message: generic }
 		else if !token then return done null, false, { message: credentials }
 		else db.users.find token.userID, (err, user) ->


only emit pageloaded after the scripts executed

--- src/server/virtual_browser/index.coffee
+++ src/server/virtual_browser/index.coffee
@@ -267,18 +267,20 @@
         if !@browserInitialized
             return @queuedSockets.push(socket)

-        nodes = serialize(@browser.window.document,
-                          @resources,
-                          @browser.window.document,
-                          @server.config)
-        compressionTable = undefined
-        if @server.config.compression
-            compressionTable = @compressor.textToSymbol
-        socket.emit('PageLoaded',
-                    nodes,
-                    @registeredEventTypes,
-                    @browser.clientComponents,
-                    compressionTable)
+        if not @browserLoading
+            nodes = serialize(@browser.window.document,
+                              @resources,
+                              @browser.window.document,
+                              @server.config)
+            compressionTable = undefined
+            if @server.config.compression
+                compressionTable = @compressor.textToSymbol
+            socket.emit('PageLoaded',
+                        nodes,
+                        @registeredEventTypes,
+                        @browser.clientComponents,
+                        compressionTable)
+
         @sockets.push(socket)
         gc() if @server.config.traceMem
         @emit('ClientAdded')


can set properties to not be enumerated by serializers

--- spec/notice/message_spec.coffee
+++ spec/notice/message_spec.coffee
@@ -63,8 +63,11 @@
                 internalCode: 'R'

         m = new Message
+        m.internalCode.should.equal 'R'
         m.should.eql {}
         done()
+
+


Fix project creation

Fix project creation

--- client/create.coffee
+++ client/create.coffee
@@ -133,7 +133,7 @@
               "Failed to create project due to error on server")
           else
             logger.info("Successfully created project")
-            Router.go("/#{qualifiedId}")
+            Router.go("/u/#{qualifiedId}")
       )
     , (err) ->
       Session.set("isWaiting", false)


Refactor server

Refactor server

--- usercycle.coffee
+++ usercycle.coffee
@@ -40,20 +40,34 @@

   # Wrap createUser so we can modify the callback
   createUser = Accounts.createUser
-  Accounts.createUser = ->
+  Accounts.createUser = (options, callback)->
     args = _.values arguments
-    callback = args[args.length-1]
+    if Meteor.isClient
+      callback = args[args.length-1]

-    if _.isFunction callback
-      args[args.length-1] = (error) ->
-        trackSignup error
-        callback error
-    else
-      args.push (error) ->
-        trackSignup error
+      if _.isFunction callback
+        args[args.length-1] = (error) ->
+          trackSignup error
+          callback error
+      else
+        args.push (error) ->
+          trackSignup error

-    createUser.apply @, args
+    userId = createUser.apply @, args

+    if Meteor.isServer
+      eventName = settings?.signup?.name or "Signed Up"
+      g.analytics.track
+        userId: userId
+        event: eventName
+        properties:
+          user:
+            userId: userId
+            email: options?.email
+            createdAt: new Date()
+      log "Tracked #{eventName}"
+
+    userId

   # Itegration with IR
   Router.onRun ->


chore(test): remove double empty line at eof

--- test/unit/document-spec.coffee
+++ test/unit/document-spec.coffee
@@ -397,4 +397,3 @@
       done()

     document.delete req, res, assert.ifError
-


Generalize the test matcher.

Generalize the test matcher.

--- testing/conf/karma-conf.coffee
+++ testing/conf/karma-conf.coffee
@@ -43,9 +43,9 @@
       config: 'jspm.config.js'
       # The unit test suites. Note that neither the tests nor the serveFiles
       # match the *.e2e-spec.* integration tests.
-      loadFiles: ['src/**/*.spec.*']
+      loadFiles: ['src/*/*.spec.*']
       # The app, TypeScript config and typings are loaded on demand.
-      serveFiles: ['src/**/*!(.spec)*.*', 'tsconfig.json', 'typings/**/*.d.ts']
+      serveFiles: ['src/*/*!(spec).*', 'tsconfig.json', 'typings/**/*.d.ts']

     # The test results reporter.
     # Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'


Don't rely on data-url to find article identifier

For the only current user (robots.thoughtbot.com), data-url is
equivalent to location.pathname which will work everywhere without
changes to markup.

--- templates/embed/Article.coffee
+++ templates/embed/Article.coffee
@@ -1,6 +1,6 @@
 class Article
   constructor: (@element) ->
-    @id = @element.getAttribute('data-url').replace(/\//g, '')
+    @id = location.pathname
     @title = document.title
     @author = CarnivalOptions.article_author
     @container = @createContainer()


syntactic sugar.

syntactic sugar.

--- web/coffee/registration.coffee
+++ web/coffee/registration.coffee
@@ -4,7 +4,7 @@
   .done (data) ->
     $("#message-box").html(data.message)

-$(document).ready ->
+$ ->
   $("#user-registration-form").on "submit", submit_registration

   $("#new-team-registration").hide()


Added acknowledgement for John Vilk and Plasma

--- web/scripts/referenceUI.coffee
+++ web/scripts/referenceUI.coffee
@@ -249,7 +249,7 @@
     Acknowledgements

     We wish to thank Holly, Maggie and Abby and the other participants at the 2013 University of Illinois Computer Science Summer G.A.M.E.S Camp for their game ideas, feedback and testing.

-    We wish to thank CJ Carey and the other developers of Doppio-JVM and BrowserFS for use of their software and their support of this project.

+    We wish to thank CJ Carey, John Vilk and the other developers of Doppio-JVM (a project by the Plasma research group at UMass) and BrowserFS for use of their software and their support of this project.

     Software development and bug contribution

     Original software created by University of Illinois students and faculty, Chris Liu, Fabian Junge, James Kelly and Lawrence Angrave.


Fix generator spec

Fix generator spec

--- test/lib/generator_spec.coffee
+++ test/lib/generator_spec.coffee
@@ -21,6 +21,7 @@
         bozonVersion: "0.3.8",
         electronVersion: "1.2.1",
         name: 'TestApp',
+        author: null,
         year: date.getFullYear()
       })


change test case names

change test case names

--- test/unit/provider.spec.coffee
+++ test/unit/provider.spec.coffee
@@ -1,20 +1,20 @@
-describe 'provider', ->
+describe 'L10n provider', ->
 	provider = null
 	beforeEach ->
-		angular.module('test-app', ['l10n']).config (l10nProvider) -> provider = l10nProvider
-		module 'test-app'
+		angular.module('test-provider', ['l10n']).config (l10nProvider) -> provider = l10nProvider
+		module 'test-provider'
 		inject ->
 	afterEach ->
 		# cleanup
 		provider.localeMessages = {}
 		provider.db = {}

-	it 'Provider found', ->
+	it 'should exist', ->
 		expect(provider).toBeDefined()
-	it 'Message DB is empty first', ->
+	it 'should have empty message DB initially', ->
 		expect(provider.localeMessages).toEqual {}
 		expect(provider.db).toEqual {}
-	it 'Adding locale messages', ->
+	it 'should be able to add locale messages', ->
 		provider.add 'uk-UA', key: 'message'
 		expect(provider.localeMessages).toEqual 'uk-UA': {key: 'message'}
 		expect(provider.db).toEqual {}
@@ -22,14 +22,15 @@
 		expect(provider.localeMessages).toEqual
 			'uk-UA': {key: 'message'}
 			'en-US': {key: 'message'}
-	it 'Adding same locale multiple times extends messages array', ->
+	it 'should extend locale messages when locale is added multiple times', ->
 		provider.add 'en-US', key: 'message'
 		provider.add 'en-US', key2: 'message2'
 		expect(provider.localeMessages).toEqual
 			'en-US': {key: 'message', key2: 'message2'}
-	it 'transforming input using "transform"', ->
+	it 'should transform input using "transform"', ->
 		provider.transform = (locale, values) ->
 			values[key] = '!!!' + value for key, value of values
 			return values
 		provider.add 'uk-UA', key: 'message'
 		expect(provider.localeMessages).toEqual 'uk-UA': {key: '!!!message'}
+		provider.transform = null


removing the registration of the message_handler. this is done in the native code.

--- src/bridges/JSCoreBridge.coffee
+++ src/bridges/JSCoreBridge.coffee
@@ -19,8 +19,3 @@
     #JSON.stringify(message)
     #no need to turn into string for iOS
     message
-
-  bindNativeBridge: ->
-    # register the handler when the native is ready
-    window.__JSCoreBridgeImpl.registerHandler steroids.nativeBridge.message_handler
-    super.bindNativeBridge()


Use node by default; don't depend on coffee.

--- lib/beantest.coffee
+++ lib/beantest.coffee
@@ -3,7 +3,11 @@
 fs     = require 'fs'

 REFRESH_RATE = 500        # in msecs
-RUN_PATH     = path.join __dirname, "run_test.coffee"
+EXECUTE_WITH = "node"
+RUN_PATH     = path.join __dirname, "run_test.js"
+unless path.exists RUN_PATH
+  EXECUTE_WITH = "coffee"
+  RUN_PATH     = path.join __dirname, "run_test.coffee"
 seen         = {}         # cache of file names
 shouldRun    = true       # if a change in file was detected
 canRun       = true       # if tests are running right now, don't run.
@@ -15,7 +19,7 @@

 beantest = (persistent=true) ->
   if shouldRun and canRun
-    exec "coffee #{RUN_PATH}", (error, stdout, stderr) ->
+    exec "#{EXECUTE_WITH} #{RUN_PATH}", (error, stdout, stderr) ->
       console.log(if error then stderr else stdout)
       canRun = true
     shouldRun = canRun = false


fix if

fix if

--- src/browser_client/system_modules/socketstream.coffee
+++ src/browser_client/system_modules/socketstream.coffee
@@ -59,7 +59,7 @@
   console.log('Reloading as files have changed...')
   window.location.reload()

-# Update browser is update system event receieved
+# Update browser if update system event receieved
 server.on '__ss:update', ->
   console.log('Updating as files have changed...')
   for tag in document.getElementsByTagName("link")


:new: Add linter:toggle command

:new: Add linter:toggle command

--- lib/commands.coffee
+++ lib/commands.coffee
@@ -5,9 +5,15 @@
     @_subscriptions = new CompositeDisposable
     @_subscriptions.add atom.commands.add 'atom-workspace',
       'linter:next-error': @nextError.bind(@)
+      'linter:toggle': @toggleLinter.bind(@)

     # Default values
     @_messages = null
+
+  toggleLinter: ->
+    activeEditorLinter = @linter.getActiveEditorLinter()
+    return unless activeEditorLinter
+    activeEditorLinter.toggleStatus()

   nextError: ->
     if not @_messages or (next = @_messages.next()).done


improve

improve

--- lib/commands.coffee
+++ lib/commands.coffee
@@ -5,8 +5,11 @@

 # ex command
 # -------------------------
-w = ->
-  atom.workspace.saveActivePaneItem()
+w = ({editor}={}) ->
+  if editor?.getPath()
+    editor.save()
+  else
+    atom.workspace.saveActivePaneItem()

 q = ->
   atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow()
@@ -17,15 +20,14 @@

 qall = ->
   q() for item in atom.workspace.getPaneItems()
-    # q()
-    # atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow()
+
+wall = ->
+  w({editor}) for editor in atom.workspace.getTextEditors() when editor.isModified()

 wqall = ->
-  # wq()
-  for editor in atom.workspace.getTextEditors() when editor.isModified()
-    w({editor})
-  qall()
-
+  for item in atom.workspace.getPaneItems()
+    w()
+    q()

 split = ({editor, editorElement}) ->
   dispatch(editorElement, 'pane:split-down-and-copy-active-item')
@@ -33,10 +35,8 @@
 vsplit = ({editor, editorElement}) ->
   dispatch(editorElement, 'pane:split-right-and-copy-active-item')

-
 # Configuration switch
 # -------------------------
-
 # Util
 toggleConfig = (param) ->
   value = atom.config.get(param)
@@ -71,6 +71,7 @@
   normalCommands: {
     w
     wq
+    wall
     wqall
     q
     qall


formatting

formatting

--- lib/git-plus.coffee
+++ lib/git-plus.coffee
@@ -1,46 +1,46 @@
-{CompositeDisposable} = require 'atom'
-{$} = require 'atom-space-pen-views'
-git = require './git'
-contextCommandMap = require './context-command-map'
-configurations = require './config'
-OutputViewManager = require './output-view-manager'
-GitPaletteView = require './views/git-palette-view'
-GitAddContext = require './models/git-add-context'
-GitBranch = require './models/git-branch'
-GitDeleteLocalBranch = require './models/git-delete-local-branch.coffee'
-GitDeleteRemoteBranch = require './models/git-delete-remote-branch.coffee'
-GitCheckoutAllFiles = require './models/git-checkout-all-files'
+{CompositeDisposable}  = require 'atom'
+{$}                    = require 'atom-space-pen-views'
+git                    = require './git'
+contextCommandMap      = require './context-command-map'
+configurations         = require './config'
+OutputViewManager      = require './output-view-manager'
+GitPaletteView         = require './views/git-palette-view'
+GitAddContext          = require './models/git-add-context'
+GitBranch              = require './models/git-branch'
+GitDeleteLocalBranch   = require './models/git-delete-local-branch.coffee'
+GitDeleteRemoteBranch  = require './models/git-delete-remote-branch.coffee'
+GitCheckoutAllFiles    = require './models/git-checkout-all-files'
 GitCheckoutCurrentFile = require './models/git-checkout-current-file'
-GitCherryPick = require './models/git-cherry-pick'
-GitCommit = require './models/git-commit'
-GitCommitAmend = require './models/git-commit-amend'
-GitDiff = require './models/git-diff'
-GitDifftool = require './models/git-difftool'
-GitDifftoolContext = require './models/git-difftool-context'
-GitDiffAll = require './models/git-diff-all'
-GitFetch = require './models/git-fetch'
-GitFetchPrune = require './models/git-fetch-prune.coffee'
-GitInit = require './models/git-init'
-GitLog = require './models/git-log'
-GitPull = require './models/git-pull'
-GitPush = require './models/git-push'
-GitRemove = require './models/git-remove'
-GitShow = require './models/git-show'
-GitStageFiles = require './models/git-stage-files'
-GitStageHunk = require './models/git-stage-hunk'
-GitStashApply = require './models/git-stash-apply'
-GitStashDrop = require './models/git-stash-drop'
-GitStashPop = require './models/git-stash-pop'
-GitStashSave = require './models/git-stash-save'
-GitStashSaveMessage = require './models/git-stash-save-message'
-GitStatus = require './models/git-status'
-GitTags = require './models/git-tags'
-GitUnstageFiles = require './models/git-unstage-files'
-GitRun = require './models/git-run'
-GitMerge = require './models/git-merge'
-GitRebase = require './models/git-rebase'
-GitOpenChangedFiles = require './models/git-open-changed-files'
-diffGrammars = require './grammars/diff.js'
+GitCherryPick          = require './models/git-cherry-pick'
+GitCommit              = require './models/git-commit'
+GitCommitAmend         = require './models/git-commit-amend'
+GitDiff                = require './models/git-diff'
+GitDifftool            = require './models/git-difftool'
+GitDifftoolContext     = require './models/git-difftool-context'
+GitDiffAll             = require './models/git-diff-all'
+GitFetch               = require './models/git-fetch'
+GitFetchPrune          = require './models/git-fetch-prune.coffee'
+GitInit                = require './models/git-init'
+GitLog                 = require './models/git-log'
+GitPull                = require './models/git-pull'
+GitPush                = require './models/git-push'
+GitRemove              = require './models/git-remove'
+GitShow                = require './models/git-show'
+GitStageFiles          = require './models/git-stage-files'
+GitStageHunk           = require './models/git-stage-hunk'
+GitStashApply          = require './models/git-stash-apply'
+GitStashDrop           = require './models/git-stash-drop'
+GitStashPop            = require './models/git-stash-pop'
+GitStashSave           = require './models/git-stash-save'
+GitStashSaveMessage    = require './models/git-stash-save-message'
+GitStatus              = require './models/git-status'
+GitTags                = require './models/git-tags'
+GitUnstageFiles        = require './models/git-unstage-files'
+GitRun                 = require './models/git-run'
+GitMerge               = require './models/git-merge'
+GitRebase              = require './models/git-rebase'
+GitOpenChangedFiles    = require './models/git-open-changed-files'
+diffGrammars           = require './grammars/diff.js'

 baseWordGrammar = __dirname + '/grammars/word-diff.json'
 baseLineGrammar = __dirname + '/grammars/line-diff.json'


referrable email: add signature annotations

--- workers/social/lib/social/models/referrableemail.coffee
+++ workers/social/lib/social/models/referrableemail.coffee
@@ -6,6 +6,21 @@
   @share()

   @set
+
+    sharedMethods :
+
+      static      :
+        invite    :
+          (signature String, Function)
+        getUninvitedEmails:
+          (signature Function)
+        deleteEmailsForAccount:
+          (signature Function)
+
+      instance    :
+        invite    :
+          (signature Function)
+
     schema        :
       title       : String
       email       :
@@ -21,9 +36,6 @@
       modifiedAt  :
         type      : Date
         get       : -> new Date
-    sharedMethods :
-      static      : ["invite", "getUninvitedEmails", "deleteEmailsForAccount"]
-      instance    : ["invite"]

   @create: (clientId, {email, title}, callback)->
     JSession = require "./session"


event refac part3

event refac part3

--- client/Framework/components/tree/treeviewcontroller.coffee
+++ client/Framework/components/tree/treeviewcontroller.coffee
@@ -136,23 +136,23 @@
     node2PId = @getNodePId node2.getData()

     return node1PId is node2PId
-
+
   ###
   DECORATORS
   ###
-
+
   setFocusState:->
-
+
     view = @getView()
     @getSingleton("windowController").addLayer view
     view.unsetClass "dim"
-
+
   setBlurState:->

     view = @getView()
     @getSingleton("windowController").removeLayer view
     view.setClass "dim"
-
+
   ###
   CRUD OPERATIONS FOR NODES
   ###
@@ -324,11 +324,7 @@

   setMainListeners:->

-    @listenTo
-      KDEventTypes       : "ReceivedMouseUpElsewhere"
-      listenedToInstance : @getSingleton("windowController")
-      callback           : (windowController, event)=>
-        @mouseUp windowController, event
+    @getSingleton("windowController").on "ReceivedMouseUpElsewhere", (event)=> @mouseUp event

     @getView().on "ReceivedClickElsewhere", => @setBlurState()

@@ -453,7 +449,7 @@
   showDragOverFeedback: do ->
     _.throttle (nodeView, event)->

-      # log "show", nodeView.getData().name
+      # log "show", nodeView.getData().name
       nodeData = nodeView.getData()
       if nodeData.type isnt "file"
         nodeView.setClass "drop-target"
@@ -467,7 +463,7 @@

   clearDragOverFeedback: do ->
     _.throttle (nodeView, event)->
-
+
       # log "clear", nodeView.getData().name
       nodeData = nodeView.getData()
       if nodeData.type isnt "file"
@@ -551,8 +547,8 @@
       @mouseIsDown = no
       @mouseDownTempItem = null

-  mouseUp:(pubInst, event)->
-
+  mouseUp:(event)->
+
     clearTimeout @mouseDownTimer
     @mouseIsDown = no
     @cancelDrag = no


resurrection: remove active content display from main tab view when showing another display

--- client/Main/ContentDisplay/ContentDisplayController.coffee
+++ client/Main/ContentDisplay/ContentDisplayController.coffee
@@ -20,19 +20,21 @@

   showDisplay:(view)->

-    {@mainTabView} = KD.singleton "mainView"
     tabPane = new ContentDisplay
       name  : 'content-display'
       type  : 'social'
+      view  : view
+
+    tabPane.on 'KDTabPaneInactive', => @hideDisplay view

     @displays[view.id] = view
-    tabPane.addSubView view
+
+    {@mainTabView} = KD.singleton "mainView"
+    activePane = @mainTabView.getActivePane()
+    @hideDisplay activePane.getMainView()  if activePane
     @mainTabView.addPane tabPane

     KD.singleton('dock').navController.selectItemByName 'Activity'
-
-    tabPane.on 'KDTabPaneInactive', => @hideDisplay view
-
     return tabPane


instead of undefined pass as ''

instead of undefined pass as ''

--- client/landing/app/MainApp/VirtualizationController.coffee
+++ client/landing/app/MainApp/VirtualizationController.coffee
@@ -487,7 +487,7 @@

     unless @defaultVmName
       content = """To #{if appName then 'use' else 'do this'}
-                 #{appName} you need to have at lease one VM created,
+                 #{appName or ''} you need to have at lease one VM created,
                  you can do that by clicking 'Create Default VM' button
                  below."""


kite: more improvements to multiple kites mode

--- client/landing/app/MainApp/VirtualizationController.coffee
+++ client/landing/app/MainApp/VirtualizationController.coffee
@@ -19,10 +19,9 @@
         withArgs : command

     @fetchVmName options, (err, vmName) =>
-      return callback err  if err?
-
-      if /^vm\./.test options.method
-        options.kiteName = "os-local"
+
+      # if /^vm\./.test options.method
+      #   options.kiteName = "osk"

       if vmName is "local-#{KD.whoami().profile.nickname}"
         if /^fs\./.test options.method
@@ -30,6 +29,9 @@

         if /^webterm\./.test options.method
             options.kiteName = "terminal"
+
+        if /^vm\./.test options.method
+          options.kiteName = "fs"

       if options.method in ['exec', 'spawn']
         options.kiteName = "os-local"


Credentials: updateCredentialSelections only if there is a stackTemplate

--- client/new-stack-editor/lib/controllers/credentials.coffee
+++ client/new-stack-editor/lib/controllers/credentials.coffee
@@ -98,6 +98,8 @@

   updateCredentialSelections: ->

+    return  unless @getData()
+
     identifiers = @getData().getCredentialIdentifiers()
     @list.items.forEach (item) ->
       item.select item.getData().identifier in identifiers


Wrap child process kill in a try catch

Wrap child process kill in a try catch

--- src/ChildProcess.coffee
+++ src/ChildProcess.coffee
@@ -5,8 +5,6 @@
 Pipe = require("./Pipe")

 class ChildProcess
-  #TODO: Remove
-  @children: []

   child: null

@@ -52,7 +50,6 @@
     @command = command

     @child = _spawn(command,args,options)
-    ChildProcess.children[@child.pid] = @child

     if pipeClass
       @pipe = new pipeClass(@child.stdout,@child.stderr)
@@ -60,7 +57,6 @@
       @pipe = new Pipe(@child.stdout,@child.stderr)

     @child.on "exit", (code,signal)=>
-      delete ChildProcess.children[@child.pid]
       if code?
         log.info "#{command} exited with code: #{code}"
       else if signal?


activity: render modals on top of content if it exists

--- client/activity/lib/components/appcomponent/index.coffee
+++ client/activity/lib/components/appcomponent/index.coffee
@@ -7,6 +7,13 @@

 module.exports = class ActivityAppComponent extends React.Component

+  constructor: (props) ->
+
+    super props
+
+    @state = { content: props.content, modal: props.modal }
+
+
   getClassName: ->

     return classnames
@@ -15,10 +22,26 @@
       'is-withModal'         : @props.modal

+  componentWillReceiveProps: (nextProps) ->
+
+    { content: currentContent, modal: currentModal } = @props
+    { content: nextContent, modal: nextModal } = nextProps
+
+    # next there will be a modal rendered,
+    # there is already a content on the back,
+    # but the route didn't inject any content;
+    # then set currentContent to be rendered as content.
+    if nextModal and currentContent and not nextContent
+      @setState { modal: nextModal, content: currentContent }
+    else
+      @setState { modal: nextModal, content: nextContent }
+
+
+
   render: ->
     <div className={@getClassName()}>
-      {@props.content}
-      {@props.modal}
+      {@state.content}
+      {@state.modal}
     </div>


client: fix case

client: fix case

--- client/app/lib/activity/sidebar/sidebarmachinebox.coffee
+++ client/app/lib/activity/sidebar/sidebarmachinebox.coffee
@@ -3,7 +3,7 @@
 KDView = kd.View
 KDListViewController = kd.ListViewController
 KDCustomHTMLView = kd.CustomHTMLView
-Machine = require 'app/providers/Machine'
+Machine = require 'app/providers/machine'
 NavigationMachineItem = require 'app/navigation/navigationmachineitem'
 SidebarWorkspaceItem = require './sidebarworkspaceitem'
 MoreWorkspacesModal = require 'app/activity/sidebar/moreworkspacesmodal'


Use new selectfield chooser

Use new selectfield chooser

--- client/skr/screens/fresh-books-import/ChooseRecords.cjsx
+++ client/skr/screens/fresh-books-import/ChooseRecords.cjsx
@@ -13,12 +13,12 @@

     getUser: ->
         if @props.row.mapped_user_id
-            user = USERS.get(@props.row.mapped_user_id)
-            label: user.login, id: user.id
+            USERS.get(@props.row.mapped_user_id)
         else null

-    setUser: (val, user) ->
+    setUser: (user) ->
         @props.row.mapped_user_id = user.id
+        @forceUpdate()

     render: ->
         <LC.SelectField
@@ -26,10 +26,10 @@
             model={this.user}
             name="user"
             labelField='login'
+            queryModel={Lanes.Models.User}
             getSelection={@getUser}
             setSelection={@setUser}
-            collection={USERS}
-            fetchWhenOpen={false}
+            choices={USERS.models}
         />


Test conditional practice button rendering

--- test/components/learning-guide/weaker-panel.spec.coffee
+++ test/components/learning-guide/weaker-panel.spec.coffee
@@ -21,7 +21,14 @@
     Testing.renderComponent( Weaker, props: @props ).then ({dom}) =>
       expect(dom.querySelector('.title').textContent).to.equal(@props.weakerTitle)

-  it 'can practice sections', ->
+
+  it 'hides practice button if onPractice property is not given', ->
+    Testing.renderComponent( Weaker, props: @props ).then ({dom}) ->
+      practice = dom.querySelector('.practice.btn')
+      expect(practice).to.be.null
+
+  it 'can practice sections if onPractice property is given', ->
+    @props.onPractice = sinon.spy()
     Testing.renderComponent( Weaker, props: @props ).then ({dom}) ->
       practice = dom.querySelector('.practice.btn')
       expect(practice).to.not.be.null


add related content link to readings

add related content link to readings

--- tutor/src/components/task-step/step-with-reading-content.cjsx
+++ tutor/src/components/task-step/step-with-reading-content.cjsx
@@ -3,6 +3,7 @@
 {TaskStepStore} = require '../../flux/task-step'
 {ArbitraryHtmlAndMath, ChapterSectionMixin} = require 'shared'
 {BookContentMixin, LinkContentMixin} = require '../book-content-mixin'
+RelatedContentLink = require '../related-content-link'

 # TODO: will combine with below, after BookContentMixin clean up
 ReadingStepContent = React.createClass
@@ -22,13 +23,13 @@
   shouldOpenNewTab: -> true
   render: ->
     {id, courseDataProps, stepType} = @props
-    {content_html} = TaskStepStore.get(id)
-
-    <ArbitraryHtmlAndMath
-      {...courseDataProps}
-      className={"#{stepType}-step"}
-      html={content_html} />
-
+    {content_html, related_content} = TaskStepStore.get(id)
+    <div className="#{stepType}-step">
+      <ArbitraryHtmlAndMath
+        {...courseDataProps}
+        html={content_html} />
+      <RelatedContentLink courseId={@props.courseId} content={related_content} />
+    </div>

 StepContent = React.createClass
   displayName: 'StepContent'


Update Cilantro max Serrano version to 2.1.1

--- src/coffee/cilantro/core.coffee
+++ src/coffee/cilantro/core.coffee
@@ -29,7 +29,7 @@
         # will be warned if no version number is found or if it is less than this
         # minimum to prepare them in the case of missing or broken functionality.
         minSerranoVersion: '2.0.18'
-        maxSerranoVersion: '2.1.0'
+        maxSerranoVersion: '2.1.1'

         # Returns the current session's Serrano version. If there is no
         # active session or version defined, the absolute minimum is returned.


[LFTILI-215] boucning users to root on success or fail logout

--- src/coffee/services/auth.coffee
+++ src/coffee/services/auth.coffee
@@ -37,7 +37,11 @@

     logout: () ->
       active_user = null
-      Api.Auth.logout().$promise.then () -> $location.path('/')
+
+      bounce = () ->
+        $location.path '/'
+
+      Api.Auth.logout().$promise.then bounce bounce

     attempt: (creds) ->
       defer = $q.defer()


Quick loop cleanup

Quick loop cleanup

--- scripts/main.coffee
+++ scripts/main.coffee
@@ -8,9 +8,7 @@
 new ZooniverseBar el: $('#zooniverse-bar')

 Pager = require 'lib/Pager'
-pagers = $('[data-page]').parent().map ->
-	new Pager
-		el: @
+pagers = (new Pager el: parent for parent in $('[data-page]').parent())

 Subject = require 'models/Subject'
 for i in [1..10] then Subject.create


Hide the upload container if cancelled last item

If the uploader shows an error ()ie. the file suze is too large the uploader displays a error message and the user can close this message. The uploader container stays open. This changes this behavior in that it closes the upload container when the last remaining item was closed.

--- app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee
+++ app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee
@@ -58,6 +58,9 @@
   @$fileProgressCancel.hide()
   @$fileProgressWrapper.delay(1500).fadeOut ->
     $(this).remove()
+    if $('.upload-progress-container').is(':empty')
+      $('.overall-upload').removeClass('visible')
+    return

 Alchemy.FileProgress::setStatus = (status) ->
   @$fileProgressStatus.text Alchemy.t(status)


label

label

--- app/assets/javascripts/components/kid_mentor_schedules.js.cjsx
+++ app/assets/javascripts/components/kid_mentor_schedules.js.cjsx
@@ -92,7 +92,7 @@

-
Mentoren Filtern:

+
Mentoren anzeigen:

             <MentorsForDisplayingFilter
               mentors=filteredMentors


Bind artista and recordings to event

Bind artista and recordings to event

--- app/assets/javascripts/controllers/player_controller.js.coffee
+++ app/assets/javascripts/controllers/player_controller.js.coffee
@@ -8,11 +8,11 @@

   artists: (->
     @get('event.artists')
-  ).property('event.artists')
+  ).property('event')

   recordings: (->
     @get('artists').map((artist) -> artist.get('recordings').toArray().shuffle()[0..1]).flatten()
-  ).property('artists.@each.recordings.@each')
+  ).property('event')

   playing: (->
     @get('currentState') == @get('states.playing')


#516 fixed sorting for tracings on dev

#516 fixed sorting for tracings on dev

--- app/assets/javascripts/dashboard/models/dashboard_model.coffee
+++ app/assets/javascripts/dashboard/models/dashboard_model.coffee
@@ -61,8 +61,9 @@

   createCollection: (name) ->
-    collection = new Backbone.Collection()
+    collection = new PaginationCollection()
     # Display newst first.
+    collection.bootstrap()
     collection.sortBy("created")
     collection.add(@get(name))
     @set(name, collection)


Implemented assert

Implemented assert

--- bin/heyu-run.coffee
+++ bin/heyu-run.coffee
@@ -3,6 +3,14 @@
 # by Pjotr Prins (c) 2013

 load('lib/statemachine.js')
+
+AssertError = (@message) ->
+
+assert = (expr, message='', got='unknown') ->
+  unless expr()
+    print 'Assertion failed',message,expr
+    print 'Got',got if got isnt 'unknown'
+    throw new AssertError(message)

 # ---- Clone objects
 clone = (obj) ->
@@ -47,6 +55,9 @@
   appl2.switchOff()
   appl2.display_state()
   appl.display_state()
+  print appl.currentState()
+  assert((-> appl.currentState() is "ON"),appl.name,appl.currentState())
+  assert((-> appl2.currentState() is "OFF"),appl2.name,appl2.currentState())
   print 'Tests passed'

 # ---- Parse the command line


conditional logic bug multiple conditions on a single rule

--- app/assets/javascripts/hanuman/conditional-logic.js.coffee
+++ app/assets/javascripts/hanuman/conditional-logic.js.coffee
@@ -45,6 +45,9 @@
         #TODO CLEAN UP THIS CODE WE HAVE STUFF IN HERE WE ARE NOT USING LIKE inRepeater
         # determine if we are in a repeater-this needs to get deleted-kdh
         inRepeater = false
+        $repeater = $conditionElement.closest(".form-container-repeater")
+        if $repeater.length > 0
+            inRepeater = true
         if rule.conditions.length > 1
           self.checkConditionsAndHideShow(rule.conditions, ancestorId, $ruleContainer, $ruleContainer, inRepeater, matchType)
         else


added dynamic dataset description

added dynamic dataset description

--- app/assets/javascripts/views/spotlight_dataset_view.coffee
+++ app/assets/javascripts/views/spotlight_dataset_view.coffee
@@ -33,9 +33,13 @@

<%= owningTeam %>

-
Original data and segmentation

+

Dataset: <%= name %>

-
<%= description %>

+        <% if(description) { %>
+
<%= description %>

+        <% } else { %>
+
Original data and segmentation

+        <% } %>

   """)


whitespace

whitespace

--- app/assets/javascripts/mixins/comprobante_on_form_mixin.js.coffee
+++ app/assets/javascripts/mixins/comprobante_on_form_mixin.js.coffee
@@ -9,9 +9,7 @@

   didInsertElement: ->
     @_super()
-    @$(".comprobante_select").chosen().on("change", $.proxy(@comprobanteSelectChanged, @)).
-      trigger("change")
-
+    @$(".comprobante_select").chosen().on("change", $.proxy(@comprobanteSelectChanged, @)).trigger("change")

   willDestroyElement: ->
     @_super()


planned intervention modale displayed

planned intervention modale displayed

--- app/assets/javascripts/backend/interventions_base.js.coffee
+++ app/assets/javascripts/backend/interventions_base.js.coffee
@@ -888,6 +888,23 @@
             $(e.currentTarget).find('.modal-footer').append(data)

+    $(document).on 'click', '.duplicate-intervention', (e) =>
+      e.stopImmediatePropagation();
+      interventions = $(e.currentTarget).data().interventions
+      $.ajax
+        url: '/backend/interventions/duplicate_interventions'
+        data: { interventions: interventions }
+        success: (data) =>
+          if $('#taskboard-modal').length > 0
+            interventionModal = new ekylibre.modal('#taskboard-modal')
+            interventionModal.getModal().modal 'hide'
+          else
+            interventionModal = new ekylibre.modal('#create-intervention-modal')
+            interventionModal.getModal().modal 'hide'
+          $('#wrap').after(data)
+          duplicateModal = new ekylibre.modal('#duplicate-modal')
+          duplicateModal.getModal().modal 'show'
+
     $(document).on 'click', '#duplicate-modal #validate-duplication', (e) =>
       e.stopImmediatePropagation();
       intervention = $(e.currentTarget).data().intervention


Minor fix to help text option for pick many tool (via #202)

--- app/assets/javascripts/components/core-tools/pick-many.cjsx
+++ app/assets/javascripts/components/core-tools/pick-many.cjsx
@@ -118,8 +118,8 @@
           {option.label}

-        {if tool.help
-
+        {if option.help
+
         }


stay in sync with changing world

stay in sync with changing world

--- app/assets/javascripts/jax/dev/views/tools/lights.js.coffee
+++ app/assets/javascripts/jax/dev/views/tools/lights.js.coffee
@@ -3,10 +3,17 @@

   initialize: ->
     @jax = @options.context
+    @jax.world.on 'lightAdded', @tainted
+    @jax.world.on 'lightRemoved', @tainted
     @render()

-  render: ->
+  render: =>
     @$el.empty()
     for light in @jax.world.lights
       @$el.append new Jax.Dev.Views.Tools.Lights.Item(model: light).$el
-    true+    true
+
+  _timeout = null
+  tainted: =>
+    clearTimeout _timeout if _timeout
+    _timeout = setTimeout @render, 10


don't show time for all day calendar events

fixes #CNVS-2582

test plan
- create an all day event
- ensure that the details popup shows only the date, not the time
- create a not all day event
- ensure that the details popup shows the time as well as date
- ensure that other event types like assignments and quizzes are
  unchanged

Change-Id: I4bd1cedcd33d098caf40a9d63fd62324b3e92183
Reviewed-on: https://gerrit.instructure.com/16599
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Zach Pendleton <514dbb4d54d4f29e454990df7d075678f43f92aa@instructure.com>
QA-Review: Marc LeGendre <d33c80bc45d65303e33ca83108a9952b745af9ef@instructure.com>

--- app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee
+++ app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee
@@ -52,7 +52,11 @@
         $.replaceTags(@contextInfo.calendar_event_url, 'id', @calendarEvent.parent_event_id ? @calendarEvent.id)

     displayTimeString: () ->
-      semanticDateRange(@calendarEvent.start_at, @calendarEvent.end_at)
+        if @calendarEvent.all_day
+          date = this.startDate()
+          "<time datetime='#{date.toISOString()}'>#{$.dateString(date)}</time>"
+        else
+          semanticDateRange(@calendarEvent.start_at, @calendarEvent.end_at)

     saveDates: (success, error) =>
       @save {


reworking the setState in the dynamic router

--- app/assets/javascripts/components/dynamic-router.cjsx
+++ app/assets/javascripts/components/dynamic-router.cjsx
@@ -27,10 +27,7 @@
         console.log 'workflow', workflow
         @setState mark_tasks: workflow.tasks if workflow.key is 'mark'
         @setState transcribe_tasks: workflow.tasks if workflow.key is 'transcribe'
-
-      @setState mark_tasks: workflow.tasks, => console.log "MARK FOWKFLOW: ", workflow if workflow.key is 'mark'
-
-      console.log 'At the end of the mount lifecycle'
+

   controllerForPage: (page) ->
     React.createClass


use uniform logging style

use uniform logging style

--- app/assets/javascripts/store/gestpay/iframe.js.coffee
+++ app/assets/javascripts/store/gestpay/iframe.js.coffee
@@ -4,10 +4,10 @@
   generate: ->
     # Probably not on the correct page
     if @browserSupported()
-      @log("GESTPAY: iframe initialized")
+      @log("iframe initialized")
       @getToken()
     else
-      @log("GESTPAY: browser not supported")
+      @log("browser not supported")

   browserSupported: ->
     # This variable is set on window directly by the initialization script of
@@ -27,11 +27,11 @@
       dataType: "json"
     .done (response) =>
       token = response.token
-      @log("GESTPAY: getToken success - #{token}")
+      @log("getToken success - #{token}")
       @createPaymentPage(token)
     .fail (response) =>
       json = $.parseJSON(response.responseText)
-      @log("GESTPAY: getToken failure - #{json.error}")
+      @log("getToken failure - #{json.error}")

   createPaymentPage: (token) ->
     GestPay.CreatePaymentPage(@merchant, token, @paymentPageLoaded)
@@ -46,13 +46,13 @@
     # Gestpay returns error codes as strings. Convert them to integers before
     # comparing them
     if parseInt(result.ErrorCode) == GESTPAY_NO_ERROR
-      @log("GESTPAY: iframe loaded!")
+      @log("iframe loaded!")
     else
-      @log("GESTPAY: error loading iframe: '#{result.ErrorDescription}'
+      @log("error loading iframe: '#{result.ErrorDescription}'
       (#{result.ErrorCode})")

   log: (string) ->
-    console.log && console.log(string)
+    console.log && console.log("[gestpay][iframe]: #{string}")

 $ ->
   $gestpay = $(".gestpay-data")


Remove leak to window.

Remove leak to window.

--- core/app/backbone/controllers/profile_controller.coffee
+++ core/app/backbone/controllers/profile_controller.coffee
@@ -92,8 +92,7 @@
         model: channel

   withFact: (fact)->
-    window.efv = new DiscussionView(model: fact)
-    @main.contentRegion.show(efv)
+    @main.contentRegion.show new DiscussionView(model: fact)

     username = fact.get('created_by').username
     return_to_text = "#{ username.capitalize() }'s profile"


All tests pass

All tests pass

--- src/god.coffee
+++ src/god.coffee
@@ -10,5 +10,5 @@
 exports.god = (rx, doc) ->
   god = new GOD()
   root = world(god, rx)
-  root.import(doc)
+  #root.import(doc)
   root


Allow for hosted images

Allow for hosted images

--- framer/Components/DeviceComponent.coffee
+++ framer/Components/DeviceComponent.coffee
@@ -272,7 +272,11 @@
 		return "#{@_deviceType}.png"

 	_deviceImageUrl: (name) ->
+
 		return null unless name
+
+		if _.startsWith(name, "http://") or _.startsWith(name, "https://")
+			return name

 		if Utils.isFramerStudio() and window.FramerStudioInfo
 			resourceUrl = window.FramerStudioInfo.deviceImagesUrl


Fix link to shards on Namespace.Overview

--- admin/static/coffee/namespaces/namespace.coffee
+++ admin/static/coffee/namespaces/namespace.coffee
@@ -100,7 +100,7 @@

         change_shards: (event) =>
             event.preventDefault()
-            @.$('.namespace_sharding-link').tab('show')
+            @.$('#namespace_sharding-link').tab('show')

         change_pinning: (event) =>
             event.preventDefault()


cancel fee option was appearing by default when order was canceled

--- app/assets/javascripts/app/manage_orders.coffee
+++ app/assets/javascripts/app/manage_orders.coffee
@@ -23,8 +23,8 @@
     @$element.find('.copy_actual_from_reservation a').click(@copyReservationTimeIntoActual)
     @init_total_calcuating()
     @init_price_updating()
+    @init_reconcile_note()
     @init_cancel_fee_options()
-    @init_reconcile_note()
     @init_resolution_note()
     @disable_form() if @$element.hasClass('disabled')


Show the right buttons (new/edit) at the right times.

This should finish the lifecycle of an ImageQuestion for stories [#54716124] and [#58992462]. We use the presence of Snapshot or Drawing buttons to determine what values make a question "answered" and show the appropriate buttons (create or edit) based on the presence of those values.

https://www.pivotaltracker.com/story/show/58992462
https://www.pivotaltracker.com/story/show/54716124

--- app/assets/javascripts/image_question.js.coffee
+++ app/assets/javascripts/image_question.js.coffee
@@ -127,6 +127,7 @@
   update_display: ->
     @current_thumbnail = $("#{@form_sel} [name=\"embeddable_image_question_answer[annotated_image_url]\"]").val() ||
                          $("#{@form_sel} [name=\"embeddable_image_question_answer[image_url]\"]").val()
+    @current_annotation = $("#image_question_annotation_for_#{@image_question_id}").val()
     @$thumbnail.show()
     @$thumbnail.attr("src", @current_thumbnail)
     @$thumbnail.hide()
@@ -137,17 +138,24 @@
     @$replace_button.hide()
     @$edit_button.hide()

-    if (@current_src or @current_thumbnail) and (@$text_response.val() != '')
-      @$edit_button.show()
-      @$replace_button.show()
-      @$drawing_button.hide()
-      @$snapshot_button.hide()
+    if (@$snapshot_button.length > 0) and (@current_src or @current_thumbnail)
+      # This is a shutterbug question, so it's answered if there's a thumbnail
+      @show_edit_buttons()
+    else if (@$drawing_button.length > 0) and @current_annotation
+      # This is a drawing question, so an annotation is needed for it to be answered
+      @show_edit_buttons()

     if @undo_button
       @undo_button.hide()
     if @last_src
       @$undo_button.show()
     @set_svg_background()
+
+  show_edit_buttons: =>
+    @$edit_button.show()
+    @$replace_button.show()
+    @$drawing_button.hide()
+    @$snapshot_button.hide()

   get_svg_canvas: =>
     svgCanvas["#{@svg_canvas_id}"]


Polygon tutorial edits

Polygon tutorial edits

--- app/assets/javascripts/inspector_address.coffee
+++ app/assets/javascripts/inspector_address.coffee
@@ -214,7 +214,7 @@
     steps: [
       {
         element: "#map-highlight"
-        intro: "Generally speaking, it's really easy to match most buildings with their street numbers. Click on the address number next to highlighted structure and type it into the text box that pops up."
+        intro: "By and large, it's pretty easy to match most buildings with their street numbers. Click on the address number next to highlighted structure and type it into the text box that pops up. Don't worry about the street names - we'll get those later."
         position: "right"
         polygon_index: -1
       }
@@ -227,149 +227,75 @@
       }
       {
         element: "#map-highlight"
-        intro: "Seems easy right? Well this one is anyway - mark it 20. But we'll take you through a few more examples so you can see some harder \"edge cases\" as well. "
+        intro: "Piece of cake, right? Like this one - mark it 20...  "
         position: "right"
         polygon_index: 0
       }
       {
         element: "#submit-button"
-        intro: "Okay smart guy. Hit next and we'll get to some tough ones!"
+        intro: "and hit next."
         position: "top"
         polygon_index: 0
       }
       {
-        element: "#map-highlight"
-        intro: "It can be easy to be fooled by those olde tyme numbers. 47 or 17? If you can't tell, look to addresses around it. It's near the 20s, so it must be ye olde 17. Click-eth it and type-eth it in. "
+        element: "#submit-button"
+        intro: "What if there is no number at all? Skip it and move on. "
+        position: "right"
+        polygon_index: 4
+      }
+      {
+        element: "#map-highlight"
+        intro: "Now for some trickier \"edge cases.\" If an address includes a fraction, decimalize it! Turn that 1/2 into a \".5.\" This would be 395.5 "
+        position: "right"
+        polygon_index: 2
+      }
+      {
+        element: "#submit-button"
+        intro: "Boom! Hit next to save and continue!"
+        position: "top"
+        polygon_index: 2
+        ixactive: true
+      }
+      {
+        element: "#map-highlight"
+        intro: "It can be easy to be fooled by those olde tyme numbers. 47 or 17? If you can't tell, check th neighbors. This one's near the 20s, so it must be ye olde 17. Click. Type. Proceed. "
         position: "right"
         polygon_index: 1
       }
       {
         element: "#submit-button"
-        intro: "Hit next to save it and move on. "
+        intro: "Hit next to save it and move on.

 Okay, you probably get the concept of hitting \"Next\" at this point - so we're just going to roll through some examples lighting round style and trust that when the time comes for the real thing - you'll know what to do!"
         position: "top"
         polygon_index: 1
         ixactive: true
       }
       {
         element: "#map-highlight"
-        intro: "If an address includes a fraction, decimalize it! Turn that 1/2 into a \".5.\" This would be 395.5 "
-        position: "right"
-        polygon_index: 2
-      }
-      {
-        element: "#submit-button"
-        intro: "Boom! Hit next to save and continue!"
-        position: "top"
-        polygon_index: 2
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Times change and so do addresses. When you see new numbers written in under the old ones, enter both!  They were both right at some point and it's all info we can use."
+        intro: "Buildings with more than one number? We'll take as many as we can get. Click and type both of them."
+        position: "right"
+        polygon_index: 5
+      }
+      {
+        element: "#map-highlight"
+        intro: "Sometimes the numbers wrap around a building. Grab 'em all!"
+        position: "right"
+        polygon_index: 7
+      }
+      {
+        element: "#map-highlight"
+        intro: "Or you might find bizarre labyrinthine escape routes! \"Yes officer, he ran into 108 Wall Street and took off out of 121 Front Street!\" Smoke screen!"
+        position: "right"
+        polygon_index: 9
+      }
+       {
+        element: "#map-highlight"
+        intro: "Times change and so do addresses. When you see new numbers written in under the old ones, enter both!"
         position: "right"
         polygon_index: 3
       }
       {
-        element: "#submit-button"
-        intro: "Next!"
-        position: "top"
-        polygon_index: 3
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "But, what if there is no number at all? Well that's just a headache so we won't even bother with these. "
-        position: "right"
-        polygon_index: 4
-      }
-      {
-        element: "#submit-button"
-        intro: "Skip it like a jump rope!"
-        position: "top"
-        polygon_index: 4
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "A house divided cannot stand? Abe Lincoln should have spent more time in New York. While this proved to be an apt metaphor for our nation torn asunder, large structures were actually frequently divided on the inside and were given more than one address (without collapsing as a result). Give us both numbers.
 They could be on the same street, like this one..."
-        position: "right"
-        polygon_index: 5
-      }
-      {
-        element: "#submit-button"
-        intro: "Hit next to save 'em."
-        position: "top"
-        polygon_index: 5
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "On corner buildings on two streets..."
-        position: "right"
-        polygon_index: 6
-      }
-      {
-        element: "#submit-button"
-        intro: "You know what to do."
-        position: "top"
-        polygon_index: 6
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "On three streets..."
-        position: "right"
-        polygon_index: 7
-      }
-      {
-        element: "#submit-button"
-        intro: "Yep, hit next."
-        position: "top"
-        polygon_index: 7
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "On parallel streets... "
-        position: "right"
-        polygon_index: 8
-      }
-      {
-        element: "#submit-button"
-        intro: "I know, I know \" Next, next, next, next,  NEXT!\" Sorry for all the redundancy but this is just how tutorials work!"
-        position: "top"
-        polygon_index: 8
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Or bizarre labyrinthine escape routes! Yes officer, he ran into 108 Wall Street and took off out of 121 Front Street! Smoke screen!"
-        position: "right"
-        polygon_index: 9
-      }
-      {
-        element: "#submit-button"
-        intro: "Next. (at least you'll be an expert at hitting next by the end of this)"
-        position: "top"
-        polygon_index: 9
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Soooooooo many numbers! We'll take 'em all! "
-        position: "right"
-        polygon_index: 10
-      }
-      {
-        element: "#submit-button"
-        intro: "Clearly, next."
-        position: "top"
-        polygon_index: 10
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Now don't get confused if you see a number  ON  the polygon. This is just how many stories/floors/levels the building has - NOT the address. This particular building is three stories high and has no street number.  "
+        element: "#map-highlight"
+        intro: "Watch out: sometimes you'll find a number  ON  the polygon. That's a floor count - not an address. "
         position: "right"
         polygon_index: 11
       }
@@ -382,80 +308,45 @@
       }
       {
         element: "#map-highlight"
-        intro: "Be careful of reading the numbers upside down! This is a 60, not an 09. Always check other nearby addresses to make sure you're reading it correctly."
+        intro: "Be careful of reading the numbers upside down! This is a 60, not an 09. Always check the neighbors if you're not sure."
         position: "right"
         polygon_index: 12
       }
       {
-        element: "#submit-button"
-        intro: "Ext-nay (a little pig latin always keeps things interesting right?)"
-        position: "top"
-        polygon_index: 12
-        ixactive: true
-      }
-      {
         element: ".leaflet-control-zoom.leaflet-bar.leaflet-control"
-        intro: "Space is always at a premium in NYC and some properties may have more than one building on it - one right on the street and another in the backyard. Both of them share the same address. Use the zoom function to see who owns this building. "
+        intro: "Finally: backlots! You may need to zoom out to see what's going on with these. "
         position: "left"
         polygon_index: 13
       }
       {
         element: "#map-highlight"
-        intro: "This backlot structure is a part of 17 Morton St."
+        intro: "Generally, take the straightest route to the street, and use that address. This one's probably 17."
         position: "right"
         polygon_index: 13
       }
       {
-        element: "#submit-button"
-        intro: "You know what to do."
-        position: "top"
-        polygon_index: 13
-        ixactive: true
-      }
-      {
         element: ".leaflet-control-zoom.leaflet-bar.leaflet-control"
-        intro: "This can get tricky when dealing with funky boundary lines. When you run into this, look for one or two that seem to be primary dividers of multiple properties and use that to decide what belongs to whom. Zooming out a bit might make it easier to determine. "
+        intro: "Again, you'll want to zoom out. This can get kind of tricky.  "
         position: "left"
         polygon_index: 14
       }
       {
         element: "#map-highlight"
-        intro: "Enter the number when you figure it out."
+        intro: "Take your best guess and let the geometry guide you. Dividing lines that anchor multiple properties evenly often suggest to which street a backlot belongs."
         position: "top"
         polygon_index: 14
       }
       {
-        element: "#submit-button"
-        intro: "You know the rest!"
-        position: "top"
-        polygon_index: 14
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Here's another - even though this back lot structure is closer to 65 Second Street, look at how it follows the property line of 52 First Street. Mark it 52."
-        position: "right"
-        polygon_index: 15
-      }
-      {
-        element: "#submit-button"
-        intro: "!TXEN (hold computer up to mirror to reveal this secret instruction.)"
-        position: "top"
-        polygon_index: 15
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "The narrow alley leading to this building is a horserun - bascially a 19th century driveway. The structure was probably the stable for number 67, so mark it 67... "
-        position: "right"
+        element: ".leaflet-control-zoom.leaflet-bar.leaflet-control"
+        intro: "Zoom it on out my friend!"
+        position: "left"
         polygon_index: 16
       }
       {
-        element: "#submit-button"
-        intro: "And submit it the best way you know how."
-        position: "top"
+        element: "#map-highlight"
+        intro: "Okay. Now, the narrow alley leading to this building is a horserun - bascially a 19th century driveway. The structure was probably the stable or \"horse garage\" for number 67. "
+        position: "right"
         polygon_index: 16
-        ixactive: true
       }
       {
         element: "#map-highlight"
@@ -464,79 +355,20 @@
         polygon_index: 17
       }
       {
-        element: "#submit-button"
-        intro: "Whichever is cool with us. Hit next to continue."
-        position: "top"
-        polygon_index: 17
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "This one too. It might have been a carriage house (horse garage) shared by 556 and 554. It's another tossup. "
-        position: "right"
-        polygon_index: 18
-      }
-      {
-        element: "#submit-button"
-        intro: "Next, of course. You're showing remarkable patience and fortitude with this. You should really be proud of yourself!"
-        position: "top"
-        polygon_index: 18
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Another thing to remember is that structures may be set farther back from the road than you'd expect. Maybe the people at 46 Leonard just really wanted a front yard."
+        element: "#map-highlight"
+        intro: "Another thing to remember is that structures may be set farther back from the road than you'd expect. Maybe the folks at 46 Leonard just really wanted a front yard."
         position: "right"
         polygon_index: 19
       }
       {
-        element: "#submit-button"
-        intro: "Duh."
-        position: "top"
-        polygon_index: 19
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Here's another that's set back: 114 West Broadway. In this case you'd have to enter through a narrow opening between the neighbors walls to get back there!"
-        position: "right"
-        polygon_index: 20
-      }
-      {
-        element: "#submit-button"
-        intro: "What do we want?
  NEXT!
 When do we want it?
  NOW! "
-        position: "top"
-        polygon_index: 20
-        ixactive: true
-      }
-      {
-          element: ".leaflet-control-zoom.leaflet-bar.leaflet-control"
-        intro: "This structure was actually built to house the world's longest hot dog. No probably not, but it's very long. Zoom out to see who it belongs to. "
-        position: "left"
-        polygon_index: 26
-      }
-      {
-        element: "#map-highlight"
-        intro: "I'm thinking it extends from 103."
-        position: "top"
-        polygon_index: 26
-      }
-      {
-        element: "#submit-button"
-        intro: "Next."
-        position: "top"
-        polygon_index: 26
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "It looks like this could be a backlot building for 222 or 220 but don't be fooled! Anything that faces the street like that is probably a separate property. This one just doesn't have a number."
+        element: "#map-highlight"
+        intro: "It looks like this could be a backlot building for 222 or 220 but don't be fooled! Anything that faces the street like that is probably a separate property.

 This one just doesn't have a number..."
         position: "right"
         polygon_index: 21
       }
       {
         element: "#submit-button"
-        intro: "[So skip it like a flat stone on a calm lake!"
+        intro: "So skip it like a flat stone on a calm lake!"
         position: "top"
         polygon_index: 21
         ixactive: true
@@ -548,26 +380,12 @@
         polygon_index: 22
       }
       {
-        element: "#submit-button"
-        intro: "Aaaaaaaaaaaaaand NEXT!"
-        position: "top"
-        polygon_index: 22
-        ixactive: true
-      }
-      {
         element: "#map-highlight"
         intro: "If the number is written right between two buildings, and there isn't another number on the other side of either, you can assign both buildings the same address. Both this one and the green L-shaped structure next to it are 693. "
         position: "right"
         polygon_index: 24
       }
       {
-        element: "#submit-button"
-        intro: "[no text provided]"
-        position: "top"
-        polygon_index: 24
-        ixactive: true
-      }
-      {
         element: "#map-highlight"
         intro: "Sometimes you just need use your best judgement. The property here seems to be extending from 16 White St, but it's hard to tell. Don't be ashamed to skip it... "
         position: "right"
@@ -575,7 +393,7 @@
       }
       {
         element: "#submit-button"
-        intro: " Like Wild Horses on a Rolling Stones playlist!"
+        intro: "Like Wild Horses on a Rolling Stones playlist!"
         position: "top"
         polygon_index: 25
         ixactive: true
@@ -587,15 +405,8 @@
         polygon_index: 27
       }
       {
-        element: "#submit-button"
-        intro: "I swear this is the last one - Next!"
-        position: "top"
-        polygon_index: 27
-        ixactive: true
-      }
-      {
-        element: "#map-highlight"
-        intro: "Remember that the backlot buildings tend to be the trickiest, but hopefully these tips will make it a little bit easier.
 If you run into trouble, you can always review this tutorial again... "
+        element: "#map-highlight"
+        intro: "That's about it! The back lots can be tricky, but hopefully these tips will make it a little bit easier.

 If you run into trouble, you can always review this tutorial again... "
         position: "right"
         polygon_index: 28
       }


fix send method.

fix send method.

--- send_message.coffee
+++ send_message.coffee
@@ -265,7 +265,7 @@
             , (err, response, body) ->
               console.log "err: #{err}" if err?
         when "idobata"
-          console.log("form: %j", form)
+          # console.log("form: %j", @form)
           request.post
             url: tg
             headers: @headers


Don't continue automatically to other buttons anymore, we have a special button now.

--- server/admin.coffee
+++ server/admin.coffee
@@ -286,8 +286,6 @@

     Log.info "Done"

-    Meteor.call 'sync-local-pdf-cache' if count > 0
-
   'sync-local-pdf-cache': ->
     throw new Meteor.Error 403, "Permission denied" unless Meteor.person()?.isAdmin

@@ -306,8 +304,6 @@

     Log.info "Done"

-    Meteor.call 'process-pdfs' if count > 0
-
   'process-pdfs': ->
     throw new Meteor.Error 403, "Permission denied" unless Meteor.person()?.isAdmin


added upsteam tile renderer change

added upsteam tile renderer change

--- bokehjs/src/coffee/renderer/tile/tile_renderer.coffee
+++ bokehjs/src/coffee/renderer/tile/tile_renderer.coffee
@@ -21,6 +21,8 @@
     @y_range = @map_plot.get('y_range')
     @y_mapper = this.map_frame.get('y_mappers')['default']
     @extent = @get_extent()
+    @_last_height = undefined
+    @_last_width = undefined

   _map_data: () ->
     @initial_extent = @get_extent()
@@ -76,28 +78,32 @@
     @mget('tile_source').tiles[tile.tile_data.cache_key] = tile.tile_data
     tile.src = @mget('tile_source').get_image_url(x, y, z)
     return tile
-
-  render: (ctx, indices, args) ->
-
-    if not @map_initialized?
-      @_set_data()
-      @_map_data()
-      @map_initialized = true
-
+
+  _enforce_aspect_ratio: () ->
     # brute force way of handling resize or responsive event -------------------------------------------------------------
-    if @height != @map_frame.get('height') or @width != @map_frame.get('width')
+    if @_last_height != @map_frame.get('height') or @_last_width != @map_frame.get('width')
       extent = @get_extent()
       zoom_level = @mget('tile_source').get_level_by_extent(extent, @map_frame.get('height'), @map_frame.get('width'))
       new_extent = @mget('tile_source').snap_to_zoom(extent, @map_frame.get('height'), @map_frame.get('width'), zoom_level)
       @x_range.set({start:new_extent[0], end: new_extent[2]})
       @y_range.set({start:new_extent[1], end: new_extent[3]})
       @extent = new_extent
-      @height = @map_frame.get('height')
-      @width = @map_frame.get('width')
+      @_last_height = @map_frame.get('height')
+      @_last_width = @map_frame.get('width')
+      return true
+    return false
+
+  render: (ctx, indices, args) ->
+
+    if not @map_initialized?
+      @_set_data()
+      @_map_data()
+      @map_initialized = true
+
+    if @_enforce_aspect_ratio()
       return

     @_update()
-
     if @prefetch_timer?
       clearTimeout(@prefetch_timer)

@@ -235,9 +241,6 @@

     @render_timer = setTimeout((=> @_fetch_tiles(need_load)), 65)

-    # prune cached tiles
-    #@tile_source.prune_tiles()
-
 class TileRenderer extends HasParent
   default_view: TileRendererView
   type: 'TileRenderer'


EDSC-148: Fix failing spec

EDSC-148: Fix failing spec

--- app/assets/javascripts/models/ui/datasets_list.js.coffee
+++ app/assets/javascripts/models/ui/datasets_list.js.coffee
@@ -3,7 +3,7 @@
 ns = @edsc.models.ui
 data = @edsc.models.data

-ns.DatasetsList = do ($=jQuery, DatasetsModel=data.Datasets, GranulesList=ns.GranulesList) ->
+ns.DatasetsList = do ($=jQuery, config = @edsc.config, DatasetsModel=data.Datasets, GranulesList=ns.GranulesList) ->

   class DatasetsList
     constructor: (@query, @datasets, @project) ->
@@ -46,7 +46,7 @@

     unfocusDataset: =>
       if @focused()?
-        setTimeout((=> @focused(null)), 400)
+        @_unfocusTimeout = setTimeout((=> @focused(null)), config.defaultAnimationDurationMs)

     _readFocused: ->
       current = @_focusedList
@@ -56,6 +56,7 @@
         @_focusedList = null
       else if current?.dataset != dataset
         current?.dispose()
+        clearTimeout(@_unfocusTimeout)
         @_focusedList = new GranulesList(dataset)
       @_focusedList

@@ -63,7 +64,9 @@
       @_hasFocus(focus?)
       @_focusedList?.dispose()
       @_focusedList = focus
-      @project.focus(focus?.dataset) unless @_hasSelected()
+      clearTimeout(@_unfocusTimeout)
+      dataset = focus?.dataset
+      @project.focus(dataset) if dataset || !@_hasSelected()

     _readSelected: ->
       if @_hasSelected()


#1397 Reimplement NullBucket

#1397 Reimplement NullBucket

--- app/assets/javascripts/oxalis/model/binary/bucket.coffee
+++ app/assets/javascripts/oxalis/model/binary/bucket.coffee
@@ -126,13 +126,20 @@
           @data[i * @BYTE_OFFSET + j] = newData[i * @BYTE_OFFSET + j]

-class NullBucket extends Bucket
+class NullBucket
+
+  # A NullBucket represents a bucket that does not exist, e.g. because it's
+  # outside the dataset's bounding box. It supports only a small subset of
+  # Bucket's methods.
+

   constructor : ->
-    super(0)
-    @state = @STATE_LOADED

-  label : (_) ->  # Do nothing
+    @isNullBucket = true
+
+
+  hasData : -> return false
+  needsRequest : -> return false

 module.exports = {Bucket, NullBucket}


Do not use shipping address if it does not exist

--- src/script/payment-group/credit-card/credit-card-vm.coffee
+++ src/script/payment-group/credit-card/credit-card-vm.coffee
@@ -109,7 +109,7 @@
     @cardNumber.subscribe @cardNumberUpdatedHandler

     @shippingAddress = new ShippingAddressViewModel()
-    if window.paymentData.shippingAddress
+    if window.paymentData.shippingAddress()
       @updateShippingAddress(window.paymentData.shippingAddress())

     $(window).on 'orderFormUpdated.vtex', (e, orderForm) =>


filetree double folders fix

filetree double folders fix

--- client/landing/app/MainApp/filetree/controllers/findercontroller.coffee
+++ client/landing/app/MainApp/filetree/controllers/findercontroller.coffee
@@ -60,13 +60,14 @@
         type        : "mount"
     @defaultStructureLoaded = no
     @treeController.initTree [mount]
+
     if @treeController.getOptions().useStorage
-      @defaultStructureLoaded = no
       @loadDefaultStructureTimer = @utils.wait @treeController.getOptions().initDelay, =>
         @loadDefaultStructure()

   loadDefaultStructure:->

+    return if @defaultStructureLoaded
     @defaultStructureLoaded = yes
     @utils.killWait @loadDefaultStructureTimer


refactoring the table text maker

refactoring the table text maker

--- tech-tests/primes-table/src/table-to-text-converter.coffee
+++ tech-tests/primes-table/src/table-to-text-converter.coffee
@@ -1,7 +1,8 @@
-
-
 horizontalLine = (character, width) ->
-    Array[width].join(character)
+    if width == 0
+        ""
+    else
+        Array( width + 1 ).join(character);

 findLargestNumberWidth = (listOfLists) ->
     max = listOfLists[0][0]
@@ -17,7 +18,7 @@
     widthOfVerticalSeparatorsInRow = numberOfColumns + 1
     widthOfNumbersInRow + widthOfPaddingInRow + widthOfVerticalSeparatorsInRow

-createRow = (listOfNumbers, maxNumberWidth) ->
+createRowText = (listOfNumbers, maxNumberWidth) ->
     row = "|"
     for number in listOfNumbers
         paddingWidth = maxNumberWidth - number.toString().length
@@ -29,7 +30,7 @@
     textTable = ""
     for list in listOfLists
         textTable += horizontalLine("-", tableWidth) + "\n"
-        textTable += createRow(list, maxNumberWidth) + "\n"
+        textTable += createRowText(list, maxNumberWidth) + "\n"
     textTable += horizontalLine("-", tableWidth)

 module.exports.convertToText = (listOfLists, padding = 1) ->


add id, name & state to instance

add id, name & state to instance

--- code/instance.coffee
+++ code/instance.coffee
@@ -3,8 +3,11 @@
 cf     = require 'config'

 exports.Instance = class Instance
-  constructor: (config) ->
-    @config = new cf.Config config
+  constructor: (config, id, name, state) ->
+    @config = new cf.Config config if config?
+    @id = id if id?
+    @name = name if name?
+    @state = state if state?

   # Create a server ready to run. Somewhere on the internet.
   # Servers are created in the "stopped" state.


Add CloudHealthCheck to main server file

--- coffee/server.coffee
+++ coffee/server.coffee
@@ -62,6 +62,7 @@

 app.get '/system', system.info
 app.get '/system/gc', system.gc
+app.get '/CloudHealthCheck', system.check

 app.param 'objectid', document.param
 app.all '/:collection/:objectid', (req, res, next) ->


Change to non-privileged mongo status command

--- coffee/system.coffee
+++ coffee/system.coffee
@@ -40,7 +40,7 @@

     res.json status, service if Object.keys(service).length is 2

-  req.cache.mongo.admin().serverStatus (err, info) ->
+  req.cache.mongo.command {dbStats:true}, (err, info) ->
     service.Mongo = {}

     if err


Fix bug with moving segments to the beginning of the document

--- src/model.coffee
+++ src/model.coffee
@@ -403,7 +403,7 @@

         when 'segmentStart'
           unless parent.next is parent.segment.end
-            parent = parent.insert new NewlineToken()
+            parent.insert new NewlineToken()

         # We can only move into a socket
         # if we are exactly one block.


Add other page fields to preview functionality

--- app/assets/javascripts/cmtool/application.js.coffee
+++ app/assets/javascripts/cmtool/application.js.coffee
@@ -21,6 +21,9 @@
     url = $(@).attr('href')
     iframe = $('#preview-modal iframe')
     params =
+      name: $('#page_name').val()
+      menu_text: $('#page_menu_text').val()
+      title: $('#page_title').val()
       body: $('#page_body').val()
       sidebar: $('#page_sidebar').val()
       footer: $('#page_footer').val()


Staff live in the moment.

Staff live in the moment.

--- app/assets/javascripts/reservation_popups.js.coffee
+++ app/assets/javascripts/reservation_popups.js.coffee
@@ -209,7 +209,7 @@
       values: [0, max_reservation/60/10-1]
     )
     initial_start = 0
-    if new_start_time?
+    if new_start_time? && User.current().get_value("staff") != true
       initial_start = new_start_time.diff(start_time, 'minutes')/10
       initial_start = 0 if initial_start < 0
     this.slid(1, {values: [0, max_reservation/60/10]})


allow money to be built from other Moneys

--- src/money.coffee
+++ src/money.coffee
@@ -16,6 +16,7 @@
       return 0 if num is NaN
       return num if typeof num is 'number'
       return @buildFromString num if typeof num is 'string'
+      return num.cents if num.cents?
       console.warn "Please use a number when creating a Money object not a #{typeof num}. Called from #{arguments.callee.caller.toString()} with ", num
       0


Moved inicialize function callback to collection constructor

--- app/assets/javascripts/action_cable_notifications/store.coffee
+++ app/assets/javascripts/action_cable_notifications/store.coffee
@@ -62,7 +62,6 @@
       console.warn "[registerCollection]: Collection '#{name}' already exists"
     else
       @collections[name] = new CableNotifications.Collection(this, name, tableName, actions)
-      @collections[name].initialize()
       if channel
         @syncToChannel(channel, @collections[name])


Fix fetch posts pool when nothing in feed

--- assets/javascripts/views/fetch_posts_pool.js.coffee
+++ assets/javascripts/views/fetch_posts_pool.js.coffee
@@ -13,8 +13,9 @@
       @posts_feed_view_cid = posts_feed_view.cid
       posts_feed_view.posts_collection.once 'fetch:success', (posts_collection) =>
         @posts_collection = new TentStatus.Collections.Posts
+        @posts_collection.params = posts_collection.params
         @posts_collection.pagination_params = {
-          prev: posts_collection.pagination_params.prev
+          prev: posts_collection.pagination_params?.prev || {}
         }
         @fetch_interval.start()


activity: extend `ActivityActionsView` from `JView`

--- client/Social/Activity/views/activityactions.coffee
+++ client/Social/Activity/views/activityactions.coffee
@@ -1,5 +1,4 @@
-class ActivityActionsView extends KDView
-
+class ActivityActionsView extends JView

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

@@ -52,6 +51,8 @@
       loaderOptions :
         color       : '#6B727B'

+    @attachListeners()
+

   attachListeners: ->

@@ -67,10 +68,9 @@

   viewAppended: ->

-    @setTemplate @pistachio()
-    @template.update()
-    @attachListeners()
     @loader.hide()
+
+    super

   pistachio: ->


Set `CollaborativeString` as editor content when Ace is ready

--- client/ide/lib/workspace/panes/ideeditorpane.coffee
+++ client/ide/lib/workspace/panes/ideeditorpane.coffee
@@ -303,11 +303,14 @@
     unless string = @rtm.getFromModel path
       return @rtm.create 'string', path, @getContent()

-    @setContent string.getText(), no
-
     ace = @getAce()
-    if ace.contentChanged = ace.isCurrentContentChanged()
-      ace.emit 'FileContentChanged'
+
+      .once 'ace.ready', =>
+
+        @setContent string.getText(), no
+
+        if ace.contentChanged = ace.isCurrentContentChanged()
+          ace.emit 'FileContentChanged'

   listenCollaborativeStringChanges: ->


Removed unneeded "KDMarkdownModalText" also merged to "MarkdownModal".

--- client/landing/app/CommonViews/markdownmodal.coffee
+++ client/landing/app/CommonViews/markdownmodal.coffee
@@ -1,4 +1,30 @@
-class KDMarkdownModalText
+class MarkdownModal extends KDModalView
+
+  constructor:(options = {}, data)->
+
+    options = $.extend
+      title       : "How to use the Markdown syntax."
+      cssClass    : "what-you-should-know-modal markdown-cheatsheet"
+      height      : "auto"
+      overlay     : yes
+      width       : 500
+      content     : @markdownText()
+      buttons     :
+        Close     :
+          title   : 'Close'
+          style   : 'modal-clean-gray'
+          callback: => @destroy()
+    , options
+
+    return  if KD._markdownHelpModal
+
+    KD._markdownHelpModal = this
+
+    super options, data
+
+  destroy:->
+    delete KD._markdownHelpModal
+    super

   markdownText:->
     # if we ever need any highlighting
@@ -6,7 +32,6 @@

   markdownTextHTML:->
     """
-

This form supports Markdown and GitHub-flavored Markdown. Here is how to use it:

@@ -149,4 +174,4 @@

-  """+  """


Document MenuItem `enabled` and `visible`

The Electron MenuItem[1] `enabled` and `visible` options are exposed to
Atom context menus in menu_helpers.coffee[2] but are not yet documented.
Both options are passed through to Electron.

[1] http://electron.atom.io/docs/v0.31.0/api/menu-item/
[2] https://github.com/atom/atom/blob/v1.0.7/src/menu-helpers.coffee#L49

--- src/context-menu-manager.coffee
+++ src/context-menu-manager.coffee
@@ -86,9 +86,14 @@
   #   * `label` (Optional) A {String} containing the menu item's label.
   #   * `command` (Optional) A {String} containing the command to invoke on the
   #     target of the right click that invoked the context menu.
+  #   * `enabled` (Optional) A {Boolean} indicating whether the menu item
+  #     should be clickable. Disabled menu items typically appear grayed out.
+  #     Defaults to `true`.
   #   * `submenu` (Optional) An {Array} of additional items.
   #   * `type` (Optional) If you want to create a separator, provide an item
   #      with `type: 'separator'` and no other keys.
+  #   * `visible` (Optional) A {Boolean} indicating whether the menu item
+  #     should appear in the menu. Defaults to `true`.
   #   * `created` (Optional) A {Function} that is called on the item each time a
   #     context menu is created via a right click. You can assign properties to
   #    `this` to dynamically compute the command, label, etc. This method is


Unset user location if not-present

Unset user location if not-present

--- components/inquiry_questionnaire/views/basic_info.coffee
+++ components/inquiry_questionnaire/views/basic_info.coffee
@@ -17,7 +17,10 @@

     form.state 'loading'

-    @user.save form.data(),
+    @user.set form.data()
+    @user.unset('location') unless @user.has('location')
+
+    @user.save null,
       success: => @next()
       error: form.error.bind form


in showFact, the background page is not necessarily the stream

--- core/app/backbone/controllers/channels_controller.coffee
+++ core/app/backbone/controllers/channels_controller.coffee
@@ -71,4 +71,4 @@
     fact = new Fact id: fact_id
     fact.fetch
       success: ->
-        FactlinkApp.DiscussionModalOnFrontend.openDiscussion fact, currentUser.streamLink()
+        FactlinkApp.DiscussionModalOnFrontend.openDiscussion fact


Fix fs open bug

Fix fs open bug

--- src/tub.coffee
+++ src/tub.coffee
@@ -9,7 +9,7 @@
     @file = "#{@dir}/.jakhu/#{@tub}tub_config.yml"
     @yml = yml
     @yaml = {}
-    fs.openSync @file
+    fs.openSync @file, 'w+'
   create: (args) ->
     # body...
     @yaml.name = @tub


Updating routes to new format

Updating routes to new format

--- common/routes.coffee
+++ common/routes.coffee
@@ -3,6 +3,6 @@
         trackPageView: true
         templateNameConverter: (input) -> input.replace /-/g, '_'

-    @route 'home',
-        path: '/'
+    @route '/',
+        name: 'home'
         fastRender: true


Added integration tests for enableArithAbort

--- test/integration/connection-test.coffee
+++ test/integration/connection-test.coffee
@@ -1020,3 +1020,68 @@
     runSqlBatch test, config, sql, (err) ->
         test.ok(err instanceof Error)
         test.strictEqual err?.number, 515 # Cannot insert the value NULL
+
+
+# Test that the default behaviour has ARITHABORT set to off
+exports.testArithAbortDefault = (test) ->
+	test.expect(5)
+
+	config = getConfig()
+	request = new Request('SELECT SESSIONPROPERTY(\'ARITHABORT\') AS ArithAbortSetting', (err, rowCount) ->
+		test.ifError(err)
+		test.strictEqual(rowCount, 1)
+
+		connection.close()
+	)
+
+	request.on('columnMetadata', (columnsMetadata) ->
+		test.strictEqual(Object.keys(columnsMetadata).length, 1)
+	)
+
+	request.on('row', (columns) ->
+		test.strictEqual(Object.keys(columns).length, 1)
+		test.strictEqual(columns[0].value, 0)
+	)
+
+	connection = new Connection(config)
+
+	connection.on('connect', (err) ->
+		connection.execSql(request)
+	)
+
+	connection.on('end', (info) ->
+		test.done()
+	)
+
+# Test that ARITHABORT can be set to on
+exports.testArithAbortCanBeSetToOn = (test) ->
+	test.expect(5)
+
+	config = getConfig()
+	config.options.enableArithAbort = true
+
+	request = new Request('SELECT SESSIONPROPERTY(\'ARITHABORT\') AS ArithAbortSetting', (err, rowCount) ->
+		test.ifError(err)
+		test.strictEqual(rowCount, 1)
+
+		connection.close()
+	)
+
+	request.on('columnMetadata', (columnsMetadata) ->
+		test.strictEqual(Object.keys(columnsMetadata).length, 1)
+	)
+
+	request.on('row', (columns) ->
+		test.strictEqual(Object.keys(columns).length, 1)
+		test.strictEqual(columns[0].value, 1)
+	)
+
+	connection = new Connection(config)
+
+	connection.on('connect', (err) ->
+		connection.execSql(request)
+	)
+
+	connection.on('end', (info) ->
+		test.done()
+	)


Cleanup of maybe-we-can-skip-this-in-sane-way

--- test/integration/notifiers/redis.coffee
+++ test/integration/notifiers/redis.coffee
@@ -1,5 +1,4 @@
 {assert}    = require 'chai'
-#{describe}  = require 'mocha'

 {
   factorial
@@ -19,7 +18,7 @@
   before (done) ->
     factorialFinishedCounterObject.value = 0
     ivy.registerTask factorial, factorialFinished, name: 'factorial'
-
+
     queue.clear -> notifier.clear done

   describe 'When I set up redis notifier for producer', ->


fixed remove behavior a little

fixed remove behavior a little

--- src/xml.coffee
+++ src/xml.coffee
@@ -20,6 +20,7 @@
 connect_tags = (parent, child) ->
     listeners = {}
     pipe = (event) ->
+        return if listeners[event]?
         child.on? event, listeners[event] = ->
             parent.emit(event, arguments...)
     wire = ->
@@ -32,14 +33,16 @@
     remove = (soft) ->
         if this is child
             parent.removeListener('removed', remove)
-            dispose()
             parent.removeListener('replaced', replace)
             child.removeListener('replaced', replace)
-        else unless soft
+            dispose()
+        else if soft
+            parent.once('removed', remove)
+        else
             child.removeListener('removed', remove)
-            dispose()
             parent.removeListener('replaced', replace)
             child.removeListener('replaced', replace)
+            dispose()
     replace = (tag) ->
         if this is child
             remove.call(parent)


Add debugging statements

Add debugging statements

--- models/index.coffee
+++ models/index.coffee
@@ -6,8 +6,8 @@
 config    = require("#{__dirname}/../db")[env]
 db        = {}

-console.log process.env.NODE_ENV
-console.log process.env.DATABASE_URL
+console.log "NODE_ENV: #{process.env.NODE_ENV}"
+console.log "DATABASE_URL: #{process.env.DATABASE_URL}"
 console.log config

 sequelize =


Clean up

Clean up

--- elements/QuetzalElement.coffee
+++ elements/QuetzalElement.coffee
@@ -115,6 +115,7 @@
     # Wire up the contentChanged event.
     # REVIEW: The class should have some way of indicating it actually wants
     # to consume this event so we don't create unnecessary observers.
+    # TODO: How to stop listening?
     observer = new MutationObserver =>
       event = document.createEvent "CustomEvent"
       event.initCustomEvent "contentChanged", false, false, null


Client: Activity: Feed: Added share icons link builder methods

--- client/activity/lib/components/activitysharepopup/index.coffee
+++ client/activity/lib/components/activitysharepopup/index.coffee
@@ -78,6 +78,37 @@

     return shareText

+
+  buildGPlusShareLink: ->
+
+    if @props.gplus.enabled
+      link = "https://plus.google.com/share?url=#{encodeURIComponent(@props.url)}"
+
+
+  buildTwitterShareLink: ->
+
+    if @props.twitter.enabled
+      shareText = @getTwitterShareText() or @props.twitter.text
+      link = """https://twitter.com/intent/tweet?
+        text=#{encodeURIComponent shareText}&via=koding&source=koding"""
+
+
+  buildFacebookShareLink: ->
+
+    if @props.facebook.enabled
+      link = "https://www.facebook.com/sharer/sharer.php?u=#{encodeURIComponent(@props.url)}"
+
+
+  buildLinkedInShareLink: ->
+
+    if @props.linkedin.enabled
+      link = """http://www.linkedin.com/shareArticle?mini=true&url=
+        #{encodeURIComponent(@props.url)}&
+        title=#{encodeURIComponent(@props.linkedin.title)}&
+        summary=#{encodeURIComponent(@props.url)}&
+        source=#{location.origin}"""
+
+
   render: ->

     return null  unless @props.isOpened


Workspace: Minor code cleanup for chat pane.

--- client/app/CommonViews/workspace/collaborativeworkspace.coffee
+++ client/app/CommonViews/workspace/collaborativeworkspace.coffee
@@ -7,13 +7,11 @@
     @createLoader()
     @fetchUsers()
     @createUserListContainer()
-    @createChat()
+    @createChat()  if @getOptions().enableChat
     @bindRemoteEvents()

   createChat: ->
-    return unless @getOptions().enableChat
-    @container.addSubView @chatView = new ChatPane
-      delegate: this
+    @container.addSubView @chatView = new ChatPane delegate: this
     @chatView.hide()

   createRemoteInstance: ->


rakefile simplification

rakefile simplification

--- chrome/content/zotero-better-bibtex/test/setup.coffee
+++ chrome/content/zotero-better-bibtex/test/setup.coffee
@@ -4,44 +4,44 @@
     @passed = 0
     @failed = 0

-  for event in ['start', 'suite', 'suite end', 'pending', 'pass', 'fail', end']
+  for event in ['start', 'suite', 'suite end', 'pending', 'pass', 'fail', 'end']
     runner.on(event, @[event].bind(@))

   start: ->

   suite: (suite) ->
     ++@indents
-    dump indent() + suite.title + '\n'
+    dump(indent() + suite.title + '\n')
     return

   'suite end': (suite) ->
     --@indents
-    if 1 == indents
-      dump '\n'
+    dump('\n') if 1 == indents
     return

   pending: (test) ->
-    dump '\ud' + indent() + 'pending  -' + test.title + '\n'
+    # dump('\ud' + indent() + 'pending  -' + test.title + '\n')
     return

   pass: (test) ->
     passed++
-    msg = '\ud' + indent() + Mocha.reporters.Base.symbols.ok + ' ' + test.title
+    # msg = '\ud' + indent() + Mocha.reporters.Base.symbols.ok + ' ' + test.title
     if 'fast' != test.speed
       msg += ' (' + Math.round(test.duration) + ' ms)'
-    dump msg + '\n'
+    dump(msg + '\n')
     return

   fail: (test, err) ->
     failed++
-    dump '\ud' + indent() + Mocha.reporters.Base.symbols.err + ' ' + test.title + '\n' + indent() + '  ' + err.toString() + ' at\n' + indent() + '    ' + err.stack.replace('\n', '\n' + indent() + '    ', 'g')
+    #dump '\ud' + indent() + Mocha.reporters.Base.symbols.err + ' ' + test.title + '\n' + indent() + '  ' + err.toString() + ' at\n' + indent() + '    ' + err.stack.replace('\n', '\n' + indent() + '    ', 'g')
     return

   end: ->
-    dump passed + '/' + passed + failed + ' tests passed.\n'
-    quit failed != 0
+    dump(passed + '/' + passed + failed + ' tests passed.\n')
+    quit(failed != 0)
     return

   indent: ->
-    Array(indents).join '  '
+    #Array(indents).join('  ')
+    return


Activity: parent message likeview taken next to author view

--- client/Social/Activity/views/privatemessagelistitem.coffee
+++ client/Social/Activity/views/privatemessagelistitem.coffee
@@ -41,13 +41,11 @@

       {{> @avatar}}

-        {{> @author}}
-        {{> @timeAgoView}}
+        {{> @author}}{{> @timeAgoView}}{{> @likeView}}

       {{> @editWidgetWrapper}}
       {article{@formatContent #(body)}}
       {{> @embedBox}}
-      {{> @likeView}}

     {{> @commentBox}}
     """


Team Resources: update scrollbar while switching to another search mode

--- client/admin/lib/views/resources/adminresourcesview.coffee
+++ client/admin/lib/views/resources/adminresourcesview.coffee
@@ -42,6 +42,8 @@
     else
       @unsetClass 'advanced-search-mode'

+    @controller.customScrollView.wrapper.emit 'MutationHappened'
+

   search: (query) ->


MachineSettingsDomainsView: Don't list users if machine is not running.

--- client/app/lib/providers/machinesettingsdomainsview.coffee
+++ client/app/lib/providers/machinesettingsdomainsview.coffee
@@ -2,6 +2,7 @@
 nick                      = require 'app/util/nick'
 KDView                    = kd.View
 globals                   = require 'globals'
+Machine                   = require 'app/providers/machine'
 htmlencode                = require 'htmlencode'
 DomainItem                = require 'app/domains/domainitem'
 KDModalView               = kd.ModalView
@@ -49,7 +50,9 @@

   initList: ->

-   kd.singletons.computeController.fetchDomains (err, domains = []) =>
+    return no  if @getData().status.state isnt Machine.State.Running
+
+    kd.singletons.computeController.fetchDomains (err, domains = []) =>
       kd.warn err  if err

       @listController.lazyLoader.hide()


sidebar: fix reference error and use confirm modal

--- client/Social/Activity/sidebar/leavechannelbutton.coffee
+++ client/Social/Activity/sidebar/leavechannelbutton.coffee
@@ -7,13 +7,33 @@

     super options, data

-    @setCallback @bound 'delete'
+    @setCallback @bound 'showModal'
+
+
+  showModal: (event) ->
+
+    KD.utils.stopDOMEvent event
+
+    @deleteModal = KDModalView.confirm
+      title : 'Are you sure'
+      content : 'Delete this message?'
+      ok :
+        title: 'Remove'
+        callback : @bound 'delete'

   delete: (event) ->

-    KD.utils.stopDOMEvent event
+    { id } = @getData()
+    removeButton = @deleteModal.buttons['OK']
+    removeButton.showLoader()

-    PrivateMessageDeleteModal.create @getData()
+    { SocialChannel } = KD.remote.api

+    SocialChannel.delete { channelId: id }
+      .then =>
+        @deleteModal.destroy()
+        KD.singletons.router.handleRoute '/Activity/Public'
+      .catch (args...) =>
+        KD.showError args...


Hackathon: create share buttons for applicants on load

--- client/landing/site.hackathon/coffee/home/AppView.coffee
+++ client/landing/site.hackathon/coffee/home/AppView.coffee
@@ -107,7 +107,7 @@
         document.cookie = 'clientId=null'
         location.replace '/WFGH'

-    return if isApplicant
+    return @createShareButtons()  if isApplicant

     @section.addSubView button = new KDButtonView
       cssClass : 'apply-button solid green medium'


activity: refactor `KDCustomHTMLView` instantiations to `JCustomHTMLView` in `CommentListItemView` class

--- client/Social/Activity/views/comments/listitemview.coffee
+++ client/Social/Activity/views/comments/listitemview.coffee
@@ -121,14 +121,14 @@

     @author = new ProfileLinkView {origin}

-    @body       = new KDCustomHTMLView
+    @body       = new JCustomHTMLView
       cssClass  : "comment-body-container"
       pistachio : "{p{KD.utils.applyTextExpansions #(body), yes}}"
     , data

     @formWrapper = new KDCustomHTMLView cssClass: "edit-comment-wrapper hidden"

-    @editInfo   = new KDCustomHTMLView
+    @editInfo   = new JCustomHTMLView
       tagName   : "span"
       cssClass  : "hidden edited"
       pistachio : "edited"


More protractor tweaking

More protractor tweaking

--- angular/test/protractor/group_spec.coffee
+++ angular/test/protractor/group_spec.coffee
@@ -18,7 +18,7 @@
         page.signInViaEmail('new@account.com')
         page.click '.join-group-button__join-group'
         page.expectElement '.sidebar__content'
-        page.expectElement '.group-theme__name', 'Open Dirty Dancing Shoes'
+        page.expectText '.group-theme__name', 'Open Dirty Dancing Shoes'

       it 'does not allow mark as read or mute', ->
         page.loadPath('view_open_group_as_visitor')


app/components: update usage of ButtonWithMenu

--- client/app/lib/components/buttonwithmenu/index.coffee
+++ client/app/lib/components/buttonwithmenu/index.coffee
@@ -17,25 +17,11 @@
     listClass:''
     menuClassName:''

-  constructor: (props) ->
-
-    super props
-
-    @state = { isMenuOpen: @props.isMenuOpen }
-
-
-  componentWillReceiveProps: (nextProps) ->
-
-    { isMenuOpen } = nextProps
-
-    @setState { isMenuOpen }
-

   renderListMenu: ->

     onClick = (item) => (event) =>
       item.onClick event
-      @onMenuClose()

     @props.items.map (item) ->

{item.title}

@@ -60,26 +46,15 @@
     $(list).css top: menuTop, left: buttonRect.left + buttonRect.width - menuWidth

-  onMenuClose: ->
-
-    @setState isMenuOpen: no
-    @props.onMenuClose?()
-
-
-  onButtonClick: (event) ->
-
-    kd.utils.stopDOMEvent event
-    @setState isMenuOpen: yes
-    @props.onMenuOpen?()
-
-
   render: ->

+    button = <button ref='button'></button>

-      <button ref="button" onClick={@bound 'onButtonClick'}></button>
-      <Portal className={@props.menuClassName} isOpened={@state.isMenuOpen} closeOnOutsideClick={yes} closeOnEsc={yes} onClose={@bound 'onMenuClose'}>
-

-          {@renderListMenu()}
-

+      <Portal openByClickOn={button} closeOnOutsideClick closeOnEsc>
+

+

+            {@renderListMenu()}
+

+

       </Portal>


fdescribe

fdescribe

--- angular/test/protractor/group_spec.coffee
+++ angular/test/protractor/group_spec.coffee
@@ -1,4 +1,4 @@
-ddescribe 'Group Page', ->
+fdescribe 'Group Page', ->

   page = require './helpers/page_helper.coffee'
   staticPage = require './helpers/static_page_helper.coffee'


SoloMachines: Item: enable select from label

--- client/migratefromsolo/lib/components/solomachines.coffee
+++ client/migratefromsolo/lib/components/solomachines.coffee
@@ -143,7 +143,7 @@

         <CheckBox disabled={finishedSelection} onClick={onSelect} checked={!!isSelected} />
-        { machine.label }
+
{ machine.label }

{migrateStatus}

{machine.ipAddress}


BaseInitialView: Move all back-end logic to controller

--- client/stacks/lib/views/stacks/baseinitialview.coffee
+++ client/stacks/lib/views/stacks/baseinitialview.coffee
@@ -27,11 +27,6 @@
     @stackTemplateList.listView
       .on 'ItemSelected', (stackTemplate) =>
         @emit 'EditStack', stackTemplate
-
-      .on 'ItemDeleted', =>
-        kd.singletons.appManager.tell 'Stacks', 'reloadStackTemplatesList'
-
-      .on 'ItemCloned', @bound 'reload'

       .on 'ItemSelectedAsDefault', @bound 'setDefaultTemplate'


get top level domain from hostname in js

--- app/assets/javascripts/application.coffee
+++ app/assets/javascripts/application.coffee
@@ -35,7 +35,8 @@
 #= require blank
 #= require timesheet

-window.ApiBasePath = "//api.#{document.domain}"
+window.domain = (location.host.match(/([^.]+)\.\w{2,3}(?:\.\w{2})?$/) || [])[0]
+window.ApiBasePath = "//api.#{domain}"

 $(document).on 'show.bs.collapse', '.navbar-collapse', ->
   $('.navbar-collapse.in').not(this).collapse('hide')


error show

error show

--- app/assets/javascripts/checkins.js.coffee
+++ app/assets/javascripts/checkins.js.coffee
@@ -38,11 +38,10 @@

       'Error': (up, err, errTip)->
-        error = JSON.parse(err)
         swal
           type: 'error'
           title: "文件上传出错误！"
-          text: error.error
+          text: errTip

   pageIdentifier = "#checkins_show "
   $(document)


referral: send emails to forced recipient if exists

--- workers/social/lib/social/models/referrableemail.coffee
+++ workers/social/lib/social/models/referrableemail.coffee
@@ -54,7 +54,7 @@
     shareUrl  = "https://koding.com/R/#{@username}"
     email     = new JMail
       from    : 'hello@koding.com'
-      email   : @email
+      email   : KD.config.emailWorker.forcedRecipient or @email
       replyto : 'hello@koding.com'
       subject : "#{firstName} #{lastName} has invited you to try Koding!"
       content : """


Use Turbolink instead of ajax

Use Turbolink instead of ajax

--- app/assets/javascripts/issuable.js.coffee
+++ app/assets/javascripts/issuable.js.coffee
@@ -56,13 +56,6 @@
         Issuable.filterResults $('.filter-form')
         $('.js-label-select').trigger('update.label')

-  toggleLabelFilters: ->
-    $filteredLabels = $('.filtered-labels')
-    if $filteredLabels.find('.label-row').length > 0
-      $filteredLabels.removeClass('hidden')
-    else
-      $filteredLabels.addClass('hidden')
-
   filterResults: (form) =>
     formData = form.serialize()

@@ -71,32 +64,8 @@
     issuesUrl = formAction
     issuesUrl += ("#{if formAction.indexOf('?') < 0 then '?' else '&'}")
     issuesUrl += formData
-    $.ajax
-      type: 'GET'
-      url: formAction
-      data: formData
-      complete: ->
-        $('.issues-holder, .merge-requests-holder').css('opacity', '1.0')
-      success: (data) ->
-        $('.issues-holder, .merge-requests-holder').html(data.html)
-        # Change url so if user reload a page - search results are saved
-        history.replaceState {page: issuesUrl}, document.title, issuesUrl
-        Issuable.reload()
-        Issuable.updateStateFilters()
-        $filteredLabels = $('.filtered-labels')

-        if typeof Issuable.labelRow is 'function'
-          $filteredLabels.html(Issuable.labelRow(data))
-
-        Issuable.toggleLabelFilters()
-
-      dataType: "json"
-
-  reload: ->
-    if Issuable.created
-      Issuable.initChecks()
-
-    $('#filter_issue_search').val($('#issue_search').val())
+    Turbolinks.visit(issuesUrl);

   initChecks: ->
     $('.check_all_issues').off('click').on('click', ->
@@ -105,25 +74,6 @@
     )

     $('.selected_issue').off('change').on('change', Issuable.checkChanged)
-
-  updateStateFilters: ->
-    stateFilters =  $('.issues-state-filters, .dropdown-menu-sort')
-    newParams = {}
-    paramKeys = ['author_id', 'milestone_title', 'assignee_id', 'issue_search', 'issue_search']
-
-    for paramKey in paramKeys
-      newParams[paramKey] = gl.utils.getParameterValues(paramKey)[0] or ''
-
-    if stateFilters.length
-      stateFilters.find('a').each ->
-        initialUrl = gl.utils.removeParamQueryString($(this).attr('href'), 'label_name[]')
-        labelNameValues = gl.utils.getParameterValues('label_name[]')
-        if labelNameValues
-          labelNameQueryString = ("label_name[]=#{value}" for value in labelNameValues).join('&')
-          newUrl = "#{gl.utils.mergeUrlParams(newParams, initialUrl)}&#{labelNameQueryString}"
-        else
-          newUrl = gl.utils.mergeUrlParams(newParams, initialUrl)
-        $(this).attr 'href', newUrl

   checkChanged: ->
     checked_issues = $('.selected_issue:checked')