                 val
 
             elem.on 'keyup', (event) ->
+              # record that a ctrl key has been released
+              unregisterCtrl(scope) if isCtrl(event)
 
               return if invalidInput(elem, event)
 

            elem.on 'keydown', (event) ->
              keycode = event.which

              killEvent(event) unless isInertKey(keycode)

              return if invalidInput(elem, event)
              # unless isControlKey(keycode)
                # return if maxDigitsReached(event, 9) 
              
              initialPosition = elem[0].selectionStart 

              if keycode >= 48 and keycode <= 57 # insert number character
                unless maxDigitsReached(elem, 9)
                  newCursorPosition = findNewCharacterCursorPosition(elem, initialPosition)
                  insertCharacter(elem, event)
                  elem.val resetCommas(elem.val()) # reformat the number in place
                  elem[0].setSelectionRange(newCursorPosition, newCursorPosition) # set the new cursor position
                  triggerChange(elem)

              if keycode == 8 # backspace is pressed

                if elem[0].selectionEnd > elem[0].selectionStart # text is highlighted
                  # get the string before the selection and figure out how many commas it has
                  originalCursorPosition = elem[0].selectionStart
                  stringBeforeCursor = elem.val().slice(0, originalCursorPosition)
                  startingCommasBeforeCursor = (stringBeforeCursor.match(/,/g) || []).length

                  # delete the selected stuff and reset the commas
                  deleteSelectedRange(elem, event)
                  elem.val resetCommas(elem.val()) # reformat the number in place

                  # figure out how many commas were lost
                  finalStringBeforeCursor = elem.val().slice(0, originalCursorPosition)
                  endingCommasBeforeCursor = (finalStringBeforeCursor.match(/,/g) || []).length
                  commaDiff = startingCommasBeforeCursor - endingCommasBeforeCursor

                  # set the final cursor position
                  finalCursorPosition = originalCursorPosition - commaDiff
                  elem[0].setSelectionRange(finalCursorPosition, finalCursorPosition) # set the new cursor position

                  # trigger final change event
                  triggerChange(elem)

                else unless elem[0].selectionStart == 0 # do nothing if it's at the end of the end of the input
                  newCursorPosition = findNewBackspaceCursorPosition(elem, initialPosition)
                  backspacePressed(elem, event) # handle logic for backspace
                  elem.val resetCommas(elem.val()) # reformat the number in place
                  elem[0].setSelectionRange(newCursorPosition, newCursorPosition) # set the new cursor position

                  # trigger final change event
                  triggerChange(elem)
              
              if keycode == 46 # delete is pressed
                if elem[0].selectionEnd > elem[0].selectionStart # text is highlighted
                  # get the string before the selection and figure out how many commas it has
                  originalCursorPosition = elem[0].selectionStart
                  stringBeforeCursor = elem.val().slice(0, originalCursorPosition)
                  startingCommasBeforeCursor = (stringBeforeCursor.match(/,/g) || []).length

                  # delete the selected stuff and reset the commas
                  deleteSelectedRange(elem, event)
                  elem.val resetCommas(elem.val()) # reformat the number in place

                  # figure out how many commas were lost
                  finalStringBeforeCursor = elem.val().slice(0, originalCursorPosition)
                  endingCommasBeforeCursor = (finalStringBeforeCursor.match(/,/g) || []).length
                  commaDiff = startingCommasBeforeCursor - endingCommasBeforeCursor

                  # set the final cursor position
                  finalCursorPosition = originalCursorPosition - commaDiff
                  elem[0].setSelectionRange(finalCursorPosition, finalCursorPosition) # set the new cursor position

                  # trigger final change event
                  triggerChange(elem)

                else unless elem[0].selectionStart == elem.val().length
                  newCursorPosition = findNewDeleteCursorPosition(elem, initialPosition)
                  deletePressed(elem, event) # handle logic for backspace
                  elem.val resetCommas(elem.val()) # reformat the number in place
                  elem[0].setSelectionRange(newCursorPosition, newCursorPosition) # set the new cursor position

                  # trigger final change event
                  triggerChange(elem)
              
            elem.on 'keypress', (event) ->
              killEvent(event)

    {
        restrict: 'A'
        require: 'ngModel'
        scope: {
        }
        link: (scope, elem, attrs, ngModelCtrl) ->
            options = getOptions scope, attrs
            isValid = makeIsValid options
            reformatRequired = false
            scope.ctrlDownCount = 0

            ngModelCtrl.$parsers.unshift (viewVal) ->
                noCommasVal = viewVal.replace /,/g, ''
