rework Off-Campus Apt to support checking for uniqueness

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -506,11 +506,15 @@

    "Off-Campus Apartment"
    {:abilities [{:label "Install and host a connection on Off-Campus Apartment"
-                 :cost [:click 1] :prompt "Choose a connection in your Grip to install on Off-Campus Apartment"
-                 :choices {:req #(and (has-subtype? % "Connection")
-                                      (in-hand? %))}
-                 :msg (msg "host " (:title target) " and draw 1 card")
-                 :effect (effect (runner-install target {:host-card card}) (draw))}
+                 :effect (effect (resolve-ability
+                                   {:cost [:click 1]
+                                    :prompt "Choose a connection in your Grip to install on Off-Campus Apartment"
+                                    :choices {:req #(and (has-subtype? % "Connection")
+                                                         (runner-can-install? state side % false)
+                                                         (in-hand? %))}
+                                    :msg (msg "host " (:title target) " and draw 1 card")
+                                    :effect (effect (runner-install target {:host-card card}) (draw))}
+                                  card nil))}
                 {:label "Host an installed connection"
                  :prompt "Choose a connection to host on Off-Campus Apartment"
                  :choices {:req #(and (has-subtype? % "Connection")


add wait prompt and improved messaging to Woman in the Red Dress

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -766,11 +766,17 @@
    "Woman in the Red Dress"
    {:events {:runner-turn-begins
              {:msg (msg "reveal " (:title (first (:deck corp))) " on the top of R&D")
-              :optional {:player :corp
-                         :prompt (msg "Draw " (:title (first (:deck corp))) "?")
-                         :msg (msg "draw " (:title (first (:deck corp))))
-                         :yes-ability {:effect (effect (draw))}
-                         :no-ability {:effect (effect (system-msg "doesn't draw with Woman in the Red Dress"))}}}}}
+              :effect (effect (show-wait-prompt :runner "Corp to decide whether or not to draw with Woman in the Red Dress")
+                              (resolve-ability
+                                {:optional
+                                 {:player :corp
+                                  :prompt (msg "Draw " (:title (first (:deck corp))) "?")
+                                  :yes-ability {:effect (effect (clear-wait-prompt :runner)
+                                                                (system-msg (str "draws " (:title (first (:deck corp)))))
+                                                                (draw))}
+                                  :no-ability {:effect (effect (clear-wait-prompt :runner)
+                                                               (system-msg "doesn't draw with Woman in the Red Dress"))}}}
+                               card nil))}}}

    "Wyldside"
    {:events {:runner-turn-begins {:msg "draw 2 cards and lose [Click]"


check if card is installed by finding it in all-installed

--- src/clj/game/core-installing.clj
+++ src/clj/game/core-installing.clj
@@ -43,7 +43,7 @@
    (unregister-events state side card)
    (when (and (:memoryunits card) (:installed card) (not (:facedown card)))
      (gain state :runner :memory (:memoryunits card)))
-   (when (:installed card)
+   (when (find-cid (:cid card) (all-installed state side))
      (when-let [in-play (:in-play (card-def card))]
        (apply lose state side in-play)))
    (dissoc-card card keep-counter)))


Add a comment why parallel execution is not faster

in this particular case: substring.pl takes the most time. For the old
spelling however it is very quick. In other words if you let the snail
and the rabbit race in parallel it will not be much faster than if
they run in sequence. You basically still just wait for the snail.

--- src/clj/hyphen_keeper/export.clj
+++ src/clj/hyphen_keeper/export.clj
@@ -47,6 +47,10 @@
       (.write w word)
       (.newLine w))))

+;; I tried to run this in parallel (simply by using (dorun (pmap))
+;; instead of (doseq)) but as it turns out the jobs are so uneven,
+;; i.e. the first one is very small compared to the second one, we end
+;; up waiting the same time.
 (defn export []
   (let [program (.getAbsolutePath (io/file (io/resource "perl/substrings.pl")))]
     (doseq [[spelling [white-list dictionary original]] dictionaries]


Dashboard, fix bdb5552d2e

Dashboard, fix bdb5552d2e

--- src/clj/salava/social/routes.clj
+++ src/clj/salava/social/routes.clj
@@ -1,9 +1,12 @@
 (ns salava.social.routes
   (:require [compojure.api.sweet :refer :all]
+            [clojure.string :as string]
             [ring.util.http-response :refer :all]
+            [ring.util.response :refer [redirect]]
             [salava.core.layout :as layout]
             [schema.core :as s]
             [salava.core.access :as access]
+            [salava.core.util :refer [get-base-path]]
             [salava.social.db :as so]
             [salava.user.db :as u]
             [salava.factory.db :as f]
@@ -14,7 +17,8 @@
 (defn route-def [ctx]
   (routes
    (context "/social" []
-            (GET "/" []
+
+            (GET "/" req
                  :no-doc true
                  :summary ""
                  :auth-rules access/signed


Add tests for Genetics Cards and Gene Conditioning Shoppe

Adjusted Chronotype:
    lose 1 click and gain 1 click (no GCS)
    lose 2 clicks and gain 1 click (no GCS)
    lose 2 clicks and gain 2 clicks (GCS)
    lose 3 clicks and gain 2 clicks (GCS)

Symmetrical Visage:
    click-draw 2 times and gain 2 credits (GCS)
    click-draw 3 times and gain 2 credits (GCS)

Synthetic Blood:
    take damage once and draw 1 card (no GCS)
    take damage twice and draw 1 card (no GCS)
    take damage once and draw 1 card (GCS)
    take damage twice and draw 2 cards (GCS)

Enhanced Vision: Not sure how to test expose effects, but uses same
mechanics as Symm and Synth, so should be fine. Tested manually.

Gene Conditioning Shoppe
    :triggers-twice flag evals to false when not installed
    :triggers-twice flag evals to true when installed
    :triggers-twice flag evals to false when trashed
    :triggers-twice flag remains true when one of two copies is trashed

--- src/clj/test/cards-resources.clj
+++ src/clj/test/cards-resources.clj
@@ -1,4 +1,39 @@
 (in-ns 'test.core)
+
+(deftest adjusted-chronotype
+  "Ensure adjusted chronotype gains only 1 click when 2 clicks are lost"
+  (do-game
+   (new-game (default-corp) (default-runner [(qty "Adjusted Chronotype" 1) (qty "Beach Party" 2)]))
+   (take-credits state :corp)
+   (play-from-hand state :runner "Adjusted Chronotype")
+   (play-from-hand state :runner "Beach Party")
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (is (= 4 (:click (get-runner))) "Should have lost 1 click and gained 1 click")
+   (play-from-hand state :runner "Beach Party")
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (is (= 3 (:click (get-runner))) "Should have lost 2 clicks and gained 1 click")))
+
+(deftest adjusted-chronotype-gcs
+  "Ensure adjusted chronotype gains 2 clicks when 2 clicks are lost and GCS is installed"
+  (do-game
+   (new-game (default-corp) (default-runner [(qty "Adjusted Chronotype" 1) (qty "Beach Party" 3) (qty "Gene Conditioning Shoppe" 1)]))
+   (take-credits state :corp)
+   (play-from-hand state :runner "Adjusted Chronotype")
+   (play-from-hand state :runner "Beach Party")
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (is (= 4 (:click (get-runner))) "Should have lost 1 click and gained 1 click")
+   (play-from-hand state :runner "Beach Party")
+   (play-from-hand state :runner "Gene Conditioning Shoppe")
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (is (= 4 (:click (get-runner))) "Should have lost 2 clicks and gained 2 clicks")
+   (play-from-hand state :runner "Beach Party")
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (is (= 3 (:click (get-runner))) "Should have lost 3 clicks and gained 2 clicks")))

 (deftest daily-casts
   "Play and tick through all turns of daily casts"
@@ -72,6 +107,41 @@
       (card-ability state :runner fc 1)
       (is (= 1 (count (:scored (get-runner)))) "Agenda added to runner scored")
       (is (= 3 (count (:hand (get-runner)))) "No damage dealt"))))
+
+(deftest gene-conditioning-shoppe
+  "Gene Conditioning Shoppe - set :genetics-trigger-twice flag"
+  (do-game
+   (new-game (default-corp [(qty "Hedge Fund" 3)])
+             (default-runner [(qty "Gene Conditioning Shoppe" 1) (qty "Adjusted Chronotype" 1)]))
+   (take-credits state :corp)
+   (play-from-hand state :runner "Adjusted Chronotype")
+   (let [adjusted-chronotype (get-in @state [:runner :rig :resource 0])]
+     (is (not (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice)))
+     (play-from-hand state :runner "Gene Conditioning Shoppe")
+     (is (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice))
+     (core/trash state :runner (get-in @state [:runner :rig :resource 1]))
+     (is (not (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice))))))
+
+(deftest gene-conditioning-shoppe-redundancy
+  "Gene Conditioning Shoppe - set :genetics-trigger-twice flag - ensure redundant copies work"
+  (do-game
+   (new-game (default-corp [(qty "Hedge Fund" 3)])
+             (default-runner [(qty "Gene Conditioning Shoppe" 2) (qty "Adjusted Chronotype" 1)]))
+   (take-credits state :corp)
+   (take-credits state :runner)
+   (take-credits state :corp)
+   (play-from-hand state :runner "Adjusted Chronotype")
+   (let [adjusted-chronotype (get-in @state [:runner :rig :resource 0])]
+     (is (not (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice)))
+     (play-from-hand state :runner "Gene Conditioning Shoppe")
+     (play-from-hand state :runner "Gene Conditioning Shoppe")
+     (let [gcs1 (get-in @state [:runner :rig :resource 1])
+           gcs2 (get-in @state [:runner :rig :resource 2])]
+       (is (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice))
+       (core/trash state :runner gcs1)
+       (is (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice))
+       (core/trash state :runner gcs2)
+       (is (not (core/persistent-flag? state :runner adjusted-chronotype :triggers-twice)))))))

 (deftest ice-carver
   "Ice Carver - lower ice strength on encounter"
@@ -351,6 +421,68 @@
     (core/click-draw state :runner nil)
     (is (= 4 (:credit (get-runner))) "No credit gained from second click spent to draw")))

+(deftest symmetrical-visage-gcs
+  "Symmetrical Visage - Gain 1 credit the first and second time you click to draw each turn when GCS is installed"
+  (do-game
+   (new-game (default-corp) (default-runner [(qty "Symmetrical Visage" 3) (qty "Gene Conditioning Shoppe" 3) (qty "Fall Guy" 1)]))
+   (take-credits state :corp)
+   (core/gain state :runner :click 1)
+   (play-from-hand state :runner "Symmetrical Visage")
+   (is (= 3 (:credit (get-runner))))
+   (play-from-hand state :runner "Gene Conditioning Shoppe")
+   (is (= 1 (:credit (get-runner))))
+   (core/click-draw state :runner nil)
+   (is (= 2 (:credit (get-runner))) "Gained 1 credit from first click spent to draw")
+   (core/click-draw state :runner nil)
+   (is (= 3 (:credit (get-runner))) "Gained 1 credit from second click spent to draw with Gene Conditioning Shoppe")
+   ; Move Fall Guy back to deck
+   (core/move state :runner (find-card "Fall Guy" (:hand (get-runner))) :deck)
+   (core/click-draw state :runner nil)
+   (is (= 3 (:credit (get-runner))) "No credit gained from third click spent to draw with Gene Conditioning Shoppe")))
+
+(deftest synthetic-blood
+  "Synthetic Blood - The first time you take damage each turn, draw one card"
+  (do-game
+   (new-game (default-corp [(qty "Data Mine" 3) (qty "Hedge Fund" 3)])
+             (default-runner [(qty "Synthetic Blood" 3) (qty "Sure Gamble" 3) (qty "Fall Guy" 1)]))
+   (play-from-hand state :corp "Data Mine" "HQ")
+   (play-from-hand state :corp "Data Mine" "HQ")
+   (take-credits state :corp)
+   (let [first-dm (get-in @state [:corp :servers :hq :ices 1])
+         second-dm (get-in @state [:corp :servers :hq :ices 0])]
+     (play-from-hand state :runner "Synthetic Blood")
+     (core/click-run state :runner {:server "HQ"})
+     (core/rez state :corp first-dm)
+     (card-ability state :corp first-dm 0)
+     (is (= 4 (count (:hand (get-runner)))) "1 card drawn when receiving damage (1st time)")
+     (core/no-action state :corp nil)
+     (core/continue state :runner nil)
+     (core/rez state :corp second-dm)
+     (card-ability state :corp second-dm 0)
+     (is (= 3 (count (:hand (get-runner)))) "no card drawn when receiving damage (2nd time)"))))
+
+(deftest synthetic-blood-gcs
+  "Synthetic Blood - The first and second time you take damage each turn (with GCS installed), draw one card"
+  (do-game
+   (new-game (default-corp [(qty "Data Mine" 3) (qty "Hedge Fund" 3)])
+             (default-runner [(qty "Synthetic Blood" 3) (qty "Sure Gamble" 1) (qty "Gene Conditioning Shoppe" 3)]))
+   (play-from-hand state :corp "Data Mine" "HQ")
+   (play-from-hand state :corp "Data Mine" "HQ")
+   (take-credits state :corp)
+   (let [first-dm (get-in @state [:corp :servers :hq :ices 1])
+         second-dm (get-in @state [:corp :servers :hq :ices 0])]
+     (play-from-hand state :runner "Synthetic Blood")
+     (play-from-hand state :runner "Gene Conditioning Shoppe")
+     (core/click-run state :runner {:server "HQ"})
+     (core/rez state :corp first-dm)
+     (card-ability state :corp first-dm 0)
+     (is (= 3 (count (:hand (get-runner)))) "1 card drawn when receiving damage (1st time)")
+     (core/no-action state :corp nil)
+     (core/continue state :runner nil)
+     (core/rez state :corp second-dm)
+     (card-ability state :corp second-dm 0)
+     (is (= 3 (count (:hand (get-runner)))) "1 card drawn when receiving damage (2nd time)"))))
+
 (deftest the-supplier-ability
   "The Supplier - Ability"
   (do-game


add liabilities + equity line to balance sheet

[Fixes #137669567]

--- src/clj_money/models/reports.clj
+++ src/clj_money/models/reports.clj
@@ -127,18 +127,21 @@
   (let [summary (->> groups
                      (map (juxt :type :value))
                      (into {}))
-        retained (- (:income summary) (:expense summary))]
-    (->> groups
-         (map (fn [entry]
-                (if (= :equity (:type entry))
-                  (-> entry
-                      (update-in [:accounts] #(conj % {:name "Retained Earnings"
-                                                       :balance retained
-                                                       :children-balance 0}))
-                      (update-in [:value] #(+ %1 retained)))
-                  entry)))
-         (remove #(#{:income :expense} (:type %)))
-         (mapcat transform-account-group))))
+        retained (- (:income summary) (:expense summary))
+        records (->> groups
+                     (map (fn [entry]
+                            (if (= :equity (:type entry))
+                              (-> entry
+                                  (update-in [:accounts] #(conj % {:name "Retained Earnings"
+                                                                   :balance retained
+                                                                   :children-balance 0}))
+                                  (update-in [:value] #(+ %1 retained)))
+                              entry)))
+                     (remove #(#{:income :expense} (:type %)))
+                     (mapcat transform-account-group))]
+    (concat records [{:caption "Liabilities + Equity"
+                      :value (+ retained (:equity summary) (:liability summary))
+                      :style :summary}])))

 (defn balance-sheet
   "Returns the data used to populate a balance sheet report"


Remove prn

Remove prn

--- src/cljs/clojuredocs/sticky.cljs
+++ src/cljs/clojuredocs/sticky.cljs
@@ -50,7 +50,6 @@
                     left-margin (computed-style $parent :margin-left)
                     right-margin (computed-style $parent :margin-right)
                     width (- width left-padding right-padding left-margin right-margin)]
-                (prn (- (offset-top $el) px-offset))
                 (swap! starting-offset (fn [v]
                                          (if v
                                            v


Leave out alphabetic board option

Leave out alphabetic board option

--- src/cljs/db_quiz/components.cljs
+++ src/cljs/db_quiz/components.cljs
@@ -284,19 +284,24 @@
   []
   (let [selectors {:cs [[:persons :home.domains/persons]
                         [:places :home.domains/places]
+                        [:films :home.domains/films]
                         [:works :home.domains/works]
                         [:born-in-brno :home.domains/born-in-brno]
                         [:ksc-members :home.domains/ksc-members]
                         [:uncertain-death :home.domains/uncertain-death]
                         [:artists :home.domains/artists]
                         [:politicians :home.domains/politicians]
-                        [:musicians :home.domains/musicians]
-                        [:films :home.domains/films]]
+                        [:musicians :home.domains/musicians]]
                    :en [[:persons :home.domains/persons]
                         [:places :home.domains/places]
+                        [:films :home.domains/films]
                         [:companies :home.domains/companies]
                         [:software :home.domains/software]
-                        [:languages :home.domains/languages]]}]
+                        [:plants :home.domains/plants]
+                        [:languages :home.domains/languages]
+                        [:musicians :home.domains/musicians]
+                        [:insects :home.domains/insects]
+                        [:soccer-players :home.domains/soccer-players]]}]
     (fn []
       (let [language (:language @app-state)]
         [multi-select [:options :selectors]
@@ -311,8 +316,7 @@
 (defn dbpedia-options
   []
   [:div [selector-picker]
-        [difficulty-picker]
-        [field-labelling]])
+        [difficulty-picker]])

 (def advanced-options
   (let [id [:options :data-source]


badge-grid

badge-grid

--- src/cljs/salava/badge/ui/my.cljs
+++ src/cljs/salava/badge/ui/my.cljs
@@ -1,21 +1,22 @@
 (ns salava.badge.ui.my
   (:require
-            [reagent.core :refer [atom]]
-            [reagent.session :as session]
-            [reagent-modals.modals :as m]
-            [clojure.set :as set :refer [intersection]]
-            [clojure.string :refer [upper-case]]
-            [salava.core.ui.ajax-utils :as ajax]
-            [salava.core.ui.helper :as h :refer [unique-values navigate-to path-for  not-activated?]]
-            [salava.core.ui.notactivated :refer [not-activated-banner]]
-            [salava.core.ui.layout :as layout]
-            [salava.core.ui.grid :as g]
-            [salava.badge.ui.settings :as s]
-            [salava.badge.ui.helper :as bh]
-            [salava.core.helper :refer [dump]]
-            ;[salava.extra.application.ui.helper :refer [application-plugin?]]
-            [salava.core.time :refer [unix-time date-from-unix-time]]
-            [salava.core.i18n :as i18n :refer [t]]))
+    [reagent.core :refer [atom]]
+    [reagent.session :as session]
+    [reagent-modals.modals :as m]
+    [clojure.set :as set :refer [intersection]]
+    [clojure.string :refer [upper-case]]
+    [salava.core.ui.ajax-utils :as ajax]
+    [salava.core.ui.helper :as h :refer [unique-values navigate-to path-for  not-activated?]]
+    [salava.core.ui.notactivated :refer [not-activated-banner]]
+    [salava.core.ui.layout :as layout]
+    [salava.core.ui.grid :as g]
+    [salava.badge.ui.settings :as s]
+    [salava.badge.ui.helper :as bh]
+    [salava.core.helper :refer [dump]]
+    ;[salava.extra.application.ui.helper :refer [application-plugin?]]
+    [salava.core.time :refer [unix-time date-from-unix-time]]
+    [salava.core.i18n :as i18n :refer [t]]
+    [salava.core.ui.badge-grid :refer [badge-grid-element]]))

 (defn init-data [state]
@@ -64,93 +65,6 @@
                   -1)))
     true false))

-(defn show-settings-dialog [badge-id state]
-  (ajax/GET
-    (path-for (str "/obpv1/badge/settings/" badge-id) true)
-    {:handler (fn [data]
-
-                (swap! state assoc :badge-settings data (assoc data :new-tag ""))
-                (m/modal! [s/settings-modal data state init-data]
-                          {:size :lg}))}))
-
-(defn delete-badge [id state init-data]
-  (ajax/DELETE
-    (path-for (str "/obpv1/badge/" id))
-    {:handler
-      (fn []
-        (init-data state)
-        (m/close-modal!))}))
-
-
-(defn num-days-left [timestamp]
-  (int (/ (- timestamp (/ (.now js/Date) 1000)) 86400))
-)
-
-(defn delete-badge-modal [id state init-data]
-  [:div
-   [:div.modal-header
-    [:button {:type "button"
-              :class "close"
-              :data-dismiss "modal"
-              :aria-label "OK"}
-     [:span {:aria-hidden "true"
-             :dangerouslySetInnerHTML {:__html "×"}}]]]
-   [:div.modal-body
-    [:div {:class (str "alert alert-warning")}
-     (t :badge/Confirmdelete)]]
-   [:div.modal-footer
-    [:button {:type "button"
-              :class "btn btn-primary"
-              :data-dismiss "modal"}
-     (t :core/Cancel)]
-    [:button {:type "button"
-              :class "btn btn-warning"
-              :on-click #(delete-badge id state init-data)}
-     (t :core/Delete)]]])
-
-(defn badge-grid-element [element-data state]
-  (let [{:keys [id image_file name description visibility expires_on revoked issuer_content_name issuer_content_url]} element-data
-        expired? (bh/badge-expired? expires_on)
-        badge-link (path-for (str "/badge/info/" id))]
-     [:div {:class "media grid-container"}
-      [:div {:class (str "media-content " (if expired? "media-expired") (if revoked " media-revoked"))}
-      (cond
-        expired? [:div.icons
-                  [:div.lefticon [:i {:class "fa fa-history"}] (t :badge/Expired)]
-                  [:a.righticon {:class "righticon expired" :on-click (fn [] (m/modal! [delete-badge-modal id state init-data]
-                                    {:size :lg})) :title (t :badge/Delete)} [:i {:class "fa fa-trash"}]]]
-        revoked  [:div.icons
-                  [:div.lefticon [:i {:class "fa fa-ban"}] (t :badge/Revoked)]
-                  [:a.righticon {:class "righticon revoked" :on-click (fn [] (m/modal! [delete-badge-modal id state init-data]
-                                    {:size :lg})) :title (t :badge/Delete)} [:i {:class "fa fa-trash"}]]]
-        :else [:div.icons
-                [:a.visibility-icon {:on-click #(do (.preventDefault %) (show-settings-dialog id state))
-                :title
-                (case visibility
-                  "private" (str (t :badge/Badgevisibility) ": " (t :badge/Private))
-                  "internal" (str (t :badge/Badgevisibility) ": " (t :badge/Shared))
-                  "public" (str (t :badge/Badgevisibility) ": " (t :core/Public))
-                  nil)}
-             (case visibility
-               "private" [:i {:class "fa fa-lock"}]
-               "internal" [:i {:class "fa fa-group"}]
-               "public" [:i {:class "fa fa-globe"}]
-               nil)]
-               (if expires_on
-                [:div.righticon
-                  [:i {:title (str (t :badge/Expiresin) " " (num-days-left expires_on) " " (t :badge/days))
-                       :class "fa fa-hourglass-half"}]])])
-       (if image_file
-         [:div.media-left
-          [:a {:href badge-link} [:img.badge-img {:src (str "/" image_file)
-                                                  :alt name}]]])
-       [:div.media-body
-        [:div.media-heading
-         [:a.heading-link {:href badge-link :id (str id "-heading")} name]]
-        [:div.media-issuer
-         [:p issuer_content_name]]
-         ]]
-      ]))

 (defn badge-grid [state]
   (let [badges (:badges @state)
@@ -168,7 +82,7 @@
                  :id    "grid"}]
           (for [element-data badges]
             (if (badge-visible? element-data state)
-              (badge-grid-element element-data state))))))
+              (badge-grid-element element-data state "basic" init-data))))))

 (defn no-badges-text []
@@ -188,9 +102,7 @@
       (cond
         (not-activated?) (not-activated-banner)
         (empty? (:badges @state)) [no-badges-text]
-        :else [badge-grid state])
-
-      ]
+        :else [badge-grid state])]
      )])


Port planck's eval implementation (#177)

fixes #146

--- src/cljs/snapshot/lumo/repl.cljs
+++ src/cljs/snapshot/lumo/repl.cljs
@@ -4,6 +4,7 @@
                    [cljs.analyzer.macros :refer [no-warn]]
                    [lumo.repl :refer [with-err-str]])
   (:require [cljs.analyzer :as ana]
+            [cljs.compiler :as comp]
             [cljs.env :as env]
             [cljs.js :as cljs]
             [cljs.reader :as reader]
@@ -805,6 +806,57 @@
                       (map #(symbol ns-name (str %))
                            (filter matches? (public-syms ns)))))
                   (all-ns)))))
+
+;; Taken from planck eval implementation
+;; The following atoms and fns set up a scheme to
+;; emit function values into JavaScript as numeric
+;; references that are looked up.
+
+(defonce ^:private fn-index (volatile! 0))
+(defonce ^:private fn-refs (volatile! {}))
+
+(defn- clear-fns!
+  "Clears saved functions."
+  []
+  (vreset! fn-refs {}))
+
+(defn- put-fn
+  "Saves a function, returning a numeric representation."
+  [f]
+  (let [n (vswap! fn-index inc)]
+    (vswap! fn-refs assoc n f)
+    n))
+
+(defn- get-fn
+  "Gets a function, given its numeric representation."
+  [n]
+  (get @fn-refs n))
+
+(defn- emit-fn [f]
+  (print "lumo.repl.get_fn(" (put-fn f) ")"))
+
+(defmethod comp/emit-constant js/Function
+  [f]
+  (emit-fn f))
+
+(defmethod comp/emit-constant cljs.core/Var
+  [f]
+  (emit-fn f))
+
+(defn eval
+  ([form]
+   (eval form (.-name *ns*)))
+  ([form ns]
+   (let [result (volatile! nil)]
+     (cljs/eval st form
+       {:ns            ns
+        :context       :expr
+        :def-emits-var true}
+       (fn [{:keys [value error]}]
+         (if error
+           (handle-error error true)
+           (vreset! result value))))
+     @result)))

 ;; --------------------
 ;; Code evaluation
@@ -1029,6 +1081,7 @@

 (defn- ^:export execute
   [type source-or-path expression? print-nil-result? setNS session-id]
+  (clear-fns!)
   (when setNS
     (vreset! current-ns (symbol setNS)))
   (execute-source source-or-path {:type type


add more clojure refs for cljs.analyzer.api

--- src/cljs_api_gen/clojure_api.clj
+++ src/cljs_api_gen/clojure_api.clj
@@ -37,6 +37,11 @@
    "cljs.reader/read"                   "clojure.core/read"
    "cljs.analyzer.api/all-ns"           "clojure.core/all-ns"
    "cljs.analyzer.api/find-ns"          "clojure.core/find-ns"
+   "cljs.analyzer.api/ns-interns"       "clojure.core/ns-interns"
+   "cljs.analyzer.api/ns-publics"       "clojure.core/ns-publics"
+   "cljs.analyzer.api/ns-resolve"       "clojure.core/ns-resolve"
+   "cljs.analyzer.api/remove-ns"        "clojure.core/remove-ns"
+   "cljs.analyzer.api/resolve"          "clojure.core/resolve"
    })

 (defn clj-lookup-name


Export trace viz on trace plugin

Export trace viz on trace plugin

--- src/com/wsscode/pathom/core.cljc
+++ src/com/wsscode/pathom/core.cljc
@@ -737,7 +737,7 @@
             parser-trace (pt/trace-enter env' {::pt/event ::trace-plugin})]
         (let-chan [res (parser env' tx)]
           (pt/trace-leave env' {::pt/event ::trace-plugin} parser-trace)
-          (assoc res :com.wsscode.pathom/trace @trace*)))
+          (assoc res :com.wsscode.pathom/trace (pt/trace->viz @trace*))))
       (parser env tx))))

 (def trace-plugin


Fix typo in comment, make scheduler private again.

--- src/afterglow/show.clj
+++ src/afterglow/show.clj
@@ -51,7 +51,8 @@
   default-refresh-interval
   (/ 1000 30))

-(defonce ^{:doc "Provides thread scheduling for all shows' DMX data generation."}
+(defonce ^{:doc "Provides thread scheduling for all shows' DMX data generation."
+           :private true}
   scheduler
   (at-at/mk-pool))


good right

good right

--- test/epicea/vfibers/core_test.clj
+++ test/epicea/vfibers/core_test.clj
@@ -103,5 +103,7 @@

 (deftest make-node-test
-  (make-node (dnum 3)))
+  (make-node (dnum 3) [])
+  (is (= (make-node (test-add (dnum 3) (dnum 4)) [3 4 5])
+         '(clojure.core/+ 3 4 5))))


traversal tests fix

traversal tests fix

--- test/morpheus/tests/traversal.clj
+++ test/morpheus/tests/traversal.clj
@@ -75,7 +75,7 @@
                   (link! (get-vertex2 16) :link1 (get-vertex2 17))  => anything
                   (link! (get-vertex2 17) :link1 (get-vertex2 18))  => anything
                   (link! (get-vertex2 18) :link1 (get-vertex2 19))  => anything
-                  (link! (get-vertex2 19) :link (get-vertex2 20))  => anything
+                  (link! (get-vertex2 19) :link1 (get-vertex2 20))  => anything
                   (link! (get-vertex2 16) :link1 (get-vertex2 21))  => anything
                   (link! (get-vertex2 20) :link1 (get-vertex2 22))  => anything))
       (fact "Simple check"


Add `can-have-metadata?` to buffer-macros

--- src/cljc/mikron/runtime/buffer_macros.cljc
+++ src/cljc/mikron/runtime/buffer_macros.cljc
@@ -1,6 +1,5 @@
 (ns mikron.runtime.buffer-macros
-  (:require [clojure.spec :as s]
-            [mikron.compiler.spec :as compiler.spec]
+  (:require [mikron.compiler.spec :as compiler.spec]
             [mikron.compiler.util :as compiler.util])
   #?(:cljs (:require-macros [mikron.runtime.buffer-macros])))

@@ -14,10 +13,10 @@

 (defmacro with-le
   "Executes the expressions with the endianness automatically set to `le`."
-  [le [expr & exprs]]
+  [le [method & args]]
   `(if ~le
-     (~(symbol (str expr "LE")) ~@exprs)
-     (~(symbol (str expr "BE")) ~@exprs)))
+     (~(symbol (str method "LE")) ~@args)
+     (~(symbol (str method "BE")) ~@args)))

 (defn without-hint
   "Removes the type hint metadata from `value`."
@@ -31,10 +30,15 @@
                      (cond-> meta
                        (#{'long 'double} tag) (dissoc :tag)))))

+(defn can-have-metadata?
+  "Returns `true` if `value` can have metadata, `false` otherwise."
+  [value]
+  (or (symbol? value) (coll? value)))
+
 (defn with-runtime-hint
   "Takes the metadata of `value` and returns a piece of code which reapplies it to what `value` evaluates to."
   [value]
-  `(if-not (or (symbol? ~value) (coll? ~value))
+  `(if-not (can-have-metadata? ~value)
      ~value
      (vary-meta ~value assoc :tag '~(:tag (meta value)))))


Adds complete-node* and complete-nodes*

Adds complete-node* and complete-nodes*

--- src/the_little_clojurian/todo.clj
+++ src/the_little_clojurian/todo.clj
@@ -1,7 +1,77 @@
 (ns the-little-clojurian.todo
   (:require [clojure.test :refer :all]))

-(declare complete-map* complete-list*)
+(declare complete-map* complete-list* complete-node* complete-nodes*)
+
+(with-test
+  (def complete-nodes*
+    (fn [id nodes]
+      (cond (empty? nodes) '()
+            :else (cons (complete-node* id (first nodes)) (complete-nodes* id (rest nodes))))))
+
+  (is (= (complete-nodes* 1 '())
+         '()))
+
+  (is (= (complete-nodes* 1 '({:id 1}))
+         '({:id 1 :complete true})))
+
+  (is (= (complete-nodes* 1 '({:id 1} {:id 1}))
+         '({:id 1 :complete true} {:id 1 :complete true})))
+
+  (is (= (complete-nodes* 1 '({:id 1} {:id 2}))
+         '({:id 1 :complete true} {:id 2})))
+
+  (is (= (complete-nodes* 2 '({:id 1} {:id 2}))
+         '({:id 1} {:id 2 :complete true})))
+
+  (is (= (complete-nodes* 2 '({:id 1 :nodes ({:id 2})}))
+         '({:id 1 :nodes ({:id 2 :complete true})}))))
+
+(with-test
+  (def complete-node*
+    (fn [id m]
+      (cond (nil? m) {}
+            (empty? m) {}
+            (nil? (:id m)) m
+            (= (:id m) id) (assoc m :complete true)
+            (not (empty? (:nodes m))) {:id (:id m) :nodes (complete-nodes* id (:nodes m))}
+            :else m)))
+
+  (is (= (complete-node* 1 nil)
+         {}))
+
+  (is (= (complete-node* 1 {})
+         {}))
+
+  (is (= (complete-node* 1 {:foo "bar"})
+         {:foo "bar"}))
+
+  (is (= (complete-node* 1 {:id 1})
+         {:id 1 :complete true}))
+
+  (is (= (complete-node* 2 {:id 1})
+         {:id 1}))
+
+  (is (= (complete-node* 2 {:id 2})
+         {:id 2 :complete true}))
+
+  (is (= (complete-node* 1 {:id 1 :nodes ()})
+         {:id 1 :complete true :nodes ()}))
+
+  (is (= (complete-node* 1 {:id 1 :nodes '({:id 2})}))
+      {:id 1 :complete true :nodes '({:id 2})})
+
+  (is (= (complete-node* 2 {:id 1 :nodes '({:id 2})})
+         {:id 1 :nodes '({:id 2 :complete true})}))
+
+  (is (= (complete-node* 3 {:id 1 :nodes '({:id 2 :nodes ({:id 3})})})
+         {:id 1 :nodes '({:id 2 :nodes ({:id 3 :complete true})})}))
+
+  (is (= (complete-node* 4 {:id 1 :nodes '({:id 2} {:id 3} {:id 4})})
+         {:id 1 :nodes '({:id 2} {:id 3} {:id 4 :complete true})}))
+
+  (is (= (complete-node* 2 {:id 1 :nodes '({:id 2 :nodes ({:id 3})})})
+         {:id 1 :nodes '({:id 2 :complete true :nodes ({:id 3})})})))

 (with-test
   (def complete-list*
@@ -89,4 +159,3 @@

   (is (= (complete-map* 5 {:id 1 :nodes '({:id 2 :nodes ({:id 3 :nodes ({:id 4 :nodes ({:id 5} {:id 6})})})})}))
        {:id 1 :nodes '({:id 2 :nodes ({:id 3 :nodes ({:id 4 :nodes ({:id 5 :complete true} {:id 6})})})})}))
-


Use new logging shell command.

Use new logging shell command.

--- src/dragon/data/sources/core.clj
+++ src/dragon/data/sources/core.clj
@@ -1,6 +1,7 @@
 (ns dragon.data.sources.core
   (:require [clojure.java.shell :as shell]
             [dragon.config :as config]
+            [dragon.util :as util]
             [taoensso.timbre :as log]))

 (defn execute-db-command!
@@ -11,7 +12,7 @@
     (shell/with-sh-dir home
       (log/debugf "Running command in %s ..." home)
       (log/debug "Using shell/sh args:" args)
-      (apply shell/sh args))))
+      (apply util/shell! args))))

 (defn remove-connection
   [component]


Collidable. Ship color by damage

Collidable. Ship color by damage

--- src/asteroids/core.clj
+++ src/asteroids/core.clj
@@ -149,6 +149,8 @@
    :rotation-speed         0

    :life                   ship-life
+   :life-colors            [(Color. 255 0 0) (Color. 255 80 75) (Color. 250 160 75) (Color. 160 160 150)]
+   :collidable?            false                            ; is set to true at first movement / shooting
    })

 (defn create-shot
@@ -157,7 +159,7 @@

     :size           shot-size
     :shape          [[-1.0 -5.0] [1.0 -5.0] [0.0 1.0]]
-    :color          (Color. 250 100 20)
+    :color          (Color. 250 50 10)

     :position       pos
     :speed          speed
@@ -165,6 +167,8 @@

     :direction      dir
     :rotation-speed 0
+
+    :collidable?    true
     })
   ([{:keys [position size direction speed] :as ship}]
    (let [dir-vec (rotate-vec direction [0 1])
@@ -197,6 +201,8 @@

       :direction      direction
       :rotation-speed rotation-speed
+
+      :collidable?    true
       }))
   ([size pos]
    (create-asteroid size pos [0 0]))
@@ -236,7 +242,9 @@
               (and (sequential? obj1) (sequential? obj2)) :seq-seq)))

 (defmethod check-collision :map-map [obj1 obj2]
-  (if (collide? obj1 obj2)
+  (if (and (:collidable? obj1)
+           (:collidable? obj2)
+           (collide? obj1 obj2))
     [(assoc obj1 :hit? true) (assoc obj2 :hit? true)]
     [obj1 obj2]))

@@ -274,7 +282,7 @@
     (if hit?
       (if (< fragment-size asteroid-min-size)
         nil
-        (create-asteroids 3 (/ size sqrt3) position speed))
+        (create-asteroids 3 fragment-size position speed))
       asteroid)))

 (defn resolve-all-collision [{shots :shots :as ship} asteroids]
@@ -358,10 +366,12 @@
   (assoc ship :rotation-speed (+ rotation-speed rot)))

 (defn accelerate [{:keys [acceleration] :as ship} acc]
-  (assoc ship :acceleration (+ acceleration acc)))
+  (assoc ship :acceleration (+ acceleration acc)
+              :collidable? true))

 (defn toggle-shooting [ship do-shoot?]
-  (assoc ship :shooting? do-shoot?))
+  (assoc ship :shooting? do-shoot?
+              :collidable? true))

 ; ----------------------------------------------------------
 ; mutable model
@@ -420,11 +430,12 @@

 (defmulti paint (fn [_ object] (:type object)))

-(defmethod paint :ship [g {:keys [shape color cockpit-shape cockpit-color shots] :as ship}]
+(defmethod paint :ship [g {:keys [shape life-colors life cockpit-shape cockpit-color shots] :as ship}]
   (doseq [shot shots]
     (paint g shot))
   (let [transformation (get-transformation-matrix ship point-size)
         polygon (polygon-to-screen shape transformation)
+        color (get life-colors life)
         cockpit-polygon (polygon-to-screen cockpit-shape transformation)]
     (fill-polygon g polygon color)
     (fill-polygon g cockpit-polygon cockpit-color)))
@@ -485,4 +496,7 @@
       (.pack)
       (.setVisible true))
     (.start timer)                                          ; <label id="code.game.timer"/>
-    {:ship ship, :timer timer}))                            ; <label id="code.game.return"/>
+    (def ship ship)
+    (def timer timer)
+    (def frame frame)
+    {:ship ship}))                                          ; <label id="code.game.return"/>


Modified configuration function to get the configuration file path from caller.

--- src/tames/config.clj
+++ src/tames/config.clj
@@ -4,6 +4,7 @@
             [clojure.java.io :as io]
             [clojure.data.json :as json]
             [clojure.string :as string]
+            [tames.debug :as debug]
             [tames.filesystem :as fs]
             [tames.log :as log])
   (:import (java.io File InputStream)
@@ -26,9 +27,8 @@
   (. (File. @path) lastModified))

 (defn ensure-config-file
-  []
+  [path]
   (let [default-path (format "data/%s/%s.json" CLASS_ID DEFAULT_ID)
-        path         (get (System/getenv) "CONFIG_PATH" nil)
         file         (File. (fs/get-absolute-path (if (empty? path) default-path path)))
         dir          (. file getParentFile)]
     (cond (not (. dir exists))
@@ -44,8 +44,8 @@
               file))))

 (defn init
-  []
-  (let [file   (ensure-config-file)
+  [config-path]
+  (let [file   (ensure-config-file config-path)
         result (not (nil? file))]
     (when result
       (reset! path (. file getAbsolutePath))


Working param-editor.

Working param-editor.

--- sonic-jam/src/sonic_jam/core.cljs
+++ sonic-jam/src/sonic_jam/core.cljs
@@ -40,31 +40,42 @@
       {:state :init})
     om/IRenderState
     (render-state [this state]
-      (condp = (:state state)
-        :init (dom/table nil
-                         (apply dom/tbody nil
-                                (map (fn [k v] (dom/tr nil
-                                                       (dom/td nil k)
-                                                       (dom/td #js {:onClick #(do
-                                                                                (print "bonk")
-                                                                                (om/update-state! owner
+      (let [commit #(do
+                      (om/update-state! owner (fn [s] (merge s {:state :init})))
+                      (om/transact! cursor (fn [c] (assoc c (:field state) (:text state))))
+                      (go (>! set-state-ch id)))]
+        (condp = (:state state)
+          :init (dom/table nil
+                           (apply dom/tbody nil
+                                  (map (fn [k v] (dom/tr nil
+                                                         (dom/td nil k)
+                                                         (dom/td #js {:onClick #(om/update-state! owner
                                                                                (fn [s] (merge s {:state :editing
                                                                                :text v
-                                                                                :field k}))))} v)))
-                                     (keys cursor)
-                                     (vals cursor))))
-        :editing (dom/table nil
-                            (apply dom/tbody nil
-                                   (map (fn [k v] (dom/tr nil
-                                                          (dom/td nil k)
-                                                          (dom/td nil
-                                                                  (dom/input #js {:type "text" :value (:text state)
-                                                                                :onChange #(handle-change % owner state)})))))
-                                   (keys cursor)
-                                   (vals cursor)))))))
+                                                                                :field k})))}
+                                                                 v)))
+                                       (keys cursor)
+                                       (vals cursor))))
+          :editing (dom/table nil
+                              (apply dom/tbody nil
+                                     (map (fn [k v] (dom/tr nil
+                                                            (dom/td nil k)
+                                                            (if (= k (:field state))
+                                                              (dom/td nil
+                                                                      (dom/input #js {:type "text" :value (:text state)
+                                                                                :onChange #(handle-change % owner state)
+                                                                                :onKeyDown #(when (= 13 (.-which %))
+                                                                                (commit))}))
+                                                              (dom/td #js {:onClick #(om/update-state! owner
+                                                                                (fn [s] (merge s {:state :editing
+                                                                                :text v
+                                                                                :field k})))}
+                                                                      v))))
+                                          (keys cursor)
+                                          (vals cursor)))))))))

-(defn track-editor [{:keys [cursor id delete-ch]} owner]
+(defn track-editor [{:keys [cursor id delete-ch set-state-ch]} owner]
   (reify
     om/IInitState
     (init-state [_]
@@ -77,7 +88,7 @@
         :open (dom/p #js {:style #js {:color "#999"}}
                      (dom/span #js {:onClick #(om/update-state! owner (fn [s] (merge s {:state :init})))} "{-")
                      (dom/span nil
-                               (om/build param-editor {:cursor (get cursor "params") :id id :set-state-ch nil}))
+                               (om/build param-editor {:cursor (get cursor "params") :id id :set-state-ch set-state-ch}))
                      (dom/span #js {:onClick #(go (>! delete-ch cursor))} " delete? ")
                      (dom/span nil "}"))))))

@@ -180,7 +191,8 @@
                                             (repeat id))]
                            (om/build-all cell-view cursors {:state state})))))
                 (dom/td #js {:style #js {:color "#999" :paddingRight "10px"}}
-                        (om/build track-editor {:cursor cursor :id id :delete-ch delete-ch}))
+                        (om/build track-editor {:cursor cursor :id id :delete-ch delete-ch
+                                                :set-state-ch (:set-state-ch state)}))
                 (dom/td nil
                         (when (= "grid" (get cursor "type"))
                           (let [id (get cursor "id")


Finished adding planets info to ALL systems

--- src/glory_of_empires/systems.clj
+++ src/glory_of_empires/systems.clj
@@ -2,7 +2,8 @@
   (:use clojure-common.utils))

 (def all-systems-arr
-  [ { :id :aah       :image "1planet/Tile-Aah.gif"     :planets { :aah { :res 1 :inf 1 :loc [ 0 0 ] } } }
+  [ ; 1 planet
+    { :id :aah       :image "1planet/Tile-Aah.gif"     :planets { :aah { :res 1 :inf 1 :loc [ 0 0 ] } } }
     { :id :acheron   :image "1planet/Tile-Acheron.gif" :planets { :acheron { :res 1 :inf 2 :tech { :green 1 } :loc [ 0 0 ] } } }
     { :id :aeon      :image "1planet/Tile-Aeon.gif"    :planets { :aeon { :res 1 :inf 3 :tech { :green 1 } :loc [ 0 0 ] } } }
     { :id :aker      :image "1planet/Tile-Aker.gif"    :planets { :aker { :res 1 :inf 2 :loc [ 0 0 ] } } }
@@ -29,7 +30,6 @@
     { :id :chuuka    :image "1planet/Tile-Chuuka.gif"  :planets { :chuuka { :res 1 :inf 0 :tech { :blue 1 } :loc [ 0 0 ] } } }
     { :id :cicerus   :image "1planet/Tile-Cicerus.gif" :planets { :cicerus { :res 2 :inf 2 :loc [ 0 0 ] } } }
     { :id :coruscant :image "1planet/Tile-Coruscant.gif" :planets { :coruscant { :res 2 :inf 4 :loc [ 0 0 ] } } }
-
     { :id :dedun     :image "1planet/Tile-Dedun.gif" :planets { :dedun { :res 2 :inf 0 :tech { :green 1 } :loc [ 0 0 ] } } }
     { :id :deimo     :image "1planet/Tile-Deimo.gif" :planets { :deimo { :res 0 :inf 1 :loc [ 0 0 ]
                      :special "Occupier gains: Built-in space-dock with no fighter support and unlimited prod capacity." } } }
@@ -74,7 +74,6 @@
     { :id :pakhet    :image "1planet/Tile-Pakhet.gif"   :planets { :pakhet { :res 1 :inf 1 } :loc [ 0 0 ] } }
     { :id :parzifal  :image "1planet/Tile-Parzifal.gif" :planets { :parzifal { :res 4 :inf 3 :tech { :green 1 } :loc [ 0 0 ] } } }
     { :id :perimeter :image "1planet/Tile-Perimeter.gif" :planets { :perimeter { :res 2 :inf 2 :loc [ 0 0 ] } } }
-
     { :id :petbe     :image "1planet/Tile-Petbe.gif"   :planets { :petbe { :res 1 :inf 1 :loc [ 0 0 ] } } }
     { :id :primor    :image "1planet/Tile-Primor.gif"  :planets { :primor { :res 2 :inf 1 :loc [ 0 0 ] :special "Exhaust for 2 GF" } } }
     { :id :ptah      :image "1planet/Tile-Ptah.gif"    :planets { :ptah { :res 1 :inf 1 :loc [ 0 0 ] } } }
@@ -102,67 +101,192 @@
     { :id :wellon    :image "1planet/Tile-Wellon.gif"  :planets { :wellon { :res 1 :inf 2 :loc [ 0 0 ] } } }
     { :id :wepwawet  :image "1planet/Tile-Wepwawet.gif" :planets { :wepwawet { :res 2 :inf 1 :loc [ 0 0 ] } } }

+    ; TODO: Move following tiles to 1-planet folder
+    { :id :babylon-5 :image "Special/Tile-Babylon_5.gif" :planets { :babylon-5 { :res 1 :inf 6 :loc [ 0 0 ] } } }
+    { :id :citadel :image "Special/Tile-Citadel.gif" :planets { :citadel { :res 1 :inf 6 :loc [ 0 0 ] } } }
+    { :id :cormund :image "Special/Tile-Cormund.gif" :planets { :cormund { :res 2 :inf 0 :special "Gravity rift" :loc [ 0 0 ] } } }
+    { :id :mecatol-rex :image "Special/Tile-Mecatol_Rex.gif" :planets { :mecatol-rex { :res 1 :inf 6 :loc [ 0 0 ] } } }
+    { :id :mecatol-rex09 :image "Special/Tile-Mecatol_Rex09.gif" :planets { :mecatol-rex { :res 0 :inf 9 :loc [ 0 0 ] } } }
+    { :id :old-mecatol-rex :image "Special/Tile-OldMecatolRex.gif" :planets { :mecatol-rex { :res 4 :inf 10 :loc [ 0 0 ] } } }
+    { :id :orion2 :image "Special/Tile-Orion2.gif" :planets { :orion { :res 4 :inf 6 :loc [ 0 0 ] } } }
+
+    ; 2 planets
     { :id :abyz-fria :image "2planet/Tile-Abyz-Fria.gif"
-      :planets { :abyz { :res 3 :inf 0 :loc [ -75 -70 ] }
-                 :fria { :res 2 :inf 0 :tech { :blue 1 } :loc [ 75 70 ] } } }
-    { :id :achill    :image "2planet/Tile-Achill.gif" }
-    { :id :aeterna-tammuz :image "2planet/Tile-AeternaTammuz.gif" }
-    { :id :arinam-meer :image "2planet/Tile-Arinam-Meer.gif" }
-    { :id :arnor-lor :image "2planet/Tile-Arnor-Lor.gif" }
-    { :id :aztlan-senhora :image "2planet/Tile-Aztlan-Senhora.gif" }
-    { :id :bereg-lirta4 :image "2planet/Tile-Bereg-Lirta_IV.gif" }
-    { :id :bondar-maclean :image "2planet/Tile-Bondar-MacLean.gif" }
-    { :id :cato :image "2planet/Tile-Cato.gif" }
-    { :id :centauri-gral :image "2planet/Tile-Centauri-Gral.gif" }
-    { :id :coorneeq-resculon :image "2planet/Tile-Coorneeq-Resculon.gif" }
-    { :id :custos-xhal :image "2planet/Tile-Custos-Xhal.gif" }
-    { :id :dal-bootha-xxehan :image "2planet/Tile-Dal_Bootha-Xxehan.gif" }
-    { :id :garneau-hadfield :image "2planet/Tile-Garneau-Hadfield.gif" }
-    { :id :gilea-xerel-wu :image "2planet/Tile-Gilea-Xerel_Wu.gif" }
-    { :id :gurmee-uguza :image "2planet/Tile-Gurmee-Uguza.gif" }
-    { :id :hana :image "2planet/Tile-Hana.gif" }
-    { :id :hercalor-tiamat :image "2planet/Tile-Hercalor-Tiamat.gif" }
-    { :id :kazaros-mirabar :image "2planet/Tile-Kazaros-Mirabar.gif" }
-    { :id :lazar-sakulag :image "2planet/Tile-Lazar-Sakulag.gif" }
-    { :id :lisis-velnor :image "2planet/Tile-Lisis-Velnor.gif" }
-    { :id :machall-sorkragh :image "2planet/Tile-MachallSorkragh.gif" }
-    { :id :masada-jamiah :image "2planet/Tile-Masada-Jamiah.gif" }
-    { :id :massada-iuddaea :image "2planet/Tile-Massada-Iuddaea.gif" }
-    { :id :mellon-zohbat :image "2planet/Tile-Mellon-Zohbat.gif" }
-    { :id :nadir-lucus :image "2planet/Tile-Nadir-Lucus.gif" }
-    { :id :new-albion-starpoint :image "2planet/Tile-New_Albion-Starpoint.gif" }
-    { :id :nummantia-hisspania :image "2planet/Tile-Nummantia-Hisspania.gif" }
+      :planets { :abyz { :res 3 :inf 0 :loc [ -75 -70 ] }, :fria { :res 2 :inf 0 :tech { :blue 1 } :loc [ 75 70 ] } } }
+    { :id :achill    :image "2planet/Tile-Achill.gif"
+      :planets { :achill-ii { :res 2 :inf 2 :loc [ -75 -70 ] }, :achill-iv { :res 2 :inf 2 :loc [ 75 70 ] } } }
+    { :id :aeterna-tammuz :image "2planet/Tile-AeternaTammuz.gif"
+      :planets { :aeterna { :res 1 :inf 3 :loc [ -75 -70 ] }, :tammuz { :res 2 :inf 1 :loc [ 75 70 ] } } }
+    { :id :arinam-meer :image "2planet/Tile-Arinam-Meer.gif"
+      :planets { :arinam { :res 1 :inf 2 :tech { :blue 1 } :loc [ -75 -70 ] }, :meer { :res 0 :inf 4 :loc [ 75 70 ] } } }
+    { :id :arnor-lor :image "2planet/Tile-Arnor-Lor.gif"
+      :planets { :arnor { :res 2 :inf 1 :loc [ -75 -70 ] }, :lor { :res 1 :inf 2 :tech { :red 1 } :loc [ 75 70 ] } } }
+    { :id :aztlan-senhora :image "2planet/Tile-Aztlan-Senhora.gif"
+      :planets { :aztlan { :res 2 :inf 1 :loc [ -75 -70 ] :special "???" },
+                 :senhora-da-sorte { :res 1 :inf 2 :special "???" :loc [ 75 70 ] } }}
+    { :id :bereg-lirta-iv :image "2planet/Tile-Bereg-Lirta_IV.gif"
+      :planets { :bereg { :res 3 :inf 1 :tech { :red 1 } :loc [ -75 -70 ] }
+                 :lirta-iv { :res 2 :inf 3 :tech { :green 1 } :loc [ 75 70 ] } } }
+    { :id :bondar-maclean :image "2planet/Tile-Bondar-MacLean.gif"
+      :planets { :bondar { :res 1 :inf 3 :special "science station" :loc [ -75 -70 ] }
+                 :maclean { :res 0 :inf 2 :tech { :any 1 } :loc [ 75 70 ] } } }
+    { :id :cato :image "2planet/Tile-Cato.gif"
+      :planets { :cato-i { :res 2 :inf 1 :tech { :blue 1 } :loc [ -75 -70 ] }
+                 :cato-ii { :res 1 :inf 1 :loc [ 75 70 ] } } }
+    { :id :centauri-gral :image "2planet/Tile-Centauri-Gral.gif"
+      :planets { :centauri { :res 1 :inf 3 :loc [ -75 -70 ] }
+                 :gral { :res 1 :inf 1 :tech { :blue 1 } :loc [ 75 70 ] } } }
+    { :id :coorneeq-resculon :image "2planet/Tile-Coorneeq-Resculon.gif"
+      :planets { :coorneeq { :res 1 :inf 2 :tech { :red 1 } :loc [ -75 -70 ] }
+                 :resculon { :res 2 :inf 0 :loc [ 75 70 ] } } }
+    { :id :custos-xhal :image "2planet/Tile-Custos-Xhal.gif"
+      :planets { :custos { :res 2 :inf 2 :loc [ -75 -70 ] :special "Exhaust for 2 TG" }
+                 :xhal { :res 3 :inf 0 :loc [ 75 70 ] } } }
+    { :id :dal-bootha-xxehan :image "2planet/Tile-Dal_Bootha-Xxehan.gif"
+      :planets { :dal-bootha { :res 0 :inf 2 :tech { :red 1 } :loc [ -75 -70 ] }
+                 :xxehan { :res 1 :inf 1 :tech { :green 1 } :loc [ 75 70 ] } } }
+    { :id :garneau-hadfield :image "2planet/Tile-Garneau-Hadfield.gif"
+      :planets { :garneau { :res 1 :inf 3 :special "science station" :loc [ -75 -70 ] }
+                 :hadfield { :res 0 :inf 2 :tech { :any 1 } :loc [ 75 70 ] } } }
+    { :id :gilea-xerel-wu :image "2planet/Tile-Gilea-Xerel_Wu.gif"
+      :planets { :gilea { :res 1 :inf 1 :loc [ -75 -70 ] }
+                 :xerel-wu { :res 2 :inf 2 :tech { :yellow 1 } :loc [ 75 70 ] } } }
+    { :id :gurmee-uguza :image "2planet/Tile-Gurmee-Uguza.gif"
+      :planets { :gurmee { :res 1 :inf 1 :loc [ -75 -70 ] }
+                 :uguza { :res 0 :inf 3 :tech { :red 1 } :loc [ 75 70 ] } } }
+    { :id :hana :image "2planet/Tile-Hana.gif"
+      :planets { :hana-major { :res 3 :inf 1 :loc [ -75 -70 ] }
+                 :hana-minor { :res 0 :inf 1 :tech { :yellow 1 } :loc [ 75 70 ] } } }
+    { :id :hercalor-tiamat :image "2planet/Tile-Hercalor-Tiamat.gif"
+      :planets { :hercalor { :res 1 :inf 0 :tech { :yellow 1 } :loc [ -75 -70 ] }
+                 :tiamat { :res 1 :inf 2 :tech { :yellow 1 } :loc [ 75 70 ] } } }
+    { :id :kazaros-mirabar :image "2planet/Tile-Kazaros-Mirabar.gif"
+      :planets { :kazaros { :res 0 :inf 0 :loc [ -75 -70 ] }
+                 :mirabar { :res 2 :inf 3 :loc [ 75 70 ] } } }
+    { :id :lazar-sakulag :image "2planet/Tile-Lazar-Sakulag.gif"
+      :planets { :lazar { :res 1 :inf 0 :loc [ -75 -70 ] }
+                 :sakulag { :res 2 :inf 1 :loc [ 75 70 ] } } }
+    { :id :lisis-velnor :image "2planet/Tile-Lisis-Velnor.gif"
+      :planets { :lisis { :res 2 :inf 2 :loc [ -75 -70 ] }
+                 :velnor { :res 2 :inf 0 :tech { :red 1 } :loc [ 75 70 ] } } }
+    { :id :machall-sorkragh :image "2planet/Tile-MachallSorkragh.gif"
+      :planets { :machall { :res 1 :inf 2 :loc [ -75 -70 ] }
+                 :sorkragh { :res 1 :inf 2 :loc [ 75 70 ] } } }
+    { :id :masada-jamiah :image "2planet/Tile-Masada-Jamiah.gif"
+      :planets { :masada { :res 0 :inf 0 :special "Fleet supply +2 in this system for the controller" :loc [ -75 -70 ] }
+                 :jamiah { :res 4 :inf 0 :loc [ 75 70 ] } } }
+    { :id :massada-iuddaea :image "2planet/Tile-Massada-Iuddaea.gif"
+      :planets { :massada { :res 3 :inf 1 :special "Fleet supply +1 in this system for the controller" :loc [ -75 -70 ] }
+                 :iuddaea { :res 1 :inf 1 :loc [ 75 70 ] } } }
+    { :id :mellon-zohbat :image "2planet/Tile-Mellon-Zohbat.gif"
+      :planets { :mellon { :res 0 :inf 2 :loc [ -75 -70 ] }
+                 :zohbat { :res 3 :inf 1 :tech { :blue 1 } :loc [ 75 70 ] } } }
+    { :id :nadir-lucus :image "2planet/Tile-Nadir-Lucus.gif"
+      :planets { :nadir { :res 2 :inf 0 :loc [ -75 -70 ] }
+                 :lucus { :res 0 :inf 3 :tech { :green 1 } :loc [ 75 70 ] } } }
+    { :id :new-albion-starpoint :image "2planet/Tile-New_Albion-Starpoint.gif"
+      :planets { :new-albion { :res 1 :inf 1 :tech { :green 1 } :loc [ -75 -70 ] }
+                 :starpoint { :res 3 :inf 1 :loc [ 75 70 ] } } }
+    { :id :nummantia-hisspania :image "2planet/Tile-Nummantia-Hisspania.gif"
+      :planets { :nummantia { :res 3 :inf 1 :special "Fleet supply +1 in this system for the controller" :loc [ -75 -70 ] }
+                 :hisspania { :res 1 :inf 1 :loc [ 75 70 ] } } }
     { :id :othor-aiel :image "2planet/Tile-OthorAiel.gif"
-      :planets { :othor { :res 1 :inf 3 :tech { :green 1 } } :aiel { :res 2 :inf 0 :tech { :blue 1 } } } }
-    { :id :pankow-prenzlberg :image "2planet/Tile-Pankow-Prenzlberg.gif" }
-    { :id :perro-senno :image "2planet/Tile-Perro-Senno.gif" }
-    { :id :qucenn-rarron :image "2planet/Tile-Qucenn-Rarron.gif" }
-    { :id :renenutet-osiris :image "2planet/Tile-Renenutet-Osiris.gif" }
-    { :id :renpet-tawaret :image "2planet/Tile-Renpet-Tawaret.gif" }
-    { :id :resheph-ogdoad :image "2planet/Tile-Resheph-Ogdoad.gif" }
-    { :id :salem-iogu :image "2planet/Tile-SalemIogu.gif" }
-    { :id :shiva-wishnu :image "2planet/Tile-Shiva-Wishnu.gif" }
-    { :id :sulla-martinez :image "2planet/Tile-SullaMartinez.gif" }
-    { :id :sumerian-arcturus :image "2planet/Tile-Sumerian-Arcturus.gif" }
-    { :id :temujin-avanti :image "2planet/Tile-Temujin-Avanti.gif" }
-    { :id :tequran-torkan :image "2planet/Tile-Tequran-Torkan.gif" }
-    { :id :thoth-mafdet :image "2planet/Tile-Thoth-Mafdet.gif" }
-    { :id :tsion-bellatrix :image "2planet/Tile-Tsion-Bellatrix.gif" }
-    { :id :vega :image "2planet/Tile-Vega.gif" }
-    { :id :verne-quebec :image "2planet/Tile-Verne-Quebec.gif" }
-    { :id :vortekai-deguzz :image "2planet/Tile-Vortekai-Deguzz.gif" }
-
-    { :id :ashtroth-loki-abaddon :image "3planet/Tile-Ashtroth-Loki-Abaddon.gif" }
-    { :id :rigel :image "3planet/Tile-Rigel.gif" }
-    { :id :elder-uhuru-amani :image "3planet/Tile-Elder-Uhuru-Amani.gif" }
-    { :id :tianshang-tiangu-changtian :image "3planet/Tile-Tianshang-Tiangu-Changtian.gif" }
-
+      :planets { :othor { :res 1 :inf 3 :tech { :green 1 } }
+                 :aiel { :res 2 :inf 0 :tech { :blue 1 } } } }
+    { :id :pankow-prenzlberg :image "2planet/Tile-Pankow-Prenzlberg.gif"
+      :planets { :pankow { :res 3 :inf 1 :loc [ -75 -70 ] }
+                 :prenzlberg { :res 1 :inf 3 :loc [ 75 70 ] } }}
+    { :id :perro-senno :image "2planet/Tile-Perro-Senno.gif"
+      :planets { :perro { :res 2 :inf 2 :loc [ -75 -70 ] }
+                 :senno { :res 3 :inf 1 :tech { :blue 1 } :loc [ 75 70 ] } } }
+    { :id :qucenn-rarron :image "2planet/Tile-Qucenn-Rarron.gif"
+      :planets { :qucenn { :res 1 :inf 2 :loc [ -75 -70 ] }
+                 :rarron { :res 0 :inf 3 :tech { :green 1 } :loc [ 75 70 ] } } }
+    { :id :renenutet-osiris :image "2planet/Tile-Renenutet-Osiris.gif"
+      :planets { :renenutet { :res 1 :inf 1 :tech { :green 1 } :loc [ -75 -70 ] }
+                 :osiris { :res 1 :inf 1 :loc [ 75 70 ] } } }
+    { :id :renpet-tawaret :image "2planet/Tile-Renpet-Tawaret.gif"
+      :planets { :renpet { :res 0 :inf 2 :loc [ -75 -70 ] }
+                 :tawaret { :res 1 :inf 0 :loc [ 75 70 ] } } }
+    { :id :resheph-ogdoad :image "2planet/Tile-Resheph-Ogdoad.gif"
+      :planets { :resheph { :res 0 :inf 2 :tech { :red 1 } :loc [ -75 -70 ] }
+                 :ogdoad { :res 1 :inf 0 :loc [ 75 70 ] } } }
+    { :id :salem-iogu :image "2planet/Tile-SalemIogu.gif"
+      :planets { :salem { :res 0 :inf 1 :tech { :blue 1 } :loc [ -75 -70 ] }
+                 :iogu { :res 1 :inf 0 :tech { :green 1 } :loc [ 75 70 ] } } }
+    { :id :shiva-wishnu :image "2planet/Tile-Shiva-Wishnu.gif"
+      :planets { :shiva { :res 0 :inf 0 :tech { :red 1 } :loc [ 75 -70 ] }
+                 :wishnu { :res 2 :inf 2 :special "???" :loc [ -75 70 ] } } }
+    { :id :sulla-martinez :image "2planet/Tile-SullaMartinez.gif"
+      :planets { :sulla { :res 2 :inf 0 :tech { :blue 1 } :loc [ -75 -70 ] }
+                 :martinez { :res 2 :inf 2 :tech { :red 1 } :loc [ 75 70 ] } } }
+    { :id :sumerian-arcturus :image "2planet/Tile-Sumerian-Arcturus.gif"
+      :planets { :sumerian { :res 2 :inf 2 :special "Can be exhausted for 2 TG" :loc [ -75 -70 ] }
+                 :arcturus { :res 1 :inf 1 :loc [ 75 70 ] } } }
+    { :id :tequran-torkan :image "2planet/Tile-Tequran-Torkan.gif"
+      :planets { :tequran { :res 2 :inf 0 :tech { :red 1 } :loc [ -75 -70 ] }
+                 :torkan { :res 0 :inf 3 :tech { :blue 1 } :loc [ 75 70 ] } } }
+    { :id :thoth-mafdet :image "2planet/Tile-Thoth-Mafdet.gif"
+      :planets { :thoth { :res 1 :inf 1 :loc [ -75 -70 ] }
+                 :mafdet { :res 1 :inf 1 :loc [ 75 70 ] } } }
+    { :id :tsion-bellatrix :image "2planet/Tile-Tsion-Bellatrix.gif"
+      :planets { :tsion { :res 2 :inf 2 :special "Can be exhausted for 2 TG" :loc [ -75 -70 ] }
+                 :bellatrix { :res 0 :inf 1 :tech { :red 1 } :loc [ 75 70 ] } } }
+    { :id :vega :image "2planet/Tile-Vega.gif"
+      :planets { :vega-minor { :res 1 :inf 2 :tech { :blue 1 } :loc [ -75 -70 ] }
+                 :vega-major { :res 2 :inf 1 :loc [ 75 70 ] } } }
+    { :id :verne-quebec :image "2planet/Tile-Verne-Quebec.gif"
+      :planets { :verne { :res 0 :inf 3 :special "Exhaust for action card" :loc [ -75 -70 ] }
+                 :nouveau-quebec { :res 1 :inf 2 :special "Exhaust for action card" :loc [ 75 70 ] } } }
+    { :id :vortekai-deguzz :image "2planet/Tile-Vortekai-Deguzz.gif"
+      :planets { :vortekai { :res 4 :inf 1 :loc [ -75 -70 ] }
+                 :deguzz { :res 1 :inf 2 :loc [ 75 70 ] } } }
+
+    ; 3 planets
+    { :id :ashtroth-loki-abaddon :image "3planet/Tile-Ashtroth-Loki-Abaddon.gif"
+      :planets { :ashtroth { :res 2 :inf 0 :loc [ 0 -50 ] }
+                 :loki { :res 1 :inf 2 :loc [ 50 50 ] }
+                 :abaddon { :res 1 :inf 0 :tech { :red 1 } :loc [ -50 -50 ] } } }
+    { :id :rigel :image "3planet/Tile-Rigel.gif"
+      :planets { :rigel-i { :res 0 :inf 1 :tech { :green 1 } :loc [ 0 -50 ] }
+                 :rigel-ii { :res 1 :inf 2 :loc [ 50 50 ] }
+                 :rigel-iii { :res 1 :inf 1 :tech { :blue 1 } :loc [ -50 -50 ] } } }
+    { :id :elder-uhuru-amani :image "3planet/Tile-Elder-Uhuru-Amani.gif"
+      :planets { :elder-one { :res 0 :inf 0 :tech { :green 3 } :loc [ 0 -50 ] }
+                 :uhuru { :res 1 :inf 0 :loc [ -50 60 ] }
+                 :amani { :res 0 :inf 1 :loc [ 50 50 ] } } }
+    { :id :tianshang-tiangu-changtian :image "3planet/Tile-Tianshang-Tiangu-Changtian.gif"
+      :planets { :tianshang { :res 1 :inf 1 :loc [ 50 -50 ] }
+                 :tiangu-xing { :res 1 :inf 1 :loc [ -70 0 ] }
+                 :changtian { :res 2 :inf 0 :special "Exhaust for 2 TG" :loc [ 50 50 ] } }}
+
+    ; Regular homesystems
+    { :id :arborec   :type :home-system   :image "HomeSystem/Tile-HS-Arborec.gif" }
+    { :id :creuss    :type :home-system   :image "HomeSystem/Tile-HS-Creuss.gif" }
+    { :id :creuss-gate  :type :home-system   :image "HomeSystem/Tile-HS-Creuss_Gate.gif" }
+    { :id :hacan   :type :home-system     :image "HomeSystem/Tile-HS-Hacan.gif" }
+    { :id :jolnar  :type :home-system :image "HomeSystem/Tile-HS-Jolnar.gif" }
+    { :id :lisix   :type :home-system :image "HomeSystem/Tile-HS-L1z1x.gif" }
+    { :id :mentak  :type :home-system  :image "HomeSystem/Tile-HS-Mentak.gif" }
+    { :id :lazax   :type :home-system :image "HomeSystem/Tile-HS-Lazax.gif" }
+    { :id :letnev  :type :home-system   :image "HomeSystem/Tile-HS-Letnev.gif" }
+    { :id :winnu   :type :home-system  :image "HomeSystem/Tile-HS-Winnu.gif" }
+    { :id :muaat   :type :home-system  :image "HomeSystem/Tile-HS-Muaat.gif" }
+    { :id :naalu   :type :home-system  :image "HomeSystem/Tile-HS-Naalu.gif" }
+    { :id :nekro   :type :home-system  :image "HomeSystem/Tile-HS-Nekro.gif" }
+    { :id :sol     :type :home-system  :image "HomeSystem/Tile-HS-Sol.gif" }
+    { :id :xxcha   :type :home-system  :image "HomeSystem/Tile-HS-Xxcha.gif" }
+    { :id :yin     :type :home-system  :image "HomeSystem/Tile-HS-Yin.gif" }
+    { :id :yssaril :type :home-system   :image "HomeSystem/Tile-HS-Yssaril.gif" }
+    { :id :saar    :type :home-system  :image "HomeSystem/Tile-HS-Saar.gif"
+      :planets { :lisis2 { :res 1 :inf 0 } :ragh { :res 2 :inf 1 } } }
+
+    ; Community race homesystems
     { :id :akoytay   :type :home-system   :image "HomeSystem/Tile-HS-Akoytay.gif" }
     { :id :alkari    :type :home-system   :image "HomeSystem/Tile-HS-Alkari.gif" }
     { :id :alliance  :type :home-system   :image "HomeSystem/Tile-HS-Alliance.gif" }
     { :id :altair    :type :home-system   :image "HomeSystem/Tile-HS-Altair.gif" }
     { :id :andorian  :type :home-system   :image "HomeSystem/Tile-HS-Andorian.gif" }
-    { :id :arborec   :type :home-system   :image "HomeSystem/Tile-HS-Arborec.gif" }
     { :id :asari     :type :home-system   :image "HomeSystem/Tile-HS-Asari.gif" }
     { :id :asgard    :type :home-system   :image "HomeSystem/Tile-HS-Asgard.gif" }
     { :id :atreides  :type :home-system   :image "HomeSystem/Tile-HS-Atreides.gif" }
@@ -176,114 +300,98 @@
     { :id :caitian   :type :home-system   :image "HomeSystem/Tile-HS-Caitian.gif" }
     { :id :cannibals :type :home-system   :image "HomeSystem/Tile-HS-Cannibals.gif" }
     { :id :cardassian  :type :home-system  :image "HomeSystem/Tile-HS-Cardassian.gif" }
-    { :id :cartel   :image "HomeSystem/Tile-HS-Cartel.gif" }
-    { :id :centauri   :image "HomeSystem/Tile-HS-Centauri.gif" }
-    { :id :chaos   :image "HomeSystem/Tile-HS-Chaos.gif" }
-    { :id :chromatics   :image "HomeSystem/Tile-HS-Chromatics.gif" }
-    { :id :corrino   :image "HomeSystem/Tile-HS-Corrino.gif" }
-    { :id :creuss   :image "HomeSystem/Tile-HS-Creuss.gif" }
-    { :id :creuss-gate   :image "HomeSystem/Tile-HS-Creuss_Gate.gif" }
-    { :id :croax   :image "HomeSystem/Tile-HS-Croax.gif" }
-    { :id :dark-eldar   :image "HomeSystem/Tile-HS-DarkEldar.gif" }
-    { :id :darlocks   :image "HomeSystem/Tile-HS-Darlocks.gif" }
-    { :id :dominion   :image "HomeSystem/Tile-HS-Dominion.gif" }
-    { :id :dusun   :image "HomeSystem/Tile-HS-Dusun.gif" }
-    { :id :earth   :image "HomeSystem/Tile-HS-Earth.gif" }
-    { :id :eldar   :image "HomeSystem/Tile-HS-Eldar.gif" }
-    { :id :elerians   :image "HomeSystem/Tile-HS-Elerians.gif" }
-    { :id :elzenkar   :image "HomeSystem/Tile-HS-Elzenkar.gif" }
-    { :id :embers   :image "HomeSystem/Tile-HS-Embers.gif" }
-    { :id :fedaron   :image "HomeSystem/Tile-HS-Fedaron.gif" }
-    { :id :federation   :image "HomeSystem/Tile-HS-Federation.gif" }
-    { :id :ferengi   :image "HomeSystem/Tile-HS-Ferengi.gif" }
-    { :id :firijii   :image "HomeSystem/Tile-HS-Firijii.gif" }
-    { :id :geth   :image "HomeSystem/Tile-HS-Geth.gif" }
-    { :id :gnolams   :image "HomeSystem/Tile-HS-Gnolams.gif" }
-    { :id :goauld   :image "HomeSystem/Tile-HS-Goauld.gif" }
-    { :id :hacan   :image "HomeSystem/Tile-HS-Hacan.gif" }
-    { :id :harkonnen   :image "HomeSystem/Tile-HS-Harkonnen.gif" }
-    { :id :hirogen   :image "HomeSystem/Tile-HS-Hirogen.gif" }
-    { :id :humans   :image "HomeSystem/Tile-HS-Humans.gif" }
-    { :id :imperium-of-man   :image "HomeSystem/Tile-HS-Imperium_of_Man.gif" }
-    { :id :ironleague   :image "HomeSystem/Tile-HS-Ironleague.gif" }
-    { :id :jipa   :image "HomeSystem/Tile-HS-Jipa.gif" }
-    { :id :jolnar   :image "HomeSystem/Tile-HS-Jolnar.gif" }
-    { :id :kazon   :image "HomeSystem/Tile-HS-Kazon.gif" }
-    { :id :klackon   :image "HomeSystem/Tile-HS-Klackon.gif" }
-    { :id :klingon   :image "HomeSystem/Tile-HS-Klingon.gif" }
-    { :id :krenim   :image "HomeSystem/Tile-HS-Krenim.gif" }
-    { :id :krogan   :image "HomeSystem/Tile-HS-Krogan.gif" }
-    { :id :lisix   :image "HomeSystem/Tile-HS-L1z1x.gif" }
-    { :id :lazax   :image "HomeSystem/Tile-HS-Lazax.gif" }
-    { :id :letnev   :image "HomeSystem/Tile-HS-Letnev.gif" }
-    { :id :lun   :image "HomeSystem/Tile-HS-Lun.gif" }
-    { :id :mahact-sodality   :image "HomeSystem/Tile-HS-Mahact_Sodality.gif" }
-    { :id :maquis   :image "HomeSystem/Tile-HS-Maquis.gif" }
-    { :id :meklars   :image "HomeSystem/Tile-HS-Meklars.gif" }
-    { :id :mentak   :image "HomeSystem/Tile-HS-Mentak.gif" }
-    { :id :minbari   :image "HomeSystem/Tile-HS-Minbari.gif" }
-    { :id :mirssen   :image "HomeSystem/Tile-HS-Mirssen.gif" }
-    { :id :moritani   :image "HomeSystem/Tile-HS-Moritani.gif" }
-    { :id :mrrshan   :image "HomeSystem/Tile-HS-Mrrshan.gif" }
-    { :id :muaat   :image "HomeSystem/Tile-HS-Muaat.gif" }
-    { :id :mystics   :image "HomeSystem/Tile-HS-Mystics.gif" }
-    { :id :naalu   :image "HomeSystem/Tile-HS-Naalu.gif" }
-    { :id :narn   :image "HomeSystem/Tile-HS-Narn.gif" }
-    { :id :necron   :image "HomeSystem/Tile-HS-Necron.gif" }
-    { :id :nekro   :image "HomeSystem/Tile-HS-Nekro.gif" }
-    { :id :norr   :image "HomeSystem/Tile-HS-Norr.gif" }
-    { :id :omohry   :image "HomeSystem/Tile-HS-Omohry.gif" }
-    { :id :ori   :image "HomeSystem/Tile-HS-Ori.gif" }
-    { :id :orion   :image "HomeSystem/Tile-HS-Orion.gif" }
-    { :id :orks   :image "HomeSystem/Tile-HS-Orks.gif" }
-    { :id :overmind   :image "HomeSystem/Tile-HS-Overmind.gif" }
-    { :id :paradisian   :image "HomeSystem/Tile-HS-Paradisian.gif" }
-    { :id :protoss   :image "HomeSystem/Tile-HS-Protoss.gif" }
-    { :id :psilons   :image "HomeSystem/Tile-HS-Psilons.gif" }
-    { :id :qikai   :image "HomeSystem/Tile-HS-Qikai.gif" }
-    { :id :raiders   :image "HomeSystem/Tile-HS-Raiders.gif" }
-    { :id :renegade   :image "HomeSystem/Tile-HS-Renegade.gif" }
-    { :id :replicator   :image "HomeSystem/Tile-HS-Replicator.gif" }
-    { :id :richese   :image "HomeSystem/Tile-HS-Richese.gif" }
-    { :id :romulan   :image "HomeSystem/Tile-HS-Romulan.gif" }
-    { :id :rrargan   :image "HomeSystem/Tile-HS-Rrargan.gif" }
-    { :id :saar   :image "HomeSystem/Tile-HS-Saar.gif" :planets { :lisis2 { :res 1 :inf 0 } :ragh { :res 2 :inf 1 } } }
-    { :id :sakkra   :image "HomeSystem/Tile-HS-Sakkra.gif" }
-    { :id :salarian   :image "HomeSystem/Tile-HS-Salarian.gif" }
-    { :id :shabbak   :image "HomeSystem/Tile-HS-Shabbak.gif" }
-    { :id :shadows   :image "HomeSystem/Tile-HS-Shadows.gif" }
-    { :id :silicoids   :image "HomeSystem/Tile-HS-Silicoids.gif" }
-    { :id :sirkaan1   :image "HomeSystem/Tile-HS-Sirkaan_1.gif" }
-    { :id :sirkaan2   :image "HomeSystem/Tile-HS-Sirkaan_2.gif" }
-    { :id :slavers   :image "HomeSystem/Tile-HS-Slavers.gif" }
-    { :id :sol   :image "HomeSystem/Tile-HS-Sol.gif" }
-    { :id :sturmgard   :image "HomeSystem/Tile-HS-Sturmgard.gif" }
-    { :id :swarm   :image "HomeSystem/Tile-HS-Swarm.gif" }
-    { :id :systems-alliance   :image "HomeSystem/Tile-HS-SystemsAlliance.gif" }
-    { :id :tau   :image "HomeSystem/Tile-HS-Tau.gif" }
-    { :id :tauri   :image "HomeSystem/Tile-HS-Tauri.gif" }
-    { :id :tellarite   :image "HomeSystem/Tile-HS-Tellarite.gif" }
-    { :id :terran   :image "HomeSystem/Tile-HS-Terran.gif" }
-    { :id :tlet   :image "HomeSystem/Tile-HS-Tlet.gif" }
-    { :id :tokra   :image "HomeSystem/Tile-HS-Tokra.gif" }
-    { :id :traelyn   :image "HomeSystem/Tile-HS-Traelyn.gif" }
-    { :id :triacterial   :image "HomeSystem/Tile-HS-Triacterial.gif" }
-    { :id :trilarians   :image "HomeSystem/Tile-HS-Trilarians.gif" }
-    { :id :trill   :image "HomeSystem/Tile-HS-Trill.gif" }
-    { :id :trillarians   :image "HomeSystem/Tile-HS-Trillarians.gif" }
-    { :id :turian   :image "HomeSystem/Tile-HS-Turian.gif" }
-    { :id :tyranid   :image "HomeSystem/Tile-HS-Tyranid.gif" }
-    { :id :vernius   :image "HomeSystem/Tile-HS-Vernius.gif" }
-    { :id :vorlon   :image "HomeSystem/Tile-HS-Vorlon.gif" }
-    { :id :vulcan   :image "HomeSystem/Tile-HS-Vulcan.gif" }
-    { :id :winnu   :image "HomeSystem/Tile-HS-Winnu.gif" }
-    { :id :xel-naga   :image "HomeSystem/Tile-HS-XelNaga.gif" }
-    { :id :xindi   :image "HomeSystem/Tile-HS-Xindi.gif" }
-    { :id :xxcha   :image "HomeSystem/Tile-HS-Xxcha.gif" }
-    { :id :yin   :image "HomeSystem/Tile-HS-Yin.gif" }
-    { :id :yssaril   :image "HomeSystem/Tile-HS-Yssaril.gif" }
-    { :id :zzedajin   :image "HomeSystem/Tile-HS-Zzedajin.gif" }
-
+    { :id :cartel    :type :home-system :image "HomeSystem/Tile-HS-Cartel.gif" }
+    { :id :centauri  :type :home-system  :image "HomeSystem/Tile-HS-Centauri.gif" }
+    { :id :chaos     :type :home-system :image "HomeSystem/Tile-HS-Chaos.gif" }
+    { :id :chromatics :type :home-system   :image "HomeSystem/Tile-HS-Chromatics.gif" }
+    { :id :corrino   :type :home-system :image "HomeSystem/Tile-HS-Corrino.gif" }
+    { :id :croax     :type :home-system :image "HomeSystem/Tile-HS-Croax.gif" }
+    { :id :dark-eldar :type :home-system   :image "HomeSystem/Tile-HS-DarkEldar.gif" }
+    { :id :darlocks  :type :home-system  :image "HomeSystem/Tile-HS-Darlocks.gif" }
+    { :id :dominion  :type :home-system  :image "HomeSystem/Tile-HS-Dominion.gif" }
+    { :id :dusun     :type :home-system  :image "HomeSystem/Tile-HS-Dusun.gif" }
+    { :id :earth     :type :home-system  :image "HomeSystem/Tile-HS-Earth.gif" }
+    { :id :eldar     :type :home-system  :image "HomeSystem/Tile-HS-Eldar.gif" }
+    { :id :elerians  :type :home-system  :image "HomeSystem/Tile-HS-Elerians.gif" }
+    { :id :elzenkar  :type :home-system  :image "HomeSystem/Tile-HS-Elzenkar.gif" }
+    { :id :embers   :type :home-system :image "HomeSystem/Tile-HS-Embers.gif" }
+    { :id :fedaron   :type :home-system :image "HomeSystem/Tile-HS-Fedaron.gif" }
+    { :id :federation :type :home-system   :image "HomeSystem/Tile-HS-Federation.gif" }
+    { :id :ferengi   :type :home-system :image "HomeSystem/Tile-HS-Ferengi.gif" }
+    { :id :firijii   :type :home-system :image "HomeSystem/Tile-HS-Firijii.gif" }
+    { :id :geth      :type :home-system :image "HomeSystem/Tile-HS-Geth.gif" }
+    { :id :gnolams   :type :home-system :image "HomeSystem/Tile-HS-Gnolams.gif" }
+    { :id :goauld    :type :home-system :image "HomeSystem/Tile-HS-Goauld.gif" }
+    { :id :harkonnen  :type :home-system  :image "HomeSystem/Tile-HS-Harkonnen.gif" }
+    { :id :hirogen   :type :home-system :image "HomeSystem/Tile-HS-Hirogen.gif" }
+    { :id :humans   :type :home-system :image "HomeSystem/Tile-HS-Humans.gif" }
+    { :id :imperium-of-man :type :home-system   :image "HomeSystem/Tile-HS-Imperium_of_Man.gif" }
+    { :id :ironleague :type :home-system   :image "HomeSystem/Tile-HS-Ironleague.gif" }
+    { :id :jipa      :type :home-system :image "HomeSystem/Tile-HS-Jipa.gif" }
+    { :id :kazon     :type :home-system :image "HomeSystem/Tile-HS-Kazon.gif" }
+    { :id :klackon   :type :home-system :image "HomeSystem/Tile-HS-Klackon.gif" }
+    { :id :klingon   :type :home-system :image "HomeSystem/Tile-HS-Klingon.gif" }
+    { :id :krenim    :type :home-system :image "HomeSystem/Tile-HS-Krenim.gif" }
+    { :id :krogan    :type :home-system :image "HomeSystem/Tile-HS-Krogan.gif" }
+    { :id :lun       :type :home-system :image "HomeSystem/Tile-HS-Lun.gif" }
+    { :id :mahact-sodality :type :home-system   :image "HomeSystem/Tile-HS-Mahact_Sodality.gif" }
+    { :id :maquis    :type :home-system :image "HomeSystem/Tile-HS-Maquis.gif" }
+    { :id :meklars   :type :home-system :image "HomeSystem/Tile-HS-Meklars.gif" }
+    { :id :minbari   :type :home-system :image "HomeSystem/Tile-HS-Minbari.gif" }
+    { :id :mirssen   :type :home-system :image "HomeSystem/Tile-HS-Mirssen.gif" }
+    { :id :moritani  :type :home-system :image "HomeSystem/Tile-HS-Moritani.gif" }
+    { :id :mrrshan   :type :home-system :image "HomeSystem/Tile-HS-Mrrshan.gif" }
+    { :id :mystics   :type :home-system :image "HomeSystem/Tile-HS-Mystics.gif" }
+    { :id :narn      :type :home-system :image "HomeSystem/Tile-HS-Narn.gif" }
+    { :id :necron    :type :home-system :image "HomeSystem/Tile-HS-Necron.gif" }
+    { :id :norr      :type :home-system :image "HomeSystem/Tile-HS-Norr.gif" }
+    { :id :omohry    :type :home-system :image "HomeSystem/Tile-HS-Omohry.gif" }
+    { :id :ori       :type :home-system :image "HomeSystem/Tile-HS-Ori.gif" }
+    { :id :orion     :type :home-system :image "HomeSystem/Tile-HS-Orion.gif" }
+    { :id :orks      :type :home-system :image "HomeSystem/Tile-HS-Orks.gif" }
+    { :id :overmind  :type :home-system :image "HomeSystem/Tile-HS-Overmind.gif" }
+    { :id :paradisian :type :home-system  :image "HomeSystem/Tile-HS-Paradisian.gif" }
+    { :id :protoss   :type :home-system :image "HomeSystem/Tile-HS-Protoss.gif" }
+    { :id :psilons   :type :home-system :image "HomeSystem/Tile-HS-Psilons.gif" }
+    { :id :qikai     :type :home-system :image "HomeSystem/Tile-HS-Qikai.gif" }
+    { :id :raiders   :type :home-system :image "HomeSystem/Tile-HS-Raiders.gif" }
+    { :id :renegade  :type :home-system :image "HomeSystem/Tile-HS-Renegade.gif" }
+    { :id :replicator :type :home-system  :image "HomeSystem/Tile-HS-Replicator.gif" }
+    { :id :richese   :type :home-system :image "HomeSystem/Tile-HS-Richese.gif" }
+    { :id :romulan   :type :home-system :image "HomeSystem/Tile-HS-Romulan.gif" }
+    { :id :rrargan   :type :home-system :image "HomeSystem/Tile-HS-Rrargan.gif" }
+    { :id :sakkra    :type :home-system :image "HomeSystem/Tile-HS-Sakkra.gif" }
+    { :id :salarian  :type :home-system :image "HomeSystem/Tile-HS-Salarian.gif" }
+    { :id :shabbak   :type :home-system :image "HomeSystem/Tile-HS-Shabbak.gif" }
+    { :id :shadows   :type :home-system :image "HomeSystem/Tile-HS-Shadows.gif" }
+    { :id :silicoids :type :home-system :image "HomeSystem/Tile-HS-Silicoids.gif" }
+    { :id :sirkaan1  :type :home-system :image "HomeSystem/Tile-HS-Sirkaan_1.gif" }
+    { :id :sirkaan2  :type :home-system :image "HomeSystem/Tile-HS-Sirkaan_2.gif" }
+    { :id :slavers   :type :home-system :image "HomeSystem/Tile-HS-Slavers.gif" }
+    { :id :sturmgard :type :home-system  :image "HomeSystem/Tile-HS-Sturmgard.gif" }
+    { :id :swarm     :type :home-system :image "HomeSystem/Tile-HS-Swarm.gif" }
+    { :id :systems-alliance :type :home-system   :image "HomeSystem/Tile-HS-SystemsAlliance.gif" }
+    { :id :tau      :type :home-system :image "HomeSystem/Tile-HS-Tau.gif" }
+    { :id :tauri    :type :home-system :image "HomeSystem/Tile-HS-Tauri.gif" }
+    { :id :tellarite :type :home-system  :image "HomeSystem/Tile-HS-Tellarite.gif" }
+    { :id :terran   :type :home-system :image "HomeSystem/Tile-HS-Terran.gif" }
+    { :id :tlet     :type :home-system :image "HomeSystem/Tile-HS-Tlet.gif" }
+    { :id :tokra    :type :home-system :image "HomeSystem/Tile-HS-Tokra.gif" }
+    { :id :traelyn  :type :home-system :image "HomeSystem/Tile-HS-Traelyn.gif" }
+    { :id :triacterial :type :home-system  :image "HomeSystem/Tile-HS-Triacterial.gif" }
+    { :id :trilarians :type :home-system  :image "HomeSystem/Tile-HS-Trilarians.gif" }
+    { :id :trill    :type :home-system  :image "HomeSystem/Tile-HS-Trill.gif" }
+    { :id :trillarians  :type :home-system  :image "HomeSystem/Tile-HS-Trillarians.gif" }
+    { :id :turian   :type :home-system  :image "HomeSystem/Tile-HS-Turian.gif" }
+    { :id :tyranid  :type :home-system   :image "HomeSystem/Tile-HS-Tyranid.gif" }
+    { :id :vernius  :type :home-system  :image "HomeSystem/Tile-HS-Vernius.gif" }
+    { :id :vorlon   :type :home-system  :image "HomeSystem/Tile-HS-Vorlon.gif" }
+    { :id :vulcan   :type :home-system  :image "HomeSystem/Tile-HS-Vulcan.gif" }
+    { :id :xel-naga :type :home-system  :image "HomeSystem/Tile-HS-XelNaga.gif" }
+    { :id :xindi    :type :home-system  :image "HomeSystem/Tile-HS-Xindi.gif" }
+    { :id :zzedajin :type :home-system  :image "HomeSystem/Tile-HS-Zzedajin.gif" }
+
+    ; Special systems
     { :id :empty :image "Special/Tile-Empty.gif" }
     { :id :galactic-storm :image "Special/Tile-Galactic_Storm.gif" }
     { :id :gravity-well :image "Special/Tile-Gravity_Well.gif" }
@@ -294,20 +402,10 @@
     { :id :blackHole :image "Special/Tile-BlackHole.gif" }
     { :id :pulsar :image "Special/Tile-Pulsar.gif" }
     { :id :nebula, :type :nebula, :image "Special/Tile-Nebula.gif" }
-
-    { :id :babylon5 :image "Special/Tile-Babylon_5.gif" }
-    { :id :citadel :image "Special/Tile-Citadel.gif" }
-    { :id :cormund :image "Special/Tile-Cormund.gif" }
-    { :id :mecatol-rex :image "Special/Tile-Mecatol_Rex.gif" }
-    { :id :mecatol-rex09 :image "Special/Tile-Mecatol_Rex09.gif" }
-    { :id :muaat-supernova :image "Special/Tile-Muaat-Supernova.gif" }
-    { :id :old-mecatol-rex :image "Special/Tile-OldMecatolRex.gif" }
-    { :id :orion2 :image "Special/Tile-Orion2.gif" }
-    { :id :quantum-singularity :image "Special/Tile-Quantum_Singularity.gif" }
-    { :id :summer-palace :image "Special/Tile-Summer_Palace.gif" }
-    { :id :Supernova :image "Special/Tile-Supernova.gif" }
     { :id :wormhole-a :image "Special/Tile-Wormhole_A.gif" }
     { :id :wormhole-b :image "Special/Tile-Wormhole_B.gif" }
+    { :id :supernova :image "Special/Tile-Supernova.gif" }
+    { :id :quantum-singularity :image "Special/Tile-Quantum_Singularity.gif" }

     { :id :setup-dark-blue, :type :setup, :image "Setup/Tile-Setup-DarkBlue.gif" }
     { :id :setup-light-blue, :type :setup, :image "Setup/Tile-Setup-LightBlue.gif" }


Fixed dependency package in id_set_triples.clj

--- src/kabob/build/id_sets/id_set_triples.clj
+++ src/kabob/build/id_sets/id_set_triples.clj
@@ -1,6 +1,6 @@
 (ns kabob.build.id-sets.id-set-triples
   (use kabob.build.id-sets.id-sets
-       kabob.util.union-find
+       kabob.core.util.union-find

        clojure.pprint
        clojure.stacktrace


Change signature of IBuffer related functions.

--- src/bytebuf/buffer.clj
+++ src/bytebuf/buffer.clj
@@ -6,10 +6,10 @@

 (defprotocol IBuffer
-  (read-integer* [_] "Read an integer (32 bits) from buffer.")
-  (read-long* [_] "Read an long (64 bits) from buffer.")
-  (tell* [_] "Get the current position index of buffer.")
-  (seek* [_ val] "Set the current position index on buffer."))
+  (read-int [_ pos] "Read an integer (32 bits) from buffer.")
+  (write-int [_ pos value] "Write an integer to the buffer.")
+  (read-long [_ pos] "Read an long (64 bits) from buffer.")
+  (write-long [_ pos value] "Write an long to the buffer."))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; NIO ByteBuffer implementation


Revert "add :copy-deps true to the default project template so that global :dev-deps will work"

This reverts commit 5992af49827e8e235282ba49663fd8a256b768eb.

--- src/cake/tasks/new.clj
+++ src/cake/tasks/new.clj
@@ -10,8 +10,7 @@
 (def default-template
 "(defproject +project+ \"0.0.1-SNAPSHOT\"
   :description \"TODO: add summary of your project\"
-  :dependencies [[clojure \"1.2.0\"]]
-  :copy-deps true)
+  :dependencies [[clojure \"1.2.0\"]])
 ")

 (def template-dir (file "~" ".cake" "templates"))


Repaired error in background color.

Repaired error in background color.

Remember that the "style" attribute of an element needs a value of type
**string** and not of type Object (a map). Argh!

--- src/hello_closure_cljs/core.cljs
+++ src/hello_closure_cljs/core.cljs
@@ -11,9 +11,8 @@

 (defn say-hi []
   (let [new-header
-        (dom/createDom "h1"
-                       #js {:style
-                            #js {:backgroundColor "#eee"}}
+        (dom/createDom "h1"
+                       #js {:style "background-color:#EEE"}
                        "Hello Closure World!")]
     (println "Where am I?")
     (dom/appendChild (.-body js/document) new-header)))


Fix html spec to work with coerced dates.

--- spec/incise/parsers/html_spec.clj
+++ spec/incise/parsers/html_spec.clj
@@ -1,6 +1,7 @@
 (ns incise.parsers.html-spec
   (:require [incise.parsers.html :refer :all]
             [incise.parsers.core :refer [map->Parse]]
+            [clj-time.coerce :refer [to-date]]
             [clojure.java.io :refer [file resource]]
             [speclj.core :refer :all]))

@@ -9,7 +10,7 @@
   (it "reads some stuff out of a file, yo"
     (should= (map->Parse {:title "My Short Page"
                           :layout :page
-                          :date "2013-08-12"
+                          :date (to-date "2013-08-12")
                           :path "2013/8/12/my-short-page/index.html"
                           :tags [:cool]
                           :category :blarg


Another test of per-mutation res-ch.

Another test of per-mutation res-ch.

--- src/cbfg/test/kvs.cljs
+++ src/cbfg/test/kvs.cljs
@@ -371,6 +371,32 @@
                                 (dissoc (merge m7bs {:status :ok})
                                         :change-reqs)
                                 (atake tkvs res-ch7bs)))))
+                        (let [res-ch7bs-1 (achan tkvs) ; Test change with bad sq.
+                              m7bs {:opaque @n
+                                    :op :multi-change
+                                    :kvs-ident (:kvs-ident open)
+                                    :change-reqs [{:change-fn
+                                                   (cbfg.kvs/mutate-entry
+                                                    {:key :a
+                                                     :val :will-be-rejected
+                                                     :sq :some-wrong-sq})
+                                                   :res-ch res-ch7bs-1}]}]
+                          (aput tkvs cmd-ch m7bs)
+                          (let [res7bs (atake tkvs res-ch7bs-1)]
+                            (and
+                             (e n res7bs
+                                (dissoc (merge m7bs
+                                               {:more true
+                                                :status :mismatch
+                                                :status-info [:wrong-sq
+                                                               :some-wrong-sq]
+                                                :key :a})
+                                        :change-reqs)
+                                nil)
+                             (e n (atake tkvs res-ch7bs-1)
+                                (dissoc (merge m7bs {:status :ok})
+                                        :change-reqs)
+                                (atake tkvs res-ch7bs-1)))))
                         (let [res-ch7c (achan tkvs) ; Test change with right sq.
                               m7c {:opaque @n
                                    :res-ch res-ch7c


Whitespace.

Whitespace.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -87,9 +87,9 @@
 (defn make-partition [actx sq path kvs-mgr-ch]
   (let [partition-ch (achan actx)
         partition-res {:sq sq
-                  :path path
-                  :partition-ch partition-ch
-                  :kvs-mgr-ch kvs-mgr-ch}]
+                       :path path
+                       :partition-ch partition-ch
+                       :kvs-mgr-ch kvs-mgr-ch}]
     (act partition-init actx
          (let [res (areq partition-init kvs-mgr-ch {:op :kvs-open :name [path sq]})]
            (if (= (:status res) :ok)
@@ -351,6 +351,8 @@
   (init-server :kv-server server-addr ports
                make-initial-server-state initial-lane-state))

+; --------------------------------------------
+
 (defn kv-client [client-addr server-addr server-port]
   (let [world (:world (prog-base-now))
         ready (atom false)


increasing timeout to 5 min

increasing timeout to 5 min

--- src/celestial/jobs.clj
+++ src/celestial/jobs.clj
@@ -42,7 +42,7 @@
 (defn save-status
    "marks jobs as succesful"
    [spec status]
-  (let [id (add-job-status (merge spec {:status status :end (System/currentTimeMillis)})) status-exp 60]
+  (let [id (add-job-status (merge spec {:status status :end (System/currentTimeMillis)})) status-exp (* 5 60)]
     (wcar (car/expire (job-status-id id) status-exp)) {:status status}))

 (defn job-exec [f  {:keys [message attempt]}]


converted the decode to use case instead of condp

--- src/chip8_clj/core.clj
+++ src/chip8_clj/core.clj
@@ -29,101 +29,56 @@
         nibble3 (utils/get-nibble3 opcode)]
     (log/debug (format "decode-and-execute: opcode: 0x%04x, byte0: 0x%02x, byte1: 0x%02x"
                        opcode byte0 byte1))
-    (cond
-      (= nibble0 0x0)
-        (cond
-          (and (= nibble1 0x0) (= byte1 0xE0))
-            (instructions/execute-00E0 machine-state opcode)
-          (and (= nibble1 0x0) (= byte1 0xEE))
-            (instructions/execute-00EE machine-state opcode)
-          :else
+    (case nibble0
+      0x0 (case nibble1
+            0x0 (case byte1
+                  0xE0 (instructions/execute-00E0 machine-state opcode)
+                  0xEE (instructions/execute-00EE machine-state opcode)
+                  (unknown-opcode-error opcode))
             (instructions/execute-0NNN machine-state opcode))
-      (= nibble0 0x1)
-        (instructions/execute-1NNN machine-state opcode)
-      (= nibble0 0x2)
-        (instructions/execute-2NNN machine-state opcode)
-      (= nibble0 0x3)
-        (instructions/execute-3XNN machine-state opcode)
-      (= nibble0 0x4)
-        (instructions/execute-4XNN machine-state opcode)
-      (= nibble0 0x5)
-        (cond
-          (= nibble3 0x0)
-            (instructions/execute-5XY0 machine-state opcode)
-          :else
+      0x1 (instructions/execute-1NNN machine-state opcode)
+      0x2 (instructions/execute-2NNN machine-state opcode)
+      0x3 (instructions/execute-3XNN machine-state opcode)
+      0x4 (instructions/execute-4XNN machine-state opcode)
+      0x5 (case nibble3
+            0x0 (instructions/execute-5XY0 machine-state opcode)
             (unknown-opcode-error opcode))
-      (= nibble0 0x6)
-        (instructions/execute-6XNN machine-state opcode)
-      (= nibble0 0x7)
-        (instructions/execute-7XNN machine-state opcode)
-      (= nibble0 0x8)
-        (cond
-          (= nibble3 0x0)
-            (instructions/execute-8XY0 machine-state opcode)
-          (= nibble3 0x1)
-            (instructions/execute-8XY1 machine-state opcode)
-          (= nibble3 0x2)
-            (instructions/execute-8XY2 machine-state opcode)
-          (= nibble3 0x3)
-            (instructions/execute-8XY3 machine-state opcode)
-          (= nibble3 0x4)
-            (instructions/execute-8XY4 machine-state opcode)
-          (= nibble3 0x5)
-            (instructions/execute-8XY5 machine-state opcode)
-          (= nibble3 0x6)
-            (instructions/execute-8XY6 machine-state opcode)
-          (= nibble3 0x7)
-            (instructions/execute-8XY7 machine-state opcode)
-          (= nibble3 0xE)
-            (instructions/execute-8XYE machine-state opcode)
-          :else
+      0x6 (instructions/execute-6XNN machine-state opcode)
+      0x7 (instructions/execute-7XNN machine-state opcode)
+      0x8 (case nibble3
+            0x0 (instructions/execute-8XY0 machine-state opcode)
+            0x1 (instructions/execute-8XY1 machine-state opcode)
+            0x2 (instructions/execute-8XY2 machine-state opcode)
+            0x3 (instructions/execute-8XY3 machine-state opcode)
+            0x4 (instructions/execute-8XY4 machine-state opcode)
+            0x5 (instructions/execute-8XY5 machine-state opcode)
+            0x6 (instructions/execute-8XY6 machine-state opcode)
+            0x7 (instructions/execute-8XY7 machine-state opcode)
+            0xE (instructions/execute-8XYE machine-state opcode)
             (unknown-opcode-error opcode))
-      (= nibble0 0x9)
-        (cond
-          (= nibble3 0x0)
-            (instructions/execute-9XY0 machine-state opcode)
-          :else
+      0x9 (case nibble3
+            0x0 (instructions/execute-9XY0 machine-state opcode)
             (unknown-opcode-error opcode))
-      (= nibble0 0xa)
-        (instructions/execute-ANNN machine-state opcode)
-      (= nibble0 0xb)
-        (instructions/execute-BNNN machine-state opcode)
-      (= nibble0 0xc)
-        (instructions/execute-CXNN machine-state opcode)
-      (= nibble0 0xd)
-        (instructions/execute-DXYN machine-state opcode)
-      (= nibble0 0xe)
-        (cond
-          (= byte1 0x9E)
-            (instructions/execute-EX9E machine-state opcode)
-          (= byte1 0xA1)
-            (instructions/execute-EXA1 machine-state opcode)
-          :else
+      0xa (instructions/execute-ANNN machine-state opcode)
+      0xb (instructions/execute-BNNN machine-state opcode)
+      0xc (instructions/execute-CXNN machine-state opcode)
+      0xd (instructions/execute-DXYN machine-state opcode)
+      0xe (case byte1
+            0x9E (instructions/execute-EX9E machine-state opcode)
+            0xA1 (instructions/execute-EXA1 machine-state opcode)
             (unknown-opcode-error opcode))
-      (= nibble0 0xf)
-        (cond
-          (= byte1 0x07)
-            (instructions/execute-FX07 machine-state opcode)
-          (= byte1 0x0A)
-            (instructions/execute-FX0A machine-state opcode)
-          (= byte1 0x15)
-            (instructions/execute-FX15 machine-state opcode)
-          (= byte1 0x18)
-            (instructions/execute-FX18 machine-state opcode)
-          (= byte1 0x1E)
-            (instructions/execute-FX1E machine-state opcode)
-          (= byte1 0x29)
-            (instructions/execute-FX29 machine-state opcode)
-          (= byte1 0x33)
-            (instructions/execute-FX33 machine-state opcode)
-          (= byte1 0x55)
-            (instructions/execute-FX55 machine-state opcode)
-          (= byte1 0x65)
-            (instructions/execute-FX65 machine-state opcode)
-          :else
+      0xf (case byte1
+            0x07 (instructions/execute-FX07 machine-state opcode)
+            0x0A (instructions/execute-FX0A machine-state opcode)
+            0x15 (instructions/execute-FX15 machine-state opcode)
+            0x18 (instructions/execute-FX18 machine-state opcode)
+            0x1E (instructions/execute-FX1E machine-state opcode)
+            0x29 (instructions/execute-FX29 machine-state opcode)
+            0x33 (instructions/execute-FX33 machine-state opcode)
+            0x55 (instructions/execute-FX55 machine-state opcode)
+            0x65 (instructions/execute-FX65 machine-state opcode)
             (unknown-opcode-error opcode))
-      :else
-        (unknown-opcode-error opcode))))
+      (unknown-opcode-error opcode))))

 (defn step
   [machine-state]


update code that determines jdbc connection timezone to fall back to the Org :report_timezone if it is set.

--- src/metabase/driver/generic_sql/native.clj
+++ src/metabase/driver/generic_sql/native.clj
@@ -51,12 +51,14 @@
          (integer? database-id)]}
   (log/debug "QUERY: \n"
              (with-out-str (clojure.pprint/pprint query)))
-  (try (let [db (-> (sel :one Database :id database-id)
+  (try (let [database (sel :one Database :id database-id)
+             db (-> database
                     korma-db
                     korma.db/get-connection)
              [columns & [first-row :as rows]] (jdbc/with-db-transaction [conn db :read-only? true]
                                                 ;; If timezone is specified in the Query and the driver supports setting the timezone then execute SQL to set it
-                                                (when-let [timezone (-> query :native :timezone)]
+                                                (when-let [timezone (or (-> query :native :timezone)
+                                                                        (-> @(:organization database) :report_timezone))]
                                                   (when-let [set-timezone-sql (*timezone->set-timezone-sql* timezone)]
                                                     (log/debug "Setting timezone to:" timezone)
                                                     (jdbc/db-do-prepared conn set-timezone-sql)))


Tweak whitespace

Tweak whitespace

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -489,9 +489,8 @@
        dispatch-table-compilation-defaults
        dispatch-table))
   ([options dispatch-table]
-     (let [options          (merge dispatch-table-compilation-defaults options)
-           build-handler    (:build-handler-fn options)
-
+     (let [options       (merge dispatch-table-compilation-defaults options)
+           build-handler (:build-handler-fn options)
            analysed-dispatch-table (analyse-dispatch-table dispatch-table)]
        (build-handler analysed-dispatch-table
          (select-keys options [:async?])))))


Put the construction of bass into a single form.

--- src/overtunes/songs/canone_alla_quarta.clj
+++ src/overtunes/songs/canone_alla_quarta.clj
@@ -45,27 +45,26 @@
     (-> notes ground-time functionalise)))

 (def leader
-  (let [call {:time (concat (repeat 2 1/4) [1/2] (repeat 14 1/4) [3/2])
-              :pitch (concat [0] (run -1 3) (run 2 0) [4] (run 1 8))}
+  (let [call
+          {:time (concat (repeat 2 1/4) [1/2] (repeat 14 1/4) [3/2])
+           :pitch (concat [0] (run -1 3) (run 2 0) [4] (run 1 8))}
         response
-             {:time (concat (repeat 10 1/4) [1/2] (repeat 2 1/4) [9/4])
-              :pitch (concat (run 7 -1) [0] (run 0 -3))}
+          {:time (concat (repeat 10 1/4) [1/2] (repeat 2 1/4) [9/4])
+           :pitch (concat (run 7 -1) [0] (run 0 -3))}
         development
-             {:time (concat [3/4] (repeat 12 1/4) [1/2 1 1/2] (repeat 12 1/4) [3])
-              :pitch (concat [4 4] (run 2 -3) [-1 -2 0] (run 3 5) (repeat 3 1) [2] (run -1 1) [0 -1] (run 5 0))}
-        mainline
-             (merge-with concat call response development)]
-    (melody mainline)))
-
-(def bassline
-  {:time (repeat 24 1)
-   :pitch (mapcat (partial repeat 3) (concat (run 0 -3) (run -5 -3) [0 7]))})
+          {:time (concat [3/4] (repeat 12 1/4) [1/2 1 1/2] (repeat 12 1/4) [3])
+           :pitch (concat [4 4] (run 2 -3) [-1 -2 0] (run 3 5) (repeat 3 1) [2] (run -1 1) [0 -1] (run 5 0))}
+        line
+          (merge-with concat call response development)]
+    (melody line)))

 (def bass
- (let [lower-note #(- % 7)
-       lower-melody (update :pitch #(connect lower-note %))]
+  (let [line
+          {:time (repeat 24 1)
+           :pitch (mapcat (partial repeat 3) (concat (run 0 -3) (run -5 -3) [0 7]))}
+        lower-note #(- % 7)
+        lower-melody (update :pitch #(connect lower-note %))]
    (-> bassline melody lower-melody)))
-

 (defn melody# [melody]
   (let [notes (update-all melody [:pitch :time] natural-seq)


fix recent articles caching

fix recent articles caching

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -86,7 +86,7 @@
                       (remove nil?)
                       (mapv format-article))
         data (extract-tweet-data tweet)]
-    (swap! state update-in [:app :recent-articles] (fn [old new] (vec (take 100 (into old new)))) articles)
+    (swap! state update-in [:app :recent-articles] (fn [old new] (vec (take 250 (into new old)))) articles)
     (when (not(empty? articles))
       (doall (map #(put! % {:topic :new-article :data articles}) (-> @state :app :out-chans))))
     (swap! state update-in [:app :recent-tweets] (fn [old new] (vec (take 100 (into [new] old)))) tweet)))


Use codox fn linking for docstring

Use codox fn linking for docstring

--- src/caesium/crypto/secretbox.clj
+++ src/caesium/crypto/secretbox.clj
@@ -57,12 +57,12 @@
     (secretbox-open-easy-to-buf! out ctext nonce key)))

 (defn encrypt
-  "Backwards-compatible alias for `secretbox-easy`."
+  "Backwards-compatible alias for [[secretbox-easy]]."
   [key nonce plaintext]
   (secretbox-easy plaintext nonce key))

 (defn decrypt
-  "Backwards-compatible alias for `secretbox-open-easy`."
+  "Backwards-compatible alias for [[secretbox-open-easy]]."
   [key nonce ciphertext]
   (secretbox-open-easy ciphertext nonce key))