               (concat (rest (map call->function mapped-frames)) [{}])))))))
 
 (defn mapped-stacktrace-str
-  "Given a vector representing the canonicalized JavaScript stacktrace
-   print the ClojureScript stacktrace. See mapped-stacktrace."
-  ([stacktrace sm]
-   (mapped-stacktrace-str stacktrace sm nil))
-  ([stacktrace sm opts]
+  "Given a vector representing the canonicalized JavaScript stacktrace and a map
+  of library names to decoded source maps, print the ClojureScript stacktrace .
+  See mapped-stacktrace."
+  ([stacktrace sms]
+   (mapped-stacktrace-str stacktrace sms nil))
+  ([stacktrace sms opts]
    (with-out-str
      (doseq [{:keys [function file line column]}
-             (mapped-stacktrace stacktrace sm opts)]
+             (mapped-stacktrace stacktrace sms opts)]
        (println "\t"
          (str (when function (str function " "))
               "(" file (when line (str ":" line))

;; -----------------------------------------------------------------------------
;; Stacktrace Mapping

(defn mapped-line-column-call
  "Given a cljs.source-map source map data structure map a generated line
   and column back to the original line, column, and function called."
  [source-map line column]
  ;; source maps are 0 indexed for columns
  ;; multiple segments may exist at column
  ;; the last segment seems most accurate
  (letfn [(get-best-column [columns column]
            (last (or (get columns
                        (last (filter #(<= % (dec column))
                                (sort (keys columns)))))
                      (second (first columns)))))
          (adjust [mapped]
            (vec (map #(%1 %2) [inc inc identity] mapped)))]
    (let [default [line column nil]]
      ;; source maps are 0 indexed for lines
      (if-let [columns (get source-map (dec line))]
        (adjust (map (get-best-column columns column) [:line :col :name]))
        default))))

(defn mapped-frame
  "Given opts and a canonicalized JavaScript stacktrace frame, return the
  ClojureScript frame."
  [{:keys [function file line column]} sm opts]
  (let [no-source-file?      (if-not file true (starts-with? file "<"))
        [line' column' call] (mapped-line-column-call sm line column)
        file'                (if (ends-with? file ".js")
                               (str (subs file 0 (- (count file) 3)) ".cljs")
                               file)]
    {:function function
     :call     call
     :file     (if no-source-file?

   identifier delimited by angle brackets. The returned mapped stacktrace will
   also contain :url entries to the original sources if it can be determined
   from the classpath."
  ([stacktrace sms]
   (mapped-stacktrace stacktrace sms nil))
  ([stacktrace sms opts]
   (letfn [(call->function [x]
             (if (:call x)
               (hash-map :function (:call x))
