         ; mentioned above, they might have calculated their new intervals based on stale information.
         ; calculating intervals is idempotent and has no second-order effects so it is fine to do it repeatedly
         ; and it also suffices to do it a single time once all the HAs are updated with new times, values and flows.
-        deps (into #{} (filter (fn [k] (some transitioned-ids (ha-dependencies (get has k)))) (keys has)))
+        deps (into #{} (filter (fn [k]
+                                 (some transitioned-ids (ha-dependencies (get has k))))
+                               (keys has)))
         reenter-has (map #(let [ha (get has %)]
                            (enter-state has ha (:state ha) t))
                          deps)]
     #_(println "next transitions" #_reenter-has (transition-intervals has
-                                                                      (second reenter-has)
-                                                                      Infinity
-                                                                      (required-transitions (second reenter-has))))
+                                                                    (second reenter-has)
+                                                                    Infinity
+                                                                    (required-transitions (second reenter-has))))
     (merge has (zipmap (map :id reenter-has) reenter-has))))
 
-(defn update-scene [scene now inputs]
+(defn update-scene [scene now inputs bailout]
+  (assert (<= bailout 100) "Recursed too deeply in update-scene")
   (let [qthen (floor-time (:now scene) time-unit)
         qnow (floor-time now time-unit)
         has (:objects scene)

        v2k (if (= (count simple-guard) 4) (third simple-guard) nil)
        [v10 v1f] (get-var-and-flow has ha v1k)
        [v20 v2f] (get-var-and-flow has ha v2k)
        ; _ (println (str "(" v10 " + " v1f "t) - (" v20 " + " v2f "t) " (case rel :gt ">" :geq ">=" :leq "<=" :lt "<") " " c))
        ; by algebra: A0+fA*dt-B0-fB*dt-C~0 --> (fA-fB)*dt ~ (-A0 + B0 + C) --> dt ~ (-A0 + B0 + C)/(fA-fB)
        denom (- v1f v2f)
        rhs (/ (+ (- v10) v20 c)
               denom)
        ; since we are dividing by denom, flip rel if denom (a constant) < 0
        rel (if (< denom 0)
              (case rel
                :gt :lt
                :geq :leq
                :leq :geq
                :lt :gt)
              rel)
        ; t REL rhs
        entry-time (:entry-time ha)
        ; _ (println (:id ha) simple-guard "et" entry-time "push up" time-unit rhs "to" (+ entry-time time-unit) (+ entry-time rhs))
        min-t (+ entry-time time-unit)
        rhs (+ entry-time rhs)]
    (assert (not (nil? v10))

                                      sx (* scale (:x (extrapolate ha s)))
                                      ex (* scale (:x (extrapolate ha e)))
                                      line-top (+ (* i line-h) (* j trans-h))]
                                  [:div {:style {:height        trans-h :width (.abs js/Math (- sx ex))
                                                 :top           line-top :left (.min js/Math sx ex)
                                                 :position      "absolute" :backgroundColor "grey"
                                                 :pointerEvents "none"}}
                                   [:div {:style {:position        "absolute"
                                                  :width           "100px"
                                                  :backgroundColor "rgba(255,255,255,0.5)"
                                                  :pointerEvents   "none"}}
                                    (str (:id ha) "-" (:target (:transition trans)))]
                                   [:div {:style {:height          "100%" :width "2px"
                                                  :position        "absolute" :left (if (< sx ex) "0%" "100%")
                                                  :backgroundColor "green"
                                                  :pointerEvents   "none"}}]
                                   [:div {:style {:height          "100%" :width "2px"
                                                  :position        "absolute" :left (if (< sx ex) "100%" "0%")
                                                  :backgroundColor "red"
                                                  :pointerEvents   "none"}}]]))
                              (transition-intervals (:objects @scene)
                                                    ha
                                                    Infinity
