Solved blur jumping issue

Solved blur jumping issue

Reverted 'round' back to 'floor' and it solved the blur jumping issue

--- lib/editor-background.coffee
+++ lib/editor-background.coffee
@@ -1,1158 +1,1158 @@
-{CompositeDisposable} = require 'atom'
-fs = require 'fs'
-blur = require './StackBlur.js'
-animation = require './animation'
-yt = require './youtube'
-popup = require './popup'
-configWindow = require './config'
-path = require 'path'
-#elementResizeEvent = require 'element-resize-event'
-
-qr = (selector) -> document.querySelector selector
-qra = (selector) -> document.querySelectorAll selector
-style = (element) -> document.defaultView.getComputedStyle element
-inline = (element,style) -> if element?.style
-  element.style.cssText += style
-escapeHTML = (text) ->
-  text
-    .replace(/&/g, "&")
-    .replace(/</g, "<")
-    .replace(/>/g, ">")
-    .replace(/"/g, """)
-    .replace(/'/g, "'")
-
-blobToBase64 = (blob, cb) ->
-  reader = new FileReader()
-  reader.onload = ->
-    dataUrl = reader.result
-    base64 = dataUrl.split(',')[1]
-    cb(base64)
-  reader.readAsDataURL(blob)
-
-shadowDomAlert = false
-
-planeInitialCss =
-  "position:absolute;
-  left:0;
-  top:0;
-  width:100%;
-  height:100%;
-  background:transparent;
-  pointer-events:none;
-  z-index:0;"
-
-colorToArray = (str) ->
-  if !str?
-    return [0,0,0,0]
-  result = str.replace(/[^\d,\.]/g,'')
-  result = result.split(',')
-  result
-
-module.exports = EditorBackground =
-  config:
-    useConfigWindow:
-      type:'string'
-      description:"USE PACKAGE CONFIG WINDOW INSTEAD OF THIS SETTINGS ( CTRL + SHIFT + E ) TO OPEN"
-      toolbox:'ignore'
-      default:''
-      order:0
-    image:
-      type:'object'
-      properties:
-        url:
-          type:'string'
-          toolbox:'file'
-          title:'Image URL'
-          default:'atom://editor-background/bg.jpg'
-          description:"URL of your image. It can be http://...
-          or just /home/yourname/image.jpg"
-        blurRadius:
-          type:'integer'
-          description:"Background image blur. 0 = none"
-          default:0
-          minimim:0
-          maximum: 200
-        backgroundSize:
-          type:"string"
-          default:"original"
-          enum:["original","100%","cover","manual"]
-          description:"Background size"
-        manualBackgroundSize:
-          type:"string"
-          default:""
-          description:"'100px 100px' or '50%' try something..."
-        backgroundPosition:
-          type:"string"
-          default:"center"
-          description:"Background position"
-        repeat:
-          type:"string"
-          default:"no-repeat"
-          enum:["no-repeat","repeat","repeat-x","repeat-y"]
-          description:"Background repeat"
-        customOverlayColor:
-          type:"boolean"
-          default:false
-          description:"Do you want different color on top of background?"
-        overlayColor:
-          type:'color'
-          default:'rgba(0,0,0,0)'
-          description:"Color used to overlay background image"
-        opacity:
-          type:'integer'
-          default:100
-          description:"Background image visibility percent 1-100"
-          minimum:0
-          maximum:100
-        style:
-          type:"string"
-          toolbox:"text"
-          default:"background:radial-gradient(rgba(0,0,0,0) 30%,rgba(0,0,0,0.75));"
-          description:"Your custom css rules :]"
-    text:
-      type:'object'
-      properties:
-        color:
-          type:"color"
-          default:"rgba(0,0,0,1)"
-          description:"background color for text/code"
-        opacity:
-          type:"integer"
-          default:100
-          minimum:0
-          maximum:100
-        blur:
-          type:"integer"
-          default:5
-          minimum:0
-          maximum:50
-        expand:
-          type:"integer"
-          default:4
-          description:"If you want larger area under text - try 4 or 10"
-          minimum:0
-          maximum:200
-        shadow:
-          type:"string"
-          default:"none"
-          description:"Add a little text shadow to code like
-          '0px 2px 2px rgba(0,0,0,0.3)' "
-    video:
-      type:'object'
-      properties:
-        youTubeURL:
-          type:'string'
-          default:''
-          description:"Search for 'background loop',
-          'background animation' or similar on youtube and paste url here."
-        playAnimation:
-          type:"boolean"
-          default:false
-          description:"enable or disable animation"
-        animationSpeed:
-          type:"integer"
-          default:75
-          description:"animation speed in ms (original is 50),
-          LOWER VALUE = HIGHER CPU USAGE"
-        opacity:
-          type:"integer"
-          default:75
-          minimum:0
-          maximum:100
-          description:"video opacity"
-        startTime:
-          type:"string"
-          default:'0s'
-          description:"video start time like 1h30m10s or 10s"
-        endTime:
-          type:"string"
-          default:"20s"
-          description:"video end time like 1h30m30s or 30s"
-    other:
-      type:'object'
-      properties:
-        treeViewOpacity:
-          type:'integer'
-          default:"35"
-          description:"Tree View can be transparent too :)"
-          minimum:0
-          maximum:100
-        transparentTabBar:
-          type:"boolean"
-          default:true
-          desctiption:"Transparent background under file tabs"
-    box3d:
-      type:'object'
-      properties:
-        depth:
-          type:"integer"
-          default: 0
-          minimum: 0
-          maximum: 2000
-          description:"This is pseudo 3D Cube. Try 500 or 1500 or
-          something similar..."
-        shadowOpacity:
-          type:"integer"
-          default:30
-          minimum:0
-          maximum:100
-          description:"shadow that exists in every corner of the box"
-        mouseFactor:
-          type:"integer"
-          default: 0
-          description: "move background with mouse (higher value = slower)
-          try 8 or 4 for 3dbox or 20 for wallpaper"
-
-
-
-
-
-  packagesLoaded:false
-  initialized:false
-  elements: {}
-  colors: {}
-  state: {}
-  mouseX:0
-  mouseY:0
-  editorStyles:[]
-  editor:{}
-
-
-  activate: (state) ->
-    @subs = new CompositeDisposable
-    @subs.add atom.commands.add 'atom-workspace',
-      'editor-background:toggle': => @toggle()
-    @subs.add atom.config.observe 'editor-background',
-     (conf) => @applyBackground.apply @,[conf]
-    @subs.add atom.config.observe 'editor-background.image.url',(url)=>
-      @blurImage.apply @,[url]
-    @subs.add atom.config.observe 'editor-background.video.youTubeURL',(url) =>
-      @startYouTube.apply @,[url]
-    @subs.add atom.config.observe 'editor-background.video.playAnimation',(play) =>
-        if play==false
-            @removeVideo()
-        else
-            @startYouTube.apply @,[]
-
-    @initializePackage()
-
-  deactivate: ()->
-    if @subs?
-        @subs.dispose()
-    if @elements?.main?
-        @elements.main.remove()
-
-  appendCss: () ->
-    css = ""
-    cssstyle = document.createElement 'style'
-    cssstyle.type = 'text/css'
-    cssstyle.setAttribute 'id','#editor-background-css'
-    @elements.main.appendChild cssstyle
-    @elements.css = cssstyle
-
-  createBox: (depth) ->
-    body = @elements.body
-    jest = qr 'body .eb-box-wrapper'
-    if not jest? or jest.length==0
-      left = document.createElement 'div'
-      top = document.createElement 'div'
-      right = document.createElement 'div'
-      bottom = document.createElement 'div'
-      back = document.createElement 'div'
-      wrapper = document.createElement 'div'
-      wrapper.appendChild left
-      wrapper.appendChild top
-      wrapper.appendChild right
-      wrapper.appendChild bottom
-      wrapper.appendChild back
-      wrapper.setAttribute 'class','eb-box-wrapper'
-      left.setAttribute 'class','eb-left'
-      top.setAttribute 'class','eb-top'
-      right.setAttribute 'class','eb-right'
-      bottom.setAttribute 'class','eb-bottom'
-      back.setAttribute 'class','eb-back'
-
-      boxStyle = document.createElement 'style'
-      boxStyle.type = "text/css"
-      @elements.main.appendChild boxStyle
-
-      @elements.main.appendChild wrapper
-    boxStyle
-
-  mouseMove: (ev) ->
-    conf=@configWnd.get('editor-background')
-    if conf.box3d.mouseFactor > 0
-      @mouseX=ev.pageX
-      @mouseY=ev.pageY
-      if conf.box3d.depth>0 then @updateBox() else @updateBgPos()
-
-
-
-  activateMouseMove: ->
-    body = @elements.body
-    body.addEventListener 'mousemove',(ev) =>  @mouseMove.apply @,[ev]
-
-  insertMain:->
-    main = document.createElement 'div'
-    main.id='editor-background-main'
-    @elements.main=main
-    document.querySelector '#editor-background-main'.remove
-    @elements.body.insertBefore main,@elements.body.firstChild
-    @elements.itemViews = document.querySelectorAll '.item-views'
-    for el in @elements.itemViews
-        el.style.cssText="background:transparent !important";
-
-  insertTextBackgroundCss:->
-    # CSS for background text
-    txtBgCss = document.createElement 'style'
-    txtBgCss.type="text/css"
-    bgColor =
-    txtBgCss.cssText="
-      .editor-background-line{
-        background:black;
-        color:white;
-      }
-      atom-pane-container atom-pane .item-views{
-        background:transparent !important;
-        background-color:transparent !important;
-      }
-    "
-    @elements.textBackgroundCss=txtBgCss
-    @elements.main.appendChild txtBgCss
-
-  insertTextBackground:->
-    # container of the background text
-    txtBg = document.createElement 'div'
-    txtBg.style.cssText="
-      position:absolute;
-      z-index:-1;
-    "
-    @elements.textBackground = txtBg
-    @elements.main.appendChild txtBg
-
-  getYTId: (url) ->
-    if url!=''
-      ytreg = /// (?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)
-      |youtu\.be\/)([^"&?\/ ]{11}) ///i
-      ytidregres=ytreg.exec(url)
-      if ytidregres?.length>0
-        ytid=ytidregres[1]
-
-  timer:{}
-  frames:[]
-  frame:0
-  videoWidth:0
-  videoHeight:0
-  playing:true
-
-  getFrame:(canvas,ctx,video,w,h)->
-    @frame++
-    tick=50
-    #console.log 'getFrame time',@time
-    if @frame*tick >= @time.end - @time.start
-      return @getImagesDone
-    frame=document.querySelector '#editor-background-frame'
-    frame.innerText=@frame
-    ctx.drawImage video,0,0
-    video.pause()
-    if @playing
-      @frames.push canvas.toDataURL('image/jpeg')
-      video.play()
-      if @playing
-        setTimeout =>
-          @getFrame.apply @,[canvas,ctx,video,w,h]
-        ,tick
-
-
-  getImages: ->
-    @playing=true
-    @frame = 0
-    #console.log 'getting images...'
-    video = @elements.video
-    canvas = @elements.videoCanvas
-    context = canvas.getContext("2d")
-    ytid = @getYTId @configWnd.get 'editor-background.video.youTubeURL'
-
-    html="
-

-    Getting Frame: 0

-    Please be patient.
"
-    title= 'Editor background - frames'
-    args = {
-      buttons:{
-        "Cancel":(ev)=>@getImagesDone()
-      },
-      title:title,
-      content:html
-    }
-    @popup.show args
-
-    w = @videoWidth
-    h = @videoHeight
-    @getFrame canvas,context,video,w,h
-
-  getImagesDone:->
-    @playing=false
-    ytid = @elements.ytid
-
-    imagesFolder = @elements.videoPath+ytid+'_images/'
-    try
-      fs.mkdirSync imagesFolder,0o777
-    catch error
-      #console.log error
-    i = 0
-    for frame in @frames
-      base64 = frame.replace(/^data:image\/jpeg;base64,/, "")
-      try
-        fs.writeFileSync imagesFolder+i+'.jpg',base64,'base64'
-      catch
-        #console.log error
-      i++
-    @elements.videoCanvas.remove()
-    @elements.video.remove()
-    @removeOldCanvas()
-    atom.config.set('editor-background.blurRadius',0)
-    atom.config.set('editor-background.imageURL','')
-    @popup.hide()
-    @initAnimation ytid
-
-
-  decodeVideo:->
-    #console.log 'decoding video',@elements.video
-    @frames = []
-    video = @elements.video
-    video.addEventListener 'ended',=>
-      @getImagesDone()
-    video.addEventListener 'canplay',=>
-      @getImages()
-
-
-  insertVideo: (savePath) ->
-    data = fs.readFileSync savePath
-    videoCanvas = document.createElement 'canvas'
-    videoWidth = @videoWidth
-    videoHeight = @videoHeight
-    videoCanvas.width = videoWidth
-    videoCanvas.height = videoHeight
-    @removeOldCanvas()
-    videoCanvas.id = "editor-background-videoCanvas"
-    conf = @configWnd.get 'editor-background'
-    videoOpacity = (conf.video.opacity/100).toFixed(2)
-    videoCanvas.style.cssText = "
-    position:absolute;
-    top:0px;
-    left:0px;
-    display:none;
-    width:#{videoWidth}px;
-    height:#{videoHeight}px;
-    opacity:#{videoOpacity};
-    "
-    @elements.videoCanvas = videoCanvas
-    @elements.main.insertBefore videoCanvas,@elements.textBackground
-    @decodeVideo()
-
-  createVideoElement:(src)->
-    video = document.createElement 'video'
-    source = document.createElement 'source'
-    @elements.video =  video
-    @elements.source = source
-    video.appendChild source
-    source.type="video/"+@elements.videoFormat
-    source.src=src
-    video.style.cssText="
-    position:absolute;
-    left:0;
-    top:0;
-    width:100%;
-    height:100%;
-    "
-    @elements.main.insertBefore video,@elements.textBackground
-
-
-
-  chooseFormat:(formats,next)->
-    #console.log 'choose format?'
-    html = '
-

-    Choose video format

-

-    <select id="background-format" name="format">'
-    #console.log 'formatChooser'
-    formatKeys = Object.keys(formats)
-    for itag in formatKeys
-      format = formats[itag]
-      #console.log 'format',format
-      html += "<option value=\"#{format.itag}\">Size: #{format.size}</option>"
-    html += '</select>

-

-

-
'
-
-    args = {
-      buttons:{
-        "OK":(ev,popup)=>
-          bgf = document.querySelector '#background-format'
-          itag = bgf.value
-          @popup.hide()
-          next(itag)
-      },
-      content:html,
-      title:"Editor Background - Video format"
-    }
-    #console.log 'show popup?'
-    @popup.show args
-
-
-
-  downloadYTVideo: (url)->
-    videoExt = @elements.videoExt
-    videoFormat = @elements.videoFormat
-    if url != ''
-      ytid = @getYTId url
-      @elements.ytid = ytid
-      savePath = @elements.videoPath+ytid+videoExt
-
-      alreadyExists = false
-      try
-        downloaded = fs.statSync(savePath)
-        alreadyExists = downloaded.isFile()
-      catch error
-        #console.log error
-
-      try
-        dirExists = fs.statSync @elements.videoPath
-        if dirExists?
-          if not dirExists.isDirectory()
-            fs.mkdirSync @elements.videoPath,0o777
-        else
-          fs.mkdirSync @elements.videoPath,0o777
-      catch e
-        #console.log e.stack
-
-      if not alreadyExists
-        @yt = new yt(url)
-        @yt.on 'formats',(formats)=>
-          #console.log 'formats',formats
-        @yt.on 'data',(data)=>
-          html='

-          Downloading: '+(data.percent).toFixed(2)+' %
-
'
-          title = 'Editor Background - download'
-          args = {
-            title:"Editor Background - downloading...",
-            content:html
-          }
-          @popup.show args
-
-        @yt.on 'done',(chunks)=>
-          @popup.hide()
-          @createVideoElement(savePath)
-          @insertVideo.apply @,[savePath]
-
-        @yt.on 'ready',=>
-          #console.log 'get video info ready'
-          conf = @configWnd.get('editor-background')
-          @time = {
-            start:conf.video.startTime,
-            end:conf.video.endTime
-          }
-          @chooseFormat @yt.formats,(format)=>
-            #console.log 'we chosen format',format
-            @videoWidth = @yt.formats[format].width
-            @videoHeight = @yt.formats[format].height
-            @yt.download {filename:savePath,itag:format,time:@time}
-        #console.log 'getting video info'
-        @yt.getVideoInfo()
-      else
-        @initAnimation(ytid)
-    else
-      @removeVideo()
-
-  removeOldCanvas:->
-    el = qra "#editor-background-videoCanvas"
-    el.forEach (e)->
-      console.log("removing",e)
-      e.remove()
-
-    el = qra ".editor-background-animation"
-    el.forEach (e)->e.remove()
-
-  removeVideo:->
-    if @animation?
-        @animation.stop()
-        delete @animation
-    @removeOldCanvas()
-
-
-  startYouTube: ->
-    if @packagesLoaded
-      conf = @configWnd.get 'editor-background'
-      if conf.video.youTubeURL? != '' && conf.video.playAnimation
-        if !@animation?
-            @downloadYTVideo conf.video.youTubeURL
-      else
-        @removeVideo()
-    else
-      setTimeout (=>@startYouTube.apply @,[]),1000
-
-
-  initAnimation:(ytid)->
-    canvasIsAdded = qra ".editor-background-animation".length>0
-    if !@animation?
-      atom.notifications.add 'notice','starting animation...'
-      @animation = new animation(ytid)
-      @animation.start @elements.main,@elements.textBackground
-      conf = @configWnd.get 'editor-background'
-      videoOpacity = (conf.video.opacity/100).toFixed(2)
-      if @animation?.canvas?
-          inline @animation.canvas,"opacity:#{videoOpacity};"
-
-
-  getOffset: (element, offset) ->
-    {left:0,top:0}
-    if element?
-      if !offset? then offset = {left:0,top:0}
-      offset.left += element.offsetLeft
-      offset.top += element.offsetTop
-      if element.offsetParent?
-        @getOffset element.offsetParent, offset
-      else
-        offset
-
-
-  drawLine: (textLine,attrs) ->
-    line = document.createElement 'div'
-    line.className = 'editor-background-line'
-    text = textLine.trim()
-    text = escapeHTML(text)
-    text = text.replace(/[\s]{1}/gi,
-      '')
-    text = text.replace(/[\t]{1}/gi,
-      '')
-    line.innerHTML = text
-
-    startTextOffset = textLine.search(/[^\s]+/gi)
-    startText = textLine.substr(0,startTextOffset)
-
-    spaces = startText.match(/ +/)?[0].length
-    if !spaces?
-      spaces=0
-    tabs = textLine.match(/^\t+/)?[0].length
-    if !tabs?
-      tabs=0
-    offsetLeft = spaces*attrs.charWidth + tabs*attrs.tabWidth
-
-    marginLeft = offsetLeft
-    marginLeft -= attrs.scrollLeft
-    line.style.cssText = "
-      margin-left:#{marginLeft}px;
-    "
-    @elements.textBackground.appendChild line
-
-  drawLines: (attrs) ->
-    if attrs?
-      if attrs.editorElement? && attrs.screenLines?
-        @elements.textBackground.innerText = ''
-        editor = attrs.editorElement
-        if editor.constructor.name == 'atom-text-editor'
-
-          conf = @configWnd.get('editor-background')
-          #console.log 'conf',conf
-          textBlur = conf.text.blur
-          opacity = (conf.text.opacity/100).toFixed(2)
-          color = conf.text.color.toHexString()
-          expand = conf.text.expand
-
-
-          root = atom.views.getView(editor)
-          scrollView = root.querySelector '.scroll-view'
-
-          activeEditor = atom.workspace.getActiveTextEditor()
-          editor = atom.views.getView(activeEditor)
-
-          #console.log "screen lines",attrs.screenLines
-
-          if scrollView?
-            offset = @getOffset scrollView
-            top = offset.top - attrs.offsetTop
-            left = offset.left
-            right = left + scrollView.width + textBlur
-            bottom = top + scrollView.height
-            activeEditor = attrs.activeEditor
-            lineHeight = attrs.lineHeight
-            charWidth = activeEditor.getDefaultCharWidth()
-            tabWidth = activeEditor.getTabLength() * charWidth
-
-
-
-          if editor?
-            computedStyle = window.getComputedStyle(editor)
-
-            fontFamily = computedStyle.fontFamily
-            fontSize = computedStyle.fontSize
-            if atom.config.settings.editor?
-              editorSetting = atom.config.settings.editor
-              if editorSetting.fontFamily?
-                fontFamily = editorSetting.fontFamily
-              if editorSetting.fontSize?
-                fontSize = editorSetting.fontSize
-
-            if !/[0-9]+px$/.test(fontSize)
-              fontSize+='px'
-
-            scaleX = 1 + parseFloat((expand / 100).toFixed(2))
-            scaleY = 1 + parseFloat((expand / 10).toFixed(2))
-
-
-            css = @elements.textBackgroundCss
-
-            css.innerText="
-              .editor-background-line{
-                font-family:#{fontFamily};
-                font-size:#{fontSize};
-                height:#{lineHeight}px;
-                display:block;
-                color:transparent;
-                background:#{color};
-                width:auto;
-                border-radius:10px;
-                transform:translate3d(0,0,0) scale(#{scaleX},#{scaleY});
-                float:left;
-                clear:both;
-              }
-              .editor-background-white{
-                width:#{charWidth}px;
-                display:inline-block;
-              }
-              .editor-background-tab{
-                width:#{tabWidth}px;
-                display:inline-block;
-              }
-            "
-            @elements.textBackground.style.cssText="
-            top:#{top}px;
-            left:#{left}px;
-            right:#{right}px;
-            bottom:#{bottom}px;
-            position:absolute;
-            overflow:hidden;
-            z-index:0;
-            pointer-events:none;
-            opacity:#{opacity};
-            transform:translate3d(0,0,0);
-            -webkit-filter:blur(#{textBlur}px);
-            "
-
-            attrsForward = {
-              charWidth:charWidth
-              tabWidth:tabWidth
-              scrollLeft:attrs.scrollLeft
-            }
-            for line in attrs.screenLines
-              @drawLine line,attrsForward if line?
-
-
-  activeEditor:{}
-
-  removeBgLines:->
-    @elements.textBackground.innerText=''
-
-  drawBackground: (event,editor)->
-    # no editors left
-    if event?.destroy?
-      if event.destroy.pane.items.length==0
-        @removeBgLines()
-        return
-    # changed active editor
-
-    @activeEditor = atom.workspace.getActiveTextEditor()
-    if event?.active?
-      @activeEditor=editor
-      if editor?
-        process.nextTick =>@drawBackground.apply @,[]
-      else
-        @removeBgLines()
-      return
-    activeEditor = @activeEditor
-
-    if activeEditor?
-      buffer = activeEditor.getBuffer()
-      editorElement = atom.views.getView(activeEditor)
-      actualLines = activeEditor.getVisibleRowRange()
-      lines = buffer.getLines()
-
-      if !actualLines?
-        @removeBgLines()
-        actualLines = [0,1]
-        # we must display text bg even if visibleRowRange returns null
-        # because there may be some characters that user is typing
-
-      if actualLines?.length == 2
-        if actualLines? && actualLines[0]? && actualLines[1]?
-          #screenLines = tokenizedLines[ actualLines[0]..actualLines[1] ]
-          screenLines = lines[actualLines[0]..actualLines[1]]
-          #console.log "screenLines",screenLines
-          elem = activeEditor.getElement()
-
-          scrollTop = elem.getScrollTop()
-          scrollLeft = elem.getScrollLeft()
-          lineHeight = activeEditor.getLineHeightInPixels()
-          offsetTop = scrollTop - Math.round(scrollTop / lineHeight) * lineHeight
-          editorElement = atom.views.getView(activeEditor)
-          if editorElement?
-            if editorElement.constructor.name == 'atom-text-editor'
-              editorRect = editorElement.getBoundingClientRect()
-              attrs =
-                {
-                  editorElement:editorElement
-                  activeEditor:activeEditor
-                  lineHeight:lineHeight
-                  screenLines:screenLines
-                  offsetTop:offsetTop
-                  scrollTop:scrollTop
-                  scrollLeft:scrollLeft
-                  visibleBuffer: actualLines
-                }
-              @drawLines attrs
-
-  watchEditor:(editor)->
-    elem = editor.getElement()
-    @subs.add elem.onDidChangeScrollTop (scroll)=>
-      @drawBackground.apply @,[{scrollTop:scroll},editor]
-    @subs.add elem.onDidChangeScrollLeft (scroll)=>
-      @drawBackground.apply @,[{scrolLeft:scroll},editor]
-    @subs.add editor.onDidChange (change)=>
-      @drawBackground.apply @,[{change:change},editor]
-    element = editor.getElement()
-    model = element.getModel()
+{CompositeDisposable} = require 'atom'
+fs = require 'fs'
+blur = require './StackBlur.js'
+animation = require './animation'
+yt = require './youtube'
+popup = require './popup'
+configWindow = require './config'
+path = require 'path'
+#elementResizeEvent = require 'element-resize-event'
+
+qr = (selector) -> document.querySelector selector
+qra = (selector) -> document.querySelectorAll selector
+style = (element) -> document.defaultView.getComputedStyle element
+inline = (element,style) -> if element?.style
+  element.style.cssText += style
+escapeHTML = (text) ->
+  text
+    .replace(/&/g, "&")
+    .replace(/</g, "<")
+    .replace(/>/g, ">")
+    .replace(/"/g, """)
+    .replace(/'/g, "'")
+
+blobToBase64 = (blob, cb) ->
+  reader = new FileReader()
+  reader.onload = ->
+    dataUrl = reader.result
+    base64 = dataUrl.split(',')[1]
+    cb(base64)
+  reader.readAsDataURL(blob)
+
+shadowDomAlert = false
+
+planeInitialCss =
+  "position:absolute;
+  left:0;
+  top:0;
+  width:100%;
+  height:100%;
+  background:transparent;
+  pointer-events:none;
+  z-index:0;"
+
+colorToArray = (str) ->
+  if !str?
+    return [0,0,0,0]
+  result = str.replace(/[^\d,\.]/g,'')
+  result = result.split(',')
+  result
+
+module.exports = EditorBackground =
+  config:
+    useConfigWindow:
+      type:'string'
+      description:"USE PACKAGE CONFIG WINDOW INSTEAD OF THIS SETTINGS ( CTRL + SHIFT + E ) TO OPEN"
+      toolbox:'ignore'
+      default:''
+      order:0
+    image:
+      type:'object'
+      properties:
+        url:
+          type:'string'
+          toolbox:'file'
+          title:'Image URL'
+          default:'atom://editor-background/bg.jpg'
+          description:"URL of your image. It can be http://...
+          or just /home/yourname/image.jpg"
+        blurRadius:
+          type:'integer'
+          description:"Background image blur. 0 = none"
+          default:0
+          minimim:0
+          maximum: 200
+        backgroundSize:
+          type:"string"
+          default:"original"
+          enum:["original","100%","cover","manual"]
+          description:"Background size"
+        manualBackgroundSize:
+          type:"string"
+          default:""
+          description:"'100px 100px' or '50%' try something..."
+        backgroundPosition:
+          type:"string"
+          default:"center"
+          description:"Background position"
+        repeat:
+          type:"string"
+          default:"no-repeat"
+          enum:["no-repeat","repeat","repeat-x","repeat-y"]
+          description:"Background repeat"
+        customOverlayColor:
+          type:"boolean"
+          default:false
+          description:"Do you want different color on top of background?"
+        overlayColor:
+          type:'color'
+          default:'rgba(0,0,0,0)'
+          description:"Color used to overlay background image"
+        opacity:
+          type:'integer'
+          default:100
+          description:"Background image visibility percent 1-100"
+          minimum:0
+          maximum:100
+        style:
+          type:"string"
+          toolbox:"text"
+          default:"background:radial-gradient(rgba(0,0,0,0) 30%,rgba(0,0,0,0.75));"
+          description:"Your custom css rules :]"
+    text:
+      type:'object'
+      properties:
+        color:
+          type:"color"
+          default:"rgba(0,0,0,1)"
+          description:"background color for text/code"
+        opacity:
+          type:"integer"
+          default:100
+          minimum:0
+          maximum:100
+        blur:
+          type:"integer"
+          default:5
+          minimum:0
+          maximum:50
+        expand:
+          type:"integer"
+          default:4
+          description:"If you want larger area under text - try 4 or 10"
+          minimum:0
+          maximum:200
+        shadow:
+          type:"string"
+          default:"none"
+          description:"Add a little text shadow to code like
+          '0px 2px 2px rgba(0,0,0,0.3)' "
+    video:
+      type:'object'
+      properties:
+        youTubeURL:
+          type:'string'
+          default:''
+          description:"Search for 'background loop',
+          'background animation' or similar on youtube and paste url here."
+        playAnimation:
+          type:"boolean"
+          default:false
+          description:"enable or disable animation"
+        animationSpeed:
+          type:"integer"
+          default:75
+          description:"animation speed in ms (original is 50),
+          LOWER VALUE = HIGHER CPU USAGE"
+        opacity:
+          type:"integer"
+          default:75
+          minimum:0
+          maximum:100
+          description:"video opacity"
+        startTime:
+          type:"string"
+          default:'0s'
+          description:"video start time like 1h30m10s or 10s"
+        endTime:
+          type:"string"
+          default:"20s"
+          description:"video end time like 1h30m30s or 30s"
+    other:
+      type:'object'
+      properties:
+        treeViewOpacity:
+          type:'integer'
+          default:"35"
+          description:"Tree View can be transparent too :)"
+          minimum:0
+          maximum:100
+        transparentTabBar:
+          type:"boolean"
+          default:true
+          desctiption:"Transparent background under file tabs"
+    box3d:
+      type:'object'
+      properties:
+        depth:
+          type:"integer"
+          default: 0
+          minimum: 0
+          maximum: 2000
+          description:"This is pseudo 3D Cube. Try 500 or 1500 or
+          something similar..."
+        shadowOpacity:
+          type:"integer"
+          default:30
+          minimum:0
+          maximum:100
+          description:"shadow that exists in every corner of the box"
+        mouseFactor:
+          type:"integer"
+          default: 0
+          description: "move background with mouse (higher value = slower)
+          try 8 or 4 for 3dbox or 20 for wallpaper"
+
+
+
+
+
+  packagesLoaded:false
+  initialized:false
+  elements: {}
+  colors: {}
+  state: {}
+  mouseX:0
+  mouseY:0
+  editorStyles:[]
+  editor:{}
+
+
+  activate: (state) ->
+    @subs = new CompositeDisposable
+    @subs.add atom.commands.add 'atom-workspace',
+      'editor-background:toggle': => @toggle()
+    @subs.add atom.config.observe 'editor-background',
+     (conf) => @applyBackground.apply @,[conf]
+    @subs.add atom.config.observe 'editor-background.image.url',(url)=>
+      @blurImage.apply @,[url]
+    @subs.add atom.config.observe 'editor-background.video.youTubeURL',(url) =>
+      @startYouTube.apply @,[url]
+    @subs.add atom.config.observe 'editor-background.video.playAnimation',(play) =>
+        if play==false
+            @removeVideo()
+        else
+            @startYouTube.apply @,[]
+
+    @initializePackage()
+
+  deactivate: ()->
+    if @subs?
+        @subs.dispose()
+    if @elements?.main?
+        @elements.main.remove()
+
+  appendCss: () ->
+    css = ""
+    cssstyle = document.createElement 'style'
+    cssstyle.type = 'text/css'
+    cssstyle.setAttribute 'id','#editor-background-css'
+    @elements.main.appendChild cssstyle
+    @elements.css = cssstyle
+
+  createBox: (depth) ->
+    body = @elements.body
+    jest = qr 'body .eb-box-wrapper'
+    if not jest? or jest.length==0
+      left = document.createElement 'div'
+      top = document.createElement 'div'
+      right = document.createElement 'div'
+      bottom = document.createElement 'div'
+      back = document.createElement 'div'
+      wrapper = document.createElement 'div'
+      wrapper.appendChild left
+      wrapper.appendChild top
+      wrapper.appendChild right
+      wrapper.appendChild bottom
+      wrapper.appendChild back
+      wrapper.setAttribute 'class','eb-box-wrapper'
+      left.setAttribute 'class','eb-left'
+      top.setAttribute 'class','eb-top'
+      right.setAttribute 'class','eb-right'
+      bottom.setAttribute 'class','eb-bottom'
+      back.setAttribute 'class','eb-back'
+
+      boxStyle = document.createElement 'style'
+      boxStyle.type = "text/css"
+      @elements.main.appendChild boxStyle
+
+      @elements.main.appendChild wrapper
+    boxStyle
+
+  mouseMove: (ev) ->
+    conf=@configWnd.get('editor-background')
+    if conf.box3d.mouseFactor > 0
+      @mouseX=ev.pageX
+      @mouseY=ev.pageY
+      if conf.box3d.depth>0 then @updateBox() else @updateBgPos()
+
+
+
+  activateMouseMove: ->
+    body = @elements.body
+    body.addEventListener 'mousemove',(ev) =>  @mouseMove.apply @,[ev]
+
+  insertMain:->
+    main = document.createElement 'div'
+    main.id='editor-background-main'
+    @elements.main=main
+    document.querySelector '#editor-background-main'.remove
+    @elements.body.insertBefore main,@elements.body.firstChild
+    @elements.itemViews = document.querySelectorAll '.item-views'
+    for el in @elements.itemViews
+        el.style.cssText="background:transparent !important";
+
+  insertTextBackgroundCss:->
+    # CSS for background text
+    txtBgCss = document.createElement 'style'
+    txtBgCss.type="text/css"
+    bgColor =
+    txtBgCss.cssText="
+      .editor-background-line{
+        background:black;
+        color:white;
+      }
+      atom-pane-container atom-pane .item-views{
+        background:transparent !important;
+        background-color:transparent !important;
+      }
+    "
+    @elements.textBackgroundCss=txtBgCss
+    @elements.main.appendChild txtBgCss
+
+  insertTextBackground:->
+    # container of the background text
+    txtBg = document.createElement 'div'
+    txtBg.style.cssText="
+      position:absolute;
+      z-index:-1;
+    "
+    @elements.textBackground = txtBg
+    @elements.main.appendChild txtBg
+
+  getYTId: (url) ->
+    if url!=''
+      ytreg = /// (?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)
+      |youtu\.be\/)([^"&?\/ ]{11}) ///i
+      ytidregres=ytreg.exec(url)
+      if ytidregres?.length>0
+        ytid=ytidregres[1]
+
+  timer:{}
+  frames:[]
+  frame:0
+  videoWidth:0
+  videoHeight:0
+  playing:true
+
+  getFrame:(canvas,ctx,video,w,h)->
+    @frame++
+    tick=50
+    #console.log 'getFrame time',@time
+    if @frame*tick >= @time.end - @time.start
+      return @getImagesDone
+    frame=document.querySelector '#editor-background-frame'
+    frame.innerText=@frame
+    ctx.drawImage video,0,0
+    video.pause()
+    if @playing
+      @frames.push canvas.toDataURL('image/jpeg')
+      video.play()
+      if @playing
+        setTimeout =>
+          @getFrame.apply @,[canvas,ctx,video,w,h]
+        ,tick
+
+
+  getImages: ->
+    @playing=true
+    @frame = 0
+    #console.log 'getting images...'
+    video = @elements.video
+    canvas = @elements.videoCanvas
+    context = canvas.getContext("2d")
+    ytid = @getYTId @configWnd.get 'editor-background.video.youTubeURL'
+
+    html="
+

+    Getting Frame: 0

+    Please be patient.
"
+    title= 'Editor background - frames'
+    args = {
+      buttons:{
+        "Cancel":(ev)=>@getImagesDone()
+      },
+      title:title,
+      content:html
+    }
+    @popup.show args
+
+    w = @videoWidth
+    h = @videoHeight
+    @getFrame canvas,context,video,w,h
+
+  getImagesDone:->
+    @playing=false
+    ytid = @elements.ytid
+
+    imagesFolder = @elements.videoPath+ytid+'_images/'
+    try
+      fs.mkdirSync imagesFolder,0o777
+    catch error
+      #console.log error
+    i = 0
+    for frame in @frames
+      base64 = frame.replace(/^data:image\/jpeg;base64,/, "")
+      try
+        fs.writeFileSync imagesFolder+i+'.jpg',base64,'base64'
+      catch
+        #console.log error
+      i++
+    @elements.videoCanvas.remove()
+    @elements.video.remove()
+    @removeOldCanvas()
+    atom.config.set('editor-background.blurRadius',0)
+    atom.config.set('editor-background.imageURL','')
+    @popup.hide()
+    @initAnimation ytid
+
+
+  decodeVideo:->
+    #console.log 'decoding video',@elements.video
+    @frames = []
+    video = @elements.video
+    video.addEventListener 'ended',=>
+      @getImagesDone()
+    video.addEventListener 'canplay',=>
+      @getImages()
+
+
+  insertVideo: (savePath) ->
+    data = fs.readFileSync savePath
+    videoCanvas = document.createElement 'canvas'
+    videoWidth = @videoWidth
+    videoHeight = @videoHeight
+    videoCanvas.width = videoWidth
+    videoCanvas.height = videoHeight
+    @removeOldCanvas()
+    videoCanvas.id = "editor-background-videoCanvas"
+    conf = @configWnd.get 'editor-background'
+    videoOpacity = (conf.video.opacity/100).toFixed(2)
+    videoCanvas.style.cssText = "
+    position:absolute;
+    top:0px;
+    left:0px;
+    display:none;
+    width:#{videoWidth}px;
+    height:#{videoHeight}px;
+    opacity:#{videoOpacity};
+    "
+    @elements.videoCanvas = videoCanvas
+    @elements.main.insertBefore videoCanvas,@elements.textBackground
+    @decodeVideo()
+
+  createVideoElement:(src)->
+    video = document.createElement 'video'
+    source = document.createElement 'source'
+    @elements.video =  video
+    @elements.source = source
+    video.appendChild source
+    source.type="video/"+@elements.videoFormat
+    source.src=src
+    video.style.cssText="
+    position:absolute;
+    left:0;
+    top:0;
+    width:100%;
+    height:100%;
+    "
+    @elements.main.insertBefore video,@elements.textBackground
+
+
+
+  chooseFormat:(formats,next)->
+    #console.log 'choose format?'
+    html = '
+

+    Choose video format

+

+    <select id="background-format" name="format">'
+    #console.log 'formatChooser'
+    formatKeys = Object.keys(formats)
+    for itag in formatKeys
+      format = formats[itag]
+      #console.log 'format',format
+      html += "<option value=\"#{format.itag}\">Size: #{format.size}</option>"
+    html += '</select>

+

+

+
'
+
+    args = {
+      buttons:{
+        "OK":(ev,popup)=>
+          bgf = document.querySelector '#background-format'
+          itag = bgf.value
+          @popup.hide()
+          next(itag)
+      },
+      content:html,
+      title:"Editor Background - Video format"
+    }
+    #console.log 'show popup?'
+    @popup.show args
+
+
+
+  downloadYTVideo: (url)->
+    videoExt = @elements.videoExt
+    videoFormat = @elements.videoFormat
+    if url != ''
+      ytid = @getYTId url
+      @elements.ytid = ytid
+      savePath = @elements.videoPath+ytid+videoExt
+
+      alreadyExists = false
+      try
+        downloaded = fs.statSync(savePath)
+        alreadyExists = downloaded.isFile()
+      catch error
+        #console.log error
+
+      try
+        dirExists = fs.statSync @elements.videoPath
+        if dirExists?
+          if not dirExists.isDirectory()
+            fs.mkdirSync @elements.videoPath,0o777
+        else
+          fs.mkdirSync @elements.videoPath,0o777
+      catch e
+        #console.log e.stack
+
+      if not alreadyExists
+        @yt = new yt(url)
+        @yt.on 'formats',(formats)=>
+          #console.log 'formats',formats
+        @yt.on 'data',(data)=>
+          html='

+          Downloading: '+(data.percent).toFixed(2)+' %
+
'
+          title = 'Editor Background - download'
+          args = {
+            title:"Editor Background - downloading...",
+            content:html
+          }
+          @popup.show args
+
+        @yt.on 'done',(chunks)=>
+          @popup.hide()
+          @createVideoElement(savePath)
+          @insertVideo.apply @,[savePath]
+
+        @yt.on 'ready',=>
+          #console.log 'get video info ready'
+          conf = @configWnd.get('editor-background')
+          @time = {
+            start:conf.video.startTime,
+            end:conf.video.endTime
+          }
+          @chooseFormat @yt.formats,(format)=>
+            #console.log 'we chosen format',format
+            @videoWidth = @yt.formats[format].width
+            @videoHeight = @yt.formats[format].height
+            @yt.download {filename:savePath,itag:format,time:@time}
+        #console.log 'getting video info'
+        @yt.getVideoInfo()
+      else
+        @initAnimation(ytid)
+    else
+      @removeVideo()
+
+  removeOldCanvas:->
+    el = qra "#editor-background-videoCanvas"
+    el.forEach (e)->
+      console.log("removing",e)
+      e.remove()
+
+    el = qra ".editor-background-animation"
+    el.forEach (e)->e.remove()
+
+  removeVideo:->
+    if @animation?
+        @animation.stop()
+        delete @animation
+    @removeOldCanvas()
+
+
+  startYouTube: ->
+    if @packagesLoaded
+      conf = @configWnd.get 'editor-background'
+      if conf.video.youTubeURL? != '' && conf.video.playAnimation
+        if !@animation?
+            @downloadYTVideo conf.video.youTubeURL
+      else
+        @removeVideo()
+    else
+      setTimeout (=>@startYouTube.apply @,[]),1000
+
+
+  initAnimation:(ytid)->
+    canvasIsAdded = qra ".editor-background-animation".length>0
+    if !@animation?
+      atom.notifications.add 'notice','starting animation...'
+      @animation = new animation(ytid)
+      @animation.start @elements.main,@elements.textBackground
+      conf = @configWnd.get 'editor-background'
+      videoOpacity = (conf.video.opacity/100).toFixed(2)
+      if @animation?.canvas?
+          inline @animation.canvas,"opacity:#{videoOpacity};"
+
+
+  getOffset: (element, offset) ->
+    {left:0,top:0}
+    if element?
+      if !offset? then offset = {left:0,top:0}
+      offset.left += element.offsetLeft
+      offset.top += element.offsetTop
+      if element.offsetParent?
+        @getOffset element.offsetParent, offset
+      else
+        offset
+
+
+  drawLine: (textLine,attrs) ->
+    line = document.createElement 'div'
+    line.className = 'editor-background-line'
+    text = textLine.trim()
+    text = escapeHTML(text)
+    text = text.replace(/[\s]{1}/gi,
+      '')
+    text = text.replace(/[\t]{1}/gi,
+      '')
+    line.innerHTML = text
+
+    startTextOffset = textLine.search(/[^\s]+/gi)
+    startText = textLine.substr(0,startTextOffset)
+
+    spaces = startText.match(/ +/)?[0].length
+    if !spaces?
+      spaces=0
+    tabs = textLine.match(/^\t+/)?[0].length
+    if !tabs?
+      tabs=0
+    offsetLeft = spaces*attrs.charWidth + tabs*attrs.tabWidth
+
+    marginLeft = offsetLeft
+    marginLeft -= attrs.scrollLeft
+    line.style.cssText = "
+      margin-left:#{marginLeft}px;
+    "
+    @elements.textBackground.appendChild line
+
+  drawLines: (attrs) ->
+    if attrs?
+      if attrs.editorElement? && attrs.screenLines?
+        @elements.textBackground.innerText = ''
+        editor = attrs.editorElement
+        if editor.constructor.name == 'atom-text-editor'
+
+          conf = @configWnd.get('editor-background')
+          #console.log 'conf',conf
+          textBlur = conf.text.blur
+          opacity = (conf.text.opacity/100).toFixed(2)
+          color = conf.text.color.toHexString()
+          expand = conf.text.expand
+
+
+          root = atom.views.getView(editor)
+          scrollView = root.querySelector '.scroll-view'
+
+          activeEditor = atom.workspace.getActiveTextEditor()
+          editor = atom.views.getView(activeEditor)
+
+          #console.log "screen lines",attrs.screenLines
+
+          if scrollView?
+            offset = @getOffset scrollView
+            top = offset.top - attrs.offsetTop
+            left = offset.left
+            right = left + scrollView.width + textBlur
+            bottom = top + scrollView.height
+            activeEditor = attrs.activeEditor
+            lineHeight = attrs.lineHeight
+            charWidth = activeEditor.getDefaultCharWidth()
+            tabWidth = activeEditor.getTabLength() * charWidth
+
+
+
+          if editor?
+            computedStyle = window.getComputedStyle(editor)
+
+            fontFamily = computedStyle.fontFamily
+            fontSize = computedStyle.fontSize
+            if atom.config.settings.editor?
+              editorSetting = atom.config.settings.editor
+              if editorSetting.fontFamily?
+                fontFamily = editorSetting.fontFamily
+              if editorSetting.fontSize?
+                fontSize = editorSetting.fontSize
+
+            if !/[0-9]+px$/.test(fontSize)
+              fontSize+='px'
+
+            scaleX = 1 + parseFloat((expand / 100).toFixed(2))
+            scaleY = 1 + parseFloat((expand / 10).toFixed(2))
+
+
+            css = @elements.textBackgroundCss
+
+            css.innerText="
+              .editor-background-line{
+                font-family:#{fontFamily};
+                font-size:#{fontSize};
+                height:#{lineHeight}px;
+                display:block;
+                color:transparent;
+                background:#{color};
+                width:auto;
+                border-radius:10px;
+                transform:translate3d(0,0,0) scale(#{scaleX},#{scaleY});
+                float:left;
+                clear:both;
+              }
+              .editor-background-white{
+                width:#{charWidth}px;
+                display:inline-block;
+              }
+              .editor-background-tab{
+                width:#{tabWidth}px;
+                display:inline-block;
+              }
+            "
+            @elements.textBackground.style.cssText="
+            top:#{top}px;
+            left:#{left}px;
+            right:#{right}px;
+            bottom:#{bottom}px;
+            position:absolute;
+            overflow:hidden;
+            z-index:0;
+            pointer-events:none;
+            opacity:#{opacity};
+            transform:translate3d(0,0,0);
+            -webkit-filter:blur(#{textBlur}px);
+            "
+
+            attrsForward = {
+              charWidth:charWidth
+              tabWidth:tabWidth
+              scrollLeft:attrs.scrollLeft
+            }
+            for line in attrs.screenLines
+              @drawLine line,attrsForward if line?
+
+
+  activeEditor:{}
+
+  removeBgLines:->
+    @elements.textBackground.innerText=''
+
+  drawBackground: (event,editor)->
+    # no editors left
+    if event?.destroy?
+      if event.destroy.pane.items.length==0
+        @removeBgLines()
+        return
+    # changed active editor
+
+    @activeEditor = atom.workspace.getActiveTextEditor()
+    if event?.active?
+      @activeEditor=editor
+      if editor?
+        process.nextTick =>@drawBackground.apply @,[]
+      else
+        @removeBgLines()
+      return
+    activeEditor = @activeEditor
+
+    if activeEditor?
+      buffer = activeEditor.getBuffer()
+      editorElement = atom.views.getView(activeEditor)
+      actualLines = activeEditor.getVisibleRowRange()
+      lines = buffer.getLines()
+
+      if !actualLines?
+        @removeBgLines()
+        actualLines = [0,1]
+        # we must display text bg even if visibleRowRange returns null
+        # because there may be some characters that user is typing
+
+      if actualLines?.length == 2
+        if actualLines? && actualLines[0]? && actualLines[1]?
+          #screenLines = tokenizedLines[ actualLines[0]..actualLines[1] ]
+          screenLines = lines[actualLines[0]..actualLines[1]]
+          #console.log "screenLines",screenLines
+          elem = activeEditor.getElement()
+
+          scrollTop = elem.getScrollTop()
+          scrollLeft = elem.getScrollLeft()
+          lineHeight = activeEditor.getLineHeightInPixels()
+          offsetTop = scrollTop - Math.floor(scrollTop / lineHeight) * lineHeight
+          editorElement = atom.views.getView(activeEditor)
+          if editorElement?
+            if editorElement.constructor.name == 'atom-text-editor'
+              editorRect = editorElement.getBoundingClientRect()
+              attrs =
+                {
+                  editorElement:editorElement
+                  activeEditor:activeEditor
+                  lineHeight:lineHeight
+                  screenLines:screenLines
+                  offsetTop:offsetTop
+                  scrollTop:scrollTop
+                  scrollLeft:scrollLeft
+                  visibleBuffer: actualLines
+                }
+              @drawLines attrs
+
+  watchEditor:(editor)->
+    elem = editor.getElement()
+    @subs.add elem.onDidChangeScrollTop (scroll)=>
+      @drawBackground.apply @,[{scrollTop:scroll},editor]
+    @subs.add elem.onDidChangeScrollLeft (scroll)=>
+      @drawBackground.apply @,[{scrolLeft:scroll},editor]
+    @subs.add editor.onDidChange (change)=>
+      @drawBackground.apply @,[{change:change},editor]
+    element = editor.getElement()
+    model = element.getModel()
     activeEditor = atom.workspace.getActiveTextEditor()
-    editorElement = atom.views.getView(activeEditor)
-    #editorElement = model.editorElement.component.domNodeValue
-    # little hack because of no "resize" event on textEditor
-    #elementResizeEvent editorElement,()=>
-    #  @drawBackground.apply @,[{resize:editorElement},editor]
-    #  elementResizeEvent does not work anymore
-
-
-  watchEditors: ->
-    @subs.add atom.workspace.observeTextEditors (editor) =>
-      @editorLoaded()
-      @watchEditor.apply @,[editor]
-    @subs.add atom.workspace.observeActivePaneItem (editor)=>
-      @editorLoaded()
-      @drawBackground.apply @,[{active:editor},editor]
-    @subs.add atom.workspace.onDidDestroyPaneItem (pane)=>
-      @drawBackground.apply @,[{destroy:pane}]
-    @subs.add atom.workspace.onDidDestroyPane (pane)=>
-      @drawBackground.apply @,[{destroy:pane}]
-    # another hack to be notified when new editor comes in place
-    @subs.add atom.workspace.emitter.on "did-add-text-editor",(ev)=>
-      @editorLoaded()
-      editor = ev.textEditor
-      @drawBackground.apply @,[{active:editor},editor]
-    #@subs.add atom.workspace.onDidInsertText (text)=>
-
-  editorLoaded: ->
-    if @elements.workspace?
-      activeEditor = atom.workspace.getActiveTextEditor()
-      @elements.editor = atom.views.getView(activeEditor)
-      if @elements.editor?
-        @colors.workspaceBgColor=style(@elements.editor).backgroundColor
-
-  initializePackage: ->
-    @elements.body = qr 'body'
-    @elements.workspace = qr 'atom-workspace'
-    @elements.editor = null
-    if @elements.workspace?
-      activeEditor = atom.workspace.getActiveTextEditor()
-      @elements.editor = atom.views.getView(activeEditor)
-    @elements.treeView = qr '.tree-view'
-    @elements.left = qr '.left'
-    @elements.leftPanel = (qr '.panel-left') or (qr '.panel-right')
-    @elements.resizer = qr '.tree-view-resizer'
-    @elements.tabBar = qr '.tab-bar'
-    @elements.insetPanel = qr '.inset-panel'
-
-    keys = Object.keys @elements
-    loaded = (@elements[k] for k in keys when @elements[k]?)
-    #console.log 'keys',keys,loaded
-    if true
-
-      @insertMain()
-      @popup = new popup()
-      confOptions = {
-        onChange:()=>
-          @drawBackground()
-      }
-      @configWnd = new configWindow 'editor-background',confOptions
-      @activateMouseMove()
-
-      conf=@configWnd.get('editor-background')
-
-      @elements.image = document.createElement 'img'
-      @elements.image.id='editor-background-image'
-      @elements.image.setAttribute 'src',conf.image.url
-
-      @elements.blurredImage = conf.image.url
-
-      @insertTextBackgroundCss()
-
-      if conf.box3d.mouseFactor>0 then @activateMouseMove()
-
-      @appendCss()
-      @watchEditors()
-
-      @elements.bg = document.createElement 'div'
-      @elements.bg.style.cssText="position:absolute;width:100%;height:100%;"
-      @elements.main.appendChild @elements.bg
-
-      @elements.boxStyle = @createBox()
-
-      @elements.plane = document.createElement('div')
-      @elements.plane.style.cssText = planeInitialCss
-      @elements.main.appendChild @elements.plane
-
-      @insertTextBackground()
-
-      if @elements.editor?
-        @colors.workspaceBgColor=style(@elements.editor).backgroundColor
-      else
-        @colors.workspaceBgColor="rgb(0,0,0)"
-
-      if @elements.treeView?
-        @colors.treeOriginalRGB=style(@elements.treeView).backgroundColor
-      else
-        @colors.treeOriginalRGB="rgb(0,0,0)"
-
-      @packagesLoaded = true
-
-      videoOpacity = (conf.video.opacity/100).toFixed(2)
-      if @animation?.canvas?
-          inline @animation.canvas,"opacity:#{videoOpacity};";
-
-      @blurImage()
-
-
-      @elements.videoPath=@pluginPath()+'/youtube-videos/'
-      @elements.libPath=@pluginPath()+'/lib/'
-      @elements.videoExt = '.mp4'
-      @elements.videoFormat = 'mp4'
-      try
-        fs.mkdirSync @elements.videoPath,0o777
-      catch error
-
-      @applyBackground.apply @
-    else
-      setTimeout (=>@initializePackage.apply @),1000
-
-  updateBgPos: ->
-    conf = @configWnd.get('editor-background')
-    body = @elements.body
-    factor = conf.box3d.mouseFactor
-    polowaX = body.clientWidth // 2
-    polowaY = body.clientHeight // 2
-    offsetX =  @mouseX - polowaX
-    offsetY =  @mouseY - polowaY
-    x = (offsetX // factor)
-    y = (offsetY // factor)
-    inline @elements.bg,"background-position:#{x}px #{y}px !important;"
-
-  updateBox: (depth) ->
-    conf=@configWnd.get('editor-background')
-    if not depth? then depth = conf.box3d.depth
-    depth2 = depth // 2
-    background=@elements.blurredImage
-    opacity=(conf.box3d.shadowOpacity / 100).toFixed(2)
-    imgOpacity = conf.image.opacity / 100
-    range=300
-    range2=range // 3
-    bgSize=conf.image.backgroundSize
-    if bgSize=='manual' then bgSize=conf.image.manualBackgroundSize
-    if bgSize=='original' then bgSize='auto'
-    body = @elements.body
-    factor = conf.box3d.mouseFactor
-    polowaX = body.clientWidth // 2
-    polowaY = body.clientHeight // 2
-    offsetX =  @mouseX - polowaX
-    offsetY =  @mouseY - polowaY
-    x = polowaX + (offsetX // factor)
-    y = polowaY + (offsetY // factor)
-    inline @elements.bg,"opacity:0;"
-    position = conf.image.backgroundPosition
-    repeat = conf.image.repeat
-    boxCss="
-    .eb-box-wrapper{
-      perspective:1000px;
-      perspective-origin:#{x}px #{y}px;
-      backface-visibility: hidden;
-      position:fixed;
-      top:0;
-      left:0;
-      width:100%;
-      height:100%;
-      opacity:#{imgOpacity};
-    }
-    .eb-left,.eb-top,.eb-right,.eb-bottom,.eb-back{
-      position:fixed;
-      transform-origin:50% 50%;
-      box-shadow:inset 0px 0px #{range}px rgba(0,0,0,#{opacity}),
-                  inset 0px 0px #{range2}px rgba(0,0,0,#{opacity});
-      background-image:url('#{background}');
-      background-size:#{bgSize};
-      backface-visibility: hidden;
-      background-position:#{position};
-      background-repeat:#{repeat};
-    }
-    .eb-left,.eb-right{
-      width:#{depth}px;
-      height:100%;
-    }
-    .eb-top,.eb-bottom{
-      width:100%;
-      height:#{depth}px;
-    }
-    .eb-left{
-      transform: translate3d(-50%,0,0) rotateY(-90deg);
-      left:0;
-    }
-    .eb-top{
-      transform: translate3d(0,-50%,0) rotateX(90deg);
-      top:0;
-    }
-    .eb-right{
-      transform: translate3d(50%,0,0) rotateY(-90deg);
-      right:0;
-    }
-    .eb-bottom{
-      transform: translate3d(0,50%,0) rotateX(90deg);
-      bottom:0;
-    }
-    .eb-back{
-      transform: translate3d(0,0,-#{depth2}px);
-      width:100%;
-      height:100%;
-    }
-    "
-    @elements.boxStyle.innerText = boxCss
-    if depth==0
-      @elements.boxStyle.innerText=".eb-box-wrapper{display:none;}"
-
-  pluginPath:->
-    _path = atom.packages.resolvePackagePath('editor-background')
-    if !_path
-      _path = path.resolve(__dirname)
-    return _path
-
-  blurImage:->
-    if @packagesLoaded
-      conf = @configWnd.get('editor-background')
-      @elements.image.setAttribute 'src',conf.image.url
-      applyBlur = false
-      if conf.image.blurRadius > 0
-        if @elements.image?
-          if @elements.image.complete
-            applyBlur = true
-          else
-            setTimeout (=> @blurImage.apply @),1000
-      if applyBlur and conf.image.url
-        imageData = blur.stackBlurImage @elements.image, conf.image.blurRadius, false
-        base64Data = imageData.replace(/^data:image\/png;base64,/, "")
-        filename = @pluginPath()+"/blur.png"
-        filename = filename.replace /\\/gi,'/'
-
-        fs.writeFileSync filename, base64Data,{mode:0o777,encoding:'base64'}
-        imageData=filename+"?timestamp="+Date.now()
-      else
-        imageData = conf.image.url
-      @elements.blurredImage = imageData
-      if conf.box3d.depth > 0
-        @updateBox()
-      else
-        opacity = conf.image.opacity / 100
-        position = conf.image.backgroundPosition
-        repeat = conf.image.repeat
-        inline @elements.bg,"background-image: url('#{imageData}') !important;"
-        inline @elements.bg,"opacity:#{opacity};"
-        inline @elements.bg,"background-position:#{position};"
-        inline @elements.bg,"background-repeat:#{repeat};"
-
-  applyBackground: ->
-    if @packagesLoaded
-      workspaceView = @elements.workspace
-      #console.log 'workspaceView',workspaceView
-      if workspaceView?
-        if workspaceView.className.indexOf('editor-background') == -1
-            workspaceView.className += ' editor-background'
-      conf = @configWnd.get 'editor-background'
-      opacity = 100 - conf.image.opacity
-      alpha=(opacity / 100).toFixed(2)
-
-      rgb = colorToArray @colors.workspaceBgColor
-      newColor = 'rgba( '+rgb[0]+' , '+rgb[1]+' , '+rgb[2]+' , '+alpha+')'
-
-      treeOpacity = conf.other.treeViewOpacity
-      treeAlpha = (treeOpacity / 100).toFixed(2)
-      treeRGB = colorToArray @colors.treeOriginalRGB
-
-      newTreeRGBA =
-        'rgba('+treeRGB[0]+','+treeRGB[1]+','+treeRGB[2]+','+treeAlpha+')'
-
-      if conf.image.customOverlayColor
-        _newColor = conf.image.overlayColor.toRGBAString()
-        rgb = colorToArray _newColor
-        newColor = 'rgba('+rgb[0]+','+rgb[1]+','+rgb[2]+','+alpha+')'
-        newTreeRGBA='rgba('+rgb[0]+','+rgb[1]+','+rgb[2]+','+treeAlpha+')'
-      else
-        _newColor = @colors.workspaceBgColor
-      @elements.css.innerText+="body{background:#{_newColor} !important;}"
-
-      #@elements.css.innerText+="\natom-pane-container atom-pane .item-views{background:transparent !important;}"
-
-      if conf.text.shadow
-        @elements.css.innerText+="\natom-text-editor::shadow .line{text-shadow:"+
-        conf.text.shadow+" !important;}"
-
-      if conf.box3d.depth>0
-        @updateBox conf.box3d.depth
-      else
-        @elements.boxStyle.innerText=".eb-box-wrapper{display:none;}"
-
-      #console.log 'conf.image.size',conf.image.backgroundSize
-      if conf.image.backgroundSize!='original'
-        inline @elements.bg, 'background-size:'+conf.image.backgroundSize+
-        ' !important;'
-      else
-        inline @elements.bg, 'background-size:auto !important'
-      if conf.image.backgroundSize == 'manual'
-        inline @elements.bg, 'background-size:'+conf.image.manualBackgroundSize+
-        ' !important;'
-
-      if conf.image.style
-        @elements.plane.style.cssText+=conf.image.style
-
-      @blurImage()
-
-      if conf.other.transparentTabBar
-        inline @elements.tabBar,'background:rgba(0,0,0,0) !important;'
-        inline @elements.insetPanel,'background:rgba(0,0,0,0) !important;'
-
-      if conf.other.treeViewOpacity > 0
-        inline @elements.treeView,'background:'+newTreeRGBA+' !important;'
-        inline @elements.left,'background:transparent !important;'
-        inline @elements.resizer,'background:transparent !important;'
-        inline @elements.leftPanel,'background:transparent !important;'
-
-
-
-
-
-
-  # show config window
-  toggle:->
-    if not @configWnd
-      atom.notifications.add 'warning','Editor-background is only available after you open some files.'
-    else
-      if not @configWnd.visible
-        @configWnd.show()
-      else
-        @popup.hide()
+    editorElement = atom.views.getView(activeEditor)
+    #editorElement = model.editorElement.component.domNodeValue
+    # little hack because of no "resize" event on textEditor
+    #elementResizeEvent editorElement,()=>
+    #  @drawBackground.apply @,[{resize:editorElement},editor]
+    #  elementResizeEvent does not work anymore
+
+
+  watchEditors: ->
+    @subs.add atom.workspace.observeTextEditors (editor) =>
+      @editorLoaded()
+      @watchEditor.apply @,[editor]
+    @subs.add atom.workspace.observeActivePaneItem (editor)=>
+      @editorLoaded()
+      @drawBackground.apply @,[{active:editor},editor]
+    @subs.add atom.workspace.onDidDestroyPaneItem (pane)=>
+      @drawBackground.apply @,[{destroy:pane}]
+    @subs.add atom.workspace.onDidDestroyPane (pane)=>
+      @drawBackground.apply @,[{destroy:pane}]
+    # another hack to be notified when new editor comes in place
+    @subs.add atom.workspace.emitter.on "did-add-text-editor",(ev)=>
+      @editorLoaded()
+      editor = ev.textEditor
+      @drawBackground.apply @,[{active:editor},editor]
+    #@subs.add atom.workspace.onDidInsertText (text)=>
+
+  editorLoaded: ->
+    if @elements.workspace?
+      activeEditor = atom.workspace.getActiveTextEditor()
+      @elements.editor = atom.views.getView(activeEditor)
+      if @elements.editor?
+        @colors.workspaceBgColor=style(@elements.editor).backgroundColor
+
+  initializePackage: ->
+    @elements.body = qr 'body'
+    @elements.workspace = qr 'atom-workspace'
+    @elements.editor = null
+    if @elements.workspace?
+      activeEditor = atom.workspace.getActiveTextEditor()
+      @elements.editor = atom.views.getView(activeEditor)
+    @elements.treeView = qr '.tree-view'
+    @elements.left = qr '.left'
+    @elements.leftPanel = (qr '.panel-left') or (qr '.panel-right')
+    @elements.resizer = qr '.tree-view-resizer'
+    @elements.tabBar = qr '.tab-bar'
+    @elements.insetPanel = qr '.inset-panel'
+
+    keys = Object.keys @elements
+    loaded = (@elements[k] for k in keys when @elements[k]?)
+    #console.log 'keys',keys,loaded
+    if true
+
+      @insertMain()
+      @popup = new popup()
+      confOptions = {
+        onChange:()=>
+          @drawBackground()
+      }
+      @configWnd = new configWindow 'editor-background',confOptions
+      @activateMouseMove()
+
+      conf=@configWnd.get('editor-background')
+
+      @elements.image = document.createElement 'img'
+      @elements.image.id='editor-background-image'
+      @elements.image.setAttribute 'src',conf.image.url
+
+      @elements.blurredImage = conf.image.url
+
+      @insertTextBackgroundCss()
+
+      if conf.box3d.mouseFactor>0 then @activateMouseMove()
+
+      @appendCss()
+      @watchEditors()
+
+      @elements.bg = document.createElement 'div'
+      @elements.bg.style.cssText="position:absolute;width:100%;height:100%;"
+      @elements.main.appendChild @elements.bg
+
+      @elements.boxStyle = @createBox()
+
+      @elements.plane = document.createElement('div')
+      @elements.plane.style.cssText = planeInitialCss
+      @elements.main.appendChild @elements.plane
+
+      @insertTextBackground()
+
+      if @elements.editor?
+        @colors.workspaceBgColor=style(@elements.editor).backgroundColor
+      else
+        @colors.workspaceBgColor="rgb(0,0,0)"
+
+      if @elements.treeView?
+        @colors.treeOriginalRGB=style(@elements.treeView).backgroundColor
+      else
+        @colors.treeOriginalRGB="rgb(0,0,0)"
+
+      @packagesLoaded = true
+
+      videoOpacity = (conf.video.opacity/100).toFixed(2)
+      if @animation?.canvas?
+          inline @animation.canvas,"opacity:#{videoOpacity};";
+
+      @blurImage()
+
+
+      @elements.videoPath=@pluginPath()+'/youtube-videos/'
+      @elements.libPath=@pluginPath()+'/lib/'
+      @elements.videoExt = '.mp4'
+      @elements.videoFormat = 'mp4'
+      try
+        fs.mkdirSync @elements.videoPath,0o777
+      catch error
+
+      @applyBackground.apply @
+    else
+      setTimeout (=>@initializePackage.apply @),1000
+
+  updateBgPos: ->
+    conf = @configWnd.get('editor-background')
+    body = @elements.body
+    factor = conf.box3d.mouseFactor
+    polowaX = body.clientWidth // 2
+    polowaY = body.clientHeight // 2
+    offsetX =  @mouseX - polowaX
+    offsetY =  @mouseY - polowaY
+    x = (offsetX // factor)
+    y = (offsetY // factor)
+    inline @elements.bg,"background-position:#{x}px #{y}px !important;"
+
+  updateBox: (depth) ->
+    conf=@configWnd.get('editor-background')
+    if not depth? then depth = conf.box3d.depth
+    depth2 = depth // 2
+    background=@elements.blurredImage
+    opacity=(conf.box3d.shadowOpacity / 100).toFixed(2)
+    imgOpacity = conf.image.opacity / 100
+    range=300
+    range2=range // 3
+    bgSize=conf.image.backgroundSize
+    if bgSize=='manual' then bgSize=conf.image.manualBackgroundSize
+    if bgSize=='original' then bgSize='auto'
+    body = @elements.body
+    factor = conf.box3d.mouseFactor
+    polowaX = body.clientWidth // 2
+    polowaY = body.clientHeight // 2
+    offsetX =  @mouseX - polowaX
+    offsetY =  @mouseY - polowaY
+    x = polowaX + (offsetX // factor)
+    y = polowaY + (offsetY // factor)
+    inline @elements.bg,"opacity:0;"
+    position = conf.image.backgroundPosition
+    repeat = conf.image.repeat
+    boxCss="
+    .eb-box-wrapper{
+      perspective:1000px;
+      perspective-origin:#{x}px #{y}px;
+      backface-visibility: hidden;
+      position:fixed;
+      top:0;
+      left:0;
+      width:100%;
+      height:100%;
+      opacity:#{imgOpacity};
+    }
+    .eb-left,.eb-top,.eb-right,.eb-bottom,.eb-back{
+      position:fixed;
+      transform-origin:50% 50%;
+      box-shadow:inset 0px 0px #{range}px rgba(0,0,0,#{opacity}),
+                  inset 0px 0px #{range2}px rgba(0,0,0,#{opacity});
+      background-image:url('#{background}');
+      background-size:#{bgSize};
+      backface-visibility: hidden;
+      background-position:#{position};
+      background-repeat:#{repeat};
+    }
+    .eb-left,.eb-right{
+      width:#{depth}px;
+      height:100%;
+    }
+    .eb-top,.eb-bottom{
+      width:100%;
+      height:#{depth}px;
+    }
+    .eb-left{
+      transform: translate3d(-50%,0,0) rotateY(-90deg);
+      left:0;
+    }
+    .eb-top{
+      transform: translate3d(0,-50%,0) rotateX(90deg);
+      top:0;
+    }
+    .eb-right{
+      transform: translate3d(50%,0,0) rotateY(-90deg);
+      right:0;
+    }
+    .eb-bottom{
+      transform: translate3d(0,50%,0) rotateX(90deg);
+      bottom:0;
+    }
+    .eb-back{
+      transform: translate3d(0,0,-#{depth2}px);
+      width:100%;
+      height:100%;
+    }
+    "
+    @elements.boxStyle.innerText = boxCss
+    if depth==0
+      @elements.boxStyle.innerText=".eb-box-wrapper{display:none;}"
+
+  pluginPath:->
+    _path = atom.packages.resolvePackagePath('editor-background')
+    if !_path
+      _path = path.resolve(__dirname)
+    return _path
+
+  blurImage:->
+    if @packagesLoaded
+      conf = @configWnd.get('editor-background')
+      @elements.image.setAttribute 'src',conf.image.url
+      applyBlur = false
+      if conf.image.blurRadius > 0
+        if @elements.image?
+          if @elements.image.complete
+            applyBlur = true
+          else
+            setTimeout (=> @blurImage.apply @),1000
+      if applyBlur and conf.image.url
+        imageData = blur.stackBlurImage @elements.image, conf.image.blurRadius, false
+        base64Data = imageData.replace(/^data:image\/png;base64,/, "")
+        filename = @pluginPath()+"/blur.png"
+        filename = filename.replace /\\/gi,'/'
+
+        fs.writeFileSync filename, base64Data,{mode:0o777,encoding:'base64'}
+        imageData=filename+"?timestamp="+Date.now()
+      else
+        imageData = conf.image.url
+      @elements.blurredImage = imageData
+      if conf.box3d.depth > 0
+        @updateBox()
+      else
+        opacity = conf.image.opacity / 100
+        position = conf.image.backgroundPosition
+        repeat = conf.image.repeat
+        inline @elements.bg,"background-image: url('#{imageData}') !important;"
+        inline @elements.bg,"opacity:#{opacity};"
+        inline @elements.bg,"background-position:#{position};"
+        inline @elements.bg,"background-repeat:#{repeat};"
+
+  applyBackground: ->
+    if @packagesLoaded
+      workspaceView = @elements.workspace
+      #console.log 'workspaceView',workspaceView
+      if workspaceView?
+        if workspaceView.className.indexOf('editor-background') == -1
+            workspaceView.className += ' editor-background'
+      conf = @configWnd.get 'editor-background'
+      opacity = 100 - conf.image.opacity
+      alpha=(opacity / 100).toFixed(2)
+
+      rgb = colorToArray @colors.workspaceBgColor
+      newColor = 'rgba( '+rgb[0]+' , '+rgb[1]+' , '+rgb[2]+' , '+alpha+')'
+
+      treeOpacity = conf.other.treeViewOpacity
+      treeAlpha = (treeOpacity / 100).toFixed(2)
+      treeRGB = colorToArray @colors.treeOriginalRGB
+
+      newTreeRGBA =
+        'rgba('+treeRGB[0]+','+treeRGB[1]+','+treeRGB[2]+','+treeAlpha+')'
+
+      if conf.image.customOverlayColor
+        _newColor = conf.image.overlayColor.toRGBAString()
+        rgb = colorToArray _newColor
+        newColor = 'rgba('+rgb[0]+','+rgb[1]+','+rgb[2]+','+alpha+')'
+        newTreeRGBA='rgba('+rgb[0]+','+rgb[1]+','+rgb[2]+','+treeAlpha+')'
+      else
+        _newColor = @colors.workspaceBgColor
+      @elements.css.innerText+="body{background:#{_newColor} !important;}"
+
+      #@elements.css.innerText+="\natom-pane-container atom-pane .item-views{background:transparent !important;}"
+
+      if conf.text.shadow
+        @elements.css.innerText+="\natom-text-editor::shadow .line{text-shadow:"+
+        conf.text.shadow+" !important;}"
+
+      if conf.box3d.depth>0
+        @updateBox conf.box3d.depth
+      else
+        @elements.boxStyle.innerText=".eb-box-wrapper{display:none;}"
+
+      #console.log 'conf.image.size',conf.image.backgroundSize
+      if conf.image.backgroundSize!='original'
+        inline @elements.bg, 'background-size:'+conf.image.backgroundSize+
+        ' !important;'
+      else
+        inline @elements.bg, 'background-size:auto !important'
+      if conf.image.backgroundSize == 'manual'
+        inline @elements.bg, 'background-size:'+conf.image.manualBackgroundSize+
+        ' !important;'
+
+      if conf.image.style
+        @elements.plane.style.cssText+=conf.image.style
+
+      @blurImage()
+
+      if conf.other.transparentTabBar
+        inline @elements.tabBar,'background:rgba(0,0,0,0) !important;'
+        inline @elements.insetPanel,'background:rgba(0,0,0,0) !important;'
+
+      if conf.other.treeViewOpacity > 0
+        inline @elements.treeView,'background:'+newTreeRGBA+' !important;'
+        inline @elements.left,'background:transparent !important;'
+        inline @elements.resizer,'background:transparent !important;'
+        inline @elements.leftPanel,'background:transparent !important;'
+
+
+
+
+
+
+  # show config window
+  toggle:->
+    if not @configWnd
+      atom.notifications.add 'warning','Editor-background is only available after you open some files.'
+    else
+      if not @configWnd.visible
+        @configWnd.show()
+      else
+        @popup.hide()


rootElement removed

rootElement removed

--- lib/editor-background.coffee
+++ lib/editor-background.coffee
@@ -663,7 +663,8 @@
           color = conf.text.color.toHexString()
           expand = conf.text.expand

-          root = editor.rootElement
+
+          root = atom.views.getView(editor)
           scrollView = root.querySelector '.scroll-view'

           activeEditor = atom.workspace.getActiveTextEditor()


Replaces H. to @ on Url helpers

Replaces H. to @ on Url helpers

--- app/assets/javascripts/javascript_renderer/helpers/url.jsh.coffee
+++ app/assets/javascripts/javascript_renderer/helpers/url.jsh.coffee
@@ -1,6 +1,6 @@
 helper 'urlFor', (source, options = {}) ->
   if @forceDomain
-    options['domain'] ||= H.domain.app
+    options['domain'] ||= @domain.app
   if options['domain']
     source = options['domain'] + source
   if options['format']


remove print

remove print

--- test/studio/ScrollComponentContentInset.framer/app.coffee
+++ test/studio/ScrollComponentContentInset.framer/app.coffee
@@ -3,8 +3,6 @@
 	width: Screen.width
 	height: 400
 	image: "https://ununsplash.imgix.net/photo-1423753623104-718aaace6772"
-
-print background.siblingLayers

 scroll = new ScrollComponent
 scroll.size = Screen.size


Handle all variations of pane splitting commands

--- lib/fuzzy-finder-view.coffee
+++ lib/fuzzy-finder-view.coffee
@@ -18,15 +18,24 @@
     @setMaxItems(10)
     @subscriptions = new CompositeDisposable

+    splitLeft = => @splitOpenPath (pane) -> pane.splitLeft.bind(pane)
+    splitRight = => @splitOpenPath (pane) -> pane.splitRight.bind(pane)
+    splitUp = => @splitOpenPath (pane) -> pane.splitUp.bind(pane)
+    splitDown = => @splitOpenPath (pane) -> pane.splitDown.bind(pane)
+
     atom.commands.add @element,
-      'pane:split-left': =>
-        @splitOpenPath (pane) -> pane.splitLeft.bind(pane)
-      'pane:split-right': =>
-        @splitOpenPath (pane) -> pane.splitRight.bind(pane)
-      'pane:split-down': =>
-        @splitOpenPath (pane) -> pane.splitDown.bind(pane)
-      'pane:split-up': =>
-        @splitOpenPath (pane) -> pane.splitUp.bind(pane)
+      'pane:split-left': splitLeft
+      'pane:split-left-and-copy-active-item': splitLeft
+      'pane:split-left-and-move-active-item': splitLeft
+      'pane:split-right': splitRight
+      'pane:split-right-and-copy-active-item': splitRight
+      'pane:split-right-and-move-active-item': splitRight
+      'pane:split-up': splitUp
+      'pane:split-up-and-copy-active-item': splitUp
+      'pane:split-up-and-move-active-item': splitUp
+      'pane:split-down': splitDown
+      'pane:split-down-and-copy-active-item': splitDown
+      'pane:split-down-and-move-active-item': splitDown
       'fuzzy-finder:invert-confirm': =>
         @confirmInvertedSelection()


add enable/disable/reset

add enable/disable/reset

--- src/editor.coffee
+++ src/editor.coffee
@@ -17,8 +17,14 @@
   options:
     POLL_INTERVAL: 500

-  constructor: (@container) ->
+  constructor: (@container, enabled = true) ->
     @container = document.getElementById(@container) if _.isString(@container)
+    this.reset()
+    this.enable() if enabled
+
+  reset: ->
+    @ignoreDomChanges = true
+    @container.innerHTML = ""
     @iframe = this.createIframe(@container)
     @doc = new Tandem.Document(this, @iframe.contentWindow.document.body)
     @ignoreDomChanges = false
@@ -99,9 +105,14 @@
     else
       style.appendChild(doc.createTextNode(css))
     head.appendChild(style)
-    doc.body.setAttribute('contenteditable', true)
     doc.body.innerHTML = html
     return iframe
+
+  disable: ->
+    @doc.root.setAttribute('contenteditable', false)
+
+  enable: ->
+    @doc.root.setAttribute('contenteditable', true)

   initContentListeners: ->
     onEdit = _.debounce( =>


fix applyDelta

fix applyDelta

--- src/editor.coffee
+++ src/editor.coffee
@@ -207,8 +207,6 @@
     index = 0       # Stores where the last retain end was, so if we see another one, we know to delete
     offset = 0      # Tracks how many characters inserted to correctly offset new text
     oldDelta = @doc.toDelta()
-    currentDeltas = JetDelta.copy(oldDelta).deltas
-    curDeltaOffset = 0
     _.each(delta.deltas, (delta) =>
       if JetDelta.isInsert(delta)
         this.insertAt(index + offset, delta.text, false)
@@ -218,29 +216,17 @@
         offset += delta.getLength()
       else if JetDelta.isRetain(delta)
         if delta.start > index
-          length = delta.start - index
-          this.deleteAt(index + offset, length, false)
+          this.deleteAt(index + offset, delta.start - index, false)
           offset -= (delta.start - index)
-          while length >= currentDeltas[0].text.length - curDeltaOffset
-            length -= (currentDeltas[0].text.length - curDeltaOffset)
-            currentDeltas.splice(0, 1)
-            curDeltaOffset = 0
-        else
-          start = index + offset
-          length = delta.end - delta.start
-          while length > 0
-            attributes = _.extend({}, currentDeltas[0].attributes, delta.attributes)
-            deltaLength = currentDeltas[0].text.length - curDeltaOffset
-            if deltaLength <= length
-              currentDeltas.splice(0, 1)
-              curDeltaOffset = 0
-            else
-              curDeltaOffset += length
-            _.each(attributes, (value, attr) =>
-              this.applyAttribute(start, Math.min(deltaLength, length), attr, value, false)
-            )
-            start += deltaLength
-            length -= deltaLength
+        deltasInRange = oldDelta.getDeltasAt(delta)
+        deltaOffset = 0
+        _.each(deltasInRange, (deltaInRange) =>
+          attributes = _.extend({}, deltaInRange.attributes, delta.attributes)
+          _.each(attributes, (value, attr) =>
+            this.applyAttribute(delta.start + offset + deltaOffset, deltaInRange.text.length, attr, value, false)
+          )
+          deltaOffset += deltaInRange.text.length
+        )
         index = delta.end
       else
         console.warn('Unrecognized type in delta', delta)
@@ -251,7 +237,7 @@
     newDelta = @doc.toDelta()
     composed = JetSync.compose(oldDelta, delta)
     composed.compact()
-    console.assert(_.isEqual(composed, newDelta), oldDelta, delta, newDelta, composed)
+    console.assert(_.isEqual(composed, newDelta), oldDelta, delta, composed, newDelta)

   applyLineAttribute: (line, attr, value) ->
     indent = if _.isNumber(value) then value else (if value then 1 else 0)


removed ability to change slug. create/remove membership policy and invitations tabs when group privacy changed.

--- client/landing/app/Applications/Groups.kdapplication/Views/generalsettingsview.coffee
+++ client/landing/app/Applications/Groups.kdapplication/Views/generalsettingsview.coffee
@@ -14,12 +14,22 @@
     isPrivateGroup = 'private' is group.privacy

     _updateGroupHandler =(group, formData)=>
-      group.modify formData, (err)->
+      group.modify formData, (err)=>
+        @settingsForm.buttons.Save.hideLoader()
         if err
           new KDNotificationView
             title: err.message
             duration: 1000
         else
+          if formData.privacy isnt group.privacy
+            group.privacy = formData.privacy
+            if formData.privacy is 'private'
+              KD.getSingleton('appManager').tell 'Groups', 'prepareMembershipPolicyTab'
+              KD.getSingleton('appManager').tell 'Groups', 'prepareInvitationsTab'
+            else
+              @parent.parent.removePaneByName 'Membership policy'
+              @parent.parent.removePaneByName 'Invitations'
+
           new KDNotificationView
             title: 'Group was updated!'
             duration: 1000
@@ -33,7 +43,7 @@
           _updateGroupHandler group, formData
       buttons:
         Save                :
-          style             : "modal-clean-gray"
+          style             : "modal-clean-green"
           type              : "submit"
           loader            :
             color           : "#444444"
@@ -49,20 +59,8 @@
           label             : "Group Name"
           itemClass         : KDInputView
           name              : "title"
-          keydown           : (pubInst, event)=>
-            value = @settingsForm.inputs.Title.getValue()
-            setTimeout =>
-              slug = @utils.slugify @settingsForm.inputs.Title.getValue()
-              @settingsForm.inputs.Slug.setValue slug
-            , 1
           defaultValue      : Encoder.htmlDecode group.title ? ""
           placeholder       : 'Please enter a title here'
-        Slug :
-          itemClass         : KDInputView
-          label             : 'Path'
-          name              : "slug"
-          defaultValue      : group.slug ? ""
-          placeholder       : 'This value will be automatically generated'
         Description         :
           label             : "Description"
           type              : "textarea"


Gameplay, restart codes, default settings values


+ add the property writable check. * [bug] getProperties function should return the property descriptor dict


Configuration docs

Configuration docs

--- lib/layervault/configuration.coffee
+++ lib/layervault/configuration.coffee
@@ -1,4 +1,9 @@
+# Stores the configuration info for the {Client}
 module.exports = class Configuration
+  # Constructs a new Configuration object
+  #
+  # @param [Function] cb
+  #   Allows you to configure the settings immediately without calling setup.
   constructor: (cb = null) ->
     @oauthKey = null
     @oauthSecret = null
@@ -9,4 +14,8 @@

     @setup(cb) if cb?

+  # Executes a callback in the context of this Configuration object.
+  # Mostly a stylistic way to set the configuration options.
+  #
+  # @param [Function] cb Executes the callback under the context of this object
   setup: (cb) -> cb.call(@)


rm underscore string

rm underscore string

--- lib/middleware/locals.coffee
+++ lib/middleware/locals.coffee
@@ -5,7 +5,6 @@
 # uuid = require 'node-uuid'
 { parse, format } = require 'url'
 _ = require 'underscore'
-_.mixin require 'underscore.string'
 { NODE_ENV } = require '../../config'

 module.exports = (req, res, next) ->


:bug: Fix legacy code remaining in deactivate

--- lib/minimap-git-diff-binding.coffee
+++ lib/minimap-git-diff-binding.coffee
@@ -27,11 +27,11 @@
     @updateDiffs()

   deactivate: ->
-    @removeDiffs()
+    @removeDecorations()
     @unsubscribe()
+    @diffs = null

-  scheduleUpdate: ->
-    setImmediate(@updateDiffs)
+  scheduleUpdate: -> setImmediate(@updateDiffs)

   updateDiffs: =>
     @removeDecorations()


Embed: pass the embedded object's parent type to container

--- client/activity/lib/views/embedbox.coffee
+++ client/activity/lib/views/embedbox.coffee
@@ -24,8 +24,9 @@
       else               EmbedBoxLinkDisplayView

     embedOptions =
-      cssClass: 'link-embed clearfix'
-      delegate: this
+      cssClass   : 'link-embed clearfix'
+      delegate   : this
+      type       : @getOptions().type

     @addSubView new containerClass embedOptions, data


Cleanup blocks tests

Cleanup blocks tests

--- test/blocks.coffee
+++ test/blocks.coffee
@@ -11,19 +11,17 @@
             'values': ["foo", "bar", "baz"]

   test_for_with_variable: renderTest (render, assert) ->
-    render(' 1  2  3 ','{%for item in array%} {{item}} {%endfor%}','array': [1,2,3])
-    render('123','{%for item in array%}{{item}}{%endfor%}','array': [1,2,3])
-    render('123','{% for item in array %}{{item}}{% endfor %}','array': [1,2,3])
-    render('abcd','{%for item in array%}{{item}}{%endfor%}','array': ['a','b','c','d'])
-    render('a b c','{%for item in array%}{{item}}{%endfor%}','array': ['a',' ','b',' ','c'])
-    render('abc','{%for item in array%}{{item}}{%endfor%}','array': ['a','','b','','c'])
+    render(' 1  2  3 ', '{%for item in array%} {{item}} {%endfor%}', array: [1, 2, 3])
+    render('123', '{%for item in array%}{{item}}{%endfor%}', array: [1, 2, 3])
+    render('123', '{% for item in array %}{{item}}{% endfor %}', array: [1, 2, 3])
+    render('abcd', '{%for item in array%}{{item}}{%endfor%}', array: ['a', 'b', 'c', 'd'])
+    render('a b c', '{%for item in array%}{{item}}{%endfor%}', array: ['a', ' ', 'b', ' ', 'c'])
+    render('abc', '{%for item in array%}{{item}}{%endfor%}', array: ['a', '', 'b', '', 'c'])

   test_ifchanged: renderTest (render, assert) ->
-    assigns = {'array': [ 1, 1, 2, 2, 3, 3] }
-    render('123','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
-
-    assigns = {'array': [ 1, 1, 1, 1] }
-    render('1','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
-
+    render('123', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', array: [ 1, 1, 2, 2, 3, 3 ])
+    render('1', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', array: [ 1, 1, 1, 1 ])
+
   test_reverse: renderTest (render, assert) ->
     render('321', '{% for item in array reversed %}{{ item }}{% endfor %}', array: [ 1, 2, 3 ])
+


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -16,7 +16,7 @@
   enemy.include(Follow)
   enemy.follow(player)

-  ok enemy.I.velocity.equal(Point(1, 0)), 'enemy should head toward player with velocity '
+  ok enemy.I.velocity.equal(Point(1, 0)), 'enemy should head toward player with velocity Point'

   fastEnemy = GameObject
     x: 50


Add an "Expires" header to Ajax caching test

Unfortunately it doesn't fix the Android 2.3 intermittent failure.
Sometimes it will reuse cached response, sometimes it will refetch.

--- test/server.coffee
+++ test/server.coffee
@@ -83,6 +83,7 @@

 app.get '/test/cached', (req, res) ->
   res.set 'Cache-Control', 'max-age=2'
+  res.set 'Expires', new Date(Date.now() + 2000).toUTCString()
   now = new Date()
   res.send now.getTime().toString()


Clarifly level 6

Clarifly level 6

--- games/tutorial.coffee
+++ games/tutorial.coffee
@@ -102,7 +102,6 @@
         { kind: 'turtle', actions: {} }
       ]
     }
-    # TODO Explain Left-Right
     {
       name: 'Click "Right" Program Brick to Remove It'
       comment: '
@@ -117,8 +116,9 @@
       ]
     }
     # TODO: add a level explaining how/why to rearrange bricks
+    # TODO Explain Left-Right
     {
-      name: 'Use Only Four Bricks to Move Diagonally'
+      name: 'Alternate Left and Right to Move Diagonally'
       comment: '
       Create a multi-stage program.
       Can get top score by using run loop to avoid final "Forward"s


Potential fix for ach hans run

Potential fix for ach hans run

--- scripts/card-fetcher.coffee
+++ scripts/card-fetcher.coffee
@@ -13,8 +13,17 @@

 cardDatabaseUrl = "http://mtgjson.com/json/AllCards.json"
 urlBase = "http://gatherer.wizards.com/Handlers/Image.ashx?type=card&name="
+replacements = [
+  {from : '“', to : '"'},
+  {from : '”', to : '"'}
+]
+
+doReplacement = (string, pair) ->
+  return string.replace /#{pair.from}/, /#{pair.to}/, 'g'

 verifyCard = (cardName, cardDB) ->
+  for pair in replacements
+    cardName = doReplacement cardName, pair
   if cardName.search(" // ") isnt -1
     splitCards = cardName.split " // "
     return encodeURIComponent(cardName) if splitCards[0] of cardDB and splitCards[1] of cardDB
@@ -23,7 +32,7 @@
     console.log "Not encoded: " + cardName
     matches = Object.keys(cardDB).filter (key) ->
       /Ach! Hans, Run!/.test key
-    console.log matches
+    #console.log matches
     return encodeURIComponent(cardName) if cardName of cardDB
   "Dismal%20Failure"


implement getCurrentAction

implement getCurrentAction

--- gameState.coffee
+++ gameState.coffee
@@ -93,6 +93,8 @@

   # `getCurrentAction()` returns the action being resolved that is on the
   # top of the stack.
+  getCurrentAction: () ->
+    @actionStack[@actionStack.length - 1]

   # `countInDeck(card)` counts the number of copies of a card in the deck.
   # The card may be specified either by name or as a card object.


add gainValue to prevent buying curses -- fixes #32

--- gameState.coffee
+++ gameState.coffee
@@ -924,8 +924,6 @@
     # Make sure we didn't drop cards on the floor.
     if this.countTotalCards() != @totalCards
       throw new Error("The game started with #{@totalCards} cards; now there are #{this.countTotalCards()}")
-
-    this.log("Empty piles: #{this.emptyPiles()}")

   # The player list is implemented so that the current player is always first
   # in the list; the list rotates after every turn.


Use dataset instead of set/getAttribute

Use dataset instead of set/getAttribute

--- resources/assets/coffee/_classes/tooltip-default.coffee
+++ resources/assets/coffee/_classes/tooltip-default.coffee
@@ -45,7 +45,7 @@

     el._tooltip = true

-    at = el.getAttribute('data-tooltip-position') ? 'top center'
+    at = el.dataset.tooltipPosition ? 'top center'

     my = switch at
       when 'top center' then 'bottom center'
@@ -76,7 +76,7 @@
           width: 10
           height: 8

-    el.setAttribute 'data-orig-title', title
+    el.dataset.origTitle = title

     $(el).qtip options, event

@@ -100,7 +100,7 @@
     $('.qtip').remove()

     for el in document.querySelectorAll('[data-orig-title]')
-      el.setAttribute 'title', el.getAttribute('data-orig-title')
+      el.setAttribute 'title', el.dataset.origTitle

   timeagoTip: (el, title) =>


Remove accidental addition of underscore dependency

--- scripts/controllers/routing.coffee
+++ scripts/controllers/routing.coffee
@@ -5,11 +5,10 @@
 # There is a cyclic dependency between this and various views (`->` means "depends on"):
 # controller -> layout -> WorkspaceView -> WorkspaceItemView -> controller (because clicking an item will begin editing)
 define [
-  'underscore'
   'marionette'
   'cs!collections/content'
   'cs!views/layouts/workspace'
-  ], (_, Marionette, allContent, WorkspaceLayout) ->
+  ], (Marionette, allContent, WorkspaceLayout) ->

   # Only reason to extend Backbone.Router is to get the @navigate method
   return new class AppController extends Marionette.AppRouter


constructor check

constructor check

--- turingtype.coffee
+++ turingtype.coffee
@@ -8,6 +8,7 @@
   keys: 'qwertyuiop[]asdfghjklzxcvbnm,./;-='.split ''

   constructor: (@el, @text, @options = {}) ->
+    return new TuringType arguments... unless @ instanceof TuringType
     @len = @text.length
     @i = 0
     {accuracy, interval, @callback} = @options


Explain for different ways for get dependencies.

--- example/src/app.cjsx
+++ example/src/app.cjsx
@@ -1,7 +1,11 @@
 "use strict"

+# React-Toolbox full dependency way:
 # Toolbox = require 'react-toolbox'
 # Button  = Toolbox.Button
+# Form    = Toolbox.Form
+
+# Standalone dependencies way:
 Button  = require 'react-toolbox/components/button'
 Form    = require 'react-toolbox/components/form'


fix(lxd): lxc.file.push test fix (#403)

fix(lxd): lxc.file.push test fix (#403)

Co-authored-by: Kellian Cottart <972705254527c7df6021301a5d3a5394a27ef074@adaltas.com>

--- packages/lxd/test/file/push.coffee
+++ packages/lxd/test/file/push.coffee
@@ -35,7 +35,7 @@
         $tmpdir: true
       , ({metadata: {tmpdir}, registry}) ->
         registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-1', force: true
+          await @lxc.delete 'nikita-file-push-1', force: true
         await @clean()
         await @lxc.init
           image: "images:#{images.alpine}"
@@ -43,7 +43,7 @@
           start: true
         await @file.touch
           target: "#{tmpdir}/a_file"
-        @lxc.file.push
+        await @lxc.file.push
           container: 'nikita-file-push-1'
           source: "#{tmpdir}/a_file"
           target: '/root/a_file'
@@ -56,51 +56,79 @@
         $ssh: ssh
         $tmpdir: true
       , ({metadata: {tmpdir}, registry}) ->
-        registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-2', force: true
-        await @clean()
-        await @lxc.init
-          image: "images:#{images.alpine}"
-          container: 'nikita-file-push-2'
-          start: true
-        await @lxc.exec
-          $$: retry: 3, sleep: 200 # Wait for network to be ready
-          container: 'nikita-file-push-2'
+        await registry.register 'clean', ->
+          await @lxc.delete
+            container: 'nikita-file-push-2'
+            force: true
+          await @lxc.network.delete
+            network: 'nktlxdpub'
+        await registry.register 'test', ->
+          # creating network
+          await @lxc.network
+            network: 'nktlxdpub'
+            properties:
+              'ipv4.address': '10.10.40.1/24'
+              'ipv4.nat': true
+              'ipv6.address': 'none'
+          # creating a container
+          await @lxc.init
+            image: "images:#{images.alpine}"
+            container: 'nikita-file-push-2'
+            nic:
+              eth0:
+                name: 'eth0', nictype: 'bridged', parent: 'nktlxdpub'
+            ssh: enabled: true
+            start: true
+          # attaching network
+          await @lxc.network.attach
+            container: 'nikita-file-push-2'
+            network: 'nktlxdpub'
+          # adding openssl for file push
+          await @lxc.exec
+            $retry: 100
+            $wait: 200 # Wait for network to be ready
+            container: 'nikita-file-push-2'
+            command: 'apk add openssl'
+          await @file
+            target: "#{tmpdir}/a_file"
+            content: 'something'
+          {$status} = await @lxc.file.push
+            container: 'nikita-file-push-2'
+            source: "#{tmpdir}/a_file"
+            target: '/root/a_file'
+          $status.should.be.true()
+          {$status} = await @lxc.file.exists
+            container: 'nikita-file-push-2'
+            target: '/root/a_file'
+          $status.should.be.true()
+        try
+          await @clean()
+          await @test()
+        catch err
+          await @clean()
+        finally
+          await @clean()
+
+    they 'the same file', ({ssh}) ->
+      nikita
+        $ssh: ssh
+        $tmpdir: true
+      , ({metadata: {tmpdir}, registry}) ->
+        registry.register 'clean', ->
+          await @lxc.delete 'nikita-file-push-3', force: true
+        await @clean()
+        await @lxc.init
+          image: "images:#{images.alpine}"
+          container: 'nikita-file-push-3'
+          start: true
+        await @lxc.exec
+          $$: retry: 3, sleep: 200 # Wait for network to be ready
+          container: 'nikita-file-push-3'
           command: 'apk add openssl'
         await @file
           target: "#{tmpdir}/a_file"
           content: 'something'
-        {$status} = await @lxc.file.push
-          container: 'nikita-file-push-2'
-          source: "#{tmpdir}/a_file"
-          target: '/root/a_file'
-        $status.should.be.true()
-        {$status} = await @lxc.file.exists
-          container: 'nikita-file-push-2'
-          target: '/root/a_file'
-        $status.should.be.true()
-        await @clean()
-
-    they 'the same file', ({ssh}) ->
-      nikita
-        $ssh: ssh
-        $tmpdir: true
-      , ({metadata: {tmpdir}, registry}) ->
-        registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-3', force: true
-        await @clean()
-        @lxc.init
-          image: "images:#{images.alpine}"
-          container: 'nikita-file-push-3'
-          start: true
-        await @lxc.exec
-          $$: retry: 3, sleep: 200 # Wait for network to be ready
-          container: 'nikita-file-push-3'
-          command: 'apk add openssl'
-        @file
-          target: "#{tmpdir}/a_file"
-          content: 'something'
-        @lxc.file.push
+        await @lxc.file.push
           container: 'nikita-file-push-3'
           source: "#{tmpdir}/a_file"
           target: '/root/a_file'
@@ -119,9 +147,9 @@
         $ssh: ssh
       , ({registry}) ->
         registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-4', force: true
-        await @clean()
-        @lxc.init
+          await @lxc.delete 'nikita-file-push-4', force: true
+        await @clean()
+        await @lxc.init
           image: "images:#{images.alpine}"
           container: 'nikita-file-push-4'
           start: true
@@ -145,17 +173,17 @@
         $ssh: ssh
       , ({registry}) ->
         registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-5', force: true
-        await @clean()
-        @lxc.init
-          image: "images:#{images.alpine}"
-          container: 'nikita-file-push-5'
-          start: true
-        await @lxc.exec
-          $$: retry: 3, sleep: 200 # Wait for network to be ready
-          container: 'nikita-file-push-5'
-          command: 'apk add openssl'
-        @lxc.file.push
+          await @lxc.delete 'nikita-file-push-5', force: true
+        await @clean()
+        await @lxc.init
+          image: "images:#{images.alpine}"
+          container: 'nikita-file-push-5'
+          start: true
+        await @lxc.exec
+          $$: retry: 3, sleep: 200 # Wait for network to be ready
+          container: 'nikita-file-push-5'
+          command: 'apk add openssl'
+        await @lxc.file.push
           container: 'nikita-file-push-5'
           target: '/root/a_file'
           content: 'something'
@@ -174,17 +202,17 @@
         $ssh: ssh
       , ({registry}) ->
         registry.register 'clean', ->
-          @lxc.delete 'nikita-file-push-6', force: true
-        await @clean()
-        @lxc.init
-          image: "images:#{images.alpine}"
-          container: 'nikita-file-push-6'
-          start: true
-        @lxc.exec
-          $$: retry: 3, sleep: 200 # Wait for network to be ready
-          container: 'nikita-file-push-6'
-          command: 'apk add openssl'
-        @lxc.file.push
+          await @lxc.delete 'nikita-file-push-6', force: true
+        await @clean()
+        await @lxc.init
+          image: "images:#{images.alpine}"
+          container: 'nikita-file-push-6'
+          start: true
+        await @lxc.exec
+          $$: retry: 3, sleep: 200 # Wait for network to be ready
+          container: 'nikita-file-push-6'
+          command: 'apk add openssl'
+        await @lxc.file.push
           container: 'nikita-file-push-6'
           target: '/root/a_file'
           content: 'something'


Translate

Translate

Next function now uses translate instead of left if possible.


Client: Activity: Added ADD_PARTICIPANTS_TO_CHANNEL_SUCCESS event listener to channelparticipantidstore

--- client/activity/lib/flux/stores/channelparticipantidsstore.coffee
+++ client/activity/lib/flux/stores/channelparticipantidsstore.coffee
@@ -16,7 +16,7 @@

     @on actions.LOAD_CHANNEL_PARTICIPANTS_BEGIN, @handleLoadBegin
     @on actions.LOAD_CHANNEL_PARTICIPANT_SUCCESS, @handleLoadSuccess
-
+    @on actions.ADD_PARTICIPANTS_TO_CHANNEL_SUCCESS, @handleLoadSuccess

   ###*
    * Initializes a new channel participants container for loaded channel.