 
 (defn champion-select []
   [:div.media
-   [:div.media-left (champion-image)]
+   [:div.media-left [champion-image]]
    [:div.media-body
     [:h4.media-heading "Make a build for:"]
     [:select {:value (:id (:champ @app))
-              :on-change (fn [event]
-                           (swap! app
-                                  #(assoc %1 :champ (get-in %1 [:champs %2]))
-                                  (keyword (-> event .-target .-value))))}
-     (for [[id ch] (sort-by (comp :name val) (:champs @app))]
-       [:option {:key id :value id} (:name ch)])]]])
+                   :on-change (fn [event]
+                                (swap! app
+                                       #(assoc %1 :champ (get-in %1 [:champs %2]))
+                                       (keyword (-> event .-target .-value))))}
+        (for [[id ch] (sort-by (comp :name val) (:champs @app))]
+          [:option {:key id :value id} (:name ch)])]]])
 
 (defn item-select [idx item]
   [:select {:value (:id item)

                                                {:id "2004" :count 1}
                                                {:id "3340" :count 1}]}]}}))

(go
  (let [champ-chan (data/champ-chan)
        item-chan (data/item-chan)
        champs (<! champ-chan)
        items (<! item-chan)]
    (swap! app assoc :items items :champs champs :champ (val (first champs)))))

(defn recommend []
  (let [{:keys [items num-items champ champ-level props]} @app

             :value (key @app)
             :on-change #(swap! app assoc key (int (-> % .-target .-value)))}]]])

(def stats
  "A vector of maps
  :name - The user friendly name of the stat
  :calc - A function that takes a champion, champion level, and item
  set, and returns the raw value of that stat.
  :pretty - A function that takes the raw value of a stat and returns
  a user friendly value (i.e. adds a % sign if appropriate). Optional,
  default is the \"int\" function."
  [{:name "Attack damage (AD)"
    :calc algo/attack-damage
    :optimizable true}
   {:name "Critical strike chance"
    :calc algo/critical-strike
    :pretty (fn [n] (str (int (* 100 n)) "%"))}
   {:name "Attack speed"
    :calc algo/attack-speed
    :pretty (fn [n] (.toFixed n 2))}
   {:name "Physical damage per second (DPS)"
    :calc algo/build-dps
    :optimizable true}

   {:name "Life steal"
    :calc (algo/item-wrapper algo/life-steal)
    :pretty (fn [n] (str (int (* 100 n)) "%"))}
   {:name "Life stolen per second"
    :calc algo/build-lsps
    :optimizable true}

   {:name "Ability power (AP)"
    :calc (algo/item-wrapper algo/ability-power)
    :optimizable true}

   {:name "Health"
    :calc algo/health}
   {:name "Armor"
    :calc algo/armor}
   {:name "Magic resist"
    :calc algo/magic-resist}
   {:name "Effective health (physical)"
    :calc algo/build-hp-ad
    :optimizable true}
   {:name "Effective health (magic)"
    :calc algo/build-hp-ap
    :optimizable true}

   {:name "Mana"
    :calc algo/mana
    :optimizable true}
   {:name "Mana regen over 5 seconds"
    :calc algo/mana-regen
    :optimizable true}])

(defn build-stats []
  (let [{:keys [recommended champ champ-level]} @app]
    [:div.panel.panel-primary
     [:div.panel-heading "Build statistics"]
     (into [:table.table
            [:tr [:th "Stat"] [:th "Value"]]]
           (for [{:keys [name calc pretty] :as stat} stats
                 :let [stat-optimized? (contains? (:props @app) name)]]
             [(if stat-optimized?
                :tr.info
                :tr)
              [:td (cond-> name
                     stat-optimized? (as-> el [:b el]))]
              [:td (cond-> (calc champ champ-level recommended)
                     (not pretty) int
                     pretty pretty
                     stat-optimized? (as-> el [:b el]))]]))]))

(defn item-block [id block all-items]
  (let [items (map #(get all-items (int (:id %))) (:items block))]
