         # and finally, we add up what a user can add (with the maybe negative remainder) and cap at 0
         user_limits = misc.map_max(misc.map_sum(limits, user_current), 0)
         return
-            limits    : user_limits
-            remaining : user_remaining
-            current   : user_current
-            totals    : total_upgrades
+            limits         : user_limits
+            remaining      : user_remaining
+            current        : user_current
+            totals         : total_upgrades
+            proj_remainder : proj_remainder
 
     clear_upgrades: ->
         @set_upgrades('min')

            # the amount displayed remaining subtracts off the amount you type in
            show_remaining = misc.round2(remaining + current - current_input)

            val = @state["upgrade_#{name}"]
            if misc.parse_number_input(val)?
                if not @is_upgrade_input_valid(Math.max(val, 0), limit)
                    reasons = []
                    if val > remaining + current then reasons.push('not enough upgrades')
                    if val > limit then reasons.push('exceeding limit')
                    reason = reasons.join(' and ')
                    bs_style = 'error'
                    label = <div style={UPGRADE_ERROR_STYLE}>Value too high: {reason}</div>

    render_addon: (misc, name, display_unit, limit) ->
        <div style={minWidth:'81px'}>{"#{misc.plural(2,display_unit)}"} {@render_max_button(name, limit)}</div>

    render_upgrade_row: (name, data, remaining=0, current=0, limit=0, total=0, proj_remainder=0) ->
        if not data?
            return

