   (:require [c2.layout.histogram :refer [histogram]]
             [c2.scale :as scale]
             [c2.svg :as svg]
-            #+clj [clj-time.format :as tf]
-            #+clj [clj-time.coerce :as tc]
-            #+cljs [cljs-time.format :as tf]
-            #+cljs [cljs-time.coerce :as tc]
-            #+clj [clojure.math.numeric-tower :refer [gcd lcm floor ceil abs]]
-            #+cljs [hatti.maths :refer [gcd lcm floor ceil abs]]
-            #+cljs [hatti.utils :refer [format]]
+            [#?(:clj  clj-time.format
+                :cljs cljs-time.format) :as tf]
+            [#?(:clj  clj-time.coerce
+                :cljs cljs-time.coerce) :as tc]
+            [#? (:clj clojure.math.numeric-tower
+                :cljs hatti.maths) :refer [gcd lcm floor ceil abs]]
+            #?(:cljs [hatti.utils :refer [format]])
             [hatti.ona.forms :as f]
             [clojure.string :refer [join blank?]]))
 

   Optional digits parameter = number of digits after decimal, default is 1."
  (let [int-fmt-s (str "%." digits "f")
        d->millis #(* millis-in-day %)
        date->str #+clj #(tf/unparse (tf/formatters :year-month-day)
                                     (tc/from-long  %))
                  #+cljs #(.format (js/moment %) "ll")]
    (case typ
      "int" #(format int-fmt-s (float %))
      "date" #(date->str (d->millis %)))))

(defn range->str [[mn mx] typ]

    (if (<= mx mn) (fmt mn)
      (join " to " [(fmt mn) (fmt mx)]))))

#?(:cljs
   (defn evenly-spaced-bins
     "Given a list of answers, returns each one as a bin, in string form.
   nil is mapped to nil. The bins, in order, are returned as metadata.
   eg. (evenly-spaced-bins [1 2 10] 5 'int') => ['1 to 2' '1 to 2' '9 to 10']
   metadata of this above value would be:
   {:bins ['1 to 2', '3 to 4', '5 to 6', '7 to 8', '9 to 10']}"
     [answers bins typ]
     (let [numbers (map (str->int typ) answers)
           mx (reduce max (remove nil? numbers))
           mn (reduce min (remove nil? numbers))
           s (scale/linear :domain [mn mx] :range [0 (- bins (/ 1 10000))])
           is (map safe-floor (map #(when % (s %)) numbers))
           t (scale/linear :domain [0 bins] :range [mn mx])
           lbounds (->> (range bins) (map t) (map float) distinct)
           ubounds (conj (mapv #(if (= % (safe-floor %))
                                  (dec %) %) (drop 1 lbounds)) mx)
           fmt (int->str typ :digits 0)
           strings (mapv #(range->str [%1 %2] typ) lbounds ubounds)
           results (map (fn [i] (when i (get strings (int i)))) is)
           strings (-> strings distinct vec)] ; remove repeats before output
       (with-meta results
         {:bins (if (contains? (set answers) nil)
                  (conj strings nil) strings)}))))

(defn label-count-pairs
  "Take chart-data from the ona API, returns label->count map.
