Preliminary port of LLVM's Kaleidoscope example. Expressions, function calls and definitions work.

error: pathspec 'examples/kaleidoscope.coffee' did not match any file(s) known to git

--- examples/kaleidoscope.coffee
+++ examples/kaleidoscope.coffee
@@ -0,0 +1,993 @@
+llvm = require '../index'
+readline = require 'readline'
+
+#===----------------------------------------------------------------------===#
+# Lexer
+#===----------------------------------------------------------------------===#
+# The lexer returns strings if it is an unknown character, otherwise one
+# of these for known things.
+
+class Token
+  constructor: (@name) ->
+
+tok_eof = new Token('eof')
+EOF = '\0'
+
+# commands
+tok_def = new Token('def')
+tok_extern = new Token('extern')
+
+# primary
+tok_identifier = new Token('identifier')
+tok_number = new Token('number')
+
+# control
+tok_if = new Token('if')
+tok_then = new Token('then')
+tok_else = new Token('else')
+tok_for = new Token('for')
+tok_in = new Token('in')
+
+# operators
+tok_binary = new Token('binary')
+tok_unary = new Token('unary')
+
+# var definition
+tok_var = new Token('var')
+
+isalnum = (c) -> /\w/.test(c)
+isalpha = (c) -> /[a-zA-Z]/.test(c)
+isdigit = (c) -> /[0-9.]/.test(c)
+isspace = (c) -> /\s/.test(c)
+
+isascii = (c) -> c not instanceof Token
+
+class Lexer
+  constructor: ->
+    @buffer = []
+
+  # add a line to the buffer
+  feed: (line) ->
+    for i in line then @buffer.push(i)
+
+  getchar: ->
+    if @buffer.length
+      @buffer.shift()
+    else
+      EOF
+
+  testchar: -> @buffer[0]
+
+  # gettok - Return the next token from standard input.
+  gettok: ->
+    lastChar = ' '
+
+    # Skip any whitespace.
+    while isspace(lastChar)
+      lastChar = @getchar()
+
+    if isalpha(lastChar) # identifier: [a-zA-Z][a-zA-Z0-9]*
+      @val = lastChar
+      while isalnum(@testchar())
+        @val += @getchar()
+
+      return switch @val
+        when "def" then tok_def
+        when "extern" then tok_extern
+        when "if" then tok_if
+        when "then" then tok_then
+        when "else" then tok_else
+        when "for" then tok_for
+        when "in" then tok_in
+        when "binary" then tok_binary
+        when "unary" then tok_unary
+        when "var" then tok_var
+        else tok_identifier
+
+    if isdigit(lastChar) or lastChar == '.'   # Number: [0-9.]+
+      numStr = lastChar
+      while isdigit(@testchar())
+        numStr += @getchar()
+
+      @val = parseFloat(numStr, 10)
+      return tok_number
+
+    if lastChar == '#'
+      # Comment until end of line.
+
+      while lastChar != EOF and lastChar != '\n' and lastChar != '\r'
+        lastChar = @getchar()
+
+      if lastChar != EOF
+        return @gettok()
+
+    # Check for end of file.  Don't eat the EOF.
+    if lastChar == EOF
+      return tok_eof
+
+    # Otherwise, just return the character as its ascii value.
+    return lastChar
+
+#===----------------------------------------------------------------------===#
+# Abstract Syntax Tree (aka Parse Tree)
+#===----------------------------------------------------------------------===#
+
+# ExprAST - Base class for all expression nodes.
+class ExprAST
+  toString: ->
+    n = ["<#{this.constructor.name}>"]
+    for own k, v of this
+      n.push "\t#{k}: #{v?.toString().replace(/\n/g, '\n\t')}"
+    n.join('\n')
+
+
+# NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST extends ExprAST
+  constructor: (@val) ->
+
+# VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST extends ExprAST
+  constructor: (@name) ->
+
+# UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST extends ExprAST
+  constructor: (@opcode, @operand) ->
+
+# BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST extends ExprAST
+  constructor: (@op, @lhs, @rhs) ->
+
+# CallExprAST - Expression class for function calls.
+class CallExprAST extends ExprAST
+  constructor: (@callee, @args) ->
+
+# IfExprAST - Expression class for if/then/else.
+class IfExprAST extends ExprAST
+  constructor: (@cond, @then, @else) ->
+
+# ForExprAST - Expression class for for/in.
+class ForExprAST extends ExprAST
+  constructor: (@varName, @start, @end, @step, @body) ->
+
+# VarExprAST - Expression class for var/in
+class VarExprAST extends ExprAST
+  constructor: (@varNames, @body) ->
+
+# PrototypeAST - This class represents the "prototype" for a function,
+# which captures its name, and its argument names (thus implicitly the number
+# of arguments the function takes), as well as if it is an operator.
+class PrototypeAST
+  constructor: (@name, @args, @isOperator=false, @precedence=0) ->
+
+  isUnaryOp:  -> @isOperator and @args.length == 1
+  isBinaryOp: -> @isOperator and @args.length == 2
+  getOperatorName: ->
+    assert(@isUnaryOp() or @isBinaryOp())
+    @name
+
+  createArgumentAllocas: (f) ->
+
+# FunctionAST - This class represents a function definition itself.
+class FunctionAST
+  constructor: (@Proto, @body) ->
+
+#===----------------------------------------------------------------------===#
+# Parser
+#===----------------------------------------------------------------------===#
+
+class Parser
+  constructor: ->
+    @lexer = new Lexer()
+    @curTok = null
+
+    # This holds the precedence for each binary operator that is defined.
+    # char -> int
+    @binopPrecedence = {}
+
+  # @curTok/getNextToken - Provide a simple token buffer.  @curTok is the current
+  # token the parser is looking at.  getNextToken reads another token from the
+  # lexer and updates @curTok with its results.
+  getNextToken: ->
+    @curTok = @lexer.gettok()
+    #console.log 'tok', @curTok
+    #console.trace 'at'
+    @curTok
+
+  # GetTokPrecedence - Get the precedence of the pending binary operator token.
+  GetTokPrecedence: ->
+    if !isascii(@curTok)
+      return -1
+
+    # Make sure it's a declared binop.
+    tokPrec = @binopPrecedence[@curTok] ? -1
+
+  # identifierexpr
+  #   ::= identifier
+  #   ::= identifier '(' expression* ')'
+  ParseIdentifierExpr: ->
+    idName = @lexer.val
+
+    @getNextToken()  # eat identifier.
+
+    if @curTok != '(' # Simple variable ref.
+      return new VariableExprAST(idName)
+
+    # Call.
+    @getNextToken()  # eat (
+    args = []
+    if @curTok != ')'
+      while true
+        arg = @ParseExpression()
+        if not arg then return null
+        args.push(arg)
+
+        if @curTok == ')' then break
+
+        if @curTok != ','
+          throw new Error("Expected ')' or ',' in argument list")
+        @getNextToken()
+
+    # Eat the ')'.
+    @getNextToken()
+
+    return new CallExprAST(idName, args)
+
+  # numberexpr ::= number
+  ParseNumberExpr: ->
+    result = new NumberExprAST(@lexer.val)
+    t1 = @curTok
+    @getNextToken() # consume the number
+    t2 = @curTok
+    return result
+
+  # parenexpr ::= '(' expression ')'
+  ParseParenExpr: ->
+    @getNextToken()  # eat (.
+    v = @ParseExpression()
+    if not v then return null
+
+    if @curTok != ')'
+      throw new Error("expected ')'")
+    @getNextToken()  # eat ).
+    return v
+
+  # ifexpr ::= 'if' expression 'then' expression 'else' expression
+  ParseIfExpr: ->
+    @getNextToken()  # eat the if.
+
+    # condition.
+    Cond = @ParseExpression()
+    if not Cond then return null
+
+    if @curTok != tok_then
+      throw new Error("expected then")
+    @getNextToken()  # eat the then
+
+    Then = @ParseExpression()
+    if not Then then return null
+
+    if @curTok != tok_else
+      throw new Error("expected else")
+    @getNextToken()
+
+    Else = @ParseExpression()
+    if not Else then return null
+
+    return new IfExprAST(Cond, Then, Else)
+
+  # forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
+  ParseForExpr: ->
+    @getNextToken()  # eat the for.
+
+    if @curTok != tok_identifier
+      throw new Error("expected identifier after for")
+
+    IdName = @lexer.val
+    @getNextToken()  # eat identifier.
+
+    if @curTok != '='
+      throw new Error("expected '=' after for")
+    @getNextToken()  # eat '='.
+
+    Start = @ParseExpression()
+    if not Start then return null
+
+    if @curTok != ','
+      throw new Error("expected ',' after for start value")
+    @getNextToken()
+
+    End = @ParseExpression()
+    if not End then return null
+
+    # The step value is optional.
+    Step = null
+    if @curTok == ','
+      @getNextToken()
+      Step = @ParseExpression()
+      if not Step then return 0
+
+    if @curTok != tok_in
+      throw new Error("expected 'in' after for")
+    @getNextToken()  # eat 'in'.
+
+    Body = @ParseExpression()
+    if not Body then return null
+
+    return new ForExprAST(IdName, Start, End, Step, Body)
+
+  # varexpr ::= 'var' identifier ('=' expression)?
+  #                    (',' identifier ('=' expression)?)* 'in' expression
+  ParseVarExpr: ->
+    @getNextToken()  # eat the var.
+
+    VarNames = {}
+
+    # At least one variable name is required.
+    if @curTok != tok_identifier
+      throw new Error("expected identifier after var")
+
+    while true
+      Name = @lexer.val
+      @getNextToken()  # eat identifier.
+
+      # Read the optional initializer.
+      Init = null
+      if @curTok == '='
+        @getNextToken()  # eat the '='.
+
+        Init = @ParseExpression()
+        if not Init then return null
+
+      VarNames[Name] = Init
+
+      # End of var list, exit loop.
+      if @curTok != ',' then break
+      @getNextToken()  # eat the ','.
+
+      if @curTok != tok_identifier
+        throw new Error("expected identifier list after var")
+
+    # At this point, we have to have 'in'.
+    if @curTok != tok_in
+      throw new Error("expected 'in' keyword after 'var'")
+    @getNextToken()  # eat 'in'.
+
+    Body = @ParseExpression()
+    if not Body then return null
+
+    return new @VarExprAST(VarNames, Body)
+
+  # primary
+  #   ::= identifierexpr
+  #   ::= numberexpr
+  #   ::= parenexpr
+  #   ::= ifexpr
+  #   ::= forexpr
+  #   ::= varexpr
+  ParsePrimary: ->
+    switch (@curTok)
+      when tok_identifier then @ParseIdentifierExpr()
+      when tok_number     then @ParseNumberExpr()
+      when '('            then @ParseParenExpr()
+      when tok_if         then @ParseIfExpr()
+      when tok_for        then @ParseForExpr()
+      when tok_var        then @ParseVarExpr()
+      else Error("Unknown token #{@curTok.name} when expecting an expression")
+
+  # unary
+  #   ::= primary
+  #   ::= '!' unary
+  ParseUnary: ->
+    # If the current token is not an operator, it must be a primary expr.
+    if !isascii(@curTok) || @curTok == '(' || @curTok == ','
+      return @ParsePrimary()
+
+    # If this is a unary operator, read it.
+    Opc = @curTok
+    @getNextToken()
+    if Operand = @ParseUnary()
+      return new UnaryExprAST(Opc, Operand)
+    else
+      null
+
+  # binoprhs
+  #   ::= ('+' unary)*
+  ParseBinOpRHS: (ExprPrec, LHS) ->
+    # If this is a binop, find its precedence.
+    while true
+      TokPrec = @GetTokPrecedence()
+
+      # If this is a binop that binds at least as tightly as the current binop,
+      # consume it, otherwise we are done.
+      if TokPrec < ExprPrec
+        return LHS
+
+      # Okay, we know this is a binop.
+      BinOp = @curTok
+      @getNextToken()  # eat binop
+
+      # Parse the unary expression after the binary operator.
+      RHS = @ParseUnary()
+      if not RHS then return null
+
+      # If BinOp binds less tightly with RHS than the operator after RHS, let
+      # the pending operator take RHS as its LHS.
+      NextPrec = @GetTokPrecedence()
+      if TokPrec < NextPrec
+        RHS = @ParseBinOpRHS(TokPrec+1, RHS)
+        if not RHS then return null
+
+      # Merge LHS/RHS.
+      LHS = new BinaryExprAST(BinOp, LHS, RHS)
+
+  # expression
+  #   ::= unary binoprhs
+  #
+  ParseExpression: ->
+    LHS = @ParseUnary()
+    if not LHS then return null
+    return @ParseBinOpRHS(0, LHS)
+
+  # prototype
+  #   ::= id '(' id* ')'
+  #   ::= binary LETTER number? (id, id)
+  #   ::= unary LETTER (id)
+  ParsePrototype: ->
+    FnName = ''
+
+    Kind = 0  # 0 = identifier, 1 = unary, 2 = binary.
+    BinaryPrecedence = 30
+
+    switch @curTok
+      when tok_identifier
+        FnName = @lexer.val
+        Kind = 0
+        @getNextToken()
+      when tok_unary
+        @getNextToken()
+        if !isascii(@curTok)
+          return ErrorP("Expected unary operator")
+        FnName = "unary" + @curTok
+        Kind = 1
+        @getNextToken()
+      when tok_binary
+        @getNextToken()
+        if !isascii(@curTok)
+          return ErrorP("Expected binary operator")
+        FnName = "binary" + @curTok
+        Kind = 2
+        @getNextToken()
+
+        # Read the precedence if present.
+        if @curTok == tok_number
+          if NumVal < 1 || NumVal > 100
+            return ErrorP("Invalid precedence: must be 1..100")
+          BinaryPrecedence = NumVal
+          @getNextToken()
+      else
+        return ErrorP("Expected function name in prototype")
+
+    if @curTok != '('
+      return ErrorP("Expected '(' in prototype")
+
+    ArgNames = []
+    while @getNextToken() == tok_identifier
+      ArgNames.push(@lexer.val)
+    if @curTok != ')'
+      return ErrorP("Expected ')' in prototype")
+
+    # success.
+    @getNextToken()  # eat ')'.
+
+    # Verify right number of names for operator.
+    if Kind && ArgNames.size() != Kind
+      return ErrorP("Invalid number of operands for operator")
+
+    return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence)
+
+  # definition ::= 'def' prototype expression
+  ParseDefinition: ->
+    @getNextToken()  # eat def.
+    Proto = @ParsePrototype()
+    if not Proto then return null
+
+    if (E = @ParseExpression())
+      return new FunctionAST(Proto, E)
+    return null
+
+  # toplevelexpr ::= expression
+  ParseTopLevelExpr: ->
+    if (E = @ParseExpression())
+      # Make an anonymous proto.
+      Proto = new PrototypeAST("", [])
+      return new FunctionAST(Proto, E)
+    return null
+
+  # external ::= 'extern' prototype
+  ParseExtern: ->
+    @getNextToken()  # eat extern.
+    return @ParsePrototype()
+
+#===----------------------------------------------------------------------===#
+# Code Generation
+#===----------------------------------------------------------------------===#
+
+TheModule = null
+Builder = new llvm.IRBuilder(llvm.globalContext)
+NamedValues = {}
+TheFPM = null
+doubleTy = llvm.globalContext.getDoubleTy()
+
+# CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+# the function.  This is used for mutable variables etc.
+CreateEntryBlockAlloca = (TheFunction, VarName) ->
+  TmpB = new llvm.IRBuilder(llvm.globalContext)
+  TmpB.setInsertPoint(TheFunction.basicBlocks[0])
+  TmpB.createAlloca(doubleTy, 0, VarName)
+
+NumberExprAST::Codegen = ->
+  return Context.getDouble(@val)
+
+VariableExprAST::Codegen = ->
+  # Look this variable up in the function.
+  V = NamedValues[@name]
+  if V == 0 then throw new Error("Unknown variable name")
+
+  # Load the value.
+  return Builder.createLoad(V, @name)
+
+UnaryExprAST::Codegen = ->
+  OperandV = @operand.Codegen()
+  if not OperandV then return null
+
+  F = TheModule.getFunction("unary"+@Opcode)
+  if not F
+    throw new Error("Unknown unary operator")
+
+  return Builder.CreateCall(F, OperandV, "unop")
+
+BinaryExprAST::Codegen = ->
+  # Special case '=' because we don't want to emit the LHS as an expression.
+  if @op == '='
+    # Assignment requires the LHS to be an identifier.
+    if @lhs not instanceof VariableExprAST
+      return ErrorV("destination of '=' must be a variable")
+    # Codegen the RHS.
+    Val = @rhs.Codegen()
+    if not Val then return null
+
+    # Look up the name.
+    Variable = NamedValues[@lhs.name]
+    if Variable == 0 then return ErrorV("Unknown variable name")
+
+    Builder.createStore(Val, Variable)
+    return Val
+
+  L = @lhs.Codegen()
+  R = @rhs.Codegen()
+  if not (L and R) then return null
+
+  switch @op
+    when '+' then return Builder.createFAdd(L, R, "addtmp")
+    when '-' then return Builder.createFSub(L, R, "subtmp")
+    when '*' then return Builder.createFMul(L, R, "multmp")
+    when '<'
+      L = Builder.createFCmpULT(L, R, "cmptmp")
+      # Convert bool 0/1 to double 0.0 or 1.0
+      return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp")
+
+  # If it wasn't a builtin binary operator, it must be a user defined one. Emit
+  # a call to it.
+  F = TheModule.getFunction("binary"+@op)
+  assert(F, "binary operator not found!")
+
+  Ops = [ L, R ]
+  return Builder.CreateCall(F, Ops, "binop")
+
+CallExprAST::Codegen = ->
+  # Look up the name in the global module table.
+  CalleeF = TheModule.getFunction(@callee)
+  if not CalleeF
+    throw new Error("Unknown function referenced")
+
+  # If argument mismatch error.
+  if CalleeF.arguments.length != @args.length
+    throw new Error("Incorrect # arguments passed")
+
+  ArgsV = []
+  for i in @args
+    if (l = i.Codegen())
+      ArgsV.push(l)
+    else
+      return null
+
+  return Builder.createCall(CalleeF, ArgsV, "calltmp")
+
+IfExprAST::Codegen = ->
+  CondV = @Cond.Codegen()
+  if not CondV then return null
+
+  # Convert condition to a bool by comparing equal to 0.0.
+  CondV = Builder.CreateFCmpONE(CondV, Context.getDouble(0.0), "ifcond")
+
+  TheFunction = Builder.GetInsertBlock().parent
+
+  # Create blocks for the then and else cases.
+  ThenBB = new llvm.BasicBlock::Create(llvm.globalContext, "then",)
+  ElseBB = new llvm.BasicBlock::Create(llvm.globalContext, "else")
+  MergeBB = new llvm.BasicBlock::Create(llvm.globalContext, "ifcont")
+
+  # Insert the 'then' block at the end of the function.
+  TheFunction.addBasicBlock(ThenBB)
+
+  Builder.CreateCondBr(CondV, ThenBB, ElseBB)
+
+  # Emit then value.
+  Builder.setInsertPoint(ThenBB)
+
+  ThenV = Then.Codegen()
+  if not ThenV then return null
+
+  Builder.CreateBr(MergeBB)
+  # Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+  ThenBB = Builder.GetInsertBlock()
+
+  # Emit else block.
+  TheFunction.getBasicBlockList().push_back(ElseBB)
+  Builder.setInsertPoint(ElseBB)
+
+  ElseV = Else.Codegen()
+  if not ElseV then return null
+
+  Builder.CreateBr(MergeBB)
+  # Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+  ElseBB = Builder.GetInsertBlock()
+
+  # Emit merge block.
+  TheFunction.getBasicBlockList().push_back(MergeBB)
+  Builder.setInsertPoint(MergeBB)
+  PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp")
+  PN.addIncoming(ThenV, ThenBB)
+  PN.addIncoming(ElseV, ElseBB)
+  return PN
+
+ForExprAST::Codegen = ->
+  # Output this as:
+  #   var = alloca double
+  #   ...
+  #   start = startexpr
+  #   store start -> var
+  #   goto loop
+  # loop:
+  #   ...
+  #   bodyexpr
+  #   ...
+  # loopend:
+  #   step = stepexpr
+  #   endcond = endexpr
+  #
+  #   curvar = load var
+  #   nextvar = curvar + step
+  #   store nextvar -> var
+  #   br endcond, loop, endloop
+  # outloop:
+
+  TheFunction = Builder.insertBlock.parent
+
+  # Create an alloca for the variable in the entry block.
+  Alloca = CreateEntryBlockAlloca(TheFunction, VarName)
+
+  # Emit the start code first, without 'variable' in scope.
+  StartVal = Start.Codegen()
+  if not StartVal then return null
+
+  # Store the value into the alloca.
+  Builder.createStore(StartVal, Alloca)
+
+  # Make the new basic block for the loop header, inserting after current
+  # block.
+  LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction)
+
+  # Insert an explicit fall through from the current block to the LoopBB.
+  Builder.CreateBr(LoopBB)
+
+  # Start insertion in LoopBB.
+  Builder.setInsertPoint(LoopBB)
+
+  # Within the loop, the variable is defined equal to the PHI node.  If it
+  # shadows an existing variable, we have to restore it, so save it now.
+  OldVal = NamedValues[VarName]
+  NamedValues[VarName] = Alloca
+
+  # Emit the body of the loop.  This, like any other expr, can change the
+  # current BB.  Note that we ignore the value computed by the body, but don't
+  # allow an error.
+  if not Body.Codegen()
+    return null
+
+  # Emit the step value.
+  if Step
+    StepVal = Step.Codegen()
+    if not StepVal then return null
+  else
+    # If not specified, use 1.0.
+    StepVal = Context.getDouble(1.0)
+
+  # Compute the end condition.
+  EndCond = End.Codegen()
+  if not EndCond then return EndCond
+
+  # Reload, increment, and restore the alloca.  This handles the case where
+  # the body of the loop mutates the variable.
+  CurVar = Builder.createLoad(Alloca, VarName)
+  NextVar = Builder.createFAdd(CurVar, StepVal, "nextvar")
+  Builder.createStore(NextVar, Alloca)
+
+  # Convert condition to a bool by comparing equal to 0.0.
+  EndCond = Builder.CreateFCmpONE(EndCond, Context.getDouble(0.0), "loopcond")
+
+  # Create the "after loop" block and insert it.
+  AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction)
+
+  # Insert the conditional branch into the end of LoopEndBB.
+  Builder.CreateCondBr(EndCond, LoopBB, AfterBB)
+
+  # Any new code will be inserted in AfterBB.
+  Builder.setInsertPoint(AfterBB)
+
+  # Restore the unshadowed variable.
+  if OldVal
+    NamedValues[VarName] = OldVal
+  else
+    NamedValues.erase(VarName)
+
+  # for expr always returns 0.0.
+  return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()))
+
+
+VarExprAST::Codegen = ->
+  OldBindings = []
+
+  TheFunction = Builder.insertBlock.parent
+
+  # Register all variables and emit their initializer.
+  for VarName, Init of @VarNames
+    # Emit the initializer before adding the variable to scope, this prevents
+    # the initializer from referencing the variable itself, and permits stuff
+    # like this:
+    #  var a = 1 in
+    #    var a = a in ...   # refers to outer 'a'.
+    if Init
+      InitVal = Init.Codegen()
+      if not InitVal then return null
+    else # If not specified, use 0.0.
+      InitVal = Context.getDouble(0.0)
+
+    Alloca = CreateEntryBlockAlloca(TheFunction, VarName)
+    Builder.createStore(InitVal, Alloca)
+
+    # Remember the old variable binding so that we can restore the binding when
+    # we unrecurse.
+    OldBindings.push(NamedValues[VarName])
+
+    # Remember this binding.
+    NamedValues[VarName] = Alloca
+
+  # Codegen the body, now that all vars are in scope.
+  BodyVal = Body.Codegen()
+  if not BodyVal then return null
+
+  # Pop all our variables from scope.
+  for vn, i in VarNames
+    NamedValues[vn] = OldBindings[i]
+
+  # Return the body computation.
+  return BodyVal
+
+PrototypeAST::Codegen = ->
+  # Make the function type:  double(double,double) etc.
+  Doubles = (doubleTy for i in @args)
+  FT = Context.getFunctionType(doubleTy, Doubles, false)
+
+  F = TheModule.getOrInsertFunction(@name, FT, llvm.Function.ExternalLinkage)
+
+  # If F conflicted, there was already something named 'Name'.  If it has a
+  # body, don't allow redefinition or reextern.
+  if F.name != @name
+    # Delete the one we just made and get the existing one.
+    F.eraseFromParent()
+    F = TheModule.getFunction(Name)
+
+    # If F already has a body, reject this.
+    if F.empty()
+      Error("redefinition of function")
+      return null
+
+    # If F took a different number of args, reject.
+    if F.arguments.length != Args.length
+      Error("redefinition of function with different # args")
+      return null
+
+  # Set names for all arguments.
+  for AI, i in F.arguments
+    AI.name = @args[i]
+
+  return F
+
+# CreateArgumentAllocas - Create an alloca for each argument and register the
+# argument in the symbol table so that references to it will succeed.
+PrototypeAST::CreateArgumentAllocas = (F) ->
+  for AI, Idx in F.arguments
+    # Create an alloca for this variable.
+    Alloca = CreateEntryBlockAlloca(F, @args[Idx])
+
+    # Store the initial value into the alloca.
+    Builder.createStore(AI, Alloca)
+
+    # Add arguments to variable symbol table.
+    NamedValues[@args[Idx]] = Alloca
+
+FunctionAST::Codegen = ->
+  NamedValues = {}
+
+  TheFunction = @Proto.Codegen()
+  if not TheFunction then return null
+
+  # If this is an operator, install it.
+  if @Proto.isBinaryOp()
+    BinopPrecedence[@Proto.getOperatorName()] = @Proto.getBinaryPrecedence()
+
+  # Create a new basic block to start insertion into.
+  BB = TheFunction.addBasicBlock("entry")
+  Builder.setInsertPoint(BB)
+
+  # Add all arguments to the symbol table and create their allocas.
+  @Proto.CreateArgumentAllocas(TheFunction)
+
+  if (RetVal = @body.Codegen())
+    # Finish off the function.
+    Builder.createRet(RetVal)
+
+    # Validate the generated code, checking for consistency.
+    #verifyFunction(TheFunction)
+
+    # Optimize the function.
+    TheFPM.run(TheFunction)
+
+    return TheFunction
+
+  # Error reading body, remove function.
+  TheFunction.eraseFromParent()
+
+  if Proto.isBinaryOp()
+    BinopPrecedence.erase(Proto.getOperatorName())
+  return null
+
+#===----------------------------------------------------------------------===#
+# Top-Level parsing and JIT Driver
+#===----------------------------------------------------------------------===#
+
+TheExecutionEngine = null
+
+HandleDefinition = ->
+  if (F = parser.ParseDefinition())
+    if (LF = F.Codegen())
+      console.log "Read function definition:"
+      console.log LF.dump()
+  else
+    # Skip token for error recovery.
+    getNextToken()
+
+HandleExtern = ->
+  if (P = parser.ParseExtern())
+    if (F = P.Codegen())
+      console.log "Read extern:"
+      console.log F.dump()
+  else
+    # Skip token for error recovery.
+    getNextToken()
+
+HandleTopLevelExpression = ->
+  # Evaluate a top-level expression into an anonymous function.
+  if (F = parser.ParseTopLevelExpr())
+    console.log "parse", F.body.toString()
+    if (LF = F.Codegen())
+      # JIT the function, returning a function pointer.
+      FP = TheExecutionEngine.getFFIFunction(LF)
+      console.log "Evaluated to", FP()
+  else
+    # Skip token for error recovery.
+    getNextToken()
+
+# top ::= definition | external | expression | ';'
+# Returns true if the next line is a continuation
+MainExpr = ->
+  switch parser.curTok
+    when tok_eof then return
+    when ';' then return# ignore top-level semicolons.
+    when tok_def then HandleDefinition()
+    when tok_extern then HandleExtern()
+    else HandleTopLevelExpression()
+
+runLine = (done) ->
+  rl.prompt()
+  rl.question 'ready> ', (line) ->
+    parser.lexer.feed(line)
+    parser.getNextToken()
+    MainExpr()
+    runLine(done)
+
+#===----------------------------------------------------------------------===#
+# "Library" functions that can be "extern'd" from user code.
+#===----------------------------------------------------------------------===#
+
+"""
+# putchard - putchar that takes a double and returns 0.
+extern "C"
+double putchard(double X) {
+  putchar((char)X)
+  return 0
+}
+
+# printd - printf that takes a double prints it as "%f\n", returning 0.
+extern "C"
+double printd(double X) {
+  printf("%f\n", X)
+  return 0
+}
+"""
+
+#===----------------------------------------------------------------------===#
+# Main driver code.
+#===----------------------------------------------------------------------===#
+
+#InitializeNativeTarget()
+Context = llvm.globalContext
+
+# Install standard binary operators.
+# 1 is lowest precedence.
+parser = new Parser()
+parser.binopPrecedence['='] = 2
+parser.binopPrecedence['<'] = 10
+parser.binopPrecedence['+'] = 20
+parser.binopPrecedence['-'] = 20
+parser.binopPrecedence['*'] = 40  # highest.
+
+rl = readline.createInterface
+  input: process.stdin
+  output: process.stdout
+
+# Make the module, which holds all the code.
+TheModule = new llvm.Module("my cool jit", Context)
+
+# Create the JIT.
+TheExecutionEngine = new llvm.ExecutionEngine(TheModule)
+OurFPM = new llvm.FunctionPassManager(TheModule)
+
+# Set up the optimizer pipeline.  Start with registering info about how the
+# target lays out data structures.
+OurFPM.addDataLayoutPass('') #TheExecutionEngine.dataLayout)
+# Provide basic AliasAnalysis support for GVN.
+OurFPM.addBasicAliasAnalysisPass()
+# Promote allocas to registers.
+#OurFPM.addPromoteMemoryToRegisterPass()
+# Do simple "peephole" optimizations and bit-twiddling optzns.
+OurFPM.addInstructionCombiningPass()
+# Reassociate expressions.
+OurFPM.addReassociatePass()
+# Eliminate Common SubExpressions.
+OurFPM.addGVNPass()
+# Simplify the control flow graph (deleting unreachable blocks, etc).
+#OurFPM.addCFGSimplificationPass()
+
+OurFPM.doInitialization()
+
+# Set the global so the code gen can use this.
+TheFPM = OurFPM
+
+# Run the main "interpreter loop" now.
+runLine ->
+  TheFPM = null
+
+  # Print out all of the generated code.
+  console.log TheModule.dump()


add alias to 'this.set()' snippet

add alias to 'this.set()' snippet

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AlexKVal/dotfiles.git/'


Add scrolling benchmark to React editor

Add scrolling benchmark to React editor

--- src/editor-component.coffee
+++ src/editor-component.coffee
@@ -262,6 +262,7 @@
         'editor:scroll-to-cursor': => editor.scrollToCursorPosition()
         'core:page-up': => editor.pageUp()
         'core:page-down': => editor.pageDown()
+        'benchmark:scroll': @runScrollBenchmark

   addCommandListeners: (listenersByCommandName) ->
     {parentView} = @props
@@ -476,3 +477,26 @@

   show: ->
     @setState(visible: true)
+
+  runScrollBenchmark: ->
+    node = @getDOMNode()
+
+    scroll = (delta, done) ->
+      dispatchMouseWheelEvent = ->
+        node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -0, wheelDeltaY: -delta))
+
+      stopScrolling = ->
+        clearInterval(interval)
+        done?()
+
+      interval = setInterval(dispatchMouseWheelEvent, 10)
+      setTimeout(stopScrolling, 500)
+
+    console.timeline('scroll')
+    scroll 50, ->
+      scroll 100, ->
+        scroll 200, ->
+          scroll 400, ->
+            scroll 800, ->
+              scroll 1600, ->
+                console.timelineEnd('scroll')


unit test for using gulp.dest together with gulp-tap

error: pathspec 'tests/dest.coffee' did not match any file(s) known to git

--- tests/dest.coffee
+++ tests/dest.coffee
@@ -0,0 +1,49 @@
+fs    = require 'fs'
+path  = require 'path'
+gulp  = require 'gulp'
+tap   = require '../lib/tap'
+
+exports.tapTest =
+
+#  setUp: (callback) ->
+#    @calculator = new Calculator
+#    callback()
+
+  'gulp-tap can change dest in the middle of stream': (test) ->
+    destinations =
+      "scss": "sass"
+      "js":   "scripts"
+      "img":  "assets/images"
+
+    # helper function to get a path relative to the root
+    getPath = (rel) -> path.resolve __dirname, "..", rel
+
+    fixturePath = getPath "tests/fixtures/"
+
+    fs.readdir fixturePath, (err, files) ->
+      test.expect 3
+      if err
+        test.ok no, "Can not read fixtures"
+        test.done(err)
+
+      gulp.src files.map (p) -> (fixturePath + "/" + p)
+        .pipe tap where
+        .on "end", ->
+          test.ok !fs.existsSync getPath "sass/s.scss", "sass file"
+          test.ok !fs.existsSync getPath "assets/images/img.png", "image file"
+          test.ok !fs.existsSync getPath "scripts/js.js", "js file"
+          test.done()
+        .on "error", (err) -> test.done(err)
+
+    where = (file, t) ->
+      match = (p) ->
+        ext = (path.extname p).substr 1 # remove leading "."
+        if( ext in ["jpg", "png", "svg", "gif"] )
+          ext = "img"
+        [destinations[ext] or null]
+
+      destPath = (match file.path)
+        .filter (p) -> p isnt null
+
+      if destPath.length
+        t.through gulp.dest, destPath


MainRouter: render TimelinePage when navigated to /timeline/

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rremizov/github-notifier.git/'


Add global settings config file

Add global settings config file

error: pathspec 'src/scripts/settings.coffee' did not match any file(s) known to git

--- src/scripts/settings.coffee
+++ src/scripts/settings.coffee
@@ -0,0 +1,10 @@
+define (require) ->
+  return {
+    # Hostname and port for the cnxarchive server
+    cnxarchive:
+      host: location.hostname
+      port: 6543
+
+    # Google Analytics tracking ID
+    analyticsID: 'UA-7903479-1'
+  }


Create organizations coffee to add new address divs

error: pathspec 'app/assets/javascripts/organization.coffee' did not match any file(s) known to git

--- app/assets/javascripts/organization.coffee
+++ app/assets/javascripts/organization.coffee
@@ -0,0 +1,25 @@
+window.addAddressRow = (count) ->
+  newRow = $ """
+

+    Mailing Address
+
+

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

+

+
+  <input type="hidden" value="" name="organization[addresses_attributes][""" + count + """][id]" id="organization_addresses_attributes_""" + count + """_id">
+  """
+
+  $("#organization_edit").append newRow
+
+$(document).on "click", "#add-new-address", (event) ->
+  event.preventDefault()
+  count = $("[id^='organization_addresses_attributes']:text").length
+  addAddressRow(count)
+
+# $(document).on "click", ".delete-row", (event) ->
+#   event.preventDefault()
+#   $(@).parents("tr:first").remove()
+#   addOrderRow() if $("#order-table tbody tr").length == 0
+


FtpReconnectError error class

FtpReconnectError error class

error: pathspec 'lib/ftpReconnectError.coffee' did not match any file(s) known to git

--- lib/ftpReconnectError.coffee
+++ lib/ftpReconnectError.coffee
@@ -0,0 +1,25 @@
+### jshint node:true ###
+### jshint -W097 ###
+'use strict'
+
+
+class FtpReconnectError extends Error
+  constructor: (@disconnectError='', @connectError='', onCwd) ->
+    @name = 'FtpReconnectError'
+    prefix = "Error automatically reconnecting to server"
+    suffix = "Triggering disconnect error"
+    if onCwd
+      mainMsg = "Could not connect to server"
+    else
+      mainMsg = "Could not preserve CWD"
+    @message = "#{prefix}.  #{mainMsg}: #{@connectError}.  #{suffix}: #{@disconnectError}."
+    connectErrorStack = "#{@connectError.stack||@connectError}"
+    if connectErrorStack[-1..-1] != '\n'
+      connectErrorStack += '\n'
+    disconnectErrorStack = "#{@disconnectError.stack||@disconnectError}"
+    if disconnectErrorStack[-1..-1] != '\n'
+      disconnectErrorStack += '\n'
+    @stack = "#{@name}: #{prefix}.\n#{mainMsg}: #{connectErrorStack}#{suffix}: #{disconnectErrorStack}"
+
+
+module.exports = FtpReconnectError


cleanup

cleanup

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/civilframe/resistance.git/'


A proper exported class

A proper exported class

--- app/javascript/src/legacy/pool.coffee
+++ app/javascript/src/legacy/pool.coffee
@@ -1,6 +1,6 @@
 $ = jQuery

-class PoolClass
+export default class Pool
   constructor: ->
     @pools = {}

@@ -137,6 +137,3 @@
       tags: "pool:#{pool_id}:#{new_sequence}"
       old_tags: ""
     }], callback
-
-
-window.Pool = new PoolClass


Cruft

Cruft

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -63,7 +63,6 @@
       css: "<%= dirs.build %>/themes/css"

     clean:
-      zepto: ["zepto/lib"]
       build: ["stage"]
       dist: ["<%= dirs.dist %>"]


Fix Gruntfile error

Fix Gruntfile error

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -16,7 +16,7 @@
       banner += " * (c) <%= core.pkg.author %>.\n *\n"
       banner += " * <%= core.pkg.name %> - v<%= core.pkg.version %> (<%= grunt.template.today('mm-dd-yyyy') %>)\n"
       # banner += " * <%= core.pkg.homepage %>\n"
-      banner += " * <%= core.pkg.license.type %> - <%= core.pkg.license.url %>\n"
+      banner += " * <%= core.pkg.licenses.type %> - <%= core.pkg.licenses.url %>\n"
       banner += " */"
       banner


Unfocus spec. Fix spec.

Unfocus spec. Fix spec.

--- spec/stdlib/native-spec.coffee
+++ spec/stdlib/native-spec.coffee
@@ -6,16 +6,19 @@
   beforeEach ->
     nativeModule = new Native

-  fdescribe "addMenuItem(path, keyBinding)", ->
+  describe "addMenuItem(path, keyBinding)", ->
+    mainMenu = null
     mainMenuItems = null

     beforeEach ->
-      mainMenuItems = OSX.NSApp.mainMenu.itemArray
+      mainMenu = OSX.NSApp.mainMenu
+      mainMenuItems = mainMenu.itemArray

     it "adds the item at the path terminus to the main menu, adding submenus as needed", ->
-      initialMenuCount = mainMenuItems.length
+      initialMenuCount = mainMenu.itemArray.length

       nativeModule.addMenuItem('Submenu > Item')

-      expect(mainMenuItems.length).toBe initialMenuCount + 1
+      expect(mainMenu.itemArray.length).toBe initialMenuCount + 1

+


starting to make a few functions more easily testable

error: pathspec 'src/configuration/index.coffee' did not match any file(s) known to git

--- src/configuration/index.coffee
+++ src/configuration/index.coffee
@@ -0,0 +1,12 @@
+{resolve} = require "path"
+{async, read} = require "fairmont"
+{yaml} = require "panda-serialize"
+
+exports.read = async (appRoot) ->
+  try
+    config = yaml yield read resolve appRoot, "sky.yaml"
+  catch e
+    console.error "There was a problem reading this project's configuration.", e
+    # FIXME: Why a new, messageless error?
+    #throw new Error()
+  config


Removes fixed date from 'updatedAgo' comparison.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/usermindinc/hubot-jira-reporter.git/'


remove readMeshConfig

remove readMeshConfig

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/crcn-archive/mesh.git/'


Fixed the bug of displaying the magnifier and edit icon for mobile devices.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/evercam/evercam-dashboard.git/'


Moves argument model from ranking plugin to here.

error: pathspec 'app/assets/javascripts/voluntary/ember_js/models/argument.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/voluntary/ember_js/models/argument.js.coffee
+++ app/assets/javascripts/voluntary/ember_js/models/argument.js.coffee
@@ -0,0 +1,7 @@
+Volontariat.Argument = DS.Model.extend
+  topicId: DS.attr('number')
+  topicName: DS.attr('string')
+  argumentableType: DS.attr('string')
+  argumentableId: DS.attr('number')
+  argumentableName: DS.attr('string')
+  value: DS.attr('string')


Don’t override lineOverdrawMargin with null

--- src/text-editor-element.coffee
+++ src/text-editor-element.coffee
@@ -15,7 +15,6 @@
   componentDescriptor: null
   component: null
   attached: false
-  lineOverdrawMargin: null
   focusOnAttach: false

   createdCallback: ->
@@ -110,7 +109,6 @@
       rootElement: @rootElement
       stylesElement: @stylesElement
       editor: @model
-      lineOverdrawMargin: @lineOverdrawMargin
       useShadowDOM: @useShadowDOM
     )
     @component = React.renderComponent(@componentDescriptor, @rootElement)


Create Main.coffee

Create Main.coffee

https://paiza.jp/poh/hatsukoi/share/4cd0a6af

error: pathspec 'POH8/TwinTailSet/Main.coffee' did not match any file(s) known to git

--- POH8/TwinTailSet/Main.coffee
+++ POH8/TwinTailSet/Main.coffee
@@ -0,0 +1,33 @@
+# Try POH
+# author: Leonardone @ NEETSDKASU
+# ===================================================
+
+solve = (mr) ->
+    s = mr.gi()
+    t = mr.gi()
+    r = ''
+    for i in [1..s]
+        r += if i is t then '+' else '-'
+    console.log r
+
+# ===================================================
+(() ->
+    buf = ''
+    process.stdin.resume()
+    process.stdin.setEncoding 'utf8'
+    process.stdin.on 'data', (chunk) -> buf += chunk.toString()
+    process.stdin.on 'end', () ->
+        lines = buf.split '\n'
+        cur = 0
+        gs = -> lines[cur++]
+        gi = -> parseInt gs()
+        gss = -> gs().split ' '
+        gis = -> gss().map (x) -> parseInt x
+        ngt = (n, f) -> f() for _ in [1..n]
+        ngs = (n) -> ngt n, gs
+        ngi = (n) -> ngt n, gi
+        ngss = (n) -> ngt n, gss
+        ngis = (n) -> ngt n, gis
+        solve "gs": gs, "gi": gi, "gss": gss, "gis": gis, "ngs": ngs, "ngi": ngi, "ngss": ngss, "ngis": ngis
+    )()
+# ===================================================


added player tracer

added player tracer

error: pathspec 'src/plugins/trace.coffee' did not match any file(s) known to git

--- src/plugins/trace.coffee
+++ src/plugins/trace.coffee
@@ -0,0 +1,24 @@
+moment = require 'moment'
+
+module.exports =
+
+    onBootstrap: (callback) ->
+
+        if argv.trace
+            bootstrap ->
+                callback 'end'
+        else
+            callback()
+
+bootstrap = (callback) ->
+
+    cursor = Database.db.collection('Chat.Public').find(
+        'markup.PLAYER1.plain': argv.player
+        time:
+            $gte: Date.now() - 30 * 24 * 60 * 60 * 1000
+    ).sort({time: -1}).limit(500).toArray (err, logs) ->
+
+        for item in logs
+            console.log '[%s]\t%s', moment(item.time).format('LLL'), item.text
+
+        callback()


Added Trailer Park Boys script

Added Trailer Park Boys script

error: pathspec 'src/scripts/tpb.coffee' did not match any file(s) known to git

--- src/scripts/tpb.coffee
+++ src/scripts/tpb.coffee
@@ -0,0 +1,208 @@
+# Description:
+#   Quotes by the Trailer Park Boys
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   hey j-roc - Display a random J-ROC quote
+#   hey lahey - Display a random Lahey quote
+#   hey ricky - Display a random Ricky quote
+#   hey bubbles - Display a random Bubbles quote
+#
+# Notes:
+#   None
+#
+# Author:
+#   carmstrong
+
+jroc = [
+  "There's 2 things mafukas gonna know about J-to-the-ROC: I spin more rhymes than a lazy Susan, and I'm innocent until mah guilt is proven! Peace! Representin' Sunnyvale, straight-the-fuck-up.",
+  "(To Lahey and Randy) Why don't you run along, Gut Cassidy and the Sundance Cheeseburger. Don't look into my eyes like I got candy for you.",
+  "Only wacksuckas like Cory and Trevor steal gas...and deal dope.",
+  "Yo Julian, I'm going to be a daddy. Not once but two times dawg, two times.",
+  "You know what I'm sayin'?",
+  "Rayyyyy - Kojak's got a wig on, RAYYY!",
+  "So why don't you move it along, you Rico-Suave-lookin' mafucka, cuz you ain't beatin' nobody.",
+  "You mean we can't go on with the game cuz some mafucka can't go to Canadian Mafacka (Tire) and get a new orange mafucka (ball) for $2.99? That's wack, Jules.",
+  "Yo, it's Rocky and Bullma'fucker.",
+  "J-Roc an' da Rock-Pile ALL UP IN DIS' MA' !",
+  "Naw, man, I don't play guns, mafucka.",
+  "We ain't down with killin', we down with chillin'. Peace!",
+  "The day J-ROC loses his flow, is the day the hair on Jim Lahey's bald head grow!",
+  "(referring to Jacob) That's the fuckin' law bitch from the grocery store y'man, who you pointin' at, skeleton?",
+  "This is BULL-ISH!",
+  "I can't even breathe up in this piece!",
+  "(to Randy) Oh what, you ain't pregnant with a bucketa chicken?",
+  "(to Randy) What you talkin' 'bout, you inflatable Elvis?",
+  "Oh, no, you di'n't just call me Jamie!",
+  "(holding his chains to Randy's gut like a stethoscope) I hear chicken. I hear cola fizz, and mustard and relish coagulating together with french fries and onion rings, but you know what? I don't hear a heart.",
+  "Carpe Dizem!"
+]
+
+ricky = [
+  "Lucy is banging cops which is no big deal, I guess. I don't run Lucy. She's for to be her own woman (free to be)",
+  "Lucy might have a problem, but what Lucy doesn't know won't learn her. (hurt)",
+  "Get me two bags of chips: Dressed All Over, and Zesty Mordant. (All Dressed and Zesty. Mordant is French for Zesty and is a mix-up of reading both languages on the bilingual packaging in Canada)",
+  "Yeah, get me some ja-LAP-ano chips (jalapeño)",
+  "Worst case Ontario... (scenario)",
+  "It's basically Peach'n'Cake (a piece of cake)",
+  "Denial and Error... (trial)",
+  "Make my words (Mark)*",
+  "Hey Bubs, are you watching that documentary on Saskatchewans?(Sasquatches)*",
+  "(While addressing the Judge in court) Thank you, Your Majesty. (Honour, which is still incorrect. In Canada a female judge is referred to as My Lady.)",
+  "I'm trying to try here, Sarah.",
+  "Who's playing the pianio? (piano)",
+  "Make like a tree and fuck off. (leave)",
+  "I'm not the kind of person to say atodaso, but you know what? Atodaso, I-fucking-atodaso. (I told you so)",
+  "It was golfing flames, flames just golfing, golfing. (engulfed in flames)",
+  "It's a Catch-23 situation. (Catch-22)",
+  "(To Alex Lifeson of Rush) Well, play that Diane Sawyer song, then. (Tom Sawyer - Rush song)",
+  "Looks like a tropical earthquake blew through here. (storm)",
+  "We can get 2 birds stoned at once. (kill 2 birds with one stone)",
+  "Why do you look like Indianapolis Jones? (Indiana)",
+  "He passed with flying fucking carpets. (colours)",
+  "It doesn't take rocket appliances. (science)",
+  "Trinity's at the age where it's gorilla see gorilla do. (monkey)",
+  "Do you got a search warranty for that? (warrant)*",
+  "I must be fire retarded or something. (retardant)",
+  "I'm not a pezmist, I'm an optometrist. (Pessimist, Optimist)",
+  "These plates got me from Tuscany, Arizona to Kentville, Nova Scotia. (Tucson) - Ray, Ricky's Dad",
+  "I'll drive you back to the park, Lucy, but there is probably a pretty good chance that it might be over between us (Ricky uses a triple conditional; just one would be sufficient)",
+  "If my dad and Julian and Bubbles hadn't had been out all night getting lap-dances and getting drunk, the whole thing could have been preventative. (prevented)",
+  "To be honest with you, I fucking hate bagminten. (badminton)",
+  "Breaker, Breaker, come in earth. This is Rocketship 27, some aliens fucked over the carbinator in engine number four, we are going to try to refuckulate it and land on Juniper. (carburetor, repair, Jupiter)",
+  "That's not a ladybug. It's a cannerpillar. (caterpillar)",
+  "...how to get Buhurbon stains out of Kahayki pants (Bourbon, Khaki)",
+  "One man's garbage is another man person's good ungarbage. (One man's garbage is another man's treasure)",
+  "Au gratin (gratis, free; au gratin is with cheese)",
+  "I-surance (Insurance)*",
+  "Swallow my prize (pride)",
+  "Neither here, there, or everywhere (Neither here nor there)",
+  "Boys, let's make toast (Let's make a toast)",
+  "There's no lurches in there, Bubbles, is there? (leeches)",
+  "I know what you're doing, Lahey, you're trying to fill my feet. (fill my shoes)",
+  "You gotta remember, every kid goes through phrases. (phases)",
+  "What Julian don't grow won't burn him. (know, hurt)",
+  "Nice decnals! (decals)",
+  "I'm just stretched out! (stressed)*",
+  "I don't need your cherry trees. (charity)*",
+  "What if he has radies? (rabies)",
+  "Supply and command. (demand)",
+  "What comes around is all around (What goes around comes around)",
+  "What, do you own space? No. Nay-saw does. (NASA)",
+  "Do unto others as you do unto you. (Do unto others as you would have them do unto you)",
+  "One day I will go somewhere that is hot, like Majaica or the Dromedary Republic (Jamaica, Dominican Republic)",
+  "Trinity made a life-ing thing basically out of this chicken. Started with a little eggy thing, and heated it up under these incu-baker things, and it...it was bornt. (living, incubator, born)",
+  "We'll split 50/50/50. (three ways.)",
+  "(To Trevor and Cory) Well, I'd like for you two to come with us, but apparently it's clear to see who makes the pants here. (wears the pants)",
+  "I hate to have to give you an ultimarium (ultimatum)",
+  "It's me or Gumby and Pifuckio (Cory and Trevor)",
+  "Raykins! That's what they are, Julian, fuckin' raykins! (raccoons)",
+  "I'm not working for J-Roc, that's against my vice principals (principles)",
+  "Bubbles, I don't want any rich peopleman's food, I want some fuckin' meat that's cooked. (people's)",
+  "It's survival of the fitness, boys. (fittest)",
+  "If Randy thinks he's smartener than me, he's wrong. (smarter)*",
+  "You gotta do illegal things once in a while, and then maturinate into a better person. (mature)",
+  "Your thoughts might be better than mine, but I have thoughts going around in my head too, about...different thinkings...about brain things that you can use and...doing different things.",
+  "Sweet empowered chicken things (sweet and sour chicken)",
+  "(To Shitty Bill) Take a shower for fuck's sake! You look like a fuckin' hobolo! (hobo)",
+  "(To Randy) Why don't you fuck off and go get some hypo-suction! (liposuction)",
+  "It was my mother's mating name. (maiden name)",
+  "Holy shit, you got us a lemon-zine? (Limousine)",
+  "Randy bornt my baby. (Randy is the father of Lucy's 2nd child)",
+  "Lucy, I will make you have a eternity test. (paternity)",
+  "He's gettin' all frustated. (frustrated)",
+  "You can go to college and get your little Pf.D, or whatever the fuck it's called! (Ph.D.)",
+  "Child reports (Child Support)",
+  "Get us the fuckin' land papers A.S.A.T! (Land papers because he couldn't pronounce 'topographic map', A.S.A.P)",
+  "I'm fucked over from being electromecuted! (electrocuted)",
+  "Those them cigarettes in there is our lifes! (are our lives)",
+  "...it's distraculating my case. (distracting)",
+  "Amernicans! (Americans)",
+  "I have responsibles now... (Responsibilities)",
+  "Well, now we gotta go to the library and get a book on horficulture. (Horticulture)",
+  "I self-learned myself. (self-taught)"
+]
+
+lahey = [
+  "When you plant shit-seeds, you get shit-weeds.",
+  "Birds of a shitfeather flock together, Randy.",
+  "We're in the eye of a shiticane here, Julian, and Ricky's a low-shit system!",
+  "Shit-storm troopers",
+  "The shit-apple doesn't fall far from the shit-tree",
+  "Captain Shittacular",
+  "I'm watching you like a shithawk",
+  "We're sailing into a shit-typhoon Randy, we'd better haul in the jib before it gets covered in shit.",
+  "When you're getting pelted with shitballs, deputy, you gotta get a shit-bat.",
+  "The shit pool's gettin full, Randy, time to strain the shit before it overflows. I will not have a Pompeiian catastrophie happening in Sunnyvale.* How dare you involve my daughter in your hemisphere of shit?",
+  "Your shit-goose is cooked, Ricky",
+  "Shit-apples never fall far from the shit-tree",
+  "He's about to enter the shit-tornado to Oz.",
+  "Do you know what a shit-rope is Julian? It's a rope covered in shit that criminals try to cling to. Y'see, the shit acts like grease, and the harder you tighten your grip, the more you slide down it.",
+  "A shit-leopard can't change its spots.",
+  "We need more shit puppets for our play, Randy, and we need angry shit puppets but they aren't mad at us. Shit puppets only get angry at other shit puppets",
+  "Randy: Cops and dope don't mix, do they Mr. Lahey? Lahey: Like shit and strawberry shortcake Randy.",
+  "I live by the golden rule: if you don't cross my shitline I won't cross yours. But when Ray told everybody in the park that I was drinking again, he crossed the goddamn shitline.",
+  "Lahey: Do you know what a shit barometer is, Bubbles? Measures the shit pressure in the air. You can feel it. Listen, Bubs. You hear that? The sounds of the whispering winds of shit? You can hear it.",
+  "Do you feel that, Randy, the way the shit clings to the air? Shit Blizzard.",
+  "Never Cry Shitwolf.",
+  "Did you see that Randy, Goddamn shitapple driving the shitmobile. Nobody else in this park gives a fuck, why should I?",
+  "Lahey -You know what's at work here, it's shit tectonics, when two shit plates strike and come together under incredible pressure, do you know what happens, Bubbles?",
+  "Yes I used to drink, Randy, but I got the shitmonkey off my back for good.",
+  "You just opened Pandora's Shitbox, Ray",
+  "You know what you get when two shit-tectonic plates collide? Shitquakes, Julian. Shitquakes.",
+  "The ole shit liner is coming to port, and I'll be there to tie her up.",
+  "Y'see, Ricky started off as a little shitspark from the ol' shitflint that eventually grew into a shitbonfire, and driven by the winds of his monumental ignorance, grew into a raging shitfirestorm. If I marry Barb, I'll have total control of Sunnyvale, and then I'll be able to unleash a shitnami tidal wave that will extinguish Ricky and his shitflames forever. And with any luck, he'll drown in the undershit of that wave...shitwaves.",
+  "Tic Toc, Shit clock's tickin' Rick.",
+  "We got the key to shitty city, Ran, and Julian's the muscular mayor.",
+  "You boys have loaded up a hair-trigger, double barrelled shitmachinegun, and the barrel's pointing right at your own heads.",
+  "Shit flowers, Randy. From a distance they look like ordinary flowers, but when you get right down and stick your nose in them you realize they're shit flowers, and there's a whole fucking bouquet down there right in front of Ray's trailer.",
+  "Lahey: Shit moths, Randy. Randy: Is that you or the liquor speaking, Mr Lahey?",
+  "Hey Sexian (Lahey adressing Julian)",
+  "Whenever I'm sober, the boys are careful, they're scared of me cause they know what I'll do. They're cautious, it's hard to catch them. But when I'm drinking, their shitguards are down and they fuck up, but the problem is when I'm drinking, I fuck up too, a lot, Barb. I gotta be drinking, but not drinking, ya see? The only way to do that, is to pretend, I am gonna pretend to be drunk, collect evidence and build a solid case against them. Sober as a judge I'm gonna show up today at the cheeseburger picnic, and I'm gonna pretend to be a drunken idiot. And why? Shitguards, Barb...shitguards.",
+  "This place is a dump. You have my permission to do whatever you want, any time any place, and you don't have to listen to Pilsbandy Doughboy (Randy) or Team Sexy (the police)"
+]
+
+bubbles = [
+  "I'd like to see that Red Blue Green cocksucker put one of those together fucking duct taping it.",
+  "Dino. Did you call Fred and Barney too? How about Mr. Slate?",
+  "I won't tell anyone you have splinters in your lips if you don't tell anyone I have a wooden cock.",
+  "Randy: Does that thing really launch, Bubbles? Bubbles: Does the Tin Man have a sheet-metal cock?",
+  "Julian, what's a shit hawk? Is it some kind of shitty bird that swoops down and puts poop on you?",
+  "Ricky, what happened to your fucking eyes? You look like Alice Cooper?",
+  "(in reference to the Helix song Rock You) I'm not giving anyone a fucking R!",
+  "Ricky, those laws are there to protect kids, not so goofballs like you can put them in the car with no door on it, and drive around the fuckin' neighbourhood stealin' barbecues!",
+  "Can I come out now? I think I have a leech on my bird.",
+  "Julian, we're both baked. That's why were probably not making any sense.",
+  "No, he's just a really big kitty, and he's baked!",
+  "Bubbles: Stealing gas? Why, Cory and Trevor, that's highly illegal, you shouldn't be stealing gas, Cory and Trevor.",
+  "(Rapping) I got a grey kitty, white one, and a tabby too/ And a big orange guy who put snakes in my shoes/ Mad MC skills, leave ya struck, and I roll with ma kitties, and I'am hard as fuck/ I am down with Plato and Socrates/ And I like to get busy with all the ladies. Grunt, grunt/ sumthin,' sumthin,' sumthin,'/ Grunt/ Up in ma shed, up in ma shed...",
+  "Holy fuck boys, this shed is like a fucking palace! Indoor plumbing (toilet seat inside), satellite tv, 400 channels, anything I wanna watch, it's right there, space for my kitties, Mobile phone, new technology (holds up an ancient mobile phone), this is the best fucking shed there ever was!",
+  "Here, Cory-Trevor, Cory-Trevor!",
+  "Hampton: Can you read, my son? Bubbles: Well, that depends, can you go fuck yourself?",
+  "Trevor: Julian, this looks like a pirate gun. Bubbles: Well Trevor, I guess that makes you Long John Dickweed, then.",
+  "Green Bastard, from parts unknown (grunts and inhales).",
+  "Lahey, can you please get the flyin' fuck out of our way!",
+  "COCK-SUCKER!",
+  "There's a note pinned to a tree! Diddly-dee!",
+  "(To Randy re: cheeseburgers) How many did you drive into that big fuckin cheeseburger-locker?",
+  "Well, when I was a little guy, I always wanted to go up into space, be a space-man. But you gotta be able to see really fuckin' good to do that job. Some guy would take one look at me and say 'Uhhh, sorry sir, you gotta be able to see a little better than you'... I don't give a fuck.",
+  "Holy sweet flying fuck!"
+]
+
+module.exports = (robot) ->
+  robot.hear /.*(hey bubbles).*/i, (msg) ->
+    msg.send msg.random bubbles
+
+  robot.hear /.*(hey ricky).*/i, (msg) ->
+    msg.send msg.random ricky
+
+  robot.hear /.*(hey j-roc).*/i, (msg) ->
+    msg.send msg.random jroc
+
+  robot.hear /.*(hey lahey).*/i, (msg) ->
+    msg.send msg.random lahey


Improve socket log messages

Improve socket log messages

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ChHeLeJa/SpaceTrader.git/'


totally re-did meteors to not overstress iPad. the meteor sky now moves, and meteors have spacing rules sort of like stars'

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/UCSFMemoryAndAging/tabcat.git/'


skip timer

skip timer

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/LucasAdam/hubot-trivia-game-french.git/'


giftv

giftv

error: pathspec 'src/scripts/giftv.coffee' did not match any file(s) known to git

--- src/scripts/giftv.coffee
+++ src/scripts/giftv.coffee
@@ -0,0 +1,9 @@
+# Return random animated GIFs from giftv.
+#
+# giftv me            - Returns a random animated GIF.
+module.exports = (robot) ->
+  robot.respond /giftv( me)?$/i, (msg) ->
+    msg
+      .http('http://www.gif.tv/gifs/get.php')
+      .get() (err, res, body) ->
+        msg.send 'http://www.gif.tv/gifs/' + body + '.gif' || 'Could not compute.'


Add index test

Add index test

error: pathspec 'test/index_spec.coffee' did not match any file(s) known to git

--- test/index_spec.coffee
+++ test/index_spec.coffee
@@ -0,0 +1,6 @@
+sinos = require('../index')
+
+describe 'sinos-river-level-twitter', ->
+  describe '#search', ->
+    it 'is a function', ->
+      expect(sinos.search).to.be.instanceof Function


Remove deprecated option from selection spec

--- spec/selection-spec.coffee
+++ spec/selection-spec.coffee
@@ -58,7 +58,7 @@

   describe "when only the selection's tail is moved (regression)", ->
     it "emits the 'screen-range-changed' event", ->
-      selection.setBufferRange([[2, 0], [2, 10]], isReversed: true)
+      selection.setBufferRange([[2, 0], [2, 10]], reversed: true)
       changeScreenRangeHandler = jasmine.createSpy('changeScreenRangeHandler')
       selection.on 'screen-range-changed', changeScreenRangeHandler


A first dummy spec to get testing running

error: pathspec 'spec/sample_spec.spec.coffee' did not match any file(s) known to git

--- spec/sample_spec.spec.coffee
+++ spec/sample_spec.spec.coffee
@@ -0,0 +1,4 @@
+describe 'le me trying to get testing running', ->
+  it 'is a stubpid test', ->
+    foo = 1
+    expect(foo).toEqual(1)


fixing ulimit bs

fixing ulimit bs

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bubblegroup/bubblebot.git/'


replaced end with close

replaced end with close

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jaunkst/atom-html2haml.git/'


Perform InputComponent DOM updates manually

--- src/input-component.coffee
+++ src/input-component.coffee
@@ -8,9 +8,7 @@

   render: ->
     {className} = @props
-    style = @props.presenter.state.hiddenInput
-    style.WebkitTransform ?= 'translateZ(0)'
-    input {className, style, 'data-react-skip-selection-restoration': true}
+    input {className}

   getInitialState: ->
     {lastChar: ''}
@@ -19,11 +17,33 @@
     node = @getDOMNode()
     node.addEventListener 'paste', @onPaste
     node.addEventListener 'compositionupdate', @onCompositionUpdate
+    node.setAttribute('data-react-skip-selection-restoration', true)
+    node.style['-webkit-transform'] = 'translateZ(0)'

-  # Don't let text accumulate in the input forever, but avoid excessive reflows
   componentDidUpdate: ->
+    node = @getDOMNode()
+    @oldState ?= {}
+    newState = @props.presenter.state.hiddenInput
+
+    if newState.top isnt @oldState.top
+      node.style.top = newState.top + 'px'
+      @oldState.top = newState.top
+
+    if newState.left isnt @oldState.left
+      node.style.left = newState.left + 'px'
+      @oldState.left = newState.left
+
+    if newState.width isnt @oldState.width
+      node.style.width = newState.width + 'px'
+      @oldState.width = newState.width
+
+    if newState.height isnt @oldState.height
+      node.style.height = newState.height + 'px'
+      @oldState.height = newState.height
+
+    # Don't let text accumulate in the input forever, but avoid excessive reflows
     if @lastValueLength > 500 and not @isPressAndHoldCharacter(@state.lastChar)
-      @getDOMNode().value = ''
+      node.value = ''
       @lastValueLength = 0

   # This should actually consult the property lists in /System/Library/Input Methods/PressAndHold.app


added (very minimal) support for other templating engines

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/olmokramer/atom-shell-layoutbuilder.git/'


reorder

reorder

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/zzzev/insta.git/'


Update web lint task names.

Update web lint task names.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/knottie/example.git/'


add some git motions

add some git motions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/demhydraz/til.git/'


Create snippets.cson

Create snippets.cson

error: pathspec 'atom_snippets/snippets.cson' did not match any file(s) known to git

--- atom_snippets/snippets.cson
+++ atom_snippets/snippets.cson
@@ -0,0 +1,13 @@
+'.source.js':
+  'ProtoSS':
+    'prefix': 'protoss'
+    'body': 'function $1($2) {\n\tvar o = this,\n\t\ta = arguments;\n\t$3\n\to.super(a$4);\n\tvar m = {};\n\t$5\n\to.superize(a, m, true, true);\n\treturn o;\n}'
+  'ProtoSS Method':
+    'prefix': 'protossmethod'
+    'body': 'm.$1 = function $2($3) {\n\t$4\n\treturn $5;\n};'
+  'ProtoSS Var':
+    'prefix': 'protossvar'
+    'body': 'o.$1 = $2;'
+  'ProtoSS Package':
+    'prefix': 'protosspackage'
+    'body': 'window.package("$1").internal(\nfunction $2($3) {\n\tvar o = this,\n\t\ta = arguments;\n\t$4\n\to.super(a$5);\n\tvar m = {};\n\t$6\n\to.superize(a, m, true, true);\n\treturn o;\n});'


set test bundle directory before loading syntax

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stratuseditor/fractus.git/'


new file:   src/maps.coffee

new file:   src/maps.coffee

error: pathspec 'src/maps.coffee' did not match any file(s) known to git

--- src/maps.coffee
+++ src/maps.coffee
@@ -0,0 +1,25 @@
+riot = require('riot')
+Q = require('q')
+
+class GeoCoder
+  constructor: () ->
+    @geocoder = new google.maps.Geocoder()
+    riot.observable @
+  code: (request) ->
+    deferred = Q.defer()
+    @geocoder.geocode request, (results, status) ->
+      if status is google.maps.GeocoderStatus.OK
+        deferred.resolve results.map (result) ->
+          address: result.formatted_address
+          location:
+            longitude: result.geometry.loaction.lng()
+            latitude:  result.geometry.loaction.lat()
+      else
+        deferred.reject status
+    deferred.promise
+  codeAddress: (address) ->
+    @code address: address
+  codeLocation: (location) ->
+    @code location: google.maps.LatLng(location.latitude, location.longitude)
+
+exports = {GeoCoder}


TODO comment.

TODO comment.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/philbooth/GitHubReminder.git/'


Added JS utility functions.

Added JS utility functions.

error: pathspec 'src/util.coffee' did not match any file(s) known to git

--- src/util.coffee
+++ src/util.coffee
@@ -0,0 +1,24 @@
+#
+# JavaScript Language Utility Methods
+#
+util = {}
+
+util.extend = (obj, source) ->
+  # ECMAScript5 compatibility based on: http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/
+  if Object.keys
+    keys = Object.keys(source)
+    i = 0
+    il = keys.length
+
+    while i < il
+      prop = keys[i]
+      Object.defineProperty obj, prop, Object.getOwnPropertyDescriptor(source, prop)
+      i++
+  else
+    safeHasOwnProperty = {}.hasOwnProperty
+    for prop of source
+      obj[prop] = source[prop]  if safeHasOwnProperty.call(source, prop)
+  obj
+
+
+module.exports.util = util


added templates angular file forgoten in last commit

error: pathspec 'services/web/public/coffee/main/templates.coffee' did not match any file(s) known to git

--- services/web/public/coffee/main/templates.coffee
+++ services/web/public/coffee/main/templates.coffee
@@ -0,0 +1,49 @@
+define [
+	"base"
+], (App) ->
+
+	App.factory "algoliawiki", ->
+		client = new AlgoliaSearch("SK53GL4JLY", "e398f35d3074fde57ca6d6c88d8be37c")
+		index = client.initIndex("lean-wiki-index")
+		return index
+
+	App.controller "SearchWikiController", ($scope, algoliawiki, _) ->
+		algolia = algoliawiki
+		$scope.hits = []
+
+		$scope.clearSearchText = ->
+			$scope.searchQueryText = ""
+			updateHits []
+
+		$scope.safeApply = (fn)->
+			phase = $scope.$root.$$phase
+			if(phase == '$apply' || phase == '$digest')
+				$scope.$eval(fn)
+			else
+				$scope.$apply(fn)
+
+		buildHitViewModel = (hit)->
+			page_underscored = hit.pageName.replace(/\s/g,'_')
+			section_underscored = hit.sectionName.replace(/\s/g,'_')
+			result =
+				name : hit._highlightResult.pageName.value + " - " + hit._highlightResult.sectionName.value
+				url :"/learn/#{page_underscored}##{section_underscored}"
+			console.log result
+			return result
+
+		updateHits = (hits)->
+			$scope.safeApply ->
+				$scope.hits = hits
+
+		$scope.search = ->
+			query = $scope.searchQueryText
+			if !query? or query.length == 0
+				updateHits []
+				return
+
+			algolia.search query, (err, response)->
+				if response.hits.length == 0
+					updateHits []
+				else
+					hits = _.map response.hits, buildHitViewModel
+					updateHits hits


Create yara.coffee

Create yara.coffee

error: pathspec 'yara.coffee' did not match any file(s) known to git

--- yara.coffee
+++ yara.coffee
@@ -0,0 +1,21 @@
+# Description:
+#   Generate Yara Rule with strings
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   hubot yara - Generates default rule template
+#   hubot yara "string1" "string2" ... - Generates rule with given strings
+#
+# Author:
+#   Scott J Roberts - @sroberts
+
+module.exports = (robot) ->
+  robot.respond /yara/i, (msg) ->
+    # If there's strings generate rule with strings
+
+    # If there aren't then just generate a template


change signature tag from pre to p

change signature tag from pre to p

reason: firefox compatibility

--- client/app/utils/message_utils.coffee
+++ client/app/utils/message_utils.coffee
@@ -119,6 +119,8 @@
             message.inReplyTo  = [inReplyTo.get 'id']
             message.references = inReplyTo.get('references') or []
             message.references = message.references.concat message.inReplyTo
+
+        signature = "--\n#{signature}"

         options = {
             message
@@ -176,7 +178,7 @@
         message.subject = @getReplySubject inReplyTo
         message.text = separator + @generateReplyText(text) + "\n"
         if signature
-            message.text += "\n\n--\n#{signature}"
+            message.text += "\n\n#{signature}"
         message.html = """
             #{COMPOSE_STYLE}

#{separator} …

@@ -184,8 +186,9 @@

             """
         if signature
+            signature = signature.replace /\n/g, '
'
             message.html += """
-

--\n#{signature}

+

#{signature}

             """

@@ -223,7 +226,7 @@
         message.subject = @getReplySubject inReplyTo
         message.text = separator + @generateReplyText(text) + "\n"
         if signature
-            message.text += "\n\n--\n#{signature}"
+            message.text += "\n\n#{signature}"
         message.html = """
             #{COMPOSE_STYLE}

#{separator} …

@@ -231,8 +234,9 @@

             """
         if signature
+            signature = signature.replace /\n/g, '
'
             message.html += """
-

--\n#{signature}

+

#{signature}

             """

@@ -310,9 +314,10 @@
             message.text += "\n\n--\n#{signature}"
         message.html = COMPOSE_STYLE
         if signature
+            signature = signature.replace /\n/g, '
'
             message.html += """

-
--\n#{signature}

+
--\n#{signature}

             """

         return message


Cherrypick pull request from @houfeng0923 Closes #70

--- coffee/angular-daterangepicker.coffee
+++ coffee/angular-daterangepicker.coffee
@@ -1,6 +1,6 @@
 picker = angular.module('daterangepicker', [])

-picker.value('dateRangePickerConfig',
+picker.constant('dateRangePickerConfig',
   separator: ' - '
   format: 'YYYY-MM-DD'
 )
@@ -119,7 +119,7 @@
       # watchers that reinit will be attached to old daterangepicker instance.
       _picker = el.data('daterangepicker')
       return
-
+
     _init()

     # If input is cleared manually, set dates to null.


Added create_event perm

Added create_event perm

error: pathspec 'client/config.coffee' did not match any file(s) known to git

--- client/config.coffee
+++ client/config.coffee
@@ -0,0 +1,3 @@
+Accounts.ui.config
+  requestPermissions:
+    facebook: ['email', 'create_event', 'user_events']


Updated lib.coffee -- added historic value,  object_refinement

Historic value is a class for changing/updating/recording a value over
time.

Object refinement is a class for wrapping objects in another class
with new methods.

error: pathspec 'lib_spec.coffee' did not match any file(s) known to git

--- lib_spec.coffee
+++ lib_spec.coffee
@@ -0,0 +1,36 @@
+#= require lib
+describe "lib/object_refinement", ->
+  describe "example usage", ->
+    beforeEach ->
+      class ATypeToRefine
+        normal: -> 'a'
+      class BTypeToRefine
+        normal: -> 'b'
+      class XTypeToRefine
+        normal: -> 'x'
+
+      refinement = ttm.require('lib/object_refinement').build()
+      refinement.forType(ATypeToRefine, {refined: -> 'a'})
+      refinement.forType(BTypeToRefine, {refined: -> 'b'})
+
+      @a = new ATypeToRefine
+      @b = new BTypeToRefine
+      @x = new XTypeToRefine
+
+      @ap = refinement.refine(@a)
+      @bp = refinement.refine(@b)
+      @xp = refinement.refine(@x)
+
+
+
+    describe "added methods via refinement", ->
+      it "does not add them to the unrefined object", ->
+        expect(@a.refined).toEqual undefined
+        expect(@b.refined).toEqual undefined
+
+      it "adds them to the refined object", ->
+        expect(@ap.refined()).toEqual "a"
+        expect(@bp.refined()).toEqual "b"
+
+    it "does nothing to a class that has no applicable refinement", ->
+      expect(@xp.refined).toEqual undefined


bugfix: user email field in unset_user

bugfix: user email field in unset_user

 On branch master

	modified:   nodejs_server/middleware/unset_user.coffee

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/FireworksProject/platform.y.git/'


stack-editor: searchbox: docs link taken to searchbox

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


Correct method description

Correct method description

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/supersonic.git/'


Changed sender and recipient email addresses.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/virtdb/virtdb-error-notifier.git/'


cut, tmoutdent, tmindent

cut, tmoutdent, tmindent

--- HTML/atomicity.coffee
+++ HTML/atomicity.coffee
@@ -42,6 +42,11 @@
   text = editor.getSession().doc.getTextRange editor.getSelectionRange()
   Chrome.writeToPasteboard text

+Chrome.bindKey 'cut', 'Command-X', (env, args, request) ->
+  text = editor.getSession().doc.getTextRange editor.getSelectionRange()
+  Chrome.writeToPasteboard text
+  editor.session.remove editor.getSelectionRange()
+
 Chrome.bindKey 'eval', 'Command-R', (env, args, request) ->
   eval env.editor.getSession().getValue()

@@ -49,6 +54,12 @@

 Chrome.bindKey 'togglecomment', 'Command-/', (env) ->
   env.editor.toggleCommentLines()
+
+Chrome.bindKey 'tmoutdent', 'Command-[', (env) ->
+  env.editor.blockOutdent()
+
+Chrome.bindKey 'tmindent', 'Command-]', (env) ->
+  env.editor.indent()

 # emacs > you


Use object for tempting within haml-coffee

error: pathspec 'views/outer/about/_team.coffee' did not match any file(s) known to git

--- views/outer/about/_team.coffee
+++ views/outer/about/_team.coffee
@@ -0,0 +1,10 @@
+root = exports ? this
+
+root.team =
+  paul:
+    name: "Paul Bigger"
+    role: "Founder"
+    github: "pbiggar"
+    email: "paul@circleci.com"
+    bio: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam at eros non dui sollicitudin mattis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean elementum mi tincidunt orci rhoncus tempus. Cras tincidunt feugiat purus a venenatis.  Morbi sollicitudin turpis sapien, sed consequat justo. Sed semper sagittis ornare. Etiam et est tortor, at tristique sem. Maecenas a quam magna."
+    visible: true


Gruntfile fix

Gruntfile fix

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/pysight/translucent.git/'


UnCSS weg

UnCSS weg

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/SpaceK33z/Pluff.git/'


travis-ci & phantomjs timeout

travis-ci & phantomjs timeout

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -426,7 +426,6 @@
         # Also occasional bug with grunt-watch causes constant rerun of tasks when mocha has errors
         # atBegin: true

-
     shell:
       mochaCmd: command: "node_modules/.bin/mocha #{buildSpecDir}/index --recursive" # --reporter spec"
       mochaCmdDev: command: "node_modules/.bin/mocha #{buildSpecDir}_combined/index-combined --recursive" # --reporter spec"
@@ -440,7 +439,7 @@
           'build/spec/SpecRunner_almondJs_noAMD_plainScript.html'
           'build/spec/SpecRunner_almondJs_noAMD_plainScript_min.html'
         ]
-        options: run:true
+        options: run: true

       AMD:
         src: [
@@ -476,7 +475,7 @@
   grunt.registerTask cmd, splitTasks "shell:#{cmd}" for cmd of gruntConfig.shell # shortcut to all "shell:cmd"
   grunt.registerTask shortCut, splitTasks tasks for shortCut, tasks of {
      # generic shortcuts
-     "default":   "build dev min test testDev testMin mocha run"
+     "default":   "build dev min test testDev testMin mocha:AMD run"
      "release":   "build urequire:AMD urequire:AMDunderscore dev min test testDev testMin mocha run"
      "examples":  "urequire:AMD urequire:UMDplainReplaceDep urequire:AMDunderscore urequire:UMDunderscore urequire:nodejsCompileAndCopy"
      "all":       "build dev min test testDev testMin mocha examples run"
@@ -515,7 +514,7 @@
     'grunt-contrib-concat'
     'grunt-contrib-watch'
     'grunt-mocha'
-    'grunt-bower-requirejs'
+    #'grunt-bower-requirejs'
   ]

   grunt.initConfig gruntConfig


add copy .png from style path

add copy .png from style path

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tmuhonkin/homekeep.git/'


Fix `latex-beamer` artefact

Fix `latex-beamer` artefact

error: pathspec 'grammars/latex' did not match any file(s) known to git
error: pathspec 'beamer.cson' did not match any file(s) known to git


importing and release elastic ip addresses

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bubblegroup/bubblebot.git/'


fixes

fixes


Started main bundle file.

Started main bundle file.

error: pathspec 'index.coffee' did not match any file(s) known to git

--- index.coffee
+++ index.coffee
@@ -0,0 +1,4 @@
+module.exports =
+	Linkedlist : require './LinkedList'
+	Queue : require './Queue'
+


Add Access key of help menu label

Add Access key of help menu label

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/will-hart/marp.git/'


Create coffee_direct.coffee

Create coffee_direct.coffee

error: pathspec 'tasks/coffee_direct.coffee' did not match any file(s) known to git

--- tasks/coffee_direct.coffee
+++ tasks/coffee_direct.coffee
@@ -0,0 +1,64 @@
+exec = require('child_process').execFile
+fs = require('fs')
+
+parseOptions = (opts) ->
+  args = []
+  for key, val of opts
+    continue unless val
+    dashes = if key.length is 1 then '-' else '--'
+    args.push dashes+key
+    args.push val if val isnt true
+  args
+
+
+module.exports = (grunt) ->
+  # define new task
+  grunt.registerMultiTask "coffee", "OS Compile", ->
+    done = @async()
+    #subtask (dev, test, prod)
+    name = @target
+
+    #src dir checks
+    src = @data.src
+    unless fs.existsSync(src)
+      grunt.log.writeln "'#{name}': '#{src}' does not exist. Skipping."
+      return done true
+
+    #dest dir checks
+    dest = @data.dest
+    unless fs.existsSync(dest)
+      grunt.file.mkdir dest
+    stats = fs.statSync dest
+    if stats.isFile()
+      grunt.log.writeln "'#{name}': '#{dest}' must be directory."
+      return done true
+
+    grunt.log.writeln "'#{name}': '#{src}' into '#{dest}"
+
+    args = parseOptions @data.options
+    args.push '--compile'
+    args.push '--output'
+    args.push dest
+    args.push src
+
+    grunt.verbose.writeflags(args, 'Options');
+
+    bin = './node_modules/coffee-script/bin/coffee'
+    exec bin, args, {}, (error, stdout, stderr) ->
+      if error isnt null
+        grunt.log.writeln error
+        return done false
+      grunt.log.writeln stdout if stdout
+      grunt.fail.warn stderr if stderr
+      done true
+
+  #and the config
+  coffee:
+    dev:
+      src: 'src/scripts/'
+      dest: './build/dev/scripts/'
+      options:
+        b: true
+    test:
+      src: 'test/scripts/'
+      dest: 'build/test/scripts/'


made the example clearer

made the example clearer

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Industrial/stream-flow.git/'


Fix the method name

Fix the method name

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Hiroto-K/EncryptionHelper.git/'


Keep activate events in api preview mode

--- src/package.coffee
+++ src/package.coffee
@@ -489,7 +489,7 @@
         else if _.isArray(commands)
           @activationCommands[selector].push(commands...)

-    if includeDeprecatedAPIs and @metadata.activationEvents?
+    if @metadata.activationEvents?
       deprecate("""
         Use `activationCommands` instead of `activationEvents` in your package.json
         Commands should be grouped by selector as follows:


Remove unused methods in Project

Remove unused methods in Project

--- src/project.coffee
+++ src/project.coffee
@@ -105,18 +105,6 @@
   getRootDirectory: ->
     @rootDirectory

-  # Public: Determines if a path is ignored via Atom configuration.
-  isPathIgnored: (path) ->
-    for segment in path.split("/")
-      ignoredNames = atom.config.get("core.ignoredNames") or []
-      return true if _.contains(ignoredNames, segment)
-
-    @ignoreRepositoryPath(path)
-
-  # Public: Determines if a given path is ignored via repository configuration.
-  ignoreRepositoryPath: (repositoryPath) ->
-    atom.config.get("core.hideGitIgnoredFiles") and @repo?.isPathIgnored(path.join(@getPath(), repositoryPath))
-
   # Public: Given a uri, this resolves it relative to the project directory. If
   # the path is already absolute or if it is prefixed with a scheme, it is
   # returned unchanged.
@@ -192,12 +180,6 @@
   # Returns an {Array} of {TextBuffer}s.
   getBuffers: ->
     new Array(@buffers.getValues()...)
-
-  isPathModified: (filePath) ->
-    @findBufferForPath(@resolve(filePath))?.isModified()
-
-  findBufferForPath: (filePath) ->
-    _.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath

   # Private: Only to be used in specs
   bufferForPathSync: (filePath) ->


Add missing path require

Add missing path require

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -1,3 +1,5 @@
+path = require 'path'
+
 module.exports = (grunt) ->
   grunt.initConfig
     pkg: grunt.file.readJSON('package.json')


add missing assert

add missing assert


fixed boot path for osx and changed some other settings

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/talvdav/dotfiles.git/'


Add some comments!

Add some comments!

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/demhydraz/til.git/'


Replace directoryExistsSync() with Directory::existsSync().

This makes it possible to remove a TODO in `GitRepositoryProvider`.

--- src/git-repository-provider.coffee
+++ src/git-repository-provider.coffee
@@ -11,7 +11,7 @@
   # can return cached values rather than always returning new objects:
   # getParent(), getFile(), getSubdirectory().
   gitDir = directory.getSubdirectory('.git')
-  if directoryExistsSync(gitDir) and isValidGitDirectorySync gitDir
+  if gitDir.existsSync() and isValidGitDirectorySync gitDir
     gitDir
   else if directory.isRoot()
     return null
@@ -26,19 +26,9 @@
   # To decide whether a directory has a valid .git folder, we use
   # the heuristic adopted by the valid_repository_path() function defined in
   # node_modules/git-utils/deps/libgit2/src/repository.c.
-  return directoryExistsSync(directory.getSubdirectory('objects')) and
+  return directory.getSubdirectory('objects').existsSync() and
       directory.getFile('HEAD').existsSync() and
-      directoryExistsSync(directory.getSubdirectory('refs'))
-
-# Returns a boolean indicating whether the specified directory exists.
-#
-# * `directory` {Directory} to check for existence.
-directoryExistsSync = (directory) ->
-  # TODO: Directory should have its own existsSync() method. Currently, File has
-  # an exists() method, which is synchronous, so it may be tricky to achieve
-  # consistency between the File and Directory APIs. Once Directory has its own
-  # method, this function should be replaced with direct calls to existsSync().
-  return fs.existsSync(directory.getPath())
+      directory.getSubdirectory('refs').existsSync()

 # Provider that conforms to the atom.repository-provider@0.1.0 service.
 module.exports =


JStackTemplate: run generate slug max 20 iterations


Add spec for channel model

Add spec for channel model

error: pathspec 'spec/javascripts/models/channel_spec.coffee' did not match any file(s) known to git

--- spec/javascripts/models/channel_spec.coffee
+++ spec/javascripts/models/channel_spec.coffee
@@ -0,0 +1,3 @@
+ test 'Channel is a DS.Model', ->
+  ok(Dashboard.Channel)
+  ok(DS.Model.detect(Dashboard.Channel))


fix opts reference issue when renderFile is rapidly called async

the local opts somehow references the same object if `renderFile` is called asynchronously with different `opts` args. this causes the very last `opts` arguments to be passed into the compiler for every single call, instead of each discrete set of arguments. we need to deep clone the object to break the reference.

--- lib/adapter_base.coffee
+++ lib/adapter_base.coffee
@@ -9,6 +9,7 @@
     @_render(str, opts)

   renderFile: (file, opts = {}) ->
+    opts = _.clone(opts, true)
     (new File(file))
       .read(encoding: 'utf8')
       .then _.partialRight(@render, _.extend(opts, {filename: file})).bind(@)


More Calculation in Coffee

More Calculation in Coffee

error: pathspec 'Coffeescript/Equations.coffee' did not match any file(s) known to git

--- Coffeescript/Equations.coffee
+++ Coffeescript/Equations.coffee
@@ -0,0 +1,118 @@
+# This is a small set of Classes that will allow fast
+# differentiation and calculation of Mathematical functions
+#
+# TODO: Write a regular text Parser
+#
+
+class Item
+  constructor: () ->
+  evaluate: (vars) -> 0
+  differential: (d) -> this
+  isZero: () -> true
+  isOne: () -> false
+  simplify: () -> this
+
+class Number extends Item
+  constructor: (@value) ->
+  evaluate: (vars) -> value
+  differential: (d) -> new Number(0)
+  isZero: () -> value == 0
+  isOne: () -> value == 1
+  simplify: () -> this
+
+class Variable extends Item
+  constructor: (@name) ->
+  evaluate: (vars) -> vars[name] | 0
+  differential: (d) -> if d == name then new Number(1) else new Number(0)
+  isZero: () -> false
+  isOne: () -> false
+  simplify: () -> this
+
+class Sum extends Item
+  constructor: (@items) ->
+  evaluate: (vars) -> items.reduce((r,i) -> r + i.evaluate(vars))
+  differential: (d) -> (new Sum(items.map((x) -> x.differential(d)))).simplify()
+  isZero: () -> items.reduce(true, (a,x) -> a and x.isZero())
+  isOne: () -> false
+  simplify: () ->
+    newItems = items.map((x) -> x.simplify()).filter((x) -> x != null and !x.isZero())
+    numbers = newItems.filter((x) -> x.constructor == Number)
+    otherSums = newItems.filter((x) -> x.constructor == Sum)
+    rest = newItems.filter((x) -> x.constructor != Number and x.constructor != Sum)
+    newItems = otherSums.reduce([], (r,x) -> r.concat(x))
+    number = numbers.reduce((a,b) -> a + b)
+    newItems.push(number)
+    for item in rest
+      newItems.push(item)
+    if newItems.length == 0
+      new Number(0)
+    else if newItems.length == 1
+      newItems[0]
+    else
+      new Sum(newItems)
+
+class Multiplication extends Item
+  constructor: (@firstInput, @secondInput) ->
+  evaluate: (vars) -> firstInput.evaluate(vars) * secondInput.evaluate(vars)
+  differential: (d) -> (new Sum([new Multiplication(firstInput.differential(d), secondInput), new Multiplication(firstInput, secondInput.differential(d))])).simplify()
+  isZero: () -> firstInput.isZero() or secondInput.isZero()
+  isOne: () -> false
+  simplify: () ->
+    first = firstInput.simplify()
+    second = secondInput.simplify()
+    if first.isZero() or second.isZero()
+      new Number(0)
+    else if first.isOne()
+      second
+    else if second.isOne()
+      first
+    else
+      new Multiplication(first,second)
+
+class PolynomialOp extends Item
+  constructor: (@var, @pow) ->
+  evaluation: (vars) -> this.var.evaluate(vars) ** pow
+  isZero: () -> this.var.isZero()
+  isOne: () -> pow == 0
+  differential: (d) -> (new Multiplication(new Multiplication(this.var.differential(d), pow),new PolynomialOp(this.var, pow - 1))).simplify()
+  simplify: () ->
+    if pow == 0
+      new Number(1)
+    else
+      this
+
+class VarUnderOne extends item
+  constructor: (@var) ->
+  evaluation: (vars) -> 1 / this.var.evaluate(vars)
+  differential: (d) -> (new Multiplication(new Multiplication(new Item(-1), this.var.differential(d)),new PolynomialOp(this.var, new Number(-2)))).simplify()
+  isOne() -> this.var.isOne()
+  isZero() -> false
+  simplify: () ->
+    if this.var.constructor == Number
+      new Number(1/this.var.value)
+    else
+      this
+
+class Log extends Item
+  constructor: (@var) ->
+  evaluation: (vars) -> Math.log(this.var.evaluate(vars))
+  isOne: () -> this.var.constructor == Number and this.var.value == Math.E
+  isZero: () -> this.var.isOne()
+  differential: (d) -> (new Multiplication(new VarUnderOne(this.var), this.var.differential(d))).simplify()
+  simplify: () -> this
+
+class ExponentialOp extends Item ->
+  constructor: (@var, @exp) ->
+  evaluation: (vars) -> (exp ** this.var.evaluate(vars))
+  isZero: () -> exp.isZero()
+  isOne: () -> exp.isOne() or this.var.isZero()
+
+class Function extends Item
+  constructor: (@name, @vars, @item) ->
+  evaluate: (vars) -> item.evaluate(vars)
+  differential: (d) -> new Function(name + "'",vars,item.differential(d))
+
+class Graph
+  constructor: (@name, @f) ->
+  dimensions: () -> f.vars.length + 1
+  axis: (i) -> if i == 0 then f.name else f.vars[i-1]


Added config file

Added config file

error: pathspec 'app/scripts/config.coffee' did not match any file(s) known to git

--- app/scripts/config.coffee
+++ app/scripts/config.coffee
@@ -0,0 +1,2 @@
+define ->
+  API_URL: "#{location.hostname}:4000"


initial commit

initial commit

Have some basics started from just playing around. Spawns a few things,
but doesn't do much

--- src/main.coffee
+++ src/main.coffee
@@ -0,0 +1,69 @@
+LOG = console.log
+
+WORKER_ATTRIBUTES = [Game.MOVE, Game.CARRY, Game.WORK]
+WARRIOR_ATTRIBUTES = [Game.TOUGH, Game.TOUGH, Game.TOUGH, Game.ATTACK, Game.MOVE]
+HEALER_ATTRIBUTES = [Game.TOUGH, Game.HEAL, Game.MOVE, Game.MOVE]
+
+
+for _, spawn of Game.spawns
+  if spawn.spawning
+    continue
+
+  creeps = spawn.room.find(Game.MY_CREEPS)
+  if ((c for c in creeps when c.memory.role == 'harvester').length < 2)
+    LOG("Spawning worker")
+    spawn.createCreep(WORKER_ATTRIBUTES, null, {'role': 'harvester'})
+    continue
+  if ((c for c in creeps when c.memory.role == 'warrior').length == 0)
+    LOG("Spawning warrior")
+    spawn.createCreep(WARRIOR_ATTRIBUTES, null, {'role': 'warrior'})
+    continue
+  if ((c for c in creeps when c.memory.role == 'healer').length == 0)
+    LOG("Spawning healer")
+    spawn.createCreep(HEALER_ATTRIBUTES, null, {'role': 'healer'})
+    continue
+  if (spawn.energy > (spawn.energyCapacity * .8))
+    if ((c for c in creeps when c.memory.role == 'harvester').length > 5)
+      continue
+    LOG("Spawn current energy: #{spawn.energy}. Spawning worker")
+    spawn.createCreep(WORKER_ATTRIBUTES, null, {'role': 'harvester'})
+    continue
+
+closest_spawn = (creep) -> creep.pos.findNearest(Game.MY_SPAWNS)
+
+
+return_to_closest_spawn = (creep) ->
+  creep.moveTo(closest_spawn(creep))
+
+
+harvest_closest_source = (creep) ->
+  closest_source = creep.pos.findNearest(Game.SOURCES)
+  creep.moveTo(closest_source)
+  creep.harvest(closest_source)
+
+
+for _, creep of Game.creeps
+  if creep.getActiveBodyparts(Game.HEAL) > 0
+    hurt_creeps = (c for _, c of Game.creeps when c.hits < c.hitsMax)
+    if hurt_creeps.length == 0
+      creep.moveTo(closest_spawn(creep))
+      continue
+    creep_to_heal = hurt_creeps[0]
+    LOG("#{creep.name} healing #{creep_to_heal.name}")
+    creep.moveTo(creep_to_heal)
+    creep.heal(creep_to_heal)
+    continue
+  if creep.getActiveBodyparts(Game.ATTACK) > 0
+    closest_hostile = creep.pos.findNearest(Game.HOSTILE_CREEPS)
+    if closest_hostile != null
+      LOG("#{creep.name} attacking creep of " +
+          "'#{closest_hostile.owner.username}' at #{closest_hostile.pos}")
+      creep.moveTo(closest_hostile)
+      creep.attack(closest_hostile)
+      continue
+  if creep.memory.role == 'harvester'
+    if creep.energy >= creep.energyCapacity
+      return_to_closest_spawn(creep)
+      creep.transferEnergy(closest_spawn(creep))
+    else
+      harvest_closest_source(creep)