increase influxdb size

increase influxdb size

--- src/terraboot/vpc.clj
+++ src/terraboot/vpc.clj
@@ -102,13 +102,22 @@
                                                :associate_public_ip_address true
                                                })

+             (vpc-resource "aws_ebs_volume" "influxdb"
+                           {:availability_zone region
+                            :size 20})
+
              (aws-instance "influxdb" {:ami "ami-9b9c86f7"
+                                       :instance_type "m4.large"
                                        :vpc_security_group_ids [(vpc-id-of "aws_security_group" "influxdb")
                                                                 (id-of "aws_security_group" "allow_ssh")
                                                                 (vpc-id-of "aws_security_group" "allow_elb_chronograf")
                                                                 ]
-                                       :subnet_id (vpc-id-of "aws_subnet" "public-a")
-                                       })
+                                       :subnet_id (vpc-id-of "aws_subnet" "public-a")})
+
+             (vpc-resource "aws_volume_attachment" "influxdb_volume"
+                           {:device_name "/dev/xvdh"
+                            :instance_id (id-of "aws_instance" "influxdb")
+                            :volume_id (vpc-id-of "aws_ebs_volume" "influxdb")})

              (elb "chronograf" resource {:name "chronograf"
                                          :health_check {:healthy_threshold 2


Fix dismiss-all media-type.

Fix dismiss-all media-type.

--- src/oc/storage/representations/activity.clj
+++ src/oc/storage/representations/activity.clj
@@ -84,7 +84,7 @@
         links (remove nil?
                [(hateoas/link-map collection-rel hateoas/GET collection-url {:accept mt/activity-collection-media-type} {})
                 (if inbox? ;; Inbox has no sort
-                 (hateoas/link-map "dismiss-all" hateoas/POST (dismiss-all-url org) {:accept mt/activity-collection-media-type} {})
+                 (hateoas/link-map "dismiss-all" hateoas/POST (dismiss-all-url org) {:accept mt/entry-media-type} {})
                  (hateoas/link-map other-sort-rel hateoas/GET other-sort-url {:accept mt/activity-collection-media-type} {}))
                 (hateoas/up-link (org-rep/url org) {:accept mt/org-media-type})])
         full-links (concat links (pagination-links org collection-type sort-type params activity))]


define a constant var for literal

define a constant var for literal

--- storm-core/src/clj/backtype/storm/stats.clj
+++ storm-core/src/clj/backtype/storm/stats.clj
@@ -28,6 +28,8 @@
   (:use [backtype.storm.daemon [common :only [system-id?]]]))

 ;;TODO: consider replacing this with some sort of RRD
+
+(def TEN-MIN-IN-SECONDS (* 10 60))

 (defn curr-time-bucket
   [^Integer time-secs ^Integer bucket-size-secs]
@@ -464,13 +466,13 @@
       (merge-with (fn weighted-avg+count-fn
                     [avg cnt]
                     [(* avg cnt) cnt])
-                  (get (:execute-latencies m) "600")
-                  (get (:executed m) "600"))
+                  (get (:execute-latencies m) (str TEN-MIN-IN-SECONDS))
+                  (get (:executed m) (str TEN-MIN-IN-SECONDS)))
       vals ;; Ignore the stream ids.
       (reduce add-pairs
               [0. 0]) ;; Combine weighted averages and counts.
       ((fn [[weighted-avg cnt]]
-        (div weighted-avg (* 1000 (min uptime 600))))))))
+        (div weighted-avg (* 1000 (min uptime TEN-MIN-IN-SECONDS))))))))

 (defn agg-pre-merge-comp-page-bolt
   [{exec-id :exec-id
@@ -1518,9 +1520,9 @@
                     (aggregate-bolt-stats true)
                     (aggregate-bolt-streams)
                     swap-map-order
-                    (get "600")))
+                    (get (str TEN-MIN-IN-SECONDS))))
         uptime (nil-to-zero (.get_uptime_secs e))
-        window (if (< uptime 600) uptime 600)
+        window (if (< uptime TEN-MIN-IN-SECONDS) uptime TEN-MIN-IN-SECONDS)
         executed (-> stats :executed nil-to-zero)
         latency (-> stats :execute-latencies nil-to-zero)]
     (if (> window 0)


[STORM-1427] delete tuple.clj

[STORM-1427] delete tuple.clj

--- storm-core/src/clj/backtype/storm/tuple.clj
+++ storm-core/src/clj/backtype/storm/tuple.clj
@@ -1,24 +0,0 @@
-;; Licensed to the Apache Software Foundation (ASF) under one
-;; or more contributor license agreements.  See the NOTICE file
-;; distributed with this work for additional information
-;; regarding copyright ownership.  The ASF licenses this file
-;; to you under the Apache License, Version 2.0 (the
-;; "License"); you may not use this file except in compliance
-;; with the License.  You may obtain a copy of the License at
-;;
-;; http://www.apache.org/licenses/LICENSE-2.0
-;;
-;; Unless required by applicable law or agreed to in writing, software
-;; distributed under the License is distributed on an "AS IS" BASIS,
-;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-;; See the License for the specific language governing permissions and
-;; limitations under the License.
-
-(ns backtype.storm.tuple
-  (:import [java.util Arrays List]))
-
-(defn list-hash-code
-  [^List alist]
-  (if (nil? alist)
-    1
-    (Arrays/deepHashCode (.toArray alist))))


add extra failure output

add extra failure output

--- test/clj_money/models/transactions_test.clj
+++ test/clj_money/models/transactions_test.clj
@@ -623,6 +623,7 @@
       (pprint-diff expected-checking actual-checking)
       (is (= expected-checking actual-checking)
           "Checking items should have the correct values after update")
+      (pprint-diff expected-groceries actual-groceries)
       (is (= expected-groceries actual-groceries)
           "Groceries items should have the correct values after update"))
     (assert-account-quantities checking 798.01M groceries 201.99M)))


CMR-6270 -- updated references to latest  Preview Gem (#915)

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -10,9 +10,9 @@
    the hardcoded commit id during dev integration with cmr_metadata_preview project.
    The hardcoded commit id should be updated when MMT releases a new version of the gem."
   {:repo "https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git"
-   :version "cmr_metadata_preview-0.2.0"
+   :version "cmr_metadata_preview-0.2.1"
    :commit-id (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-                  "5dc1e67b1a")})
+                  "1d700ebba34")})

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


remove debug comment

remove debug comment

--- src-cljs/frontend/rtc.cljs
+++ src-cljs/frontend/rtc.cljs
@@ -61,8 +61,7 @@
     (.close conn)))

 (defn new-peer-conn [extra-servers]
-  (PeerConnection. (clj->js (update-in config [:iceServers] concat nil;extra-servers
-                                       ))))
+  (PeerConnection. (clj->js (update-in config [:iceServers] concat extra-servers))))

 (defn handle-negotiation [conn {:keys [signal-fn comms] :as signal-data}]
   (.createOffer conn


revert spurious debugging change

revert spurious debugging change

--- src-cljs/frontend/utils.cljs
+++ src-cljs/frontend/utils.cljs
@@ -91,7 +91,7 @@
                      (config/logging-enabled?)))

 (defn mlog [& messages]
-  (when true #_(logging-enabled?)
+  (when (logging-enabled?)
     (.apply (.-log js/console) js/console (clj->js messages))))

 (defn mwarn [& messages]


Better UI handling of operations on shown references

- Disabling Skip button if there aren't any remaining elements
- Disabling the Interesting button if we don't have an item to show
- Fixed a bug where we tried to do a ran-nth on an empty collection,
  which raises an exception (doing it on nil is valid, though)

https://app.asana.com/0/29043151838323/35000461625276

--- src-cljs/tropology/core.cljs
+++ src-cljs/tropology/core.cljs
@@ -91,7 +91,7 @@
   :pick-random-reference
   (fn [app-state [_]]
     (let [tropes  (get-in app-state [:article-data :tropes])
-          pick    (rand-nth tropes)
+          pick    (rand-nth (not-empty tropes))
           element (if (nil? pick) {} pick)]
       (assoc-in app-state [:article-data :current-reference] element))))

@@ -179,8 +179,8 @@
                                    :id    id}]))

-(defn button-item [label class dispatch-vals]
-  [:button {:type "button" :class (str "btn " class) :on-click #(re-frame/dispatch dispatch-vals)} label])
+(defn button-item [label class dispatch-vals is-disabled?]
+  [:button {:type "button" :class (str "btn " class) :disabled is-disabled? :on-click #(re-frame/dispatch dispatch-vals)} label])

 (defn nav-item [selected item-key label]
   [:li {:class (when (= selected item-key) "active")}
@@ -214,7 +214,7 @@
   [:div {:class class}
    [bind-fields trope-code-form form-data]
    [:div
-    [button-item "Graph!" "btn-primary" [:draw-graph (:trope-code @form-data)]]
+    [button-item "Graph!" "btn-primary" [:draw-graph (:trope-code @form-data)] false]
     [:div {:id "graph-container"}]]]
   )

@@ -244,15 +244,16 @@
          [:p (process-trope @current-ref [true])]
          [:div [:span (str "(" @remaining " remaining)")]]
          [:div
-          [button-item "Interesting" "btn-success" [:vote :like]]
-          [button-item "Skip" "btn-info" [:vote :skip]]]])
+          [button-item "Interesting" "btn-success" [:vote :like] (empty? @current-ref)]
+          [button-item "Skip" "btn-info" [:vote :skip] (>=  0 @remaining)]]])
       (if (some? @like-list)
         [:div {:id "trope-list-container"}
-         [:p "Selected items: "]
+         [:hr]
+         [:h2 "Selected items"]
          [:ul
           (for [trope @like-list]
             ^{:key (hash trope)} [:li (process-trope (:ref trope) [false])
-                                  " (" [:a {:on-click #(re-frame/dispatch [:load-article (:code trope) false])} (:display trope)] ")"  ])]
+                                  " (" [:a {:on-click #(re-frame/dispatch [:load-article (:code trope) false])} (:display trope)] ")"])]
          ])
       ]])
   )


Rely on default for :optimizations

Rely on default for :optimizations

--- Clojure/project.clj
+++ Clojure/project.clj
@@ -8,6 +8,5 @@
   :source-paths ["src"]
   :compiler {
      :output-dir "out"
-     :optimizations :none
      :cache-analysis true
      :source-map true})


Fix method invocation in Clojure example

--- clojure/src/funcatron/sample/clojure/funcs.clj
+++ clojure/src/funcatron/sample/clojure/funcs.clj
@@ -13,7 +13,7 @@
       .getLogger
       (.info "In Simple Get... Clojure style"))
   (let [num (some-> c
-                    .getRequestInfo
+                    .getMergedParams
                     (.get "num"))
         num-map (if num {"num" num} {})
         ret (merge


use a faster debounce method

use a faster debounce method

--- frontend/utils.cljs
+++ frontend/utils.cljs
@@ -112,12 +112,11 @@
 (defn debounce
   "Takes a unique key and a function, will only execute the last function
    in a sliding 20ms interval (slightly longer than 16ms, time for rAF, seems to work best)"
-  [unique-key f]
-  (let [f-uuid (uuid)]
-    (swap! debounce-state assoc unique-key f-uuid)
-    (js/setTimeout #(when (= f-uuid (get @debounce-state unique-key))
-                      (f))
-                   20)))
+  [unique-key f & {:keys [timeout]
+                   :or {timeout 100}}]
+  (js/clearTimeout (get @debounce-state unique-key))
+  (let [timeout-id (js/setTimeout f timeout)]
+    (swap! debounce-state assoc unique-key timeout-id)))

 (defn edit-input
   "Meant to be used in a react event handler, usually for the :on-change event on input.


whitespace and indentation

whitespace and indentation

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -19,184 +19,163 @@
     2 "arrowRight"
     "arrowLeft"))

-(def templates {"ruby" {:language "Ruby"
-                        :headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
-                        :logo-path "/img/outer/languages/ruby-logo.svg"
-                        :features [{:feature "CircleCI provides support for a wide variety of Ruby versions and gems, including Ruby on Rails. It is trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
-                                    :title "Built For Ruby"
-                                    :icon "/img/outer/languages/gear-icon.svg"}
-                                   {:feature "Circle manages all your database requirements for you, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB as well as frameworks such as DataMapper, Mongoid, and ActiveRecord. You can also add custom database commands via your circle.yml."
-                                    :title "Database Management"
-                                    :icon "/img/outer/languages/file-icon.svg"}
-                                   {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha. Parallel builds can also be set up automatically for your Ruby projects to keep build times down."
-                                    :title "Inference That Just Works"
-                                    :icon "/img/outer/languages/book-icon.svg"}]
-                        :docs-link "/docs/language-ruby-on-rails"
-                        :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
-                                        :img "/img/outer/languages/olivier.jpg"
-                                        :author "Olivier Melcher"
-                                        :title "Developer @PasswordBox"}
-                                       {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                                        :img "/assets/img/outer/stories/john.jpg"
-                                        :author "John Duff"
-                                        :title "Director of Engineering @Shopify"}
-                                       {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                                        :img "/img/outer/languages/aaron.jpg"
-                                        :author "Aaron Suggs"
-                                        :title "Operations Engineer @Kickstarter"}]}
-                "python" {:language "Python"
-                        :headline "CircleCI makes Continous Integration and Deployment for Python projects a breeze."
-                        :logo-path "/img/outer/languages/python-logo.svg"
-                        :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
-                                    :title "Built For Ruby"
-                                    :icon "/img/outer/languages/gear-icon.svg"}
-                                   {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
-                                    :title "Database Management"
-                                    :icon "/img/outer/languages/file-icon.svg"}
-                                   {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
-                                    :title "Inference That Just Works"
-                                    :icon "/img/outer/languages/book-icon.svg"}]
-                        :docs-link "/docs/language-ruby-on-rails"
-                        :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
-                                        :img "/img/outer/languages/olivier.jpg"
-                                        :author "Olivier Melcher"
-                                        :title "Developer @PasswordBox"}
-                                       {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                                        :img "/assets/img/outer/stories/john.jpg"
-                                        :author "John Duff"
-                                        :title "Director of Engineering @Shopify"}
-                                       {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                                        :img "/img/outer/languages/aaron.jpg"
-                                        :author "Aaron Suggs"
-                                        :title "Operations Engineer @Kickstarter"}]}
-                "node" {:language "Node"
-                        :headline "CircleCI makes Continous Integration and Deployment for Node.js projects a breeze."
-                        :logo-path "/img/outer/languages/node-logo.svg"
-                        :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
-                                    :title "Built For Ruby"
-                                    :icon "/img/outer/languages/gear-icon.svg"}
-                                   {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
-                                    :title "Database Management"
-                                    :icon "/img/outer/languages/file-icon.svg"}
-                                   {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
-                                    :title "Inference That Just Works"
-                                    :icon "/img/outer/languages/book-icon.svg"}]
-                        :docs-link "/docs/language-ruby-on-rails"
-                        :testimonials [{:text "I was up and running in CircleCI with Node in literally minutes.  It guessed the correct settings and was running my tests before I even understood what was happening.  Later when we needed more fine grained control it was very easy to grow into greater customization with our integrations.  CircleCI has transformed our testing and deployment process, and allowed us to develop and deploy much faster."
-                                        :img "/img/outer/languages/ben.jpg"
-                                        :author "Ben Bernard"
-                                        :title "CTO @FieldBook"}
-                                       {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                                        :img "/assets/img/outer/stories/john.jpg"
-                                        :author "John Duff"
-                                        :title "Director of Engineering @Shopify"}
-                                       {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                                        :img "/img/outer/languages/aaron.jpg"
-                                        :author "Aaron Suggs"
-                                        :title "Operations Engineer @Kickstarter"}]}})
+(def templates
+  {"ruby" {:language "Ruby"
+           :headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
+           :logo-path "/img/outer/languages/ruby-logo.svg"
+           :features [{:feature "CircleCI provides support for a wide variety of Ruby versions and gems, including Ruby on Rails. It is trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
+                       :title "Built For Ruby"
+                       :icon "/img/outer/languages/gear-icon.svg"}
+                      {:feature "Circle manages all your database requirements for you, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB as well as frameworks such as DataMapper, Mongoid, and ActiveRecord. You can also add custom database commands via your circle.yml."
+                       :title "Database Management"
+                       :icon "/img/outer/languages/file-icon.svg"}
+                      {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha. Parallel builds can also be set up automatically for your Ruby projects to keep build times down."
+                       :title "Inference That Just Works"
+                       :icon "/img/outer/languages/book-icon.svg"}]
+           :docs-link "/docs/language-ruby-on-rails"
+           :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
+                           :img "/img/outer/languages/olivier.jpg"
+                           :author "Olivier Melcher"
+                           :title "Developer @PasswordBox"}
+                          {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
+                           :img "/assets/img/outer/stories/john.jpg"
+                           :author "John Duff"
+                           :title "Director of Engineering @Shopify"}
+                          {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
+                           :img "/img/outer/languages/aaron.jpg"
+                           :author "Aaron Suggs"
+                           :title "Operations Engineer @Kickstarter"}]}
+   "python" {:language "Python"
+             :headline "CircleCI makes Continous Integration and Deployment for Python projects a breeze."
+             :logo-path "/img/outer/languages/python-logo.svg"
+             :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
+                         :title "Built For Ruby"
+                         :icon "/img/outer/languages/gear-icon.svg"}
+                        {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
+                         :title "Database Management"
+                         :icon "/img/outer/languages/file-icon.svg"}
+                        {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
+                         :title "Inference That Just Works"
+                         :icon "/img/outer/languages/book-icon.svg"}]
+             :docs-link "/docs/language-ruby-on-rails"
+             :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
+                             :img "/img/outer/languages/olivier.jpg"
+                             :author "Olivier Melcher"
+                             :title "Developer @PasswordBox"}
+                            {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
+                             :img "/assets/img/outer/stories/john.jpg"
+                             :author "John Duff"
+                             :title "Director of Engineering @Shopify"}
+                            {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
+                             :img "/img/outer/languages/aaron.jpg"
+                             :author "Aaron Suggs"
+                             :title "Operations Engineer @Kickstarter"}]}
+   "node" {:language "Node"
+           :headline "CircleCI makes Continous Integration and Deployment for Node.js projects a breeze."
+           :logo-path "/img/outer/languages/node-logo.svg"
+           :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
+                       :title "Built For Ruby"
+                       :icon "/img/outer/languages/gear-icon.svg"}
+                      {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
+                       :title "Database Management"
+                       :icon "/img/outer/languages/file-icon.svg"}
+                      {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
+                       :title "Inference That Just Works"
+                       :icon "/img/outer/languages/book-icon.svg"}]
+           :docs-link "/docs/language-ruby-on-rails"
+           :testimonials [{:text "I was up and running in CircleCI with Node in literally minutes.  It guessed the correct settings and was running my tests before I even understood what was happening.  Later when we needed more fine grained control it was very easy to grow into greater customization with our integrations.  CircleCI has transformed our testing and deployment process, and allowed us to develop and deploy much faster."
+                           :img "/img/outer/languages/ben.jpg"
+                           :author "Ben Bernard"
+                           :title "CTO @FieldBook"}
+                          {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
+                           :img "/assets/img/outer/stories/john.jpg"
+                           :author "John Duff"
+                           :title "Director of Engineering @Shopify"}
+                          {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
+                           :img "/img/outer/languages/aaron.jpg"
+                           :author "Aaron Suggs"
+                           :title "Operations Engineer @Kickstarter"}]}})

 (defn language-landing [app owner]
   (reify
     om/IRender
     (render [_]
-            (let [subpage (get-in app [:navigation-data :language])
-                  template (get templates subpage)
-                  selected-testimonial (get-in app state/language-testimonial-tab-path 0)
-                  controls-ch (om/get-shared owner [:comms :controls])]
-              (html
-                [:div.languages.page
-                 [:div.languages-head {:class (:language template)}
-                  [:img {:src (utils/cdn-path (:logo-path template))}]
-                  [:h1 (:headline template)]
-                  [:div.languages-screenshots]
-                  [:div.hero-shadow]]
-                 [:div.languages-body
-                  [:div.languages-features
-                   [:div.center-text
-                    [:h3 "FEATURES"]]
-                   (map-indexed
-                     (fn [i feature]
-                       (if (odd? i)
-                         [:div.feature
-                          [:div.feature-image
-                           [:img {:src (utils/cdn-path (:icon feature))}]
-                           ]
-                          [:div.feature-copy
-                           [:h4.feature-title (:title feature)
-                            ]
-                           [:p.feature-description (:feature feature)]
-                           ]
+      (let [subpage (get-in app [:navigation-data :language])
+            template (get templates subpage)
+            selected-testimonial (get-in app state/language-testimonial-tab-path 0)
+            controls-ch (om/get-shared owner [:comms :controls])]
+        (html
+         [:div.languages.page
+          [:div.languages-head {:class (:language template)}
+           [:img {:src (utils/cdn-path (:logo-path template))}]
+           [:h1 (:headline template)]
+           [:div.languages-screenshots]
+           [:div.hero-shadow]]
+          [:div.languages-body
+           [:div.languages-features
+            [:div.center-text
+             [:h3 "FEATURES"]]
+            (map-indexed
+             (fn [i feature]
+               (if (odd? i)
+                 [:div.feature
+                  [:div.feature-image
+                   [:img {:src (utils/cdn-path (:icon feature))}]]
+                  [:div.feature-copy
+                   [:h4.feature-title (:title feature)]
+                   [:p.feature-description (:feature feature)]]]
+                 [:div.feature
+                  [:div.feature-copy
+                   [:h4.feature-title (:title feature)]
+                   [:p.feature-description (:feature feature)]]
+                  [:div.feature-image
+                   [:img {:src (utils/cdn-path (:icon feature))}]]]))
+             (:features template))

-                          ]
-                         [:div.feature
-                          [:div.feature-copy
-                           [:h4.feature-title (:title feature)
-                            ]
-                           [:p.feature-description (:feature feature)]
-                           ]
-                          [:div.feature-image
-                           [:img {:src (utils/cdn-path (:icon feature))}]
-                           ]
-                          ]))
-                     (:features template))
+            [:div.button
+             [:a {:href (:docs-link template)} "Read documentation on " (:language template)]]]]
+          [:div.languages-testimonials {:class (arrow-class selected-testimonial)}
+           [:div.languages-body
+            [:div.center-text
+             [:h3 "TESTIMONIALS"]]
+            [:div.testimonial-authors
+             (map-indexed (fn [i testimonial] [:img {:src (utils/cdn-path (:img testimonial)) :on-click #(put! controls-ch [:language-testimonial-tab-selected {:index i}])}])
+                          (:testimonials template))]
+            [:div.testimonial-box
+             [:div.testimonial
+              [:p.testimonial-text (get-in template [:testimonials selected-testimonial :text])]

-                   [:div.button
-                    [:a {:href (:docs-link template)} "Read documentation on " (:language template)]]
-                   ]
-                  ]
-                 [:div.languages-testimonials {:class (arrow-class selected-testimonial)}
-                  [:div.languages-body
-                   [:div.center-text
-                    [:h3 "TESTIMONIALS"
-                     ]
-                    ]
-                   [:div.testimonial-authors
-                    (map-indexed (fn [i testimonial] [:img {:src (utils/cdn-path (:img testimonial)) :on-click #(put! controls-ch [:language-testimonial-tab-selected {:index i}])}])
-                                 (:testimonials template))]
-                   [:div.testimonial-box
-                    [:div.testimonial
-                     [:p.testimonial-text (get-in template [:testimonials selected-testimonial :text])]
+              [:div.testimonial-author "—" (get-in template [:testimonials selected-testimonial :author])]
+              [:div.testimonial-author-title (get-in template [:testimonials selected-testimonial :title])]]]]]

-                     [:div.testimonial-author "—" (get-in template [:testimonials selected-testimonial :author])]
-                     [:div.testimonial-author-title (get-in template [:testimonials selected-testimonial :title])]]
-                    ]
-                   ]
-                  ]
-
-                 [:div.languages-cta
-                  [:div.languages-body
-                   [:h3
-                    "How do I start using my " (:language template) " app with CircleCI?"]
-                   [:div.languages-cta-steps
-                    [:div.languages-cta-step
-                     [:div.step-number "1"]
-                     [:div
-                      "Start by signing up "
-                      [:br]
-                      "using GitHub"]
-                     ]
-                    [:div.languages-cta-step
-                     [:div.step-number "2"]
-                     [:div
-                      "Run one of your Ruby projects on Circle"]]
-                    [:div.languages-cta-step
-                     [:div.step-number "3"]
-                     [:div
-                      [:strong "That's it!"]
-                      " Contact support if you run in to any issues. "]
-                     ]]
-                   [:div.cta-divider]
-                   [:div.center-text
-                    [:a.languages-cta-button
-                     {:href (auth-url)
-                      :on-click #(put! controls-ch [:track-external-link-clicked {:event "Auth GitHub"
-                                                                                :properties {:source (:language template)}
-                                                                                :path (auth-url)}])}
-                     [:i.fa.fa-github-alt]
-                     " Sign Up With "
-                     [:strong "GitHub"]]
-                    [:div.language-cta-trial "14-day free trial"]
-                    ]
-                   ]]
-
-                 ])))))
+          [:div.languages-cta
+           [:div.languages-body
+            [:h3
+             "How do I start using my " (:language template) " app with CircleCI?"]
+            [:div.languages-cta-steps
+             [:div.languages-cta-step
+              [:div.step-number "1"]
+              [:div
+               "Start by signing up "
+               [:br]
+               "using GitHub"]]
+             [:div.languages-cta-step
+              [:div.step-number "2"]
+              [:div
+               "Run one of your Ruby projects on Circle"]]
+             [:div.languages-cta-step
+              [:div.step-number "3"]
+              [:div
+               [:strong "That's it!"]
+               " Contact support if you run in to any issues. "]]]
+            [:div.cta-divider]
+            [:div.center-text
+             [:a.languages-cta-button
+              {:href (auth-url)
+               :on-click #(put! controls-ch [:track-external-link-clicked {:event "Auth GitHub"
+                                                                           :properties {:source (:language template)}
+                                                                           :path (auth-url)}])}
+              [:i.fa.fa-github-alt]
+              " Sign Up With "
+              [:strong "GitHub"]]
+             [:div.language-cta-trial "14-day free trial"]]]]])))))


add parsing rule for feminine plurals ending in 'ca' (e.g. 'mucche'+:sing => 'mucca')

--- src/babel/italiano/morphology/nouns.cljc
+++ src/babel/italiano/morphology/nouns.cljc
@@ -29,6 +29,11 @@
                        :gender :masc}}}}

    {:p [#"(.*)e$" "$1a"] ;; "donne" -> "donna"
+    :u {:synsem {:cat :noun
+                 :agr {:gender :fem
+                       :number :plur}}}}
+
+   {:p [#"(.*)che$" "$1ca"] ;; "mucche" -> "mucca"
     :u {:synsem {:cat :noun
                  :agr {:gender :fem
                        :number :plur}}}}


Designer code prettification

Designer code prettification

--- src/cljs/simplection/views/designer.cljs
+++ src/cljs/simplection/views/designer.cljs
@@ -6,10 +6,9 @@
             [jayq.core :as $]))

 (def measure-or-dimensions-dragged? (atom false))
+
 (defn get-css-display-value [visible?]
-  (if (identity visible?)
-    "" "none"
-    ))
+  (if (identity visible?) "" "none"))

 (defn format-measure-dimension [obj]
   (if (nil? (:aggregate obj))
@@ -24,44 +23,47 @@

 (defn init-left-menu-search []
   [:div.row.white-border {:id "designer-left-menu-search"
-             :style {:height "5%"}}
-   [:input.col-xs-12 {:type "text"
-                      :value @controller/search-term
-                      :on-change #(reset! controller/search-term (-> % .-target .-value))
-                      :placeholder "Filter Measures / Dimensions"
-                      :style {:height "100%"}
-                      :on-key-down #(case (.-which %)
-                                      27 (reset! controller/search-term "")
-                                      nil)}]])
+                          :style {:height "5%"}}
+   [:input.col-xs-12
+    {:type "text"
+     :value @controller/search-term
+     :on-change #(reset! controller/search-term (-> % .-target .-value))
+     :placeholder "Filter Measures / Dimensions"
+     :style {:height "100%"}
+     :on-key-down #(case (.-which %)
+                     27 (reset! controller/search-term "")
+                     nil)}]])

 (defn init-left-menu-measures []
   (let [query @controller/search-term
         measures @controller/measures]
     [:div.row.white-border {:id "designer-left-menu-measures"
-               :style {:height "40%"}}
+                            :style {:height "40%"}}
      [:h4 "Measures"]
      [:ul
       (for [m (case-insensitive-search query measures)]
         [:li [:a {:href "#"
                   :draggable true
                   :on-click #(.preventDefault %)
-                  :on-drag-start #(let [dt (.-dataTransfer %)]
-                                    (do (.setData dt "type" "measure")
-                                        (.setData dt "value" (:value m))
-                                        (.setData dt "displayValue" (:displayValue m))
-                                        (reset! measure-or-dimensions-dragged? true)))
-                  :on-drag-end #(reset! measure-or-dimensions-dragged? false)}
+                  :on-drag-start
+                  #(let [dt (.-dataTransfer %)]
+                     (do (.setData dt "type" "measure")
+                       (.setData dt "value" (:value m))
+                       (.setData dt "displayValue" (:displayValue m))
+                       (reset! measure-or-dimensions-dragged? true)))
+                  :on-drag-end
+                  #(reset! measure-or-dimensions-dragged? false)}
               (:displayValue m)]])]]))

 (defn init-left-menu-dimensions []
   (let [query @controller/search-term
         dimensions @controller/dimensions]
     [:div.row.white-border {:id "designer-left-menu-dimensions"
-               :style {:height "35%"}}
+                            :style {:height "35%"}}
      [:h4 "Dimensions"]
      [:ul
       (for [m (case-insensitive-search query dimensions)]
-         [:li [:a {:href "#"
+        [:li [:a {:href "#"
                   :draggable true
                   :on-click #(.preventDefault %)
                   :on-drag-start
@@ -71,11 +73,11 @@
                        (.setData dt "displayValue" (:displayValue m))
                        (reset! measure-or-dimensions-dragged? true)))
                   :on-drag-end #(reset! measure-or-dimensions-dragged? false)}
-               (:displayValue m)]])]]))
+              (:displayValue m)]])]]))

 (defn init-left-menu-it []
   [:div.row.white-border {:id "designer-left-menu-it"
-             :style {:height "20%"}}
+                          :style {:height "20%"}}
    [:h4 {:style {:height "20%"
                  :margin "0"}}
     "IT" ]
@@ -84,12 +86,13 @@
                :style {:height "80%"
                        :resize "none"
                        :width "100%"}
-               :on-key-up #(case (.-which %)
-                             27 (set! (-> % .-target .-value) "")
-                             13 (do (set! (-> % .-target .-value) "")
-                                     (layout/show-notification "Your request has been sent." :success)
-                                     );TODO: send data to back-end
-                             nil)}]])
+               :on-key-up
+               #(case (.-which %)
+                  27 (set! (-> % .-target .-value) "")
+                  13 (do (set! (-> % .-target .-value) "")
+                       (layout/show-notification "Your request has been sent." :success)
+                       );TODO: send data to back-end
+                  nil)}]])

 (defn init-left-menu []
   [:div.col-xs-1.full-height {:id "designer-left-menu"}
@@ -100,7 +103,7 @@

 (defn init-center-columns-container []
   [:div.row.white-border {:id "designer-center-columns-container"
-             :style {:height "40px"}}
+                          :style {:height "40px"}}
    [:div {:style {:height "100%"}}
     [:div.col-xs-1 {:style {:height "100%"
                             :width "100px"
@@ -122,7 +125,9 @@
         [:span (format-measure-dimension m)]
         [:a {:href "#"
              :on-click #(do
-                          (swap! controller/selected-columns set/difference #{m})
+                          (swap! controller/selected-columns
+                                 set/difference
+                                 #{m})
                           (.preventDefault %))
              :style {:float "right"
                      :margin-left "30px"
@@ -137,11 +142,12 @@
                      :padding "0px"
                      :height "40px"
                      :width "100%"
-                     :display (get-css-display-value @measure-or-dimensions-dragged?)}}
+                     :display (get-css-display-value
+                                @measure-or-dimensions-dragged?)}}
       (for [aggr @controller/aggregates]
         [:div.white-border
          {:on-drag-enter
-          #(do
+          #(do
              (.preventDefault %)
              (set! (.-effectAllowed (.-dataTransfer %)) "copy")
              (set! (.-effectAllowed (.-dataTransfer %)) "copy")
@@ -157,7 +163,9 @@
                  val (.getData dt "value")
                  dVal (.getData dt "displayValue")]
              (do
-               (swap! controller/selected-columns conj {:value val :displayValue dVal :aggregate aggr})
+               (swap! controller/selected-columns
+                      conj
+                      {:value val :displayValue dVal :aggregate aggr})
                (.remove (-> % .-target .-classList) "highlighted")))
           :on-drag-over #(.preventDefault %)
           :style {:display "inline-block"
@@ -173,17 +181,21 @@
    [:div {:style {:height "22px"}} "Series Grouping"]
    [:div
     (for [gr @controller/selected-groupings]
-      [:div.white-border-top {:style {:padding "2px 4px"}} (format-measure-dimension gr)
+      [:div.white-border-top
+       {:style {:padding "2px 4px"}}
+       (format-measure-dimension gr)
        [:a {:href "#"
-            :on-click #(do
-                         (swap! controller/selected-groupings set/difference #{gr})
-                         (.preventDefault %))
-            :style {:float "right" :font-weight "bold"}}
+            :style {:float "right" :font-weight "bold"}
+            :on-click
+            #(do (swap! controller/selected-groupings
+                        set/difference
+                        #{gr})
+               (.preventDefault %))}
         "X"]])
     [:div.white-border-top]]
    [:div {:id "series-grouping-drop-place"
           :on-drag-enter
-          #(do
+          #(do
              (.preventDefault %)
              (set! (.-effectAllowed (.-dataTransfer %)) "copy")
              (.add (-> % .-target .-classList) "highlighted"))
@@ -197,7 +209,9 @@
                  val (.getData dt "value")
                  dVal (.getData dt "displayValue")]
              (do
-               (swap! controller/selected-groupings conj {:value val :displayValue dVal})
+               (swap! controller/selected-groupings
+                      conj
+                      {:value val :displayValue dVal})
                (.remove (-> % .-target .-classList) "highlighted")))
           :on-drag-over #(.preventDefault %)
           :style {:position "absolute"
@@ -210,66 +224,80 @@
                   :padding "15px"
                   :width "100%"
                   :height "calc(100% - 22px)"
-                  :display (get-css-display-value @measure-or-dimensions-dragged?)}}
+                  :display (get-css-display-value
+                             @measure-or-dimensions-dragged?)}}
     "Drop Here"]])

 (defn init-center-rows-container []
   [:div {:style {:height "50%" :position "relative"}
-          }
-    [:div {:style {:border-bottom "solid 1px white" :height "22px"}}
-     "Rows :"]
-    [:div
-     (for [m @controller/selected-rows]
-       [:div.white-border-top {:style {:padding "2px 4px"}} (format-measure-dimension m)
-        [:a {:href "#"
-             :on-click
-             #(do
-                (swap! controller/selected-rows set/difference #{m})
-                (.preventDefault %))
-             :style {:float "right"
-                     :font-weight "bold"}}
-            "X"]])
-     [:div.white-border-top]]
-    [:div  {:id "row-aggregate-holder"
-            :style {:position "absolute"
-                    :background-color "white"
-                    :top "22px"
-                    :margin "0"
-                    :width "100%"
-                    :height "calc(100% - 22px)"
-                    :display (get-css-display-value @measure-or-dimensions-dragged?)}}
-     (for [aggr @controller/aggregates]
-       [:div.white-border
-        {:style {:padding "10px"}
-         :on-drag-enter
-         #(do
-            (.preventDefault %)
-            (set! (.-effectAllowed (.-dataTransfer %)) "copy")
-            (.add (-> % .-target .-classList) "highlighted"))
-         :on-drag-leave
-         #(do
-            (.preventDefault %)
-            (.remove (-> % .-target .-classList) "highlighted"))
-         :on-drop
-         #(let [dt (.-dataTransfer %)
-                t (.getData dt "type")
-                val (.getData dt "value")
-                dVal (.getData dt "displayValue")
-                ]
-            (do
-              (swap! controller/selected-rows conj {:value val :displayValue dVal :aggregate aggr})
-              (.remove (-> % .-target .-classList) "highlighted")))
-         :on-drag-over
-         #(.preventDefault %)} aggr])]])
+         }
+   [:div {:style {:border-bottom "solid 1px white" :height "22px"}}
+    "Rows :"]
+   [:div
+    (for [m @controller/selected-rows]
+      [:div.white-border-top
+       {:style {:padding "2px 4px"}}
+       (format-measure-dimension m)
+       [:a {:href "#"
+            :on-click
+            #(do
+               (swap! controller/selected-rows
+                      set/difference
+                      #{m})
+               (.preventDefault %))
+            :style {:float "right"
+                    :font-weight "bold"}}
+        "X"]])
+    [:div.white-border-top]]
+   [:div  {:id "row-aggregate-holder"
+           :style {:position "absolute"
+                   :background-color "white"
+                   :top "22px"
+                   :margin "0"
+                   :width "100%"
+                   :height "calc(100% - 22px)"
+                   :display (get-css-display-value
+                              @measure-or-dimensions-dragged?)}}
+    (for [aggr @controller/aggregates]
+      [:div.white-border
+       {:style {:padding "10px"}
+        :on-drag-enter
+        #(do
+           (.preventDefault %)
+           (set! (.-effectAllowed (.-dataTransfer %)) "copy")
+           (.add (-> % .-target .-classList) "highlighted"))
+        :on-drag-leave
+        #(do
+           (.preventDefault %)
+           (.remove (-> % .-target .-classList) "highlighted"))
+        :on-drop
+        #(let [dt (.-dataTransfer %)
+               t (.getData dt "type")
+               val (.getData dt "value")
+               dVal (.getData dt "displayValue")
+               ]
+           (do
+             (swap! controller/selected-rows
+                    conj
+                    {:value val
+                     :displayValue dVal
+                     :aggregate aggr})
+             (.remove (-> % .-target .-classList) "highlighted")))
+        :on-drag-over
+        #(.preventDefault %)} aggr])]])

 (defn init-center-plot-area []
-  [:div.col-xs-10.full-height.white-border {:id "designer-center-plot-area"} @controller/graph])
+  [:div.col-xs-10.full-height.white-border
+   {:id "designer-center-plot-area"}
+   @controller/graph])

 (defn init-center []
-  [:div.col-xs-10.full-height.white-border {:id "designer-center"}
+  [:div.col-xs-10.full-height.white-border
+   {:id "designer-center"}
    (init-center-columns-container)
-   [:div.row.white-border {:style {:height "calc(100% - 40px)"}}
-    [:div.col-xs-2.full-height.white-border
+   [:div.row.white-border
+    {:style {:height "calc(100% - 40px)"}}
+    [:div.col-xs-2.full-height.white-border
      {:id "designer-center-rows-container" :style {:padding "0"}}
      (init-center-rows-container)
      (init-center-rows-container-series-grouping)]
@@ -277,7 +305,7 @@

 (defn init-right-menu-chart-types []
   [:div.row.white-border {:id "designer-right-menu--types"
-             :style {:height "40%"}}
+                          :style {:height "40%"}}
    [:h4 (str "Chart Type: " @controller/selected-chart-type)]
    (let [c-types @controller/chart-types]
      [:div.container-fluid {:style {:padding "0"}}
@@ -286,14 +314,15 @@
          (for [t (take-nth 2 (drop mod c-types))]
            [:button {:value t
                      :class "draggable-chart-item"
-                     :on-click #(reset! controller/selected-chart-type t)
+                     :on-click
+                     #(reset! controller/selected-chart-type t)
                      :style {:width "100%"
                              :margin "4px 0 0 0"}}
             t])])])])

 (defn init-right-menu-settings []
   [:div.row.white-border {:id "designer-right-menu-settings"
-             :style {:height "60%"}}
+                          :style {:height "60%"}}
    "Settings"])

 (defn init-right-menu []
@@ -303,7 +332,9 @@

 (defn designer-init []
   (layout
-    [:div.container-fluid.row {:id "designer-container" :style {:min-height "600px"}}
+    [:div.container-fluid.row
+     {:id "designer-container"
+      :style {:min-height "600px"}}
      [:div.row-fluid.full-height
       (init-left-menu)
       (init-center)


removed old test function

removed old test function

--- src/cljs/swannodette/utils/reactive.cljs
+++ src/cljs/swannodette/utils/reactive.cljs
@@ -36,13 +36,6 @@
                 (close! out)))
             (close! out))))
     out))
-
-(defn multi-chan [v]
-  (let [c1 (chan)
-        c2 (chan)]
-    (put! c1 v)
-    (put! c2 c1)
-    c2))

 (defn map [f in]
   (let [out (chan)]


Provide a way find all addresses used by a fixture

--- src/afterglow/channels.clj
+++ src/afterglow/channels.clj
@@ -43,12 +43,20 @@
   [fixtures]
   (mapcat #(concat [%] (:heads %)) fixtures))

+(defn all-addresses
+  "Returns all the addresses being used by a list of patched fixtures,
+  including those used by any fixture heads."
+  [fixtures]
+  (map :address (mapcat :channels (afterglow.channels/expand-heads fixtures))))
+
+
 (defn extract-heads-with-some-matching-channel
   "Given a fixture list, returns all heads (which may be top-level fixtures too)
   whose channels contain a match for the specified predicate."
   [fixtures pred]
   (filter #(some pred (:channels %)) (expand-heads fixtures)))

+;; TODO: is this a good range data structure for finding which one a value falls into?
 (defn full-range
   "Returns a range spefication that encompasses all possible DMX values as a single variable setting."
   [range-type label]
@@ -57,7 +65,6 @@
    :type range-type
    :label label})

-;; TODO is this a good range data structure for finding which one a value falls into?
 (defn fine-channel
   "Defines a channel for which sometimes multi-byte values are desired, via a separate
 channel which specifies the fractional value to be added to the main channel."
@@ -119,6 +126,6 @@
    (fine-channel :zoom offset :fine-offset fine-offset)))

-;; TODO control channels
+;; TODO: control channels

-;; TODO gobo wheel and color wheel channels special variants of control channels?
+;; TODO: gobo wheel and color wheel channels special variants of control channels?


added an explain-diff tool

added an explain-diff tool

--- src/bluebell/utils/debug.clj
+++ src/bluebell/utils/debug.clj
@@ -1,5 +1,5 @@
 (ns bluebell.utils.debug
-  (:require [clojure.pprint]))
+  (:require [clojure.pprint :as pp]))

 (defn dout-sub [label x]
   `(let [x# ~x]
@@ -36,3 +36,72 @@
 (defn pprint-code [& args]
   (with-pprint-code
     (apply clojure.pprint/pprint args)))
+
+(defn cmp-ab [x]
+  (assoc x :eq (= (:a x) (:b x))))
+
+(declare explain-diff)
+
+(defn explain-diff-maps [a b]
+  (str "\nBoth are maps"
+       (let [ks (set (keys a))]
+         (if (= ks (set (keys b)))
+           (str "\n with the same set of keys"
+                (let [f (first
+                         (filter (complement :eq)
+                                 (map (fn [k]
+                                        (cmp-ab {:key k
+                                                 :a (get a k)
+                                                 :b (get b k)}))
+                                      ks)))]
+                  (str "\nBut different values at "
+                       (with-out-str
+                         (clojure.pprint/pprint (:key f)))
+                       "Compare them there:"
+                       (explain-diff (:a f) (:b f)))))
+           (str "\n with different set of keys"
+                "\n  a: " (with-out-str (pp/pprint (sort (keys a))))
+                "\n  b: " (with-out-str (pp/pprint (sort (keys b)))))))))
+
+
+(defn explain-diff-sequentials [a b]
+  (str "\nBoth are sequentials"
+       (if (= (count a) (count b))
+         (str "\nOf the same length"
+              (let [f (first (filter (complement :eq)
+                                     (map (fn [i a b]
+                                            (cmp-ab
+                                             {:index i
+                                              :a a
+                                              :b b}))
+                                          (range (count a))
+                                          a b)))]
+                (str "\nBut their elements at " (:index f) " differ:"
+                     (explain-diff (:a f) (:b f)))))
+         (str "\nOf different lengths: " (count a) " and " (count b)))))
+
+(defn explain-diff-sets [a b]
+  (let [amb (clojure.set/difference a b)
+        bma (clojure.set/difference b a)]
+    (str "\nBoth are sets but"
+         (if (empty? amb) "" (str  "\nOnly a contains " (with-out-str (pp/pprint amb))))
+         (if (empty? bma) "" (str  "\nOnly b contains " (with-out-str (pp/pprint bma)))))))
+
+(defn limit-string [n s]
+  (if (<= (count s) n) s (str (subs s 0 n) "...")))
+
+(def max-diff-len 30)
+
+(defn explain-diff [a b]
+  (if
+    (= a b) "Identitical"
+    (str "\nThey are different"
+         (cond
+           (and (map? a)
+                (map? b)) (explain-diff-maps a b)
+           (and (sequential? a)
+                (sequential? b)) (explain-diff-sequentials a b)
+           (and (set? a) (set? b)) (explain-diff-sets a b)
+           :default (str "\nThey have different type"
+                         "\na = \n" (limit-string max-diff-len (with-out-str (pp/pprint a)))
+                         "\nb = \n" (limit-string max-diff-len (with-out-str (pp/pprint b))))))))


do not require real-fs and smb-fs

do not require real-fs and smb-fs

the uberjar builds fine with ':profiles {:uberjar {:aot :all}}', so we
don't have to force inclusion of those 2 namespaces.

--- src/brainbot/nozzle/main.clj
+++ src/brainbot/nozzle/main.clj
@@ -1,7 +1,6 @@
 (ns brainbot.nozzle.main
   (:require [clojure.tools.logging :as logging])
   (:require [brainbot.nozzle
-             real-fs smb-fs   ;; we need these two for the uberjar
              [fsworker :as fsworker]
              [manage :as manage]
              [extract2 :as extract]


set default target val in code so we dont have to pass it in as ENV var


Have logging macros pass through exceptions as last arg

--- core/src/immutant/internal/util.clj
+++ core/src/immutant/internal/util.clj
@@ -122,22 +122,33 @@
   [ns]
   (WunderBoss/logger (str ns)))

+(defn ^:internal handle-log-args [& args]
+  (update-in
+    (if (instance? Throwable (last args))
+      [(butlast args) (last args)]
+      [args])
+    [0] #(apply print-str %)))
+
 (defmacro warn
   "Logs as warn."
   [& msg]
-  `(.warn (logger ~*ns*) (print-str ~@msg)))
+  `(let [[m# t#] (handle-log-args ~@msg)]
+    (.warn (logger ~*ns*) m# t#)))

 (defmacro error
   "Logs as error."
   [& msg]
-  `(.error (logger ~*ns*) (print-str ~@msg)))
+  `(let [[m# t#] (handle-log-args ~@msg)]
+     (.error (logger ~*ns*) m# t#)))

 (defmacro info
   "Logs as info."
   [& msg]
-  `(.info (logger ~*ns*) (print-str ~@msg)))
+  `(let [[m# t#] (handle-log-args ~@msg)]
+     (.info (logger ~*ns*) m# t#)))

 (defmacro debug
   "Logs as debug."
   [& msg]
-  `(.debug (logger ~*ns*) (print-str ~@msg)))
+  `(let [[m# t#] (handle-log-args ~@msg)]
+     (.debug (logger ~*ns*) m# t#)))


why does this not work for trucco?

why does this not work for trucco?

--- src/clj/apollo/db/schema.clj
+++ src/clj/apollo/db/schema.clj
@@ -3,7 +3,8 @@
             [clojure.java.io :as io]
             [apollo.utils :as utils]
             [clj-time.core :as t]
-            [clj-time.coerce :as c]))
+            [clj-time.coerce :as c]
+            [clojure.tools.logging :as log]))

 (def the-db {:classname "org.sqlite.JDBC",
              :subprotocol "sqlite",
@@ -114,7 +115,14 @@
   [db]
   (let [fkeys (keys (last-modified-index db))
         mounts (mount-points db)
-        should-prune? (fn [f] (or (not (.exists f)) (not (managed? f mounts))))
+        should-prune? (fn [f]
+                        (do
+                          (log/info
+                           (.getAbsolutePath f)
+                           mounts
+                           (.exists f)
+                           (not (managed? f mounts)))
+                          (or (not (.exists f)) (not (managed? f mounts)))))
         files (filter should-prune? (map io/file fkeys))]
     (map (partial delete-track! db) (map (fn [f] (.getAbsolutePath f)) files))))


fix tests

fix tests

--- src/clj/com/rpl/specter.cljc
+++ src/clj/com/rpl/specter.cljc
@@ -120,7 +120,7 @@
         (-> path i/dynamic-param? not)
         ))

-     (defn- wrap-dynamic-nav [f]
+     (defn wrap-dynamic-nav [f]
        (fn [& args]
          (let [ret (apply f args)]
            (if (and (sequential? ret) (static-path? ret))


produce a more sensible error if `cljs.core/*main-cli-fn*` is not set for :target :nodejs

--- src/cljs/cljs/nodejscli.cljs
+++ src/cljs/cljs/nodejscli.cljs
@@ -13,5 +13,8 @@
   (:require [cljs.nodejs :as nodejs]))

 ; Call the user's main function
-(apply cljs.core/*main-cli-fn* (drop 2 (.-argv nodejs/process)))
+(if (or (nil? cljs.core/*main-cli-fn*)
+        (not (fn? cljs.core/*main-cli-fn*)))
+  (throw (js/Error. "cljs.core/*main-cli-fn* not set"))
+  (apply cljs.core/*main-cli-fn* (drop 2 (.-argv nodejs/process))))


Implement game and logic loops with fixed time-step looping, and implement world-state as a global atom.

--- src/cljs/cljs_game/core.cljs
+++ src/cljs/cljs_game/core.cljs
@@ -2,6 +2,30 @@
   (:require [threejs :as three]))

 (enable-console-print!)
+
+(def world (atom {}))
+
+(defn update-world
+  [delta-time]
+  (let [mesh (@world :mesh)]
+    (set! (.-x (.-rotation mesh)) (+ 0.01 (.-x (.-rotation mesh))))
+    (set! (.-y (.-rotation mesh)) (+ 0.02 (.-y (.-rotation mesh))))
+    (swap! world assoc :mesh mesh)))
+
+(defn game-loop
+  [now]
+  (let [prev (@world :prev-time)
+        leftover-time (@world :accum-time)
+        time-step 16.666666666666668]
+    (swap! world assoc :prev-time now)
+    (swap! world assoc :leftover-time
+           (loop [accumulated (+ leftover-time (- now prev))]
+             (if (>= accumulated time-step)
+               (do (update-world time-step)
+                   (recur (- accumulated time-step)))
+               accumulated)))
+    (js/requestAnimationFrame game-loop)))
+

 (defn ^:export init-game
   []
@@ -15,14 +39,17 @@
         light2 (three/PointLight. 0xffffff 2 0)]
     (set! (.-z (.-position camera)) 900)
     (.add scene mesh)
+    (swap! world assoc :mesh mesh)
     (.add scene light)
     (.set (.-position light2) 300 300 300)
     (.add scene light2)
     (.setSize renderer js/window.innerWidth js/window.innerHeight)
     (js/document.body.appendChild (.-domElement renderer))
-    (let [animate (fn animate []
-         (js/requestAnimationFrame animate)
-         (set! (.-x (.-rotation mesh)) (+ 0.01 (.-x (.-rotation mesh))))
-         (set! (.-y (.-rotation mesh)) (+ 0.02 (.-y (.-rotation mesh))))
+    (swap! world assoc :prev js/Performance.now)
+    (swap! world assoc :accum-time 0.0)
+    (let [animate (fn animate [current-time]
+                    (js/requestAnimationFrame animate)
+                    (game-loop current-time)
                     (.render renderer scene camera))]
-      (animate))))
+      (animate js/Performance.now))))
+


added missing trace on Troll subroutine

added missing trace on Troll subroutine

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -539,11 +539,12 @@
                 {:msg "end the run" :effect (effect (end-run))}]}

    "Troll"
-   {:abilities [{:player :runner :prompt "Choose one" :choices ["Lose [Click]" "End the run"]
-                 :label "Force the Runner to lose [Click] or end the run"
-                 :effect (req (if-not (and (= target "Lose [Click]") (pay state side card :click 1))
-                                (do (end-run state side) (system-msg state side "ends the run"))
-                                (system-msg state side "loses [Click]")))}]}
+   {:abilities [{:label "Trace 2 - Force the runner to lose [Click] or end the run"
+                 :trace {:base 2 :player :runner
+                         :prompt "Choose one" :choices ["Lose [Click]" "End the run"]
+                         :effect (req (if-not (and (= target "Lose [Click]") (pay state side card :click 1))
+                                        (do (end-run state side) (system-msg state side "ends the run"))
+                                        (system-msg state side "loses [Click]")))}}]}

    "Tsurugi"
    {:abilities [{:msg "end the run" :effect (effect (end-run))}


Assign previously unassigned neighborhoods.

--- src/clj/hbg_crime/core.clj
+++ src/clj/hbg_crime/core.clj
@@ -61,15 +61,19 @@
                                 (:address-components %))))
                  results)))

+(defn classify-neighborhood
+  [report]
+  (if-let [neighborhood (g/neighborhood-for-point [(:lng report) (:lat report)])]
+    (name neighborhood)))
+
 (defn geocode-report
   [report]
   (let [res (first-zip-match (geo/geocode-address
                               (str (:address report) ", Harrisburg, PA")))
-        loc (get-in res [:geometry :location])
-        neighborhood (g/neighborhood-for-point [(:lng loc) (:lat loc)])]
+        loc (get-in res [:geometry :location])]
     (-> report
         (merge loc)
-        (assoc :neighborhood (if neighborhood (name neighborhood))))))
+        (assoc :neighborhood (classify-neighborhood report)))))

 (defn results-of-file
   [src]
@@ -91,6 +95,11 @@
   (doseq [report (filter identity (all-current-reports n))]
     (db/insert-report report)))

+(defn assign-neighborhoods
+  []
+  (doseq [report (db/ungeocoded-reports)]
+    (db/update-report! (assoc report :neighborhood (classify-neighborhood report)))))
+
 (defn regeocode-reports
   []
   (doseq [report (db/ungeocoded-reports)]


Add symlink-resolving functions

Add symlink-resolving functions

--- src/clj/runbld/util/io.clj
+++ src/clj/runbld/util/io.clj
@@ -1,4 +1,5 @@
 (ns runbld.util.io
+  (:require [schema.core :as s])
   (:require [clojure.java.io :as jio]
             [clojure.java.shell :as sh]
             [slingshot.slingshot :refer [throw+]]))
@@ -54,10 +55,34 @@
       (throw+ {:error ::resource-not-found
                :msg (format "cannot find %s" path)}))))

+(defn os []
+  (-> (System/getProperties)
+      (get "os.name")
+      .toUpperCase
+      symbol))
+
+(defn which-bin []
+  (case (os)
+    LINUX "which"
+    WINDOWS "where.exe"))
+
 (defn which [name]
-  (let [res (sh/sh "which" name)]
+  (let [res (sh/sh (which-bin) name)]
     (when (zero? (:exit res))
       (.trim (:out res)))))
+
+(s/defn readlink
+  [path :- s/Str]
+  (-> path
+      file
+      .toPath
+      (.toRealPath
+       (into-array java.nio.file.LinkOption []))
+      str))
+
+(s/defn resolve-binary :- s/Str
+  [name :- s/Str]
+  (readlink (which name)))

 (defmacro with-tmp-source [bindings body]
   (let [f (first bindings)


add state truncate

add state truncate

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -81,6 +81,13 @@
  :re-form/value-changed
  (fn [db [_ form-name v]]
    (assoc-in db [:re-form form-name :value] v)))
+
+(rf/reg-event-db
+ :re-form/truncate-state
+ (fn [db [_ form-name keys]]
+   (reduce (fn [acc k]
+             (update-in acc [:re-form form-name] dissoc k))
+           db keys)))

 (rf/reg-event-db
  :re-form/set-input-flags


Doc, source and dir create their own env and resolves #86

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -65,6 +65,12 @@
   returns the path to the actual file (without extension)."
   [provide]
   (get-in @app-env [:goog-provide->path provide]))
+
+(defn empty-analyzer-env
+  []
+  (assoc (ana/empty-env)
+         :ns (get-namespace (:current-ns @app-env))
+         :context :expr))

 (defn map-keys
   [f m]
@@ -474,7 +480,7 @@
                                  (common/wrap-success nil))))))))

 (defn process-doc
-  [opts cb data env sym]
+  [opts cb data sym]
   (call-back! (merge opts {:no-pr-str-on-value true})
               cb
               data
@@ -484,7 +490,7 @@
                    (docs/special-doc-map sym) (repl/print-doc (docs/special-doc sym))
                    (docs/repl-special-doc-map sym) (repl/print-doc (docs/repl-special-doc sym))
                    (get-namespace sym) (repl/print-doc (select-keys (get-namespace sym) [:name :doc]))
-                   :else (repl/print-doc (get-var opts env sym)))))))
+                   :else (repl/print-doc (get-var opts (empty-analyzer-env) sym)))))))

 (defn process-pst
   [opts cb data expr]
@@ -548,9 +554,10 @@
                                      (cb (common/wrap-success "nil"))))))

 (defn process-source
-  [opts cb data env sym]
-  (let [var (get-var opts env sym)
+  [opts cb data sym]
+  (let [var (get-var opts (empty-analyzer-env) sym)
         call-back (partial call-back! (merge opts {:no-pr-str-on-value true}) cb data)]
+
     (if-let [filepath (or (:file var) (:file (:meta var)))]
       (let [src-paths (:src-paths opts)
             ;; see discussion here: https://github.com/ScalaConsultants/replumb/issues/17#issuecomment-163832028
@@ -563,7 +570,7 @@
       (call-back (common/wrap-success "nil")))))

 (defn process-dir
-  [opts cb data env sym]
+  [opts cb data sym]
   (let [vars (-> (ns-publics st sym) keys sort)
         call-back (partial call-back! (merge opts {:no-pr-str-on-value true}) cb data)]
     (if (seq vars)
@@ -572,18 +579,16 @@

 (defn process-repl-special
   [opts cb data expression-form]
-  (let [env (assoc (ana/empty-env) :context :expr
-                   :ns {:name (:current-ns @app-env)})
-        argument (second expression-form)]
+  (let [argument (second expression-form)]
     (case (first expression-form)
       in-ns (process-in-ns opts cb data argument)
       require (process-require opts cb data :require (rest expression-form))
       require-macros (process-require opts cb data :require-macros (rest expression-form))
       import (process-require opts cb data :import (rest expression-form))
-      doc (process-doc opts cb data env argument)
-      source (process-source opts cb data env argument)
+      doc (process-doc opts cb data argument)
+      source (process-source opts cb data argument)
       pst (process-pst opts cb data argument)
-      dir (process-dir opts cb data env argument)
+      dir (process-dir opts cb data argument)
       load-file (call-back! opts cb data (common/error-keyword-not-supported "load-file" ex-info-data))))) ;; (process-load-file argument opts)

 (defn process-1-2-3


add labels

add labels

--- src/cljs/tictag/views.cljs
+++ src/cljs/tictag/views.cljs
@@ -92,14 +92,18 @@
 (defn login-or-signup-form [& {:keys [username password login-fn signup-fn ch-username ch-password]}]
   [:div
    [:div
-    [username-input
-     :value username
-     :change ch-username
-     :login login-fn]
-    [password-input
-     :value password
-     :change ch-password
-     :login login-fn]]
+    [:div
+     [:label "Username"
+      [username-input
+       :value username
+       :change ch-username
+       :login login-fn]]]
+    [:div
+     [:label "Password"
+      [password-input
+       :value password
+       :change ch-password
+       :login login-fn]]]]
    [login login-fn]
    [signup signup-fn]])


Add :base-type boolean to all terrains

Add :base-type boolean to all terrains

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -76,27 +76,38 @@

     :terrains
     {:plains        {:description "Plains"
-                     :image "tilesets/elite-command/terrains/plains.png"}
+                     :image "tilesets/elite-command/terrains/plains.png"
+                     :base-type false}
      :mountains     {:description "Mountains"
-                     :image "tilesets/elite-command/terrains/mountains.png"}
+                     :image "tilesets/elite-command/terrains/mountains.png"
+                     :base-type false}
      :woods         {:description "Woods"
-                     :image "tilesets/elite-command/terrains/woods.png"}
+                     :image "tilesets/elite-command/terrains/woods.png"
+                     :base-type false}
      :desert        {:description "Desert"
-                     :image "tilesets/elite-command/terrains/desert.png"}
+                     :image "tilesets/elite-command/terrains/desert.png"
+                     :base-type false}
      :tundra        {:description "Tundra"
-                     :image "tilesets/elite-command/terrains/tundra.png"}
+                     :image "tilesets/elite-command/terrains/tundra.png"
+                     :base-type false}
      :swamp         {:description "Swamp"
-                     :image "tilesets/elite-command/terrains/swamp.png"}
+                     :image "tilesets/elite-command/terrains/swamp.png"
+                     :base-type false}
      :ford          {:description "Ford"
-                     :image "tilesets/elite-command/terrains/ford.png"}
+                     :image "tilesets/elite-command/terrains/ford.png"
+                     :base-type false}
      :shallow-water {:description "Shallow Water"
-                     :image "tilesets/elite-command/terrains/shallow-water.png"}
+                     :image "tilesets/elite-command/terrains/shallow-water.png"
+                     :base-type false}
      :deep-water    {:description "Deep Water"
-                     :image "tilesets/elite-command/terrains/deep-water.png"}
+                     :image "tilesets/elite-command/terrains/deep-water.png"
+                     :base-type false}
      :base          {:description "Base"
-                     :image "tilesets/elite-command/terrains/base-COLOR.png"}
+                     :image "tilesets/elite-command/terrains/base-COLOR.png"
+                     :base-type true}
      :seaport       {:description "Seaport"
-                     :image "tilesets/elite-command/terrains/seaport-COLOR.png"}}
+                     :image "tilesets/elite-command/terrains/seaport-COLOR.png"
+                     :base-type true}}

     :unit-state-maps
     {:move-attack


Give hover label a more compact name

Give hover label a more compact name

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -62,7 +62,7 @@
          "here</a>.")

     ;; Status information
-    :hover-tile-location "Hovering over tile: "
+    :hover-tile-location "Hover: "
     :none "none"
     }})


count-by-value should return map

count-by-value should return map

--- src/clojure/flambo/api.clj
+++ src/clojure/flambo/api.clj
@@ -298,7 +298,7 @@
   "Return the count of each unique value in `rdd` as a map of (value, count)
   pairs."
   [rdd]
-  (.countByValue rdd))
+  (into {} (.countByValue rdd)))

 (defn save-as-text-file
   "Writes the elements of `rdd` as a text file (or set of text files)


Add rainbow cues to push example.

Add rainbow cues to push example.

--- src/afterglow/examples.clj
+++ src/afterglow/examples.clj
@@ -172,7 +172,12 @@

 (defn use-push
   []
-  (let [pc (push/bind-to-show *show*)]
+  (let [pc (push/bind-to-show *show*)
+        hue-bar (params/build-oscillated-param ; Spread a rainbow across a bar of music
+                 (oscillators/sawtooth-bar) :max 360)
+        hue-gradient (params/build-spatial-param ; Spread a rainbow across the light grid
+                      (show/all-fixtures)
+                      (fn [head] (- (:x head) (:min-x @(:dimensions *show*)))) :end 360)]
     (global-color-cue "red" 0 0 :include-color-wheels true)
     (global-color-cue "orange" 1 0 :include-color-wheels true)
     (global-color-cue "yellow" 2 0 :include-color-wheels true)
@@ -181,6 +186,18 @@
     (global-color-cue "purple" 5 0 :include-color-wheels true)
     (global-color-cue "white" 6 0 :include-color-wheels true)

+
+    (ct/set-cue! (:cue-grid *show*) 0 1
+                 (ct/cue :color (fn [] (global-color-effect
+                                        (params/build-color-param :s 100 :l 50 :h hue-bar)))))
+    (ct/set-cue! (:cue-grid *show*) 1 1
+                 (ct/cue :color (fn [] (global-color-effect
+                                        (params/build-color-param :s 100 :l 50 :h hue-gradient)
+                                        :include-color-wheels true))))
+    (ct/set-cue! (:cue-grid *show*) 2 1
+                 (ct/cue :color (fn [] (global-color-effect
+                                        (params/build-color-param :s 100 :l 50 :h hue-gradient
+                                                                  :adjust-hue hue-bar)))))
     (ct/set-cue! (:cue-grid *show*) 0 7
                  (ct/cue :sparkle (fn [] (fun/sparkle (show/all-fixtures) :chance 0.05 :fade-time 50))
                          :held true


Make eastwood happy.

Make eastwood happy.

--- src/oc/storage/resources/maintenance.clj
+++ src/oc/storage/resources/maintenance.clj
@@ -2,7 +2,6 @@
   "fns to maintain storage resources."
   (:require [schema.core :as schema]
             [taoensso.timbre :as timbre]
-            [clojure.pprint :as pp]
             [oc.lib.db.common :as db-common]
             [oc.lib.schema :as lib-schema]
             [oc.storage.resources.org :as org-res]
@@ -19,7 +18,7 @@
   [conn :- lib-schema/Conn entry :- common/Entry limit]
   (let [old-shared (:shared entry)
         grouped-shared (group-by :shared-at old-shared)
-        unique-shared (into [] (map first (vals grouped-shared)))
+        unique-shared (vec (map first (vals grouped-shared)))
         sorted-shared (reverse (sort-by :shared-at unique-shared))
         limited-shared (take limit sorted-shared)]
     (timbre/info "      Old shared" (count old-shared))
@@ -52,7 +51,7 @@
   (let [limit (or limit 50)]
     (timbre/info "Cut :shared lists for all entries to:" limit "(orgs from " (* batch-length batch-offset) "to" (* batch-length (inc batch-offset)) ")")
     (let [orgs (org-res/list-orgs conn)
-          batches (into [] (partition batch-length orgs))
-          batch (into [] (get batches batch-offset))]
+          batches (vec (partition batch-length orgs))
+          batch (vec (get batches batch-offset))]
       (for [org batch]
         (shared-limit-for-org! conn (:uuid org) limit)))))


Fixing docstrings in grafter.rdf.sesame

Fixing docstrings in grafter.rdf.sesame

--- src/grafter/rdf/sesame.clj
+++ src/grafter/rdf/sesame.clj
@@ -396,9 +396,10 @@
   ([datadir indexes]
      (NativeStore. datadir indexes)))

-(defn http-repo [repo-url]
+(defn http-repo
   "Given a URL as a String return a Sesame HTTPRepository for e.g.
   interacting with the OpenRDF Workbench."
+  [repo-url]
   (doto (HTTPRepository. repo-url)
     (.initialize)))

@@ -455,9 +456,10 @@
   (rollback [repo]
     (-> repo .rollback)))

-(defmacro with-transaction [repo & forms]
+(defmacro with-transaction
   "Wraps the given forms in a transaction on the supplied repository.
   Exceptions are rolled back on failure."
+  [repo & forms]
   `(try
     (pr/begin ~repo)
     (let [return# (do ~@forms)]
@@ -472,9 +474,9 @@
 string and returns a lazy sequence of results.

 It doesn't clear up properly in all cases, for example if the sequence
-isn't fully consumed you may cause a resource leak.
-
-TODO: reimplement with proper resource handling."
+isn't fully consumed you may cause a resource leak."
+
+  ;; TODO: reimplement interfaces with proper resource handling.
   (query-dataset [this sparql-string model])

   (update! [this sparql-string]))
@@ -742,6 +744,7 @@
                            (sesame-statement->IStatement msg)))]
           (map read-rdf statements))))))

-(defn shutdown [repo]
+(defn shutdown
   "Cleanly shutsdown the repository."
+  [repo]
   (.shutDown repo))


Large print should end on even

Large print should end on even

so that it can easily be combined with a cover page

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -421,6 +421,7 @@
      (declarations (layout/translations :grossdruck) description)
      [:fo:page-sequence {:master-reference "main"
                          :initial-page-number "1"
+                         :force-page-count "end-on-even"
                          :language "de"}
       (header :recto)
       (header :verso)


Add a space before and after the leader in the toc

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -83,8 +83,8 @@
                  {:text-align-last "justify"}
                  {:text-align-last "justify" :start-indent "1em"})
      [:fo:basic-link {:internal-destination (hash path)}
-      (str (layout/translations (last path)) " ")
-      [:fo:leader {:leader-pattern "dots"}]
+      (layout/translations (last path))
+      " " [:fo:leader {:leader-pattern "dots"}] " "
       [:fo:page-number-citation {:ref-id (hash path)}]]
      (when (and (map? items) (< depth to-depth))
        (keep #(toc-entry (% items) (conj path %) to-depth) (order (keys items))))]))


Fix validation for hörfilm and ludo

Fix validation for hörfilm and ludo

--- src/catalog/validation.clj
+++ src/catalog/validation.clj
@@ -21,7 +21,7 @@
 (def BrailleGrade
   (apply s/enum (vals vubis/braille-grade-raw-to-braille-grade)))

-(def SignatureRE #"(DS |GDB |BG |ED |BM |BK |PS|DY|GD)\d{4,6}")
+(def SignatureRE #"(DS |GDB |BG |ED |BM |BK |PS|DY|GD)\d{4,6}|LUD \d{1,3}|BK \d{3}|VI \d{1,3}")

 (def SignatureTuple
   [(s/one SignatureRE "signature")
@@ -119,6 +119,7 @@
   :producer s/Str
   :directed-by [s/Str]
   :actors [s/Str]
+  :personel-text s/Str
   :movie_country s/Str})

 (abstract-map/extend-schema


show groups without any tags in sidebar too

--- src/chat/client/views.cljs
+++ src/chat/client/views.cljs
@@ -214,12 +214,16 @@
     om/IRender
     (render [_]
       (let [threads (vals (data :threads))
+            groups-map (into {} (map (juxt :id (constantly nil))) (data :groups))
+            ; groups-map is just map of group-ids to nil, to be merged with
+            ; tags, so there is still an entry for groups without any tags
             tags (->> (data :tags)
                       vals
                       (map (fn [tag]
                              (assoc tag :subscribed?
                                (contains? (get-in @store/app-state [:user :subscribed-tag-ids]) (tag :id)))))
-                      (group-by :group-id))]
+                      (group-by :group-id)
+                      (merge groups-map))]
         (dom/div nil
           (dom/div #js {:className "meta"}
             (dom/img #js {:className "avatar"


fix indent

fix indent

--- src/chat/server/schema.clj
+++ src/chat/server/schema.clj
@@ -132,77 +132,77 @@
   :db/unique :db.unique/identity
   :db/id #db/id [:db.part/db]
   :db.install/_attribute :db.part/db}
-{:db/ident :tag/name
- :db/valueType :db.type/string
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :tag/group
- :db/valueType :db.type/ref
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :tag/description
- :db/valueType :db.type/string
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-
-; groups
-{:db/ident :group/id
- :db/valueType :db.type/uuid
- :db/cardinality :db.cardinality/one
- :db/unique :db.unique/identity
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :group/name
- :db/valueType :db.type/string
- :db/cardinality :db.cardinality/one
- :db/unique :db.unique/identity
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :group/user
- :db/valueType :db.type/ref
- :db/cardinality :db.cardinality/many
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :group/admins
- :db/valueType :db.type/ref
- :db/cardinality :db.cardinality/many
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :group/settings
- :db/valueType :db.type/string
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-
-; invitations
-{:db/ident :invite/id
- :db/valueType :db.type/uuid
- :db/cardinality :db.cardinality/one
- :db/unique :db.unique/identity
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :invite/group
- :db/valueType :db.type/ref
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :invite/from
- :db/valueType :db.type/ref
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :invite/to
- :db/valueType :db.type/string
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
-{:db/ident :invite/created-at
- :db/valueType :db.type/instant
- :db/cardinality :db.cardinality/one
- :db/id #db/id [:db.part/db]
- :db.install/_attribute :db.part/db}
+ {:db/ident :tag/name
+  :db/valueType :db.type/string
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :tag/group
+  :db/valueType :db.type/ref
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :tag/description
+  :db/valueType :db.type/string
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+
+ ; groups
+ {:db/ident :group/id
+  :db/valueType :db.type/uuid
+  :db/cardinality :db.cardinality/one
+  :db/unique :db.unique/identity
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :group/name
+  :db/valueType :db.type/string
+  :db/cardinality :db.cardinality/one
+  :db/unique :db.unique/identity
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :group/user
+  :db/valueType :db.type/ref
+  :db/cardinality :db.cardinality/many
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :group/admins
+  :db/valueType :db.type/ref
+  :db/cardinality :db.cardinality/many
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :group/settings
+  :db/valueType :db.type/string
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+
+ ; invitations
+ {:db/ident :invite/id
+  :db/valueType :db.type/uuid
+  :db/cardinality :db.cardinality/one
+  :db/unique :db.unique/identity
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :invite/group
+  :db/valueType :db.type/ref
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :invite/from
+  :db/valueType :db.type/ref
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :invite/to
+  :db/valueType :db.type/string
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}
+ {:db/ident :invite/created-at
+  :db/valueType :db.type/instant
+  :db/cardinality :db.cardinality/one
+  :db/id #db/id [:db.part/db]
+  :db.install/_attribute :db.part/db}

 ])


Fix swipe-delete delete action handler

Fix swipe-delete delete action handler

Signed-off-by: Oskar Thoren <aeed71d78dc09e4764ceac69b111eee9b50cfdd0@oskarthoren.com>

--- src/status_im/ui/screens/home/views.cljs
+++ src/status_im/ui/screens/home/views.cljs
@@ -36,7 +36,7 @@

 (views/defview home-list-deletable [[home-item-id home-item]]
   (views/letsubs [swiped? [:delete-swipe-position home-item-id]]
-    (let [delete-action (if (:chat-id home-item) :remove-chat :remove-browser)
+    (let [delete-action (if (:chat-id home-item) :delete-chat :remove-browser)
           inner-item-view (if (:chat-id home-item)
                             inner-item/home-list-chat-item-inner-view
                             inner-item/home-list-browser-item-inner-view)


fixes datahound

fixes datahound

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -120,7 +120,7 @@
    {:abilities [{:label "Trace 2 - Look at the top of Stack"
                  :trace {:base 2 :msg (msg "look at the top " (- target (second targets)) " cards of Stack")
                          :effect (req (doseq [c (take (- target (second targets)) (:deck runner))]
-                                        (move state side c :play-area false true)))}}]}
+                                        (move state side c :play-area)))}}]}

    "Data Mine"
    {:abilities [{:msg "do 1 net damage" :effect (effect (trash card) (damage :net 1 {:card card}))}]}


improve all-installed to include hosted Corp cards

things installed on Worlds Plaza, Awakening Center, and the upcoming RecStudio needed to be spotted by this function

--- src/clj/game/core-misc.clj
+++ src/clj/game/core-misc.clj
@@ -69,8 +69,11 @@
   (if (= side :runner)
     (let [installed (flatten (for [t [:program :hardware :resource]] (get-in @state [:runner :rig t])))]
       (concat installed (filter :installed (mapcat :hosted installed))))
-    (let [servers (->> (:corp @state) :servers seq flatten)]
-      (concat (mapcat :content servers) (mapcat :ices servers)))))
+    (let [servers (->> (:corp @state) :servers seq flatten)
+          content (mapcat :content servers)
+          ice (mapcat :ices servers)
+          hosted-on-content (mapcat :hosted content)]
+      (concat ice content hosted-on-content))))

 (defn all-active
   "Returns a vector of all active cards for the given side. Active cards are either installed, the identity,


Fixes informative toasting when accessing Gagarin card with 0 credits.

--- src/clj/game/core-runs.clj
+++ src/clj/game/core-runs.clj
@@ -99,8 +99,10 @@
     (swap! state update-in [:bonus] dissoc :steal-cost)
     (swap! state update-in [:bonus] dissoc :access-cost)
     (trigger-event state side :pre-access-card c)
-    (let [acost (access-cost state side c)]
-      (if (or (empty? acost) (pay state side c acost))
+    (let [acost (access-cost state side c)
+          ;; hack to prevent toasts when playing against Gagarin and accessing on 0 credits
+          anon-card (dissoc c :title)]
+      (if (or (empty? acost) (pay state side anon-card acost))
         ;; Either there were no access costs, or the runner cold pay them.
         (let [cdef (card-def c)
               c (assoc c :seen true)]


Add diff and interp validation for optional and multi types.

--- src/clj/seria/validate.clj
+++ src/clj/seria/validate.clj
@@ -88,19 +88,28 @@
      (validate-schema key-schema) (validate-schema val-schema)]))

 (defmethod validate-composite :optional [[_ options inner-schema :as schema]]
-  (assert (= 3 (count schema))
-          (format "Invalid schema: %s. :optional-s must have 1 or 2 arguments."
-                  schema))
-  [:optional {} (validate-schema inner-schema)])
+  (let [[_ options inner-schema] (->> schema
+                                      (validate-diffable)
+                                      (validate-interpable))]
+    (assert (= 3 (count schema))
+            (format "Invalid schema: %s. :optional-s must have 1 or 2 arguments."
+                    schema))
+    [:optional (select-keys options [:diff :interp])
+     (validate-schema inner-schema)]))

-(defmethod validate-composite :enum [[_ _ values :as schema]]
-  (assert (= 3 (count schema))
-          (format "Invalid schema: %s. :enum-s must have 1 or 2 arguments."
-                  schema))
-  (assert (vector? values)
-          (format "Invalid schema: %s. Possible :enum values must be listed in a vector."
-                  schema))
-  [:enum {} values])
+(defmethod validate-composite :enum [schema]
+  (let [[_ options values :as schema] (->> schema
+                                           (validate-diffable))]
+    (assert (= 3 (count schema))
+            (format "Invalid schema: %s. :enum-s must have 1 or 2 arguments."
+                    schema))
+    (assert (vector? values)
+            (format "Invalid schema: %s. Possible :enum values must be listed in a vector."
+                    schema))
+    (assert (every? vector? values)
+            (format "Invalid schema: %s. Possible :enum values must be keywords."
+                    schema))
+    [:enum (select-keys options [:diff]) values]))

 (defmethod validate-composite :tuple [schema]
   (let [[_ options inner-schemas :as schema] (->> schema
@@ -138,23 +147,28 @@
       (assert (every? keyword? fields)
               (format "Invalid schema: %s. :record fields must be accessible by keywords."
                       schema))
-      [:record (assoc (select-keys options [:diff :interp]) :extends extends
-                                                            :constructor constructor)
+      [:record (assoc (select-keys options [:diff :interp :constructor])
+                      :extends extends)
        (zipmap fields (map validate-schema inner-schemas))])))

 (defmethod validate-composite :multi [[_ _ selector arg-map :as schema]]
-  (assert (= 4 (count schema))
-          (format "Invalid schema: %s. :multi-s must have 2 or 3 arguments."
-                  schema))
-  (assert (keyword? selector)
-          (format "Invalid schema: %s. The :selector parameter of a :multi must be a keyword."
-                  schema))
-  (assert (map? arg-map)
-          (format "Invalid schema: %s. The last parameter of a :multi must be a map."
-                  schema))
-  (let [multi-cases   (keys arg-map)
-        inner-schemas (vals arg-map)]
-    [:multi {} selector (zipmap multi-cases (map validate-schema inner-schemas))]))
+  (let [[_ options selector arg-map :as schema] (->> schema
+                                                     (validate-diffable)
+                                                     (validate-interpable))]
+    (assert (= 4 (count schema))
+            (format "Invalid schema: %s. :multi-s must have 2 or 3 arguments."
+                    schema))
+    (assert (keyword? selector)
+            (format "Invalid schema: %s. The :selector parameter of a :multi must be a keyword."
+                    schema))
+    (assert (map? arg-map)
+            (format "Invalid schema: %s. The last parameter of a :multi must be a map."
+                    schema))
+    (let [multi-cases   (keys arg-map)
+          inner-schemas (vals arg-map)]
+      [:multi (select-keys options [:diff :interp])
+       selector
+       (zipmap multi-cases (map validate-schema inner-schemas))])))

 (defn validate-schema [schema]
   (cond


Exception handling for cases when the DB does not exist

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -128,7 +128,11 @@

 (defn is-word-from-dictionary?
     [input]
-    (dictionary/word-exist? input))
+    (try
+        (dictionary/word-exist? input)
+        (catch java.sql.SQLException e
+            (log/error e "is-word-from-dictionary?")
+            false)))

 (defn return-words-from-dictionary
     [input]
@@ -159,7 +163,11 @@

 (defn dictionary-status
     []
-    (str "Number of terms in dictionary: " (dictionary/term-count)))
+    (try
+        (str "Number of terms in dictionary: " (dictionary/term-count))
+        (catch java.sql.SQLException e
+            (log/error e "dictionary-status")
+            "Can not access database")))

 (defn congrats?
     [input]


FIX DATA VALIDATION

FIX DATA VALIDATION

--- src/cljs/bmihw/submit.cljs
+++ src/cljs/bmihw/submit.cljs
@@ -18,10 +18,10 @@
                :keyword keyword
                :content content}]
     (cond
-      (not (or target-username keyword))
+      (not (or (seq target-username) (seq keyword)))
       (js/alert "YOU NEED A USERNAME OR KEYWORD.")

-      (not content)
+      (not (seq content))
       (js/alert "YOU NEED CONTENT.")

       :else


Declare symbols that Cursive cannot resolve

--- src/cljs/cglossa/core.cljs
+++ src/cljs/cglossa/core.cljs
@@ -4,6 +4,8 @@
             [cglossa.centre :as centre]))

 (def state {:showing-results false})
+; avoid "not resolved" messages in Cursive
+(declare getElementById)

 (def data {:categories ["ku" "hest"]
            :users      ["per" "kari"]})