Add skeleton of github-pull-request form.

--- src/cljs/hatnik/web/client/form/github_pull_request.cljs
+++ src/cljs/hatnik/web/client/form/github_pull_request.cljs
@@ -6,11 +6,76 @@
             [schema.core :as s])
   (:use [clojure.string :only [split replace]]))

+(defn github-issue-on-change [gh-repo timer form-handler form-status-handler error-handler]
+  (js/clearTimeout timer)
+
+  (let [pr (split gh-repo "/")
+        user (first pr)
+        repo (second pr)]
+    (form-handler
+     (if (or (nil? repo)
+             (nil? user)
+             (= "" user)
+             (= "" repo))
+       (do
+         (form-status-handler "has-warning")
+         nil)

+       (js/setTimeout
+        (fn []
+          (action/get-github-repos
+           user
+           (fn [reply]
+             (let [rest (js->clj reply)
+                   result (->> rest
+                               (map #(get % "name"))
+                               (filter #(= % repo)))]
+               (if (first result)
+                 (form-status-handler "has-success")
+                 (form-status-handler "has-error"))))
+           error-handler))
+        1000)))))

 (defn github-pull-request-component [data owner]
   (reify
-    om/IRender
-    (render [this]
+    om/IInitState
+    (init-state [this]
+      {})
+
+    om/IRenderState
+    (render-state [this state]
       (dom/div nil
-               "Github pull request"))))
+               (dom/div #js {:className (str "form-group " (:form-status state))}
+                        (dom/label nil "GitHub repository")
+                        (dom/input #js {:type "text"
+                                        :className "form-control"
+                                        :value (:value (:repo data))
+                                        :placeholder "user/repository or organization/repository"
+
+                                        :onChange
+                                        #(github-issue-on-change
+                                          (.. % -target -value)
+                                          (:timer state)
+                                          (fn [t]
+                                            ((:handler (:repo data)) (.. % -target -value))
+                                            (om/set-state! owner :timer t))
+                                          (fn [st] (om/set-state! owner :form-status st))
+                                          (fn [st] (om/set-state! owner :form-status "has-error")))
+                                        }))
+
+               (dom/div #js {:className "form-group"}
+                        (dom/label nil "Title")
+                        (dom/input #js {:type "text"
+                                        :className "form-control"}))
+
+               (dom/div #js {:className "form-group"}
+                        (dom/label nil "Body")
+                        (dom/textarea #js {:cols "40"
+                                               :className "form-control"}))
+
+               (dom/div #js {:className "form-group"}
+                        (dom/label nil "Commit message")
+                        (dom/textarea #js {:cols "40"
+                                               :className "form-control"}))
+
+               (dom/div nil "Operations")))))


DM + CW #139 - refactor draft template

DM + CW #139 - refactor draft template

--- src/objective8/front_end/templates/draft.clj
+++ src/objective8/front_end/templates/draft.clj
@@ -112,19 +112,22 @@
                                         [:.clj-comment-history-link] (html/set-attr :href comment-history-link)
                                         [:.clj-comment-create] (html/content (pf/comment-create context :draft)))))))

-(defn draft-page [{:keys [translations data doc] :as context}]
+(defn render-draft-page [{:keys [translations data doc] :as context}]
   (let [objective (:objective data)]
-    (apply str
-           (html/emit*
-             (tf/translate context
-                           (pf/add-google-analytics
-                             (html/at draft-template
-                                      [:title] (html/content (:title doc))
-                                      [(and (html/has :meta) (html/attr= :name "description"))] (html/set-attr "content" (:description doc))
-                                      [:.clj-masthead-signed-out] (html/substitute (pf/masthead context))
-                                      [:.clj-status-bar] (html/substitute (pf/status-flash-bar context))
+    (html/at draft-template
+             [:title] (html/content (:title doc))
+             [(and (html/has :meta) (html/attr= :name "description"))] (html/set-attr "content" (:description doc))
+             [:.clj-masthead-signed-out] (html/substitute (pf/masthead context))
+             [:.clj-status-bar] (html/substitute (pf/status-flash-bar context))

-                                      [:.clj-guidance-buttons] nil
-                                      [:.clj-guidance-heading] (html/content (translations :draft-guidance/heading))
+             [:.clj-guidance-buttons] nil
+             [:.clj-guidance-heading] (html/content (translations :draft-guidance/heading))

-                                      [:.clj-draft-wrapper] (html/substitute (draft-wrapper context)))))))))
+             [:.clj-draft-wrapper] (html/substitute (draft-wrapper context)))))
+
+(defn draft-page [context]
+  (->> (render-draft-page context)
+       pf/add-google-analytics
+       (tf/translate context)
+       html/emit*
+       (apply str)))


dual 3d canvas model

dual 3d canvas model


retry 5 times on open subtitles calls

retry 5 times on open subtitles calls


Removing unused reaget-utils namespace

Removing unused reaget-utils namespace

--- src/common/relevance/reagent_utils.cljs
+++ src/common/relevance/reagent_utils.cljs
@@ -1,6 +0,0 @@
-(ns relevance.reagent-utils
-  (:require [reagent.core :as reagent]))
-
-(def initial-focus-wrapper
-  (with-meta identity
-             {:component-did-mount #(.focus (reagent/dom-node %))}))


function for updating data with schema change

--- server/src/gratefulplace/db/manage.clj
+++ server/src/gratefulplace/db/manage.clj
@@ -113,4 +113,12 @@
 (defn reload
   []
   (delete)
-  (migrate))+  (migrate))
+
+(defn pref-update-transactions
+  []
+  (map
+   (fn [ent]
+     {:db/id (:db/id ent)
+      :user/preferences ["receive-watch-notifications"]})
+   (db/all [:user/receive-watch-notifications true])))


CMR-3369: Removed unneeded channel.

CMR-3369: Removed unneeded channel.

--- bootstrap-app/src/cmr/bootstrap/system.clj
+++ bootstrap-app/src/cmr/bootstrap/system.clj
@@ -78,9 +78,6 @@
              ;; Channel for processing collections to index.
              :collection-index-channel (chan 100)

-             ;; Channel for requesting full acl indexing.
-             :acl-index-channel (chan 10)
-
              ;; Channel for processing data newer than a given date-time.
              :data-index-channel (chan 10)


Moved lots of stuff from static to preprocess.


Still trying to get client side routing to work


refactor new loop

refactor new loop


add with-ppe macro for more pretty backtraces

--- clj-backtrace/src/clj_backtrace/repl.clj
+++ clj-backtrace/src/clj_backtrace/repl.clj
@@ -52,3 +52,11 @@
     (print-trace (:trace-elems exec) source-width)
     (if-let [cause (:cause exec)]
       (ppe-cause cause source-width))))
+
+(defmacro with-ppe
+  "Wrap code in a guard that will print pretty stack traces instead of default
+  Java traces on exceptions"
+  [& body]
+  `(try
+     ~@body
+     (catch Exception e# (ppe e#))))


CMR-6288: Install jruby before gems.

CMR-6288: Install jruby before gems.

--- orbits-lib/project.clj
+++ orbits-lib/project.clj
@@ -51,7 +51,7 @@
                             ~jruby-version
                             ~dev-gem-install-path]
             "clean-gems" ["shell" "rm" "-rf" ~dev-gem-install-path]
-            "install" ["do" "clean-gems," "install-gems," "install," "clean"]
+            "install" ["do" "clean," "deps," "clean-gems," "install-gems," "install"]
             "install!" "install"
             ;; Alias to test2junit for consistency with lein-test-out
             "test-out" ["test2junit"]


parallel display limited to paradigms

parallel display limited to paradigms

--- src/clj/webapp/routes/multipdgmmod.clj
+++ src/clj/webapp/routes/multipdgmmod.clj
@@ -226,7 +226,7 @@
             [:p "valclusters: " [:pre pdgms]]
             [:p "headerset2: " [:pre headerset2]]
             [:p "pdgmstr2: " [:pre pdgmstr2]]
-            [:p "==========================="]]
+            [:h4 "==========================="]]
            [:h3 "Parallel Display of Paradigms (Personal Pronoun and Finite Verb Only)"]
            [:p "At present only accommodates parallel display of paradigms with columns 'Number Person Gender Token' -- to be generalized."]
            [:hr]
@@ -284,7 +284,7 @@
       "goog.require('webapp.core');"])))

 (defn pstring2map2
-  "Takes pivot property out of comma-separated properties in pdgm string, and arranges the rest as a set of {:property-list 'token'} maps"
+  "Used in handle-multimodplldisplay4. Takes pivot property out of comma-separated properties in pdgm string, and arranges the rest as a set of {:property-list 'token'} maps"
   [pdgm pivot]
   (let [pdgm1 (clojure.string/replace pdgm #"^\\r\\n.*?," "") ;; initial pivot out
         pdgm2 (clojure.string/replace pdgm1 #"(\\r\\n).*?," "$1") ;; other pivots out
@@ -299,24 +299,34 @@
     (clojure.walk/keywordize-keys pmap)
     ))

-(defn handle-multimodplldisplay3
+(defn pstring2map
+  "Used in handle-multimodplldisplay2. Takes out default pivot, pdgm; splits features from token and makes hash-map."
+  [pdgm]
+  (let [pdgm1a (clojure.string/replace pdgm #"^\\r\\n.*?," "") ;; initial line-feed & pdgm label out
+        pdgm1b (clojure.string/replace pdgm1a #"\\r\\n$" "") ;; final line-feed out
+        pdgmstring (clojure.string/replace pdgm1b #"\\r\\n.*?," "%%")
+        pdgmstr (clojure.string/replace pdgmstring #",([^,]*%%)" "&$1")
+        pdgmstr2 (clojure.string/replace pdgmstr #",([^,]*)$" "&$1")
+        pdgm2 (clojure.string/replace pdgmstr2 #"&" " ")
+        pdgm3  (clojure.string/replace pdgm2 #"%%" " ")
+        plist (split pdgm3 #" ")
+        pmap (apply hash-map plist)
+        ]
+    (clojure.walk/keywordize-keys pmap)
+    ))
+
+(defn handle-multimodplldisplay2
   "This version does not rely on external png file for sort order; keyset should be generalized beyond png to any sequence of cols between col-1 ('pivot', here limited to paradigms) and token column. Also need to 'presort' cols before initial display."
-  [pdgms headerset2 pdgmstr2 pivot]
-  (let [pnamestr (clojure.string/replace pdgms #"[\[\]\"]" "")
+  [pdgmnames headerset2 pdgmstr2]
+  (let [pnamestr (clojure.string/replace pdgmnames #"[\[\]\"]" "")
         pnames (split pnamestr #" ")
         pstrings (split pdgmstr2 #" ")
-        pmaps (for [pdgm pstrings] (pstring2map2 pdgm pivot))
+        pmaps (for [pdgm pstrings] (pstring2map pdgm))
         ;; headerset should be derived from pdgm query (=headerset2)
-        ;;diffset (clojure.set/difference (set pstringvec) (set pordervec))
-        pivotstr (str pivot "token")
-        pivotvec (split pivotstr #" ")
-        headervec (split headerset2 #" ")
-        rowheads (clojure.set/difference (set headervec) (set pivotvec))
         headerset (str "Number " "Person " "Gender ")
         heads (split headerset #" ")
         pdgmnums (into [] (take (clojure.core/count pnames) (iterate inc 1)))
         ;; There has to be an easier way to get to keyset!
-        ;; (keyset is the set of all value combinations in the combined pdgms)
         keylists (set (for [pmap pmaps] (keys pmap)))
         keystring (clojure.string/replace (str keylists) #"[#(){}]" "")
         keyvec (split keystring #" ")
@@ -326,14 +336,6 @@
      [:body
       [:h3 "Parallel Display of Paradigms:" ]
       [:p "Click on column to sort (multiple sort by holding down shift key). Columns can be dragged by clicking and holding on 'drag-bar' at top of column."]
-      [:p "headerset2: " [:pre headerset2]]
-      [:p "rowheads: " [:pre rowheads]]
-      [:p "pdgmstr2: " [:pre pdgmstr2]]
-      [:p "pmaps: " [:pre pmaps]]
-      [:p "pivot: " [:pre pivot]]
-      [:p "keylists: " [:pre keylists]]
-      [:p "keystring: " [:pre keystring]]
-      [:p "keyset: " [:pre keyset]]
      [:p "Paradigms:"
       [:ol
       (for [pname pnames]
@@ -343,8 +345,8 @@
          [:thead
           (for [head heads]
             [:th [:div {:class "some-handle"}] head])
-          (for [pnum pdgmnums]
-            [:th [:div {:class "some-handle"}] (str "P-" pnum)])]
+          (for [pdgmnum pdgmnums]
+            [:th [:div {:class "some-handle"}] (str "P-" pdgmnum)])]
        [:tbody
         (for [keys keyset]
           [:tr
@@ -355,11 +357,20 @@
                 (for [npg npgs]
                   [:td npg])
                 (for [pmap pmaps]
-               [:td (kstrkey pmap)])])])]
+               [:td (kstrkey pmap)])])])]]
+      [:div
+       [:h4 "======= Debug Info: ======="]
+       [:p "pdgmstr2: " [:pre pdgmstr2]]
+       [:p "pmaps: " [:pre pmaps]]
+       [:p "keylists: " [:pre keylists]]
+       [:p "keystring: " [:pre keystring]]
+       [:p "keyset: " [:pre keyset]]
+       [:h4 "======================="]]
       [:script {:src "js/goog/base.js" :type "text/javascript"}]
       [:script {:src "js/webapp.js" :type "text/javascript"}]
       [:script {:type "text/javascript"}
-       "goog.require('webapp.core');"]]])))
+       "goog.require('webapp.core');"]])))
+

 (defn cleanpdgms [pdgmstr]
   (let [
@@ -370,6 +381,7 @@
     (clojure.string/replace pdgmstr-c #"\r\n " "")))

 ;; from http://stackoverflow.com/questions/1394991
+
 (defn vec-remove
   "remove elem in coll"
    [coll pos]
@@ -389,7 +401,7 @@
 ;;(clojure.string/replace (join "," row) #"(.*),(.*?$)" "$1 $2"))

 (defn handle-multimodplldisplay4
-  "In this version pivot/keyset can be generalized beyond png any col (eventually any sequence of cols) between col-1 and token column. Need to find out hosw to 'presort' cols before initial display."
+  "In this version pivot/keyset can be generalized beyond png any col (eventually any sequence of cols) between col-1 and token column. (Need to find out how to 'presort' cols before initial display?)"
   [pdgms headerset2 pdgmstr2 pivotname]
   (let [pnamestr (clojure.string/replace pdgms #"[\[\]\"]" "")
         pnames (split pnamestr #" ")
@@ -474,4 +486,5 @@
   (GET "/multipdgmmod" [] (multipdgmmod))
   (POST "/multimodqry" [languages pos] (handle-multimodqry languages pos))
   (POST "/multimoddisplay" [valclusters pos] (handle-multimoddisplay valclusters pos))
-  (POST "/multimodplldisplay" [pdgmnames header pdgmstr2 pivot] (handle-multimodplldisplay4 pdgmnames header pdgmstr2 pivot)))
+  (POST "/multimodplldisplay" [pdgmnames header pdgmstr2] (handle-multimodplldisplay2 pdgmnames header pdgmstr2)))
+;;(POST "/multimodplldisplay" [pdgmnames header pdgmstr2 pivot] (handle-multimodplldisplay4 pdgmnames header pdgmstr2 pivot)))


evidences

evidences

--- src/cljs/salava/badge/ui/evidence.cljs
+++ src/cljs/salava/badge/ui/evidence.cljs
@@ -1,13 +1,18 @@
 (ns salava.badge.ui.evidence
   (:require [salava.core.ui.modal :as mo]
             [reagent.core :refer [cursor atom]]
-            [salava.core.i18n :refer [t]]
+            [salava.core.i18n :refer [t translate-text]]
             [reagent.session :as session]
             [salava.core.ui.helper :refer [plugin-fun path-for hyperlink base-url]]
             [salava.core.ui.ajax-utils :as ajax]
             [salava.core.time :refer [date-from-unix-time]]
-            [clojure.string :refer [blank? includes?]]
-            [salava.file.icons :refer [file-icon]]))
+            [clojure.string :refer [blank? includes? split trim]]
+            [salava.file.icons :refer [file-icon]]
+            [salava.file.ui.my :refer [send-file]]))
+
+(defn url? [s]
+  (when-not (blank? s)
+    (not (blank? (re-find #"^http" (str (trim s)))))))

 (defn input [input-data textarea?]
   (let [{:keys [name atom placeholder type error-message-atom rows cols]} input-data]
@@ -19,120 +24,213 @@
       :placeholder placeholder
       :on-change   #(do
                       (reset! atom (.-target.value %))
-                      (if error-message-atom(reset! error-message-atom (:message "")))
-                      )
+                      (if error-message-atom(reset! error-message-atom (:message ""))))
       :value       @atom
       :rows rows
       :cols cols}]))

-#_(defn input [input-data textarea?]
-   (let [{:keys [name atom placeholder type error-message-atom rows cols]} input-data
-         opt-map (merge input-data {:class "form-control"
-                                    :id (str "input-" name)
-                                    :value @atom
-                                    :on-change #(do
-                                                  (reset! atom (.-target.value %))
-                                                  (if error-message-atom(reset! error-message-atom (:message ""))))})]
-     [(if textarea? :textarea :input) opt-map]))
-
-
-(defn toggle-input-mode [key state url?]
-  (let [key-atom (cursor state [key])]
-    (do
-      (if url? (swap! state assoc :resource_input false) (swap! state assoc :url_input false))
-      (if @key-atom (swap! state assoc key false) (swap! state assoc key true) ))))
-
-(defn init-user-pages [resource-atom]
-  (ajax/GET
-    (path-for "/obpv1/page" true)
-    {:handler (fn [data]
-                (swap! resource-atom assoc :pages data)
-                )}))
-
-(defn init-user-files [resource-atom]
-  (ajax/GET
-    (path-for "/obpv1/file" true)
-    {:handler (fn [data]
-                (swap! resource-atom assoc :files data)
-                )}))
-
-(defn init-resources [resource-atom]
-  (do
-    (init-user-pages resource-atom)
-    (init-user-files resource-atom)))
-
-(defn toggle-selected [resource coll]
-  (if (contains? @coll resource)
-    (reset! coll (disj @coll resource))
-    (swap! coll conj resource)))
-
-(defn resource-grid-element [element-data type coll]
+
+
+(defn toggle-input-mode [key state]
+  (let [key-atom (cursor state [:input_mode])]
+    (if (= key @key-atom) (reset! key-atom nil) (do (reset! key-atom nil) (reset! key-atom key)))))
+
+
+(defn init-resources [key resource-atom]
+  (let [url (case key
+              :page_input "/obpv1/page"
+              :file_input "/obpv1/file")]
+    (ajax/GET
+      (path-for url true)
+      {:handler (fn [data]
+                  (reset! resource-atom data)
+                  )})))
+
+
+(defn remove-url [url coll state]
+  (swap! state assoc-in [:evidence :urls] (remove #(= url %) @coll)))
+
+(defn grid-element [element-data state key]
   (let [{:keys [id name path visibility mtime badges ctime mime_type]} element-data
-        page-url (str (session/get :site-url) (path-for (str "/page/view/" id)))
-        checked? (if-not (blank? path)
-                   (boolean (some #(= path %) @coll))
-                   (boolean (some #(= page-url %) @coll) )) ]
-    [:div.checkbox
-     [:input {:id (str "input-" name)
-              :type "checkbox"
-              :on-change #(do (toggle-selected (.-target.value %) coll ))
-              :value (case type
-                       :page page-url
-                       :file path)
-              :checked checked?
-              }]
-     (case type
-       :page [:a {:href "#" :on-click #(do
-                                         (.preventDefault %)
-                                         (mo/open-modal [:page :view] {:page-id id}))} name]
-
-       :file [:div [:i {:style {:margin-right "10px"}
-                        :class (str "file-icon-large fa " (file-icon mime_type))}]
-              [:a {:href (str "/" path) :target "_blank"} name]])]))
-
-(defn selected-resources-block [selected-resources-atom]
-  (fn []
-    [:div
-     (reduce (fn [coll resource]
-               (conj coll [:p (hyperlink resource)])
-               ) [:div] @selected-resources-atom)
-     [:br]]))
+        value (case key
+                :page_input (str (session/get :site-url) (path-for (str "/page/view/" id)))
+                :file_input (str (session/get :site-url) "/" path)
+                nil)
+        evidence-url-atom (cursor state [:evidence :url])
+        show-url? (cursor state [:evidence :show_url])
+        resource-input-mode (cursor state [:input_mode])]
+    [:div.radio
+     [:label
+      [:input { :name "opt"
+                :type "radio"
+                :value value
+                :on-change #(do
+                              (reset! evidence-url-atom (.-target.value %))
+                              (reset! resource-input-mode nil)
+                              (reset! show-url? true))}]
+      (case key
+        :page_input [:a {:href "#" :on-click #(do
+                                                (.preventDefault %)
+                                                (mo/open-modal [:page :view] {:page-id id}))} name]
+
+        :file_input [:div [:i {:style {:margin-right "10px"}
+                               :class (str "file-icon-large fa " (file-icon mime_type))}]
+                     [:a {:href (str "/" path) :target "_blank"} name]])]]))
+
+
+

 (defn toggle-visible-area [visible-area-atom key]
   (if (= key @visible-area-atom) (reset! visible-area-atom nil) (reset! visible-area-atom key)))

-
-(defn resources-grid [state]
-  (let [resource-atom (atom {:pages [] :files [] :visible_area nil})
-        visible-area-atom (cursor state [:visible_area])
-        selected-resources-atom (atom #{})]
-    (init-resources resource-atom)
+(defn upload-status [status title message]
+  [:div
+   [:h4.modal-title (translate-text title)]
+   [:div (if status
+           [:div {:class (str "alert " (if (= status "error")
+                                         "alert-warning"
+                                         "alert-success"))}
+            (translate-text message)]
+           [:div
+            [:i {:class "fa fa-cog fa-spin fa-2x"}]
+            [:span " " (translate-text message)]])]
+   ])
+
+(defn upload-file [files-atom state]
+  (let [files (:files @files-atom)
+        file (-> (.querySelector js/document "input")
+                 .-files
+                 (.item 0))
+        form-data (doto
+                    (js/FormData.)
+                    (.append "file" file (.-name file)))]
+    (ajax/POST
+      (path-for "/obpv1/file/upload")
+      {:body    form-data
+       :response-format :json
+       :keywords?       true
+       :handler (fn [data]
+                  (if (= (:status data) "success")
+                    (swap! files-atom assoc :files (conj files (:data data))))
+                  (swap! state assoc :evidence {:message [upload-status (:status data) (:message data) (:reason data)]})
+                  )
+
+
+       :error-handler (fn [{:keys [status status-text]}]
+                        (swap! state assoc :evidence {:message [upload-status "error" (t :file/Errorwhileuploading) (t :file/Filetoobig)]})
+                        )})))
+
+
+(defn resources-grid [key resource-atom state]
+  (let [evidence-url-atom (cursor state [:evidence :url])
+        {:keys[files]} @resource-atom]
+    [:div.resource-upload
+     (if files
+       [:div.col-md-9 [:label
+                       [:span [:i.fa.fa-upload] (t :file/Upload) ]
+                       [:input {:id "grid-file-upload"
+                                :type "file"
+                                :name "file"
+                                :on-change #(upload-file resource-atom state)
+                                :style {:display "none"}}]
+                       ]])
+     [:div.col-md-9.resource-container
+      (reduce (fn [r resource]
+                (conj r [grid-element resource state key])
+                ) [:form] (if files files @resource-atom))
+      ]]))
+
+
+(defn init-evidence-form [evidence state show-url?]
+  (let [evidence { :id (:id evidence)
+                   :name (:name evidence)
+                   :url (:url evidence)
+                   :audience (:audience evidence)
+                   :narrative (:narrative evidence)
+                   :genre (:genre evidence)
+                   :description (:description evidence)
+                   }]
+    (if show-url?
+      (swap! state assoc :evidence (assoc evidence :show_url true
+                                     :input_mode nil) )
+      (swap! state assoc :evidence evidence))))
+
+(defn save-badge-evidence [data state init-data]
+  (let [{:keys [id name description audience genre url narrative]} (:evidence @state)
+        badge-id (:id data)
+        init-settings (first (plugin-fun (session/get :plugins) "modal" "show_settings_dialog"))]
+    (swap! state assoc :evidence {:message nil})
+    (if (blank? url)
+      (swap! state assoc :evidence {:message [:div.alert.alert-warning [:p "Resource field can't be empty!"]]})
+
+      (ajax/POST
+        (path-for (str "/obpv1/badge/evidence/" badge-id))
+        {:params {:id id
+                  :name (if name (trim name))
+                  :description description
+                  :audience (if audience (trim audience))
+                  :genre (if genre (trim genre))
+                  :url (if url (trim url))
+                  :narrative narrative}
+         :handler (fn [resp]
+                    (when (= "success" (:status resp))
+                      (init-data state (:id data) nil)
+                      #_(init-settings (:id data) state init-data "settings"))
+
+
+                    )}))))
+
+(defn selected-url [state init-data]
+  (let [evidence-url-atom (cursor state [:evidence :url])
+        show-url? (cursor state [:evidence :show_url])
+        evidence (cursor state [:evidence])]
     (fn []
-      (let [{:keys [pages files]} @resource-atom
-            files (:files files)]
-        [:div#badge-stats
-                   (when-not (empty? @selected-resources-atom)
-        [selected-resources-block selected-resources-atom])
-         [:div.panel
-          [:div.panel-heading
-           [:h3 [:a {:href "#" :on-click #(do (.preventDefault %) (toggle-visible-area visible-area-atom :pages))}(str (t :page/Pages) " : " (count pages))]]]
-          (if (= @visible-area-atom :pages)
-            (reduce (fn [r p]
-                      (conj r
-                            [resource-grid-element p :page selected-resources-atom])) [:div.panel-body] pages))
-          ]
-         [:div.panel
-          [:div.panel-heading
-           [:h3 [:a {:href "#" :on-click #(do (.preventDefault %) (toggle-visible-area visible-area-atom :files))} (str (t :page/Files) " : " (count files))]]]
-          (if (= @visible-area-atom :files)
-            (reduce (fn [r p]
-                      (conj r
-                            [resource-grid-element p :file selected-resources-atom])) [:div.panel-body] files)
-            )
-          ]]
-        )
-      )
-    ))
+      (when (and (not (empty? @evidence-url-atom )) @show-url?)
+        [:div.col-md-9
+
+
+         [:button.close {:type "button"
+                         :aria-label "OK"
+                         :on-click #(do
+                                      (.preventDefault %)
+                                      (reset! show-url? false)
+                                      (reset! evidence (assoc @evidence :url nil :show_url false
+                                                         ))
+                                      (init-evidence-form @evidence state false)
+                                      )
+                         }
+          [:span {:aria-hidden "true"
+                  :dangerouslySetInnerHTML {:__html "×"}}]]
+         [:div.selected-url (hyperlink (trim @evidence-url-atom))]]
+        ))))
+
+(defn resource-input [state]
+  (let [resource-input-mode (cursor state [:input_mode])
+        evidence-url-atom (cursor state [:evidence :url])
+        resource-atom (atom {})
+        show-url? (cursor state [:evidence :show_url])]
+    (fn []
+      [:div.form-group
+       [:div.col-md-9
+        (case @resource-input-mode
+          :file_input (do
+                        (init-resources :file_input resource-atom)
+                        [:div [resources-grid :file_input resource-atom state]])
+          :page_input (do
+                        (init-resources :page_input resource-atom)
+                        [:div [resources-grid :page_input resource-atom state]])
+          :url_input [:div
+                      [input {:name "evidence-url" :atom evidence-url-atom :type "url"}]
+                      [:button {:type "button"
+                                :class "btn btn-primary"
+                                :disabled (not (url? @evidence-url-atom))
+                                :on-click #(do
+                                             (.preventDefault %)
+                                             (reset! show-url? true)
+                                             (reset! resource-input-mode nil)
+                                             #_(swap! state assoc-in [:evidence :url] @evidence-url-atom))}
+                       "Add"]]
+          nil)]])))

 (defn evidence-form [data state init-data]
@@ -142,72 +240,172 @@
         evidence-audience-atom (cursor state [:evidence :audience])
         evidence-genre-atom (cursor state [:evidence :genre])
         evidence-url-atom (cursor state [:evidence :url])
-        url-input-enabled? (cursor state [:url_input])
-        resource-input-enabled? (cursor state [:resource_input])
+        evidence-narrative-atom (cursor state [:evidence :narrative])
+        page-input-enabled? (cursor state [:page_input])
+        message (cursor state [:evidence :message])
+        show-url? (cursor state [:evidence :show_url])
+        file-input-enabled? (cursor state [:file_input])
+        resource-input-mode (cursor state [:input_mode])
+        show-form (cursor state [:show_form])
         {:keys [image_file name]} data]
+
     [:div {:id "badge-settings" :class "row flip"}
      [:div {:class "col-md-3 badge-image modal-left"}
       [:img {:src (str "/" image_file) :alt name}]]
      [:div {:class "col-md-9 settings-content settings-tab"}
-      [:form.form-horizontal
-       [:div.form-group
-        [:label.col-md-3 "Name"]
-        [:div.col-md-9
-         [input {:name "name" :atom evidence-name-atom :placeholder "input a name" :type "text"} nil]]]
-       [:div.form-group
-        [:label.col-md-3 "Audience"]
-        [:div.col-md-9
-         [input {:name "audience" :atom evidence-audience-atom :placeholder "" :type "text"} nil]]]
-       [:div.form-group
-        [:label.col-md-3 "Genre"]
-        [:div.col-md-9
-         [input {:name "genre" :atom evidence-genre-atom :placeholder "" :type "text"} nil]]]
-
-       [:div.form-group
-        [:label.col-xs-12 (t :page/Description)]
-        [:div.col-xs-12
-         [input {:name "Description" :rows 5 :cols 40 :atom evidence-description-atom } true]]]
-
-       [:div.form-group.pages
-        [:label.col-xs-12 "Resource"]
-        [:div {:style {:margin "10px"}}
-         [:a {:style {:margin "10px"} :href "#"  :on-click #(toggle-input-mode :url_input state true)} [:i.fa.fa-link] (t :admin/Url)]
-         [:a {:href "#" :on-click #(do (toggle-input-mode :resource_input state nil)
-                                     #_(swap! state assoc :tab [resource-tab data state init-data])
-                                     ) } [:i.fa.fa-file] (t :page/File)]]
-
-        (if @url-input-enabled?
-          [:div.col-md-9
-           [input {:name "evidence-url" :atom evidence-url-atom :type "url"}]])
-        (if @resource-input-enabled?
-          [:div.col-md-9
-           [resources-grid state]
+      (if @message [:div @message])
+      [:div
+       [:div.form-horizontal
+        [:div.form-group
+         [:label.col-md-3 "Add evidence page"]
+         [:div.col-md-9 {:style {:margin-top "10px" :margin-bottom "10px"}}
+          ;[:div {:style {:float "left" :margin-right "10px"}} [:i.fa.fa-plus]]
+          [:div {:style {:float "left"}}
+           [:div {:style {:float "left" :margin-right "10px"}}[:a {:style {:margin "10px"} :href "#"  :on-click #(toggle-input-mode :url_input state)} [:i.fa.fa-link] (t :admin/Url)]]
+           [:div {:style {:float "left" :margin-right "10px"}} [:a {:href "#" :on-click #(do (toggle-input-mode :page_input state)
+                                                                                #_(swap! state assoc :tab [resource-tab data state init-data])
+                                                                                ) } [:i.fa.fa-file] (t :page/Mypages)]]
+           [:div {:style {:float "left"}} [:a {:href "#"
+                                               :on-click #(do
+                                                            (.preventDefault %)
+                                                            (toggle-input-mode :file_input state))
+                                               } [:i.fa.fa-file] (t :page/Files)]]]]
+
+         [selected-url state init-data]
+         [resource-input state]]
+
+        (if @show-form
+          [:div
+           [:div.form-group
+            [:label.col-md-3 "Name"]
+            [:div.col-md-9
+             [input {:name "name" :atom evidence-name-atom :placeholder "input a name" :type "text"} nil]]]
+           [:div.form-group
+            [:label.col-md-3 "Audience"]
+            [:div.col-md-9
+             [input {:name "audience" :atom evidence-audience-atom :placeholder "" :type "text"} nil]]]
+           [:div.form-group
+            [:label.col-md-3 "Genre"]
+            [:div.col-md-9
+             [input {:name "genre" :atom evidence-genre-atom :placeholder "" :type "text"} nil]]]
+
+           [:div.form-group
+            [:label.col-md-3 (t :page/Description)]
+            [:div.col-md-9
+             [input {:name "Description" :rows 5 :cols 40 :atom evidence-description-atom } true]]]
+
+           [:div.form-group
+            [:label.col-md-3 (t :badge/Narrative)]
+            [:div.col-md-9
+             [input {:name "Narrative" :rows 5 :cols 40 :atom evidence-narrative-atom } true]]]
            ]
-          )
-        ]
-
-       [:div
-        [:button {:type         "button"
-                  :class        "btn btn-primary"
-                  :on-click     #()}
-         (t :badge/Save)]
-        [:button {:type "button"
-                  :class "btn btn-primary"
-                  :on-click #(do (.preventDefault %) (swap! state assoc :tab [settings-tab data state init-data] :tab-no 2))}
-         (t :core/Cancel)]]
-       ]]]))
-
+          [:div
+           [:a {:href "#" :on-click #(do (.preventDefault %) (reset! show-form true))} "Add more info about this evidence"]])
+                   [:div
+            [:button {:type         "button"
+                      :class        "btn btn-primary"
+                      :on-click     #(save-badge-evidence data state init-data)}
+             (t :badge/Save)]
+            [:button {:type "button"
+                      :class "btn btn-primary"
+                      :on-click #(do (.preventDefault %) (swap! state assoc :tab [settings-tab (dissoc data :evidence) state init-data] :tab-no 2))}
+             (t :core/Cancel)]]]]]]))
+
+(defn delete-evidence! [id data state init-data]
+  (let [init-settings (first (plugin-fun (session/get :plugins) "modal" "show_settings_dialog"))]
+    (ajax/DELETE
+      (path-for (str "/obpv1/badge/evidence/" id))
+      { :params {:user_badge_id (:id data)}
+        :handler (fn [r]
+                   (if (= "success" (:status r))
+                     (init-settings (:id data) state init-data "settings")
+                     ;(swap! state assoc :tab [settings-tab data state init-data] :tab-no 2)
+                     )
+                   )}
+      )
+    ))
+
+#_(defn evidence-list [data state init-data]
+    (reduce (fn [r evidence]
+              (let [{:keys [genre description narrative name audience id url mtime ctime]} evidence]
+                (conj r
+                      [:div.col-md-9.evidence-block
+                       [:a {:href "#" :on-click #(do (.preventDefault %)
+                                                   (init-evidence-form evidence state true)
+                                                   (swap! state assoc :tab [evidence-form data #_(assoc data :evidence evidence) state init-data]))}
+                        [:div [:div {:style {:float "left"}} [:i.fa.fa-link]]  url]
+                        (if name [:div.inline [:label (t :badge/Name) ": "] name])
+                        (if narrative [:div [:label (t :badge/Narrative) ": "] narrative])
+                        (if description [:div [:label (t :admin/Description) ": "]  description])
+                        (if genre [:div [:label (t :badge/Genre) ": "] genre])
+                        (if audience [:div [:label (t :badge/Audience) ": "] audience])
+                        ]
+                       [:button {:type "button"
+                                 :aria-label "OK"
+                                 :class "close"
+                                 :on-click #(delete-evidence! id data state init-data)}
+                        [:span {:aria-hidden "true"
+                                :dangerouslySetInnerHTML {:__html "×"}}]]
+                       ])
+                )) [:div.evidence-list] (:evidences data)))
+
+(defn evidence-list [data state init-data]
+  (reduce (fn [r evidence]
+            (let [{:keys [genre description narrative name audience id url mtime ctime]} evidence]
+              (conj r
+                    [:div.panel.panel-default
+                     [:div.panel-heading {:id (str "heading" id)
+                                          :role "tab"}
+                      [:div.panel-title
+                       [:a {:href "#" :on-click #(do (.preventDefault %)
+                                                   (init-evidence-form evidence state true)
+                                                   (swap! state assoc :tab [evidence-form data state init-data] :show_form true))}
+                        [:div [:div {:style {:float "left"}} [:i.fa.fa-link]]  url]]
+                       (if (or genre description narrative name audience)
+                         [:div.show-more [:a {:role "button" :data-toggle "collapse"
+                          :data-parent "#accordion"
+                          :href (str "#collapse" id)
+                              :aria-expanded "true"
+                              :aria-controls (str "collapse" id)} "show more"]]
+                         )
+                       ]
+                                             [:div [:button {:type "button"
+                                 :aria-label "OK"
+                                 :class "close panel-close"
+                                 :on-click #(delete-evidence! id data state init-data)}
+                        [:span {:aria-hidden "true"
+                                :dangerouslySetInnerHTML {:__html "×"}}]]]
+                      ]
+                     (if (or genre description narrative name audience)
+                     [:div {:id (str "collapse" id)
+                            :class "panel-collapse collapse"
+                            :role "tabpanel"
+                            :aria-labelledby (str "heading" id)}
+                      [:div.panel-body
+                       (if name [:div.inline [:label (t :badge/Name) ": "] name])
+                        (if narrative [:div [:label (t :badge/Narrative) ": "] [:div narrative]])
+                        (if description [:div [:label (t :admin/Description) ": "]  [:div description]])
+                        (if genre [:div [:label (t :badge/Genre) ": "] genre])
+                        (if audience [:div [:label (t :badge/Audience) ": "] audience])
+                       ]])])
+              )
+            )[:div {:id "accordion" :class "panel-group evidence-list" :role "tablist" :aria-multiselectable "true"}] (:evidences data)))

 (defn evidence-block [data state init-data]
-  [:div
+  [:div#badge-settings
    [:div.form-group
     [:label {:class "col-md-12 sub-heading" :for "evidence"} (t :badge/Evidence)]

-    [:div.col-md-9
-     [:i.fa.fa-plus-square]
+
+    [:div.col-md-9 {:class "new-evidence"}
+     [:i.fa.fa-plus-square.fa-sm]
      [:a {:href "#" :on-click #(do (.preventDefault %)
-                                 (swap! state assoc :tab [evidence-form data state init-data] :tab-no 2))} "Add new evidence"]]
-    ]])
+                                 (swap! state assoc :evidence nil)
+                                 (swap! state assoc :tab [evidence-form data state init-data] :tab-no 2))} (t :badge/Addnewevidence)]]]
+
+   [:div.form-group
+    [:div.col-md-9 [evidence-list data state init-data]]]
+   ])

 (defn evidence-modal [state]
   (fn []


Use case instead of multi-method to derive action data

--- src/ctia/task/migration/migrations.clj
+++ src/ctia/task/migration/migrations.clj
@@ -183,39 +183,45 @@
               :targets (into (get m1 :targets)
                              (get m2 :targets))})))

-(defmulti derive-action-data
-  (fn [action]
-    (get action :type))
-  :default ::default)
-
-(defmethod derive-action-data ::default [_]
-  empty-action-data)
-
-(defmethod derive-action-data "collect" [action]
-  (let [investigated-observables (into #{}
-                                       (map (fn [{:keys [type value]}]
-                                              (str type ":" value)))
+(defn derive-collect-action-data
+  {:private true}
+  [action]
+  (let [investigated-observables (into #{} (map (fn [{:keys [type value]}]
+                                                  (str type ":" value)))
                                        (:result action))]
     (assoc empty-action-data :investigated_observables investigated-observables)))

-(defmethod derive-action-data "investigate" [action]
+(defn derive-investigate-action-data
+  {:private true}
+  [action]
   (let [data (get-in action [:result :data])]
-    (transduce
-     (comp (map :data)
-           (mapcat vals)
-           (mapcat :docs))
-     (fn
-       ([result] result)
-       ([result doc]
-        (let [result (if-some [object-id (object-id doc)]
-                       (update result :object_ids conj object-id)
-                       result)
-              result (update result :targets into (get doc :targets))]
-          result)))
-     {:object_ids #{}
-      :investigated_observables []
-      :targets #{}}
-     data)))
+    (transduce (comp (map :data)
+                     (mapcat vals)
+                     (mapcat :docs))
+               (fn
+                 ([result] result)
+                 ([result doc]
+                  (let [result (if-some [object-id (object-id doc)]
+                                 (update result :object_ids conj object-id)
+                                 result)
+                        result (update result :targets into (get doc :targets))]
+                    result)))
+               {:object_ids #{}
+                :investigated_observables []
+                :targets #{}}
+               data)))
+
+(defn derive-action-data [action]
+  (let [action-type (get action :type)]
+    (case action-type
+      "collect"
+      (derive-collect-action-data action)
+
+      "investigate"
+      (derive-investigate-action-data action)
+
+      ;; else
+      empty-action-data)))

 (defn migrate-action-data [investigation]
   (transduce (map derive-action-data)


simplify

simplify

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@8786 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -365,15 +365,14 @@
                            (Long/parseLong cam-chan-str)
                            0)
                 camera-channel-name (nth camera-channel-names cam-chan)
-                event (first (burst-seqs cam-chan))
-                event+ (-> event
+                event (-> (first (burst-seqs cam-chan))
                            (update-in [:channel-index] make-multicamera-channel cam-chan)
                            (update-in [:channel :name] super-channel-name camera-channel-name))]
             (when (zero? i)
               (swap! state assoc
                      :burst-time-offset (- (elapsed-time @state)
                                            (core-time-from-tags (image :tags)))))
-            (.put out-queue (make-TaggedImage (annotate-image image event+ @state
+            (.put out-queue (make-TaggedImage (annotate-image image event @state
                                                               (burst-time (:tags image) @state))))
             (recur (update-in burst-seqs [cam-chan] next) (inc i)))))))
   (burst-cleanup)) ;; burst is done!


remove redundant tag

remove redundant tag

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@6293 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -379,38 +379,38 @@
 (defn make-summary-metadata [settings]
   (let [depth (int (core getBytesPerPixel))
         channels (settings :channels)]
-     (JSONObject. {"Channels" (count (settings :channels))
-      "ChNames" (JSONArray. (map :name channels))
-      "ChColors" (JSONArray. (map #(.getRGB (:color %)) channels))
-      "ChContrastMax" (JSONArray. (repeat (count channels) Integer/MIN_VALUE))
-      "ChContrastMin" (JSONArray. (repeat (count channels) Integer/MAX_VALUE))
-      "Comment" (settings :comment)
-      "ComputerName" (.. InetAddress getLocalHost getHostName)
-      "Depth" (core getBytesPerPixel)
-      "Frames" (count (settings :frames))
-      "GridColumn" 0
-      "GridRow" 0
-      "Height" (core getImageHeight)
-      "Interval_ms" (settings :interval-ms)
-      "IntervalMs" (settings :interval-ms)
-      "IJType" (get-IJ-type depth)
-      "KeepShutterOpenChannels" (settings :keep-shutter-open-channels)
-      "KeepShutterOpenSlices" (settings :keep-shutter-open-slices)
-      "MetadataVersion" 10
-      "PixelAspect" 1.0
-      "PixelSize_um" (core getPixelSizeUm)
-      "PixelType" (get-pixel-type)
-      "Positions" (count (settings :positions))
-      "Prefix" (if (settings :save) (settings :prefix))
-      "Directory" (if (settings :save) (settings :root))
-      "Slices" (count (settings :slices))
-      "SlicesFirst" (settings :slices-first)
-      "Source" "Micro-Manager"
-      "TimeFirst" (settings :time-first)
-      "UserName" (System/getProperty "user.name")
-      "UUID" (UUID/randomUUID)
-      "Width" (core getImageWidth)
-      "z-step_um" (get-z-step-um (settings :slices))
+     (JSONObject. {
+			"Channels" (count (settings :channels))
+			"ChNames" (JSONArray. (map :name channels))
+			"ChColors" (JSONArray. (map #(.getRGB (:color %)) channels))
+			"ChContrastMax" (JSONArray. (repeat (count channels) Integer/MIN_VALUE))
+			"ChContrastMin" (JSONArray. (repeat (count channels) Integer/MAX_VALUE))
+			"Comment" (settings :comment)
+			"ComputerName" (.. InetAddress getLocalHost getHostName)
+			"Depth" (core getBytesPerPixel)
+			"Frames" (count (settings :frames))
+			"GridColumn" 0
+			"GridRow" 0
+			"Height" (core getImageHeight)
+			"Interval_ms" (settings :interval-ms)
+			"IJType" (get-IJ-type depth)
+			"KeepShutterOpenChannels" (settings :keep-shutter-open-channels)
+			"KeepShutterOpenSlices" (settings :keep-shutter-open-slices)
+			"MetadataVersion" 10
+			"PixelAspect" 1.0
+			"PixelSize_um" (core getPixelSizeUm)
+			"PixelType" (get-pixel-type)
+			"Positions" (count (settings :positions))
+			"Prefix" (if (settings :save) (settings :prefix))
+			"Directory" (if (settings :save) (settings :root))
+			"Slices" (count (settings :slices))
+			"SlicesFirst" (settings :slices-first)
+			"Source" "Micro-Manager"
+			"TimeFirst" (settings :time-first)
+			"UserName" (System/getProperty "user.name")
+			"UUID" (UUID/randomUUID)
+			"Width" (core getImageWidth)
+			"z-step_um" (get-z-step-um (settings :slices))
      })))

 (defn acquire-single [position-index]


fix typo

fix typo

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@6100 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -337,7 +337,6 @@
   [[] (atom {:running false :stop false})])

 (defn -run [this settings acq-eng]
-  (def latest-acq this)
   (load-mm)
   (create-device-agents)
 	(let [out-queue (GentleLinkedBlockingQueue.)
@@ -367,7 +366,10 @@

 (defn -isRunning [this]
   (:running @(.state this)))
-
+
+(defn -isPaused [this]
+  (:pause @(.state this)))
+
 (defn -stopHasBeenRequested [this]
   (:stop @(.state this)))


report an acquisition error

report an acquisition error

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@7789 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -33,6 +33,7 @@
            [org.micromanager.acquisition AcquisitionWrapperEngine LiveAcq TaggedImageQueue
                                          ProcessorStack SequenceSettings MMImageCache
                                          TaggedImageStorageRam VirtualAcquisitionDisplay]
+           [org.micromanager.utils ReportingUtils]
            [mmcorej TaggedImage Configuration Metadata]
            [java.util.prefs Preferences]
            [java.net InetAddress]
@@ -480,16 +481,19 @@
     (await-resume)))

 (defn run-acquisition [this settings out-queue]
-  (def acq-settings settings)
-  (prepare-state this)
-  (binding [state (.state this)]
-    (def last-state state) ; for debugging
-    (let [acq-seq (generate-acq-sequence settings @attached-runnables)]
-       (def acq-sequence acq-seq)
-      (execute (mapcat #(make-event-fns % out-queue) acq-seq))
-      (.put out-queue TaggedImageQueue/POISON)
-      (cleanup)
-     )))
+  (try
+    (def acq-settings settings)
+    (prepare-state this)
+    (binding [state (.state this)]
+      (def last-state state) ; for debugging
+      (let [acq-seq (generate-acq-sequence settings @attached-runnables)]
+        (def acq-sequence acq-seq)
+        (execute (mapcat #(make-event-fns % out-queue) acq-seq))
+        (.put out-queue TaggedImageQueue/POISON)
+        (cleanup)
+        ))
+    (catch Throwable t (do (ReportingUtils/showError t "Acquisition failed.")
+                           (cleanup)))))

 ;; generic metadata


add link for shopify stories page

add link for shopify stories page

--- frontend/components/landing_b.cljs
+++ frontend/components/landing_b.cljs
@@ -263,7 +263,7 @@
                       Continuous integration and delivery is revolutionizing the way development teams operate by reducing barriers between your ideas and your production code.
                       Remember, it doesn't count until it ships."]
                   [:p
-                   [:a.shopify-link
+                   [:a.shopify-link {:href "/stories/shopify"}
                     "See how Shopify does it"
                     (common/ico :slim-arrow-right)]]]]]
                [:section.home-practice


get range slider up and styled

get range slider up and styled

--- frontend/components/pricing-b.cljs
+++ frontend/components/pricing-b.cljs
@@ -42,7 +42,10 @@
             [:div.pricing-calculator-controls
              [:div.controls-containers
               [:h2 "Number of Containers"]
-              [:input {:type "range" :max "16"}]]
+              [:div.containers-range
+               [:figure.range-back]
+               [:figure.range-highlight]
+               [:figure.range-knob]]]
              [:div.controls-parallelism
               [:h2 "Amount of Parallelism"]
               [:button "1x"]


cleanup

cleanup

--- ui/ringo/utils.cljs
+++ ui/ringo/utils.cljs
@@ -1,7 +1,7 @@
 (ns ringo.utils
   (:require [om.core :as om :include-macros true]
-            [om.dom :as dom :include-macros true]
-            [cljs.reader :as reader])
+             [om.dom :as dom :include-macros true]
+             [cljs.reader :as reader])
   (:import [goog.ui IdGenerator]))

 (def debug true)


More refactoring of function parsing

More refactoring of function parsing

--- parser/parser.clj
+++ parser/parser.clj
@@ -182,13 +182,6 @@
                        _
                           (sexp-to-list-expression expressions range))))

-(def sexp-to-function-name (name-symbol)
-     (match name-symbol
-            (Symbol name _)
-                (Result name))
-            (List _ range)
-                (Error (MalformedFunctionNameError range)))
-
 (def sexp-to-function-definition (name-symbol
                                   rest
                                   range)
@@ -200,7 +193,7 @@
                                              arguments
                                              expression
                                              range))
-                 (sexp-to-function-name name-symbol)))
+                 (symbol-to-string name-symbol)))
                  (sexp-to-expression (pair-right body))))
                  (sexp-to-arguments (pair-left body))))
                  (sexp-to-function-body range rest)))


t-utils was split out

t-utils was split out

--- test/com/billpiel/mem_tracer/core_test.clj
+++ test/com/billpiel/mem_tracer/core_test.clj
@@ -79,7 +79,7 @@
         (->> trace
              mt/entry->string
              println
-             remove-iso-ctrl)
+             t-utils/remove-iso-ctrl)
         => ""))

     (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)))
@@ -406,7 +406,7 @@
             :started-at #inst "2010-01-01T01:00:00.000-00:00"})

       (fact "string output is correct"
-        (remove-iso-ctrl (mt/entry->string trace))
+        (t-utils/remove-iso-ctrl (mt/entry->string trace))
         => "[31m [1;37m>[31m[m[33m [33m|[1;37m>[33mcom.billpiel.mem-tracer.test.ns1/func-throws[m [33m|  [33m:a[0m[m [33m| [1;37;41mTHROW[m => [35m\"Exception from func-throws: :a\"[0m [33m| [31m[[0m[35m\"com.billpiel.mem_tracer.test.ns1$func_throws ns1.clj:14\"[0m[31m][0m[m")

       (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1))))


[scamp] Add tests for add-upstream.

[scamp] Add tests for add-upstream.

--- modules/scamp/test/scamp/core_test.clj
+++ modules/scamp/test/scamp/core_test.clj
@@ -285,3 +285,15 @@

       )))

+(deftest notify-add-upstream-test
+  (is (= (-> {:self {:id "canticle"} :upstream #{} :downstream #{} :messages-seen {}}
+             (core/notify-add-upstream "liebowitz")
+             purge-envelope-id)
+         [:message-envelope "liebowitz" :add-upstream "canticle"])))
+
+(deftest handle-add-upstream-test
+  (is (= (core/handle-add-upstream (:logging core/default-config)
+                                   {:self {:id "canticle"} :upstream #{} :downstream #{} :messages-seen {}}
+                                   "liebowitz")
+         [{:self {:id "canticle"}, :upstream #{"liebowitz"}, :downstream #{} :messages-seen {}} []])))
+


diagnostics and renaming

diagnostics and renaming

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -66,14 +66,13 @@
     (log/debug (str "nugents:" depth "/" max-depth ":         " (strip-refs spec)))
     (let [bolts-and-comps (filter #(not (some empty? (vals %)))
                                   (bolts-with-comps spec model depth max-depth))
-          all-of-them
-          (mapcat (fn [each-bolt-and-comps]
-                    (let [trellis (apply combo/cartesian-product (vals each-bolt-and-comps))]
-                      (map (fn [each-path-through-trellis]
-                             (zipmap (keys each-bolt-and-comps)
-                                     each-path-through-trellis))
-                           trellis)))
-                  bolts-and-comps)]
+          routes (mapcat (fn [each-bolt-and-comps]
+                           (let [trellis (apply combo/cartesian-product (vals each-bolt-and-comps))]
+                             (map (fn [each-path-through-trellis]
+                                    (zipmap (keys each-bolt-and-comps)
+                                            each-path-through-trellis))
+                                  trellis)))
+                         bolts-and-comps)]
       (filter not-fail?
               (map (fn [bolt-and-comps]
                      (log/debug (str "doing defaults on: " depth "/" max-depth ":" ((:morph-ps model) (get bolt-and-comps []))))
@@ -82,21 +81,23 @@
                                  (keys bolt-and-comps)))
                      (do-defaults
                       (do-assocs (get bolt-and-comps [])
-                                 (dissoc bolt-and-comps []))
+                                 (dissoc bolt-and-comps []) model)
                       model))
-                   all-of-them)))))
+                   routes)))))

 ;; TODO: use recur or reduce
-(defn do-assocs [accum paths-to-vals-at-path]
-  (if (empty? paths-to-vals-at-path)
+(defn do-assocs [accum paths-to-val model]
+  (if (empty? paths-to-val)
     accum
-    (let [path (first (first paths-to-vals-at-path))]
+    (let [path (first (first paths-to-val))
+          val (second (first paths-to-val))]
+      (log/debug (str "do-assocs: path=" path "; val=" ((:morph-ps model) val)))
       (do-assocs
-       (dissoc-paths (assoc-in accum
-                               path
-                               (second (first paths-to-vals-at-path)))
-                     [path])
-       (dissoc paths-to-vals-at-path path)))))
+;       (dissoc-paths
+       (assoc-in accum path val)
+;        [path])
+       (dissoc paths-to-val path)
+       model))))

 (declare comp-path-to-complements)

@@ -117,7 +118,15 @@
                          comp-paths)))
           {[]
            (filter not-fail? [lb])}))
-       (lightning-bolts model spec depth max-depth)))
+       (let [bolts
+             (lightning-bolts model spec depth max-depth)]
+         (if (empty? bolts)
+           (do
+             (log/debug (str "bolts-with-comps:" depth "/" max-depth ":" (strip-refs spec) ": no bolts found."))
+             nil)
+           (do
+             (log/debug (str "bolts-with-comps:" depth "/" max-depth ":" (strip-refs spec) ": one or more bolts found."))
+             bolts)))))

 (defn comp-path-to-complements
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."


clearing wcar disable

clearing wcar disable

--- src/celestial/redis.clj
+++ src/celestial/redis.clj
@@ -28,18 +28,13 @@

 (defm spec-server [] (car/make-conn-spec :host (get! :redis :host)))

-(def wcar-disable false)
-
 (defmacro wcar [& body]
-  `(if-not wcar-disable
-     (try
+   `(try
        (car/with-conn (pool) (spec-server) ~@body)
        (catch Exception e#
          (error e#)
          #_(throw+ {:type ::redis:connection :redis-host (get! :redis :host)} "Redis connection error")
-         ))
-     ~@body
-     ))
+         )))

 (defn lock-id [k] (<< "lock.~{k}"))


Fix the proxy mechanism

Fix the proxy mechanism

--- nightweb-desktop/src/nightweb/core.clj
+++ nightweb-desktop/src/nightweb/core.clj
@@ -2,18 +2,23 @@
   (:use nightweb.console)
   (:import net.i2p.router.Router
            net.i2p.i2ptunnel.I2PTunnel
-           net.i2p.util.EventDispatcher)
+           java.net.ProxySelector
+           java.net.Proxy
+           java.net.InetSocketAddress)
   (:gen-class))

 (defn start-http-proxy
   "Launch the http proxy."
   []
-  (java.lang.System/setProperty "http.proxyHost" "localhost")
-  (java.lang.System/setProperty "http.proxyPort" "4708")
-  (java.lang.System/setProperty "https.proxyHost" "localhost")
-  (java.lang.System/setProperty "https.proxyPort" "4708")
+  (let [proxy-selector (proxy [ProxySelector] []
+                         (select [uri]
+                                 [(Proxy. java.net.Proxy$Type/HTTP
+                                          (InetSocketAddress. "localhost" 4707))])
+                         (connectFailed [uri socket exception]
+                                        (println "Connect failed.")))]
+    (ProxySelector/setDefault proxy-selector))
   (future (I2PTunnel/main
-            (into-array java.lang.String ["-nogui" "-nocli" "-e" "httpclient 4708"]))))
+            (into-array java.lang.String ["-nogui" "-nocli" "-e" "httpclient 4707"]))))

 (defn start-router
   "Launch the router."


Add topic archive to entry representation.

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -72,7 +72,8 @@
         full-links (if (= access-level :author)
                       (concat links [(partial-update-link org-slug board-slug entry timestamp)
                                      (delete-link org-slug board-slug entry timestamp)
-                                     (create-link org-slug board-slug topic-slug)])
+                                     (create-link org-slug board-slug topic-slug)
+                                     (archive-link org-slug board-slug topic-slug)])
                       links)]
     (assoc entry :links full-links)))


fix starting

fix starting

--- src/clj/signet/core.clj
+++ src/clj/signet/core.clj
@@ -46,11 +46,11 @@

 (defn -main [& args]
-  (info "Starting Server ...")
-  (run-server (site #'handler) {:port 8091 :join? false})
-  (info "done")
-  (info  "Visit http://localhost:8091"))
-
+  (let [port (-> args first read-string)]
+    (info "Starting Server ...")
+    (run-server (site #'handler) {:port (or port 8082) :join? false})
+    (info "done")
+    (info  (str "Visit http://localhost:" (or port 8082)))))

 (comment


rewrite some

rewrite some

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/cljs/chip8/cpu.cljs
+++ src/cljs/chip8/cpu.cljs
@@ -54,50 +54,48 @@
 (defn- VxVy [V x y]
   [(nth V x) (nth V y)])

-(defn- update-memory
+
+(defn- write-pc
+  [state pc]
+  (assoc-in state [:cpu :pc] pc))
+
+(defn- write-sp
+  [state sp]
+  (assoc-in state [:cpu :sp] sp))
+
+(defn- write-i
+  [state i]
+  (assoc-in state [:cpu :i] i))
+
+(defn- write-dt
+  [state dt]
+  (assoc-in state [:cpu :dt] dt))
+
+(defn- write-st
+  [state st]
+  (assoc-in state [:cpu :st] st))
+
+(defn- write-draw-flag
+  [state draw-flag]
+  (assoc-in state [:cpu :draw-flag] draw-flag))
+
+(defn- write-stack
+  ([{{:keys [stack]} :cpu :as state} idx val]
+   (write-stack state (assoc stack idx val)))
+  ([state stack]
+   (assoc-in state [:cpu :stack] stack)))
+
+(defn- write-memory
   ([{{:keys [memory]} :cpu :as state} arr start]
-   (update-memory state (assoc-in-range memory arr start)))
+   (write-memory state (assoc-in-range memory arr start)))
   ([state memory]
    (assoc-in state [:cpu :memory] memory)))

-(defn- update-pc
-  [state pc]
-  (assoc-in state [:cpu :pc] pc))
-
-(defn- update-sp
-  [state sp]
-  (assoc-in state [:cpu :sp] sp))
-
-(defn- update-i
-  [state i]
-  (assoc-in state [:cpu :i] i))
-
-(defn- update-dt
-  [state dt]
-  (assoc-in state [:cpu :dt] dt))
-
-(defn- update-st
-  [state st]
-  (assoc-in state [:cpu :st] st))
-
-(defn- update-draw-flag
-  [state draw-flag]
-  (assoc-in state [:cpu :draw-flag] draw-flag))
-
-(defn- update-stack
-  ([{{:keys [stack]} :cpu :as state} idx val]
-   (update-stack state (assoc stack idx val)))
-  ([state stack]
-   (assoc-in state [:cpu :stack] stack)))
-
-(defn- update-v
+(defn- write-v
   ([{{:keys [v]} :cpu :as state} x val]
-   (update-v state (assoc v x val)))
+   (write-v state (assoc v x val)))
   ([{{:keys [v]} :cpu :as state} val]
-   (assoc-in state [:cpu :v]
-             (if (sequential? val)
-               (assoc-in-range v val) val))))
-
+   (assoc-in state [:cpu :v] (assoc-in-range v val))))

 (def ^{:private true}
   default-state
@@ -166,7 +164,7 @@
   "Load rom to memory. The program will be loaded start at 0x200."
   [state rom]
   (-> state
-      (update-memory (vec rom) 0x200)))
+      (write-memory (vec rom) 0x200)))

 ;; FIXME:
 (defn opcode-00E0
@@ -176,97 +174,97 @@
   (-> state
       (assoc :screen (screen/make-screen))
       (assoc-in [:cpu :draw-flag] 1)
-      (update-draw-flag 1)
-      (update-pc 2)))
+      (write-draw-flag 1)
+      (write-pc 2)))

 (defn opcode-00EE
   "Return from a subroutine."
   [{{:keys [sp stack]} :cpu :as state}]
   (-> state
-      (update-sp (dec sp))
-      (update-pc (+ 2 (nth stack (dec sp))))))
+      (write-sp (dec sp))
+      (write-pc (+ 2 (nth stack (dec sp))))))

 (defn opcode-1NNN
   "Jump to address NNN."
   [state nnn]
   (-> state
-      (update-pc nnn)))
+      (write-pc nnn)))

 (defn opcode-2NNN
   "Call subroutine at nnn."
   [{{:keys [pc sp stack]} :cpu :as state} nnn]
   (-> state
-      (update-stack sp pc)
-      (update-sp (inc pc))
-      (update-pc nnn)))
+      (write-stack sp pc)
+      (write-sp (inc pc))
+      (write-pc nnn)))

 (defn opcode-3XNN
   "Skip next instruction if VX = NN."
   [{{:keys [v]} :cpu :as state} x nn]
   (let [Vx (nth v x)]
     (-> state
-        (update-pc (if (= Vx nn) 4 2)))))
+        (write-pc (if (= Vx nn) 4 2)))))

 (defn opcode-4XNN
   "Skip next instruction if VX != NN."
   [{{:keys [v]} :cpu :as state} x nn]
   (let [Vx (nth v x)]
     (-> state
-        (update-pc (if-not (= Vx nn) 4 2)))))
+        (write-pc (if-not (= Vx nn) 4 2)))))

 (defn opcode-5XY0
   "Skip next instruction if Vx = Vy."
   [{{:keys [v]} :cpu :as state} X Y]
   (let [[Vx Vy] (VxVy v X Y)]
     (-> state
-        (update-pc (if (= Vx Vy) 4 2)))))
+        (write-pc (if (= Vx Vy) 4 2)))))

 (defn opcode-6XNN
   "Set Vx to NN."
   [state x nn]
   (-> state
-      (update-v x nn)
-      (update-pc 2)))
+      (write-v x nn)
+      (write-pc 2)))

 (defn opcode-7XNN
   "Set Vx = Vx + NN."
   [{{:keys [v]} :cpu :as state} x nn]
   (let [Vx (bit-and (+ (nth v x) nn) 0xff)]
     (-> state
-        (update-v x Vx)
-        (update-pc 2))))
+        (write-v x Vx)
+        (write-pc 2))))

 (defn opcode-8XY0
   "Set Vx = Vy."
   [{{:keys [v]} :cpu :as state} x y]
   (let [Vy (nth v y)]
     (-> state
-        (update-v  x Vy)
-        (update-pc 2))))
+        (write-v  x Vy)
+        (write-pc 2))))

 (defn opcode-8XY1
   "Set Vx = Vx OR Vy."
   [{{:keys [v]} :cpu :as state} x y]
   (let [[Vx Vy] (VxVy v x y)]
     (-> state
-        (update-v  x (bit-or Vx Vy))
-        (update-pc 2))))
+        (write-v  x (bit-or Vx Vy))
+        (write-pc 2))))

 (defn opcode-8XY2
   "Set Vx = Vx AND Vy."
   [{{:keys [v]} :cpu :as state} x y]
   (let [[Vx Vy] (VxVy v x y)]
     (-> state
-        (update-v  x (bit-and Vx Vy))
-        (update-pc 2))))
+        (write-v  x (bit-and Vx Vy))
+        (write-pc 2))))

 (defn opcode-8XY3
   "Set Vx = Vx XOR Vy."
   [{{:keys [v]} :cpu :as state} x y]
   (let [[Vx Vy] (VxVy v x y)]
     (-> state
-        (update-v  x (bit-xor Vx Vy))
-        (update-pc 2))))
+        (write-v  x (bit-xor Vx Vy))
+        (write-pc 2))))

 (defn opcode-8XY4
   "Set Vx = Vx + Vy, set VF = carry."
@@ -274,9 +272,9 @@
   (let [[Vx Vy] (VxVy v x y)
         sum (+ Vx Vy)]
     (-> state
-        (update-v  x (if (> sum 0xff) (- sum 256) sum))
-        (update-v 15 (if (> sum 0xff) 1 0))
-        (update-pc 2))))
+        (write-v  x (if (> sum 0xff) (- sum 256) sum))
+        (write-v 15 (if (> sum 0xff) 1 0))
+        (write-pc 2))))

 (defn opcode-8XY5
   "Set Vx = Vx - Vy, set VF = NOT borrow."
@@ -284,64 +282,64 @@
   (let [[Vx Vy] (VxVy v x y)
         sub (- Vx Vy)]
     (-> state
-        (update-v  x (if (< sub 0) (+ sub 256) sub))
-        (update-v 15 (if (< sub 0) 1 0))
-        (update-pc 2))))
+        (write-v  x (if (< sub 0) (+ sub 256) sub))
+        (write-v 15 (if (< sub 0) 1 0))
+        (write-pc 2))))

 (defn opcode-8XY6
   "Set Vx = Vx SHR 1."
   [{{:keys [v]} :cpu :as state} x]
   (let [Vx (nth v x)]
     (-> state
-        (update-v 15 (bit-and Vx 0x01))
-        (update-v  x (bit-shift-right Vx 1))
-        (update-pc 2))))
+        (write-v 15 (bit-and Vx 0x01))
+        (write-v  x (bit-shift-right Vx 1))
+        (write-pc 2))))

 (defn opcode-8XY7
   "Set Vx = Vy - Vx, set VF = NOT borrow."
   [{{:keys [v]} :cpu :as state} x y]
   (let [[Vx Vy] (VxVy v x y)]
     (-> state
-        (update-v 15 (if (> Vx Vy) 0 1))
-        (update-v  x (- Vy Vx))
-        (update-pc 2))))
+        (write-v 15 (if (> Vx Vy) 0 1))
+        (write-v  x (- Vy Vx))
+        (write-pc 2))))

 (defn opcode-8XYE
   "Set Vx = Vx SHL 1."
   [{{:keys [v]} :cpu :as state} x]
   (let [Vx (nth v x)]
     (-> state
-        (update-v 15 (bit-and Vx 0x80))
-        (update-v  x (bit-shift-left Vx 1))
-        (update-pc 2))))
+        (write-v 15 (bit-and Vx 0x80))
+        (write-v  x (bit-shift-left Vx 1))
+        (write-pc 2))))

 (defn opcode-9XY0
   "Skip next instruction if Vx != Vy."
   [{{:keys [v]} :cpu :as state} x y]
   (let [[Vx Vy] (VxVy v x y)]
     (-> state
-        (update-pc (if-not (= Vx Vy) 4 2)))))
+        (write-pc (if-not (= Vx Vy) 4 2)))))

 (defn opcode-ANNN
   "Set I = NNN."
   [state nnn]
   (-> state
-      (update-i nnn)
-      (update-pc 2)))
+      (write-i nnn)
+      (write-pc 2)))

 (defn opcode-BNNN
   "Jump to location nnn + V0"
   [{{:keys [v]} :cpu :as state} nnn]
   (let [V0 (nth v 0)]
     (-> state
-        (update-pc (+ V0 nnn)))))
+        (write-pc (+ V0 nnn)))))

 (defn opcode-CXNN
   "Set Vx = random byte AND NN"
   [{{:keys [v]} :cpu :as state} x nn]
   (-> state
-      (update-v x (bit-and (rand-int 256) nn))
-      (update-pc 2)))
+      (write-v x (bit-and (rand-int 256) nn))
+      (write-pc 2)))

 ;; FIXME:
 (defn opcode-DXYN
@@ -353,10 +351,11 @@
         ]
     (-> state
         ;; clear VF before we start
-        (assoc-in [:cpu :v] (assoc v 0xF 0))
+        (write-v 0xf 0)
+
         ;; detect collision
-        (assoc-in [:cpu :draw-flag] 1)
-        (assoc-in [:cpu :pc] 2))))
+        (write-draw-flag 1)
+        (write-pc 2))))

 ;; TODO: Ex09E

@@ -366,8 +365,8 @@
   "Set Vx = delay timer value."
   [{{:keys [v dt]} :cpu :as state} x]
   (-> state
-      (update-v x dt)
-      (update-pc 2)))
+      (write-v x dt)
+      (write-pc 2)))

 ;; TODO: Fx0A

@@ -376,60 +375,54 @@
   [{{:keys [v]} :cpu :as state} x]
   (let [Vx (nth v x)]
     (-> state
-        (update-dt Vx)
-        (update-pc 2))))
+        (write-dt Vx)
+        (write-pc 2))))

 (defn opcode-FX18
   "Set sound timer = Vx."
   [{{:keys [v]} :cpu :as state} X]
   (let [Vx (nth v X)]
     (-> state
-        (update-st Vx)
-        (update-pc 2))))
+        (write-st Vx)
+        (write-pc 2))))

 (defn opcode-FX29
   "Set I = location of sprite for digit Vx."
   [{{:keys [v]} :cpu :as state} X]
   (let [Vx (nth v X)]
     (-> state
-        (update-i (* 5 Vx))
-        (update-pc 2))))
-
-;; FIXME:
+        (write-i (* 5 Vx))
+        (write-pc 2))))
+
 (defn opcode-FX33
   "Store BCD representation of Vx in memory locations I, I+1, I+2."
   [{{:keys [i v memory]} :cpu :as state} X]
-  (let [Vx (nth v X)
-        val (->bcd Vx)]
-    (-> state
-        (assoc-in [:cpu :memory]
-                  (assoc-in-range memory val i))
-        (assoc-in [:cpu :pc] 2))))
-
-;; FIXME:
+  (let [Vx (nth v X)]
+    (-> state
+        (write-memory (->bcd Vx) i)
+        (write-pc 2))))
+
 (defn opcode-FX55
   "Store registers V0 through Vx in memory starting at location I."
-  [{{:keys [i v memory]} :cpu :as state} X]
-  (-> state
-      (assoc-in [:cpu :memory]
-                (assoc-in-range memory (get-in-range v 0 (inc X)) i))
-      (update-pc 2)
-      ))
+  [{{:keys [i v memory]} :cpu :as state} x]
+  (-> state
+      (write-memory (get-in-range v 0 (inc x)) i)
+      (write-pc 2)))

 (defn opcode-FX65
   "Read registers V0 through Vx from memory starting at location I."
   [{{:keys [i v memory]} :cpu :as state} X]
   (-> state
-      (update-v (get-in-range memory i (+ i X 1)))
-      (update-pc 2)))
+      (write-v (get-in-range memory i (+ i X 1)))
+      (write-pc 2)))

 (defn opcode-FX1E
   "Set I = I + Vx."
   [{{:keys [i v]} :cpu :as state} x]
   (let [Vx (nth v x)]
     (-> state
-        (update-i (+ i Vx))
-        (update-pc 2))))
+        (write-i (+ i Vx))
+        (write-pc 2))))

 (defn initial-vm [state]


Added filter

Added filter

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -342,6 +342,17 @@
   ([f val coll]
      (let [s (seq coll)]
        (-reduce s f val))))
+
+(defn filter
+  "Returns a lazy sequence of the items in coll for which
+  (pred item) returns true. pred must be free of side-effects."
+  ([pred coll]
+   (lazy-seq
+    (when-let [s (seq coll)]
+      (let [f (first s) r (rest s)]
+        (if (pred f)
+          (cons f (filter pred r))
+          (filter pred r)))))))

 ; simple reduce, to be removed when IReduce is working
 (defn reduce


* src/cljs/cljs/core.cljs: 10X improvement to PersistentVector construction

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2991,10 +2991,14 @@
 (set! cljs.core.PersistentVector/fromArray
       (fn [xs]
         (let [l (alength xs)]
-         (loop [i 0 out (-as-transient cljs.core.PersistentVector/EMPTY)]
-           (if (< i l)
-             (recur (inc i) (conj! out (aget xs i)))
-             (persistent! out))))))
+          (if (< l 32)
+            (PersistentVector. nil l 5 cljs.core.PersistentVector/EMPTY_NODE xs nil)
+            (let [node (.slice xs 0 32)
+                  v (PersistentVector. nil 32 5 cljs.core.PersistentVector/EMPTY_NODE node nil)]
+             (loop [i 32 out (-as-transient v)]
+               (if (< i l)
+                 (recur (inc i) (conj! out (aget xs i)))
+                 (persistent! out))))))))

 (defn vec [coll]
   (reduce conj cljs.core.PersistentVector/EMPTY coll))


Adding bootstrap notes

Adding bootstrap notes

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1,10 +1,10 @@
-;   Copyright (c) Rich Hickey. All rights reserved.
-;   The use and distribution terms for this software are covered by the
-;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
-;   which can be found in the file epl-v10.html at the root of this distribution.
-;   By using this software in any fashion, you are agreeing to be bound by
-;   the terms of this license.
-;   You must not remove this notice, or any other, from this software.
+                                        ;   Copyright (c) Rich Hickey. All rights reserved.
+                                        ;   The use and distribution terms for this software are covered by the
+                                        ;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+                                        ;   which can be found in the file epl-v10.html at the root of this distribution.
+                                        ;   By using this software in any fashion, you are agreeing to be bound by
+                                        ;   the terms of this license.
+                                        ;   You must not remove this notice, or any other, from this software.

 (ns cljs.core)

@@ -12,7 +12,7 @@
   (icount [coll] "constant time count"))

 #_(defprotocol IEmptyableCollection
-  (iempty [coll]))
+    (iempty [coll]))

 (defprotocol ICollection
   (iconj [coll o]))
@@ -85,8 +85,8 @@
     (irest coll)))

 #_(defn conj
-  ([coll x]
-     (if coll (iconj coll x) '(x))))
+    ([coll x]
+       (if coll (iconj coll x) '(x))))

 (defn reduce
   "f should be a function of 2 arguments. If val is not supplied,
@@ -117,14 +117,14 @@
   (ifirst [coll] first)
   (irest [coll] rest)

-#_ICounted
-#_(icount [coll] (inc (count rest)))
+  #_ICounted
+  #_(icount [coll] (inc (count rest)))

   ICollection
   (iconj [coll o] (new Cons nil o coll))

-;  IEmptyableCollection
-;  (iempty [coll] List.EMPTY)
+                                        ;  IEmptyableCollection
+                                        ;  (iempty [coll] List.EMPTY)

   ISeqable
   (iseq [coll] coll))
@@ -133,3 +133,24 @@
   "Returns a new seq where x is the first element and seq is the rest."
   [first rest]
   (new Cons nil first rest))
+
+(comment
+  (use 'cljs.compiler)
+
+  (import '[javax.script ScriptEngineManager])
+
+  (def jse (-> (ScriptEngineManager.) (.getEngineByName "JavaScript")))
+  (.eval jse bootjs)
+
+  (defmacro js [form]
+    `(emit (analyze {:ns (@namespaces 'cljs.user) :context :statement :locals {}} '~form)))
+
+  (defn jseval [form]
+    (let [js (emits (analyze {:ns (@namespaces 'cljs.user) :context :expr :locals {}}
+                             form))]
+      ;;(prn js)
+      (.eval jse (str "print(" js ")"))))
+
+  (with-open [r (PushbackReader. (clojure.java.io/reader "src/cljs/cljs/core.cljs"))]
+    (dorun (map-indexed #(do jseval (take-while identity (repeatedly #(read r false nil))))))
+    (jseval '(ifirst (irest (cons 1 (cons 2 nil))))))


Be more defensive in url generation

Be more defensive in url generation

This will catch cases where the base url has maven template values in
it (`${project.name}`, etc) since Clojars doesn't support them.

--- src/clojars/web/jar.clj
+++ src/clojars/web/jar.clj
@@ -48,6 +48,13 @@
     (when (and repo-url tag)
       (str repo-url "/tree/" tag))))

+(defn- vcs-host-tree-link [jar link-text]
+  (try
+   (when-some [url (vcs-host-tree-url jar)]
+     (link-to url link-text))
+   (catch Exception _
+     nil)))
+
 (defn dependency-link [db dep]
   (link-to
    (if (jar-exists db (:group_name dep) (:jar_name dep)) (jar-url dep) (maven-jar-url dep))
@@ -91,11 +98,15 @@
      ["/images/git-mark.png" "VCS"])))

 (defn- vcs-host-link [jar]
-  (if-let [{:keys [repo-url type user repo-name]} (vcs-host-info jar)]
-    (link-to repo-url
-             (vcs-logo type)
-             (format "%s/%s" user repo-name))
-    [:p (vcs-logo :unknown) "N/A"]))
+  (let [unknown [:p (vcs-logo :unknown) "N/A"]]
+    (if-some [{:keys [repo-url type user repo-name]} (vcs-host-info jar)]
+      (try
+        (link-to repo-url
+                (vcs-logo type)
+                (format "%s/%s" user repo-name))
+        (catch Exception _
+          unknown))
+      unknown)))

 (defn cljdoc-uri
   "Returns the URI that this JAR would have on cljdoc.org. Doesn't validate that
@@ -173,8 +184,8 @@
    [:h4 "Pushed by"]
    (user-link (:user jar)) " on "
    [:span {:title (str (:created jar))} (simple-date (:created jar))]
-   (when-let [url (vcs-host-tree-url jar)]
-     [:span.commit-url " with " (link-to url "this git tree")])))
+   (when-some [link (vcs-host-tree-link jar "this git tree")]
+     [:span.commit-url " with " link])))

 (defn versions [jar recent-versions count]
   (list


Allow and ignore nils in UI tree

Allow and ignore nils in UI tree

--- src/clojure/neko/ui.clj
+++ src/clojure/neko/ui.clj
@@ -79,7 +79,7 @@
         wdg (construct-element widget-kw context
                                (:constructor-args attributes))
         new-opts (apply-attributes widget-kw wdg attributes options)]
-    (doseq [element inside-elements]
+    (doseq [element inside-elements :when element]
       (.addView ^android.view.ViewGroup wdg
                 (make-ui-element context element new-opts)))
     wdg))


better handling of mouse down state

better handling of mouse down state


add some numbers IT (#109)

add some numbers IT (#109)

Thanks

--- resources/languages/it/corpus/numbers.clj
+++ resources/languages/it/corpus/numbers.clj
@@ -10,7 +10,43 @@
   "1"
   "uno"
   (number 1)
-
+
+  "2"
+  "due"
+  (number 2)
+
+  "3"
+  "tre"
+  (number 3)
+
+  "4"
+  "quattro"
+  (number 4)
+
+  "5"
+  "cinque"
+  (number 5)
+
+  "6"
+  "sei"
+  (number 6)
+
+  "7"
+  "sette"
+  (number 7)
+
+  "8"
+  "otto"
+  (number 8)
+
+  "9"
+  "nove"
+  (number 9)
+
+  "10"
+  "dieci"
+  (number 10)
+
   "33"
   "trentatré"
   "0033"


added mixpanel events for

added mixpanel events for

Signed-off-by: Andrey Shovkoplyas <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/data_store/realm/core.cljs
+++ src/status_im/data_store/realm/core.cljs
@@ -9,7 +9,8 @@
             [goog.string :as gstr]
             [cognitect.transit :as transit]
             [clojure.walk :as walk]
-            [status-im.react-native.js-dependencies :as rn-dependencies])
+            [status-im.react-native.js-dependencies :as rn-dependencies]
+            [status-im.utils.utils :as utils])
   (:refer-clojure :exclude [exists?]))

 (defn realm-version
@@ -39,6 +40,7 @@
   (open-realm (last schemas) file-name))

 (defn reset-realm [file-name schemas]
+  (utils/show-popup "Please note" "You must recover or create a new account with this upgrade. Also chatting with accounts in previous releases is incompatible")
   (delete-realm file-name)
   (open-realm (last schemas) file-name))


Removes some redundant code from camel-kebab.

--- src/tumblr_identity_manager/camel_kebab.clj
+++ src/tumblr_identity_manager/camel_kebab.clj
@@ -63,28 +63,7 @@
               ~type-converter)))))

 (defmacro defconversion [case-label first-fn rest-fn sep]
-  `(do  ~(type-preserving-function  case-label first-fn rest-fn sep)
-       ~@(type-converting-functions case-label first-fn rest-fn sep)))
-
-(defn type-preserving-function [case-label first-fn rest-fn sep]
-  `(let [convert-case# (partial convert-case ~first-fn ~rest-fn ~sep)]
-     (defn ~(symbol (str "->" case-label)) [s#]
-       (alter-name s# convert-case#))))
-
-(defn type-converting-functions [case-label first-fn rest-fn sep]
-  (letfn [(make-name [type-label]
-            (->> (str case-label " " type-label)
-                 (convert-case (resolve first-fn) (resolve rest-fn) sep)
-                 (str "->")
-                 (symbol)))]
-    (for [[type-label type-converter] {"string" `identity "symbol" `symbol "keyword" `keyword}]
-      `(defn ~(make-name type-label) [s#]
-         (->> (name s#)
-              (convert-case ~first-fn ~rest-fn ~sep)
-              ~type-converter)))))
-
-(defmacro defconversion [case-label first-fn rest-fn sep]
-  `(do  ~(type-preserving-function  case-label first-fn rest-fn sep)
+  `(do ~(type-preserving-function  case-label first-fn rest-fn sep)
        ~@(type-converting-functions case-label first-fn rest-fn sep)))

 (defprotocol AlterName


add test for create conference| fs / cb | #3


Added copyright notice to compojure.jetty

--- src/compojure/jetty.clj
+++ src/compojure/jetty.clj
@@ -1,8 +1,20 @@
-;; Jetty interface for Compojure
+;; Copyright (c) James Reeves. All rights reserved.
+;; The use and distribution terms for this software are covered by the Eclipse
+;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which
+;; can be found in the file epl-v10.html at the root of this distribution. By
+;; using this software in any fashion, you are agreeing to be bound by the
+;; terms of this license. You must not remove this notice, or any other, from
+;; this software.
+
+;; compojure.jetty:
+;;
+;; Clojure interface to start an embedded Jetty server.
+
 (ns compojure.jetty
-  (:import (org.mortbay.jetty Server)
-           (org.mortbay.jetty.servlet Context ServletHolder)
-           (org.mortbay.util.ajax ContinuationSupport)))
+  (:import org.mortbay.jetty Server)
+  (:import org.mortbay.jetty.servlet.Context)
+  (:import org.mortbay.jetty.servlet.ServletHolder)
+  (:import org.mortbay.util.ajax.ContinuationSupport))

 ;;;;; HTTP server ;;;;


Modify result of test case for s/fspec

Modify result of test case for s/fspec

--- test/cljc/pinpointer/formatter_test.cljc
+++ test/cljc/pinpointer/formatter_test.cljc
@@ -229,8 +229,8 @@

     (s/fspec :args (s/cat :x int?) :ret keyword?)
     identity
-    #?(:clj [["!!!#function[core/identity]!!!\n"]]
-       :cljs [["!!!#function[cljs/core/identity]!!!\n"]])
+    #?(:clj [["!!!#function[core/identity]!!!\n" "!!!0!!!\n"]]
+       :cljs [["!!!#function[cljs/core/identity]!!!\n" "!!!0!!!\n"]])

     (s/fspec :args (s/cat :x int?) :ret string?)
     name


Remove deleted refinement.

Remove deleted refinement.

--- test/onyx/plugin/input_recovery_test.clj
+++ test/onyx/plugin/input_recovery_test.clj
@@ -117,7 +117,6 @@
                            :window/type :global
                            :window/aggregation :onyx.windowing.aggregation/conj}]
                  triggers [{:trigger/window-id :collect-segments
-                            :trigger/refinement :onyx.refinements/accumulating
                             :trigger/fire-all-extents? true
                             :trigger/id :collect-trigger
                             :trigger/on :onyx.triggers/segment


don't break if we don't have sharing settings yet

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -434,7 +434,8 @@
             :document.privacy/public (om/build public-sharing app)
             :document.privacy/private (om/build private-sharing app)
             ;;read-only sharing needs to know the user's permission for the doc
-            :document.privacy/read-only (om/build read-only-sharing app))
+            :document.privacy/read-only (om/build read-only-sharing app)
+            nil)

           (case cant-edit-reason
             :no-private-docs-flag


Added more details to sensors table.

Added more details to sensors table.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -555,17 +555,25 @@
          [:table {:className "table table-hover"}
           [:thead
            [:tr
+            (sorting-th owner "Name" :name)
             (sorting-th owner "Type" :type)
             (sorting-th owner "Unit" :unit)
             (sorting-th owner "Period" :period)
-            (sorting-th owner "Device" :device_id)
+            (sorting-th owner "Resolution" :resolution)
+            (sorting-th owner "Device ID" :device_id)
+            (sorting-th owner "Location" :location)
+            (sorting-th owner "Privacy" :privacy)
+            (sorting-th owner "Events" :events)
+            (sorting-th owner "Errors" :errors)
             (sorting-th owner "Status" :status)]]
           [:tbody
            (for [row (if sort-asc
                        (sort-by sort-key flattened-sensors)
                        (reverse (sort-by sort-key flattened-sensors)))]
-             (let [{:keys [device_id type unit period status]} row
-                   id (str type "-" device_id)]
+             (let [{:keys [device_id type unit period resolution status events errors parent-device]} row
+                   {:keys [name privacy location]} parent-device
+                   id (str type "-" device_id)
+                   ]
                [:tr {:onClick (fn [_ _]
                                 (om/update! sensors :selected id)
                                 (om/update! chart :sensor id)
@@ -573,10 +581,16 @@
                                 (history/update-token-ids! history :sensors id))
                      :className (if (= id (:selected sensors)) "success")
                      :id (str table-id "-selected")}
+                [:td name]
                 [:td type]
                 [:td unit]
                 [:td period]
+                [:td resolution]
                 [:td device_id]
+                [:td location]
+                [:td privacy]
+                [:td events]
+                [:td errors]
                 [:td (status-label status)]]))]])))))

 (defn chart-summary


Animate data drill ui appear and dissapear

--- src/datadrill/core.cljs
+++ src/datadrill/core.cljs
@@ -134,20 +134,20 @@
 (defn DataDrillShell [data-atom]
   (let [data-drill (:data-drill @data-atom)
         visible? (:visible? data-drill)]
-    (if visible?
-      [:div {:style {:backgroundColor "#EEFFED"
-                     :position "fixed"
-                     :right 0
-                     :bottom 0
-                     :width "100%"
-                     :height "50%"
-                     :padding 0}}
-       [DataDrillShellVisibleButton visible? (fn [_] (swap! data-atom assoc-in [:data-drill :visible?] false))]
-       [:div {:style {:padding "10px"
-                      :height "100%"
-                      :overflow-y "scroll"}}
-        [Root data-atom]]]
-      [DataDrillShellVisibleButton visible? (fn [_] (swap! data-atom assoc-in [:data-drill :visible?] true))])))
+    [:div {:style {:backgroundColor "#EEFFED"
+                   :position "fixed"
+                   :right 0
+                   :bottom 0
+                   :width "100%"
+                   :height "50%"
+                   :max-height (if visible? "50%" 0)
+                   :transition "all 0.3s ease-out"
+                   :padding 0}}
+     [DataDrillShellVisibleButton visible? (fn [_] (swap! data-atom assoc-in [:data-drill :visible?] (not visible?)))]
+     [:div {:style {:padding "10px"
+                    :height "100%"
+                    :overflow-y "scroll"}}
+      [Root data-atom]]]))

 (defn mount-root []
   (r/render


arg not needed

arg not needed

--- examples/session/src/authexample/web.clj
+++ examples/session/src/authexample/web.clj
@@ -96,7 +96,7 @@
 (defroutes app
   (GET "/" [] home)
   (GET "/login" [] login)
-  (POST "/login" [username password] login-authenticate)
+  (POST "/login" [] login-authenticate)
   (GET "/logout" [] logout))


Auto-update when pokemon were crunched

Auto-update when pokemon were crunched

--- frontend/src/cruncher/shredder/main.cljs
+++ frontend/src/cruncher/shredder/main.cljs
@@ -10,7 +10,8 @@
   "React on response after sending a new statement. Reset atom and call newly received url."
   [response]
   (let [res (com/process-response response)]
-    (lib/info! "Converted Pokemon to bonbons. Jeah!")))
+    (lib/info! "Converted Pokemon to bonbons. Jeah!")
+    (com/route :get-all-pokemon)))

 (defn power-on
   "Crunch 'em all!"


Fixed code formatting.

Fixed code formatting.

--- src/clj_formal_specifications_app/api.clj
+++ src/clj_formal_specifications_app/api.clj
@@ -33,10 +33,10 @@
   Returns a map of the formal specification, where filename is parsed from
   the ns form in spec."
   [spec]
-    {:body {:filename (if-let [ns (spec/get-ns-name spec)]
-                        (str (peek (str/split ns #"\.")) ".clj")
-                        "untitled.clj")
-            :contents spec}})
+  {:body {:filename (if-let [ns (spec/get-ns-name spec)]
+                      (str (peek (str/split ns #"\.")) ".clj")
+                      "untitled.clj")
+          :contents spec}})

 (defn execute-with-ns
   "Evaluates command, which should be a valid Clojure form with execute or


Added type hint optimization for attribute maps

--- src/hiccup/compiler.clj
+++ src/hiccup/compiler.clj
@@ -10,7 +10,8 @@
   "Renders a tree of vectors into a string of HTML. Pre-compiles where
   possible."
   (:use clojure.contrib.def
-        clojure.contrib.java-utils))
+        clojure.contrib.java-utils)
+  (:import java.util.Map))

 (defn escape-html
   "Change special characters into HTML character entities."
@@ -83,9 +84,14 @@
     (seq? data) (apply str (map render-html data))
     :else (as-str data)))

-(defn- unknown?
-  "True if the type of x is unknown, i.e. if x is an unevaluated form or
-  symbol."
+(defn- not-hint?
+  "True if x is not hinted to be the supplied type."
+  [x type]
+  (if-let [hint (-> x meta :tag)]
+    (not (isa? (eval hint) type))))
+
+(defn- uneval?
+  "True if x is an unevaluated form or symbol."
   [x]
   (or (symbol? x)
       (and (seq? x)
@@ -94,7 +100,7 @@
 (defn- literal?
   "True if x is a literal value that can be rendered as-is."
   [x]
-  (and (not (unknown? x))
+  (and (not (uneval? x))
        (or (not (vector? x))
            (every? literal? x))))

@@ -118,7 +124,7 @@
       (render-tag (eval element))
     (and (literal? tag) (map? attrs))
       (compile-partial tag attrs content)
-    (and (literal? tag) (not (unknown? attrs)))
+    (and (literal? tag) (or (not (uneval? attrs)) (not-hint? attrs Map)))
       (compile-partial tag {} (cons attrs content))
     :else
       `(render-tag


Added ->cli coercion that mimics output of redis-cli (FIX)

--- src/labs/redis/core.clj
+++ src/labs/redis/core.clj
@@ -83,7 +83,6 @@
       java.lang.Object (->str r))))

 (defn ->cli [r]
-  (println (class r))
   (if (nil? r) "(nil)"
     (apply str
            (condp instance? r


add editor conversion

add editor conversion

--- src/lt/objs/editor.cljs
+++ src/lt/objs/editor.cljs
@@ -316,10 +316,10 @@
   (count (line e l)))

 (defn +line-class [e lh plane class]
-  (.addLineClass e lh (name plane) (name class)))
+  (.addLineClass (->cm-ed e) lh (name plane) (name class)))

 (defn -line-class [e lh plane class]
-  (.removeLineClass e lh (name plane) (name class)))
+  (.removeLineClass (->cm-ed e) lh (name plane) (name class)))

 (defn show-hints [e hint-fn options]
   (js/CodeMirror.showHint (->cm-ed e) hint-fn (clj->js options))


upsert test objects 10ms in the past

upsert test objects 10ms in the past

--- src/er_cassandra/model/util/timestamp.clj
+++ src/er_cassandra/model/util/timestamp.clj
@@ -19,7 +19,7 @@
                     (current-time-micros))))))

 (defn past-timestamp-opt
-  "generates a USING TIMESTAMP at least 1 ms ago, useful for unit test fixtures"
+  "generates a USING TIMESTAMP at least 10 ms ago, useful for unit test fixtures"
   ([] (past-timestamp-opt nil))
   ([opts]
    (update-in opts
@@ -28,4 +28,4 @@
                 (or v
                     (-
                      (current-time-micros)
-                     1000))))))
+                     10000))))))


Only get the first row if we expect only one result

--- src/mdr2/production.clj
+++ src/mdr2/production.clj
@@ -82,7 +82,7 @@
 (defn find
   "Find a production given its `id`"
   [id]
-  (db/find {:id id}))
+  (first (db/find {:id id})))

 (defn find-all
   "Find all productions"
@@ -92,12 +92,12 @@
 (defn find-by-productnumber
   "Find a production given its `product_number`"
   [product_number]
-  (db/find-by-productnumber {:product_number product_number}))
+  (first (db/find-by-productnumber {:product_number product_number})))

 (defn find-by-state
   "Find all productions with the given `state`"
   [state]
-  (db/find-by-state {:state state}))
+  (first (db/find-by-state {:state state})))

 (defn volumes
   "Find all volumes for a given `production`"


fix: adjusting stuck if second tap is much quicker

--- src/metronome/core.cljs
+++ src/metronome/core.cljs
@@ -120,26 +120,22 @@
                                                       (let [interval (- m previous-click)
                                                             previous-intervals (om/get-state owner :previous-intervals)
                                                             previous-interval (first previous-intervals)
-                                                            new-interval (fn []
+                                                            avg-interval (fn [intervals]
                                                                            (clear-adjusting-timeout)
-                                                                           (om/update-state! owner :previous-intervals #(conj % interval))
-                                                                           (let [avg (/ (reduce + interval previous-intervals) (inc (count previous-intervals)))
+                                                                           (om/set-state! owner :previous-intervals intervals)
+                                                                           (let [avg (/ (reduce + intervals) (count intervals))
                                                                                t (.setTimeout js/window (fn []
                                                                                (reset-intervals)
                                                                                (stop-adjusting)) (* interval 1.2))]
                                                                              (put! tempo-channel avg)
                                                                              (om/set-state! owner :adjusting-timeout t)))]
-                                                        (cond
-                                                          (nil? previous-interval)
-                                                          (new-interval)
-
-                                                          (> interval (* 0.8 previous-interval))
-                                                          (new-interval)
-
-                                                          :else
-                                                          (do
-                                                            (reset-intervals)
-                                                            (clear-adjusting-timeout)))))
+
+                                                        (avg-interval
+                                                          (if (or
+                                                                (nil? previous-interval)
+                                                                (< interval (* 0.8 previous-interval)))
+                                                            (list interval) ; start anew
+                                                            (conj previous-intervals interval))))) ; avg
                                                     (om/set-state! owner :previous-click m)))))}
                               (str
                                 (if should-stop "stop" "tap tempo")


(MAINT) schematize boot-services* fn

(MAINT) schematize boot-services* fn

--- src/puppetlabs/trapperkeeper/internal.clj
+++ src/puppetlabs/trapperkeeper/internal.clj
@@ -527,14 +527,11 @@
                                           :error t})))
     (deliver result-promise app)))

-(defn boot-services*
+(schema/defn ^:always-validate boot-services* :- (schema/protocol a/TrapperkeeperApp)
   "Given the services to run and the map of configuration data, create the
   TrapperkeeperApp and boot the services.  Returns the TrapperkeeperApp."
-  [services config-data-fn]
-  {:pre  [(sequential? services)
-          (every? #(satisfies? s/ServiceDefinition %) services)
-          (ifn? config-data-fn)]
-   :post [(satisfies? a/TrapperkeeperApp %)]}
+  [services :- [(schema/protocol s/ServiceDefinition)]
+   config-data-fn :- IFn]
   (let [app                     (try
                                   (build-app* services
                                               config-data-fn)


Fix spacing

Fix spacing

--- src/pinpointer/core.clj
+++ src/pinpointer/core.clj
@@ -4,7 +4,7 @@

 (defn extract* [z [k & more :as in]]
   (if (empty? in)
-    (let [[_ pos] (z/position z)]
+    (let [pos (dec (second (z/position z)))]
       [pos (+ pos (z/length z))])
     (cond (z/vector? z) (recur (z/get z k) more)
           (z/map? z) (let [z' (z/get z k)]
@@ -34,7 +34,7 @@
        #_(print " Problem: ")
        #_(prn (assoc problem :val val))
        (println "   Input:" (pr-str val))
-       (printf  "        :%s\n" (wavy-line start end))
+       (printf  "        : %s\n" (wavy-line start end))
        (print "Expected: ")
        (doseq [[j {:keys [pred reason]}] (map-indexed vector probs)]
          (when (not= j 0)