Naming.

Naming.

--- src/fm/simrunner/app.clj
+++ src/fm/simrunner/app.clj
@@ -56,11 +56,11 @@
           on-close (if stand-alone?
                      JFrame/EXIT_ON_CLOSE
                      JFrame/DISPOSE_ON_CLOSE)
-          wdir     (-> working-directory
+          wrkdir   (-> working-directory
                        (or ".")
                        File.
                        .getAbsolutePath)
-          config   (assoc config :working-directory wdir)
+          config   (assoc config :working-directory wrkdir)
           app      (app config view)]
       (wrg/wire-up! view (event-handler app))
       (rdg/render! app
@@ -68,7 +68,7 @@
                    (rdg/console-logger (format "%s started."
                                                app-title)
                                        (format "(Working directory: '%s')"
-                                               wdir)))
+                                               wrkdir)))
       (doto frame
         (.setDefaultCloseOperation on-close)
         (.setTitle app-title)


whoops, meant editing to be on type show, not type stats

--- app/src/semtag_web/rendering.cljs
+++ app/src/semtag_web/rendering.cljs
@@ -277,7 +277,6 @@
                                          {:title "Percent of things for a type that have a name"}
                                          {:title "Percent of things for a type that have a url"}]))

-  (enable-editable-table "#type_stats_table" input-queue)
   (enable-clickable-links-on "#type_stats_table" input-queue))

 (defn render-tag-stats-results [_ [_ _ _ new-value] input-queue]
@@ -355,6 +354,7 @@
                           :fields [:name :url :desc :tags :created-at])))
     (add-type-stats tags things))
   (enable-toggle-stats-button input-queue)
+  (enable-editable-table "#type_show_table" input-queue)
   (enable-clickable-links-on "#type_show_table td:not([data-field=url])" input-queue))

 (defn render-alert-fn


transducers are awesome

transducers are awesome

--- spinning/src/app/core.cljs
+++ spinning/src/app/core.cljs
@@ -5,7 +5,7 @@
   (:require
     ;[ankha.core :as ankha]
     [clairvoyant.core :as trace :include-macros true]
-    [cljs.core.async :refer [<! >! chan close! pipe put! sliding-buffer take! timeout]]
+    [cljs.core.async :refer [<! >! chan close! onto-chan pipe put! sliding-buffer take! timeout]]
     [clojure.string :as string]
     [goog.dom :as dom]
     [goog.object]
@@ -156,27 +156,23 @@
 ;; -----------------------------------------------------------------------------
 ;; Sieve of Eratosthenes Prime Number Generator

-(defn chan-of-ints [xform start-n]
-  (let [ints (chan 1 xform)]
-    (go-loop [n start-n]
-      (>! ints n)
-      (recur (inc n)))
-    ints))
-
-(defn new-prime? [n knowm-primes]
-  (every? #(not= 0 (mod n %)) knowm-primes))
+(defn posmod-sift []
+  (fn [rf]
+    (let [seen (volatile! [])]
+      (fn
+        ([] (rf))
+        ([result] (rf result))
+        ([result input]
+         (if (every? #(pos? (mod input %)) @seen)
+           (do (vswap! seen conj input)
+               (rf result input))
+           result))))))

 (defn chan-of-primes []
-  (let [primes (chan)]
-    (go-loop [cur-xf (map identity)
-              cur-ch (chan-of-ints cur-xf 2)
-              knowns [2]]
-      (let [prime  (<! cur-ch)
-            knowns (conj knowns prime)
-            new-xf (filter #(new-prime? % knowns))
-            new-ch (chan-of-ints new-xf prime)]
-        (>! primes prime)
-        (recur new-xf new-ch knowns)))
+  (let [inputs (filter odd? (drop 3 (range)))
+        primes (chan 1 (posmod-sift))]
+    (put! primes 2)
+    (onto-chan primes inputs)
     primes))

 (defn update-soa! [primes]
@@ -190,14 +186,6 @@
     (swap! state assoc-in [:app :update-soa?] true)
     (swap! state assoc-in [:soa :channel] primes)
     (poly/listen-next-tick! (partial update-soa! primes))))
-
-#_(defn start-soa! []
-  (let [primes (chan-of-primes)]
-    (go-loop []
-      (when-let [next-prime (<! primes)]
-        (swap! state update-in [:soa :prime-count] inc)
-        (swap! state assoc-in [:soa :max-prime] next-prime)
-        (recur)))))

 (defn stop-soa! []
   (console/info "stop soa")
@@ -289,7 +277,7 @@
         ppf (str "PPF: " (/ (get-in state [:soa :prime-count]) (get-in state [:env :frame-count])))
         generation (str "Gen: " (get-in state [:gol :generation]))
         population (str "Pop: " (count (get-in state [:gol :cells])))
-        display [f-count fps prime-count ppf generation population]]
+        display [f-count fps prime-count max-prime ppf generation population]]
     (set! (.-innerText (app-div)) (string/join ", " display))))

 (defn render-cycle! [timestamp]


Add check to reload files only if there are no warnings

--- src/adzerk/boot_reload.clj
+++ src/adzerk/boot_reload.clj
@@ -121,7 +121,11 @@
                           (send-visual! @pod {:exception (merge {:message (.getMessage e)}
                                                                 (ex-data e))})
                           (throw e)))]
-          (send-changed! @pod asset-path (changed @prev fileset))
-          (doseq [f (relevant-cljs-edn nil fileset ids)]
-            (send-visual! @pod (:adzerk.boot-cljs/messages f)))
-          (reset! prev fileset))))))
+          (let [warnings (apply merge (map :adzerk.boot-cljs/warnings (relevant-cljs-edn nil fileset ids)))]
+            (send-visual! @pod {:warnings warnings})
+            ; Only send changed files when there are no warnings
+            ; As prev is updated only when changes are sent, changes are queued untill they can be sent
+            (when (empty? warnings)
+              (send-changed! @pod asset-path (changed @prev fileset))
+              (reset! prev fileset))
+            fileset))))))


Documentation.

Documentation.

--- clj_record/validation/built_ins.clj
+++ clj_record/validation/built_ins.clj
@@ -11,4 +11,6 @@
   [pattern]
   (complement (match pattern)))

-(def numeric? (non-match #"\D"))
+(def
+  #^{:doc "Validation function that makes sure a value is numeric (though not necessarily a number)."}
+  numeric? (non-match #"\D"))


Showing a different label when elaborating

Yak shaving, mostly.

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -573,8 +573,10 @@
   )

 (defn write-section []
-  (let [note     (subscribe [:note :current-note])
-        is-busy? (subscribe [:ui-state :is-busy?])]
+  (let [note        (subscribe [:note :current-note])
+        is-busy?    (subscribe [:ui-state :is-busy?])
+        focus       (subscribe [:note :focus])
+        is-focused? (reaction (not-empty @focus))]
     (fn []
       [:fielset
        [:div {:class "form-horizontal"}
@@ -584,7 +586,8 @@
           [:button {:type     "submit"
                     :disabled (or @is-busy? (empty? @note))
                     :class    "btn btn-primary"
-                    :on-click #(dispatch [:memory-save])} "Remember"]
+                    :on-click #(dispatch [:memory-save])}
+           (if @is-focused? "Elaborate" "Record")]
           ]]
         ]]
       )))


Removed wrong assertion

Removed wrong assertion

from scale-points-to-rectangle.

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/layout/util.clj
+++ src/conexp/layout/util.clj
@@ -9,9 +9,6 @@
   [[x1 y1] [x2 y2] points]
   (if (empty? points)
     (illegal-argument (str "Cannot scale empty sequence of points.")))
-  (if (or (= x1 x2)
-	  (= y1 y2))
-    (illegal-argument (str "Cannot scale to rectangle with size 0.")))
   (let [[x0 y0] (first points)
 	[x_min y_min x_max y_max] (loop [x_min x0
 					 y_min y0


disable debug log

disable debug log

--- src/graphql_clj/parser.clj
+++ src/graphql_clj/parser.clj
@@ -4,8 +4,8 @@
             [taoensso.timbre :as log]
             [graphql-clj.type :as type]))

-(log/merge-config! {:level :debug
-                    :appenders {:println {:async? true}}})
+(log/merge-config! {:level :info
+                    :appenders {:println {:async? false}}})

 (def whitespace
   (insta/parser


Sample web ui: show anchors starting at byte-offset 0

Reviewers: zarko

Reviewed By: zarko

Differential Revision: https://phabricator-dot-kythe-repo.appspot.com/D928

--- kythe/web/ui/src-cljs/ui/src.cljs
+++ kythe/web/ui/src-cljs/ui/src.cljs
@@ -88,7 +88,7 @@
         anchors (mapcat overlay-anchors
                   (group-overlapping-anchors
                     (filter (fn [{:keys [start end kind]}]
-                              (and start end (< start end)))
+                              (and (> end 0) (< start end)))
                             (map (fn [{:keys [source_ticket target_ticket anchor_start anchor_end kind target_definition]}]
                                    (let [def (when target_definition
                                                (get definitions (keyword target_definition)))]


Add missing recur on health check

Add missing recur on health check

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -268,4 +268,5 @@
   (future
     (loop []
       (health-check-instances)
-      (Thread/sleep 10000))))
+      (Thread/sleep 10000)
+      (recur))))


don't give thread-id to autocomplete action

--- src/braid/ui/views/autocomplete.cljs
+++ src/braid/ui/views/autocomplete.cljs
@@ -22,7 +22,6 @@
 ;                 html (as returned by (dom/*) functions)
 ;         :action - fn to be triggered when result picked
 ;             inputs:
-;                 thread-id
 ;             output:
 ;                 none expected
 ;         :message-transform - fn to apply to text of message
@@ -65,7 +64,7 @@
                      {:key
                       (fn [] k)
                       :action
-                      (fn [thread-id])
+                      (fn [])
                       :message-transform
                       (fn [text]
                         (string/replace text pattern (str k " ")))
@@ -88,7 +87,7 @@
                      {:key
                       (fn [] (user :id))
                       :action
-                      (fn [thread-id])
+                      (fn [])
                       :message-transform
                       (fn [text]
                         (string/replace text pattern (str "@" (user :nickname) " ")))
@@ -112,7 +111,7 @@
                        {:key
                         (fn [] (tag :id))
                         :action
-                        (fn [thread-id])
+                        (fn [])
                         :message-transform
                         (fn [text]
                           (string/replace text pattern (str "#" (tag :name) " ")))
@@ -127,7 +126,7 @@
                                                     :group-id (store/open-group-id)})]
                           {:key (constantly (tag :id))
                            :action
-                           (fn [thread-id]
+                           (fn []
                              (dispatch! :create-tag [(tag :name) (tag :group-id) (tag :id)]))
                            :message-transform
                            (fn [text]


case insensitive login

case insensitive login

--- server/src/gratefulplace/middleware/auth.clj
+++ server/src/gratefulplace/middleware/auth.clj
@@ -1,6 +1,7 @@
 (ns gratefulplace.middleware.auth
   (:require [gratefulplace.controllers.users :as users]
             [gratefulplace.db.query :as q]
+            [datomic.api :as d]
             [gratefulplace.db.maprules :as mr]
             [flyingmachine.cartographer.core :as c]
             [cemerick.friend :as friend]
@@ -10,7 +11,15 @@

 (defn user
   [username]
-  (if-let [user-ent (q/one [:user/username username])]
+  (if-let [user-ent (-> (d/q '[:find ?e :in $ ?username
+                                          :where
+                                          [?e :user/username ?u]
+                                          [(clojure.string/lower-case ?u) ?lower-username]
+                                          [(= ?lower-username ?username)]],
+                                        (q/db)
+                                        (clojure.string/lower-case username))
+                        ffirst
+                        q/ent)]
     (c/mapify user-ent mr/ent->userauth)))

 (defn credential-fn


Add note to make Datom a type.

Add note to make Datom a type.

--- src/vault/entity/datom.clj
+++ src/vault/entity/datom.clj
@@ -9,6 +9,7 @@
     [vault.entity.tx :as tx]))

+; TODO: make this deftype instead, implement equality checks and such.
 (defrecord Datom [op entity attribute value tx time])


Commented out two very picky nice-to-have corpus tests

--- resources/languages/de/corpus/time.clj
+++ resources/languages/de/corpus/time.clj
@@ -4,6 +4,14 @@
   {:reference-time (time/t -2 2013 2 12 4 30 0)
    :min (time/t -2 1900)
    :max (time/t -2 2100)}
+
+  ; this currently becomes 4 in the morning - thats not wrong, but 16 would be better
+  ;"25.4. um 4"
+  ;(datetime 2013 4 25 16 0)
+
+  ; this currently becomes 3 in the morning - thats not wrong, but 15 would be better
+  ;"morgen um 3"
+  ;(datetime 2013 2 13 15)

   "jetzt"
   "genau jetzt"
@@ -584,11 +592,8 @@
   "um 2"
   (datetime 2013 2 12 14)

-  "25.4. um 4"
-  (datetime 2013 4 25 16 0)

   "morgen um 15 Uhr"
-  "morgen um 3"
   (datetime 2013 2 13 15)

   "nach 14 Uhr"


send last screenshot to new clients

send last screenshot to new clients

--- clj/src/i_approve/core.clj
+++ clj/src/i_approve/core.clj
@@ -11,11 +11,10 @@
 (def listeners (atom {}))
 (def clients (atom {}))

-(def last-status (atom nil))
-(defn save-last-status!
-  [status]
-  (reset! last-status status))
-
+(def last-actions (atom {}))
+(defn save-last-action!
+  [action]
+  (swap! last-actions merge action))

 (defn tell!
   [who what]
@@ -46,8 +45,7 @@
     (web-socket-handler
       clients
       (fn []
-        (when @last-status
-          (tell! clients @last-status)))
+        (tell! clients @last-actions))
       (fn [data]
         (tell! listeners data)
         (with-mongo db (insert! :comments data)))))
@@ -58,10 +56,7 @@
       (fn [data]
         (tell! clients data)
         (with-mongo db (insert! :actions data))
-        (doseq [[k v] data]
-          (case k
-            "tab-changed" (save-last-status! data)
-            "screenshot"  (spit "/Users/chetan/Desktop/screenshot.jpg" v))))))
+        (save-last-action! data))))
   (GET "/" []
   	(clojure.java.io/resource "public/index.html"))
   (route/resources "/")


Don't close the response OutputStream

Don't close the response OutputStream

Also don't flush the OutputStream. The Servlet Container will flush
and close the response OutputStream.

--- ring-servlet/src/ring/util/servlet.clj
+++ ring-servlet/src/ring/util/servlet.clj
@@ -103,10 +103,8 @@
           (.print writer (str chunk))
           (.flush writer)))
     (instance? InputStream body)
-      (with-open [out (.getOutputStream response)
-                  ^InputStream b body]
-        (io/copy b out)
-        (.flush out))
+      (with-open [^InputStream b body]
+        (io/copy b (.getOutputStream response)))
     (instance? File body)
       (let [^File f body]
         (with-open [stream (FileInputStream. f)]


Added trace when tag not found

Added trace when tag not found

--- src/cljs/common/ghoul/parse_rss.cljs
+++ src/cljs/common/ghoul/parse_rss.cljs
@@ -14,9 +14,14 @@
   ([map node target-keyword tag] (add-tag map node target-keyword tag identity))
   ([map node target-keyword tag transformer]
    (try
-     (assoc map (keyword target-keyword) (-> node (.getElements tag) (aget 0) .getText transformer))
+     (let [tag-elements (-> node (.getElements tag))
+           to-insert (if (and (not (nil? tag-elements))
+                              (> (.-length tag-elements) 0))
+                       (-> tag-elements (aget 0) .getText transformer)
+                       (do (.log js/console (str "Not found " tag)) nil))]
+       (assoc map (keyword target-keyword) to-insert))
      (catch js/Object e
-       (do (.log js/console (str e) node)
+       (do (.log js/console (str "Error processing " target-keyword " " tag) node e)
            (assoc map (keyword tag) nil))))))

 (defn parse-node [node]


Focus management #38 - :focus-traversal-order performance optimization rolled back

--- src/flatgui/focus.clj
+++ src/flatgui/focus.clj
@@ -93,20 +93,17 @@
 ;;; Sorts focusable components so that they are traversed in left->right, up->down direction.
 ;;; To make such an order, arranges components in a vector of horizontal "lines".
 ;;;
-;;; NOTE: This implementation is slow. Use only if explicitly needed to follow changes in child positions
-(fg/defevolverfn sort-focus-traversal-order-evolver :focus-traversal-order
+;;;  NOTE:
+;;; This implementation is slow. For containers that have frequenlty moving children, it's better
+;;; to wrap it into another function that would call this one in rare cases (e.g. only when :children
+;;; change)
+(fg/defevolverfn :focus-traversal-order
   (let [accepting-children (get-accepting-children component)]
     (if (pos? (count accepting-children))
       (let [lines (group-by-lines component accepting-children)
             result (mapcat (fn [i] (map :id (nth lines i))) (range 0 (count lines)))]
         result)
       [])))
-
-(fg/defevolverfn :focus-traversal-order
-  (let [reason (fg/get-reason)]
-    (if (or (nil? reason) (= reason [:this]))
-      (sort-focus-traversal-order-evolver component)
-      old-focus-traversal-order)))

 (fg/defaccessorfn get-child-ids-in-traversal-order [component]
   (if-let [focus-traversal-order (get-property component [:this] :focus-traversal-order)]


adding some more validations on add form on click

--- src_cljs/rrm/corecljs.cljs
+++ src_cljs/rrm/corecljs.cljs
@@ -621,7 +621,7 @@
          (when (nil? (:id @data-set)) [button {:bs-style "info" :on-click #((reset! data-set {:isactive true})
                                                                             (reset-mut-combo-boxes))} "Refresh"])
          [button {:bs-style "danger" :on-click form-cancel } "Cancel"]]]]
-       [:span (str @data-set)]
+       ;; [:span (str @data-set)]
        ]]]])

 (defn receiveddate-validator [data-set]
@@ -732,25 +732,28 @@

 (defn add-form-onclick [data-set focus]
-  (if (= nil (form-validator @data-set))
-    (let [onres (fn[json] (swap! data-set dissoc
-                                 :mutationnumber
-                                 :khasranumber
-                                 :khatakhatuninumber
-                                 :nameofthesecondparty
-                                 :nameofthefirstparty
-                                 :nameofpo
-                                 :o6number
-                                 :o2number
-                                 :o4number
-                                 :title
-                                 :dateofdecision
-                                 :dateofinstitution
-                                 :racknumber
-                                 :area
+  (if (= nil (@data-set :senddate))
+    (if (= nil (form-validator @data-set))
+      (let [onres (fn[json] (swap! data-set dissoc
+                                 :mutationnumber  :khasranumber  :khatakhatuninumber
+                                 :nameofthesecondparty :nameofthefirstparty
+                                 :nameofpo :o6number :o2number :o4number
+                                 :title :dateofdecision :dateofinstitution
+                                 :racknumber :area :senddate
+                                 :remarks
                                  ))]
-      (http-post (str serverhost "mutations") onres  (.serialize (Serializer.) (clj->js (map-mutation-data @data-set)))))
-    (reset! focus "on")))
+        (http-post (str serverhost "mutations") onres  (.serialize (Serializer.) (clj->js (map-mutation-data @data-set)))))
+      (reset! focus "on"))
+    (when (= nil (form-validator @data-set) (senddate-validator @data-set))
+      (let [onres (fn[json] (swap! data-set dissoc
+                                   :mutationnumber  :khasranumber  :khatakhatuninumber
+                                   :nameofthesecondparty :nameofthefirstparty
+                                   :nameofpo :o6number :o2number :o4number
+                                   :title :dateofdecision :dateofinstitution
+                                   :racknumber :area :senddate
+                                   :remarks
+                                   ))]
+        (http-post (str serverhost "mutations") onres  (.serialize (Serializer.) (clj->js (map-mutation-data @data-set))))))))

 (defn update-form-onclick [data-set focus]
   (if (= nil (@data-set :senddate) (@data-set :receiveddate))


make default tab "usage-queue" while running build

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -738,8 +738,8 @@
    (and (:read-settings scopes)
         (build-model/in-usage-queue? build))
    :usage-queue
-   ;; If there's no SSH info, build isn't finished, show the config
-   (build-model/running? build) (if (feature/enabled? :ui-v2) :config :commits)
+   ;; If there's no SSH info, build isn't finished, show the usage-queue or commits.
+   (build-model/running? build) (if (feature/enabled? :ui-v2) :usage-queue :commits)
    ;; Otherwise, just use the first one.
    :else :tests))


add density evolution

add density evolution

--- ws/temporal-analysis.clj
+++ ws/temporal-analysis.clj
@@ -10,7 +10,7 @@
   (:require [gorilla-plot.core :as plot]
             [gg4clj.core :as gg4clj]
             [monger.collection :as mc]
-            [ceres-analytics.core :refer [db news-accounts nodes links]]
+            [ceres-analytics.measures :refer [density]]
             [clojure.data.priority-map :refer [priority-map]]
             [clj-time.core :as t]
             [clj-time.periodic :as p]
@@ -81,5 +81,24 @@
 ;; <=

 ;; @@
+(let [dat {:day (range 3 23)
+           :density (map #(density :full (t/date-time 2015 4 %)) (range 3 23))}]
+  (gg4clj/view
+    [[:<- :d (gg4clj/data-frame dat)]
+     (gg4clj/r+
+       [:ggplot :d [:aes :day :density]]
+       [:geom_line {:stat "identity" :color "steelblue"}]
+       [:geom_point {:color "steelblue"}]
+       [:xlab "Day"]
+       [:ylab "Density"]
+       [:ggtitle "Density Evolution"])]
+    {:width 10
+     :height 6}))
+;; @@
+;; =>
+;;; {"type":"html","content":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"720pt\" height=\"432pt\" viewBox=\"0 0 720 432\" version=\"1.1\">\n<defs>\n<g>\n<symbol overflow=\"visible\" id=\"94980bc3-0478-471d-8319-22067927c547\">\n<path style=\"stroke:none;\" d=\"\"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"af94a11e-ffc8-484f-8ce1-fb3dee6aa124\">\n<path style=\"stroke:none;\" d=\"M 4.984375 -1.625 L 4.984375 -2.390625 L 3.984375 -2.390625 L 3.984375 -6.796875 L 3.359375 -6.796875 L 0.265625 -2.515625 L 0.265625 -1.625 L 3.140625 -1.625 L 3.140625 0 L 3.984375 0 L 3.984375 -1.625 Z M 3.140625 -2.390625 L 1 -2.390625 L 3.140625 -5.359375 Z M 3.140625 -2.390625 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"07b6ce2f-5553-4a12-b1e2-b5b67a9a0af2\">\n<path style=\"stroke:none;\" d=\"M 1.828125 0 L 1.828125 -1 L 0.828125 -1 L 0.828125 0 Z M 1.828125 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"cf89de59-6622-4d3b-8bee-71daa6160e2f\">\n<path style=\"stroke:none;\" d=\"M 4.859375 -3.265625 C 4.859375 -5.625 4.109375 -6.796875 2.640625 -6.796875 C 1.171875 -6.796875 0.40625 -5.609375 0.40625 -3.328125 C 0.40625 -1.03125 1.1875 0.140625 2.640625 0.140625 C 4.078125 0.140625 4.859375 -1.03125 4.859375 -3.265625 Z M 4 -3.34375 C 4 -1.421875 3.5625 -0.5625 2.625 -0.5625 C 1.734375 -0.5625 1.28125 -1.453125 1.28125 -3.3125 C 1.28125 -5.1875 1.734375 -6.046875 2.640625 -6.046875 C 3.546875 -6.046875 4 -5.171875 4 -3.34375 Z M 4 -3.34375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"48d6dc27-ff9a-4c5f-95fe-8c1ea1069b66\">\n<path style=\"stroke:none;\" d=\"M 4.921875 -2.28125 C 4.921875 -3.015625 4.859375 -3.46875 4.71875 -3.84375 C 4.390625 -4.671875 3.625 -5.171875 2.6875 -5.171875 C 1.28125 -5.171875 0.390625 -4.140625 0.390625 -2.484375 C 0.390625 -0.828125 1.25 0.140625 2.671875 0.140625 C 3.8125 0.140625 4.609375 -0.515625 4.8125 -1.53125 L 4.015625 -1.53125 C 3.796875 -0.859375 3.34375 -0.59375 2.703125 -0.59375 C 1.859375 -0.59375 1.234375 -1.125 1.21875 -2.28125 Z M 4.0625 -3 C 4.0625 -3 4.0625 -2.953125 4.0625 -2.9375 L 1.234375 -2.9375 C 1.3125 -3.828125 1.875 -4.4375 2.671875 -4.4375 C 3.46875 -4.4375 4.0625 -3.78125 4.0625 -3 Z M 4.0625 -3 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"b6592c77-ad99-46e4-bc5d-e5f767dc1f16\">\n<path style=\"stroke:none;\" d=\"M 2.71875 -2.296875 L 2.71875 -3 L 0.4375 -3 L 0.4375 -2.296875 Z M 2.71875 -2.296875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"5cdb481d-18c8-474a-b8d8-28804ca088d8\">\n<path style=\"stroke:none;\" d=\"M 4.921875 -2.109375 C 4.921875 -3.375 4.0625 -4.234375 2.84375 -4.234375 C 2.171875 -4.234375 1.640625 -3.96875 1.28125 -3.46875 C 1.28125 -5.125 1.828125 -6.046875 2.796875 -6.046875 C 3.390625 -6.046875 3.796875 -5.671875 3.9375 -5.03125 L 4.78125 -5.03125 C 4.609375 -6.140625 3.890625 -6.796875 2.84375 -6.796875 C 1.265625 -6.796875 0.40625 -5.46875 0.40625 -3.09375 C 0.40625 -0.984375 1.140625 0.140625 2.703125 0.140625 C 3.984375 0.140625 4.921875 -0.78125 4.921875 -2.109375 Z M 4.0625 -2.046875 C 4.0625 -1.1875 3.484375 -0.609375 2.703125 -0.609375 C 1.921875 -0.609375 1.328125 -1.21875 1.328125 -2.09375 C 1.328125 -2.9375 1.90625 -3.484375 2.734375 -3.484375 C 3.546875 -3.484375 4.0625 -2.953125 4.0625 -2.046875 Z M 4.0625 -2.046875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"8df656a3-f8f8-41cf-a857-0d6f9675bc22\">\n<path style=\"stroke:none;\" d=\"M 4.921875 -2.25 C 4.921875 -3.59375 4.03125 -4.484375 2.71875 -4.484375 C 2.25 -4.484375 1.859375 -4.359375 1.46875 -4.0625 L 1.734375 -5.828125 L 4.5625 -5.828125 L 4.5625 -6.65625 L 1.0625 -6.65625 L 0.546875 -3.09375 L 1.328125 -3.09375 C 1.71875 -3.5625 2.046875 -3.734375 2.578125 -3.734375 C 3.484375 -3.734375 4.0625 -3.140625 4.0625 -2.140625 C 4.0625 -1.15625 3.484375 -0.609375 2.578125 -0.609375 C 1.828125 -0.609375 1.375 -0.984375 1.1875 -1.75 L 0.328125 -1.75 C 0.609375 -0.390625 1.375 0.140625 2.59375 0.140625 C 3.96875 0.140625 4.921875 -0.8125 4.921875 -2.25 Z M 4.921875 -2.25 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"37948431-33c7-4440-adb2-18dbb943d5e1\">\n<path style=\"stroke:none;\" d=\"M 3.328125 0 L 3.328125 -6.796875 L 2.765625 -6.796875 C 2.46875 -5.75 2.28125 -5.609375 0.984375 -5.453125 L 0.984375 -4.84375 L 2.484375 -4.84375 L 2.484375 0 Z M 3.328125 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"36fa1f1c-3fe4-420f-8639-5118001a09e1\">\n<path style=\"stroke:none;\" d=\"M 4.90625 -4.8125 C 4.90625 -5.953125 4.015625 -6.796875 2.71875 -6.796875 C 1.328125 -6.796875 0.53125 -6.09375 0.484375 -4.4375 L 1.328125 -4.4375 C 1.390625 -5.578125 1.859375 -6.0625 2.703125 -6.0625 C 3.46875 -6.0625 4.03125 -5.515625 4.03125 -4.78125 C 4.03125 -4.25 3.71875 -3.796875 3.125 -3.4375 L 2.234375 -2.9375 C 0.8125 -2.140625 0.40625 -1.5 0.328125 0 L 4.859375 0 L 4.859375 -0.828125 L 1.28125 -0.828125 C 1.359375 -1.390625 1.671875 -1.75 2.5 -2.234375 L 3.46875 -2.75 C 4.40625 -3.265625 4.90625 -3.96875 4.90625 -4.8125 Z M 4.90625 -4.8125 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"13371a99-ccdc-4329-9a9a-3409abf19c21\">\n<path style=\"stroke:none;\" d=\"\"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"fd00b189-f2d8-40ff-9803-28ba03e6e278\">\n<path style=\"stroke:none;\" d=\"M 8 -4.375 C 8 -7.09375 6.65625 -8.75 4.4375 -8.75 L 1.0625 -8.75 L 1.0625 0 L 4.4375 0 C 6.640625 0 8 -1.65625 8 -4.375 Z M 6.890625 -4.375 C 6.890625 -2.15625 5.96875 -0.984375 4.25 -0.984375 L 2.1875 -0.984375 L 2.1875 -7.765625 L 4.25 -7.765625 C 5.96875 -7.765625 6.890625 -6.59375 6.890625 -4.375 Z M 6.890625 -4.375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"6b15c19b-c211-4912-aab3-b46b86f14aa0\">\n<path style=\"stroke:none;\" d=\"M 6.421875 -0.03125 L 6.421875 -0.78125 C 6.3125 -0.75 6.265625 -0.75 6.203125 -0.75 C 5.859375 -0.75 5.65625 -0.9375 5.65625 -1.25 L 5.65625 -4.75 C 5.65625 -5.875 4.84375 -6.46875 3.296875 -6.46875 C 1.78125 -6.46875 0.84375 -5.875 0.78125 -4.421875 L 1.78125 -4.421875 C 1.875 -5.203125 2.328125 -5.546875 3.265625 -5.546875 C 4.15625 -5.546875 4.671875 -5.203125 4.671875 -4.609375 L 4.671875 -4.34375 C 4.671875 -3.921875 4.421875 -3.75 3.625 -3.640625 C 2.203125 -3.46875 1.984375 -3.421875 1.609375 -3.265625 C 0.875 -2.96875 0.5 -2.40625 0.5 -1.625 C 0.5 -0.484375 1.296875 0.1875 2.5625 0.1875 C 3.375 0.1875 4.15625 -0.15625 4.703125 -0.75 C 4.8125 -0.265625 5.25 0.078125 5.734375 0.078125 C 5.9375 0.078125 6.09375 0.0625 6.421875 -0.03125 Z M 4.671875 -2.171875 C 4.671875 -1.265625 3.75 -0.703125 2.78125 -0.703125 C 2 -0.703125 1.546875 -0.96875 1.546875 -1.65625 C 1.546875 -2.3125 1.984375 -2.609375 3.0625 -2.765625 C 4.109375 -2.90625 4.328125 -2.953125 4.671875 -3.109375 Z M 4.671875 -2.171875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"1fc40d9a-ebe4-492e-81de-a1f65f7210f4\">\n<path style=\"stroke:none;\" d=\"M 5.734375 -6.28125 L 4.65625 -6.28125 L 2.921875 -1.390625 L 1.3125 -6.28125 L 0.234375 -6.28125 L 2.359375 0.03125 L 1.984375 1.015625 C 1.8125 1.46875 1.609375 1.625 1.171875 1.625 C 1.03125 1.625 0.859375 1.609375 0.640625 1.5625 L 0.640625 2.453125 C 0.859375 2.5625 1.0625 2.609375 1.3125 2.609375 C 2.03125 2.609375 2.609375 2.21875 2.9375 1.3125 Z M 5.734375 -6.28125 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"9da04829-5148-4cfc-b6ef-7cb033c3a31c\">\n<path style=\"stroke:none;\" d=\"\"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"f8a60ab6-f083-406c-8e7d-29d7cecf0882\">\n<path style=\"stroke:none;\" d=\"M -4.375 -8 C -7.09375 -8 -8.75 -6.65625 -8.75 -4.4375 L -8.75 -1.0625 L 0 -1.0625 L 0 -4.4375 C 0 -6.640625 -1.65625 -8 -4.375 -8 Z M -4.375 -6.890625 C -2.15625 -6.890625 -0.984375 -5.96875 -0.984375 -4.25 L -0.984375 -2.1875 L -7.765625 -2.1875 L -7.765625 -4.25 C -7.765625 -5.96875 -6.59375 -6.890625 -4.375 -6.890625 Z M -4.375 -6.890625 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"5344cf14-14d2-4c94-87b7-e3fe3d25426a\">\n<path style=\"stroke:none;\" d=\"M -2.859375 -6.15625 C -3.765625 -6.15625 -4.34375 -6.078125 -4.8125 -5.90625 C -5.84375 -5.5 -6.46875 -4.53125 -6.46875 -3.359375 C -6.46875 -1.609375 -5.171875 -0.484375 -3.109375 -0.484375 C -1.046875 -0.484375 0.1875 -1.578125 0.1875 -3.34375 C 0.1875 -4.78125 -0.640625 -5.765625 -1.90625 -6.03125 L -1.90625 -5.015625 C -1.078125 -4.734375 -0.75 -4.171875 -0.75 -3.375 C -0.75 -2.328125 -1.421875 -1.546875 -2.859375 -1.53125 Z M -3.75 -5.09375 C -3.75 -5.09375 -3.703125 -5.09375 -3.671875 -5.078125 L -3.671875 -1.546875 C -4.78125 -1.625 -5.546875 -2.34375 -5.546875 -3.34375 C -5.546875 -4.328125 -4.734375 -5.09375 -3.75 -5.09375 Z M -3.75 -5.09375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"d65faf52-42e0-4eb1-ab78-31844921022f\">\n<path style=\"stroke:none;\" d=\"M 0 -5.84375 L -4.75 -5.84375 C -5.796875 -5.84375 -6.46875 -5.0625 -6.46875 -3.859375 C -6.46875 -2.921875 -6.109375 -2.3125 -5.234375 -1.765625 L -6.28125 -1.765625 L -6.28125 -0.84375 L 0 -0.84375 L 0 -1.84375 L -3.46875 -1.84375 C -4.75 -1.84375 -5.59375 -2.53125 -5.59375 -3.546875 C -5.59375 -4.34375 -5.109375 -4.84375 -4.359375 -4.84375 L 0 -4.84375 Z M 0 -5.84375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"2a58f5f4-fc05-4c70-a7eb-98ffae9d6bf4\">\n<path style=\"stroke:none;\" d=\"M -1.765625 -5.515625 C -2.703125 -5.515625 -3.171875 -4.984375 -3.46875 -3.734375 L -3.703125 -2.765625 C -3.890625 -1.953125 -4.15625 -1.609375 -4.59375 -1.609375 C -5.171875 -1.609375 -5.546875 -2.125 -5.546875 -2.9375 C -5.546875 -3.75 -5.203125 -4.171875 -4.53125 -4.203125 L -4.53125 -5.25 C -5.765625 -5.25 -6.46875 -4.421875 -6.46875 -2.96875 C -6.46875 -1.515625 -5.71875 -0.5625 -4.546875 -0.5625 C -3.5625 -0.5625 -3.09375 -1.0625 -2.734375 -2.5625 L -2.515625 -3.484375 C -2.34375 -4.1875 -2.140625 -4.46875 -1.6875 -4.46875 C -1.09375 -4.46875 -0.75 -3.875 -0.75 -3 C -0.75 -2.09375 -0.953125 -1.59375 -1.921875 -1.46875 L -1.921875 -0.40625 C -0.46875 -0.453125 0.1875 -1.265625 0.1875 -2.921875 C 0.1875 -4.5 -0.546875 -5.515625 -1.765625 -5.515625 Z M -1.765625 -5.515625 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"97b3df32-11ba-44a3-b2e2-791cf980a264\">\n<path style=\"stroke:none;\" d=\"M 0 -1.84375 L -6.28125 -1.84375 L -6.28125 -0.84375 L 0 -0.84375 Z M -7.234375 -1.96875 L -8.484375 -1.96875 L -8.484375 -0.71875 L -7.234375 -0.71875 Z M -7.234375 -1.96875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"ca73ad01-6836-4742-9bf0-c2d555ca6e8e\">\n<path style=\"stroke:none;\" d=\"M 0 -3.046875 L -0.84375 -3.046875 C -0.796875 -2.921875 -0.796875 -2.765625 -0.796875 -2.5625 C -0.796875 -2.140625 -0.90625 -2.015625 -1.359375 -2.015625 L -5.46875 -2.015625 L -5.46875 -3.046875 L -6.28125 -3.046875 L -6.28125 -2.015625 L -8.015625 -2.015625 L -8.015625 -1.015625 L -6.28125 -1.015625 L -6.28125 -0.171875 L -5.46875 -0.171875 L -5.46875 -1.015625 L -0.90625 -1.015625 C -0.28125 -1.015625 0.078125 -1.453125 0.078125 -2.234375 C 0.078125 -2.46875 0.0625 -2.71875 0 -3.046875 Z M 0 -3.046875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"ed0466c2-42da-47b7-9ba7-ace2a4c64f6d\">\n<path style=\"stroke:none;\" d=\"M -6.28125 -5.734375 L -6.28125 -4.65625 L -1.390625 -2.921875 L -6.28125 -1.3125 L -6.28125 -0.234375 L 0.03125 -2.359375 L 1.015625 -1.984375 C 1.46875 -1.8125 1.625 -1.609375 1.625 -1.171875 C 1.625 -1.03125 1.609375 -0.859375 1.5625 -0.640625 L 2.453125 -0.640625 C 2.5625 -0.859375 2.609375 -1.0625 2.609375 -1.3125 C 2.609375 -2.03125 2.21875 -2.609375 1.3125 -2.9375 Z M -6.28125 -5.734375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"9e53e992-6791-456e-a3ef-cd71d8ce9c51\">\n<path style=\"stroke:none;\" d=\"\"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"fc131a74-71c3-492e-9e7e-6993533db291\">\n<path style=\"stroke:none;\" d=\"M 9.609375 -5.265625 C 9.609375 -8.515625 8 -10.5 5.328125 -10.5 L 1.28125 -10.5 L 1.28125 0 L 5.328125 0 C 7.984375 0 9.609375 -1.984375 9.609375 -5.265625 Z M 8.265625 -5.25 C 8.265625 -2.59375 7.171875 -1.1875 5.09375 -1.1875 L 2.625 -1.1875 L 2.625 -9.328125 L 5.09375 -9.328125 C 7.171875 -9.328125 8.265625 -7.921875 8.265625 -5.25 Z M 8.265625 -5.25 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"314d1483-21ba-4d80-912b-60ce2bb35069\">\n<path style=\"stroke:none;\" d=\"M 7.390625 -3.421875 C 7.390625 -4.53125 7.296875 -5.21875 7.09375 -5.78125 C 6.59375 -7.015625 5.453125 -7.765625 4.03125 -7.765625 C 1.9375 -7.765625 0.578125 -6.203125 0.578125 -3.734375 C 0.578125 -1.25 1.890625 0.21875 4 0.21875 C 5.734375 0.21875 6.921875 -0.765625 7.234375 -2.296875 L 6.015625 -2.296875 C 5.6875 -1.296875 5.015625 -0.890625 4.046875 -0.890625 C 2.796875 -0.890625 1.859375 -1.703125 1.828125 -3.421875 Z M 6.109375 -4.5 C 6.109375 -4.5 6.109375 -4.4375 6.09375 -4.40625 L 1.859375 -4.40625 C 1.953125 -5.75 2.8125 -6.65625 4.015625 -6.65625 C 5.203125 -6.65625 6.109375 -5.671875 6.109375 -4.5 Z M 6.109375 -4.5 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"e0fd04a9-6ba8-44ee-b2aa-7c7b512840e2\">\n<path style=\"stroke:none;\" d=\"M 7.015625 0 L 7.015625 -5.703125 C 7.015625 -6.953125 6.078125 -7.765625 4.625 -7.765625 C 3.5 -7.765625 2.78125 -7.328125 2.125 -6.28125 L 2.125 -7.546875 L 1.015625 -7.546875 L 1.015625 0 L 2.203125 0 L 2.203125 -4.15625 C 2.203125 -5.703125 3.046875 -6.71875 4.265625 -6.71875 C 5.21875 -6.71875 5.8125 -6.140625 5.8125 -5.234375 L 5.8125 0 Z M 7.015625 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"899a8067-8d25-4a52-81e3-06c1e3c24786\">\n<path style=\"stroke:none;\" d=\"M 6.609375 -2.125 C 6.609375 -3.234375 5.984375 -3.796875 4.484375 -4.15625 L 3.328125 -4.4375 C 2.34375 -4.671875 1.9375 -4.984375 1.9375 -5.515625 C 1.9375 -6.203125 2.546875 -6.65625 3.53125 -6.65625 C 4.5 -6.65625 5.015625 -6.234375 5.046875 -5.453125 L 6.3125 -5.453125 C 6.296875 -6.921875 5.3125 -7.765625 3.578125 -7.765625 C 1.8125 -7.765625 0.671875 -6.859375 0.671875 -5.453125 C 0.671875 -4.28125 1.28125 -3.71875 3.0625 -3.28125 L 4.1875 -3.015625 C 5.03125 -2.8125 5.359375 -2.5625 5.359375 -2.015625 C 5.359375 -1.3125 4.65625 -0.890625 3.59375 -0.890625 C 2.515625 -0.890625 1.921875 -1.15625 1.75 -2.3125 L 0.484375 -2.3125 C 0.546875 -0.5625 1.53125 0.21875 3.5 0.21875 C 5.40625 0.21875 6.609375 -0.65625 6.609375 -2.125 Z M 6.609375 -2.125 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"75138dbc-7675-48f0-885a-6595d9b6e42e\">\n<path style=\"stroke:none;\" d=\"M 2.203125 0 L 2.203125 -7.546875 L 1.015625 -7.546875 L 1.015625 0 Z M 2.359375 -8.6875 L 2.359375 -10.1875 L 0.859375 -10.1875 L 0.859375 -8.6875 Z M 2.359375 -8.6875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"1b31275a-698a-427d-9999-9a70c709c41c\">\n<path style=\"stroke:none;\" d=\"M 3.65625 0 L 3.65625 -1.015625 C 3.5 -0.96875 3.3125 -0.953125 3.078125 -0.953125 C 2.5625 -0.953125 2.421875 -1.09375 2.421875 -1.625 L 2.421875 -6.5625 L 3.65625 -6.5625 L 3.65625 -7.546875 L 2.421875 -7.546875 L 2.421875 -9.625 L 1.21875 -9.625 L 1.21875 -7.546875 L 0.203125 -7.546875 L 0.203125 -6.5625 L 1.21875 -6.5625 L 1.21875 -1.09375 C 1.21875 -0.328125 1.75 0.09375 2.671875 0.09375 C 2.96875 0.09375 3.25 0.078125 3.65625 0 Z M 3.65625 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"1af89fbe-bddb-4ca1-9f8a-24a5e37e7896\">\n<path style=\"stroke:none;\" d=\"M 6.890625 -7.546875 L 5.59375 -7.546875 L 3.5 -1.671875 L 1.5625 -7.546875 L 0.28125 -7.546875 L 2.84375 0.03125 L 2.375 1.21875 C 2.171875 1.75 1.9375 1.953125 1.40625 1.953125 C 1.234375 1.953125 1.03125 1.9375 0.78125 1.875 L 0.78125 2.953125 C 1.015625 3.078125 1.265625 3.140625 1.578125 3.140625 C 2.4375 3.140625 3.125 2.671875 3.53125 1.578125 Z M 6.890625 -7.546875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"5cb8a867-0b16-4460-b702-05dd0fa3c2d6\">\n<path style=\"stroke:none;\" d=\"\"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"9e858675-2ef9-4844-b2ea-061070b7da0f\">\n<path style=\"stroke:none;\" d=\"M 8.828125 0 L 8.828125 -1.1875 L 2.640625 -1.1875 L 2.640625 -4.78125 L 8.359375 -4.78125 L 8.359375 -5.96875 L 2.640625 -5.96875 L 2.640625 -9.328125 L 8.578125 -9.328125 L 8.578125 -10.5 L 1.296875 -10.5 L 1.296875 0 Z M 8.828125 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"a66d7509-7790-45fd-beff-7e3ee34a5ae3\">\n<path style=\"stroke:none;\" d=\"M 7 -7.546875 L 5.640625 -7.546875 L 3.515625 -1.421875 L 1.5 -7.546875 L 0.140625 -7.546875 L 2.796875 0 L 4.109375 0 Z M 7 -7.546875 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"298366cc-ff4e-4a25-a49c-d5467c2814b9\">\n<path style=\"stroke:none;\" d=\"M 7.34375 -3.71875 C 7.34375 -6.328125 6.09375 -7.765625 3.921875 -7.765625 C 1.796875 -7.765625 0.515625 -6.3125 0.515625 -3.78125 C 0.515625 -1.234375 1.78125 0.21875 3.9375 0.21875 C 6.046875 0.21875 7.34375 -1.234375 7.34375 -3.71875 Z M 6.09375 -3.734375 C 6.09375 -1.953125 5.265625 -0.890625 3.9375 -0.890625 C 2.59375 -0.890625 1.765625 -1.9375 1.765625 -3.78125 C 1.765625 -5.59375 2.59375 -6.65625 3.9375 -6.65625 C 5.28125 -6.65625 6.09375 -5.609375 6.09375 -3.734375 Z M 6.09375 -3.734375 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"27fc551c-2e0f-4a4a-ad6b-b92b989064d4\">\n<path style=\"stroke:none;\" d=\"M 2.171875 0 L 2.171875 -10.5 L 0.984375 -10.5 L 0.984375 0 Z M 2.171875 0 \"/>\n</symbol>\n<symbol overflow=\"visible\" id=\"4bf942d2-524d-4582-ad9f-9296e45cf4c5\">\n<path style=\"stroke:none;\" d=\"M 6.9375 0 L 6.9375 -7.546875 L 5.75 -7.546875 L 5.75 -3.390625 C 5.75 -1.84375 4.9375 -0.828125 3.6875 -0.828125 C 2.734375 -0.828125 2.125 -1.40625 2.125 -2.3125 L 2.125 -7.546875 L 0.9375 -7.546875 L 0.9375 -1.84375 C 0.9375 -0.59375 1.875 0.21875 3.34375 0.21875 C 4.453125 0.21875 5.15625 -0.171875 5.859375 -1.171875 L 5.859375 0 Z M 6.9375 0 \"/>\n</symbol>\n</g>\n<clipPath id=\"792e5913-06a5-463e-9def-e62a0d4e548e\">\n  <path d=\"M 63.488281 32.601562 L 706 32.601562 L 706 395 L 63.488281 395 Z M 63.488281 32.601562 \"/>\n</clipPath>\n<clipPath id=\"20aa5edc-9964-4cba-97d4-be5104f775bf\">\n  <path d=\"M 63.488281 373 L 706 373 L 706 374 L 63.488281 374 Z M 63.488281 373 \"/>\n</clipPath>\n<clipPath id=\"e41a4f5d-9144-4f83-ba08-39ff17d19484\">\n  <path d=\"M 63.488281 280 L 706 280 L 706 282 L 63.488281 282 Z M 63.488281 280 \"/>\n</clipPath>\n<clipPath id=\"342c9aaf-9cbf-4253-addd-f60fdf5569e4\">\n  <path d=\"M 63.488281 188 L 706 188 L 706 189 L 63.488281 189 Z M 63.488281 188 \"/>\n</clipPath>\n<clipPath id=\"01b1d4fa-7dcb-4cb4-9c3a-c0580356e4d0\">\n  <path d=\"M 63.488281 95 L 706 95 L 706 97 L 63.488281 97 Z M 63.488281 95 \"/>\n</clipPath>\n<clipPath id=\"e6198697-854a-4d9e-9ffc-7ba86aea5b02\">\n  <path d=\"M 77 32.601562 L 78 32.601562 L 78 395 L 77 395 Z M 77 32.601562 \"/>\n</clipPath>\n<clipPath id=\"1e39620b-fe7b-44fc-8d78-b9f5c8fb7de1\">\n  <path d=\"M 230 32.601562 L 232 32.601562 L 232 395 L 230 395 Z M 230 32.601562 \"/>\n</clipPath>\n<clipPath id=\"0da217c5-c2f3-46b4-ba43-9a6d96fe7bfa\">\n  <path d=\"M 384 32.601562 L 385 32.601562 L 385 395 L 384 395 Z M 384 32.601562 \"/>\n</clipPath>\n<clipPath id=\"e283734a-6b68-4f68-a3a7-00e2901e8f22\">\n  <path d=\"M 537 32.601562 L 539 32.601562 L 539 395 L 537 395 Z M 537 32.601562 \"/>\n</clipPath>\n<clipPath id=\"3b888742-900d-4f60-8215-928a6da86bde\">\n  <path d=\"M 691 32.601562 L 693 32.601562 L 693 395 L 691 395 Z M 691 32.601562 \"/>\n</clipPath>\n<clipPath id=\"abf5f01c-58de-4824-b6ff-351d18b68dee\">\n  <path d=\"M 63.488281 326 L 706.601562 326 L 706.601562 328 L 63.488281 328 Z M 63.488281 326 \"/>\n</clipPath>\n<clipPath id=\"99f308be-7732-4e4e-8589-3016562b18a3\">\n  <path d=\"M 63.488281 234 L 706.601562 234 L 706.601562 236 L 63.488281 236 Z M 63.488281 234 \"/>\n</clipPath>\n<clipPath id=\"f9fc56aa-0e21-4bd9-86d0-b925286f4219\">\n  <path d=\"M 63.488281 141 L 706.601562 141 L 706.601562 144 L 63.488281 144 Z M 63.488281 141 \"/>\n</clipPath>\n<clipPath id=\"b9a57cd6-688d-4815-8169-f20704784b5d\">\n  <path d=\"M 63.488281 49 L 706.601562 49 L 706.601562 51 L 63.488281 51 Z M 63.488281 49 \"/>\n</clipPath>\n<clipPath id=\"e28f4453-11ae-4447-947a-664e605eaaed\">\n  <path d=\"M 153 32.601562 L 155 32.601562 L 155 395.515625 L 153 395.515625 Z M 153 32.601562 \"/>\n</clipPath>\n<clipPath id=\"016fdeb2-8a26-4653-84de-098ced3896d5\">\n  <path d=\"M 307 32.601562 L 309 32.601562 L 309 395.515625 L 307 395.515625 Z M 307 32.601562 \"/>\n</clipPath>\n<clipPath id=\"8c2c2987-c3a5-48cd-86da-ca027791b0f8\">\n  <path d=\"M 460 32.601562 L 462 32.601562 L 462 395.515625 L 460 395.515625 Z M 460 32.601562 \"/>\n</clipPath>\n<clipPath id=\"cd57c39d-3fac-4ae4-b0f2-d86e55c09ad9\">\n  <path d=\"M 614 32.601562 L 616 32.601562 L 616 395.515625 L 614 395.515625 Z M 614 32.601562 \"/>\n</clipPath>\n</defs>\n<g id=\"3bf4de1a-080d-4250-899d-14477d835f69\">\n<rect x=\"0\" y=\"0\" width=\"720\" height=\"432\" style=\"fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;\"/>\n<rect x=\"0\" y=\"0\" width=\"720\" height=\"432\" style=\"fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;\"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 0 432 L 720 432 L 720 0 L 0 0 Z M 0 432 \"/>\n<g clip-path=\"url(#792e5913-06a5-463e-9def-e62a0d4e548e)\" clip-rule=\"nonzero\">\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(89.803922%,89.803922%,89.803922%);fill-opacity:1;\" d=\"M 63.488281 394.511719 L 705.601562 394.511719 L 705.601562 32.597656 L 63.488281 32.597656 Z M 63.488281 394.511719 \"/>\n</g>\n<g clip-path=\"url(#20aa5edc-9964-4cba-97d4-be5104f775bf)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 373.703125 L 705.601562 373.703125 \"/>\n</g>\n<g clip-path=\"url(#e41a4f5d-9144-4f83-ba08-39ff17d19484)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 281.21875 L 705.601562 281.21875 \"/>\n</g>\n<g clip-path=\"url(#342c9aaf-9cbf-4253-addd-f60fdf5569e4)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 188.730469 L 705.601562 188.730469 \"/>\n</g>\n<g clip-path=\"url(#01b1d4fa-7dcb-4cb4-9c3a-c0580356e4d0)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 96.246094 L 705.601562 96.246094 \"/>\n</g>\n<g clip-path=\"url(#e6198697-854a-4d9e-9ffc-7ba86aea5b02)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 77.3125 394.511719 L 77.3125 32.601562 \"/>\n</g>\n<g clip-path=\"url(#1e39620b-fe7b-44fc-8d78-b9f5c8fb7de1)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 230.925781 394.511719 L 230.925781 32.601562 \"/>\n</g>\n<g clip-path=\"url(#0da217c5-c2f3-46b4-ba43-9a6d96fe7bfa)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 384.542969 394.511719 L 384.542969 32.601562 \"/>\n</g>\n<g clip-path=\"url(#e283734a-6b68-4f68-a3a7-00e2901e8f22)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 538.160156 394.511719 L 538.160156 32.601562 \"/>\n</g>\n<g clip-path=\"url(#3b888742-900d-4f60-8215-928a6da86bde)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:0.531496;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(94.901961%,94.901961%,94.901961%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 691.773438 394.511719 L 691.773438 32.601562 \"/>\n</g>\n<g clip-path=\"url(#abf5f01c-58de-4824-b6ff-351d18b68dee)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 327.460938 L 705.601562 327.460938 \"/>\n</g>\n<g clip-path=\"url(#99f308be-7732-4e4e-8589-3016562b18a3)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 234.972656 L 705.601562 234.972656 \"/>\n</g>\n<g clip-path=\"url(#f9fc56aa-0e21-4bd9-86d0-b925286f4219)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 142.488281 L 705.601562 142.488281 \"/>\n</g>\n<g clip-path=\"url(#b9a57cd6-688d-4815-8169-f20704784b5d)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 63.488281 50.003906 L 705.601562 50.003906 \"/>\n</g>\n<g clip-path=\"url(#e28f4453-11ae-4447-947a-664e605eaaed)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 154.121094 394.511719 L 154.121094 32.601562 \"/>\n</g>\n<g clip-path=\"url(#016fdeb2-8a26-4653-84de-098ced3896d5)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 307.734375 394.511719 L 307.734375 32.601562 \"/>\n</g>\n<g clip-path=\"url(#8c2c2987-c3a5-48cd-86da-ca027791b0f8)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 461.351562 394.511719 L 461.351562 32.601562 \"/>\n</g>\n<g clip-path=\"url(#cd57c39d-3fac-4ae4-b0f2-d86e55c09ad9)\" clip-rule=\"nonzero\">\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 614.964844 394.511719 L 614.964844 32.601562 \"/>\n</g>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(27.45098%,50.980392%,70.588235%);stroke-opacity:1;stroke-miterlimit:1;\" d=\"M 92.671875 49.050781 L 123.398438 75.558594 L 154.121094 103.027344 L 184.84375 123.210938 L 215.566406 149.308594 L 246.289062 182.738281 L 277.011719 208.644531 L 307.734375 232.285156 L 338.457031 254.007812 L 369.183594 269.242188 L 399.90625 285.546875 L 430.628906 306.703125 L 492.074219 306.703125 L 522.796875 327.195312 L 553.519531 343.464844 L 614.964844 343.464844 L 645.691406 361.804688 L 676.414062 378.0625 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 94.800781 49.050781 C 94.800781 51.886719 90.546875 51.886719 90.546875 49.050781 C 90.546875 46.214844 94.800781 46.214844 94.800781 49.050781 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 125.523438 75.558594 C 125.523438 78.394531 121.269531 78.394531 121.269531 75.558594 C 121.269531 72.726562 125.523438 72.726562 125.523438 75.558594 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 156.246094 103.027344 C 156.246094 105.859375 151.992188 105.859375 151.992188 103.027344 C 151.992188 100.191406 156.246094 100.191406 156.246094 103.027344 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 186.96875 123.210938 C 186.96875 126.042969 182.71875 126.042969 182.71875 123.210938 C 182.71875 120.375 186.96875 120.375 186.96875 123.210938 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 217.691406 149.308594 C 217.691406 152.140625 213.441406 152.140625 213.441406 149.308594 C 213.441406 146.472656 217.691406 146.472656 217.691406 149.308594 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 248.414062 182.738281 C 248.414062 185.570312 244.164062 185.570312 244.164062 182.738281 C 244.164062 179.902344 248.414062 179.902344 248.414062 182.738281 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 279.136719 208.644531 C 279.136719 211.476562 274.886719 211.476562 274.886719 208.644531 C 274.886719 205.808594 279.136719 205.808594 279.136719 208.644531 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 309.863281 232.285156 C 309.863281 235.121094 305.609375 235.121094 305.609375 232.285156 C 305.609375 229.449219 309.863281 229.449219 309.863281 232.285156 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 340.585938 254.007812 C 340.585938 256.839844 336.332031 256.839844 336.332031 254.007812 C 336.332031 251.171875 340.585938 251.171875 340.585938 254.007812 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 371.308594 269.242188 C 371.308594 272.074219 367.054688 272.074219 367.054688 269.242188 C 367.054688 266.40625 371.308594 266.40625 371.308594 269.242188 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 402.03125 285.546875 C 402.03125 288.382812 397.777344 288.382812 397.777344 285.546875 C 397.777344 282.714844 402.03125 282.714844 402.03125 285.546875 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 432.753906 306.703125 C 432.753906 309.539062 428.503906 309.539062 428.503906 306.703125 C 428.503906 303.867188 432.753906 303.867188 432.753906 306.703125 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 463.476562 306.703125 C 463.476562 309.539062 459.226562 309.539062 459.226562 306.703125 C 459.226562 303.867188 463.476562 303.867188 463.476562 306.703125 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 494.199219 306.703125 C 494.199219 309.539062 489.949219 309.539062 489.949219 306.703125 C 489.949219 303.867188 494.199219 303.867188 494.199219 306.703125 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 524.921875 327.195312 C 524.921875 330.03125 520.671875 330.03125 520.671875 327.195312 C 520.671875 324.363281 524.921875 324.363281 524.921875 327.195312 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 555.648438 343.464844 C 555.648438 346.300781 551.394531 346.300781 551.394531 343.464844 C 551.394531 340.628906 555.648438 340.628906 555.648438 343.464844 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 586.371094 343.464844 C 586.371094 346.300781 582.117188 346.300781 582.117188 343.464844 C 582.117188 340.628906 586.371094 340.628906 586.371094 343.464844 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 617.09375 343.464844 C 617.09375 346.300781 612.839844 346.300781 612.839844 343.464844 C 612.839844 340.628906 617.09375 340.628906 617.09375 343.464844 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 647.816406 361.804688 C 647.816406 364.640625 643.5625 364.640625 643.5625 361.804688 C 643.5625 358.972656 647.816406 358.972656 647.816406 361.804688 \"/>\n<path style=\" stroke:none;fill-rule:nonzero;fill:rgb(27.45098%,50.980392%,70.588235%);fill-opacity:1;\" d=\"M 678.539062 378.0625 C 678.539062 380.898438 674.285156 380.898438 674.285156 378.0625 C 674.285156 375.226562 678.539062 375.226562 678.539062 378.0625 \"/>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#af94a11e-ffc8-484f-8ce1-fb3dee6aa124\" x=\"23.398438\" y=\"329.980469\"/>\n  <use xlink:href=\"#07b6ce2f-5553-4a12-b1e2-b5b67a9a0af2\" x=\"28.732422\" y=\"329.980469\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"31.399414\" y=\"329.980469\"/>\n  <use xlink:href=\"#48d6dc27-ff9a-4c5f-95fe-8c1ea1069b66\" x=\"36.733398\" y=\"329.980469\"/>\n  <use xlink:href=\"#b6592c77-ad99-46e4-bc5d-e5f767dc1f16\" x=\"42.067383\" y=\"329.980469\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"45.261719\" y=\"329.980469\"/>\n  <use xlink:href=\"#5cdb481d-18c8-474a-b8d8-28804ca088d8\" x=\"50.595703\" y=\"329.980469\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#af94a11e-ffc8-484f-8ce1-fb3dee6aa124\" x=\"23.398438\" y=\"237.492188\"/>\n  <use xlink:href=\"#07b6ce2f-5553-4a12-b1e2-b5b67a9a0af2\" x=\"28.732422\" y=\"237.492188\"/>\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"31.399414\" y=\"237.492188\"/>\n  <use xlink:href=\"#48d6dc27-ff9a-4c5f-95fe-8c1ea1069b66\" x=\"36.733398\" y=\"237.492188\"/>\n  <use xlink:href=\"#b6592c77-ad99-46e4-bc5d-e5f767dc1f16\" x=\"42.067383\" y=\"237.492188\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"45.261719\" y=\"237.492188\"/>\n  <use xlink:href=\"#5cdb481d-18c8-474a-b8d8-28804ca088d8\" x=\"50.595703\" y=\"237.492188\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"23.398438\" y=\"145.007812\"/>\n  <use xlink:href=\"#07b6ce2f-5553-4a12-b1e2-b5b67a9a0af2\" x=\"28.732422\" y=\"145.007812\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"31.399414\" y=\"145.007812\"/>\n  <use xlink:href=\"#48d6dc27-ff9a-4c5f-95fe-8c1ea1069b66\" x=\"36.733398\" y=\"145.007812\"/>\n  <use xlink:href=\"#b6592c77-ad99-46e4-bc5d-e5f767dc1f16\" x=\"42.067383\" y=\"145.007812\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"45.261719\" y=\"145.007812\"/>\n  <use xlink:href=\"#5cdb481d-18c8-474a-b8d8-28804ca088d8\" x=\"50.595703\" y=\"145.007812\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"23.398438\" y=\"52.523438\"/>\n  <use xlink:href=\"#07b6ce2f-5553-4a12-b1e2-b5b67a9a0af2\" x=\"28.732422\" y=\"52.523438\"/>\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"31.399414\" y=\"52.523438\"/>\n  <use xlink:href=\"#48d6dc27-ff9a-4c5f-95fe-8c1ea1069b66\" x=\"36.733398\" y=\"52.523438\"/>\n  <use xlink:href=\"#b6592c77-ad99-46e4-bc5d-e5f767dc1f16\" x=\"42.067383\" y=\"52.523438\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"45.261719\" y=\"52.523438\"/>\n  <use xlink:href=\"#5cdb481d-18c8-474a-b8d8-28804ca088d8\" x=\"50.595703\" y=\"52.523438\"/>\n</g>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 59.234375 327.460938 L 63.488281 327.460938 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 59.234375 234.972656 L 63.488281 234.972656 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 59.234375 142.488281 L 63.488281 142.488281 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 59.234375 50.003906 L 63.488281 50.003906 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 154.121094 398.765625 L 154.121094 394.511719 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 307.734375 398.765625 L 307.734375 394.511719 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 461.351562 398.765625 L 461.351562 394.511719 \"/>\n<path style=\"fill:none;stroke-width:1.062992;stroke-linecap:butt;stroke-linejoin:round;stroke:rgb(49.803922%,49.803922%,49.803922%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 614.964844 398.765625 L 614.964844 394.511719 \"/>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"151.121094\" y=\"407.621094\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#37948431-33c7-4440-adb2-18dbb943d5e1\" x=\"302.234375\" y=\"407.621094\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"307.568359\" y=\"407.621094\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#37948431-33c7-4440-adb2-18dbb943d5e1\" x=\"455.851562\" y=\"407.621094\"/>\n  <use xlink:href=\"#8df656a3-f8f8-41cf-a857-0d6f9675bc22\" x=\"461.185547\" y=\"407.621094\"/>\n</g>\n<g style=\"fill:rgb(49.803922%,49.803922%,49.803922%);fill-opacity:1;\">\n  <use xlink:href=\"#36fa1f1c-3fe4-420f-8639-5118001a09e1\" x=\"609.464844\" y=\"407.621094\"/>\n  <use xlink:href=\"#cf89de59-6622-4d3b-8bee-71daa6160e2f\" x=\"614.798828\" y=\"407.621094\"/>\n</g>\n<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n  <use xlink:href=\"#fd00b189-f2d8-40ff-9803-28ba03e6e278\" x=\"373.542969\" y=\"420.975586\"/>\n  <use xlink:href=\"#6b15c19b-c211-4912-aab3-b46b86f14aa0\" x=\"382.207031\" y=\"420.975586\"/>\n  <use xlink:href=\"#1fc40d9a-ebe4-492e-81de-a1f65f7210f4\" x=\"388.579102\" y=\"420.975586\"/>\n</g>\n<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n  <use xlink:href=\"#f8a60ab6-f083-406c-8e7d-29d7cecf0882\" x=\"19.577148\" y=\"234.058594\"/>\n  <use xlink:href=\"#5344cf14-14d2-4c94-87b7-e3fe3d25426a\" x=\"19.577148\" y=\"225.394531\"/>\n  <use xlink:href=\"#d65faf52-42e0-4eb1-ab78-31844921022f\" x=\"19.577148\" y=\"218.722656\"/>\n  <use xlink:href=\"#2a58f5f4-fc05-4c70-a7eb-98ffae9d6bf4\" x=\"19.577148\" y=\"212.050781\"/>\n  <use xlink:href=\"#97b3df32-11ba-44a3-b2e2-791cf980a264\" x=\"19.577148\" y=\"206.050781\"/>\n  <use xlink:href=\"#ca73ad01-6836-4742-9bf0-c2d555ca6e8e\" x=\"19.577148\" y=\"203.386719\"/>\n  <use xlink:href=\"#ed0466c2-42da-47b7-9ba7-ace2a4c64f6d\" x=\"19.577148\" y=\"200.050781\"/>\n</g>\n<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n  <use xlink:href=\"#fc131a74-71c3-492e-9e7e-6993533db291\" x=\"328.542969\" y=\"28.530273\"/>\n  <use xlink:href=\"#314d1483-21ba-4d80-912b-60ce2bb35069\" x=\"338.944336\" y=\"28.530273\"/>\n  <use xlink:href=\"#e0fd04a9-6ba8-44ee-b2aa-7c7b512840e2\" x=\"346.954102\" y=\"28.530273\"/>\n  <use xlink:href=\"#899a8067-8d25-4a52-81e3-06c1e3c24786\" x=\"354.963867\" y=\"28.530273\"/>\n  <use xlink:href=\"#75138dbc-7675-48f0-885a-6595d9b6e42e\" x=\"362.166992\" y=\"28.530273\"/>\n  <use xlink:href=\"#1b31275a-698a-427d-9999-9a70c709c41c\" x=\"365.365234\" y=\"28.530273\"/>\n  <use xlink:href=\"#1af89fbe-bddb-4ca1-9f8a-24a5e37e7896\" x=\"369.370117\" y=\"28.530273\"/>\n  <use xlink:href=\"#5cb8a867-0b16-4460-b702-05dd0fa3c2d6\" x=\"376.573242\" y=\"28.530273\"/>\n  <use xlink:href=\"#9e858675-2ef9-4844-b2ea-061070b7da0f\" x=\"380.578125\" y=\"28.530273\"/>\n  <use xlink:href=\"#a66d7509-7790-45fd-beff-7e3ee34a5ae3\" x=\"390.1875\" y=\"28.530273\"/>\n  <use xlink:href=\"#298366cc-ff4e-4a25-a49c-d5467c2814b9\" x=\"397.174805\" y=\"28.530273\"/>\n  <use xlink:href=\"#27fc551c-2e0f-4a4a-ad6b-b92b989064d4\" x=\"405.18457\" y=\"28.530273\"/>\n  <use xlink:href=\"#4bf942d2-524d-4582-ad9f-9296e45cf4c5\" x=\"408.382812\" y=\"28.530273\"/>\n  <use xlink:href=\"#1b31275a-698a-427d-9999-9a70c709c41c\" x=\"416.392578\" y=\"28.530273\"/>\n  <use xlink:href=\"#75138dbc-7675-48f0-885a-6595d9b6e42e\" x=\"420.397461\" y=\"28.530273\"/>\n  <use xlink:href=\"#298366cc-ff4e-4a25-a49c-d5467c2814b9\" x=\"423.595703\" y=\"28.530273\"/>\n  <use xlink:href=\"#e0fd04a9-6ba8-44ee-b2aa-7c7b512840e2\" x=\"431.605469\" y=\"28.530273\"/>\n</g>\n</g>\n</svg>\n","value":"#gg4clj.core.GGView{:plot-command [[:<- :d [:data.frame {:day [:c 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22], :density [:c 5.5051582E-6 5.36184E-6 5.2133496E-6 5.104232E-6 4.96314E-6 4.782412E-6 4.642357E-6 4.514542E-6 4.3971104E-6 4.3147456E-6 4.2265865E-6 4.112217E-6 4.112217E-6 4.112217E-6 4.0014197E-6 3.9134725E-6 3.9134725E-6 3.9134725E-6 3.8143103E-6 3.7264244E-6]}]] [:+ [:+ [:+ [:+ [:+ [:ggplot :d [:aes :day :density]] [:geom_line {:stat \"identity\", :color \"steelblue\"}]] [:geom_point {:color \"steelblue\"}]] [:xlab \"Day\"]] [:ylab \"Density\"]] [:ggtitle \"Density Evolution\"]]], :options {:width 10, :height 6}}"}
+;; <=

 ;; @@
+
+;; @@


with-repo-sandbox checks out a clean working copy

--- test/clj_git/test_util.clj
+++ test/clj_git/test_util.clj
@@ -1,5 +1,6 @@
 (ns clj-git.test-util
   (:require [clojure.test :refer :all]
+            [clojure.java.shell :refer :all]
             [clj-git.repo :refer :all]
             [clj-git.util :refer :all])
   (:gen-class))
@@ -9,11 +10,13 @@
       (list 'assert (list '.isDirectory (list 'clojure.java.io/as-file bare-repo-path)))
       (list 'assert (list 'not (list '.exists (list 'clojure.java.io/as-file sandbox-pathname))))
       (list 'assert (list '.mkdir (list 'clojure.java.io/as-file sandbox-pathname)))
-      (list 'ok-sh "cp" "-rf" bare-repo-path (str sandbox-pathname "/.git"))
-      (list 'with-redefs ['git-root (list 'fn [] (str sandbox-pathname "/.git"))]
-        (list 'let ['res (cons 'do body)]
-          (list 'ok-sh "rm" "-rf" sandbox-pathname)
-          'res))))
+      (list 'ok-sh "cp" "-rf" bare-repo-path (str sandbox-pathname "/.git/"))
+      (list 'with-redefs ['repo-root (list 'fn [] (str sandbox-pathname "/"))]
+        (list 'with-sh-dir (list 'repo-root)
+          (list 'ok-sh "git" "checkout" ".")
+          (list 'let ['res (cons 'do body)]
+            (list 'ok-sh "rm" "-rf" (str "../" sandbox-pathname))
+            'res)))))

 (deftest t-with-repo-sandbox
   (with-repo-sandbox "fixtures/base_repo.git" "t-with-repo-sandbox"
@@ -22,7 +25,15 @@
       (is (.exists (clojure.java.io/as-file "t-with-repo-sandbox/.git/index")))
     )
     (testing "(git-root) points to the correct location"
-      (is (= (git-root) "t-with-repo-sandbox/.git"))
+      (is (= (git-root) "t-with-repo-sandbox/.git/"))
     )
   )
 )
+
+(deftest t-bare-repo-sandbox
+  (with-repo-sandbox "fixtures/base_repo.git" "t-bare-repo-sandbox"
+    (testing "test_file correctly checked out"
+      (is (.exists (clojure.java.io/as-file (str (repo-root) "test_file"))))
+    )
+  )
+)


PDOK-1599 extract-channel toegevoegd om extract-request te verwerken

--- src/main/clojure/pdok/featured/api.clj
+++ src/main/clojure/pdok/featured/api.clj
@@ -39,6 +39,15 @@
    :file URI
    (s/optional-key :callback) URI})

+(def ExtractRequest
+  "A schema for a JSON extract request"
+  {:dataset s/Str
+   :collection s/Str
+   :extractType s/Str
+   :extractVersion s/Str
+   (s/optional-key :callback) URI})
+
+
 (defn- callbacker [uri run-stats]
   (http/post uri {:body (json/generate-string run-stats) :headers {"Content-Type" "application/json"}}))

@@ -66,31 +75,37 @@
                (go (>! callback-chan [(:callback request) error-stats])))))))
   )

-(defn- process [process-chan http-req]
+(defn- extract* [callback-chan request]
+  (log/info "Processing extract: " request))
+
+(defn- process-request [schema request-chan http-req]
   (let [request (:body http-req)
-        invalid (s/check ProcessRequest request)]
+        invalid (s/check schema request)]
     (if invalid
       (r/status (r/response invalid) 400)
-      (do (go (>! process-chan request)) (r/response {:result :ok})))))
+      (do (go (>! request-chan request)) (r/response {:result :ok})))))

-(defn api-routes [process-chan callback-chan stats]
+(defn api-routes [process-chan extract-chan callback-chan stats]
   (defroutes api-routes
     (context "/api" []
              (GET "/ping" [] (r/response {:pong (tl/local-now)}))
              (POST "/ping" [] (fn [r] (println "!ping pong!" (:body r)) (r/response {:pong (tl/local-now)})))
              (GET "/stats" [] (r/response @stats))
-             (POST "/process" [] (partial process process-chan) ))
+             (POST "/process" [] (partial process-request ProcessRequest process-chan))
+             (POST "/extract" [] (partial process-request ExtractRequest extract-chan )))
     (route/not-found "NOT FOUND")))

 (defn rest-handler [& more]
   (let [pc (chan)
+        ec (chan)
         cc (chan 10)
         stats (atom {:processing nil
                      :processed []
                      :errored []})]
     (go (while true (process* stats cc (<! pc))))
+    (go (while true (extract* cc (<! ec))))
     (go (while true (apply callbacker (<! cc))))
-    (-> (api-routes pc cc stats)
+    (-> (api-routes pc ec cc stats)
         (wrap-json-body {:keywords? true :bigdecimals? true})
         (wrap-json-response)
         (wrap-defaults api-defaults))))


simplify store

simplify store

--- src/cljs/triboard/store.cljs
+++ src/cljs/triboard/store.cljs
@@ -25,8 +25,7 @@

 (def game (reaction (:game @app-state)))
 (def current-turn (reaction (game/current-turn @game)))
-(def current-player (reaction (:player @current-turn)))
-(def ai-player? (reaction (player/is-ai? @current-player)))
+(def ai-player? (reaction (player/is-ai? (:player @current-turn))))

 (def suggestions
   (reaction


remove useless class from aside menu

remove useless class from aside menu

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -63,7 +63,7 @@
             hovered-tool-line?   (:hovered-tool-line (om/get-state owner))]
         (html [:div#app {:class (str/join " " (concat (when show-grid? ["show-grid"])
                                                       (when night-mode? ["night-mode"])))}
-               [:aside.app-aside {:class (when night-mode? ["night-mode"])}
+               [:aside.app-aside
                  (om/build aside/menu app)]
                [:main.app-main
                  (om/build canvas/svg-canvas app)


use correct title for chat button once learned

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -90,9 +90,10 @@
                                 (inc unread-chat-count))]
         (html
           [:a.chat-button {:on-click #(cast! :chat-toggled)
-                                :role "button"
-                                :data-left (when-not chat-button-learned? "Open Chat")
-                                :title (when chat-button-learned? "Chat")}
+                           :role "button"
+                           :data-left (when-not chat-button-learned? "Open Chat")
+                           :title (when chat-button-learned?
+                                    (if chat-opened? "Close Chat" "Open Chat"))}
            (when (and (not chat-opened?) (pos? unread-chat-count))
              [:i.unseen-eids (str unread-chat-count)])
            (common/icon :chat)])))))


viewer-count fixes

viewer-count fixes

--- src-cljs/frontend/components/hud.cljs
+++ src-cljs/frontend/components/hud.cljs
@@ -125,14 +125,15 @@
     (render-state [_ {:keys [editing-name? new-name]}]
         (let [{:keys [cast! db]} (om/get-shared owner)
               client-id (:client-id app)
-              viewers (count (:subscribers app))
+              viewers-count (count (remove (comp :hide-in-list? last) (:subscribers app)))
               can-edit? (not (empty? (:cust app)))
-              viewers-buried? (< 4 viewers)]
+              viewers-buried? (< 4 viewers-count)]
           (html
             [:div.viewers.hud-item
              {:class (concat
                        (when viewers-buried? ["buried"])
-                       (when (:expand-viewers? app) ["expanded"]))}
+                       (when (or (:expand-viewers? app (< 1 viewers-count 5)))
+                         ["expanded"]))}
              [:div.viewers-frame.viewers-others
               (for [[id {:keys [show-mouse? color cust-name hide-in-list?]}] (dissoc (:subscribers app) client-id)
                     :when (not hide-in-list?)
@@ -185,7 +186,8 @@
                       :on-change #(om/set-state! owner :new-name (.. % -target -value))}]]

                    [:div.viewer-name
-                    {:data-count (when viewers viewers)
+                    {:data-count (when (> viewers-count 1)
+                                   viewers-count)
                      :data-name (or (get-in app [:cust :cust/name]) "You")}])
                  [:div.viewer-toggles
                   [:a


Fix wrong args order

Fix wrong args order

--- src-cljs/frontend/models/feature.cljs
+++ src-cljs/frontend/models/feature.cljs
@@ -70,4 +70,4 @@
                   nil :junit-banner}})

 (defn ab-test-treatment [feature]
-  (get-in [feature (enabled? feature)] ab-test-treatments))+  (get-in ab-test-treatments [feature (enabled? feature)]))


Fix client functions to work with Reddit API

--- src/karmanaut/client.clj
+++ src/karmanaut/client.clj
@@ -11,17 +11,14 @@
 (defn body [username]
   (json/read-str (:body (resp username))))

-(defn items [username]
-  ((body username) "items"))
-
 (defn user-data [username]
-  ((items username) 0))
+  ((body username) "data"))

 (defn user-key [username data-key]
   ((user-data username) data-key))

-(defn display-name [username]
-  (user-key username "display_name"))
+(defn link-karma [username]
+  (user-key username "link_karma"))

-(defn rep [username]
-  (user-key username "reputation"))
+(defn comment-karma [username]
+  (user-key username "comment_karma"))


Fix test for aborting exploration

Fix test for aborting exploration

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/tests/fca/exploration.clj
+++ src/conexp/tests/fca/exploration.clj
@@ -52,7 +52,7 @@
         imp #{(make-implication #{1} #{2})}
         res (explore-attributes :context ctx
                                 :background-knowledge imp
-                                :handler #(throw (Exception. "Buh!")))]
+                                :handler (fn [_ _ _] :abort))]
     (is (and (= ctx (:context res))
              (= #{} (:implications res))))))


Remove ns with old name

Remove ns with old name

--- src/clj_chrome_devtools/commands/domsnapshot.clj
+++ src/clj_chrome_devtools/commands/domsnapshot.clj
@@ -1,4 +0,0 @@
-(ns clj-chrome-devtools.commands.domsnapshot
-  "This domain facilitates obtaining document snapshots with DOM, layout, and style information."
-  (:require [clj-chrome-devtools.impl.define :refer [define-domain]]))
-(define-domain "DOMSnapshot")


Update core/run; preserve fittest in each gen

--- clojure/src/evolution_programs/core.clj
+++ clojure/src/evolution_programs/core.clj
@@ -15,16 +15,25 @@

 (def max-generations 20)

+(defn preserving-fittest [f]
+  (fn [& args]
+    (let [population (last args)
+          fittest (apply max-key #(:fitness (meta %)) population)
+          new-pop (apply f args)]
+      (if (.contains new-pop fittest)
+        new-pop
+        (cons fittest (rest new-pop))))))
+
 (defn run
   ([objective limits]
    (run objective limits (spread-logger (console/logger) (chart/logger))))
   ([objective limits logger]
    (ga/run
      objective
-     selection/binary-tournament-without-replacement
-     (partial recombination/crossover
-              (partial crossover/simulated-binary-with-limits limits)
-              (partial mutation/parameter-based-with-limits limits max-generations))
+     (preserving-fittest selection/binary-tournament-without-replacement)
+     (preserving-fittest (partial recombination/crossover-mutation
+                                  (partial crossover/simulated-binary-with-limits limits)
+                                  (partial mutation/parameter-based-with-limits limits max-generations)))
      (ga/terminate-max-generations? max-generations)
      (random-generators/generate-population 20 limits)
      logger)))


outcommented line removed

outcommented line removed

--- src/logic/truthtable.clj
+++ src/logic/truthtable.clj
@@ -30,7 +30,6 @@

   (let [symbols (ttable :symbols)
         table (ttable :table)
-        ;var-spaces (conj (vec (map (comp dec count name) symbols)) 0)]
         var-spaces (-> (comp dec count name) (map symbols) vec (conj 0))]

     ; print original formula


fix autoscroll el npe

fix autoscroll el npe

--- src/cljs/swarmpit/component/service/log.cljs
+++ src/cljs/swarmpit/component/service/log.cljs
@@ -78,13 +78,13 @@
           :label   "Auto-scroll logs"
           :onCheck (fn [_ v]
                      (state/update-value [:autoscroll] v cursor))})]]
-     (if (empty? filtered-items)
-       (comp/form-icon-value icon/info "There are no logs available for the service.")
-       [:div.log#service-log
+     [:div.log#service-log
+      (if (empty? filtered-items)
+        [:span "There are no logs available for the service."]
         (for [item filtered-items]
           [:span
            (when timestamp
              [:span.log-timestamp (:timestamp item)])
            [:span.log-info (str (:taskName item) "." (subs (:task item) 0 12) "@" (:taskNode item))]
            [:span.log-body (str " " (:line item))]
-           [:br]])])]))
+           [:br]]))]]))


tweak tools

tweak tools

--- src/cljx/jamesmacaulay/async_tools/core.cljx
+++ src/cljx/jamesmacaulay/async_tools/core.cljx
@@ -29,17 +29,21 @@
     out))

 (defn do-effects
-  [f ch]
+  [f! ch]
   (go-loop []
     (let [v (<! ch)]
       (when-not (nil? v)
-        (f v)
+        (f! v)
         (recur))))
   ch)

-(defn log
+(defn log-mult
+  [mult]
+  (do-effects println (async/tap mult (chan))))
+
+(defn log-channel
   [ch]
-  (do-effects println ch))
+  (async/map (fn [x] (println x) x) [ch]))

 (deftype ConstantReadPort [boxed-value]


Fix precondition in `validate-order-by!`

--- src/com/puppetlabs/puppetdb/query/paging.clj
+++ src/com/puppetlabs/puppetdb/query/paging.clj
@@ -149,7 +149,7 @@
    the list of fields.  Throws an exception if validation fails."
   [columns paging-options]
   {:pre [(sequential? columns)
-         (every? (some-fn string? keyword?) columns)
+         (every? string? columns)
          ((some-fn nil? map?) paging-options)]}
   (let [columns (map underscores->dashes columns)]
     (doseq [field (map :field (:order-by paging-options))]


Explicitly specify :optimizations :none

Explicitly specify :optimizations :none

Even though ClojureScript compiler defaults to none,
this setting appears to be needed. (Investigating if this
is a cljsbuild issue.)

--- ClojureScript/project.clj
+++ ClojureScript/project.clj
@@ -11,6 +11,7 @@
   :cljsbuild {:builds {:dev
                        {:source-paths ["src"]
                         :compiler     {:output-dir     "out"
+                                       :optimizations  :none
                                        :output-to      "js/main.js"}}
                        :rel
                        {:source-paths ["src"]


additional tests.

additional tests.


More card implementations

More card implementations

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -418,6 +418,12 @@
     :events {:runner-turn-begins {:req (req (> (:agenda-point corp) (:agenda-point runner)))
                                   :msg "to gain 2[Credits]" :effect (effect (gain :credit 2))}}}

+   "Ice Analyzer"
+   {:events {:rez {:req (req (= (:type target) "ICE")) :msg "place 1 [Credits] on ICE Analyzer"
+                   :effect (effect (add-prop card :counter 1))}}
+    :abilities [{:counter-cost 1 :effect (effect (gain :credit 1))
+                 :msg "take 1 [Credits] to install programs"}]}
+
    "Inject"
    {:effect #(doseq [c (take 4 (get-in @%1 [:runner :deck]))]
                (if (= (:type c) "Program")
@@ -457,6 +463,16 @@
    "Ken \"Express\" Tenma: Disappeared Clone"
    {:events {:play-event {:req (req (has? target :subtype "Run")) :once :per-turn
                           :msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}}}
+
+   "Keyhole"
+   {:abilities [{:cost [:click 1] :msg "make run on R&D"
+                 :effect (effect (run :rd
+                                   {:replace-access
+                                    {:prompt "Choose a card to trash"
+                                     :msg (msg "trash " (:title target))
+                                     :choices (req (take 3 (:deck corp)))
+                                     :effect (effect (trash (assoc target :seen true))
+                                                     (shuffle! :corp :deck))}}))}]}

    "Lamprey"
    {:events {:successful-run {:req (req (= target :hq)) :msg "to force the Corp to lose 1 [Credits]"
@@ -1308,6 +1324,10 @@
    "Tollbooth"
    {:msg "force the runner to lose 3 [Credits]" :effect (effect (lose :runner :credit 3))
     :abilities [{:msg "end the run" :effect (effect (end-run))}]}
+
+   "Tsurugi"
+   {:abilities [{:msg "end the run" :effect (effect (end-run))}
+                {:msg "do 1 net damage" :effect (effect (damage :net 1))}]}

    "Tyrant"
    {:advanceable :while-rezzed


#21 - Initial upload to S3 support.

#21 - Initial upload to S3 support.

--- src/biblecli/commands/bucketsync.cljs
+++ src/biblecli/commands/bucketsync.cljs
@@ -13,8 +13,8 @@
 ;;;;   limitations under the License.

 (ns biblecli.commands.bucketsync
-  (:require-macros [cljs.core.async.macros :refer [go]])
-  (:require [cljs.core.async :refer [to-chan chan put! tap mult <!]]
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  (:require [cljs.core.async :refer [to-chan chan put! tap mult <! buffer onto-chan] :as async]
             [cljs.nodejs :refer [require process]]
             [clojure.string :as s]))

@@ -115,31 +115,127 @@
     (AWS.S3. (clj->js cfg))))

 (defn partition-files [s3keys files]
-  [(->> s3keys (filter (fn [[key _]] (not (contains? files key)))) (vec))
-   (->> files (filter (fn [[key _]] (not (contains? s3keys key)))) (vec))
-   (->> files
-        (map (fn [[key path]] (let [etag (get s3keys key :notfound)] [key path etag])))
-        (filter (fn [[_ _ etag]] (not= etag :notfound)))
-        (vec))])
-
-(defn delete-files [s3 onlyremote delete whatif verbose]
-  (go
-    (println onlyremote)
-    (let [parts (partition-all 1000 onlyremote)]
-      (loop [part (first parts)
-             next (rest parts)]
-        (if (not part)
-          [nil true]
-          (do
-            (doseq [key part]
-              (println (str (if whatif "Whatif: " "") "Deleting '" key "' from remote bucket.")))
-            (recur (first next) (rest next))))))))
-
-(defn copy-files [s3 onlylocal whatif]
-  (go))
-
-(defn update-files-if-changed [s3 filelist whatif force verbose]
-  (go))
+  (let [to-delete (->> s3keys (filter (fn [[key _]] (not (contains? files key)))) (vec))
+        to-copy   (->> files (filter (fn [[key _]] (not (contains? s3keys key)))) (vec))
+        to-update (->> files
+                    (map (fn [[key path]] (let [etag (get s3keys key :notfound)] [key path etag])))
+                    (filter (fn [[_ _ etag]] (not= etag :notfound)))
+                    (vec))]
+    [to-delete to-copy to-update]))
+
+(defn log-action [pred whatif verbose & parts]
+  (if pred
+    (let [parts (cond->> (list* parts)
+                         whatif (cons "Whatif: ")
+                         verbose (list* (.toISOString (js/Date.)) " "))]
+      (println (apply str parts)))))
+
+(defn perform-action [chan]
+  (go-loop []
+    (if-let [f (<! chan)]
+      (let [[err _] (<! (f))]
+        (if err
+          [err nil]
+          (recur)))
+      [nil true])))
+
+(defn perform-actions [n coll]
+  (go
+    (let [ch (to-chan coll)
+          workers (->> (range n) (map (fn [_] (perform-action ch))) (vec))]
+      (let [results (<! (async/map (fn [err _] err) workers))
+            err (reduce #(or %1 %2) nil results)
+            res (if err nil true)]
+        [err res]))))
+
+(defn object-props [content-type max-age]
+  {:content-type content-type
+   :max-age max-age})
+
+(defn calc-object-props [key]
+  (cond
+    ; should increase the max-age after things stabilize
+    (or (re-find #"\.html$" key) (re-find #"^[^.]+$" key)) (object-props "text/html;charset=utf-8" 600)
+    (re-find #"\.css$" key) (object-props "text/css;charset=utf-8" 600)
+    (re-find #"\.js$" key) (object-props "text/javascript" 600)
+    (re-find #"\.png" key) (object-props "image/png" 600)
+    (re-find #"\.txt$" key) (object-props "text/plain" 600)
+    (re-find #"\.xml$" key) (object-props "application/xml" 600)
+    :else nil))
+
+(defn calc-md5-digest [buffer]
+  (let [crypto (require "crypto")
+        hash (.createHash crypto "md5")]
+    (.update hash buffer)
+    (.digest hash)))
+
+(defn put-s3-object [s3 key buffer md5buffer]
+  (let [props (calc-object-props key)
+        content-md5 (.toString md5buffer "base64")
+        ch (chan)
+        cb (fn [err data] (put! ch [err data]))]
+    (if props
+      (.putObject
+        s3
+        #js {:ACL "public-read"
+             :Body buffer
+             :CacheControl (str "max-age=" (:max-age props))
+             :ContentMD5 content-md5
+             :ContentType (:content-type props)
+             :Key key
+             :StorageClass "STANDARD"}
+        cb)
+      (cb (str "Could not resolve content-type for '" key "'.") nil))
+    ch))
+
+(defn read-local-file [path]
+  (let [ch (chan)
+        cb (fn [err data] (put! ch [err data]))]
+    (.readFile fs path cb)
+    ch))
+
+(defn make-delete-file-action [s3 keys should-delete whatif verbose]
+  (fn delete []
+    (go
+      (let [msg (if verbose
+                  (str "deleting S3 object(s) '" (s/join keys "', '") "'")
+                  (str "deleting " (count keys) " S3 object(s)"))]
+        (log-action (not should-delete) whatif verbose "Skipped " msg ". Use the --delete option.")
+        (log-action should-delete whatif verbose "Started " msg ".")
+
+        (log-action (and should-delete verbose) whatif verbose "Finished " msg ".")
+        [nil true]))))
+
+(defn make-copy-file-action [s3 [relpath filepath] whatif verbose]
+  (fn copy []
+    (go
+      (let [msg (str "copying '" relpath "' to S3")]
+        (log-action true whatif verbose "Started " msg ".")
+        (let [[err buff] (<! (read-local-file filepath))]
+          (if err
+            (do
+              (log-action true whatif verbose "Failed to read local file '" filepath "'. " err)
+              [err nil])
+            (let [md5buff (calc-md5-digest buff)
+                  [err _] (if whatif
+                            [nil true]
+                            (<! (put-s3-object s3 relpath buff md5buff)))]
+              (if err
+                (do
+                  (log-action true whatif  verbose "Failed while " msg ". " err)
+                  [err nil])
+                (do
+                  (log-action verbose whatif  verbose "Finished " msg ".")
+                  [nil true])))))))))
+
+(defn make-update-file-action [s3 [relpath filepath etag] force whatif verbose]
+  (fn update []
+    (go
+      (let [msg (str "updating '" relpath "' to S3")]
+        (log-action verbose whatif verbose "Comparing local '" relpath "' with remote.")
+        (log-action true whatif verbose "Started " msg ".")
+        (log-action verbose whatif verbose "Finished " msg ".")
+        [nil true]))))

 (defn bucketsync
   {:summary "Synchronize a remote Amazon S3 bucket with a local asset directory."
@@ -160,7 +256,7 @@
                   :default {:bucket "kingjames-beta"
                             :region "us-east-1"
                             :profile "default"}}}
-  [{dir :_ force :force whatif :whatif delete :delete bucket :bucket region :region profile :profile verbose :verbose}]
+  [{dir :_ force :force whatif :whatif delete :delete bucket :bucket region :region profile :profile verbose :verbose :as f}]
   (go
     (if (not= (count dir) 1)
       ["<dir> parameter required." nil]
@@ -174,13 +270,13 @@
         (if firstErr
           [firstErr nil]
           (let [[onlyremote onlylocal both] (partition-files s3keys files)
-                deleteTask (delete-files s3 onlyremote delete whatif verbose)
-                copyTask (copy-files s3 onlylocal whatif)
-                updateTask (update-files-if-changed s3 both whatif force verbose)
-                [deleteErr _] (<! deleteTask)
-                [copyErr _] (<! copyTask)
-                [updateErr _] (<! updateTask)
-                firstErr (or deleteErr copyErr updateErr)]
-            (if firstErr
-              [firstErr nil]
-              [nil true])))))))+                actions (->>
+                          (concat
+                            (map #(make-copy-file-action s3 % whatif verbose) onlylocal)
+                            (->> onlyremote
+                                 (map (fn [key _] key))
+                                 (partition-all 1000)
+                                 (map #(make-delete-file-action s3 % delete whatif verbose)))
+                            (map #(make-update-file-action s3 % force whatif verbose) both))
+                          (vec))]
+            (<! (perform-actions 8 actions))))))))


with-repo-sandbox now cleans up after exceptions

--- test/clj_git/test_util.clj
+++ test/clj_git/test_util.clj
@@ -14,8 +14,10 @@
         (list 'clojure.java.shell/with-sh-dir (list 'clj-git.repo/repo-root)
           (cons 'do (concat
             (list (list 'ok-sh "git" "checkout" "."))
-            body
-            (list (list 'ok-sh "rm" "-rf" (str "../" sandbox-pathname)))))))))
+            (list (list 'try
+              (cons 'do body)
+              (list 'catch 'Exception 'e)
+              (list 'finally (list 'ok-sh "rm" "-rf" (str "../" sandbox-pathname)))))))))))

 (deftest t-with-repo-sandbox
   (with-repo-sandbox "fixtures/base_repo.git" "t-with-repo-sandbox"
@@ -29,6 +31,23 @@
   )
 )

+(deftest t-with-repo-sandbox-cleanup
+  (testing "with-repo-sandbox cleanups up dir after exception"
+    (is (thrown? Exception
+      (with-repo-sandbox "fixtures/base_repo.git" "t-with-repo-sandbox-cleanup"
+        (throw (Exception.)))))
+    (is (not (.exists (clojure.java.io/as-file "t-with-repo-sandbox-cleanup"))))
+  )
+)
+
+(deftest t-with-repo-sandbox-multiargs
+  (testing "with-repo-sandbox handles mutiple body args"
+    (with-repo-sandbox "fixtures/base_repo.git" "t-with-repo-sandbox-multiargs"
+      (+ 1 2) (- 3 4)
+    )
+  )
+)
+
 (deftest t-bare-repo-sandbox
   (with-repo-sandbox "fixtures/base_repo.git" "t-bare-repo-sandbox"
     (testing "test_file correctly checked out"


adding owner migration

adding owner migration

--- src/celestial/persistency/systems.clj
+++ src/celestial/persistency/systems.clj
@@ -98,16 +98,6 @@
   [id hostname]
   (add-system (clone (assoc-in (get-system id) [:machine :hostname] hostname))))

-(defrecord EnvIndices [identifier]
-  Migration
-  (apply- [this]
-    (doseq [id (all-systems)]
-      (update-system id (update-in (get-system id) [:env] keyword))))
-  (rollback [this]))
-
-(defn register-migrations []
-  (register :systems (EnvIndices. :systems-env-indices)))
-
 (defn systems-for
   "grabs all the systems ids that this user can see"
   [username]
@@ -116,4 +106,28 @@
       (flatten (map #(get-system-index :env (keyword %)) envs))
       (get-system-index :owner username))))

+; triggering env indexing and converting to keyword
+(defrecord EnvIndices [identifier]
+  Migration
+  (apply- [this]
+    (doseq [id (systems-for "admin")]
+      (update-system id (update-in (get-system id) [:env] keyword))))
+  (rollback [this]))

+; triggering owner indexing and setting default to admin
+(defrecord OwnerIndices [identifier]
+  Migration
+  (apply- [this]
+    (doseq [id (systems-for "admin")]
+      (when-not ((get-system id) :owner)
+        (update-system id (assoc (get-system id) :owner "admin")))))
+  (rollback [this]))
+
+(defn register-migrations []
+  (register :systems (OwnerIndices. :systems-owner-indices))
+  (register :systems (EnvIndices. :systems-env-indices))
+  )
+
+
+
+


No need to sleep in the shutdown hook any more as (quit) now uses (sync-event) to ensure all event handlers have executed.

--- src/overtone/sc/core.clj
+++ src/overtone/sc/core.clj
@@ -369,11 +369,9 @@
     (ref-set status* :no-audio)
     (unsatisfy-all-dependencies)))

-; TODO: Come up with a better way to delay shutdown until all of the :quit event handlers
-; have executed.  For now we just use 500ms.
 (defonce _shutdown-hook
   (.addShutdownHook (Runtime/getRuntime)
-                    (Thread. #(do (quit) (Thread/sleep 500)))))
+                    (Thread. quit)))

 (defn clear-msg-queue
   "Remove any scheduled OSC messages from the run queue."


add more succinct printing methods for ˚SynthNode and SynthGroup

--- src/overtone/sc/node.clj
+++ src/overtone/sc/node.clj
@@ -85,6 +85,9 @@
 (defrecord SynthNode [synth id target position args sdef status]
   to-synth-id*
   (to-synth-id [this] (:id this)))
+
+(defmethod print-method SynthNode [s-node w]
+  (.write w (format "#<synth-node: %s %d>" (:synth s-node) (:id s-node))))

 (defonce active-synth-nodes* (atom {}))

@@ -194,6 +197,9 @@
 (defrecord SynthGroup [group id target position status]
   to-synth-id*
   (to-synth-id [_] id))
+
+(defmethod print-method SynthGroup [s-group w]
+  (.write w (format "#<synth-node: %s %d>" (:group s-group) (:id s-group))))

 (defn group
   "Create a new synth group as a child of the target group. By default