       new-db)))
 
 
-(defn undoable
-  "Middleware which stores an undo checkpoint."
-  [handler]
-  (fn undoable-handler
-    [app-db event-vec]
-    (store-now!)
-    (handler app-db event-vec)))
-
 
 (defn trim-v
   "Middleware which removes the first element of v which allows you to write



(defn path
  "Supplies a sub-tree of `db` to the handler. A narrowed view.
  Assumes \"pure\" is in the middleware pipeline prior.
  Grafts the result back into db.
  If a get-in of the path results in a nil, then \"default-fn\" will be called to supply a value.

        (let [val (get-in db p)
              val (if (nil? val) (default-fn) val)]
          (assoc-in db p (handler val v)))))))


(defn undoable
  "A Middleware factory which stores an undo checkpoint.
  \"explanation\" can be either a string or a function. If it is a
  function then it must be:  (db event-vec) -> string.
  \"explanation\" can be nil. in which case no
  "
  [explanation]
  (fn middleware
    [handler]
    (fn undoable-handler
      [db event-vec]
      (let [explanation (cond
                          (fn? explanation)     (explanation db event-vec)
                          (string? explanation) explanation
                          (nil? explanation)    ""
                          :else (warn "re-frame: undoable given bad parameter. Got: " explanation))]
      (store-now! explanation)
      (handler db event-vec)))))


(defn enrich
