Now saving after changes, and with current route

Saving after changes have been made should make
the undo/redo more logical (I hope).

Also, routing is saved into app db (for now)
so that actual state of the app should be fully restorable.

--- src/cljs/mathom/core.cljs
+++ src/cljs/mathom/core.cljs
@@ -9,20 +9,34 @@
             [mathom.m :refer [nm request route_param text]]
             ))

+;
+; ClojureScript helpers
+;
+
 (enable-console-print!)

 (devtools/set-pref! :install-sanity-hints true)
 (devtools/install!)

+;
+; App dev helpers
+;
+
 ; Tooldb is for Mithril runtime tools like state store
 (def tooldb (atom {:active_state nil :states []}))
+
+(defn save-route
+  "Persist route into state db
+  under cleverly hidden ::meta structure"
+  [state]
+  (assoc state ::meta {:route (.route js/m)}))

 (defn save-state
   "Saves state into tooldb :states array and sets
   active_state point to last item of array"
   [state]
-  (swap! tooldb update-in [:states] #(conj % state))
-  (swap! tooldb update-in [:active_state] #(- (count (:states @tooldb)) 1)))
+  (swap! tooldb update-in [:states] #(conj % (save-route state)))
+  (swap! tooldb update-in [:active_state] #(dec (count (:states @tooldb)))))

 (defn serialize-edn
   "Serialize given data structure into string"
@@ -80,7 +94,7 @@
       (eval-str s))))

 ;;
-;; APP
+;; Sample App
 ;;

 (defn initialize-db
@@ -88,21 +102,21 @@
   from given data as base map"
   [data]
   (let [cdb (atom data)]
-    {:update    (fn [key val]
-                  (save-state @cdb)
-                  (swap! cdb #(assoc % key val)))
-     :query     (fn [key]
-                  (get @cdb key))
-     :save (fn [] (save-state @cdb))}))
+    {:update  (fn [key val]
+                (swap! cdb #(assoc % key val))
+                (save-state @cdb))
+     :query   (fn [key]
+                (get @cdb key))
+     :persist (fn [] (serialize-local "data" (save-route @cdb)))}))

 (defn index_view
-  [{:keys [update query save]} ctrl]
+  [{:keys [update query persist]} ctrl]
   (let [username (query :username)]
     (nm "div"
       [(nm "h1" "Mithril app with data persistence")
        (nm "div" username)
        (nm "div" [(text "username" username 40 #(update :username %))
-                  (nm "button.pure-button" {:onclick #(save)} "Persist")])
+                  (nm "button.pure-button" {:onclick #(persist)} "Persist")])
        (nm "div" [(nm "textarea" {"rows" 10 "cols" 40} (get-item "data"))])])))

 (def index-app-db


Don't show disable button for expired or used tokens

It doesn't make sense to be able to disable them.

Fixes #845.

--- src/clojars/web/token.clj
+++ src/clojars/web/token.clj
@@ -120,6 +120,8 @@
           [:td.created (format-timestamp (:created token))]
           [:td.updated (when disabled? (format-timestamp (:updated token)))]
           [:td.last-used (format-timestamp (:last_used token))]
-          [:td.actions (when-not disabled?
+          [:td.actions (when-not (or disabled?
+                                     expired?
+                                     used?)
                          (form-to [:delete (str "/tokens/" (:id token))]
                                   [:input.button {:type "submit" :value "Disable Token"}]))]])]]])))


Cameras

Cameras

--- src/clojure/yaw/world.clj
+++ src/clojure/yaw/world.clj
@@ -115,6 +115,13 @@
 ;;CAMERA MANAGEMENT------------------------------------------------
 (defn camera "Retrieve the main camera of the world" [world] (.getCamera world))

+(defn clear-cameras! "Remove all the cameras from the `world`" [world] (.emptyListCamera world))
+
+(defn add-camera!
+  "Add a camera to the `world`"
+  [world idx camera]
+  (.addCamera world idx camera))
+
 ;;COLLISIONS------------------------------------------------------

 (defn create-bouding-box!


comp to compose functions

comp to compose functions

--- src/clojure_noon/core.clj
+++ src/clojure_noon/core.clj
@@ -874,3 +874,54 @@
 ;;recursion uses function composition - instead of passing it to a different function as above, it passes it to itself

+;;Pure Functions
+;; You have already seen one function partial that creates new functions
+;; comp and memoize also creates new functions which rely on referential transparency, immutability or both
+
+;;comp - for creating a new function from the composition of any number of functions - because composing functions is so common in clojure that it has it's own function - comp
+
+((comp inc *) 2 3) ; 7 => 2*3 + 1
+
+;;another example of using comp
+(def character
+  {:name "Smooches McCutes"
+   :attributes {:intelligence 10
+                :strength 4
+                :dexterity 5}})
+
+(def c-int (comp :intelligence :attributes))
+(def c-str (comp :strength :attributes))
+(def c-dex (comp :dexterity :attributes))
+
+(c-int character) ; 10
+(c-str character) ; 4
+(c-dex character) ; 5
+
+;; equivalent of using comp above
+(defn c-str-without-comp [c] (:strength (:attributes c)))
+(c-str-without-comp character) ;4
+;;but as you can tell it's a little longer and less readable
+
+;;when you see comp you immediately know the resulting function's purpose is to combine existing functions in a well-known way
+;;what if one of the functions you want to compose needs to take more than one argument?
+;;A: wrap it in an anonymous function
+
+(defn spell-slots
+  [char]
+  (int (inc (/ (c-int char) 2))))
+
+;;now using comp
+(def spell-slots-comp (comp int inc #(/ % 2) c-int)) ;; to divide by two all you need to do was wrap the division in an anonymous functions
+;;#(/ % 2) - anonymous function that divides an input by 2
+
+(defn two-comp
+  [f g]
+  (fn [& args]
+    (f (apply g args))))
+
+
+
+
+
+
+


(#18285) Disable JMX network connector

(#18285) Disable JMX network connector

We were previously exposing JMX information over the network, to no real
end. Nobody was using that feature, and in fact the feature causes
issues on Ubuntu where remote RMI listener threads bind to all
interfaces by default.

We already expose JMX information via REST, and if people want to get at
more detailed stuff they can always use JConsole or the like.

As a bonus, this should result in a few less active threads and a little
less memory used.

Signed-off-by: Deepak Giridharagopal <d11186354d1ef01ca06ae37d7e23e827da13e85f@puppetlabs.com>

--- src/com/puppetlabs/mq.clj
+++ src/com/puppetlabs/mq.clj
@@ -96,6 +96,8 @@
                (.setPersistent true)
                (set-store-usage! (:store-usage config))
                (set-temp-usage!  (:temp-usage config)))
+          mc (doto (.getManagementContext mq)
+               (.setCreateConnector false))
           db (doto (.getPersistenceAdapter mq)
                (.setIgnoreMissingJournalfiles true)
                (.setArchiveCorruptedIndex true)


Collect tuples fully lazily

Collect tuples fully lazily

--- src/datascript/query.cljc
+++ src/datascript/query.cljc
@@ -754,6 +754,34 @@
   (binding [*implicit-source* (get (:sources context) '$)]
     (reduce resolve-clause context clauses)))

+(defn -collect-tuples
+  [acc rel ^long len copy-map]
+  (->Eduction
+   (comp
+    (map
+     (fn [#?(:cljs t1
+            :clj ^{:tag "[[Ljava.lang.Object;"} t1)]
+       (->Eduction
+        (map
+         (fn [t2]
+           (let [res (aclone t1)]
+             #?(:clj
+                (if (.isArray (.getClass ^Object t2))
+                  (dotimes [i len]
+                    (when-some [idx (aget ^objects copy-map i)]
+                      (aset res i (aget ^objects t2 idx))))
+                  (dotimes [i len]
+                    (when-some [idx (aget ^objects copy-map i)]
+                      (aset res i (get t2 idx)))))
+                :cljs
+                (dotimes [i len]
+                  (when-some [idx (aget ^objects copy-map i)]
+                    (aset res i (da/aget ^objects t2 idx)))))
+             res)))
+        (:tuples rel))))
+    cat)
+   acc))
+
 (defn -collect
   ([context symbols]
     (let [rels (:rels context)]
@@ -775,17 +803,7 @@
            len      (count symbols)]

      :else
-     (recur
-       (for [#?(:cljs t1
-                :clj ^{:tag "[[Ljava.lang.Object;"} t1) acc
-             t2 (:tuples rel)]
-         (let [res (aclone t1)]
-           (dotimes [i len]
-             (when-some [idx (aget copy-map i)]
-               (aset res i (#?(:cljs da/aget :clj get) t2 idx))))
-           res))
-       (next rels)
-       symbols))))
+     (recur (-collect-tuples acc rel len copy-map) (next rels) symbols))))

 (defn collect [context symbols]
   (into #{} (map vec) (-collect context symbols)))


Escaping problem descriptions in the RSS feed

--- src/foreclojure/feeds.clj
+++ src/foreclojure/feeds.clj
@@ -1,5 +1,8 @@
 (ns foreclojure.feeds
   (:use [clojure.contrib.prxml :only [prxml]]))
+
+(defn escape [x]
+  (str "<![CDATA[" x "]>"))

 (defn create-feed
   "Creates a feed with title, link, description, a link to the location of the feed itself, and is populated with a collection of items in the following format:
@@ -19,7 +22,7 @@
                :type "application/rss+xml"}]
              [:title feed-title]
              [:link feed-link]
-             [:description feed-description]
+             [:description (escape feed-description)]
              items]])))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


used :as to refer to clojure.set

used :as to refer to clojure.set

--- src/frontend/uploads.cljs
+++ src/frontend/uploads.cljs
@@ -1,5 +1,5 @@
 (ns moomoo-frontend.uploads
-  (:require [clojure.set]))
+  (:require [clojure.set :as set :refer [difference]]))

 (def blank-upload {:stopped? true
                    :paused?  false
@@ -62,10 +62,10 @@
         active-uploads (active-uploads room-uploads-order uploads)
         inactive-uploads (inactive-uploads room-uploads-order uploads)
         unpaused-inactive-uploads (remove #(:paused? (uploads %)) inactive-uploads)
-        new-upload-ids (clojure.set/difference (set (:client-uploads-order new-state))
-                                               (set (:client-uploads-order old-state)))
-        removed-upload-ids (clojure.set/difference (set (:client-uploads-order old-state))
-                                                   (set (:client-uploads-order new-state)))]
+        new-upload-ids (set/difference (set (:client-uploads-order new-state))
+                                       (set (:client-uploads-order old-state)))
+        removed-upload-ids (set/difference (set (:client-uploads-order old-state))
+                                           (set (:client-uploads-order new-state)))]
     (cond
       (and (not (empty? new-upload-ids))
            (<= (count room-uploads-order) upload-slots))


Refactor and document powertree algorithm

--- src/gigrig/powertree.cljs
+++ src/gigrig/powertree.cljs
@@ -3,23 +3,27 @@

 ;; Zipper
 ;; ======
-(defn- branch? [node]
+(defn- branch?
+  "Returns true if the node is a distributor or isolator"
+  [node]
   (or
    (= :distributor (first node))
    (= :isolator (first node))))

-(defn- children [node]
+(defn- children
+  "Returns all the children of the node"
+  [node]
   (rest node))

-(defn- make-node [node children]
+(defn- make-node
+  "Given the existing node and new children, returns a new node"
+  [node children]
   (cons (first node) children))

 (defn- zipper
+  "Builds our gigrig custom zipper"
   ([] (zipper :distributor))
   ([root] (zip/zipper branch? children make-node [root])))
-
-(defn- location-type [loc]
-  (-> loc zip/node first))

 ;; Tree
@@ -27,7 +31,11 @@
 (def DISTRIBUTOR_LIMIT 6)
 (def ISOLATOR_LIMIT 4)

-(defn- insert [loc pedal]
+(defn- insert
+  "Inserts a pedal at the given location in zipper. When full, the
+  last child will be replaced with a new branch containing both the
+  removed child and the new one."
+  [loc pedal]
   (if (< (count (zip/children loc)) DISTRIBUTOR_LIMIT)
     (zip/append-child loc pedal)
     (let [new-node (zip/make-node loc [:distributor] [(last (zip/children loc)) pedal])]
@@ -46,29 +54,42 @@
               keys
               last)})

-(defn- zip-pedal [pedal]
+(defn- zip-pedal
+  "Returns a version of our pedal coherent with our zip model."
+  [pedal]
   [:pedal (:name pedal)])

-(defn- group-by-power [pedals]
-  (-> (group-by :power pedals)))
-
-(defn- zip-isolators [isolators]
+(defn- zip-isolators
+  "Partitions the isolators and returns an array of zipper
+  isolators. E.g: [:isolator [:pedal '1'] [:pedal '2']]"
+  [isolators]
   (for [pedals (partition-all ISOLATOR_LIMIT isolators)]
     (cons :isolator (map zip-pedal pedals))))

-(defn- iterate-groups [groups]
-  (reduce
-   (fn [loc pedal] (insert loc pedal))
-   (zipper)
-   (concat
-    (map zip-pedal (:distributor groups))
-    (zip-isolators (:isolator groups)))))
+(defn- group-by-power
+  "Groups the pedals by whatever power supply they require"
+  [pedals]
+  (group-by :power pedals))
+
+(defn- prepare-groups
+  "Transforms the power group map into an array of entities ready to
+  be zipped, e.g: pedals and isolators with pedals"
+  [groups]
+  (concat
+   (map zip-pedal (:distributor groups))
+   (zip-isolators (:isolator groups))))
+
+(defn- build-zipper
+  "Inserts all entities into a new gigrig zipper"
+  [entities]
+  (reduce insert (zipper) entities))

 ;; Main
 ;; ====
 (defn build
-  "Builds the powertree for the given pedals"
+  "Builds the powertree for the given pedals."
   [pedals]
   (-> (map simplify pedals)
       group-by-power
-      iterate-groups))
+      prepare-groups
+      build-zipper))


Fork unconditionally for now. This helps some things but *breaks* repl.

We need to come up with an alternate approach for the repl task as Ant
simply refuses to implement support for stdin in a forked process:

http:d5d674c88eb8fb06f2acb6c8959b9c82ff3e98bc@hotmail.com%3E

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -112,12 +112,10 @@
                                           :default native-path)))))
     (.setClasspath java (apply make-path (get-classpath project)))
     (.setFailonerror java true)
-    (when (or (:fork project) (:jvm-opts project)
-              (= :macosx (get-os)) native-path)
-      (.setFork java true)
-      (doseq [arg (get-jvm-args project)]
-        (when-not (re-matches #"^-Xbootclasspath.+" arg)
-          (.setValue (.createJvmarg java) arg))))
+    (.setFork java true)
+    (doseq [arg (get-jvm-args project)]
+      (when-not (re-matches #"^-Xbootclasspath.+" arg)
+        (.setValue (.createJvmarg java) arg)))
     (.setClassname java "clojure.main")
     (.setValue (.createArg java) "-e")
     (let [cp (str (.getClasspath (.getCommandLine java)))


Copy shell wrappers from jar file to FS on install.

--- src/leiningen/install.clj
+++ src/leiningen/install.clj
@@ -1,8 +1,9 @@
 (ns leiningen.install
   "Install the project and its dependencies in your local repository."
-  (:use [leiningen.jar :only [jar]]
+  (:use [leiningen.jar :only [jar manifest-map]]
         [leiningen.pom :only [pom make-model]]
-        [clojure.java.io :only [file]])
+        [leiningen.core :only [home-dir]]
+        [clojure.java.io :only [file copy]])
   (:import [org.apache.maven.artifact.installer ArtifactInstaller]
            [org.apache.maven.project.artifact ProjectArtifactMetadata]
            [org.apache.maven.settings MavenSettingsBuilder]
@@ -10,7 +11,8 @@
            [org.apache.maven.artifact.factory ArtifactFactory]
            [org.apache.maven.artifact.repository.layout
             ArtifactRepositoryLayout]
-           [org.codehaus.plexus.embed Embedder]))
+           [org.codehaus.plexus.embed Embedder]
+           [java.util.jar JarFile]))

 ;; Welcome to the absurdist self-parodying world of Dependency Injection
 (def container (.getContainer (doto (Embedder.) (.start))))
@@ -38,6 +40,17 @@
    (.getPackaging model)
    nil))

+(defn bin-path []
+  (doto (file (home-dir) "bin") .mkdirs))
+
+(defn install-shell-wrapper [jarfile]
+  (when-let [bin-name ((manifest-map (.getManifest jarfile))
+                       "Leiningen-shell-wrapper")]
+    (let [bin-file (file (bin-path) (last (.split bin-name "/")))]
+      (println "Installing shell wrapper to" (.getAbsolutePath bin-file))
+      (copy (.getInputStream jarfile (.getEntry jarfile bin-name)) bin-file)
+      (.setExecutable bin-file true))))
+
 (defn install
   "Install the project and its dependencies in your local repository."
   [project]
@@ -50,5 +63,6 @@
     ;; generated and installed in local repo
     (if (not= "pom" (.getPackaging model))
       (add-metadata artifact (file (pom project))))
+    (install-shell-wrapper (JarFile. jarfile))
     (.install installer jarfile artifact local-repo)))


Don't disable editor controls

Don't disable editor controls

--- src/net/sekao/nightcode/editors.clj
+++ src/net/sekao/nightcode/editors.clj
@@ -56,7 +56,7 @@
         engine (.getEngine webview)
         clojure? (-> file .getName u/get-extension clojure-exts)]
     (shortcuts/add-tooltips! buttons)
-    (-> pane .getChildren (.get 0) (.setDisable true))
+    ;(-> pane .getChildren (.get 0) (.setDisable true))
     (-> engine
         (.executeScript "window")
         (.setMember "java"


corrected socket exception... jetty couldnt find its config due to misnamed config section (#4)

--- src/lcmap/aardvark/system.clj
+++ src/lcmap/aardvark/system.clj
@@ -89,4 +89,4 @@
    :db   (new-database cfg)
    :msg  (new-event cfg)
    :app  (component/using (new-app cfg) [:db :msg])
-   :server (component/using (jetty-server (:server cfg)) [:app])))
+   :http (component/using (jetty-server (:http cfg)) [:app])))


Use external classes and resources when building, add build-library task

--- src/leiningen/droid/build.clj
+++ src/leiningen/droid/build.clj
@@ -22,7 +22,7 @@
 ;;
 (defn create-dex
   "Creates a DEX file from the compiled .class files."
-  [{{:keys [sdk-path out-dex-path]} :android,
+  [{{:keys [sdk-path out-dex-path external-classes-paths]} :android,
     compile-path :compile-path :as project}]
   (info "Creating DEX....")
   (ensure-paths sdk-path)
@@ -31,7 +31,8 @@
         deps (unique-jars (resolve-dependencies :dependencies project))]
     (with-process [proc (map str
                              (flatten [dx-bin "--dex" "--output" out-dex-path
-                                       compile-path annotations deps]))]
+                                       compile-path annotations deps
+                                       external-classes-paths]))]
       (.addShutdownHook (Runtime/getRuntime) (Thread. #(.destroy proc))))))

 (defn build
@@ -60,7 +61,8 @@
   and creating a new one with Internet permission appended to it.
   After the packaging the original manifest file is restored."
   [{{:keys [sdk-path target-version manifest-path assets-path res-path
-            out-res-path out-res-pkg-path]} :android :as project}]
+            out-res-path external-res-paths out-res-pkg-path]} :android
+            :as project}]
   (info "Packaging resources...")
   (ensure-paths sdk-path manifest-path res-path)
   (let [aapt-bin (str sdk-path "/platform-tools/aapt")
@@ -69,14 +71,16 @@
         manifest-file (io/file manifest-path)
         backup-file (io/file (str manifest-path ".backup"))
         ;; Only add `assets` directory if it is present.
-        assets (if (.exists (io/file assets-path)) ["-A" assets-path] [])]
+        assets (if (.exists (io/file assets-path)) ["-A" assets-path] [])
+        external-resources (for [res external-res-paths] ["-S" res])]
     (when dev-build
       (io/copy manifest-file backup-file)
       (write-manifest-with-internet-permission manifest-path))
-    (sh aapt-bin "package" "--no-crunch" "-f" "--debug-mode"
+    (sh aapt-bin "package" "--no-crunch" "-f" "--debug-mode" "--auto-add-overlay"
         "-M" manifest-path
         "-S" out-res-path
         "-S" res-path
+        external-resources
         assets
         "-I" android-jar
         "-F" out-res-pkg-path
@@ -153,3 +157,9 @@
   (doto project
     crunch-resources package-resources
     create-apk sign-apk zipalign-apk))
+
+(defn build-library
+  "Metatask. Generate resources and compile the library project."
+  [project]
+  (doto project
+    code-gen compile crunch-resources))


[l.d.utils] Refactor build-tools discovery

--- src/leiningen/droid/utils.clj
+++ src/leiningen/droid/utils.clj
@@ -35,42 +35,50 @@
   []
   (= java.io.File/separator "\\"))

+(defn get-sdk-build-tools-path
+  "Returns a path to the correct Android Build Tools directory."
+  ([{{:keys [sdk-path build-tools-version]} :android}]
+   (get-sdk-build-tools-path sdk-path build-tools-version))
+  ([sdk-path build-tools-version]
+   (let [bt-root-dir (file sdk-path "build-tools")
+         ;; build-tools directory contains a subdir which name we don't
+         ;; know that has all the tools. Let's grab the last directory
+         ;; inside build-tools/ and hope it is the one we need.
+         bt-dir (or build-tools-version
+                    (->> (.list bt-root-dir)
+                         (filter #(.isDirectory (file bt-root-dir %)))
+                         sort last)
+                    (abort "Build tools not found."
+                           "Download them using the Android SDK Manager."))]
+     (file bt-root-dir bt-dir))))
+
 (defn sdk-binary-paths
   "Returns a map of relative paths to different SDK binaries for both
   Unix and Windows platforms."
   [sdk-path build-tools-version]
   (ensure-paths sdk-path)
-  (let [bt-root-dir (file sdk-path "build-tools")
-        ;; build-tools directory contains a subdir which name we don't
-        ;; know that has all the tools. Let's grab the last directory
-        ;; inside build-tools/ and hope it is the one we need.
-        bt-dir (or build-tools-version
-                   (->> (.list bt-root-dir)
-                        (filter #(.isDirectory (file bt-root-dir %)))
-                        sort last)
-                   (abort "Build tools not found."
-                          "Download them using the Android SDK Manager."))]
-    {:dx {:unix ["build-tools" bt-dir "dx"]
-          :win ["build-tools" bt-dir "dx.bat"]}
-     :adb {:unix ["platform-tools" "adb"]
-           :win ["platform-tools" "adb.exe"]}
-     :aapt {:unix ["build-tools" bt-dir "aapt"]
-            :win ["build-tools" bt-dir "aapt.exe"]}
-     :zipalign {:unix ["build-tools" bt-dir "zipalign"]
-                :win ["build-tools" bt-dir "zipalign.exe"]}
-     :proguard {:unix ["tools" "proguard" "bin" "proguard.sh"]
-                :win ["tools" "proguard" "bin" "proguard.bat"]}}))
+  (let [build-tools (get-sdk-build-tools-path sdk-path build-tools-version)]
+    {:dx {:unix (file build-tools "dx")
+          :win (file build-tools "dx.bat")}
+     :adb {:unix (file sdk-path "platform-tools" "adb")
+           :win (file sdk-path "platform-tools" "adb.exe")}
+     :aapt {:unix (file build-tools "aapt")
+            :win (file build-tools "aapt.exe")}
+     :zipalign {:unix (file build-tools "zipalign")
+                :win (file build-tools "zipalign.exe")}
+     :proguard {:unix (file sdk-path "tools" "proguard" "bin" "proguard.sh")
+                :win (file sdk-path "tools" "proguard" "bin" "proguard.bat")}}))

 (defn sdk-binary
   "Given the project map and the binary keyword, returns either a full
   path to the binary as a string, or a vector with call to cmd.exe for
   batch-files."
   [{{:keys [sdk-path build-tools-version]} :android} binary-kw]
-  (let [binary (get-in (sdk-binary-paths sdk-path build-tools-version)
-                       [binary-kw (if (windows?) :win :unix)])
-        binary-str (str (apply file sdk-path binary))]
+  (let [binary-str (-> (sdk-binary-paths sdk-path build-tools-version)
+                       (get-in [binary-kw (if (windows?) :win :unix)])
+                       str)]
     (ensure-paths binary-str)
-    (if (.endsWith (last binary) ".bat")
+    (if (.endsWith binary-str ".bat")
       ["cmd.exe" "/C" binary-str]
       binary-str)))


Update flatten example to use recur and remove

--- exercises/flatten-array/src/example.clj
+++ exercises/flatten-array/src/example.clj
@@ -4,8 +4,13 @@
 (defn flatten
   "Flattens the given list and removes any nil values"
   [coll]
-  (cond
-    (empty? coll) (list)
-    (nil? (first coll)) (flatten (rest coll))
-    (coll? (first coll)) (concat (flatten (first coll)) (flatten (rest coll)))
-    :else (cons (first coll) (flatten (rest coll)))))
+  (loop
+   [results nil
+    [elem & remaining] coll]
+    (if (or elem remaining)
+      (if (coll? elem)
+        (if (empty? elem)
+          (recur results remaining)
+          (recur results (conj remaining (rest elem) (first elem))))
+        (recur (conj results elem) remaining))
+      (reverse (remove nil? results)))))


[#4754] discard transaction if transaction's modal is closed before sending transaction

--- src/status_im/ui/screens/views.cljs
+++ src/status_im/ui/screens/views.cljs
@@ -116,7 +116,15 @@
       [view common-styles/modal
        [modal {:animation-type   :slide
                :transparent      true
-               :on-request-close #(dispatch [:navigate-back])}
+               :on-request-close (fn []
+                                   (cond
+                                     (#{:wallet-send-transaction-modal
+                                        :wallet-transaction-fee}
+                                      modal-view)
+                                     (dispatch [:wallet/discard-transaction-navigate-back])
+
+                                     :else
+                                     (dispatch [:navigate-back])))}
         (let [component (get-modal-component modal-view)]
           [react/main-screen-modal-view modal-view
            [component]])]])))


Fix indentation problem

Fix indentation problem

--- src/rdf-repository/grafter/rdf/repository.clj
+++ src/rdf-repository/grafter/rdf/repository.clj
@@ -56,9 +56,8 @@
                 (instance? IStatement triples))]}
        (if (not (instance? IStatement triples))
          (when (seq triples)
-               ( let [^Iterable stmts (map IStatement->sesame-statement triples)]
-               (.add this stmts (resource-array)))
-             )
+               (let [^Iterable stmts (map IStatement->sesame-statement triples)]
+                 (.add this stmts (resource-array))))
          (pr/add-statement this triples)))

@@ -68,9 +67,8 @@
                 (instance? IStatement triples))]}
        (if (not (instance? IStatement triples))
          (when (seq triples)
-             ( let [^Iterable stmts (map IStatement->sesame-statement triples)]
-                   (.add this stmts (resource-array (URIImpl. graph))))
-             )
+             (let [^Iterable stmts (map IStatement->sesame-statement triples)]
+               (.add this stmts (resource-array (URIImpl. graph)))))
          (pr/add-statement this triples)))

     ([this graph format triple-stream]


rf ui.cljs anon fns

rf ui.cljs anon fns

--- src/frontend/ui.cljs
+++ src/frontend/ui.cljs
@@ -22,8 +22,8 @@
   [[model signal :as _initial_] view-model view control reconcile]
   ; for now dispatch functions return nil to make API even smaller
   (let [model-atom (r/atom model)
-        dispatch-action (fn [a] (do (swap! model-atom reconcile a) nil))
-        dispatch-signal (fn [s] (do (control @model-atom s dispatch-action) nil))
+        dispatch-action (fn [a] (swap! model-atom reconcile a) nil)
+        dispatch-signal (fn [s] (control @model-atom s dispatch-action) nil)
         connected-view (fn [] [view (view-model @model-atom) dispatch-signal])]
     (some-> signal dispatch-signal)


used idiomatic keyword map access

used idiomatic keyword map access

--- src/midje/unprocessed.clj
+++ src/midje/unprocessed.clj
@@ -16,18 +16,18 @@
 (defmulti ^{:private true} check-result (fn [actual call]
                          (:desired-check call)))

-(defmethod ^{:private true} check-result :check-match [actual call]
-  (cond (extended-= actual (call :expected-result))
+(defmethod check-result :check-match [actual call]
+  (cond (extended-= actual (:expected-result call))
         (report {:type :pass})

         (fn? (call :expected-result))
         (report (merge {:type :mock-expected-result-functional-failure
-                        :binding-note (call :binding-note)
-                        :position (call :position)
-                        :expected (call :expected-result-text-for-failures) }
-                       (if (chatty-checker? (call :expected-result))
+                        :binding-note (:binding-note call)
+                        :position (:position call)
+                        :expected (:expected-result-text-for-failures call) }
+                       (if (chatty-checker? (:expected-result call))
                          (do
-                           (let [chatty-result ((call :expected-result) actual)]
+                           (let [chatty-result ((:expected-result call) actual)]
                              (if (map? chatty-result)
                                chatty-result
                                {:actual actual
@@ -38,30 +38,30 @@
                          {:actual actual})))
         :else
         (report {:type :mock-expected-result-failure
-                 :position (call :position)
-                 :binding-note (call :binding-note)
+                 :position (:position call)
+                 :binding-note (:binding-note call)
                  :actual actual
-                 :expected (call :expected-result) })))
+                 :expected (:expected-result call) })))

-(defmethod ^{:private true} check-result :check-negated-match [actual call]
-   (cond (not (extended-= actual (call :expected-result)))
+(defmethod check-result :check-negated-match [actual call]
+   (cond (not (extended-= actual (:expected-result call)))
          (report {:type :pass})

         (fn? (call :expected-result))
         (report {:type :mock-actual-inappropriately-matches-checker
-                 :binding-note (call :binding-note)
-                 :position (call :position)
-                 :expected (call :expected-result-text-for-failures)
+                 :binding-note (:binding-note call)
+                 :position (:position call)
+                 :expected (:expected-result-text-for-failures call)
                  :actual actual})

         :else
         (report {:type :mock-expected-result-inappropriately-matched
-                 :binding-note (call :binding-note)
-                 :position (call :position)
-                 :expected (call :expected-result-text-for-failures)
+                 :binding-note (:binding-note call)
+                 :position (:position call)
+                 :expected (:expected-result-text-for-failures call)
                  :actual actual})))

-(defn expect* [call-map local-fakes]
+(defn expect* [unprocessed-check local-fakes]
   "The core function in unprocessed Midje. Takes a map describing a
   call and a list of maps, each of which describes a secondary call
   the first call is supposed to make. See the documentation at
@@ -73,7 +73,7 @@
     (with-installed-fakes (concat (reverse (filter :data-fake (background-fakes))) local-fakes)
       (let [code-under-test-result (capturing-exception
                                     (eagerly
-                                     ((call-map :function-under-test))))]
+                                     ((:function-under-test unprocessed-check))))]
         (check-call-counts local-fakes)
-        (check-result code-under-test-result call-map)
+        (check-result code-under-test-result unprocessed-check)
         :irrelevant-return-value))))


Refactor tool 'command' macro.

Refactor tool 'command' macro.

--- src/mvxcvi/vault/tool.clj
+++ src/mvxcvi/vault/tool.clj
@@ -20,62 +20,76 @@

-;; COMMAND TREE STRUCTURE
+;; COMMAND TREE DEFINITION

 ; command nodes look like this:
 #_
 {:name "vault"
- :usage "vault [global opts] <command> [command args]"
+ :usage "[global opts] <command> [command args]"
  :desc "Command-line tool for the vault data store."
  :specs [["--blob-store" "Path to blob-store configuration." ...]]
  :init (fn [opts] ...)
- :commands {"blob" {:name "blob"}}
- :action (fn [opts args] ...)}
+ :action (fn [opts args] ...)
+ :commands [{:name "blob"} ...]}

-(def ^:private ^:dynamic *command-branch*
-  "Vector containing the command names on the current branch."
-  [])
+(defn- make-element-fn
+  "Resolves an element as a function body or symbolic reference."
+  [[element & body]]
+  (when element
+    (if (symbol? (first body))
+      (first body)
+      `(fn ~@body))))
+
+
+(defn- make-command
+  "Constructs a command node map from the given elements."
+  [cmd-name usage desc specs init-element action-element command-elements]
+  (let [cond-assoc (fn [coll [k v]] (if (and k v) (assoc coll k v) coll))
+        nonempty-vec (fn [xs] (and (seq xs) (vec xs)))]
+    (reduce cond-assoc
+            {:name cmd-name
+             :usage usage
+             :desc desc}
+            [[:specs    (nonempty-vec specs)]
+             [:init     (make-element-fn init-element)]
+             [:action   (make-element-fn action-element)]
+             [:commands (nonempty-vec command-elements)]])))

 (defmacro ^:private command
-  "Simple macro for building readable command trees."
+  "Macro to simplify building readable command trees."
   [usage desc & more]
-  (let [[cname usage] (string/split usage #" " 2)
-        [specs more] (split-with vector? more)
-        command {:name cname
-                 :usage `(string/join " " (concat *command-branch* [~usage]))
-                 :desc desc
-                 :specs (vec specs)}
-        elements (group-by first (filter list? more))]
-    (when (> (count (elements 'init)) 1)
+  (let [[cmd-name usage] (string/split usage #" " 2)
+        [specs more]     (split-with vector? more)
+        elements         (group-by first (filter list? more))
+        init-elements    (elements 'init)
+        action-elements  (elements 'action)
+        command-elements (elements 'command)]
+    (when-not (every? list? more)
       (throw (IllegalArgumentException.
-               (str "Multiple `init` elements in command definition: " (elements 'init)))))
-    (when (> (count (elements 'action)) 1)
+               (str "Non-list elements in '" cmd-name "' command definition: "
+                    (filter (complement list?) more)))))
+    (when (> (count init-elements) 1)
       (throw (IllegalArgumentException.
-               (str "Multiple `action` elements in command definition: " (elements 'action)))))
-    (when (and (elements 'command) (elements 'action))
+               (str "Multiple `init` elements in '" cmd-name
+                    "' command definition: " init-elements))))
+    (when (> (count action-elements) 1)
       (throw (IllegalArgumentException.
-               (str "Command definition contains both `command` and `action` elements: " more))))
-    (let [assoc-fn (fn [cmd [k & body]]
-                     (if k
-                       (if (symbol? (first body))
-                         (assoc cmd (keyword k) (first body))
-                         (assoc cmd (keyword k) `(fn ~@body)))
-                       cmd))
-          command (reduce assoc-fn command
-                          [(first (elements 'init))
-                           (first (elements 'action))])]
-      (if-let [subcommands (elements 'command)]
-        `(binding [*command-branch* (conj *command-branch* ~(:name command))]
-           (->>
-             ~(vec subcommands)
-             (map (juxt :name identity))
-             (into {})
-             (assoc ~command :commands)))
-        `(binding [*command-branch* (conj *command-branch* ~(:name command))]
-           ~command)))))
+               (str "Multiple `action` elements in '" cmd-name
+                    "' command definition: " action-elements))))
+    (when (and command-elements action-elements)
+      (throw (IllegalArgumentException.
+               (str "Both `command` and `action` elements in '" cmd-name
+                    "' command definition: " command-elements action-elements))))
+    (make-command cmd-name usage desc specs
+                  (first init-elements)
+                  (first action-elements)
+                  command-elements)))

+
+
+;; COMMAND TREE EXECUTION

 (defn- handle-command
   "Handles a sequence of arguments following a command tree structure."


jline work

jline work

--- src/overtone/gui/repl.clj
+++ src/overtone/gui/repl.clj
@@ -7,6 +7,12 @@
    (java.util.concurrent LinkedBlockingQueue)
    (clojure.lang IDeref))

+  (:import
+   (jline ConsoleReader Terminal)
+   (com.Ostermiller.util CircularByteBuffer)
+   (java.io ByteArrayInputStream BufferedReader InputStreamReader DataOutputStream)
+   (java.nio.charset Charset))
+
   (:import
    (javax.swing JEditorPane JScrollPane  SwingUtilities))

@@ -84,7 +90,7 @@
        (on ::repl-pong #(deliver p true))
        (event ::repl-ping)
        (try
-        (.get (future @p) 1000 TimeUnit/MILLISECONDS)
+        (.get (future @p) 300 TimeUnit/MILLISECONDS)
         (catch TimeoutException t
           false))))

@@ -105,6 +111,285 @@
   (event ::repl-exit)

   (event ::repl-write :text "(println \"hello world\")"))
+
+;; JLine part
+
+(def jline-command-map {:unknown                    'UNKNOWN
+                        :move-to-beg                'MOVE_TO_BEG
+                        :move-to-end                'MOVE_TO_END
+                        :prev-char                  'PREV_CHAR
+                        :newline                    'NEWLINE
+                        :kill-line                  'KILL_LINE
+                        :clear-screen               'CLEAR_SCREEN
+                        :next-history               'NEXT_HISTORY
+                        :prev-history               'PREV_HISTORY
+                        :redisplay                  'REDISPLAY
+                        :kill-line-prev             'KILL_LINE_PREV
+                        :delete-prev-word           'DELETE_PREV_WORD
+                        :next-char                  'NEXT_CHAR
+                        :repeat-prev-char           'REPEAT_PREV_CHAR
+                        :search-prev                'SEARCH_PREV
+                        :repeat-next-char           'REPEAT_NEXT_CHAR
+                        :search-next                'SEARCH_NEXT
+                        :prev-space-word            'PREV_SPACE_WORD
+                        :to-end-word                'TO_END_WORD
+                        :repeat-search-prev         'REPEAT_SEARCH_PREV
+                        :paste-prev                 'PASTE_PREV
+                        :replace-mode               'REPLACE_MODE
+                        :substitute-line            'SUBSTITUTE_LINE
+                        :to-prev-char               'TO_PREV_CHAR
+                        :next-space-word            'NEXT_SPACE_WORD
+                        :delete-prev-char           'DELETE_PREV_CHAR
+                        :add                        'ADD
+                        :prev-word                  'PREV_WORD
+                        :change-meta                'CHANGE_META
+                        :delete-meta                'DELETE_META
+                        :end-word                   'END_WORD
+                        :insert                     'INSERT
+                        :repeat-search-next         'REPEAT_SEARCH_NEXT
+                        :paste-next                 'PASTE_NEXT
+                        :replace-char               'REPLACE_CHAR
+                        :substitute-char            'SUBSTITUTE_CHAR
+                        :to-next-char               'TO_NEXT_CHAR
+                        :undo                       'UNDO
+                        :next-word                  'NEXT_WORD
+                        :delete-next-char           'DELETE_NEXT_CHAR
+                        :change-case                'CHANGE_CASE
+                        :complete                   'COMPLETE
+                        :exit                       'EXIT
+                        :paste                      'PASTE
+                        :start-of-history           'START_OF_HISTORY
+                        :end-of-history             'END_OF_HISTORY
+                        :clear-line                 'CLEAR_LINE })
+
+
+(def jline-command-map-ids (loop [i 4000
+                                  m (keys jline-command-map)
+                                  r {}]
+                             (if (empty? m)
+                               r
+                               (let [key (first m)
+                                     val (jline-command-map key)]
+                                 (recur (+ i 1) (rest m)  (assoc r  key i ))))))
+
+(def my-bindings (loop [m (keys jline-command-map)
+                        r ""]
+                        (if (empty? m)
+                          r
+                          (let [key (first m)
+                                val (jline-command-map key)
+                                i (jline-command-map-ids key)]
+                            (recur (rest m) (str r "\n" i " : " val) )))))
+
+(defn jline-init []
+  (let [cbb (CircularByteBuffer.)
+        output-stream (.getOutputStream cbb)
+        data-output-stream (DataOutputStream. output-stream)
+        input-stream (.getInputStream cbb)
+        print-stream (java.io.PrintStream. output-stream true  "UTF-32")
+
+        reader (BufferedReader. (InputStreamReader. input-stream "UTF-32"))
+
+        terminal (proxy [Terminal] []
+                   (isANSISupported [] true)
+                   (initializeTerminal [] )
+                   (getTerminalWidth [] 80)
+                   (getTerminalHeight [] 25)
+                   (isSupported [] true)
+                   (getEcho [] false)
+                   (isEchoEnabled [] false)
+                   (enableEcho [])
+                   (getDefaultBindings [] (-> my-bindings
+                                              .getBytes
+                                              java.io.ByteArrayInputStream.))
+                   (readCharacter [in]
+                                  (let [c (.read reader)]
+                                    c))
+                   (readVirtualKey [in]
+                                   (let [c (.readCharacter this in)]
+                                     c))
+                   (disableEcho []))
+
+        print-writer (proxy [PrintWriter] [(System/out)]
+                       (write [c]
+                              (comment (proxy-super write c))
+                              (if (isa? (type c) Integer)
+                                (let [bb (java.nio.ByteBuffer/allocate 4)
+                                      dec  (.newDecoder (Charset/forName "UTF-32"))]
+                                  (.putInt bb c)
+                                  (.flip bb)
+                                  (let [cb (.decode dec bb)]
+                                    (event ::jline-print :c (str (.get cb  0)))))))
+                       (flush []
+                              (comment (proxy-super flush))
+                              (event ::jline-flush)))
+
+        console-reader (ConsoleReader. input-stream print-writer nil terminal)
+
+        cursor-buffer (.getCursorBuffer console-reader)
+
+        running (ref false)
+
+        read-loop (future (event ::jline-read-loop-init)
+                          (dosync (ref-set running true))
+                          (loop []
+                            (let [line (.readLine console-reader)]
+                              (event ::jline-readline :text (.toString cursor-buffer))
+                              (if (not (nil? line))
+                                (recur))))
+                          (event ::jline-read-loop-exit)
+                          (dosync (ref-set running false))
+                          (future (.close cbb))
+                          (future (.close input-stream))
+                          (future (.close output-stream)))
+
+        old-cursor-buf    (ref {:pos 0, :text ""})
+        ]
+
+    (on ::jline-write-int #(.writeInt data-output-stream (:val %)))
+
+    (on ::jline-command #(.writeInt data-output-stream (jline-command-map-ids (:id %))))
+
+    (on ::jline-exit  #((event ::jline-command :id :newline)
+                        (event ::jline-command :id :exit)))
+
+    (on ::jline-write #(.print print-stream (:text %)))
+
+    (on ::jline-ping #(if (= @running true) (event ::jline-pong)))
+
+    (on ::jline-flush #(let [pos (.cursor cursor-buffer)
+                             text (.toString cursor-buffer)
+                             old-pos (:pos @old-cursor-buf)
+                             old-text (:text @old-cursor-buf)]
+
+                         (if (not (= pos old-pos))
+                           (event ::jline-update-pos :pos pos))
+
+                         (if (not (= text old-text))
+                           (event ::jline-update-text :text text))
+
+                         (dosync (ref-set old-cursor-buf {:pos pos :text text}))))))
+
+(defn jline-running? []
+     (let [p (promise)]
+       (on ::jline-pong #(deliver p true))
+       (event ::jline-ping)
+       (try
+        (.get (future @p) 300 TimeUnit/MILLISECONDS)
+        (catch TimeoutException t
+          false))))
+
+(defmacro EDT
+  "runs body on the Event-Dispatch-Thread (Swing)"
+  [& body]
+
+  `(SwingUtilities/invokeLater (fn [] ~@body)))
+
+(def keystroke-modifiers-map {:none  0
+                              :shift java.awt.event.InputEvent/SHIFT_MASK
+                              :ctrl java.awt.event.InputEvent/CTRL_MASK
+                              :meta java.awt.event.InputEvent/META_MASK
+                              :alt java.awt.event.InputEvent/ALT_MASK})
+
+(defn add-keystroke! [editorpane stroke mods performed-fn]
+  (let [stroke-key (eval `(. java.awt.event.KeyEvent ~stroke))]
+    (doto (.getKeymap editorpane)
+      (.addActionForKeyStroke
+       (javax.swing.KeyStroke/getKeyStroke stroke-key (if (vector? mods)
+                                                        (apply + (map #(keystroke-modifiers-map %) mods))
+                                                        (keystroke-modifiers-map mods)))
+       (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt] (performed-fn)))))))
+
+
+(defn set-default-keymap-action! [editorpane performed-fn]
+  (.setDefaultAction (.getKeymap editorpane) (proxy [javax.swing.Action] []
+                                               (isEnabled [] true)
+                                               (getValue [k])
+                                               (actionPerformed [e]
+                                                                (performed-fn e)))))
+
+(comment
+(EDT
+ (def fr (javax.swing.JFrame.))
+
+ (def edit (javax.swing.JEditorPane.))
+ (.setEditable edit false)
+ (.add fr edit)
+ (.pack fr)
+
+ (.show fr))
+
+(defn dcls [] (let [doc (.getDocument edit)
+                    len (.getLength doc)]
+                (EDT (.remove doc 0 len))))
+
+(defn dprint [text] (let [doc (.getDocument edit)
+                          len (.getLength doc)]
+
+
+                     (EDT (.insertString doc len text nil))))
+
+(on ::jline-read-loop-init #(println "inited"))
+(on ::jline-read-loop-exit #(println "exited"))
+(clear-handlers ::jline-print)
+
+(clear-handlers ::jline-update-pos)
+
+(on ::jline-update-pos #(do
+                          (println (str "carret: " (:pos %)))
+                          (EDT
+                           (let [doc (.getDocument edit)
+                                 len (.getLength doc)
+                                 pos (:pos %)]
+                             (if (< pos len)
+                               (.setCaretPosition edit pos))))))
+
+(clear-handlers ::jline-update-text)
+
+(on ::jline-print #(EDT
+                    (let [doc (.getDocument edit)
+                          len (.getLength doc)
+                          i (int (.charAt (:c %) 0))
+                          pos (.getCaretPosition edit)]
+
+                      (if (= 127 i)
+                        (.remove doc (- pos 1) 1)
+                        (.insertString doc (.getCaretPosition edit) (str (:c %)) nil)))))
+
+(do
+  (event ::jline-exit)
+  (Thread/sleep 1000)
+  (jline-init)
+  (dcls))
+
+
+(do
+  (dcls)
+  (event ::jline-command :id :newline)
+  (.removeBindings (.getKeymap edit))
+
+  (set-default-keymap-action! edit (fn [e] (let [content (str (.getActionCommand e))
+                                                 c (.charAt content 0)
+                                                 i (int c)]
+
+                                             (cond (= 8 i)     (event ::jline-command :id :backspace)
+                                                   (= 127 i)   (event ::jline-command :id :delete-prev-char))
+
+                                             (if (>= i 0x20)
+                                               (if (not (= i 127))
+                                                 (event ::jline-write :text (str c)))))))
+
+  (add-keystroke! edit 'VK_DELETE :none #(event ::jline-command :id :delete-next-char))
+  (add-keystroke! edit 'VK_LEFT :none #(event ::jline-command :id :prev-char))
+  (add-keystroke! edit 'VK_HOME :none #(event ::jline-command :id :move-to-beg))
+  (add-keystroke! edit 'VK_END :none #(event ::jline-command :id :move-to-end))
+  (add-keystroke! edit 'VK_ENTER :none #(event ::jline-command :id :newline))
+  nil)
+
+)
+
+
+(comment

 ;; GUI part

@@ -140,52 +425,74 @@
     (fn [pair] (-> pair set (filter string) count (mod 2) zero?))
     pairs)))

-(defn repl []
-  (let [group (sg-group)
-        history (javax.swing.JEditorPane.)
-        input (javax.swing.JEditorPane.)
-        scroll (JScrollPane. history)
-
-        println-history #(EDT (let [ doc (.getDocument history)
-                                    length (.getLength doc)]
-                                (.insertString doc length % nil)))]
-
-    (EDT (.setEditable input false)
-         (.setEditable history false)
-         (.setVerticalScrollBarPolicy scroll (JScrollPane/VERTICAL_SCROLLBAR_ALWAYS))
-         (.setHorizontalScrollBarPolicy scroll (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER)))
-
-    (doto group
-      (add! (sg-component scroll 500 300))
-      (add! (translate 0 305 (sg-component input 500 25))))
-
-    (doto (.getKeymap input)
-      (.addActionForKeyStroke
-       (javax.swing.KeyStroke/getKeyStroke (java.awt.event.KeyEvent/VK_ENTER) 0)
-       (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt]  (let [text (.getText input)]
-                                                                        (if (and (not (empty? text))
-                                                                                (balanced? text))
-                                                                          (do (event ::repl-write :text text)
-                                                                              (EDT
-                                                                               (.setText input "")
-                                                                               (.requestFocus input)))))))))
-
-    (on ::repl-print #(println-history (:text %) ))
-
-    (on ::repl-ready #((println-history "repl ready\r\n")
-                       (event ::repl-write :text "(in-ns 'user)\r\n(use 'overtone.live)")
-                       (EDT (.setEditable input true))))
-
-    (on ::repl-exited #((println-history "repl exited\r\n")
-                        (EDT (.setEditable input false))))
-
-    (if (repl-thread-running?)
-      (do (EDT (.setEditable input true))
-          (println-history "repl thread allready running\r\n"))
-      (start-repl-thread))
+(do
+ (defn repl []
+   (let [group (sg-group)
+         history (javax.swing.JEditorPane.)
+         input (javax.swing.JEditorPane.)
+         scroll (JScrollPane. history)
+
+         println-history #(EDT (let [ doc (.getDocument history)
+                                     length (.getLength doc)]
+                                 (.insertString doc length % nil)))
+
+         bb (CircularByteBuffer.)
+         ps (java.io.PrintStream. (.getOutputStream bb) true)
+         cr (ConsoleReader. (.getInputStream bb) (PrintWriter. (System/out)))
+         ]
+
+     (EDT (.setEditable input false)
+          (.setEditable history false)
+          (.setVerticalScrollBarPolicy scroll (JScrollPane/VERTICAL_SCROLLBAR_ALWAYS))
+          (.setHorizontalScrollBarPolicy scroll (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER)))
+
+     (doto group
+       (add! (sg-component scroll 500 300))
+       (add! (translate 0 305 (sg-component input 500 25))))
+
+     (doto (.getKeymap input)
+       (.addActionForKeyStroke
+        (javax.swing.KeyStroke/getKeyStroke (java.awt.event.KeyEvent/VK_ENTER) 0)
+        (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt]  (let [text (.getText input)]
+                                                                         (if (and (not (empty? text))
+                                                                                (balanced? text))
+                                                                           (do (event ::repl-write :text text)
+                                                                               (EDT
+                                                                                (.setText input "")
+                                                                                (.requestFocus input)))))))))
+
+
+
+     (on ::repl-print #(println-history (:text %) ))
+
+     (on ::repl-ready #((println-history "repl ready\r\n")
+                        (event ::repl-write :text "(in-ns 'user)\r\n(use 'overtone.live)")
+                        (EDT (.setEditable input true))))
+
+     (on ::repl-exited #((println-history "repl exited\r\n")
+                         (EDT (.setEditable input false))))
+
+     (if (repl-thread-running?)
+       (do (EDT (.setEditable input true))
+           (println-history "repl thread allready running\r\n"))
+       (start-repl-thread))

-    group))
-
-
-;(defn repl-panel []
-;  (let [panel (sg-panel)]))
+     group))
+
+
+ (defn repl-panel []
+   (let [panel (sg-panel)]
+
+     (set-scene! panel (repl))
+
+     panel))
+
+ (sg-window (repl-panel))
+
+ )
+
+)
+ (comment
+
+   )
+


enable transparency for shapes

enable transparency for shapes

--- src/play_clj/entities.clj
+++ src/play_clj/entities.clj
@@ -1,6 +1,6 @@
 (ns play-clj.entities
   (:import [com.badlogic.gdx Gdx Graphics]
-           [com.badlogic.gdx.graphics Camera Color]
+           [com.badlogic.gdx.graphics Camera Color GL20]
            [com.badlogic.gdx.graphics.g2d Batch NinePatch ParticleEffect
             TextureRegion]
            [com.badlogic.gdx.graphics.g3d Environment ModelBatch ModelInstance]
@@ -102,6 +102,8 @@
     (when camera
       (.setProjectionMatrix object (. camera combined)))
     (.begin object type)
+    (.glEnable Gdx/gl GL20/GL_BLEND)
+    (.glBlendFunc Gdx/gl GL20/GL_SRC_ALPHA GL20/GL_ONE_MINUS_SRC_ALPHA)
     (when (or x y scale-x scale-y angle)
       (let [x (float (or x 0))
             y (float (or y 0))


Convert to vector literal

Convert to vector literal

--- src/single_track/core.clj
+++ src/single_track/core.clj
@@ -29,7 +29,7 @@
   [FieldKey/ALBUM FieldKey/ARTIST FieldKey/TITLE FieldKey/TRACK FieldKey/ALBUM_ARTIST FieldKey/GENRE FieldKey/YEAR])

 (defn tag-val [tag tagname]
-  (vector (->kebab-case-keyword (.name tagname)) (.getFirst tag tagname)))
+  [(->kebab-case-keyword (.name tagname)) (.getFirst tag tagname)])

 (defn audio-tags [audiofile]
   (when-let [tag (.getTag audiofile)]


That's path->thing not thing->path

That's path->thing not thing->path

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -86,7 +86,7 @@

 (defn ensure-thing [maybe-thing]
   (cond (string? maybe-thing)
-        ,,(thing->path maybe-thing)
+        ,,(path->thing maybe-thing)

         (map? maybe-thing)
         ,,maybe-thing


Document write-docs-for-var

Document write-docs-for-var

--- src/grimoire/doc.clj
+++ src/grimoire/doc.clj
@@ -128,7 +128,9 @@
             (str "Don't know how to stringify " x)))))

 (defn write-docs-for-var
-
+  "General case of writing documentation for a Var instance with
+  metadata. Compute a \"docs\" structure from the var's metadata and then punt
+  off to write-meta which does the heavy lifting."
   [config var]
   (let [docs (-> (meta var)
                  (assoc  :src  (var->src var)


Fix footer link to correct team page

Fix footer link to correct team page

--- src-cljs/frontend/components/footer.cljs
+++ src-cljs/frontend/components/footer.cljs
@@ -9,7 +9,7 @@
      [:ul.list-unstyled
       [:li.header "CircleCI"]
       [:li [:a {:href "/about"} "About Us"]]
-      [:li [:a {:href "/about"} "Team"]]
+      [:li [:a {:href "/about/team"} "Team"]]
       [:li [:a {:href "/press"} "Press"]]
       (when-not (config/enterprise?)
         [:li [:a {:href "/jobs"} "Jobs"]])


Add the ability to select shapes.

Add the ability to select shapes.

--- frontend/uxbox/ui/workspace/canvas.cljs
+++ frontend/uxbox/ui/workspace/canvas.cljs
@@ -8,6 +8,7 @@
             [uxbox.shapes :as shapes]
             [uxbox.library.icons :as _icons]
             [uxbox.data.projects :as dp]
+            [uxbox.data.workspace :as dw]
             [uxbox.ui.mixins :as mx]
             [uxbox.ui.dom :as dom]
             [uxbox.ui.util :as util]
@@ -49,25 +50,21 @@
    :stroke "gray"})

 (defn- shape-render
-  [own {:keys [x y] :as shape}]
-  (let [local (:rum/local own)]
+  [own {:keys [id x y width height] :as shape}]
+  (let [local (:rum/local own)
+        selected (rum/react wb/selected-state)]
     (html
      [:g {
           :on-mouse-down
           (fn [event]
-            (println "mouse-down")
+            (swap! local assoc :init-coords [x y])
             (rx/push! wb/selected-shape-b shape))

-          ;; :on-mouse-move
-          ;; (fn [event]
-          ;;   (when (:drop @local)
-          ;;     (println "mouse-move" @wb/mouse-position2)
-          ;;     (let [target (.-currentTarget event)
-          ;;           [nx ny] @wb/mouse-position2
-          ;;           svg (aget (.-childNodes target) 0)]
-          ;;       (.setAttribute svg "x" nx)
-          ;;       (.setAttribute svg "y" ny)))
-          ;;   false)
+          :on-click
+          (fn [ev]
+            (when (= (:init-coords @local) [x y])
+              (rs/emit! (dw/select-shape id))
+              (println "click")))

           :on-mouse-up
           (fn [event]
@@ -75,7 +72,21 @@
             (rx/push! wb/selected-shape-b :nothing)
             (dom/stop-propagation event))
           }
-      (shapes/render shape)])))
+      (shapes/render shape)
+      (if (contains? selected id)
+        [:g {:class "controls"}
+         [:rect {:x x :y y :width width :height height
+                 :style {:stroke "black" :fill "transparent"
+                         :stroke-opacity "0.5"}}]
+         [:circle (merge default-selection-props
+                         {:cx x :cy y})]
+         [:circle (merge default-selection-props
+                         {:cx (+ x width) :cy y})]
+         [:circle (merge default-selection-props
+                         {:cx x :cy (+ y height)})]
+         [:circle (merge default-selection-props
+                         {:cx (+ x width) :cy (+ y height)})]])])))
+

 ;; (defn- shape-render
 ;;   [own shape]
@@ -104,7 +115,7 @@
   (util/component
    {:render shape-render
     :name "shape"
-    :mixins [mx/static (mx/local {})]}))
+    :mixins [mx/static rum/reactive (mx/local {})]}))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Canvas


Remove mk-sender-with-verified-bindings usage

--- src/yetibot/core/adapters/slack.clj
+++ src/yetibot/core/adapters/slack.clj
@@ -29,7 +29,6 @@
 (defonce ^{:dynamic true} *conn* (atom nil))
 (defonce ^{:dynamic true} *config* nil)

-
 (defonce hash-to-conn-and-config (atom {}))

 (defn self
@@ -62,8 +61,20 @@
 ;; send-msg and send-paste must bind *config* and *conn* themselves if it is
 ;; missing, as in the case of API calls. this is getting pretty ridiculous.

-(defn mk-sender-with-verified-bindings [f]
-  (fn [msg]
+;; this results in: "No matching ctor found for class ;; yetibot.core.adapters.slack$mk_sender_with_verified_bindings$fn__14051"
+; (defn mk-sender-with-verified-bindings [f]
+;   (fn [msg]
+;     (if (and *config* @*conn*)
+;       (f msg)
+;       (let [[conn config] (determine-conn-and-config-from-chat-source-hash)]
+;         (binding [*conn* conn
+;                   *config* config]
+;           (f msg))))))
+
+(defn send-msg [msg]
+  (let [f (fn [msg] (slack-chat/post-message
+                      (slack-config) *target* msg
+                      {:unfurl_media "true" :as_user "true"}))]
     (if (and *config* @*conn*)
       (f msg)
       (let [[conn config] (determine-conn-and-config-from-chat-source-hash)]
@@ -71,21 +82,18 @@
                   *config* config]
           (f msg))))))

-(def send-msg
-  (mk-sender-with-verified-bindings
-    (fn [msg]
-      (slack-chat/post-message (slack-config) *target* msg
-                               {:unfurl_media "true" :as_user "true"}))))
-
-(def send-paste
-  (mk-sender-with-verified-bindings
-    (fn [msg]
-      (slack-chat/post-message
-        (slack-config)
-        *target*
-        ""
-        {:unfurl_media "true" :as_user "true"
-         :attachments [{:pretext "" :text msg}]}))))
+(defn send-paste [msg]
+  (let [f (fn [msg]
+            (slack-chat/post-message
+              (slack-config) *target* ""
+              {:unfurl_media "true" :as_user "true"
+               :attachments [{:pretext "" :text msg}]}))]
+    (if (and *config* @*conn*)
+      (f msg)
+      (let [[conn config] (determine-conn-and-config-from-chat-source-hash)]
+        (binding [*conn* conn
+                  *config* config]
+          (f msg))))))

 (def messaging-fns
   {:msg send-msg


Added tests for short names.

Added tests for short names.

--- test/com/lemonodor/gflags_test.clj
+++ test/com/lemonodor/gflags_test.clj
@@ -5,13 +5,25 @@

 (deftest string-test
-  (testing "string flag"
+  (testing "string long name"
+    (binding [gflags/*flags* (gflags/make-flag-values)]
+      (gflags/define-string "filename"
+        "default-filename"
+        "The input filename")
+      (let [args ["argv0" "--filename" "foo" "arg1"]
+            unparsed-args (gflags/parse-flags args)]
+        (is (= unparsed-args ["arg1"]))
+        (let [flags (gflags/flags)]
+          (is (contains? flags :filename))
+          (is (not (contains? flags :unknown-flag)))
+          (is (= (flags :filename) "foo"))))))
+  (testing "string short name"
     (binding [gflags/*flags* (gflags/make-flag-values)]
       (gflags/define-string "filename"
         "default-filename"
         "The input filename"
         :short-name "f")
-      (let [args ["argv0" "--filename" "foo" "arg1"]
+      (let [args ["argv0" "-f" "foo" "arg1"]
             unparsed-args (gflags/parse-flags args)]
         (is (= unparsed-args ["arg1"]))
         (let [flags (gflags/flags)]


(PDB-3723) Adjust ["fact", "foo"] style node queries for jsonb

[rlb@puppet.com: adjust message]

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -384,216 +384,85 @@

 (def facts-query
   "Query structured facts."
-  (if @scf-store/enable-json-facts
-    (map->Query {:projections {"certname" {:type :string
-                                           :queryable? true
-                                           :field :fs.certname}
-                               "environment" {:type :string
-                                              :queryable? true
-                                              :field :env.environment}
-                               "name" {:type :string
-                                       :queryable? true
-                                       :field :fs.key}
-                               "value" {:type :jsonb-scalar
-                                        :queryable? true
-                                        :field :fs.value}}
-                 :selection {:from [[(hcore/raw
-                                      (str "(select certname,"
-                                           "        environment_id,"
-                                           "        (jsonb_each((stable||volatile))).*"
-                                           "   from factsets)"))
-                                     :fs]]
-                             :left-join [[:environments :env]
-                                         [:= :fs.environment_id :env.id]]}
-
-                 :relationships (merge certname-relations
-                                       {"environments" {:local-columns ["environment"]
-                                                        :foreign-columns ["name"]}
-                                        "fact_contents" {:columns ["certname" "name"]}})
-
-                 :alias "facts"
-                 :source-table "factsets"
-                 :entity :facts
-                 :subquery? false})
-    (map->Query {:projections {"path" {:type :string
-                                       :queryable? false
-                                       :query-only? true
-                                       :field :fp.path}
-                               "value" {:type :multi
-                                        :queryable? true
-                                        :field :fv.value}
-                               "depth" {:type :integer
-                                        :queryable? false
-                                        :query-only? true
-                                        :field :fp.depth}
-                               "certname" {:type :string
-                                           :queryable? true
-                                           :field :fs.certname}
-                               "environment" {:type :string
-                                              :queryable? true
-                                              :field :env.environment}
-                               "value_integer" {:type :integer
-                                                :query-only? true
-                                                :queryable? false
-                                                :field :fv.value_integer}
-                               "value_float" {:type :float
-                                              :query-only? true
-                                              :queryable? false
-                                              :field :fv.value_float}
-                               "value_string" {:type :string
-                                               :query-only? true
-                                               :queryable? false
-                                               :field :fv.value_string}
-                               "value_boolean" {:type :boolean
-                                                :query-only? true
-                                                :queryable? false
-                                                :field :fv.value_boolean}
-                               "name" {:type :string
-                                       :queryable? true
-                                       :field :fp.name}
-                               "type" {:type  :string
-                                       :query-only? true
-                                       :queryable? false
-                                       :field :vt.type}}
-
-                 :selection {:from [[:factsets :fs]]
-                             :join [[:facts :f]
-                                    [:= :fs.id :f.factset_id]
-
-                                    [:fact_values :fv]
-                                    [:= :f.fact_value_id :fv.id]
-
-                                    [:fact_paths :fp]
-                                    [:= :f.fact_path_id :fp.id]
-
-                                    [:value_types :vt]
-                                    [:= :vt.id :fv.value_type_id]]
-                             :left-join [[:environments :env]
-                                         [:= :fs.environment_id :env.id]]
-                             :where [:= :fp.depth 0]}
-
-                 :relationships (merge certname-relations
-                                       {"environments" {:local-columns ["environment"]
-                                                        :foreign-columns ["name"]}
-                                        "fact_contents" {:columns ["certname" "name"]}})
-
-                 :alias "facts"
-                 :source-table "facts"
-                 :entity :facts
-                 :subquery? false})))
+  (map->Query {:projections {"certname" {:type :string
+                                         :queryable? true
+                                         :field :fs.certname}
+                             "environment" {:type :string
+                                            :queryable? true
+                                            :field :env.environment}
+                             "name" {:type :string
+                                     :queryable? true
+                                     :field :fs.key}
+                             "value" {:type :jsonb-scalar
+                                      :queryable? true
+                                      :field :fs.value}}
+               :selection {:from [[(hcore/raw
+                                    (str "(select certname,"
+                                         "        environment_id,"
+                                         "        (jsonb_each((stable||volatile))).*"
+                                         "  from factsets)"))
+                                   :fs]]
+                           :left-join [[:environments :env]
+                                       [:= :fs.environment_id :env.id]]}
+
+               :relationships (merge certname-relations
+                                     {"environments" {:local-columns ["environment"]
+                                                      :foreign-columns ["name"]}
+                                      "fact_contents" {:columns ["certname" "name"]}})
+
+               :alias "facts"
+               :source-table "factsets"
+               :entity :facts
+               :subquery? false}))

 (def fact-contents-query
   "Query for fact nodes"
-  (if @scf-store/enable-json-facts
-    (map->Query {:projections {"certname" {:type :string
-                                           :queryable? true
-                                           :field :fs.certname}
-                               "environment" {:type :string
-                                              :queryable? true
-                                              :field :env.environment}
-                               "path" {:type :path
-                                       :queryable? true
-                                       :field :fs.path}
-                               "name" {:type :string
-                                       :queryable? true
-                                       :field :fs.name}
-                               "value" {:type :jsonb-scalar
-                                        :queryable? true
-                                        :field :value}}
-                 :selection {:from [[(hcore/raw
-                                      (str "(select certname,"
-                                           "        jsonb_extract_path(stable||volatile,"
-                                           "                           variadic path_array)"
-                                           "          as value,"
-                                           "        path,"
-                                           "        name,"
-                                           "        environment_id"
-                                           "   from factsets"
-                                           "     cross join (select distinct on (path)"
-                                           "                        path,"
-                                           "                        path_array,"
-                                           "                        name"
-                                           "                   from fact_paths) distinct_paths"
-                                           "   where jsonb_extract_path(stable||volatile,"
-                                           "                            variadic path_array)"
-                                           "           is not null"
-                                           "         and jsonb_typeof(jsonb_extract_path(stable||volatile,
-                                                                                variadic path_array))"
-                                           "               <> 'object')"))
-                                     :fs]]
-                             :left-join [[:environments :env]
-                                         [:= :fs.environment_id :env.id]]}
-
-                 :relationships (merge certname-relations
-                                       {"facts" {:columns ["certname" "name"]}
-                                        "environments" {:local-columns ["environment"]
-                                                        :foreign-columns ["name"]}})
-
-                 :alias "fact_nodes"
-                 :source-table "factsets"
-                 :subquery? false})
-
-    (map->Query {:projections {"path" {:type :path
-                                       :queryable? true
-                                       :field :fp.path}
-                               "value" {:type :multi
-                                        :queryable? true
-                                        :field :fv.value}
-                               "certname" {:type :string
-                                           :queryable? true
-                                           :field :fs.certname}
-                               "name" {:type :string
-                                       :queryable? true
-                                       :field :fp.name}
-                               "environment" {:type :string
-                                              :queryable? true
-                                              :field :env.environment}
-                               "value_integer" {:type :integer
-                                                :queryable? false
-                                                :field :fv.value_integer
-                                                :query-only? true}
-                               "value_float" {:type :float
-                                              :queryable? false
-                                              :field :fv.value_float
-                                              :query-only? true}
-                               "value_string" {:type :string
-                                               :query-only? true
-                                               :queryable? false
-                                               :field :fv.value_string}
-                               "value_boolean" {:type :boolean
-                                                :query-only? true
-                                                :queryable? false
-                                                :field :fv.value_boolean}
-                               "type" {:type :string
-                                       :queryable? false
-                                       :field :vt.type
-                                       :query-only? true}}
-
-
-                 :selection {:from [[:factsets :fs]]
-                             :join [[:facts :f]
-                                    [:= :fs.id :f.factset_id]
-
-                                    [:fact_values :fv]
-                                    [:= :f.fact_value_id :fv.id]
-
-                                    [:fact_paths :fp]
-                                    [:= :f.fact_path_id :fp.id]
-
-                                    [:value_types :vt]
-                                    [:= :fv.value_type_id :vt.id]]
-                             :left-join [[:environments :env]
-                                         [:= :fs.environment_id :env.id]]
-                             :where [:!= :vt.id 5]}
-
-                 :relationships (merge certname-relations
-                                       {"facts" {:columns ["certname" "name"]}
-                                        "environments" {:local-columns ["environment"]
-                                                        :foreign-columns ["name"]}})
-
-                 :alias "fact_nodes"
-                 :source-table "facts"
-                 :subquery? false})))
+  (map->Query {:projections {"certname" {:type :string
+                                         :queryable? true
+                                         :field :fs.certname}
+                             "environment" {:type :string
+                                            :queryable? true
+                                            :field :env.environment}
+                             "path" {:type :path
+                                     :queryable? true
+                                     :field :fs.path}
+                             "name" {:type :string
+                                     :queryable? true
+                                     :field :fs.name}
+                             "value" {:type :jsonb-scalar
+                                      :queryable? true
+                                      :field :value}}
+               :selection {:from [[(hcore/raw
+                                    (str "(select certname,"
+                                         "        jsonb_extract_path(stable||volatile,"
+                                         "                           variadic path_array)"
+                                         "          as value,"
+                                         "        path,"
+                                         "        name,"
+                                         "        environment_id"
+                                         "   from factsets"
+                                         "     cross join (select distinct on (path)"
+                                         "                        path,"
+                                         "                        path_array,"
+                                         "                        name from fact_paths) distinct_paths"
+                                         "   where jsonb_extract_path(stable||volatile,"
+                                         "                            variadic path_array)"
+                                         "           is not null"
+                                         "         and jsonb_typeof(jsonb_extract_path(stable||volatile,"
+                                         "                                             variadic path_array))"
+                                         "               <> 'object')"))
+                                   :fs]]
+                           :left-join [[:environments :env]
+                                       [:= :fs.environment_id :env.id]]}
+
+               :relationships (merge certname-relations
+                                     {"facts" {:columns ["certname" "name"]}
+                                      "environments" {:local-columns ["environment"]
+                                                      :foreign-columns ["name"]}})
+
+               :alias "fact_nodes"
+               :source-table "factsets"
+               :subquery? false}))

 (def report-logs-query
   "Query intended to be used by the `/reports/<hash>/logs` endpoint
@@ -1583,7 +1452,7 @@
   (cm/match [node]

             [[(op :guard (classic-facts-pred #{"=" "<" ">" "<=" ">="})) "value" (value :guard #(number? %))]]
-            ["or" [op "value_integer" value] [op "value_float" value]]
+            [op "value" value] ;; TODO add coercion support here

             [[(op :guard (classic-facts-pred #{"="})) "value"
               (value :guard #(or (string? %) (ks/boolean? %)))]]
@@ -1627,47 +1496,34 @@

             [[(op :guard #{"=" "~"}) ["fact" fact-name]
               (fact-value :guard #(or (string? %) (instance? Boolean %)))]]
-            (let [value-column (if (string? fact-value) "value_string" "value_boolean")]
               ["in" "certname"
                ["extract" "certname"
                 ["select_facts"
                  ["and"
                   ["=" "name" fact-name]
-                  [op value-column fact-value]]]]])
-
-            [["in" ["fact" fact-name] ["array" fact-values]]]
-            (let [clause (cond
-                           (every? string? fact-values)
-                           ["in" "value_string" ["array" fact-values]]
-
-                           (every? ks/boolean? fact-values)
-                           ["in" "value_boolean" ["array" fact-values]]
-
-                           (every? number? fact-values)
-                           ["or"
-                            ["in" "value_float" ["array" fact-values]]
-                            ["in" "value_integer" ["array" fact-values]]]
-
-                           :else (throw (IllegalArgumentException.
-                                         (tru "All values in 'array' must be the same type."))))]
-              ["in" "certname"
-               ["extract" "certname"
-                ["select_facts"
-                 ["and"
-                  ["=" "name" fact-name]
-                  clause]]]])
-
-            [[(op :guard #{"=" ">" "<" "<=" ">="}) ["fact" fact-name] fact-value]]
-            (if-not (number? fact-value)
-              (throw (IllegalArgumentException. (tru "Operator ''{0}'' not allowed on value ''{1}''" op fact-value)))
-              ["in" "certname"
-               ["extract" "certname"
-                ["select_facts"
-                 ["and"
-                  ["=" "name" fact-name]
-                  ["or"
-                   [op "value_float" fact-value]
-                   [op "value_integer" fact-value]]]]]])
+                  [op "value" fact-value]]]]]
+
+              [["in" ["fact" fact-name] ["array" fact-values]]]
+              (if-not (= (count (map type fact-values)) 1)
+                (throw (IllegalArgumentException.
+                         (tru "All values in 'array' must be the same type.")))
+                ["in" "certname"
+                 ["extract" "certname"
+                  ["select_facts"
+                   ["and"
+                    ["=" "name" fact-name]
+                    ["in" "value" ["array" fact-values]]]]]])
+
+              [[(op :guard #{"=" ">" "<" "<=" ">="}) ["fact" fact-name] fact-value]]
+              (if-not (number? fact-value)
+                (throw (IllegalArgumentException.
+                         (tru "Operator ''{0}'' not allowed on value ''{1}''" op fact-value)))
+                ["in" "certname"
+                 ["extract" "certname"
+                  ["select_facts"
+                   ["and"
+                    ["=" "name" fact-name]
+                    [op "value" fact-value]]]]])

             [["subquery" sub-entity expr]]
             (let [relationships (get-in (meta node) [:query-context :relationships sub-entity])]


Heed MBQL '98 warnings :warning:

Heed MBQL '98 warnings :warning:

--- test/metabase/permissions_test.clj
+++ test/metabase/permissions_test.clj
@@ -347,12 +347,13 @@
 (defn- expensive-venues-segment [segment-name table]
   (segment segment-name table (ql/query
                                 (ql/source-table (u/get-id table))
-                                (ql/filter (ql/= (u/get-id (field table :price)) "4")))))
+                                (ql/filter (ql/= (ql/field-id (u/get-id (field table :price)))
+                                                 4)))))

 (defn- todays-users-segment [segment-name table]
   (segment segment-name table (ql/query
                                 (ql/source-table (u/get-id table))
-                                (ql/filter (ql/= (u/get-id (field table :last_login))
+                                (ql/filter (ql/= (ql/field-id (u/get-id (field table :last_login)))
                                                  (ql/relative-datetime :current))))))

 (defn- with-segments [f]
@@ -521,7 +522,7 @@
   (not= ((test-users/user->client username) :get (str "card/" (u/get-id card)))
         "You don't have permissions to do that."))

-;; make API calls for all 8 at once since loading the test data is slow, etc.
+;; admin can fetch all 8 cards
 (expect-with-test-data true  (GET-card-id :crowberto *card:db1-count-of-venues*))
 (expect-with-test-data true  (GET-card-id :crowberto *card:db1-count-of-users*))
 (expect-with-test-data true  (GET-card-id :crowberto *card:db1-count-of-checkins*))
@@ -531,6 +532,7 @@
 (expect-with-test-data true  (GET-card-id :crowberto *card:db2-count-of-checkins*))
 (expect-with-test-data true  (GET-card-id :crowberto *card:db2-sql-count-of-users*))

+;; regular user can only fetch Cards for DB 1
 (expect-with-test-data true  (GET-card-id :rasta *card:db1-count-of-venues*))
 (expect-with-test-data true  (GET-card-id :rasta *card:db1-count-of-users*))
 (expect-with-test-data true  (GET-card-id :rasta *card:db1-count-of-checkins*))
@@ -540,6 +542,7 @@
 (expect-with-test-data false (GET-card-id :rasta *card:db2-count-of-checkins*))
 (expect-with-test-data false (GET-card-id :rasta *card:db2-sql-count-of-users*))

+;; ops user can fetch DB 1 cards of DB 2 Venues cards
 (expect-with-test-data true  (GET-card-id :lucky *card:db1-count-of-venues*))
 (expect-with-test-data true  (GET-card-id :lucky *card:db1-count-of-users*))
 (expect-with-test-data true  (GET-card-id :lucky *card:db1-count-of-checkins*))


Simple capture of figwheel output

Simple capture of figwheel output

--- src/lein_ui/core.clj
+++ src/lein_ui/core.clj
@@ -159,11 +159,12 @@

 (defn figwheel-process [project]
-  (println "starting figwheel thread")
-  {:thread (.start
-            (Thread. (bound-fn []
-                       (println "starting figwheel")
-                       (figwheel/figwheel project))))})
+  (let [out-writer (java.io.StringWriter.)]
+    {:thread (.start
+              (Thread. (bound-fn []
+                         (binding [*out* out-writer]
+                           (figwheel/figwheel project)))))
+     :out-writer out-writer}))

 (defn start-figwheel! [name]
   (let [project (get-project* "lein-ui")]


Add origin-url to email SQS message so it can construct update links.

--- src/open_company/lib/email.clj
+++ src/open_company/lib/email.clj
@@ -10,9 +10,10 @@
    :note schema/Str
    :reply-to (schema/maybe schema/Str)
    :company-slug schema/Str
-   :snapshot {schema/Keyword schema/Any}})
+   :snapshot {schema/Keyword schema/Any}
+   :origin-url schema/Str})

-(defn ctx->trigger [post-data {company :company user :user su :stakeholder-update}]
+(defn ctx->trigger [post-data {company :company user :user su :stakeholder-update :as ctx}]
   {:pre [
     (sequential? (:to post-data))
     (string? (:subject post-data))
@@ -25,7 +26,8 @@
    :note (:note post-data)
    :reply-to (:email user)
    :company-slug (:slug company)
-   :snapshot su})
+   :snapshot su
+   :origin-url (get-in ctx [:request :headers "origin"])})

 (defn send-trigger! [trigger]
   (timbre/info "Request to send msg to " c/aws-sqs-email-queue "\n" (dissoc trigger :snapshot))


Don't draw actor entities twice

Don't draw actor entities twice

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -492,13 +492,14 @@
   (let [^Batch batch (.getBatch renderer)]
     (.begin batch)
     (doseq [{:keys [additive? opacity] :as entity} entities]
-      (when additive?
-        (.setBlendFunction ^Batch batch (gl :gl-src-alpha) (gl :gl-one)))
-      (.setColor batch (color 1 1 1 (or opacity 1.0)))
-      (e/draw! entity screen batch)
-      (.setColor batch (color 1 1 1 1))
-      (when additive?
-        (.setBlendFunction ^Batch batch (gl :gl-src-alpha) (gl :gl-one-minus-src-alpha))))
+      (when-not (instance? Actor (u/get-obj entity :object))
+        (when additive?
+          (.setBlendFunction ^Batch batch (gl :gl-src-alpha) (gl :gl-one)))
+        (.setColor batch (color 1 1 1 (or opacity 1.0)))
+        (e/draw! entity screen batch)
+        (.setColor batch (color 1 1 1 1))
+        (when additive?
+          (.setBlendFunction ^Batch batch (gl :gl-src-alpha) (gl :gl-one-minus-src-alpha)))))
     (.end batch))
   entities)


remove medium conversation format, add base-clustering to small

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -42,8 +42,7 @@
                           :pca-iters 10
                           :base-iters 10
                           :base-k 50
-                          :group-iters 10
-                          :group-k 3}
+                          :group-iters 10}
                     opts))
    :rating-mat  (plmb/fnk [conv votes]
                   (update-nmat (:rating-mat conv)
@@ -61,51 +60,39 @@
               (wrapped-pca mat (:n-comps opts')
                            :start-vectors (get-in conv [:pca :comps])
                            :iters (:pca-iters opts')))
-     :group-clusters
-            (plmb/fnk [conv rating-mat mat opts']
-              (kmeans (assoc rating-mat :matrix mat)
-                (:group-k opts')
-                :last-clusters (:group-clusters conv)
-                :cluster-iters (:group-iters opts')))
      :proj  (plmb/fnk [mat pca]
-              (pca-project mat pca))
-     :repness
-            (plmb/fnk [rating-mat group-clusters]
-              (if (> (count group-clusters) 1)
-                (conv-repness rating-mat group-clusters)))}))
-
-
-(def med-conv-update-graph
-  "For computing small conversation updates (those with need of base clustering)"
-  (merge small-conv-update-graph
-    {:base-clusters
-            (plmb/fnk [conv rating-mat mat opts']
-              (kmeans (assoc rating-mat :matrix mat)
+                      (pca-project mat pca))
+
+   :base-clusters
+          (plmb/fnk [conv rating-mat proj opts']
+           (sort-by :id
+            (kmeans (assoc rating-mat :matrix proj)
                 (:base-k opts')
                 :last-clusters (:base-clusters conv)
-                :cluster-iters (:base-iters opts')))
-     :proj  (plmb/fnk [base-clusters pca]
-              (pca-project (map :center base-clusters) pca))
-     :group-clusters
+                :cluster-iters (:base-iters opts'))))
+
+    :group-clusters
         (plmb/fnk [conv rating-mat base-clusters opts']
-          (kmeans (xy-clusters-to-nmat2 base-clusters) (:group-k opts')
-                :last-clusters (:group-clusters conv)
-                :cluster-iters (:group-iters opts'))
-      )}))
-
-
-
-(def med-conv-update-graph2
-  "For computing small conversation updates (those with need of base clustering). This
-  differs from the primary med update graph in that the pca projection happens before the
-  base clustering."
-  (merge med-conv-update-graph
-    {:proj  (plmb/fnk [mat pca]
-              (pca-project mat pca))
-     :base-clusters
-            (plmb/fnk [conv rating-mat proj opts' :as args]
-              ; slick code reusability
-              ((med-conv-update-graph :base-clusters) (assoc args :mat proj)))}))
+          (sort-by :id
+          (kmeans
+            (xy-clusters-to-nmat2 base-clusters)
+            (choose-group-k base-clusters)
+            :last-clusters (:group-clusters conv)
+            :cluster-iters (:group-iters opts'))))
+
+     :repness
+          (plmb/fnk [rating-mat group-clusters base-clusters]
+            (sort-by :id
+             (if (> (count group-clusters) 1)
+               (conv-repness
+                rating-mat
+                group-clusters
+                base-clusters))))
+
+   :bid-to-pid
+           (plmb/fnk [base-clusters]
+             (map :members(sort-by :id (:base-clusters base-clusters))))
+     }))

 (defn partial-pca
@@ -134,7 +121,7 @@

 (def large-conv-update-graph
-  (merge med-conv-update-graph2
+  (merge small-conv-update-graph
     {:pca (plmb/fnk [conv mat opts']
             (let [n-ptpts (matrix/dimension-count mat 0)
                   sample-size (sample-size n-ptpts)]
@@ -146,8 +133,6 @@

 (def small-conv-update (graph/eager-compile small-conv-update-graph))
-(def med-conv-update (graph/eager-compile med-conv-update-graph))
-(def med-conv-update2 (graph/eager-compile med-conv-update-graph2))
 (def large-conv-update (graph/eager-compile large-conv-update-graph))

@@ -158,10 +143,8 @@
         n-ptpts (count (distinct (into ptpts (map :pid votes))))]
     ; dispatch to the appropriate function
     ((cond
-;       (< n-ptpts 100)   small-conv-update
-;       (< n-ptpts 1000)  med-conv-update
-      (< n-ptpts 1500)  med-conv-update2
-       :else             large-conv-update)
+       (> n-ptpts 1500)   large-conv-update
+       :else             small-conv-update)
           {:conv conv :votes votes :opts opts})))

@@ -243,8 +226,7 @@
                           :pca-iters 10
                           :base-iters 10
                           :base-k 50
-                          :group-iters 10
-                          :group-k 3}
+                          :group-iters 10}
                     opts))
    :rating-mat  (plmb/fnk [conv votes]
                   (update-nmat (:rating-mat conv)


drawing from state

drawing from state

--- src/nonaga/draw.cljs
+++ src/nonaga/draw.cljs
@@ -37,11 +37,15 @@

 (def board
   (create-class
-    "render" (fn []
+    "getInitialState"
+    (fn [] n/initial-game)
+    "render"
+    (fn []
+      (this-as this
                (svg {}
-                    (draw ring (:rings n/initial-game))
-                    (draw (partial marble "red") (:whites n/initial-game))
-                    (draw (partial marble "blue") (:blacks n/initial-game))))))
+                 (draw ring (:rings (.-state this)))
+                 (draw (partial marble "red") (:whites (.-state this)))
+                 (draw (partial marble "blue") (:blacks (.-state this))))))))

 (defn start []
   (render-component (board) (sel1 :#content)))


filter does not have page

filter does not have page

--- src/ontrail/core.clj
+++ src/ontrail/core.clj
@@ -98,7 +98,7 @@
   (GET "/rest/v1/ex-list-all/:page" {params :params cookies :cookies}
        (json-response (get-latest-ex-list-default-order (user-from-cookie cookies) {} (get-page params))))

-  (GET "/rest/v1/ex-list-filter/:page" {params :params cookies :cookies}
+  (GET "/rest/v1/ex-list-filter" {params :params cookies :cookies}
        (json-response (get-latest-ex-list (user-from-cookie cookies) (monger-filter-from params) (get-page params) {:creationDate -1})))

   (GET "/rest/v1/ex-list-user/:user/:page" {params :params cookies :cookies}


Add predicate to Trigger schema.

Add predicate to Trigger schema.

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -280,6 +280,7 @@
    :trigger/sync s/Keyword
    (s/optional-key :trigger/fire-all-extents?) s/Bool
    (s/optional-key :trigger/doc) s/Str
+   (s/optional-key :trigger/pred) s/Keyword
    (s/optional-key :trigger/period) [(s/one PosInt "trigger period")
                                      (s/one TriggerPeriod "threshold type")]
    (s/optional-key :trigger/threshold) [(s/one PosInt "number elements")


Multigoomba and visualization layout fixes

--- src/player/core.cljs
+++ src/player/core.cljs
@@ -332,8 +332,8 @@
              :right                                         ;name
              {:x speed}                                     ;flows
              ;edges
-             ; x + 16 < 64 --> x < 64 - 16 && x + 16 + dx*frame >= 64 --> x >= 48 - dx*frame
-             (make-edge :left [[:lt :x 48] [:geq :x '(- 48 [:d :x])]] #{:required})
+             ; x + 16 < 96 --> x < 96 - 16 && x + 16 + dx*frame >= 80 --> x >= 80 - dx*frame
+             (make-edge :left [[:lt :x 80] [:geq :x '(- 80 [:d :x])]] #{:required})
              ; x + 16 < x2 && x + dx*frame + 16 >= x2 + dx2*frame
              ; x - x2 < -16 && x - x2 >= dx2*frame - dx*frame - 16
              (map #(make-edge :left [[:lt :x [% :x] -16]
@@ -351,7 +351,10 @@
                                       [:leq :x [% :x] (list '+ [:d % :x] 16 (list '- [:d :x]))]]
                               #{:required}) others))))

-(defn make-scene-a [x] (let [objects [(goomba :a x 8 8 :right #{:b}) (goomba :b (+ x 18) 8 8 :left #{:a})]
+(defn make-scene-a [x] (let [objects [(goomba :ga x 8 16 :right #{:gb :gc :gd})
+                                      (goomba :gb (+ x 18) 8 16 :left #{:ga :gc :gd})
+                                      (goomba :gc (+ x 38) 8 16 :right #{:ga :gb :gd})
+                                      (goomba :gd (+ x 58) 8 16 :left #{:ga :gb :gc})]
                              obj-ids (map :id objects)
                              obj-dict (zipmap obj-ids objects)
                              ; got to let every HA enter its current (initial) state to set up state invariants like
@@ -437,9 +440,9 @@
                                   [:div {:style {:height   trans-h :width (.abs js/Math (- sx ex))
                                                  :top      line-top :left (.min js/Math sx ex)
                                                  :position :absolute :backgroundColor "grey"}}
-                                   [:div {:style {:position :absolute :top "64px" :width "200px"}} (str (:id ha) "-" (:target (:transition trans)))]
-                                   [:div {:style {:height "100%" :width (* scale 2) :position :absolute :left (if (< sx ex) "0%" "100%") :backgroundColor "green"}}]
-                                   [:div {:style {:height "100%" :width (* scale 2) :position :absolute :left (if (< sx ex) "100%" "0%") :backgroundColor "red"}}]]))
+                                   [:div {:style {:position :absolute :width "100px" :backgroundColor "rgba(255,255,255,0.5)"}} (str (:id ha) "-" (:target (:transition trans)))]
+                                   [:div {:style {:height "100%" :width "2px" :position :absolute :left (if (< sx ex) "0%" "100%") :backgroundColor "green"}}]
+                                   [:div {:style {:height "100%" :width "2px" :position :absolute :left (if (< sx ex) "100%" "0%") :backgroundColor "red"}}]]))
                               (transition-intervals (:objects @scene)
                                                     ha
                                                     Infinity