show spinner while loading data

show spinner while loading data

--- src/cljs/salava/user/ui/data.cljs
+++ src/cljs/salava/user/ui/data.cljs
@@ -36,222 +36,227 @@
      [:div
       [:p (str (t :user/Deleteinstruction) " " (t :user/Todeletedata) " ") [:a {:href (path-for "/user/cancel")} (str (t :user/Removeaccount) ".")]]
       ]
-
-     [:div.panel {:id "profile"}
-      [m/modal-window]
-      [:div.panel-body
-       [:div {:id "page-buttons-share"}
-        [:div {:id "buttons"
-               :class "text-right"}
-
-         [:button {:class "btn btn-primary"
-                   :on-click #(export-data-to-pdf state)}
-          (t :user/Exportdata)]]]
-
-       [:div.row
-        (when profile_picture [:div {:class "col-md-3 col-sm-3 col-xs-12 "}
-                               [:div {:class "profile-picture-wrapper"}
-                                [:img {:src (profile-picture profile_picture)
-                                       :style {:max-width "150px"}
-                                       :alt fullname}]]])
-        [:div {:class "col-md-9 col-sm-9 col-xs-12"}
+     (if (:initializing @state)
+       [:div.ajax-message
+        [:i {:class "fa fa-cog fa-spin fa-2x "}]
+        [:span (str (t :core/Loading) "...")]]
+       [:div.panel {:id "profile"}
+        [m/modal-window]
+
+        [:div.panel-body
+         [:div {:id "page-buttons-share"}
+          [:div {:id "buttons"
+                 :class "text-right"}
+
+           [:button {:class "btn btn-primary"
+                     :on-click #(export-data-to-pdf state)}
+            (t :user/Exportdata)]]]
+
          [:div.row
-          [:div.col-xs-12 [:b (t :user/UserID)": "] id]
-          [:div.col-xs-12 [:b (str (t :user/Role) ": ")] role]
-          [:div.col-xs-12 [:b (str (t :user/Firstname)": ")] first_name]
-          [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Lastname)": ")] last_name]
-          (if (not-empty about)
-            [:div
-             [:div.col-xs-12 [:b (t :user/Aboutme) ":"]]
-             [:div.col-xs-12 {:style {:margin-bottom "20px"}} about]])
-          (if (not-empty profile)
-            [:div {:style {:margin-top "20px"}}
-             [:div.col-xs-12 [:b (t :user/Contactinfo) ":"]]
-             [:div.col-xs-12
-              [:table.table
-               (into [:tbody]
-                     (for [profile-field (sort-by :order profile)
-                           :let [{:keys [field value]} profile-field
-                                 key (->> contact-fields
-                                          (filter #(= (:type %) field))
-                                          first
-                                          :key)]]
-                       [:tr
-                        [:td.profile-field (t key) ":"]
-                        [:td (cond
-                               (or (re-find #"www." (str value)) (re-find #"^https?://" (str value)) (re-find #"^http?://" (str value))) (hyperlink value)
-                               (and (re-find #"@" (str value)) (= "twitter" field)) [:a {:href (str "https://twitter.com/" value) :target "_blank" } (t value)]
-                               (and (re-find #"@" (str value)) (= "email" field)) [:a {:href (str "mailto:" value)} (t value)]
-                               (and  (empty? (re-find #" " (str value))) (= "facebook" field)) [:a {:href (str "https://www.facebook.com/" value) :target "_blank" } (t value)]
-                               (= "twitter" field) [:a {:href (str "https://twitter.com/" value) :target "_blank" } (t value)]
-                               (and  (empty? (re-find #" " (str value))) (= "pinterest" field)) [:a {:href (str "https://www.pinterest.com/" value) :target "_blank" } (t value)]
-                               (and  (empty? (re-find #" " (str value))) (= "instagram" field)) [:a {:href (str "https://www.instagram.com/" value) :target "_blank" } (t value)]
-                               (= "blog" field) (hyperlink value)
-                               :else (t value))]]))]]])
-
-          [:div.col-xs-12 [:b (t :user/Language)": "] language]
-          [:div.col-xs-12 [:b (t :user/Country)": "] country]
-          #_[:div.col-xs-12 [:b (t :user/Emailaddresses)": "] (count email)]
-          #_(doall
+          (when profile_picture [:div {:class "col-md-3 col-sm-3 col-xs-12 "}
+                                 [:div {:class "profile-picture-wrapper"}
+                                  [:img {:src (profile-picture profile_picture)
+                                         :style {:max-width "150px"}
+                                         :alt fullname}]]])
+          [:div {:class "col-md-9 col-sm-9 col-xs-12"}
+           [:div.row
+            [:div.col-xs-12 [:b (t :user/UserID)": "] id]
+            [:div.col-xs-12 [:b (str (t :user/Role) ": ")] role]
+            [:div.col-xs-12 [:b (str (t :user/Firstname)": ")] first_name]
+            [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Lastname)": ")] last_name]
+            (if (not-empty about)
+              [:div
+               [:div.col-xs-12 [:b (t :user/Aboutme) ":"]]
+               [:div.col-xs-12 {:style {:margin-bottom "20px"}} about]])
+            (if (not-empty profile)
+              [:div {:style {:margin-top "20px"}}
+               [:div.col-xs-12 [:b (t :user/Contactinfo) ":"]]
+               [:div.col-xs-12
+                [:table.table
+                 (into [:tbody]
+                       (for [profile-field (sort-by :order profile)
+                             :let [{:keys [field value]} profile-field
+                                   key (->> contact-fields
+                                            (filter #(= (:type %) field))
+                                            first
+                                            :key)]]
+                         [:tr
+                          [:td.profile-field (t key) ":"]
+                          [:td (cond
+                                 (or (re-find #"www." (str value)) (re-find #"^https?://" (str value)) (re-find #"^http?://" (str value))) (hyperlink value)
+                                 (and (re-find #"@" (str value)) (= "twitter" field)) [:a {:href (str "https://twitter.com/" value) :target "_blank" } (t value)]
+                                 (and (re-find #"@" (str value)) (= "email" field)) [:a {:href (str "mailto:" value)} (t value)]
+                                 (and  (empty? (re-find #" " (str value))) (= "facebook" field)) [:a {:href (str "https://www.facebook.com/" value) :target "_blank" } (t value)]
+                                 (= "twitter" field) [:a {:href (str "https://twitter.com/" value) :target "_blank" } (t value)]
+                                 (and  (empty? (re-find #" " (str value))) (= "pinterest" field)) [:a {:href (str "https://www.pinterest.com/" value) :target "_blank" } (t value)]
+                                 (and  (empty? (re-find #" " (str value))) (= "instagram" field)) [:a {:href (str "https://www.instagram.com/" value) :target "_blank" } (t value)]
+                                 (= "blog" field) (hyperlink value)
+                                 :else (t value))]]))]]])
+
+            [:div.col-xs-12 [:b (t :user/Language)": "] language]
+            [:div.col-xs-12 [:b (t :user/Country)": "] country]
+            #_[:div.col-xs-12 [:b (t :user/Emailaddresses)": "] (count email)]
+            #_(doall
+                (for [e email]
+                  ^{:key e}[:div
+                            [:div.col-xs-12 [:b (str (t :user/Email)": ")] (:email e)]
+                            [:div.col-xs-12 [:b (str (t :user/verified)": ")] (str (:verified e))]
+                            (if (true? (:primary_address e)) [:div.col-xs-12 [:b (str (t :user/Loginaddress)": ")] (str (:primary_address e))])
+                            (if (:backpack_id e) [:div.col-xs-12 [:b (str (t :user/BackpackID) ": ") ](str (:backpack_id e))])
+                            ]))
+            [:div.col-xs-12 [:b (str (t :user/Emailnotifications) ": ")] (str email_notifications)]
+            [:div.col-xs-12 [:b (str (t :user/Privateprofile) ": ")] (str private)]
+            [:div.col-xs-12 [:b (str (t :user/Activated) ": ")] (str activated?)]
+            [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Profilevisibility) ": ")] profile_visibility]]]]
+
+         [:div {:class "col-md-12 col-sm-9 col-xs-12"}
+          [:h2 {:class "uppercase-header"} [:a {:href (path-for "/user/edit/email-addresses")} (str (if (empty? (rest email)) (t :user/Email) (t :user/Emailaddresses)))]]
+          [:table.table
+           [:thead
+            [:tr
+             [:th (t :user/Email)]
+             [:th (t :user/verified)]
+             [:th (t :user/Loginaddress)]
+             [:th (t :user/BackpackID)]]]
+           [:tbody
+            (doall
               (for [e email]
-                ^{:key e}[:div
-                          [:div.col-xs-12 [:b (str (t :user/Email)": ")] (:email e)]
-                          [:div.col-xs-12 [:b (str (t :user/verified)": ")] (str (:verified e))]
-                          (if (true? (:primary_address e)) [:div.col-xs-12 [:b (str (t :user/Loginaddress)": ")] (str (:primary_address e))])
-                          (if (:backpack_id e) [:div.col-xs-12 [:b (str (t :user/BackpackID) ": ") ](str (:backpack_id e))])
-                          ]))
-          [:div.col-xs-12 [:b (str (t :user/Emailnotifications) ": ")] (str email_notifications)]
-          [:div.col-xs-12 [:b (str (t :user/Privateprofile) ": ")] (str private)]
-          [:div.col-xs-12 [:b (str (t :user/Activated) ": ")] (str activated?)]
-          [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Profilevisibility) ": ")] profile_visibility]]]]
-
-       [:div {:class "col-md-12 col-sm-9 col-xs-12"}
-        [:h2 {:class "uppercase-header"} [:a {:href (path-for "/user/edit/email-addresses")} (str (if (empty? (rest email)) (t :user/Email) (t :user/Emailaddresses)))]]
-        [:table.table
-         [:thead
-          [:tr
-           [:th (t :user/Email)]
-           [:th (t :user/verified)]
-           [:th (t :user/Loginaddress)]
-           [:th (t :user/BackpackID)]]]
-         [:tbody
-          (doall
-            (for [e email]
-              ^{:key e}[:tr
-                        [:td (:email e)]
-                        [:td (str (:verified e))]
-                        [:td (str (:primary_address e))]
-                        [:td (or (:backpack_id e) "-")]]))]]]
-
-       [:div {:class "col-md-12 col-sm-9 col-xs-12" :style {:margin-bottom "20px"}}
-        [:h2 {:class "uppercase-header"} [:a {:href (path-for "/badge")}(str (t :badge/Mybadges) ": ")(count user_badges)]]
-        (if (not-empty user_badges)
-          (doall
-            (for [b user_badges]
-              ^{:key b}[:div.col-xs-12 [:a {:href "#"
-                                            :on-click #(do
-                                                         (.preventDefault %)
-                                                         (mo/open-modal [:gallery :badges] {:badge-id (:badge_id b)})
-                                                         )} (:name b)]])))]
-       [:div {:class "col-md-12 col-sm-9 col-xs-12"}
-        (if-not (empty? pending_badges)
-          [:div
-           [:h3 [:a {:href (path-for "/social/stream")} (str (t :badge/Pendingbadges) ": ") (count pending_badges)]]
-           (doall
-             (for [p pending_badges]
-               ^{:key p}[:div
-                         #_[:div.col-xs-12 [:b (str (t :badge/BadgeID) ": ")] (str (:badge_id p))]
-                         [:div.col-xs-12 [:b (str (t :badge/Name) ": ")] (:name p)]
-                         [:div.col-xs-12 [:b (str (t :page/Description) ": ")] (:description p)]
-                         #_[:div.col-xs-12 [:b (str (t :badge/Imagefile) ": ")] (str site-url "/" (:image_file p))]
-                         #_[:div.col-xs-12 [:b (str (t :badge/Assertionurl) ": ")] (:assertion_url p)]
-                         #_[:div.col-xs-12 [:b (str (t :badge/Badgevisibility) ": ")] (str (:visibility p))]
-                         #_[:div.col-xs-12 [:b (str (t :badge/Issuedon) ": ")] (date-from-unix-time (* 1000 (:issued_on p)))]
-                         #_(when (:expires_on p) [:div.col-xs-12 [:b (str (t :badge/Expireson) ": ")] (date-from-unix-time (* 1000 (:expires_on p)))])
-                         ]))])]
-
-       [:div {:class "col-md-12 col-sm-9 col-xs-12"}
-        [:h2 {:class "uppercase-header"} [:a {:href (path-for "/page")} (str (t :page/Mypages) ": ") (count user_pages)]]
-        (if (not-empty user_pages)
-          (doall
-            (for [p user_pages]
-              ^{:key p}[:div.col-xs-12 [:a {:href "#"
-                                            :on-click #(do
-                                                         (.preventDefault %)
-                                                         (mo/open-modal [:page :view] {:page-id (:id p)})
-                                                         )} (:name p)]])))]
-
-       [:div {:class "col-md-12 col-sm-9 col-xs-12"}
-        [:h2 {:class "uppercase-header"} [:a {:href (path-for "/page/files")} (str (t :file/Files) ": ") (count user_files)]]
-        (if (not-empty user_files)
-          (doall
-            (for [f user_files]
-              ^{:key f}[:div.col-xs-12 [:a {:href  (str "/" (:path f)) :target "_blank"}
-                                        (:name f)]])))]
-
-
-       [:div {:class "col-md-12"}
-        [:h1 {:class "uppercase-header" :style {:text-align "center"}} (t :user/Activity) ]
-        (if (not-empty connections)
-          [:div
-           [:h2 {:class "uppercase-header"} [:a {:href (path-for "/social/connections")} (str (t :user/Badgeconnections) ": ") (count connections)]]
-           #_(doall
-               (for [c connections]
-                 ^{:key c}[:div {:style {:margin-top "20px"}}
-                           [:div.col-xs-12 [:b (str (t :badge/Name) ": ")] (:name c)]
-                           [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :page/Description) ": ")] (:description c)]
-                           ]))])
-        (if (or (not-empty user_following) (not-empty user_followers))
-          [:div
-           [:h2 {:class "uppercase-header"} (str (t :user/Socialconnections) ": ") (+ (count user_followers) (count user_following))]
-           (if (not-empty user_followers)
-             [:div
-              [:h3 (str (t :social/Followesrusers) ": ")]
-              (for [follower user_followers
-                    :let [id (:owner_id follower)
-                          fname (:first_name follower)
-                          lname (:last_name follower)
-                          status (:status follower)]]
-                ^{:key follower}[:div
-                                 [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:p [:b (str (t :badge/Name) ": ")] [:a {:href "#" :on-click #(mo/open-modal [:user :profile] {:user-id (:owner_id follower)})} (str (:first_name follower) " " (:last_name follower) ", ")] [:b (str (t :user/Status) ": ")] (:status follower)]]
-                                 #_[:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Status) ": ")] (:status follower)]
-                                 ])
-              [:br]])
-
-           (when-not (empty? user_following)
-             [:div
-              [:h3 (str (t :social/Followedusers) ": ")]
-              (for [f user_following
-                    :let [fid (:user_id f)
-                          fname (:first_name f)
-                          lname (:last_name f)
-                          status (:status f)]]
-                ^{:key f}[:div
-                          [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:p [:b (str (t :badge/Name) ": ")] [:a {:href "#" :on-click #(mo/open-modal [:user :profile] {:user-id (:user_id f)})} (str (:first_name f) " " (:last_name f) ", ")] [:b (str (t :user/Status) ": ")] (:status f)]]
-                          #_ [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Status) ": ")] (:status f)]
-                          ])]
-             )])
-
-        (if (not-empty events)
-          [:div
-           [:h2 {:class "uppercase-header"} (str (t :user/Activityhistory) ": ") (count events)]
-           [:table.table
-            [:thead
-             [:tr
-              [:th (t :social/Action)]
-              [:th (t :social/Object)]
-              [:th (t :badge/Name)]
-              [:th (t :social/Created)]]]
-            [:tbody
+                ^{:key e}[:tr
+                          [:td (:email e)]
+                          [:td (str (:verified e))]
+                          [:td (str (:primary_address e))]
+                          [:td (or (:backpack_id e) "-")]]))]]]
+
+         [:div {:class "col-md-12 col-sm-9 col-xs-12" :style {:margin-bottom "20px"}}
+          [:h2 {:class "uppercase-header"} [:a {:href (path-for "/badge")}(str (t :badge/Mybadges) ": ")(count user_badges)]]
+          (if (not-empty user_badges)
+            (doall
+              (for [b user_badges]
+                ^{:key b}[:div.col-xs-12 [:a {:href "#"
+                                              :on-click #(do
+                                                           (.preventDefault %)
+                                                           (mo/open-modal [:gallery :badges] {:badge-id (:badge_id b)})
+                                                           )} (:name b)]])))]
+         [:div {:class "col-md-12 col-sm-9 col-xs-12"}
+          (if-not (empty? pending_badges)
+            [:div
+             [:h3 [:a {:href (path-for "/social/stream")} (str (t :badge/Pendingbadges) ": ") (count pending_badges)]]
              (doall
-               (for [e (reverse events)]
-                 ^{:key e}[:tr
-                           [:td [:div (:verb e)]]
-                           [:td [:div (or (:type e) (:report_type e))]]
-                           [:td [:div (case (str (:verb e)(:type e))
-                                        "publishpage"  (or (get-in e [:info :object_name]) "-")
-                                        "unpublishpage" (or (get-in e [:info :object_name]) "-")
-                                        "publishbadge" (or (get-in e [:info :object_name]) "-")
-                                        "unpublishbadge" (or (get-in e [:info :object_name]) "-")
-                                        "messagebadge" [:div
-                                                        (or (get-in e [:info :object_name]) "-")"\n"
-                                                        [:br]
-                                                        [:p [:i (or (get-in e [:info :message :message]) "comment-removed")]]]
-                                        "congratulatebadge" (or (get-in e [:info :object_name]) "-")
-                                        "followbadge" (or (get-in e [:info :object_name]) "-")
-                                        "followuser" (or (get-in e [:info :object_name]) "-")
-                                        "ticketadmin" (get-in e [:info :object_name])
-                                        nil)]]
-                           [:td [:div (date-from-unix-time (* 1000 (:ctime e)))]]]
-                 ))]]])
-        ]]]]))
+               (for [p pending_badges]
+                 ^{:key p}[:div
+                           #_[:div.col-xs-12 [:b (str (t :badge/BadgeID) ": ")] (str (:badge_id p))]
+                           [:div.col-xs-12 [:b (str (t :badge/Name) ": ")] (:name p)]
+                           [:div.col-xs-12 [:b (str (t :page/Description) ": ")] (:description p)]
+                           #_[:div.col-xs-12 [:b (str (t :badge/Imagefile) ": ")] (str site-url "/" (:image_file p))]
+                           #_[:div.col-xs-12 [:b (str (t :badge/Assertionurl) ": ")] (:assertion_url p)]
+                           #_[:div.col-xs-12 [:b (str (t :badge/Badgevisibility) ": ")] (str (:visibility p))]
+                           #_[:div.col-xs-12 [:b (str (t :badge/Issuedon) ": ")] (date-from-unix-time (* 1000 (:issued_on p)))]
+                           #_(when (:expires_on p) [:div.col-xs-12 [:b (str (t :badge/Expireson) ": ")] (date-from-unix-time (* 1000 (:expires_on p)))])
+                           ]))])]
+
+         [:div {:class "col-md-12 col-sm-9 col-xs-12"}
+          [:h2 {:class "uppercase-header"} [:a {:href (path-for "/page")} (str (t :page/Mypages) ": ") (count user_pages)]]
+          (if (not-empty user_pages)
+            (doall
+              (for [p user_pages]
+                ^{:key p}[:div.col-xs-12 [:a {:href "#"
+                                              :on-click #(do
+                                                           (.preventDefault %)
+                                                           (mo/open-modal [:page :view] {:page-id (:id p)})
+                                                           )} (:name p)]])))]
+
+         [:div {:class "col-md-12 col-sm-9 col-xs-12"}
+          [:h2 {:class "uppercase-header"} [:a {:href (path-for "/page/files")} (str (t :file/Files) ": ") (count user_files)]]
+          (if (not-empty user_files)
+            (doall
+              (for [f user_files]
+                ^{:key f}[:div.col-xs-12 [:a {:href  (str "/" (:path f)) :target "_blank"}
+                                          (:name f)]])))]
+
+
+         [:div {:class "col-md-12"}
+          [:h1 {:class "uppercase-header" :style {:text-align "center"}} (t :user/Activity) ]
+          (if (not-empty connections)
+            [:div
+             [:h2 {:class "uppercase-header"} [:a {:href (path-for "/social/connections")} (str (t :user/Badgeconnections) ": ") (count connections)]]
+             #_(doall
+                 (for [c connections]
+                   ^{:key c}[:div {:style {:margin-top "20px"}}
+                             [:div.col-xs-12 [:b (str (t :badge/Name) ": ")] (:name c)]
+                             [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :page/Description) ": ")] (:description c)]
+                             ]))])
+          (if (or (not-empty user_following) (not-empty user_followers))
+            [:div
+             [:h2 {:class "uppercase-header"} (str (t :user/Socialconnections) ": ") (+ (count user_followers) (count user_following))]
+             (if (not-empty user_followers)
+               [:div
+                [:h3 (str (t :social/Followesrusers) ": ")]
+                (for [follower user_followers
+                      :let [id (:owner_id follower)
+                            fname (:first_name follower)
+                            lname (:last_name follower)
+                            status (:status follower)]]
+                  ^{:key follower}[:div
+                                   [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:p [:b (str (t :badge/Name) ": ")] [:a {:href "#" :on-click #(mo/open-modal [:user :profile] {:user-id (:owner_id follower)})} (str (:first_name follower) " " (:last_name follower) ", ")] [:b (str (t :user/Status) ": ")] (:status follower)]]
+                                   #_[:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Status) ": ")] (:status follower)]
+                                   ])
+                [:br]])
+
+             (when-not (empty? user_following)
+               [:div
+                [:h3 (str (t :social/Followedusers) ": ")]
+                (for [f user_following
+                      :let [fid (:user_id f)
+                            fname (:first_name f)
+                            lname (:last_name f)
+                            status (:status f)]]
+                  ^{:key f}[:div
+                            [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:p [:b (str (t :badge/Name) ": ")] [:a {:href "#" :on-click #(mo/open-modal [:user :profile] {:user-id (:user_id f)})} (str (:first_name f) " " (:last_name f) ", ")] [:b (str (t :user/Status) ": ")] (:status f)]]
+                            #_ [:div.col-xs-12 {:style {:margin-bottom "20px"}} [:b (str (t :user/Status) ": ")] (:status f)]
+                            ])]
+               )])
+
+          (if (not-empty events)
+            [:div
+             [:h2 {:class "uppercase-header"} (str (t :user/Activityhistory) ": ") (count events)]
+             [:table.table
+              [:thead
+               [:tr
+                [:th (t :social/Action)]
+                [:th (t :social/Object)]
+                [:th (t :badge/Name)]
+                [:th (t :social/Created)]]]
+              [:tbody
+               (doall
+                 (for [e (reverse events)]
+                   ^{:key e}[:tr
+                             [:td [:div (:verb e)]]
+                             [:td [:div (or (:type e) (:report_type e))]]
+                             [:td [:div (case (str (:verb e)(:type e))
+                                          "publishpage"  (or (get-in e [:info :object_name]) "-")
+                                          "unpublishpage" (or (get-in e [:info :object_name]) "-")
+                                          "publishbadge" (or (get-in e [:info :object_name]) "-")
+                                          "unpublishbadge" (or (get-in e [:info :object_name]) "-")
+                                          "messagebadge" [:div
+                                                          (or (get-in e [:info :object_name]) "-")"\n"
+                                                          [:br]
+                                                          [:p [:i (or (get-in e [:info :message :message]) "comment-removed")]]]
+                                          "congratulatebadge" (or (get-in e [:info :object_name]) "-")
+                                          "followbadge" (or (get-in e [:info :object_name]) "-")
+                                          "followuser" (or (get-in e [:info :object_name]) "-")
+                                          "ticketadmin" (get-in e [:info :object_name])
+                                          nil)]]
+                             [:td [:div (date-from-unix-time (* 1000 (:ctime e)))]]]
+                   ))]]])
+          ]]])]))

 (defn init-data [user-id state]
   (ajax/GET
     (path-for (str "obpv1/user/data/" user-id) true)
     {:handler (fn [data]
                 (reset! state (assoc data
-                                :user-id user-id)))}
+                                :user-id user-id))
+                (swap! state assoc :initializing false))}
     (fn [] (swap! state assoc :permission "error"))))

 (defn handler [site-navi params]
@@ -259,7 +264,8 @@
         state (atom {:user-id user-id
                      :password ""
                      :confirm-delete "false"
-                     :error-message nil})]
+                     :error-message nil
+                     :initializing true})]
     (init-data user-id state)

     (fn []


Disable popup menu

Disable popup menu

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -475,6 +475,7 @@
                  (refresh-content! this state))
                (proxy-super redoLastAction))))
      (.setAntiAliasingEnabled true)
+     (.setPopupMenu nil)
      apply-settings!))
   ([path edit-history]
    (let [extension (utils/get-extension path)]


Update tabs list after closing tabs

Update tabs list after closing tabs

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -503,11 +503,13 @@
 (defn close-selected-editor
   []
   (let [path (ui/get-selected-path)
-        file (io/file path)]
+        file (io/file path)
+        new-path (if (.isDirectory file)
+                   path
+                   (.getCanonicalPath (.getParentFile file)))]
     (remove-editors path)
-    (ui/update-project-tree (if (.isDirectory file)
-                              path
-                              (.getCanonicalPath (.getParentFile file)))))
+    (update-tabs new-path)
+    (ui/update-project-tree new-path))
   true)

 ; watchers


Pass root form to compliment

Pass root form to compliment

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -8,6 +8,7 @@
             [nightcode.ui :as ui]
             [nightcode.utils :as utils]
             [paredit.loc-utils :as loc-utils]
+            [paredit.static-analysis :as static-analysis]
             [paredit.parser :as parser]
             [paredit-widget.core :as pw]
             [seesaw.color :as color]
@@ -260,8 +261,7 @@
       (-> (str first-str "__prefix__" second-str)
           parser/parse
           loc-utils/parsed-root-loc
-          (loc-utils/loc-for-offset caretpos)
-          zip/up
+          (static-analysis/top-level-code-form caretpos)
           first
           loc-utils/node-text
           read-string))))


Fix wrong transaction management on users services.

--- src/uxbox/services/users.clj
+++ src/uxbox/services/users.clj
@@ -77,7 +77,7 @@
   [params]
   (s/assert ::update-profile params)
   (with-open [conn (db/connection)]
-    (update-profile conn params)))
+    (sc/apply-atomic conn update-profile params)))

 ;; --- Update Password

@@ -273,8 +273,7 @@
   [params]
   (s/assert ::recover-password params)
   (with-open [conn (db/connection)]
-    (sc/atomic conn
-      (recover-password conn params))))
+    (sc/apply-atomic conn recover-password params)))

 ;; --- Query Helpers


Fixed bug removing files

Fixed bug removing files

--- src/video_server/watcher.clj
+++ src/video_server/watcher.clj
@@ -111,7 +111,7 @@
 (defn add-pending-file
   "Adds a new or changing file to the list of pending files."
   [file]
-  (when-not (contains? @pending-files file)
+  (when (and (.isFile file) (not (contains? @pending-files file)))
     (log/info "watching file" (str file))
     (dosync (alter pending-files conj file))))

@@ -126,15 +126,14 @@
   [folder event filename]
   (when ((some-fn video? subtitle? image?) filename)
     (let [file (io/file filename)]
-      (when (.isFile file)
-        (try (case event
-               :create (if (stable? file)
-                         (add-file folder file)
-                         (add-pending-file file))
-               :modify (add-pending-file file)
-               :delete (remove-file folder file)
-               nil)
-             (catch Exception e (log/error e "error in file-event-callback")))))))
+      (try (case event
+             :create (if (stable? file)
+                       (add-file folder file)
+                       (add-pending-file file))
+             :modify (add-pending-file file)
+             :delete (remove-file folder file)
+             nil)
+           (catch Exception e (log/error e "error in file-event-callback"))))))

 (defn start-watcher
   "Watches for file system changes in the video folder."


wish-ul cljs

wish-ul cljs

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -19,3 +19,9 @@
    [:input {:type "text" :class "description" :value desc}]
    [:input {:type "text" :class "url" :value url}]])

+(defpartial wish-ul [wishes]
+  [:ul.wishes
+    (for [wish wishes]
+      (wish-li wish))
+    (wish-li-last)])
+


Remove unused markdown require from inkpad

--- frontend/src/faceboard/views/boards/inkpad.cljs
+++ frontend/src/faceboard/views/boards/inkpad.cljs
@@ -1,6 +1,5 @@
 (ns faceboard.views.boards.inkpad
   (:require [om-tools.core :refer-macros [defcomponent]]
-            [markdown.core :refer [md->html]]
             [faceboard.controller :refer [perform!]]
             [faceboard.helpers.utils :refer [non-sanitized-div]]
             [faceboard.logging :refer [log, log-err, log-warn]]))


undo scrollbar width function, not needed anymore

--- frontend/components/landing_b.cljs
+++ frontend/components/landing_b.cljs
@@ -46,14 +46,6 @@
                     js/window
                     "scroll"
                     scroll-callback))))
-
-(defn calculate-scrollbar-width
-  "Inserts and removes an out-of-view element to let us calculate the width of the scrollbar"
-  [owner]
-  (let [el (node [:div {:style "width: 100px; height: 100px; overflow: scroll; position: fixed; top: -200px"}])]
-    (dommy/append! (om/get-node owner) el)
-    (om/set-state! owner [:scrollbar-width] (utils/inspect (- (.-offsetWidth el) (.-clientWidth el))))
-    (dommy/remove! el)))

 (def circle-logo
   [:svg {:xmlns "http://www.w3.org/2000/svg" :x "0px" :y "0px" :viewBox "0 0 393 100" :enableBackground "new 0 0 393 100"}
@@ -173,8 +165,7 @@
   (reify
     om/IDidMount
     (did-mount [_]
-      (mount-header-logo-scroll owner)
-      (calculate-scrollbar-width owner))
+      (mount-header-logo-scroll owner))
     om/IInitState
     (init-state [_]
       {:header-logo-visible false
@@ -184,7 +175,6 @@
        :header-bkg-invisible false
        :first-fig-animate false
        :second-fig-animate false
-       :scrollbar-width 0
        :scroll-ch (chan (sliding-buffer 1))
        :hovered-customer nil})
     om/IRenderState
@@ -194,11 +184,9 @@
             selected-customer (get-in app state/customer-logo-customer-path :shopify)
             selected-toolset (get-in app state/selected-toolset-path :languages)]
         (html [:div.home.page
-               [:nav.home-nav {:style (merge {:width (if (< 0 (:scrollbar-width state))
-                                                       (str "calc(100% - " (:scrollbar-width state) "px)")
-                                                       "100%")}
-                                             (when (> 70 (:header-bkg-scroller state))
-                                               {:background-size (str "100% " (:header-bkg-scroller state) "px")}))
+               [:nav.home-nav {:style (if (> 70 (:header-bkg-scroller state))
+                                        {:background-size (str "100% " (:header-bkg-scroller state) "px")}
+                                        {})
                                :class (concat
                                        (when (:header-logo-visible state) ["logo-visible"])
                                        (when (:header-cta-visible state) ["cta-visible"])


buckets: adapt to new shape of io.cyanite.rule.Resolution

--- src/io/cyanite/engine/buckets.clj
+++ src/io/cyanite/engine/buckets.clj
@@ -1,14 +1,15 @@
 (ns io.cyanite.engine.buckets
-  (:require [io.cyanite.utils :refer [nbhm keyset remove!]]
+  (:require [io.cyanite.utils      :refer [nbhm keyset remove!]]
             [clojure.tools.logging :refer [debug]])
   (:import java.util.concurrent.atomic.AtomicLong
            java.util.concurrent.atomic.AtomicLongArray
-           java.util.concurrent.atomic.AtomicReferenceArray))
+           java.util.concurrent.atomic.AtomicReferenceArray
+           io.cyanite.engine.rule.Resolution))

-(deftype MetricTuple [^String id ^String path]
+(deftype MetricTuple [^Resolution id ^String path]
   java.lang.Object
   (hashCode [this]
-    (.hashCode (str id ":" path)))
+    (.hashCode [id path]))
   (equals [this other]
     (and
      (= (.id this) (.id other))
@@ -27,7 +28,6 @@

 (defprotocol Mutable
   (add! [this metric]))
-

 (defprotocol Snapshotable
   (snapshot! [this]))
@@ -91,7 +91,7 @@
     (* p (quot now p))))

 (defn insert-slot!
-  [time-slots k resolution]
+  [time-slots k]
   (let [slot (MetricTimeSlot.
               k
               (AtomicLong. 0)
@@ -99,21 +99,21 @@
     (assoc! time-slots k slot)
     slot))

-(defrecord MetricKey [k resolution time-slots drift]
+(defrecord MetricKey [k time-slots drift]
   Mutable
   (add! [this metric]
     (add! drift (:time metric))
-    (let [slot (time-slot resolution (:time metric))
+    (let [slot (time-slot (.id k) (:time metric))
           k    (TimeSlotTuple. (:path metric) slot)
           mts  (or (get time-slots k)
-                   (insert-slot! time-slots k resolution))]
+                   (insert-slot! time-slots k))]
       (add! mts metric)
       (snapshot! this)))
   Snapshotable
   (snapshot! [this]
     (let [now       (quot (System/currentTimeMillis) 1000)
           drift-ts  (- now @drift)
-          low-slot  (time-slot resolution drift-ts)
+          low-slot  (time-slot (.id k) drift-ts)
           slots     (keyset time-slots)
           old-slots (filter #(< (.slot %) low-slot) slots)]
       (try
@@ -126,16 +126,16 @@
           (debug e "exception while snapshotting"))))))

 (defn metric-key
-  [^MetricTuple k resolution]
-  (MetricKey. k resolution (nbhm) (drift-slot)))
+  [^MetricTuple k]
+  (MetricKey. k (nbhm) (drift-slot)))

 (defn tuple
-  [^String id ^String path]
+  [^Resolution id ^String path]
   (MetricTuple. id path))

 (comment
-  (let [k   (tuple "foo" "bar")
-        mk  (metric-key k {:precision 5 :id "foo"})
+  (let [k   (tuple (Resolution. 5 3600) "foo")
+        mk  (metric-key k)
         now (quot (System/currentTimeMillis) 1000)]
     (add! mk {:time (- now 5) :metric 1.0 :path "bar"})
     (add! mk {:time (- now 5) :metric 1.0 :path "bar"})


Adding cheshire encoder to avoid logging yada Resource instances

--- src/kixi/datastore/web_server.clj
+++ src/kixi/datastore/web_server.clj
@@ -4,6 +4,7 @@
              [vhosts :refer [vhosts-model]]]
             [byte-streams :as bs]
             [cheshire.core :as json]
+            [cheshire.generate :refer [add-encoder]]
             [clojure.core.async :as async :refer [<!!]]
             [clojure.spec.alpha :as spec]
             [com.stuartsierra.component :as component]
@@ -55,6 +56,12 @@
                       :query-string (:query-string req)
                       :user-id (ctx->user-id ctx)
                       :user-groups (ctx->user-groups ctx)})))
+
+(comment "under error conditions yada is attempting to log, into json, it's Resource instances, they are
+unparsable and don't contain any routing information, so we'll just drop them")
+(add-encoder yada.resource.Resource
+             (fn [c jsonGenerator]
+               (.writeString jsonGenerator "yada.resource")))

 (defn yada-timbre-logger
   [request-logging?]


re-implement upgrade tasks.

re-implement upgrade tasks.

--- src/leiningen/ancient/upgrade.clj
+++ src/leiningen/ancient/upgrade.clj
@@ -1,290 +1,99 @@
-(ns ^{:doc "Rewrite project.clj to include latest versions of dependencies."
-      :author "Yannick Scherer"}
-  leiningen.ancient.upgrade
-  (:require [leiningen.ancient.utils.test :as t]
-            [leiningen.ancient.utils.projects :refer :all]
-            [leiningen.ancient.utils.cli :refer :all]
-            [leiningen.ancient.utils.io :refer :all]
-            [leiningen.ancient.check :as c]
-            [leiningen.core.project :as prj]
-            [leiningen.core.main :as main]
-            [ancient-clj.verbose :refer :all]
-            [rewrite-clj.zip :as z]
-            [clojure.java.io :as io :only [file writer]])
-  (:import java.io.File))
+(ns leiningen.ancient.upgrade
+  (:require [leiningen.ancient.artifact
+             [reader :as reader]
+             [options :as o]
+             [files :as f]]
+            [leiningen.ancient
+             [collect :refer :all]
+             [console :as console]
+             [test :as t]
+             [utils :as utils]
+             [verbose :refer :all]]
+            [clojure.pprint :as pp]
+            [clojure.java.io :as io]))

-;; ## Concept
-;;
-;; We use Leiningen's built-in functions to read the project map from a file,
-;; and rewrite-clj's zipper to access said file. We can use lein-ancient's existing
-;; check functions to find the artifacts that need updating and rewrite-clj to
-;; create the updated project map.
-
-;; ## Prompt
+;; ## Logic

 (defn- prompt-for-upgrade!
-  "If the `:interactive` flag in the given settings map is set, this function will ask the
-   user (on stdout/stdin) whether he wants to upgrade the given artifact and return a boolean
-   value indicating the user's choice."
-  [settings artifact]
-  (when (:latest artifact)
-    (when (:interactive settings) (main/info))
-    (c/print-outdated-message artifact)
-    (or (not (:interactive settings))
-        (prompt "Do you want to upgrade?"))))
-
-(defn- filter-artifacts-with-prompt!
-  "Given a seq of artifacts (with the ':latest' key set), retain only those
-   that should be upgraded. If ':interactive' is set in the settings map
-   this is decided by prompting the user."
-  [settings artifacts]
-  (filter
-    (partial prompt-for-upgrade! settings)
-    artifacts))
-
-;; ## Zipper Helpers
-
-(defn- move-to-value-or-index
-  "This goes to the value preceded by a given keyword or the node
-   at a given position right of the current one."
-  [zloc p]
-  (cond (not zloc) nil
-        (integer? p) (nth
-                       (->> (iterate z/right zloc)
-                            (remove #(= (z/tag %) :uneval)))
-                       p)
-        (keyword? p) (when-let [floc (z/find-value zloc p)]
-                       (when-let [floc (z/right floc)]
-                         (z/down floc)))
-        :else nil))
-
-(defn- move-to-path
-  "Given a path seq (consisting of map keys and indices) move to a zipper location
-   represented by the given path."
-  [zloc ps]
-  (reduce move-to-value-or-index zloc ps))
-
-(defn- read-project-zipper!
-  "Read rewrite-clj zipper from project file."
-  [path]
-  (try
-    (when-let [loc (z/of-file path)]
-      (when-let [loc (z/find-value loc z/next 'defproject)]
-        (z/up loc)))
-    (catch Exception ex
-      (main/info (red "ERROR:") "could not create zipper from file at:" path)
-      (main/info (red "ERROR:") (.getMessage ex))
-      nil)))
-
-(defn read-profiles-zipper!
-  [path]
-  "Read rewrite-clj zipper from profiles file."
-  (try
-    (when-let [loc (z/of-file path)]
-      (z/find-tag loc z/next :map))
-    (catch Exception ex
-      (main/info (red "ERROR:") "could not create zipper from file at:" path)
-      (main/info (red "ERROR:") (.getMessage ex))
-      nil)))
-
-(defn- write-zipper!
-  "Write zipper back to file. Returns true if everything worked correctly."
-  [^String path zloc settings]
-  (try
-    (do
-      (if (:print settings)
-        (do
-          (main/info)
-          (z/print-root zloc)
-          (main/info))
-        (binding [*out* (io/writer path)]
-          (z/print-root zloc)
-          (.flush ^java.io.Writer *out*)))
-      true)
-    (catch Exception ex
-      (main/info (red "An error occured while writing the generated data:") (.getMessage ex)))))
-
-;; ## Zipper Update
-
-(defn- upgrade-artifact-node!
-  "Use the path stored in the artifact map to find it in the zipper and
-   upgrade its version."
-  [map-loc settings {:keys [group-id artifact-id version latest] :as artifact}]
-  (or
-    (when-let [zloc (when map-loc (z/down map-loc))]
-      (when-let [path (artifact-path artifact)]
-        (when-let [artifact-loc (move-to-path zloc path)]
-          (when (z/vector? artifact-loc)
-            (let [loc (z/down artifact-loc)]
-              (if-let [version-loc (z/right loc)]
-                (z/replace version-loc (first latest))
-                (z/insert-right loc (first latest))))))))
-    map-loc))
-
-(defn- upgrade-artifact-map!
-  "Given a zipper residing on a map (or map-like structure, e.g. defproject s-expr) and
-   a seq of outdated artifacts (containing the `:latest` key with the version to upgrade to),
-   upgrade the zipper to contain the respective versions."
-  [map-loc settings artifacts]
-  (reduce
-    (fn [map-loc artifact]
-      (z/subedit-> map-loc (upgrade-artifact-node! settings artifact)))
-    map-loc artifacts))
-
-(defn upgrade-artifact-file!
-  "Upgrade an artifact file. We need:
-   - a function that produces the data contained in the file
-   - two collect functions that retrieve repositories and artifact maps from that data
-   - a function that creates a rewrite-clj zipper from the file
-   These parts depend on whether you want to read a project or profiles file.
-   Behaviour can be modified by supplying different settings maps.
-
-   This will return true if the upgrade was successful or no changes were made; nil otherwise."
-  [read-map-fn collect-repo-fn collect-artifact-fn read-zipper-fn project settings path]
-  (when-let [artifact-map (read-map-fn path)]
-    (let [repos (collect-repo-fn project artifact-map)
-          artifacts (collect-artifact-fn artifact-map settings)]
-      (with-output-settings settings
-        (if-let [outdated (seq
-                            (->> artifacts
-                                 (c/get-outdated-artifacts! repos settings)
-                                 (filter-artifacts-with-prompt! settings)))]
-          (when-let [map-loc (read-zipper-fn path)]
-            (when-let [new-loc (upgrade-artifact-map! map-loc settings outdated)]
-              (when (:interactive settings) (main/info))
-              (main/info (count outdated)
-                         (if (= (count outdated) 1)
-                           "artifact was"
-                           "artifacts were")
-                         "upgraded.")
-              (write-zipper! path new-loc settings)))
-          (do (main/info "Nothing was upgraded.") ::nothing))))))
-
-;; ## Upgrade Mechanisms
-
-(def ^:private upgrade-project-file!*
-  "Upgrade the project file (containing 'defproject') at the given path using the given
-   settings."
-  (partial upgrade-artifact-file!
-           read-project-map!
-           #(collect-repositories %2)
-           collect-artifacts
-           read-project-zipper!))
-
-(def ^:private upgrade-profiles-file!*
-  (partial upgrade-artifact-file!
-           read-profiles-map!
-           collect-profiles-repositories
-           collect-profiles-artifacts
-           read-profiles-zipper!))
-
-;; ## Upgrade w/ Backup
-
-(defn- with-backup
-  "Wraps a given function to produce/restore backup files. Returns true
-   if upgrade was successful or no changes were written to disk. Will not
-   create backups if `:print` is specified."
-  [upgrade-fn]
-  (fn [project settings path]
-    (with-output-settings settings
-      (let [^File f (io/file path)
-            ^String path (.getCanonicalPath f)]
-        (verbose "Upgrading artifacts in: " path)
-        (if (:print settings)
-          (upgrade-fn project settings path)
-          (when-let [backup (create-backup-file! f settings)]
-            (if (upgrade-fn project settings path)
-              (do (delete-backup-file! backup) true)
-              (do (replace-with-backup! f backup) nil))))))))
-
-;; ## Tests
-
-(defn- run-regression-tests!
-  [path]
-  (main/info)
-  (when-let [project (prj/read path)]
-    (t/run-tests! project)))
-
-(defn- with-tests
-  "Wrap a given function to run tests when new data was written to disk. Returns true
-   if tests succeeded, false otherwise."
-  [upgrade-fn]
-  (fn [project settings path]
-    (when-let [r (upgrade-fn project settings path)]
-      (or (= r ::nothing)
-          (not (:tests settings))
-          (:print settings)
-          (run-regression-tests! path)))))
-
-(defn- with-abort
-  "Wrap a given function to call Leiningen's 'abort' if upgrading failed."
-  [upgrade-fn]
-  (fn [& args]
-    (when-not (apply upgrade-fn args)
-      (main/abort "Upgrade failed."))
+  [artifact {:keys [opts]}]
+  (console/print-outdated-message artifact)
+  (if (:interactive? opts)
+    (console/prompt "Do you want to upgrade?")
     true))

-;; Combine
+(defn- as-string
+  [upgraded]
+  (with-open [w (java.io.StringWriter.)]
+    (f/write! upgraded w)
+    (.trim (.toString w))))

-(def upgrade-project-file!
-  "Run upgrade on the given project file using the given settings."
-  (-> upgrade-project-file!*
-      with-tests
-      with-backup
-      with-abort))
+(defn- as-project-map
+  [upgraded]
+  (utils/with-temp-file [f (as-string upgraded)]
+    (->> (:path upgraded)
+         (.getParentFile)
+         (.getCanonicalPath)
+         (assoc (reader/read-project-map! f) :root))))

-(def upgrade-profiles-file!
-  "Run upgrade on the given profiles file using the given settings."
-  (-> upgrade-profiles-file!*
-      with-backup
-      with-abort))
+(defn- write-back!
+  [upgraded {:keys [opts]}]
+  (if (:print? opts)
+    (do
+      (printf "%n%s%n" (as-string upgraded))
+      (flush))
+    (do
+      (f/write-out! upgraded)
+      upgraded)))

-;; ## Wrappers
+(defn- report!
+  [upgraded outdated upgradable]
+  (let [o (count outdated)
+        u (count upgradable)]
+    (verbosef "%d/%d artifacts were upgraded." u o)
+    {:outdated o, :upgraded u}))
+
+(defn- test!
+  [upgraded {:keys [opts]}]
+  (if (:tests? opts)
+    (let [t (t/run-tests! (as-project-map upgraded))]
+      (if (utils/throwable? t)
+        (do
+          (errorf "tests have failed (use ':no-tests' to disable testing).")
+          t)
+        upgraded))
+    (do
+      (debugf "tests are disabled.")
+      upgraded)))

 (defn- upgrade-file!
-  "Upgrade file at the given location, either 'project.clj' or 'profiles.clj'."
-  [project ^java.io.File f settings]
-  (let [path (.getPath f)]
-    (when (.isFile f)
-      (when (:recursive settings) (main/info "--" path))
-      (cond (= (.getName f) "project.clj") (upgrade-project-file! project settings path)
-            (= (.getName f) "profiles.clj") (upgrade-profiles-file! project settings path)
-            :else (main/abort "ERROR: Can only upgrade either 'project.clj' or 'profiles.clj'."))
-      (when (:recursive settings) (main/info)))))
+  [{:keys [artifact-opts] :as opts} file]
+  (utils/with-success [r (f/read! file)]
+    (utils/with-success [outdated (f/check! r artifact-opts)]
+      (if (seq outdated)
+        (let [upgradable (filter
+                           #(prompt-for-upgrade! % opts)
+                           outdated)]
+          (utils/with-success [upgraded (f/upgrade! r upgradable)]
+            (utils/with-success [tested (test! upgraded opts)]
+              (some-> tested
+                      (write-back! opts)
+                      (report! outdated upgradable)))))
+        (verbosef "nothing to upgrade.")))))

-(defn- upgrade-directory!
-  "Upgrade directory, possibly recursively."
-  [project ^java.io.File path settings]
-  (let [top-file (io/file path "project.clj")]
-    (cond (:recursive settings) (let [project-files (find-files-recursive! path "project.clj")]
-                                  (doseq [^java.io.File project-file project-files]
-                                    (upgrade-file! project project-file settings)))
-          (.isFile top-file) (upgrade-file! project top-file settings)
-          :else (main/abort "No file at:" (.getPath top-file)))))
+;; ## Tasks

-(defn- upgrade-path!
-  "Upgrade file/directory at the given path."
-  [project path settings]
-  (let [^java.io.File f (io/file path)]
-    (cond (.isFile f) (upgrade-file! project f (assoc settings :recursive false))
-          (.isDirectory f) (upgrade-directory! project f settings)
-          :else (main/abort "No such file or directory:" path))))
+(utils/deftask upgrade
+  {:docstring "Upgrade all project artifacts."
+   :fixed {:report? true}}
+  [opts]
+  (utils/call-on-project-files upgrade-file! opts))

-;; ## Task
-
-(defn run-upgrade-task!
-  "Run artifact upgrade on project file."
-  [{:keys [root] :as project} args]
-  (if (exists? (last args))
-    (upgrade-path! project (last args) (parse-cli (butlast args)))
-    (upgrade-path! project (or root ".") (parse-cli args))))
-
-(defn run-upgrade-profiles-task!
-  "Run plugin upgrade on global profiles."
-  [project args]
-  (let [profiles-file (find-default-profiles-file)
-        settings (-> (parse-cli args)
-                     (assoc :plugins true))]
-    (if (.isFile profiles-file)
-      (upgrade-profiles-file! project settings profiles-file)
-      (main/info (yellow "No such file:") (.getPath profiles-file)))))
+(utils/deftask upgrade-profiles
+  {:docstring "Upgrade all artifacts in the global and local profiles."
+   :exclude [:no-profiles :no-tests :tests]
+   :fixed {:plugins? true
+           :profiles? true
+           :tests? false
+           :report? true}}
+  [opts]
+  (utils/call-on-profiles-files upgrade-file! opts))


CMR-1961: Added validation that content type of tag is JSON.

--- search-app/src/cmr/search/api/tags_api.clj
+++ search-app/src/cmr/search/api/tags_api.clj
@@ -33,12 +33,11 @@
                                   :maxLength 4000}}
        :required [:namespace :value]})))

-
 (defn create-tag
   "Processes a create tag request."
   [context params headers body]
-  ;; TODO validate that content type is json
-  ;; TODO validate that accept header is JSON (maybe)
+  ;; Use extract-header-mime-type to validate that it's JSON
+  (mt/extract-header-mime-type #{mt/json} headers "content-type" true)

   (let [body (slurp body)]
     (when-let [errors (seq (js/validate-json tag-schema body))]


Removed unnecessary dependencies

Removed unnecessary dependencies

--- desktop/project.clj
+++ desktop/project.clj
@@ -5,9 +5,6 @@
                  [com.badlogicgames.gdx/gdx-backend-lwjgl "1.9.3"]
                  [com.badlogicgames.gdx/gdx-box2d "1.9.3"]
                  [com.badlogicgames.gdx/gdx-box2d-platform "1.9.3"
-                  :classifier "natives-desktop"]
-                 [com.badlogicgames.gdx/gdx-bullet "1.9.3"]
-                 [com.badlogicgames.gdx/gdx-bullet-platform "1.9.3"
                   :classifier "natives-desktop"]
                  [com.badlogicgames.gdx/gdx-platform "1.9.3"
                   :classifier "natives-desktop"]


Update boot.pod/env in core pod when set-env! is called

- Namespaces that reference boot.pod/env can run in any pod---the core
  pod or dynamically created pods. Without this change you'd have to use
  boot.core/get-env in the core pod and boot.pod/env in other pods when
  specifying an env for boot.pod/make-pod.

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -187,10 +187,11 @@
   "Performs side-effects associated with changes to the env atom. Boot adds this
   function as a watcher on it."
   [old new]
+  (alter-var-root #'boot.pod/env (constantly new))
   (doseq [k (set/union (set (keys old)) (set (keys new)))]
     (let [o (get old k ::noval)
           n (get new k ::noval)]
-      (if (not= o n) (on-env! k o n new)))))
+      (when (not= o n) (on-env! k o n new)))))

 (defn- add-wagon!
   "Adds a maven wagon dependency to the worker pod and initializes it with an


Remove link

Remove link

Swagger hello example is now linked from the user manual

--- dev/src/yada/dev/website.clj
+++ dev/src/yada/dev/website.clj
@@ -51,14 +51,7 @@
                             (path-for @*router :yada.dev.user-api/user-api)
                             )}
                 "Swagger UI"]
-           " - to demonstrate Swagger integration"]
-          [:li [:a {:href
-                    (format "%s/index.html?url=%s/swagger.json"
-                            (path-for @*router :swagger-ui)
-                            (path-for @*router :hello-api)
-                            )}
-                "Swagger UI (hello)"]
-           ]]])}))
+           " - to demonstrate Swagger integration"]]])}))
    {:id ::index
     :representations [{:content-type #{"text/html"}
                        :charset #{"utf-8"}


filter core.async from :dependencies as well

too many really weird issues when using an unexpected version

--- src/main/shadow/cljs/npm/cli.cljs
+++ src/main/shadow/cljs/npm/cli.cljs
@@ -166,6 +166,7 @@
      ;; breaks cache when ending up with older version
      com.cognitect/transit-clj
      com.cognitect/transit-java
+     org.clojure/core.async
      })

 (defn drop-unwanted-deps [dependencies]
@@ -179,7 +180,8 @@
                    (when (or (contains? unwanted-deps dep-id)
                              (contains? unwanted-deps fq-dep-id))
                      (js/console.warn
-                       (str "WARNING: The " dep-id " dependency in shadow-cljs.edn was ignored. Default version is used and override is not allowed to ensure compatibility."))
+                       (str "WARNING: The " dep-id " dependency in shadow-cljs.edn was ignored. Default version is used and override is not allowed to ensure compatibility.\n"
+                            "The versions provided by shadow-cljs can be found here: https://clojars.org/thheller/shadow-cljs"))
                      true))))
        (into [])))


Oops.  Deal with dates that are null

Oops.  Deal with dates that are null

--- src/net/dishevelled/mailindex.clj
+++ src/net/dishevelled/mailindex.clj
@@ -242,9 +242,9 @@
              (chatty (format-status (/ msgcount (count to-index))
                                     mps
                                     filename)
-                     (try (index-message writer (parse-message filename basedir))
-                          (catch java.io.FileNotFoundException e
-                            (.println System/err "Oops.  Lost it")))))
+	       (try (index-message writer (parse-message filename basedir))
+		    (catch java.io.FileNotFoundException e
+		      (.println System/err "Oops.  Lost it")))))
            (when (seq fss)
              (recur fss
                     (+ msgcount (count fileset))
@@ -254,8 +254,8 @@

        (when optimise
          (chatty "Optimising"
-                 (find-deletes index writer)
-                 (.optimize writer true)))
+	   (find-deletes index writer)
+	   (.optimize writer true)))
        (clojure.set/union updates seen-messages)))
    (catch Exception e
      (.println System/err (str "Agent got exception: " e))
@@ -270,8 +270,9 @@
            (get-field doc "num")
            (int (* (.score hits %) 100000))
 	   (concat [:date
-		    (.format *date-output-format*
-			     (DateTools/stringToDate (get-field doc "date")))]
+		    (when (get-field doc "date")
+		      (.format *date-output-format*
+			       (DateTools/stringToDate (get-field doc "date"))))]
 		   (mapcat (fn [f] [(keyword f)
 				    (get-field doc f)])
 			   ["subject" "to" "from" "msgid" "lines" "chars"]))])
@@ -365,7 +366,8 @@
        (.println out (prn-str (search indexfile (.readLine in))))
      (.flush out))
    (catch Exception e
-     (.println System/err e)))
+     (.println System/err e)
+     (.printStackTrace e)))
   (send-off *agent* handle-searches indexfile port))


fix externs inference issue related to reserved names

cljs munges a few (eg. static) to static$ so GCC would still rename
.static since there only were externs for .static$

--- src/main/shadow/build/closure.clj
+++ src/main/shadow/build/closure.clj
@@ -299,14 +299,14 @@
         (str "/** @constructor */\nfunction ShadowJS() {};\n"
              (->> js-globals
                   (remove known-js-globals)
-                  (map cljs-comp/munge)
+                  (map #(cljs-comp/munge % #{}))
                   (sort)
                   (map #(str "/** @const {ShadowJS} */ var " % ";"))
                   (str/join "\n"))
              "\n"
              (->> js-props
                   (sort)
-                  (map cljs-comp/munge)
+                  (map #(cljs-comp/munge % #{}))
                   (map #(str "ShadowJS.prototype." % ";"))
                   (str/join "\n")))]


Added positioning class helpers

Added positioning class helpers

--- src/main/untangled/ui/layout.cljc
+++ src/main/untangled/ui/layout.cljc
@@ -171,3 +171,69 @@
 (def css-align-center "The CSS class string u-center for horizontal center alignment. Usable on most layout containers." "u-center")
 (def css-align-end "The CSS class string u-end for horizontal right alignment. Usable on most layout containers." "u-end")

+(def position-fixed-class
+  "A map of positioning classes that are fixed
+
+  ```
+  :top  - Positions contents top
+  :top-center - Positions contents top and centered
+  :top-right - Positions contents top and right
+  :top-left - Positions contents top and left
+  :bottom - Positions contents to the bottom
+  :bottom-right - Positions contents bottom right
+  :bottom-left - Positions contents bottom left
+  :middle - Positions contents to the middle
+  :middle-center - Positions contents to the middle center
+  ```
+
+  Can be used like this:
+
+  ```
+  (dom/div #js {:className (l/position-class :middle-center)} children)
+  ```
+
+  See also `rwhen` for a more readable alternative.
+  "
+  {:top           "u-fixed--top"
+   :top-center    "u-fixed--top-center"
+   :top-right     "u-fixed--top-right"
+   :top-left      "u-fixed--top-left"
+   :bottom        "u-fixed--bottom"
+   :bottom-left   "u-fixed--bottom-right"
+   :bottom-right  "u-fixed--bottom-right"
+   :middle        "u-fixed--middle"
+   :middle-center "u-fixed--middle-center"})
+
+
+(def position-absolute-class
+  "A map of positioning classes that are absolute
+
+  ```
+  :top  - Positions contents top
+  :top-center - Positions contents top and centered
+  :top-right - Positions contents top and right
+  :top-left - Positions contents top and left
+  :bottom - Positions contents to the bottom
+  :bottom-right - Positions contents bottom right
+  :bottom-left - Positions contents bottom left
+  :middle - Positions contents to the middle
+  :middle-center - Positions contents to the middle center
+  ```
+
+  Can be used like this:
+
+  ```
+  (dom/div #js {:className (l/position-class :middle-center)} children)
+  ```
+
+  See also `rwhen` for a more readable alternative.
+  "
+  {:top           "u-absolute--top"
+   :top-center    "u-absolute--top-center"
+   :top-right     "u-absolute--top-right"
+   :top-left      "u-absolute--top-left"
+   :bottom        "u-absolute--bottom"
+   :bottom-left   "u-absolute--bottom-right"
+   :bottom-right  "u-absolute--bottom-right"
+   :middle        "u-absolute--middle"
+   :middle-center "u-absolute--middle-center"})


Update default font size

Update default font size

--- src/net/sekao/nightcode/state.clj
+++ src/net/sekao/nightcode/state.clj
@@ -36,7 +36,7 @@
                            :expansion-set (read-pref :expansion-set #{})
                            :selection (read-pref :selection)
                            :theme (read-pref :theme :dark)
-                           :text-size (read-pref :text-size 14)}))
+                           :text-size (read-pref :text-size 15)}))

 (defonce runtime-state (atom {:web-port nil
                               :project-panes {}


Wired up gui args

Wired up gui args

--- src/layzee/core.clj
+++ src/layzee/core.clj
@@ -16,11 +16,11 @@
      (fn [opts]
        (firehose/sample settings/oauth-credential opts)))

-(def ^{:private true} realtime-filter
-     (fn [opts]
-       (firehose/filter settings/oauth-credential opts)))
+(defn- realtime-filter[args]
+     (fn [callback]
+       (firehose/filter settings/oauth-credential callback args)))

 (defn -main [& args]
   (if (< 0 (count args))
-    (realtime-sample/run {:realtime-fn realtime-filter})
-    (lazy-web/run        {:search-adapter-fn lazy-web-search})))
+    (realtime-sample/run { :realtime-fn (realtime-filter (rest args)) })
+    (lazy-web/run        { :search-adapter-fn lazy-web-search })))


fix latency reporting to zero until collection happens

--- src/preflex/resilient/hystrix.clj
+++ src/preflex/resilient/hystrix.clj
@@ -259,7 +259,10 @@
                   error-count
                   request-count
                   error-percentage
-                  execution-semaphore-permits-in-use]} (metrics-reporter)
+                  execution-semaphore-permits-in-use]
+           :as command-metrics} (metrics-reporter)
+          execute-latency (or execute-latency {:mean 0 :percentiles {}})
+          total-latency   (or total-latency   {:mean 0 :percentiles {}})
           fallback-metrics (fallback-metrics-reporter)
           cumulative-fallback-success (:cumulative-count-success fallback-metrics)
           cumulative-fallback-failure (:cumulative-count-failure fallback-metrics)


remove vestigial class

remove vestigial class

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -307,11 +307,8 @@
   (let [plans (get-in state state/user-plans-path)
         projects (get-in state state/projects-path)]
     (html
-     [:div#build-insights {:class (case (count projects)
-                                    1 "one-project"
-                                    2 "two-projects"
-                                    "three-or-more-projects")}
-        (cond
+     [:div#build-insights {}
+      (cond
           (nil? projects)    [:div.loading-spinner-big common/spinner]
           (empty? projects)  (om/build no-projects state)
           :else              (om/build-all project-insights (decorate-projects projects plans)))])))


Combining list image routes into one

Combining list image routes into one

--- src/silly_image_store/handler.clj
+++ src/silly_image_store/handler.clj
@@ -16,8 +16,8 @@
 (defn- base-url [{scheme :scheme, {host "host"} :headers}]
   (str (name scheme) "://" host))

-(defn- list-images-route [request]
-  (let [image-names (store/list-images images-dir)
+(defn- list-images-route [request bucket]
+  (let [image-names (store/list-images images-dir bucket)
         image-url (str (base-url request) "/images/")
         to-json (fn [n] {:name n :url (str image-url n)})]
     (map to-json image-names)))
@@ -30,18 +30,12 @@
   (let [image-file (store/random-image images-dir)]
     (or image-file (image-not-found "random"))))

-(defn- list-images-from-bucket-route [request bucket]
-  (let [image-names (store/list-images images-dir bucket)
-        image-url (str (base-url request) "/images/")
-        to-json (fn [n] {:name n :url (str image-url n)})]
-    (map to-json image-names)))
-

 (defroutes app-routes
-  (GET "/images" request list-images-route)
+  (GET "/images" request (list-images-route request ""))
   (GET "/images/:image" request serve-image-route)
   (GET "/random" request serve-random-image-route)
-  (GET "/buckets/:bucket/images" [bucket :as request] (list-images-from-bucket-route request bucket))
+  (GET "/buckets/:bucket/images" [bucket :as request] (list-images-route request bucket))
   (route/resources "/")
   (route/not-found "Not Found"))


fixed stuff for #2

fixed stuff for #2

--- src/tailrecursion/boot/loader.clj
+++ src/tailrecursion/boot/loader.clj
@@ -51,16 +51,16 @@
 (defn ^:from-leiningen build-url
   "Creates java.net.URL from string"
   [url]
-  (try (URL. url)
+  (try (java.net.URL. url)
        (catch java.net.MalformedURLException _
-         (URL. (str "http://" url)))))
+         (java.net.URL. (str "http://" url)))))

 (defn ^:from-leiningen get-non-proxy-hosts []
   (let [system-no-proxy (System/getenv "no_proxy")]
     (if (not-empty system-no-proxy)
-      (->> (str/split system-no-proxy #",")
+      (->> (string/split system-no-proxy #",")
            (map #(str "*" %))
-           (str/join "|")))))
+           (string/join "|")))))

 (defn ^:from-leiningen get-proxy-settings
   "Returns a map of the JVM proxy settings"


open chat

open chat

--- src/status_im/debug/handlers.cljs
+++ src/status_im/debug/handlers.cljs
@@ -67,7 +67,8 @@
                                     :debug?  true}])
           (if (get contacts whisper-identity)
             (dispatch [:update-contact! dapp])
-            (dispatch [:add-contacts [dapp]])))))))
+            (dispatch [:add-contacts [dapp]])
+            (dispatch [:open-chat-with-contact dapp])))))))

 (register-handler :debug-remove-contact
   (u/side-effect!


Namespaces aren't needed here.

Namespaces aren't needed here.

--- modules/core/src/main/clojure/immutant/repl.clj
+++ modules/core/src/main/clojure/immutant/repl.clj
@@ -27,12 +27,13 @@
     (Integer. port)
     port))

-;; We have to bind the repl * vars under 1.2.1, otherwise swank fails to start
+;; We have to bind the repl * vars under 1.2.1, otherwise swank fails to start,
+;; and with-bindings NPE's, so we roll our own
 (defmacro with-base-repl-bindings [& body]
-  `(binding [clojure.core/*e nil
-             clojure.core/*1 nil
-             clojure.core/*2 nil
-             clojure.core/*3 nil]
+  `(binding [*e nil
+             *1 nil
+             *2 nil
+             *3 nil]
      ~@body))

 (defn stop-swank


Fix up warnings

Fix up warnings

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -4231,7 +4231,7 @@

      (count [_]
        (count m))
-     (cons [_ o]
+     (cons [_ _o]
        (throw (Exception. "FakeDB doesn't implement 'cons'")))
      (empty [_]
        (FakeDB. {}))
@@ -4245,9 +4245,9 @@
      (entryAt [_ k] (get m k))

      clojure.lang.IPersistentMap
-     (assoc [this k v] (throw (Exception. "FakeDB doesn't implement 'assoc'")))
-     (assocEx [this k v] (throw (Exception. "FakeDB doesn't implement 'assocEx'")))
-     (without [this k] (throw (Exception. "FakeDB doesn't implement 'without'")))
+     (assoc [_this _k _v] (throw (Exception. "FakeDB doesn't implement 'assoc'")))
+     (assocEx [_this _k _v] (throw (Exception. "FakeDB doesn't implement 'assocEx'")))
+     (without [_this _k] (throw (Exception. "FakeDB doesn't implement 'without'")))

      clojure.lang.ILookup
      (valAt [_ k]


fix midje tests

fix midje tests

--- test/foosball/test/match.clj
+++ test/foosball/test/match.clj
@@ -12,15 +12,15 @@
                    pick-players)

 (facts "about the form"
-       (fact "it works with just a players arguments"
-             (form ...players...) => truthy)
+       (fact "it works with just players, leagues and selected league arguments"
+             (form ...players... ...leagues... ....selected...) => truthy)
        (let [team1  {:player1 ...t1p1... :player2 ...t1p2... :score ...t1score...}
              team2  {:player1 ...t2p1... :player2 ...t2p2... :score ...t2score...}
              report {:team1 team1 :team2 team2}]
          (fact "it works with a report structure"
-               (form ...players... report) => truthy
+               (form ...players... ...leagues... ...selected... report) => truthy
                (provided
                 (util/format-date anything) => ...datestring...
-                (#'foosball.views.match/team-controls :team1 1 team1 ...active-players...) => ...team1controls...
-                (#'foosball.views.match/team-controls :team2 2 team2 ...active-players...) => ...team2controls...
+                (#'foosball.views.match/render-team-controls :team1 1 team1 ...active-players...) => ...team1controls...
+                (#'foosball.views.match/render-team-controls :team2 2 team2 ...active-players...) => ...team2controls...
                 (#'foosball.views.match/filter-active-players ...players...) => ...active-players...))))


Manually implement power fn. for 2.5 speedup of badness fn.

--- src/text_justification/model.cljs
+++ src/text_justification/model.cljs
@@ -53,9 +53,7 @@
   (let [total-length (utils/line-length line)]
     (if (> total-length page-width)
       js/Infinity
-      (utils/exp (- page-width total-length) 3)))) ;; TODO do not use lib, multiply by hand
-;; (take 8 (repeat "na"))
-;; (println (time (fn..)))
+      (let [a (- page-width total-length)] (* a a a)) )))

 ;; cache results (memo)
@@ -110,6 +108,7 @@
   (clear-state)
   (doseq [paragraph (prepare-text text separate-paragraphs)]
     ; (println "PARAGRAPH:" paragraph)
+    ; (.profile js.console "text-justification")
     (let [words-raw (.split paragraph #" ")
           words (vec (flatten (map #(prepare-word page-width %) words-raw)))
           justified-text (text-justification-inner words page-width)]
@@ -117,4 +116,5 @@
         ; (.log js/console "state" (count justified-text) ":" justified-text)
         (update-state justified-text)
       )
+    ; (.profileEnd js.console)
   ))


eps8266 ping test

eps8266 ping test

--- test/otaservice/api_test.clj
+++ test/otaservice/api_test.clj
@@ -70,3 +70,22 @@
                        body (parse-body (:body response))]
                    (:status response) => 200
                    (jwt/unsign (:token body) (env :secret)) => {:user (:username creds)})))))
+
+
+(let [creds {:username "user" :password "password"}
+      non-user {:username "nobody" :password "password"}
+      version "4.20"
+      mac "F9:EC:6C:C0:29:25"]
+  (with-state-changes [(before :contents (do (migrate)
+                                             (register-req creds)))
+                       (after :contents (rollback-all))]
+    (let [ping-req #(rest-api (-> (mock/request :get (str "/api/v1/" (:username %) "/ping"))
+                                 (mock/header "user-agent" "ESP8266-http-Update")
+                                 (mock/header "x-esp8266-sta-mac" mac)
+                                 (mock/query-string {:version version})))
+          nouser-ping-resp (ping-req non-user)
+          exst-ping-resp (ping-req creds)]
+      (facts "about device management"
+             (fact "no user equals no firmware returning 304"
+                   (:status nouser-ping-resp) => 304
+                   (:status exst-ping-resp) => 304)))))


pre db-key -> id

pre db-key -> id

--- cljs/tag/src/todo/core.cljs
+++ cljs/tag/src/todo/core.cljs
@@ -4,8 +4,7 @@
   			[bide.core :as r]
   			[tiltontec.util.core :refer [pln any-ref? xor]]
   			[tiltontec.cell.base :refer [unbound ia-type]]
-  			[tiltontec.cell.core :refer-macros [c? c?n]
-  								:refer [c-in]]
+  			[tiltontec.cell.core :refer-macros [c? c?n] :refer [c-in]]
   			[tiltontec.model.core
   			 :refer [*par* fget fasc make md-reset! md-get kid-values-kids]]
             [tag.html :refer [tag  to-html on-evt tag-dom fm-asc-tag
@@ -16,9 +15,7 @@
             [todo.util :refer [pln json-to-map map-to-json uuidv4 now]]
             [todo.io :refer [io-all-keys io-truncate io-find io-upsert
             				io-read io-clear-storage]]
-
-            [todo.todo :refer
-             	[gTodo gTodo-lookup TODO_LS_PREFIX make-todo
+            [todo.todo :refer [gTodo gTodo-lookup TODO_LS_PREFIX make-todo
              	todo-to-map title completed todo-to-json todo-load todo-upsert
             	todo-dump todo-delete  load-all-todos gTodo-items]]))

@@ -85,10 +82,10 @@
 	(when (= (.-key e) "Enter")
 		;;(pln :enter!!! e (.-target e) (.-value (.-target e)))
 		(let [raw (.-value (.-target e))
-				title (str/trim raw)]
+			  title (str/trim raw)]
 			(if (= title "")
 				(when (pos? (count raw))
-					(.alert js/window "A reminder to do nothing? No sure we are relaxing yet. So, no."))
+					(.alert js/window "A reminder to do nothing? Are we relaxing yet? So, no."))
 				(md-reset! @gTodo :items-raw
 					(conj (md-get @gTodo :items-raw)
 						(make-todo {:title title}))))
@@ -118,9 +115,7 @@
 										(md-get td :db-key)))))

 		(input (:class "edit"
-				:value (c?n (let [tdt (md-get td :title)]
-								(println :editval-1 tdt)
-								tdt))
+				:value (c?n (md-get td :title))
 				:onblur (on-evt "todo.core.todo_edit" (md-get td :db-key))
 				:onkeydown (on-evt "todo.core.todo_edit" (md-get td :db-key))
 				:onkeypress (on-evt "todo.core.todo_edit" (md-get td :db-key))))))
@@ -131,17 +126,14 @@
 		  li (fm-asc-tag lbl "li")
 		  edt-doms (.getElementsByClassName (tag-dom li) "edit")
 		  edom (.item edt-doms 0)]
-		(println :edom-starting (.-value edom))
 		(.add (.-classList (tag-dom li)) "editing")
 		(.focus edom)
 		(.setSelectionRange edom 0 (.-length (.-value edom)))))

 (defn todo-item-display-rule []
-	(c? (let [f (fget (fn [x]
-						(when (= (md-get x :class) "filters")
+	(c? (let [f (fget (fn [x] (when (= (md-get x :class) "filters")
 							true)) me
-						:upp? true
-						:must? true)]
+						:upp? true)]
 			(let [sel (md-get f :selection)]
 				(if (or (= sel "All")
 						(let [td (md-get me :todo)]
@@ -150,7 +142,7 @@

 (defn todo-edit [e td-key]
 	(let [edom (.-target e)
-		  title (.-value edom)
+		  title (str/trim (.-value edom))
 		  td (gTodo-lookup td-key)
 		  li-dom (dom-ancestor-by-tag edom "li")]
 		(cond
@@ -184,14 +176,11 @@
 		  (doall
 			(for [[label route] [["All", "#/"], ["Active","#/active"], ["Completed","#/completed"]]]
 				(li () (a (:href route
-							:selected (c? #_ (println :comping (:selector @me)
-													(md-get (fm-asc-tag me "ul") :selection))
-								(= (:selector @me)
-											(md-get (fm-asc-tag me "ul") :selection)))
-							:class (c? (let [new (if (md-get me :selected) "selected" "")]
-											;;(println :liclass (:selector @me) new :old cache)
-											new))
-							:selector label) label)))))
+							:selector label
+							:selected (c? (= (:selector @me)
+											 (md-get (fm-asc-tag me "ul") :selection)))
+							:class (c? (if (md-get me :selected) "selected" "")))
+						 label)))))

 		(button (:class "clear-completed"
 				 :hidden  (c? (zero? (count (filter completed (gTodo-items)))))


Consolidate mode handling.

Consolidate mode handling.

There were previously three different atoms for tracking modes the
controller could be in (shift, record, and stop), and as I was about to
add a third, it seemed time to put this all into a more coherent
framework.

--- src/afterglow/controllers/ableton_push.clj
+++ src/afterglow/controllers/ableton_push.clj
@@ -397,12 +397,26 @@
         :green
         :red))))

+(defn- update-mode!
+  "Turn a controller mode on or off, identified by the associated
+  control button number or keyword."
+  [controller button state]
+  (let [button (if (keyword? button) (get-in control-buttons [button :control]) button)]
+    (swap! (:modes controller) #(if state (conj % button) (disj % button)))))
+
+(defn in-mode?
+  "Check whether the controller is in a particular mode, identified by
+  a control button number or keyword."
+  [controller button]
+  (let [button (if (keyword? button) (get-in control-buttons [button :control]) button)]
+    (get @(:modes controller) button)))
+
 (defn- bpm-adjusting-interface
   "Add an arrow showing the BPM is being adjusted, or point out that
   it is being externally synced."
   [controller]
   (if (= (:type (show/sync-status)) :manual)
-    (let [arrow-pos (if @(:shift-mode controller) 14 16)]
+    (let [arrow-pos (if (in-mode? controller :shift) 14 16)]
       (aset (get (:next-display controller) 2) arrow-pos (:up-arrow special-symbols)))
     (do
       (aset (get (:next-display controller) 2) 9 (:down-arrow special-symbols))
@@ -425,7 +439,7 @@
   [controller message]
   (with-show (:show controller)
     (when (= (:type (show/sync-status)) :manual)
-      (let [scale (if @(:shift-mode controller) 1 10)
+      (let [scale (if (in-mode? controller :shift) 1 10)
             delta (/ (sign-velocity (:velocity message)) scale)
             bpm (rhythm/metro-bpm (:metronome (:show controller)))]
         (rhythm/metro-bpm (:metronome (:show controller)) (min controllers/maximum-bpm
@@ -459,7 +473,7 @@
   "Add an arrow showing the beat is being adjusted."
   [controller]
   (let [marker (rhythm/metro-marker (:metronome (:show controller)))
-                         arrow-pos (if @(:shift-mode controller)
+                         arrow-pos (if (in-mode? controller :shift)
                                      (dec (.indexOf marker "." (inc (.indexOf marker "."))))
                                      (dec (count marker)))]
     (aset (get (:next-display controller) 2) arrow-pos (:up-arrow special-symbols))))
@@ -469,7 +483,7 @@
   [controller message]
   (let [delta (sign-velocity (:velocity message))
         metronome (:metronome (:show controller))
-        units (if @(:shift-mode controller)
+        units (if (in-mode? controller :shift)
                 ;; User is adjusting the current bar
                 (rhythm/metro-tock metronome)
                 ;; User is adjusting the current beat
@@ -752,9 +766,9 @@
               (write-display-cell controller 0 x (cue-variable-names controller cue (:id info)))
               (write-display-cell controller 1 x (cue-variable-values controller cue (:id info)))
               (write-display-cell controller 2 x (or (:name cue) (:name (first fx))))
-              (write-display-cell controller 3 x (concat (if @(:record-mode controller) save-label end-label)
+              (write-display-cell controller 3 x (concat (if (in-mode? controller :record) save-label end-label)
                                                          more-label))
-              (if @(:record-mode controller)
+              (if (in-mode? controller :record)
                 (when save-action
                   (aset (:next-top-pads controller) (* 2 x)
                         (top-pad-state :dim (case save-action
@@ -792,7 +806,7 @@
   "Activate the arrow buttons for directions in which scrolling is
   possible."
   [controller]
-  (if @(:shift-mode controller)
+  (if (in-mode? controller :shift)
     ;; In shift mode, scroll through the effects list
     (let [[offset max-offset] (find-effect-offset-range controller)]
       ;; If there is an offset, user can scroll to the right
@@ -848,20 +862,20 @@

       ;; If the show has stopped without us noticing, enter stop mode
       (with-show (:show controller)
-        (when-not (or (show/running?) @(:stop-mode controller))
+        (when-not (or (show/running?) (in-mode? controller :stop))
           (enter-stop-mode controller :already-stopped true)))

       ;; Reflect the shift button state
       (swap! (:next-text-buttons controller)
              assoc (:shift control-buttons)
              (button-state (:shift control-buttons)
-                           (if @(:shift-mode controller) :bright :dim)))
+                           (if (in-mode? controller :shift) :bright :dim)))

       ;; Reflect the record button state
       (swap! (:next-text-buttons controller)
              assoc (:record control-buttons)
              (button-state (:record control-buttons)
-                           (if @(:record-mode controller) :bright :dim)))
+                           (if (in-mode? controller :record) :bright :dim)))

       (render-cue-grid controller snapshot)
       (update-scroll-arrows controller)
@@ -1116,7 +1130,7 @@
   and black it out until the stop button is pressed again."
   [controller & {:keys [already-stopped]}]

-  (reset! (:stop-mode controller) true)
+  (update-mode! controller :stop true)
   (when-not already-stopped
     (with-show (:show controller)
       (show/stop!)
@@ -1141,14 +1155,14 @@
                                       (button-state (:stop control-buttons) :bright))
                                (with-show (:show controller)
                                  (when (show/running?)
-                                   (reset! (:stop-mode controller) false))
-                                 @(:stop-mode controller)))
+                                   (update-mode! controller :stop false))
+                                 (in-mode? controller :stop)))
                              (handle-control-change [this message]
                                (when (pos? (:velocity message))
                                  ;; End stop mode
                                  (with-show (:show controller)
                                    (show/start!))
-                                 (reset! (:stop-mode controller) false)
+                                 (update-mode! controller :stop false)
                                  :done))
                              (handle-note-on [this message])
                              (handle-note-off [this message])
@@ -1288,7 +1302,7 @@

     (20 22 24 26) ; Effect end/save pads
     (when (pos? (:velocity message))
-      (if @(:record-mode controller)
+      (if (in-mode? controller :record)
         (handle-save-effect controller (:note message))
         (handle-end-effect controller (:note message))))

@@ -1302,15 +1316,12 @@
     (when (pos? (:velocity message))
       (enter-stop-mode controller))

-    49 ; Shift button
-    (reset! (:shift-mode controller) (pos? (:velocity message)))
-
-    86 ; Record button
-    (reset! (:record-mode controller) (pos? (:velocity message)))
+    (49 86) ; Shift or Record button
+    (update-mode! controller (:note message) (pos? (:velocity message)))

     44 ; Left arrow
     (when (pos? (:velocity message))
-      (if @(:shift-mode controller)
+      (if (in-mode? controller :shift)
         ;; Trying to scroll back to older effects
         (let [[offset max-offset room] (find-effect-offset-range controller)
               new-offset (min max-offset (+ offset room))]
@@ -1326,7 +1337,7 @@

     45 ; Right arrow
     (when (pos? (:velocity message))
-      (if @(:shift-mode controller)
+      (if (in-mode? controller :shift)
         ;; Trying to scroll forward to newer effects
         (let [[offset max-offset room] (find-effect-offset-range controller)
               new-offset (max 0 (- offset room))]
@@ -1342,7 +1353,7 @@

     46 ; Up arrow
     (when (pos? (:velocity message))
-      (if @(:shift-mode controller)
+      (if (in-mode? controller :shift)
         ;; Jump back to oldest effect
         (let [[offset max-offset] (find-effect-offset-range controller)]
           (when (not= offset max-offset)
@@ -1357,7 +1368,7 @@

     47 ; Down arrow
     (when (pos? (:velocity message))
-      (if @(:shift-mode controller)
+      (if (in-mode? controller :shift)
         ;; Jump forward to newest effect
         (when (pos? @(:effect-offset controller))
           (reset! (:effect-offset controller) 0)
@@ -1398,7 +1409,7 @@
               (if (and active (not (:held cue)))
                 (show/end-effect! (:key cue))
                 (let [id (show/add-effect-from-cue-grid! cue-x cue-y :velocity velocity)
-                      holding (and (:held cue) (not @(:shift-mode controller)))]
+                      holding (and (:held cue) (not (in-mode? controller :shift)))]
                   (controllers/add-overlay
                    (:overlays controller)
                    (reify controllers/IOverlay
@@ -1863,7 +1874,7 @@
         port-out (first (amidi/filter-devices device-filter (amidi/open-outputs-if-needed!)))
         device   (when (every? some? [port-in port-out]) (valid-identity port-in port-out))]
     (if device
-      (let [shift-mode (atom false)
+      (let [modes (atom #{})
             controller
             (with-meta
               {:display-name         display-name
@@ -1886,12 +1897,11 @@
                :next-grid-pads       (make-array clojure.lang.IPersistentMap 64)
                :metronome-mode       (atom {})
                :last-marker          (atom nil)
-               :shift-mode           shift-mode
-               :stop-mode            (atom false)
-               :record-mode          (atom false)
+               :modes                modes
                :midi-handler         (atom nil)
                :deactivate-handler   (atom nil)
-               :tempo-tap-handler    (tempo/create-show-tempo-tap-handler show :shift-fn (fn [] @shift-mode))
+               :tempo-tap-handler    (tempo/create-show-tempo-tap-handler
+                                      show :shift-fn (fn [] (get @modes (get-in control-buttons [:shift :control]))))
                :overlays             (controllers/create-overlay-state)
                :move-listeners       (atom #{})
                :grid-controller-impl (atom nil)}


Renamed predicate keyword arguments to use trailing question marks for consistency.

--- src/appengine_magic/services/datastore.clj
+++ src/appengine_magic/services/datastore.clj
@@ -177,7 +177,7 @@
              (throw err#))))))

-(defn- make-query-object [kind ancestor filter sort keys-only]
+(defn- make-query-object [kind ancestor filter sort keys-only?]
   (let [kind (cond (nil? kind) kind
                    (string? kind) kind
                    (extends? EntityProtocol kind) (unqualified-name kind)
@@ -193,7 +193,7 @@
         filter (if (every? sequential? filter) filter (vector filter))
         ;; normalize sort criteria into a vector (even if there's just one)]
         sort (if (every? sequential? sort) sort (vector sort))]
-    (when keys-only
+    (when keys-only?
       (.setKeysOnly query-object))
     (doseq [[filter-operator filter-property-kw filter-value] filter]
       (cond
@@ -227,14 +227,14 @@
     query-object))

-(defn query [& {:keys [kind ancestor filter sort keys-only
+(defn query [& {:keys [kind ancestor filter sort keys-only?
                        count-only? in-transaction?
                        limit offset
                        start-cursor end-cursor ; TODO: Implement this.
                        prefetch-size chunk-size]
-                :or {keys-only false, filter [[]], sort [[]],
+                :or {keys-only? false, filter [[]], sort [[]],
                      count-only? false, in-transaction? false}}]
-  (let [query-object (make-query-object kind ancestor filter sort keys-only)
+  (let [query-object (make-query-object kind ancestor filter sort keys-only?)
         fetch-options-object (FetchOptions$Builder/withDefaults)]
     (when limit
       (.limit fetch-options-object limit))


Updated logging message.

Updated logging message.

--- search-app/src/cmr/search/services/query_service.clj
+++ search-app/src/cmr/search/services/query_service.clj
@@ -207,7 +207,7 @@
                                          context concept-type query))
         total-took (+ query-creation-time find-concepts-time)]
     (info (format "Found %d %ss in %d ms from client %s in format %s with params %s."
-                  (get-in results [:hits :value]) (name concept-type) total-took (:client-id context)
+                  (:hits results) (name concept-type) total-took (:client-id context)
                   (rfh/printable-result-format (:result-format query)) (pr-str params)))
     (assoc results :took total-took)))

@@ -226,7 +226,7 @@
                                                                     query))
         total-took (+ query-creation-time find-concepts-time)]
     (info (format "Found %d %ss in %d ms from client %s in format %s with JSON Query %s and query params %s."
-                  (get-in results [:hits :value]) (name concept-type) total-took (:client-id context)
+                  (:hits results) (name concept-type) total-took (:client-id context)
                   (rfh/printable-result-format (:result-format query)) json-query (pr-str params)))
     (assoc results :took total-took)))

@@ -245,7 +245,7 @@
                                                                     query))
         total-took (+ query-creation-time find-concepts-time)]
     (info (format "Found %d %ss in %d ms from client %s in format %s with aql: %s."
-                  (get-in results [:hits :value]) (name concept-type) total-took (:client-id context)
+                  (:hits results) (name concept-type) total-took (:client-id context)
                   (rfh/printable-result-format (:result-format query)) aql))
     (assoc results :took total-took)))

@@ -451,7 +451,7 @@
                                    (set visible-concept-ids)))
         results (get-highest-visible-revisions context deleted-concept-ids result-format)
         ;; when results is nil, hits is 0
-        hits (get-in results [:hits :value] 0)
+        hits (get results :hits 0)
         results (or results {:hits hits :items []})
         total-took (- (System/currentTimeMillis) start-time)
         ;; construct the response results string


Use new service to identify the king.

Use new service to identify the king.

--- src/clj/made_merits/routes/leaderboard.clj
+++ src/clj/made_merits/routes/leaderboard.clj
@@ -2,12 +2,17 @@
   (:require [made-merits.layout :as layout]
             [compojure.core :refer [defroutes GET POST]]
             [ring.util.http-response :as response]
+            [made-merits.service.winner-calculator :as winner-calculator]
             [made-merits.db.core :as db]
             [clojure.java.io :as io]))

+(defn meritted-users
+  []
+  (winner-calculator/with-winner (db/get-meritted-users)))
+
 (defn leaderboard []
   (layout/render
-    "leaderboard.html" {:meritted_users (db/get-meritted-users)}))
+    "leaderboard.html" {:meritted_users (meritted-users)}))

 (defroutes leaderboard-routes
   (GET "/" [] (leaderboard)))


In case of orphaned task use task-id as name identificator

--- src/clj/swarmpit/docker/mapper/inbound.clj
+++ src/clj/swarmpit/docker/mapper/inbound.clj
@@ -61,7 +61,8 @@

 (defn- ->service-mode
   [service-spec]
-  (str/lower-case (name (first (keys (:Mode service-spec))))))
+  (when service-spec
+    (str/lower-case (name (first (keys (:Mode service-spec)))))))

 (defn ->task-node
   [node-id nodes]
@@ -70,6 +71,14 @@
 (defn ->task-service
   [service-id services]
   (first (filter #(= (:ID %) service-id) services)))
+
+(defn ->task-name
+  "If there is no matching service for task use task-id as name. Otherwise follow rules"
+  [task-id node-id slot service-name service-mode]
+  (cond
+    (= "replicated" service-mode) (str service-name "." slot)
+    (= "global" service-mode) (str service-name "." node-id)
+    :else task-id))

 (defn ->task
   [task nodes services]
@@ -86,9 +95,7 @@
         service (->task-service service-id services)
         service-name (get-in service [:Spec :Name])
         service-mode (->service-mode (:Spec service))
-        task-name (if (= "replicated" service-mode)
-                    (str service-name "." slot)
-                    service-name)]
+        task-name (->task-name id node-id slot service-name service-mode)]
     (array-map
       :id id
       :taskName task-name
@@ -100,7 +107,7 @@
       :state (get-in task [:Status :State])
       :status {:error (get-in task [:Status :Err])}
       :desiredState (:DesiredState task)
-      :serviceName service-name
+      :serviceName (or service-name service-id)
       :nodeName (or node-name node-id))))

 (defn ->tasks


Added function for getting the namespace that was used when composing the specification.

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -32,9 +32,15 @@
   [filename]
   {:body {:contents (slurp (str example-dir "/" filename))}})

+(defn get-ns-name
+  [s]
+  (re-find #"(?<=\(ns\s)[a-zA-Z0-9\.-]+(?=[\s\(\)])" s))
+
 (defn compose
   [specification]
-  {:body (str (load-string specification))})
+  {:body (do
+           (load-string specification)
+           (get-ns-name specification))})

 (defroutes api-routes
   (GET "/api/examples" [] (example-listing))


texture keys can be anything

texture keys can be anything

--- src/cljs/infinitelives/pixi/resources.cljs
+++ src/cljs/infinitelives/pixi/resources.cljs
@@ -76,7 +76,7 @@

 (defn get-texture [key scale]
-  (scale (key @!textures)))
+  (scale (get @!textures key)))

 ;; setup a pixi texture keyed by the tail of its filename
 (defn- register-texture


small visual tweak in node list

small visual tweak in node list

--- src/cljs/swarmpit/component/node/list.cljs
+++ src/cljs/swarmpit/component/node/list.cljs
@@ -27,7 +27,8 @@
   [:div.node-item-states
    [:span.node-item-state (node-item-state (:state item))]
    (if (:leader item)
-     [:span.node-item-state (comp/label-blue "leader")])])
+     [:span.node-item-state (comp/label-blue "leader")])
+   [:span.node-item-state (comp/label-blue (:role item))]])

 (defn- node-item-header [item]
   [:div
@@ -45,11 +46,9 @@
      (node-item-header item)
      (node-item-states item)
      [:div
-      [:span "[ " (:role item) " ]"]]
+      [:span.node-item-secondary "ip: " (:address item)]]
      [:div
-      [:span.node-item-secondary "address: " (:address item)]]
-     [:div
-      [:span.node-item-secondary "engine: " (:engine item)]]
+      [:span.node-item-secondary "version: " (:engine item)]]
      [:div
       [:span.node-item-secondary "availability: " (:availability item)]]]))