Event handlers return info on the last vis delta.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -57,12 +57,14 @@
              (swap! vis #(-> %
                              (assoc-in [:actxs child-actx]
                                        {:children {} :wait-chs {}})
-                             (assoc-in [:actxs actx :children child-actx] true)))))
+                             (assoc-in [:actxs actx :children child-actx] true)))
+             [[:actx-appear child-actx]]))
     :end (fn [vis actx args]
            (let [[child-actx result] args]
              (swap! vis #(-> %
                              (dissoc-in [:actxs child-actx])
-                             (dissoc-in [:actxs actx :children child-actx])))))}
+                             (dissoc-in [:actxs actx :children child-actx])))
+             [[:actx-disappear child-actx]]))}
    "aclose"
    {:beg (fn [vis actx args]
            (let [[ch] args] nil))
@@ -73,39 +75,44 @@
            (let [[ch] args]
              (swap! vis #(-> %
                              (assoc-in [:actxs actx :wait-chs ch] :take)
-                             (vis-add-ch ch actx)))))
+                             (vis-add-ch ch actx)))
+             nil))
     :end (fn [vis actx args]
            (let [[ch msg] args]
              (swap! vis #(-> %
                              (dissoc-in [:actxs actx :wait-chs ch])
                              (dissoc-in [:chs ch :msgs msg])))
              (when (nil? msg) ; The ch is closed.
-               (swap! vis #(dissoc-in % [:chs ch])))))}
+               (swap! vis #(dissoc-in % [:chs ch])))
+             [[:msg-move msg :ch ch :actx actx]]))}
    "aput"
    {:beg (fn [vis actx args]
            (let [[ch msg] args]
              (swap! vis #(-> %
                              (assoc-in [:actxs actx :wait-chs ch] :put)
                              (vis-add-ch ch nil)
-                             (assoc-in [:chs ch :msgs msg] true)))))
+                             (assoc-in [:chs ch :msgs msg] true)))
+             [[:msg-move msg :actx actx :ch ch]]))
     :end (fn [vis actx args]
            (let [[ch msg result] args]
              (swap! vis #(-> %
                              (dissoc-in [:actxs actx :wait-chs ch])))
              ; NOTE: Normally we should cleanup ch when nil result but
              ; looks like CLJS async always incorrectly returns nil from >!.
-             ))}
+             nil))}
    "aalts"
    {:beg (fn [vis actx args]
            (let [[ch-bindings] args
                  ; The ch-actions will be [[ch :take] [ch :put] ...].
                  ch-actions (map #(if (seq? %) [(first %) :put] [% :take]) ch-bindings)]
-             (doseq [ch-action ch-actions]
-               (swap! vis #(-> %
-                               (vis-add-ch (first ch-action)
-                                           (if (= (second ch-action) :take) actx nil))
-                               (assoc-in [:actxs actx :wait-chs (first ch-action)]
-                                         (second ch-action)))))))
+             (apply concat ; NOTE: mapcat doesn't seem to work.
+                    (map (fn [ch-action]
+                           (let [[ch action] ch-action]
+                             (swap! vis #(-> %
+                                             (vis-add-ch ch (if (= action :take) actx nil))
+                                             (assoc-in [:actxs actx :wait-chs ch] action)))
+                             (when (= action :put) [[:msg-move msg :actx actx :ch ch]])))
+                         ch-actions))))
     :end (fn [vis actx args]
            (let [[ch-bindings result] args
                  chs (map #(if (seq? %) (first %) %) ch-bindings)
@@ -114,7 +121,8 @@
                (swap! vis #(dissoc-in % [:actxs actx :wait-chs ch])))
              (swap! vis #(dissoc-in % [:chs result-ch :msgs result-msg]))
              (when (nil? result-msg) ; The ch is closed.
-               (swap! vis #(dissoc-in % [:chs result-ch])))))}})
+               (swap! vis #(dissoc-in % [:chs result-ch])))
+             nil))}})

 ;; ------------------------------------------------


Identify request processing time for requests handled by the filter

--- src/main/clojure/cascade/filter.clj
+++ src/main/clojure/cascade/filter.clj
@@ -122,11 +122,14 @@
   (let [path (get-path request)
         qs (.getQueryString request)
         debug-path (if (nil? qs) path (str path "?" qs))
-        context @(.context this)]
+        context @(.context this)
+        start-time (System/currentTimeMillis)]
     (debug "Filtering %s" debug-path)
-    (when (or
+    (if (or
             (static-file? context path)
             (not (pass-to-dispatchers request response context path)))
       ; Let the servlet container process this normally.
-      (debug "Not handled; forwarding to next in chain")
-      (.doFilter chain request response))))+      (do
+        (debug "Not handled; forwarding to next in chain")
+        (.doFilter chain request response))
+      (debug "Request procesing time: %,d ms" (- (System/currentTimeMillis) start-time)))))


Added a few methods related to towns

Added a few methods related to towns

--- src/civs/model.clj
+++ src/civs/model.clj
@@ -130,6 +130,17 @@
         game (assoc game :towns towns)]
     {:game game :town new-town}))

+(defn get-tribe [game id]
+  (get (:tribes game) id))
+
+(defn get-town [game id]
+  (get (:towns game) id))
+
+(defn ghost-city? [game town-id]
+  (let [town (get-town game town-id)
+        owner (.owner town)
+        tribe (get-tribe game owner)]
+    (alive? tribe)))

 (defn update-tribe
   "Return the game, updated"
@@ -146,3 +157,9 @@

 (defn n-tribes-alive [game]
   (.size (filter alive? (:tribes game))))
+
+(defn towns [game]
+  (vals (.towns g)))
+
+(defn n-ghost-cities [game]
+  (.size (filter #(ghost-city? game (.id %)) (towns game))))


Add deref with timeout limiter

Add deref with timeout limiter

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -156,6 +156,14 @@
     (doseq [v values]
       (.add b (.bind s (into-array Object v))))
     b))
+
+(defn deref-limiter
+  "Deref with timeout limiter"
+  [f]
+  (let [result (deref f 300000 :timeout)]
+    (when (= result :timeout)
+      (throw (ex-info "Too long!" {})))
+    result))

 (defn par-fetch
   "Fetch data in parallel fashion."
@@ -174,7 +182,8 @@
                             (doall)
                             (seq)))
                     paths))]
-    (seq (into [] (r/remove nil? (r/reduce into [] (map deref futures)))))))
+    (seq (into [] (r/remove nil? (r/reduce into []
+                                           (map deref-limiter futures)))))))

 (defn cassandra-metric-store
   "Connect to cassandra and start a path fetching thread.


Show again the details

Show again the details

--- frontend/src/cruncher/views.cljs
+++ frontend/src/cruncher/views.cljs
@@ -109,7 +109,7 @@
               (dom/td nil (:individual_attack pokemon))
               (dom/td nil (:individual_defense pokemon))
               (dom/td nil (:individual_stamina pokemon))
-              #_(dom/td nil (dom/button #js {:className     "btn btn-sm btn-info"
+              (dom/td nil (dom/button #js {:className     "btn btn-sm btn-info"
                                            :type          "button"
                                            :data-toggle   "collapse"
                                            :data-target   (str "#poketable-row-details-" (:id pokemon))
@@ -139,7 +139,7 @@
                                            (vlib/sortable-table-header :individual_attack "IV Attack")
                                            (vlib/sortable-table-header :individual_defense "IV Defense")
                                            (vlib/sortable-table-header :individual_stamina "IV Stamina")
-                                           #_(dom/th nil "")))
+                                           (dom/th nil "")))
                         (dom/tbody nil
                                    (interleave
                                      (map #(poketable-entry (lib/merge-react-key %)) (lib/inventory-pokemon))


Problem 0129.

Problem 0129.

--- src/project_euler/problem_0129.clj
+++ src/project_euler/problem_0129.clj
@@ -1,5 +1,4 @@
-(ns project-euler.problem_0129
-  (:require [clojure.math.combinatorics :as combo]))
+(ns project-euler.problem_0129)

 ;; A number consisting entirely of ones is called a repunit.
 ;; We shall define R(k) to be a repunit of length k; for example, R(6) = 111111.
@@ -12,78 +11,19 @@

 ;; Find the least value of n for which A(n) first exceeds one-million.

-;; From problem 0010 :
-;; -------------------
-(defn prime?
-  [n]
-  {:pre [(integer? n) (> n 0)]}
-  (or (== 2 n)
-      (let [mmax (+ (Math/sqrt n) 1)]
-        (not (some #(== 0 (rem n %)) (concat [2] (range 3 mmax 2))))
-        )))
-;;------------------------------------------------------------------------
+(defn a [n]
+  (loop [r 1 k 1]
+    (let [r' (rem r n)]
+      (if (zero? r')
+        k
+        (recur (+ 1 (* 10 r')) (inc k))
+        ))))

-(defn prime-factors [x]
-  (letfn [(next-fact [n] (if (== n 2) 3 (+ n 2)))]
-    (loop [x x, p 2, pfs []]
-      (cond (== 1 x)          pfs
-            (> (* p p) x)     (conj pfs x)
-            (zero? (rem x p)) (recur (quot x p) p (conj pfs p))
-            :else             (recur x (next-fact p) pfs)
-            ))))
-
-(defn distinct-prime-factors [x]
-  (letfn [(next-fact [n] (if (== n 2) 3 (+ n 2)))]
-    (loop [x x, p 2, pfs #{}]
-      (cond (== 1 x)          pfs
-            (> (* p p) x)     (conj pfs x)
-            (zero? (rem x p)) (recur (quot x p) p (conj pfs p))
-            :else             (recur x (next-fact p) pfs)
-            ))))
-
-(defn totient [x]
-  (reduce (fn [prod p] (* prod (- 1 (/ p))))
-          x
-          (distinct-prime-factors x)))
-
-(defn pow [x n]
-  (loop [p 1 x x n n]
-    (if (zero? n)
-      p
-      (recur (if (odd? n)
-               (*' p x)
-               p)
-             (*' x x)
-             (quot n 2)
-             ))))
-
-(defn k [n]
-  (totient (* 9 n)))
-
-(defn repunit [n]
-  (/ (- (pow 10N n) 1) 9))
-
-(defn solution-for [n]
-  (->> (iterate inc (inc n))
-       (filter odd?)
-       (filter prime?)
-       ;;(take 50)
-       (map (fn [p]
-              [p
-               (->> (prime-factors (dec p))
-                    (combo/subsets)
-                    (next)
-                    (butlast)
-                    (map (fn [pf-ss] (reduce * pf-ss)))
-                    (some (fn [div] (zero? (rem (repunit div) p))))
-                    )]))
-       (filter (fn [[p div-ok]] (not div-ok)))
+(defn solution []
+  (->> (iterate #(+ % 2) 1000001)
+       (remove #(zero? (rem % 5)))
+       (map (fn [n] [n (a n)]))
+       (filter (fn [[n an]] (> an 1000000)))
+       (first)
        (first)
        ))
-
-(defn solution []
-  (->> (iterate inc 1)
-       (map (fn [n] [n (k n)]))
-       (filter (fn [[n k]] (> k 1000000)))
-       (first)
-       ))


Remove an old XXX comment

Remove an old XXX comment

--- src/re_frame/std_interceptors.cljc
+++ src/re_frame/std_interceptors.cljc
@@ -8,10 +8,6 @@
     [clojure.data :as data]
     [re-frame.cofx :as cofx]
     [re-frame.utils :as utils]))
-
-
-;; XXX provide a way to set what handler should be called when there is no registered handler.
-;;    by default this handler will simply print out a message saying no handler was found.

 (def debug


Sites.

Sites.

--- from-repl.clj
+++ from-repl.clj
@@ -24,3 +24,4 @@
 (render-site "AgileDevelopment/01_basic_testing")

 (render-site "WebServices/01_running_Flask")
+(render-site "WebServices/02_AJAX")


Fix  #2350: Added Italian translation for OpenBounty (#2357)

* Added Italian translation for OpenBounty, addresses #2350

* Fix #2350: riview from vigliag done

--- src/status_im/translations/it.cljs
+++ src/status_im/translations/it.cljs
@@ -2,49 +2,67 @@

 (def translations
   {
-   ;common
+   ;;common
    :members-title                         "Membri"
    :not-implemented                       "!non implementato"
    :chat-name                             "Nome della chat"
    :notifications-title                   "Notifiche e suoni"
    :offline                               "Offline"
-
-   ;drawer
-   :invite-friends                        "Invita amici"
-   :faq                                   "FAQ"
+   :search-for                            "Cercando..."
+   :cancel                                "Annulla"
+   :next                                  "Avanti"
+   :open                                  "Apri"
+   :description                           "Descrizione"
+   :url                                   "URL"
+   :type-a-message                        "Scrivi un messaggio..."
+   :type-a-command                        "Inizia a digitare un comando..."
+   :error                                 "Errore"
+   :unknown-status-go-error               "Errore status-go sconosciuto"
+   :node-unavailable                      "Nessun nodo ethereum disponibile"
+   :yes                                   "Sì"
+   :no                                    "No"
+
+   :camera-access-error                   "Per concedere i permessi necessari per la fotocamera, per favore vai nelle impostazioni di sistema e assicurati che la voce Status > Fotocamera sia selezionata."
+   :photos-access-error                   "Per concedere i permessi necessari per le foto, per favore vai nelle impostazioni di sistema e assicurati che la voce Status > Foto sia selezionata."
+
+   ;;drawer
    :switch-users                          "Cambia utente"
-
-   ;chat
+   :current-network                       "Rete corrente"
+
+   ;;chat
    :is-typing                             "sta scrivendo"
    :and-you                               "e tu"
    :search-chat                           "Cerca chat"
    :members                               {:one   "1 membro"
                                            :other "{{count}} membri"
                                            :zero  "nessun membro"}
-   :members-active                        {:one   "1 membro, 1 attivo"
-                                           :other "{{count}} membri, {{count}} attivi"
+   :members-active                        {:one   "1 membro"
+                                           :other "{{count}} membri"
                                            :zero  "nessun membro"}
+   :public-group-status                   "Pubblico"
    :active-online                         "Online"
    :active-unknown                        "Sconosciuto"
    :available                             "Disponibile"
    :no-messages                           "Nessun messaggio"
    :suggestions-requests                  "Richieste"
    :suggestions-commands                  "Comandi"
-
-   ;sync
+   :faucet-success                        "La richiesta al faucet è stata ricevuta"
+   :faucet-error                          "Errore durante la richiesta al faucet"
+
+   ;;sync
    :sync-in-progress                      "Sincronizzazione in corso..."
    :sync-synced                           "Sincronizzato"

-   ;messages
-   :status-sending                        "Invio"
-   :status-pending                        "In attesa di"
+   ;;messages
+   :status-pending                        "In attesa"
    :status-sent                           "Inviato"
    :status-seen-by-everyone               "Visto da tutti"
    :status-seen                           "Visto"
    :status-delivered                      "Consegnato"
    :status-failed                         "Fallito"

-   ;datetime
+   ;;datetime
+   :datetime-ago-format                   "{{number}} {{time-intervals}} {{ago}}"
    :datetime-second                       {:one   "secondo"
                                            :other "secondi"}
    :datetime-minute                       {:one   "minuto"
@@ -53,112 +71,148 @@
                                            :other "ore"}
    :datetime-day                          {:one   "giorno"
                                            :other "giorni"}
-   :datetime-multiple                     "s"
    :datetime-ago                          "fa"
    :datetime-yesterday                    "ieri"
    :datetime-today                        "oggi"

-   ;profile
+   ;;profile
    :profile                               "Profilo"
-   :report-user                           "SEGNALA UTENTE"
+   :edit-profile                          "Modifica profilo"
    :message                               "Messaggio"
-   :username                              "Nome dell'utente"
    :not-specified                         "Non specificato"
    :public-key                            "Chiave pubblica"
    :phone-number                          "Numero di telefono"
-   :email                                 "E-mail"
-   :profile-no-status                     "Nessuno stato"
+   :update-status                         "Aggiorna il tuo stato..."
+   :add-a-status                          "Aggiungi uno stato..."
+   :status-prompt                         "Imposta il tuo stato. L'utilizzo di #hastags aiuterà gli altri a scoprirti e a parlare di ciò che pensi"
    :add-to-contacts                       "Aggiungi ai contatti"
-   :error-incorrect-name                  "Seleziona un altro nome"
-   :error-incorrect-email                 "e-mail non valida"
+   :in-contacts                           "Nei contatti"
+   :remove-from-contacts                  "Rimuovi dai contatti"
+   :start-conversation                    "Inizia la conversazione"
+   :send-transaction                      "Invia una transazione"
+   :testnet-text                          "Sei in {{testnet}} Testnet. Non mandare ETH o SNT reali al tuo indirizzo"
+   :mainnet-text                          "Sei nella Mainnet. Verranno inviati ETH reali"

    ;;make_photo
    :image-source-title                    "Immagine del profilo"
-   :image-source-make-photo               "Catturare"
-   :image-source-gallery                  "Scegli dalla galleria"
-   :image-source-cancel                   "Elimina"
-
-   ;sign-up
+   :image-source-make-photo               "Cattura"
+   :image-source-gallery                  "Seleziona dalla galleria"
+
+   ;;sharing
+   :sharing-copy-to-clipboard             "Copia negli appunti"
+   :sharing-share                         "Condividi..."
+   :sharing-cancel                        "Annulla"
+
+   :browsing-title                        "Naviga"
+   :browsing-browse                       "@browse"
+   :browsing-open-in-web-browser          "Apri nel web browser"
+   :browsing-cancel                       "Annulla"
+
+   ;;sign-up
    :contacts-syncronized                  "I tuoi contatti sono stati sincronizzati"
-   :confirmation-code                     (str "Grazie! Ti abbiamo inviato un messaggio con un codice di conferma "
-                                               "codice. Fornisci questo codice per confermare il tuo numero di telefono")
-   :incorrect-code                        (str "Spiacenti, il codice era errato, reinseriscilo")
-   :generate-passphrase                   (str "Genereremo una passphrase da utilizzare per riattivare il tuo "
-                                               "accesso o accedere da un altro dispositivo")
-   :phew-here-is-your-passphrase          "*Uff* è stato difficile, ecco la tua passphrase, *scrivila e tienila al sicuro!* Ti servirà per poter accedere al tuo account."
-   :here-is-your-passphrase               "Questa è la tua passphrase, *scrivila e tienila al sicuro!* Ti servirà per poter accedere al tuo account."
-   :written-down                          "Assicurati di averla scritta e conservata"
-   :phone-number-required                 "Tocca qui per inserire il tuo numero di telefono e cercheremo i tuoi amici"
-   :intro-status                          "Fai una chat con me per impostare il tuo account e cambiare le tue impostazioni!"
-   :intro-message1                        "Benvenuto su Status\nTocca questo messaggio per impostare la tua password e poter cominciare!"
+   :confirmation-code                     (str "Grazie! Ti abbiamo inviato un sms con un codice "
+                                               "di conferma. Per favore inserisci quel codice per confermare il tuo numero di telefono")
+   :incorrect-code                        (str "Il codice era errato, riprova")
+   :phew-here-is-your-passphrase          "Fiù, è stato difficile. Ecco la tua passphrase, *scrivila e conservala al sicuro!* Ne avrai bisogno per recuperare il tuo account."
+   :here-is-your-passphrase               "Ecco la tua passphrase, *scrivila e conservala al sicuro!* Ne avrai bisogno per recuperare il tuo account."
+   :here-is-your-signing-phrase           "Ecco la tua signing phrase. La userai per verificare le tue transazioni. *Scrivila e conservala al sicuro!*"
+   :phone-number-required                 "Tocca qui per convalidare il tuo numero di telefono e troverò i tuoi amici."
+   :shake-your-phone                      "Hai trovato un bug o hai un suggerimento? Devi solo ~scuotere~ il tuo telefono!"
+   :intro-status                          "Chatta con me per inizializzare il tuo account e cambiare le tue impostazioni."
+   :intro-message1                        "Benvenuto in Status!\nTocca questo messaggio per impostare la tua password e cominciare."
    :account-generation-message            "Dammi un secondo, devo fare dei calcoli complicati per generare il tuo account!"
-
-   ;chats
+   :move-to-internal-failure-message      "Dobbiamo spostare alcuni file importanti dalla periferica di archiviazione esterna a quella interna. Per farlo, abbiamo bisogno del tuo permesso. Nelle versioni future non utilizzeremo periferiche di archiviazione esterne."
+   :debug-enabled                         "Il server di debug è stato lanciato! Adesso puoi eseguire *status-dev-cli scan* per trovare il server dal tuo computer nella tua stessa rete."
+
+   ;;phone types
+   :phone-e164                            "Internazionale 1"
+   :phone-international                   "Internazionale 2"
+   :phone-national                        "Nazionale"
+   :phone-significant                     "Rilevante"
+
+   ;;chats
    :chats                                 "Chat"
-   :new-chat                              "Nuova chat"
+   :delete-chat                           "Cancella chat"
    :new-group-chat                        "Nuova chat di gruppo"
-
-   ;discover
+   :new-public-group-chat                 "Entra nella chat pubblica"
+   :edit-chats                            "Modifica chat"
+   :search-chats                          "Cerca chat"
+   :empty-topic                           "Argomento vuoto"
+   :topic-format                          "Formato errato [a-z0-9\\-]+"
+   :public-group-topic                    "Argomento"
+
+   ;;discover
    :discover                              "Scopri"
    :none                                  "Nessuno"
-   :search-tags                           "Digita qui le tue etichette di ricerca"
-   :popular-tags                          "Tag popolari"
-   :recent                                "Recenti"
+   :search-tags                           "Digita qui i tuoi tag di ricerca"
+   :popular-tags                          "#hashtags popolari"
+   :recent                                "Stati recenti"
+   :no-statuses-found                     "Nessuno stato trovato"
+   :chat                                  "Chat"
+   :all                                   "Tutte"
+   :public-chats                          "Chat pubbliche"
+   :soon                                  "Presto"
+   :public-chat-user-count                "{{count}} persone"
+   :dapps                                 "ÐApps"
+   :dapp-profile                          "Profilo ÐApp"
    :no-statuses-discovered                "Nessuno stato trovato"
-
-   ;settings
+   :no-statuses-discovered-body           "Quando qualcuno posta\nuno stato lo vedrai qui."
+   :no-hashtags-discovered-title          "Nessun #hashtags trovato"
+   :no-hashtags-discovered-body           "Quando un #hashtag diventa\npopolare lo vedrai qui."
+
+   ;;settings
    :settings                              "Impostazioni"

-   ;contacts
+   ;;contacts
    :contacts                              "Contatti"
    :new-contact                           "Nuovo contatto"
-   :show-all                              "Mostra tutti"
-   :contacts-group-dapps                  "ÐApps"
-   :contacts-group-people                 "Persone"
-   :contacts-group-new-chat               "Comincia una nuova chat"
+   :delete-contact                        "Elimina contatto"
+   :delete-contact-confirmation           "Questo contatto sarà eliminato dai tuoi contatti"
+   :remove-from-group                     "Rimuovi dal gruppo"
+   :edit-contacts                         "Modifica contatto"
+   :search-contacts                       "Cerca contatti"
+   :contacts-group-new-chat               "Inizia una nuova chat"
+   :choose-from-contacts                  "Scegli dai contatti"
    :no-contacts                           "Ancora nessun contatto"
    :show-qr                               "Mostra QR"
-
-   ;group-settings
+   :enter-address                         "Inserisci indirizzo"
+   :more                                  "ancora"
+
+   ;;group-settings
    :remove                                "Rimuovi"
    :save                                  "Salva"
-   :change-color                          "Cambia colore"
+   :delete                                "Cancella"
    :clear-history                         "Cancella cronologia"
-   :delete-and-leave                      "Elimina e lascia"
-   :chat-settings                         "Impostazioni chat"
+   :mute-notifications                    "Silenzia notifiche"
+   :leave-chat                            "Lascia la chat"
+   :chat-settings                         "Impostazioni della chat"
    :edit                                  "Modifica"
    :add-members                           "Aggiungi membri"
-   :blue                                  "Blu"
-   :purple                                "Viola"
-   :green                                 "Verde"
-   :red                                   "Rosso"
-
-   ;commands
-   :money-command-description             "Invia denaro"
-   :location-command-description          "Invia posizione"
-   :phone-command-description             "Invia numero di telefono"
-   :phone-request-text                    "Richiesta numero di telefono"
-   :confirmation-code-command-description "Invia codice di conferma"
-   :confirmation-code-request-text        "Codice di conferma richiesto"
-   :send-command-description              "Invia posizione"
-   :request-command-description           "Invia richiesta"
-   :keypair-password-command-description  ""
-   :help-command-description              "Aiuto"
-   :request                               "Richiesta"
+
+   ;;commands
    :chat-send-eth                         "{{amount}} ETH"
-   :chat-send-eth-to                      "{{amount}} ETH per {{chat-name}}"
-   :chat-send-eth-from                    "{{amount}} ETH da {{chat-name}}"
-
-   ;new-group
-   :group-chat-name                       "Nome chat"
-   :empty-group-chat-name                 "Inserisci un nome"
-   :illegal-group-chat-name               "Scegli un altro nome"
-
-   ;participants
-   :add-participants                      "Aggiungi partecipanti"
-   :remove-participants                   "Rimuovi partecipanti"
-
-   ;protocol
+
+   ;;location command
+   :your-current-location                 "La tua posizione corrente"
+   :places-nearby                         "Posti vicini"
+   :search-results                        "Cerca risultati"
+   :dropped-pin                           "Pin posizionato"
+   :location                              "Posizione"
+   :open-map                              "Apri Mappa"
+   :sharing-copy-to-clipboard-address     "Copia l'Indirizzo"
+   :sharing-copy-to-clipboard-coordinates "Copia coordinate"
+
+   ;;new-group
+   :new-group                             "Nuovo gruppo"
+   :reorder-groups                        "Riordina gruppi"
+   :edit-group                            "Modifica gruppo"
+   :delete-group                          "Elimina gruppo"
+   :delete-group-confirmation             "Questo gruppo sarà cancellato dai tuoi gruppi. Questo non intaccherà i tuoi contatti"
+   :delete-group-prompt                   "Questo non intaccherà i tuoi contatti"
+   :contact-s                             {:one   "contatto"
+                                           :other "contatti"}
+
+   ;;protocol
    :received-invitation                   "invito alla chat ricevuto"
    :removed-from-chat                     "sei stato rimosso dalla chat di gruppo"
    :left                                  "lasciato"
@@ -166,140 +220,146 @@
    :removed                               "rimosso"
    :You                                   "Tu"

-   ;new-contact
-   :add-new-contact                       "Aggiungi un nuovo contatto"
-   :import-qr                             "Importa"
-   :scan-qr                               "Scansiona codice QR"
+   ;;new-contact
+   :add-new-contact                       "Aggiungi nuovo contatto"
+   :scan-qr                               "Scansiona QR"
    :name                                  "Nome"
-   :whisper-identity                      "Sussurra identità"
-   :address-explication                   "Forse qui bisognerebbe inserire un testo che spieghi cos'è un indirizzo e dove cercarlo"
-   :enter-valid-address                   "Inserisci un indirizzo valido o scansiona un codice QR"
-   :contact-already-added                 "Il contatto è stato già aggiunto"
+   :address-explication                   "La tua chiave privata è usata per generare il tuo indirizzo su Ethereum ed è una serie di numeri e lettere. Puoi trovarla facilmente nel tuo profilo"
+   :enter-valid-public-key                "Per favore inserisci una chiave pubblica valida o scansiona un QR"
+   :contact-already-added                 "Il contatto è già stato aggiunto"
    :can-not-add-yourself                  "Non puoi aggiungere te stesso"
    :unknown-address                       "Indirizzo sconosciuto"

-
-   ;login
-   :connect                               "Connettiti"
+   ;;login
+   :connect                               "Connetti"
    :address                               "Indirizzo"
    :password                              "Password"
-   :login                                 "Accedi"
-   :wrong-password                        "Password errata"
-
-   ;recover
-   :recover-from-passphrase               "Recupera l'account usando la passphrase"
-   :recover-explain                       "Inserisci la passphrase per poter accedere alla tua password"
+   :sign-in-to-status                     "Accedi a Status"
+   :sign-in                               "Accedi"
+   :wrong-password                        "Password sbagliata"
+   :enter-password                        "Inserisci la password"
+
+   ;;recover
    :passphrase                            "Passphrase"
    :recover                               "Recupera"
-   :enter-valid-passphrase                "Inserisci una passphrase"
-   :enter-valid-password                  "Inserisci una password"
-
-   ;accounts
-   :recover-access                        "Recupera accessi"
-   :add-account                           "Aggiungi account"
-
-   ;wallet-qr-code
+   :twelve-words-in-correct-order         "12 parole nell'ordine corretto"
+
+   ;;accounts
+   :recover-access                        "Recupera accesso"
+   :create-new-account                    "Crea un nuovo account"
+
+   ;;wallet-qr-code
    :done                                  "Fatto"
-   :main-wallet                           "Portafogli principale"
-
-   ;validation
-   :invalid-phone                         "Numero di telefono non valido"
-   :amount                                "Ammontare"
-   :not-enough-eth                        (str "Non hai abbastanza ETH "
-                                               "({{balance}} ETH)")
-   ;transactions
-   :confirm-transactions                  {:one   "Conferma transazione"
-                                           :other "Conferma {{count}} transazioni"
-                                           :zero  "Nessuna transazione"}
+
+   ;;validation
+   :invalid-phone                         "Numero di telefono invalido"
+   :amount                                "Quantità"
+
+   ;;transactions
+   :confirm                               "Conferma"
+   :transaction                           "Transazione"
+   :unsigned-transaction-expired          "Transazione non firmata scaduta"
    :status                                "Stato"
-   :pending-confirmation                  "Conferma in attesa"
    :recipient                             "Ricevente"
-   :one-more-item                         "Un altro oggetto"
-   :fee                                   "Commissione"
-   :value                                 "Valore"
-
-   ;:webview
-   :web-view-error                        "ops, errore"
-
-   :confirm                               "Conferma"
-   :phone-national                        "Nazionale"
-   :transactions-confirmed                {:one   "Transazione confermata"
-                                           :other "{{count}} transazioni confermate"
-                                           :zero  "Nessuna transazione confermata"}
-   :public-group-topic                    "Argomento"
-   :debug-enabled                         "Il server di debug è stato avviato! Ora puoi aggiungere la tua DApp avviando *status-dev-cli scan* dal tuo computer"
-   :new-public-group-chat                 "Entra nella chat pubblica"
-   :datetime-ago-format                   "{{number}} {{time-intervals}} {{ago}}"
-   :sharing-cancel                        "Annulla"
-   :share-qr                              "Condividi QR"
-   :feedback                              "Hai suggerimenti?\nScuoti il tuo telefono!"
-   :twelve-words-in-correct-order         "12 parole nel corretto ordine"
-   :remove-from-contacts                  "Rimuovi dai contatti"
-   :delete-chat                           "Elimina chat"
-   :edit-chats                            "Modifica chat"
-   :sign-in                               "Accedi"
-   :create-new-account                    "Crea nuovo account"
-   :sign-in-to-status                     "Accedi a Stato"
+   :to                                    "A"
+   :from                                  "Da"
+   :data                                  "Dati"
    :got-it                                "Ho capito"
-   :move-to-internal-failure-message      "Dobbiamo spostare alcuni file importanti dalla periferica di archiviazione esterna a quella interna. Per farlo, abbiamo bisogno del tuo permesso. Nelle versioni future non utilizzeremo periferiche di archiviazione esterna."
-   :edit-group                            "Modifica gruppo"
-   :delete-group                          "Elimina gruppo"
-   :browsing-title                        "Sfoglia"
-   :reorder-groups                        "Riordina gruppi"
-   :browsing-cancel                       "Annulla"
-   :faucet-success                        "La richiesta di Faucet è stata ricevuta"
-   :choose-from-contacts                  "Scegli dai contatti"
-   :new-group                             "Nuovo gruppo"
-   :phone-e164                            "Internazionale 1"
-   :remove-from-group                     "Rimuovi dal gruppo"
-   :search-contacts                       "Ricerca contatti"
-   :transaction                           "Transazione"
-   :public-group-status                   "Pubblica"
-   :leave-chat                            "Abbandona chat"
-   :start-conversation                    "Avvia conversazione"
-   :topic-format                          "Formato errato [a-z0-9\\-]+"
-   :enter-valid-public-key                "Inserisci una chiave pubblica valida o scansiona un codice QR"
-   :faucet-error                          "Errore durante richiesta di Faucet"
-   :phone-significant                     "Rilevante"
-   :search-for                            "Ricerca per..."
-   :sharing-copy-to-clipboard             "Copia su clipboard"
-   :phone-international                   "Internazionale 2"
-   :enter-address                         "Inserisci indirizzo"
-   :send-transaction                      "Invia transazione"
-   :delete-contact                        "Elimina contatto"
-   :mute-notifications                    "Disattiva suoni notifiche"
-
-
-   :contact-s                             {:one   "contatto"
-                                           :other "contatti"}
-   :group-name                            "Nome gruppo"
-   :next                                  "Avanti"
-   :from                                  "Da"
-   :search-chats                          "Ricerca chat"
-   :in-contacts                           "Nei contatti"
-
-   :sharing-share                         "Condividi..."
-   :type-a-message                        "Scrivi un messaggio..."
-   :type-a-command                        "Inizia a scrivere un messaggio..."
-   :shake-your-phone                      "Hai trovato un bug o hai un suggerimento? Devi solo ~scuotere~ il tuo telefono!"
-   :status-prompt                         "Crea uno stato per aiutare le persone a sapere cosa stai offrendo. Puoi usare anche gli #hashtag."
-   :add-a-status                          "Aggiungi uno stato..."
-   :error                                 "Errore"
-   :edit-contacts                         "Modifica contatti"
-   :more                                  "altro"
-   :cancel                                "Annulla"
-   :no-statuses-found                     "Nessuno stato trovato"
-   :swow-qr                               "Mostra QR"
-   :browsing-open-in-web-browser          "Apri nel browser web"
-   :delete-group-prompt                   "Ciò non avrà effetto sui contatti"
-   :edit-profile                          "Modifica profilo"
-
-
-   :enter-password-transactions           {:one   "Conferma la transazione digitando la tua password"
-                                           :other "Conferma le transazioni digitando la tua password"}
-   :unsigned-transactions                 "Transazioni non firmate"
-   :empty-topic                           "Argomento vuoto"
-   :to                                    "A"
-   :group-members                         "Membri del gruppo"
-   :estimated-fee                         "Tariffa stimata"
-   :data                                  "Dati"})
+   :block                                 "Blocco"
+   :hash                                  "Hash"
+   :gas-limit                             "Gas limit"
+   :gas-price                             "Gas price"
+   :gas-used                              "Gas usato"
+   :cost-fee                              "Costo/Fee"
+   :nonce                                 "Nonce"
+   :confirmations                         "Conferme"
+   :confirmations-helper-text             "Per favore aspetta almeno 12 conferme per essere sicuro che la tua transazione sia stata processata in sicurezza"
+   :copy-transaction-hash                 "Copia l'hash della transazione"
+   :open-on-etherscan                     "Apri su Etherscan.io"
+
+   ;;webview
+   :web-view-error                        "oops, errore"
+
+   ;;testfairy warning
+   :testfairy-title                       "Attenzione!"
+   :testfairy-message                     "Stai usando un app installata da una build nightly. Per scopi di testing questa build include sessioni di registrazione se è usata la connessione wifi, così tutte le tue interazioni con l'app sono salvate (sia video che log) e possono essere usate dal nostro team di sviluppo per investigare possibili problemi. I video/log salvati non includono le tue password. La registrazione è fatta solo se l'app è installata da una build nightly. Niente viene registrato se l'app è installata dal PlayStore o da TestFlight."
+
+   ;; wallet
+   :wallet                                "Portafoglio"
+   :wallets                               "Portafogli"
+   :your-wallets                          "I tuoi Portafogli"
+   :main-wallet                           "Portafoglio principale"
+   :wallet-error                          "Errore durante il caricamento dei dati"
+   :wallet-send                           "Invia"
+   :wallet-request                        "Richiedi"
+   :wallet-exchange                       "Scambia"
+   :wallet-assets                         "Assets"
+   :wallet-add-asset                      "Aggiungi asset"
+   :wallet-total-value                    "Valore totale"
+   :wallet-settings                       "Impostazioni del portafoglio"
+   :signing-phrase-description            "Firma la transazione inserendo la tua password. Assicurati che le parole sopra corrispondano alla tua signing phrase segreta"
+   :wallet-insufficient-funds             "Fondi insufficienti"
+   :request-transaction                   "Richiesta di transazione"
+   :send-request                          "Invia richiesta"
+   :share                                 "Condividi"
+   :eth                                   "ETH"
+   :currency                              "Valuta"
+   :usd-currency                          "USD"
+   :transactions                          "Transazioni"
+   :transaction-details                   "Dettagli della transazione"
+   :transaction-failed                    "Transazione fallita"
+   :transactions-sign                     "Firma"
+   :transactions-sign-all                 "Firma tutto"
+   :transactions-sign-transaction         "Firma transazione"
+   :transactions-sign-later               "Firma dopo"
+   :transactions-delete                   "Elimina transazione"
+   :transactions-delete-content           "La transazione sarà rimossa dalla lista delle tranzazioni 'Non Firmate'"
+   :transactions-history                  "Cronologia"
+   :transactions-unsigned                 "Non Firmate"
+   :transactions-history-empty            "Non hai ancora nessuna transazione nella cronologia"
+   :transactions-unsigned-empty           "Non hai nessuna transazione non firmata"
+   :transactions-filter-title             "Filtra cronologia"
+   :transactions-filter-tokens            "Tokens"
+   :transactions-filter-type              "Tipo"
+   :transactions-filter-select-all        "Seleziona tutte"
+   :view-transaction-details              "Vedi i dettagli della transazione"
+   :transaction-description               "Per favore aspetta almeno 12 conferme per essere sicuro che la tua transazione sia stata processata in sicurezza"
+   :transaction-sent                      "Transazione inviata"
+   :transaction-moved-text                "La transazione rimarrà nella lista delle transazioni 'Non Firmate' per i prossimi 5 minuti"
+   :transaction-moved-title               "Transazione spostata"
+   :sign-later-title                      "Firmare la transazione dopo?"
+   :sign-later-text                       "Controlla la cronologia delle transazioni per firmare questa transazione"
+   :not-applicable                        "Non applicabile alle transazioni non firmate"
+
+   ;; Wallet Send
+   :wallet-choose-recipient               "Scegli destinatario"
+   :wallet-choose-from-contacts           "Scegli Dai Contatti"
+   :wallet-address-from-clipboard         "Usa Indirizzo Dagli Appunti"
+   :wallet-invalid-address                "Indirizzo non valido: \n {{data}}"
+   :wallet-browse-photos                  "Sfoglia Foto"
+   :validation-amount-invalid-number      "La Quantità è un numero invalido"
+   :validation-amount-is-too-precise      "L'ammontare è troppo preciso. La più piccola unità che puoi inviare è 1 Wei (1x10^-18 ETH)"
+
+
+
+   ;; network settings
+   :new-network                           "Nuova rete"
+   :add-network                           "Aggiungi rete"
+   :add-new-network                       "Aggiungi nuova rete"
+   :existing-networks                     "Reti esistenti"
+   :add-json-file                         "Aggiugni un file JSON"
+   :paste-json-as-text                    "Incolla JSON come testo"
+   :paste-json                            "Incolla JSON"
+   :specify-rpc-url                       "Specifica un URL RPC"
+   :edit-network-config                   "Modifica configurazioni di rete"
+   :connected                             "Connesso"
+   :process-json                          "Processa JSON"
+   :error-processing-json                 "Errore nel processamento del JSON"
+   :rpc-url                               "URL RPC"
+   :remove-network                        "Rimuovi rete"
+   :network-settings                      "Impostazioni di rete"
+   :edit-network-warning                  "Attenzione, modificando i dettagli di questa rete potresti disabilitarla per te"
+   :connecting-requires-login             "La connessione ad un'altra rete richiede il login"
+   :close-app-title                       "Attenzione!"
+   :close-app-content                     "L'app si fermerà e si chiuderà. Quando la riaprirai, verrà utilizzata la rete selezionata"
+   :close-app-button                      "Conferma"})


Add scenario async-pipeline-go.

Add scenario async-pipeline-go.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -172,7 +172,8 @@
                      (and
                        (not (nil? in-data))
                        (not (.endsWith scenario "-direct"))
-                       (not (.endsWith scenario "-pmap")))
+                       (not (.endsWith scenario "-pmap"))
+                       (not (.contains scenario "async-pipeline")))
                      (create-local-processing-pipeline
                        @proc-fns
                        (fn [_ _]
@@ -221,10 +222,14 @@
                                 (async/>!! in-chan data)))))
                       (and
                         (not (nil? in-data))
+                        (not (nil? pipeline))
                         (> batch-delay 0)
                         (> batch-size 0)) (create-batched-in-fn (get-in-fn pipeline))
-                      (not (nil? in-data)) (create-flood-in-fn (get-in-fn pipeline))
-                      :default (fn [] (.inc out-cntr))))
+                      (and
+                        (not (nil? in-data))
+                        (not (nil? pipeline))) (create-flood-in-fn (get-in-fn pipeline))
+                      :default (if (not (.contains scenario "async-pipeline"))
+                                 (fn [] (.inc out-cntr)))))
           async-out-count-loop (if
                                  (and
                                    (.endsWith scenario "-async-pipeline")
@@ -232,13 +237,20 @@
                                  (ProcessingLoop.
                                    "AsyncOutputCountLoop"
                                    (fn []
-                                     (while true
-                                       (do
-                                         (async/<!! out-chan)
-                                         (.inc out-cntr))))))
+                                     (async/<!! out-chan)
+                                     (.inc out-cntr))))
+          async-count-channel (if
+                                (and
+                                  (.endsWith scenario "-async-pipeline-go")
+                                  (not (nil? in-data)))
+                                (async/go
+                                  (loop []
+                                    (async/<! out-chan)
+                                    (.inc out-cntr)
+                                    (recur))))
           async-pipeline (if
                            (and
-                             (.endsWith scenario "-async-pipeline")
+                             (.contains scenario "-async-pipeline")
                              (not (nil? in-data)))
                            (async/pipeline
                              8
@@ -278,10 +290,6 @@
                              (update-stats self-adaptivity-controller counts))))))]
       (println "Starting experiment...")
       (.setName (Thread/currentThread) "Main")
-      (.start in-loop)
-      (if
-        (not (nil? async-out-count-loop))
-        (.start async-out-count-loop))
       (run-repeat
         (executor)
         (fn []
@@ -291,5 +299,17 @@
         1000)
       (run-once
         (executor)
-        (fn [] (System/exit 0)) 120000))))
-
+        (fn [] (System/exit 0)) 120000)
+      (if (.endsWith scenario "-async-pipeline-go")
+        (do
+          (async/go
+            (loop []
+              (async/>! in-chan in-data)
+              (.inc in-cntr)
+              (recur)))
+          (sleep 130000))
+        (.start in-loop))
+      (if
+        (not (nil? async-out-count-loop))
+        (.start async-out-count-loop)))))
+


Add more experiment scenarios.

Add more experiment scenarios.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -32,6 +32,8 @@
                  (.inc out-cntr))
         in-data 1
         proc-fns [(fn [i _] i)]
+        ;proc-fns [(fn [i _] i)(fn [_ o] o)]
+        ;proc-fns [(fn [i _] i)(fn [_ o] o)(fn [_ o] o)]
         ;proc-fns [(fn [i _] (inc i)) (fn [_ o] (inc o))]
         pipeline (create-local-processing-pipeline
                    proc-fns


increase max-cmts to 1500

increase max-cmts to 1500

--- src/polismath/math/conversation.clj
+++ src/polismath/math/conversation.clj
@@ -144,7 +144,7 @@
                           :group-iters 10
                           ;; These three in particular we should be able to tune quickly
                           :max-ptpts 100000
-                          :max-cmts 1000
+                          :max-cmts 1500
                           :group-k-buffer 4}
                     opts))


Fix error

Fix error

--- src/whisper2cyanite/path_store.clj
+++ src/whisper2cyanite/path_store.clj
@@ -40,7 +40,7 @@
         update-fn (partial esrd/put conn index es-def-type)]
     (log/info (str "The path store has been created. "
                    "URL: " url ", "
-                   "index: " index)
+                   "index: " index))
     (when-not (esri/exists? conn index)
       (log/info "Creating the path index...")
       (esri/create conn index :mappings es-type-map)


Replace Exception with ExceptionInfo

Replace Exception with ExceptionInfo


Update email address

Update email address

--- src/servisne_info/notifications.clj
+++ src/servisne_info/notifications.clj
@@ -4,7 +4,7 @@
             [servisne-info.logging :as l]
             [servisne-info.views.email :as email]))

-(def default-from "nebojsa.stricevic+servisne@gmail.com")
+(def default-from "info@servisne.info")

 (defn send-email
   [to subject body]


Release ring-analytics 0.2.0

Release ring-analytics 0.2.0

--- systems/ring-analytics/project.clj
+++ systems/ring-analytics/project.clj
@@ -2,7 +2,7 @@
 ;; License, v. 2.0. If a copy of the MPL was not distributed with this
 ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.

-(defproject containium.systems/ring-analytics "0.1.0"
+(defproject containium.systems/ring-analytics "0.2.0"
   :description "Ring requests and responses stored in ElasticSearch for use with Kibana"
   :url "http://containium.org"
   :scm {:dir "../../"}


Fixed issue #368.

Fixed issue #368.

--- src/wombats/components/pedestal.clj
+++ src/wombats/components/pedestal.clj
@@ -15,11 +15,11 @@
 ;; Private helper functions

 (defn- allowed-origin?
+  "When the origin is nil, that means you've navigated to the
+  API itself (which should always be allowed)"
   [origin]
-  ;; TODO: #368 Remove this once we do some testing
-  (log/info origin)
   (if origin
-    (some? (re-find #"^$|\.wombats\.io$|\/\/wombats\.io$" origin))
+    (some? (re-find #"\.wombats\.io$|\/\/wombats\.io$" origin))
     true))

 (defn- create-service-map
@@ -32,8 +32,8 @@
     {::env env
      ::http/resource-path "/public"
      ::http/file-path "/public"
-     ::http/allowed-origins (if (contains? #{:dev} env) ;; TODO: #368 Add back :dev-ddb once we do testing
-                              (fn [origin] true)
+     ::http/allowed-origins (if (contains? #{:dev :dev-ddb} env)
+                              (fn [_] true)
                               allowed-origin?)
      ::http/routes api-routes
      ::http/port port


added param wrappers to route handler

added param wrappers to route handler

--- resources/leiningen/new/enslin/routes.clj
+++ resources/leiningen/new/enslin/routes.clj
@@ -3,6 +3,8 @@
             [compojure.core :refer [defroutes GET POST]]
             [compojure.route :refer [not-found resources]]
             [ring.middleware.json :refer [wrap-json-response]]
+            [ring.middleware.keyword-params :refer [wrap-keyword-params]]
+            [ring.middleware.params :refer [wrap-params]]
             [stencil.core :refer [render-file]]))

 (defroutes handler
@@ -11,4 +13,4 @@
   (GET "/hello/:n" [n] (println "Hello, world!:" n)))

 (defroutes app
-  (wrap-json-response handler))
+  (-> handler wrap-keyword-params wrap-params wrap-json-response))


Import missing symbols in tests.

Import missing symbols in tests.

--- test/active/clojure/monad_test.cljc
+++ test/active/clojure/monad_test.cljc
@@ -10,6 +10,7 @@
                                                    get-state put-state!
                                                    get-env get-env-component with-env-component with-env
                                                    and-finally bind-except sequ sequ_
+                                                   reduce-m scan-m
                                                    make-exception-value exception-value?
                                                    unknown-command unknown-command?
                                                    make-monad-command-config
@@ -240,17 +241,17 @@
            (run-free-reader-state-exception (null-monad-command-config nil nil)
                                             (sequ_ (repeat 20000 (return "hello"))))))))

+(defn sum-m
+  [a b]
+  (return (+ a b)))
+
 (deftest reduce-m-test
-  (letfn [(sum-m [a b]
-            (return (+ a b)))]
-    (is (= [6 nil] (run-free-reader-state-exception (null-monad-command-config nil nil)
-                                                    (reduce-m sum-m 0 [1 2 3]))))))
-
-(deftest reduce-m-test
-  (letfn [(sum-m [a b]
-            (return (+ a b)))]
-    (is (= [(list 0 1 3 6) nil] (run-free-reader-state-exception (null-monad-command-config nil nil)
-                                                                 (scan-m sum-m 0 [1 2 3]))))))
+  (is (= [6 nil] (run-free-reader-state-exception (null-monad-command-config nil nil)
+                                                  (reduce-m sum-m 0 [1 2 3])))))
+
+(deftest scan-m-test
+  (is (= [(list 0 1 3 6) nil] (run-free-reader-state-exception (null-monad-command-config nil nil)
+                                                               (scan-m sum-m 0 [1 2 3])))))

 (deftest frse-trivial
   (is (= ["Hola" nil]


factored implicit types handling, lemma support

--- src/latte/core.clj
+++ src/latte/core.clj
@@ -65,10 +65,10 @@
 ;; The `definition` macro is defined below.
 ;;}

+(declare gen-type-parameters-defimplicit)
 (declare handle-term-definition)
 (declare mk-def-doc)
 (declare defimplicit)
-(declare gen-type-parameters-defimplicit)

 (defmacro definition
   "Defines a mathematical term with the following structure:
@@ -124,6 +124,28 @@
                  [:defined :term (quote ~def-name)]))))))))

 ;;{
+;; The next function implements the support of *implicit type parameters*.
+;;}
+
+(declare gen-type-parameters-defimplicit)
+
+(defn ^:no-doc def-kind-infos [def-kind]
+  (case def-kind
+    definition ["Definition" :definition]
+    defthm ["Theorem" :theorem]
+    deflemma ["Lemma" :lemma]
+    (throw (ex-info "Definition kind not supported." {:def-kind def-kind}))))
+
+(defn ^:no-doc handle-implicit-type-parameters
+  [def-kind def-name doc params body implicit-types explicit-def-name explicit-params]
+  (let [[def-kind-name def-kind-kw] (def-kind-infos def-kind)]
+    `(do
+       (~def-kind ^:no-doc ~explicit-def-name ~(str "This is an explicit variant of [[" def-name "]].") ~explicit-params ~body)
+       ~(gen-type-parameters-defimplicit def-name def-kind-name doc explicit-def-name implicit-types params explicit-params body)
+       (alter-meta! (var ~def-name) update-in [:arglists] (fn [_#] (list (quote ~params))))
+       [:declared ~def-kind-kw (quote ~explicit-def-name) :implicit (quote ~def-name)])))
+
+;;{
 ;; The following function generates a `defimplicit` form that (if successful) synthesizes
 ;; the arguments for implicit type parameters.
 ;; An exception is raised if the synthesis fails (which means no implicity-type-parameter handler
@@ -401,12 +423,18 @@
   Otherwise the two forms are the same."
   [& args]
   (let [{thm-name :name doc :doc params :params body :body}
-        (conform-statement :lemma args)
-        [status result] (handle-statement :lemma thm-name params body)]
-    (if (= status :ko)
-      (throw (ex-info "Cannot declare lemma." result))
-      (let [metadata (statement-metadata :lemma doc params body)]
-        (define-statement! :lemma thm-name result metadata)))))
+        (conform-statement :lemma args)]
+    (if-let [res (u/fetch-implicit-type-parameters params)]
+      (handle-implicit-type-parameters 'deflemma thm-name doc params body
+                                       (:implicit-types res)
+                                       (symbol (str thm-name) "-thm")
+                                       (:new-params res))
+      ;; no implicit type parameters
+      (let [[status result] (handle-statement :lemma thm-name params body)]
+        (if (= status :ko)
+          (throw (ex-info "Cannot declare lemma." result))
+          (let [metadata (statement-metadata :lemma doc params body)]
+            (define-statement! :lemma thm-name result metadata)))))))

 ;;{
 ;; ### Axioms


added lambda, product and open variables.

--- src/latte/term.clj
+++ src/latte/term.clj
@@ -9,7 +9,8 @@
 ;;}

 (ns latte.term
-  (:require [latte.utils :refer [example append]]
+  (:require [clojure.set]
+            [latte.utils :refer [example append]]
             [latte.alist :as alist :refer [acons vassoc]]
             [latte.termparser :as parser :refer [parse]]))

@@ -28,7 +29,15 @@
     [expr]
     "Produce a `parsable` clojure expression from `expr`
  in optional lexical environement `env`."))
-
+
+
+(defprotocol FreeVars
+  "A protocol for fetching the set of free variables."
+  (free-vars
+   [expr kind]
+   "Return a set of the free variables of `expr` according
+to their kind: :product, :forall or :open."))
+
 ;;{
 ;;
 ;; ## Lambda-terms
@@ -92,10 +101,14 @@
 (extend-type Univ
   Unparser
   (unparse
-    [u] (list (symbol "univ") (:level u))))
-
+      [u] (list (symbol "univ") (:level u)))
+  FreeVars
+  (free-vars
+   [_ _] #{}))

 (example (unparse (mk-univ 2)) => '(univ 2))
+
+(example (free-vars (mk-univ 2) :forall) => #{})

 ;;{

@@ -154,7 +167,10 @@
            rator (if (instance? Application (:rator app)) urator (list urator))
            urand (unparse (:rand app))
            rand (if (instance? Application (:rand app)) urand (list urand))]
-       (append rator rand))))
+       (append rator rand)))
+  FreeVars
+  (free-vars
+      [app kind] (clojure.set/union (free-vars (:rator app) kind) (free-vars (:rand app) kind))))

 (example (unparse (parse '((univ 1) (univ 2))))
          => '((univ 1) (univ 2)))
@@ -165,6 +181,7 @@
 (example (unparse (parse '(((univ 1) (univ 2)) ((univ 3) (univ 4)))))
          => '((univ 1) (univ 2) (univ 3) (univ 4)))

+(example (free-vars (parse '((univ 1) (univ 2) (univ 3))) :forall) => #{})

 ;;{

@@ -194,7 +211,7 @@
            (parser/parse-list-check-arity expr 2)
            (let [[var etype] (second expr)
                  type (parse etype env)
-                 body (parse (nth expr 2) (acons var 'lambda env))]
+                 body (parse (nth expr 2) (acons var :lambda env))]
              (if (not (symbol? var))
                (throw (Exception. (str "Abstraction variable is not a symbol: " var))))
              (mk-abstraction var type body))))
@@ -215,11 +232,18 @@
   (unparse
     [e]
      (list 'lambda [(:var e) (unparse (:type e))]
-           (unparse (:body e)))))
+           (unparse (:body e))))
+  FreeVars
+  (free-vars
+   [e kind] (clojure.set/union
+             (free-vars (:type e) kind)
+             (disj (free-vars (:body e) kind) (:var e)))))

 (example (unparse (parse '(lambda [x (univ 1)] (univ 2))))
          => '(lambda [x (univ 1)] (univ 2)))

+(example (free-vars (parse '(lambda [x (univ 1)] (univ 2))) :lambda)
+         => #{})

 ;;{

@@ -250,7 +274,7 @@
            (parser/parse-list-check-arity expr 2)
            (let [[var etype] (second expr)
                  type (parse etype env)
-                 body (parse (nth expr 2) (acons var 'forall env))]
+                 body (parse (nth expr 2) (acons var :forall env))]
              (if (not (symbol? var))
                (throw (Exception. (str "Product variable is not a symbol: " var))))
              (mk-product var type body))))
@@ -266,16 +290,41 @@
            (catch Exception e (.getMessage e)))
          => "Product variable is not a symbol: 1")

+(defonce implication-fake-variable (gensym))
+
+(parser/register-term-list-parser
+ '=> (fn [expr env]
+       (parser/parse-list-check-arity expr 2)
+       (let [type (parse (second expr) env)
+             body (parse (nth expr 2) env)]
+         (mk-product implication-fake-variable type body))))
+
+(example (:var (parse '(=> (univ 2) (univ 1)))) => implication-fake-variable)
+
+(example (:type (parse '(forall [x (univ 2)] (univ 1)))) => (mk-univ 2))
+
+(example (:body (parse '(forall [x (univ 2)] (univ 1)))) => (mk-univ 1))
+
 (extend-type Product
   Unparser
   (unparse
-    [e]
+   [e]
+   (if (= (:var e) implication-fake-variable)
+     (list '=> (unparse (:type e)) (unparse (:body e)))
      (list 'forall [(:var e) (unparse (:type e))]
            (unparse (:body e)))))
+  FreeVars
+  (free-vars
+      [e kind] (clojure.set/union
+                (free-vars (:type e) kind)
+                (disj (free-vars (:body e) kind) (:var e)))))

 (example (unparse (parse '(forall [x (univ 1)] (univ 2))))
          => '(forall [x (univ 1)] (univ 2)))
+
+(example (free-vars (parse '(forall [x (univ 1)] (univ 2))) :forall)
+         => #{})

 ;;{

@@ -318,30 +367,44 @@
           (and binding
                (= (second binding) kind)))))

+(defn- match-free-var?
+  [expr env]
+  (and (symbol? expr)
+       (not (alist/assoc expr env))))
+
 (defn- match-lambda-var?
   [expr env]
-  (match-bound-var? expr env 'lambda))
+  (match-bound-var? expr env :lambda))

 (parser/register-term-other-parser
  match-lambda-var?
  (fn [expr env]
    (mk-lambda-var expr)))

-(example (parse 'my-var (list ['my-var 'lambda]))
+(example (parse 'my-var (list ['my-var :lambda]))
          => (mk-lambda-var 'my-var))

 (example (parse '(lambda [x (univ 0)] x))
          => (mk-abstraction 'x (mk-univ 0) (mk-lambda-var 'x)))

-
 (extend-type LambdaVar
   Unparser
-  (unparse [e] (:name e)))
+  (unparse [e] (:name e))
+  FreeVars
+  (free-vars [e kind] (if (= kind :lambda)
+                        #{(:name e)}
+                        #{})))

 (example (unparse (mk-lambda-var 'my-var)) => 'my-var)

 (example (unparse (parse '(lambda [x (univ 0)] x)))
          => '(lambda [x (univ 0)] x))
+
+(example (free-vars (:body (parse '(lambda [x (univ 0)] x))) :lambda)
+         => #{'x})
+
+(example (free-vars (:body (parse '(lambda [x (univ 0)] x))) :forall)
+         => #{})

 ;;{

@@ -361,15 +424,14 @@

 (defn- match-product-var?
   [expr env]
-  (match-bound-var? expr env 'forall))
-
+  (match-bound-var? expr env :forall))

 (parser/register-term-other-parser
  match-product-var?
  (fn [expr env]
    (mk-product-var expr)))

-(example (parse 'my-var (list ['my-var 'forall]))
+(example (parse 'my-var (list ['my-var :forall]))
          => (mk-product-var 'my-var))

 (example (parse '(forall [x (univ 0)] x))
@@ -377,9 +439,78 @@

 (extend-type ProductVar
   Unparser
-  (unparse [e] (:name e)))
+  (unparse [e] (:name e))
+  FreeVars
+  (free-vars [e kind] (if (= kind :forall)
+                        #{(:name e)}
+                        #{})))

 (example (unparse (mk-product-var 'my-var)) => 'my-var)

 (example (unparse (parse '(forall [x (univ 0)] x)))
          => '(forall [x (univ 0)] x))
+
+
+(example (free-vars (:body (parse '(forall [x (univ 0)] x))) :forall)
+         => #{'x})
+
+(example (free-vars (:body (parse '(forall [x (univ 0)] x))) :lambda)
+         => #{})
+
+;;{
+
+;; #### Open variables
+
+;; Open variables are open to substitution and/or binding
+;; in some external environment.
+
+;;}
+
+(defrecord OpenVar [name])
+
+(defn mk-open-var
+  "Make the `name` variable free and open ."
+  [name]
+  (->OpenVar name))
+
+(example (:name (mk-open-var 'my-var))
+         => 'my-var)
+
+(defn- match-open-var?
+  [expr env]
+  (match-free-var? expr env))
+
+(parser/register-term-other-parser
+ match-open-var?
+ (fn [expr env]
+   (mk-open-var expr)))
+
+(example (parse 'my-var (list))
+         => (mk-open-var 'my-var))
+
+(example (= (parse '(forall [x (univ 0)] (x y)))
+            (mk-product 'x (mk-univ 0) (mk-application
+                                        (mk-product-var 'x)
+                                        (mk-open-var 'y))))
+         => true)
+
+(extend-type OpenVar
+  Unparser
+  (unparse [e] (:name e))
+  FreeVars
+  (free-vars [e kind] (if (= kind :open)
+                        #{(:name e)}
+                        #{})))
+
+(example (unparse (mk-open-var 'my-var)) => 'my-var)
+
+(example (unparse (parse '(forall [x (univ 0)] y)))
+         => '(forall [x (univ 0)] y))
+
+
+(example (free-vars (parse '(forall [x (univ 0)] (x y))) :open)
+         => #{'y})
+
+(example (free-vars (:body (parse '(forall [x (univ 0)] (x y)))) :lambda)
+         => #{})
+


let logged in users bask in the glory of the new hompage

--- frontend/routes.cljs
+++ frontend/routes.cljs
@@ -149,7 +149,7 @@

   (defroute v1-languages (FragmentRoute. "/features/:language") {:as params}
     (open-to-outer! nav-ch :language-landing (assoc params
-                                              :_title (str "CircleCI for " (:language params)))))
+                                               :_title (str "CircleCI for " (:language params)))))

   ;; TODO: this should be integrations/:integration, but we'll wait for more integrations
   (defroute v1-integrations (FragmentRoute. "/integrations/docker") {:as params}
@@ -164,7 +164,10 @@
   (defroute v1-root (FragmentRoute. "/") {:as params}
     (if authenticated?
       (open-to-inner! nav-ch :dashboard params)
-      (open-to-outer! nav-ch :landing params))))
+      (open-to-outer! nav-ch :landing params)))
+
+  (defroute v1-root (FragmentRoute. "/landing") {:as params}
+    (open-to-outer! nav-ch :landing params)))

 (defn define-spec-routes! [nav-ch]
   (defroute trailing-slash #"(.+)/$" [path]


Show creator instead of dam number in catalog view

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -145,16 +145,16 @@
      (when error
        [:p [:ul.alert.alert-danger [:li error]]])
      [:table.table.table-striped
-      [:thead [:tr [:th "Title"] [:th "Product Number"] [:th "Library Number"] [:th "DAM Number"] [:th "Total time"] [:th "Number of CDs"] [:th "Depth"] [:th "Narrator"] [:th "Date of Production"] [:th "Libary signature"]]]
+      [:thead [:tr [:th "Title"] [:th "Author"] [:th "Product Number"] [:th "Library Number"] [:th "Total time"] [:th "Number of CDs"] [:th "Depth"] [:th "Narrator"] [:th "Date of Production"] [:th "Libary signature"]]]
       [:tbody
-       (for [{:keys [id title product_number library_number
+       (for [{:keys [id title creator product_number library_number
                      total_time volumes depth narrator produced_date]
               :as production} (prod/find-by-state "encoded")]
          [:tr
           [:td (link-to (str "/production/" id) title)]
+          [:td creator]
           [:td product_number]
           [:td library_number]
-          [:td (prod/dam-number production)]
           [:td (quot total_time (* 1000 60))] ; in minutes
           [:td volumes]
           [:td depth]


Believe I have correct clean semantics now.

--- src-cljs/freactive/core.cljs
+++ src-cljs/freactive/core.cljs
@@ -301,8 +301,8 @@
         new-val)))
   (clean [this]
     ;; (println "trying to clean" watchers iwatchers invalidation-watches)
-    (when true
-        ;; (and (identical? 0 watchers) (identical? 0 iwatchers))
+    (when ;;true
+        (and (identical? 0 watchers) (identical? 0 iwatchers))
       ;; (println "cleaning" id)
       (goog.object/forEach deps
                            (fn [val key obj]
@@ -315,8 +315,9 @@
                                  (clean* dep)))
                              (js-delete obj key)))
       ;; (.invalidate this)
-      (when-not (.-dirty this)
-        (.invalidate this))
+      ;; (when-not (.-dirty this)
+      ;;   (.invalidate this))
+      (set! (.-dirty this) true)
     ))

   IReactive


Add vibrato ugen docstrings

Add vibrato ugen docstrings

--- src/overtone/sc/machinery/ugen/metadata/osc.clj
+++ src/overtone/sc/machinery/ugen/metadata/osc.clj
@@ -182,16 +182,17 @@
        :doc "select the output signal from an array of inputs"}

       {:name "Vibrato",
-       :args [{:name "freq", :default 440.0}
-              {:name "rate", :default 6}
-              {:name "depth", :default 0.02}
-              {:name "delay", :default 0.0}
-              {:name "onset", :default 0.0}
-              {:name "rate-variation", :default 0.04}
-              {:name "depth-variation", :default 0.1}
-              {:name "iphase", :default 0.0}]
-       :doc ""}
-      ])
+       :args [{:name "freq", :default 440.0 :doc "Fundamental frequency in Hertz. If the Vibrato UGen is running at audio rate, this must not be a constant, but an actual audio rate UGen"}
+              {:name "rate", :default 6 :doc "Vibrato rate, speed of wobble in Hertz. Note that if this is set to a low value (and definitely with 0.0), you may never get vibrato back, since the rate input is only checked at the end of a cycle."}
+              {:name "depth", :default 0.02 :doc "Size of vibrato frequency deviation around the fundamental, as a proportion of the fundamental. 0.02 = 2% of the fundamental."}
+              {:name "delay", :default 0.0 :doc "Delay before vibrato is established in seconds (a singer tends to attack a note and then stabilise with vibrato, for instance)."}
+              {:name "onset", :default 0.0 :doc "Transition time in seconds from no vibrato to full vibrato after the initial delay time."}
+              {:name "rate-variation", :default 0.04 :doc "Noise on the rate, expressed as a proportion of the rate; can change once per cycle of vibrato."}
+              {:name "depth-variation", :default 0.1 :doc "Noise on the depth of modulation, expressed as a proportion of the depth; can change once per cycle of vibrato. The noise affects independently the up and the down part of vibrato shape within a cycle."}
+              {:name "iphase", :default 0.0 :doc "Initial phase of vibrato modulation, allowing starting above or below the fundamental rather than on it."}]
+       :summary "Models a slow frequency modulation."
+       :doc "Vibrato is a slow frequency modulation. Consider the systematic deviation in pitch of a singer around a fundamental frequency, or a violinist whose finger wobbles in position on the fingerboard, slightly tightening and loosening the string to add shimmer to the pitch. There is often also a delay before vibrato is established on a note. This UGen models these processes; by setting more extreme settings, you can get back to the timbres of FM synthesis. You can also add in some noise to the vibrato rate and vibrato size (modulation depth) to make for a more realistic motor pattern.
+The vibrato output is a waveform based on a squared envelope shape with four stages marking out 0.0 to 1.0, 1.0 to 0.0, 0.0 to -1.0, and -1.0 back to 0.0. Vibrato rate determines how quickly you move through these stages."}])

 (def specs-collide
   [{:name "Index",


increase buffers

increase buffers


add the share input to public docs

add the share input to public docs

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -26,6 +26,26 @@
   (:require-macros [sablono.core :refer (html)])
   (:import [goog.ui IdGenerator]))

+(defn share-url-input [app owner]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       [:div.make
+        [:form.menu-invite-form.make
+         [:input {:type "text"
+                  :required "true"
+                  :data-adaptive ""
+                  :onMouseDown (fn [e]
+                                 (js/console.log (.-target e))
+                                 (.focus (.-target e))
+                                 (goog.dom.selection/setStart (.-target e) 0)
+                                 (goog.dom.selection/setEnd (.-target e) 10000)
+                                 (utils/stop-event e))
+                  :value (urls/absolute-doc-url (:document/id app))}]
+         [:label
+          {:data-placeholder "Copy the url to share"}]]]))))
+
 (defn auth-link [app owner {:keys [source] :as opts}]
   (reify
     om/IDisplayName (display-name [_] "Overlay Auth Link")
@@ -240,22 +260,12 @@
          [:div.content
           [:h2.make
            "This document is read-only."]
+
           [:p.make
            "Anyone with the url can see the doc and chat, but can't edit the canvas. "
            "Share the url to show off your work."]
-          [:form.menu-invite-form.make
-           [:input {:type "text"
-                    :required "true"
-                    :data-adaptive ""
-                    :onMouseDown (fn [e]
-                                   (js/console.log (.-target e))
-                                   (.focus (.-target e))
-                                   (goog.dom.selection/setStart (.-target e) 0)
-                                   (goog.dom.selection/setEnd (.-target e) 10000)
-                                   (utils/stop-event e))
-                    :value (urls/absolute-doc-url (:document/id app))}]
-           [:label
-            {:data-placeholder "Copy the url to share"}]]
+          (om/build share-url-input app)
+
           [:p.make
            "Add your teammate's email to grant them full access."]
           [:form.menu-invite-form.make
@@ -360,8 +370,12 @@

              (list
                [:p.make
-                "It's visible to anyone with the url.
-                Email a friend to invite them to collaborate."]
+                "Anyone with the url can view and edit."]
+
+               (om/build share-url-input app)
+
+               [:p.make
+                "Email a friend to invite them to collaborate."]
                [:form.menu-invite-form.make
                 {:on-submit #(do (cast! :invite-submitted)
                                false)


Cometd subscribe predicate now takes client and message as arguments

--- lib/compojure/cometd/cometd.clj
+++ lib/compojure/cometd/cometd.clj
@@ -182,7 +182,7 @@
       (.addListener client
         (proxy [MessageListener] []
           (deliver [from to mesg]
-            (func (java->clj mesg)))))
+            (func from (java->clj mesg)))))
       (.subscribe (get-channel servlet channel) client)
       client)))


bugfix on socialgroup page

bugfix on socialgroup page

--- src/cljs/ohds/socialgroup/processing.cljs
+++ src/cljs/ohds/socialgroup/processing.cljs
@@ -15,8 +15,8 @@
   m/ChangeGroupType
   (process-message [response app]
     (if (= (:type response) "-----")
-      (assoc-state {:type nil} app :individual)
-      (assoc-state response app :individual)))
+      (assoc-state {:type nil} app :socialgroup)
+      (assoc-state response app :socialgroup)))

   m/CreateSocialGroupResults


can now hover inspect entanglements

can now hover inspect entanglements

--- src/qttt/game.cljs
+++ src/qttt/game.cljs
@@ -7,7 +7,6 @@

 (def ^:dynamic *speculative* false)

-;; TODO: make cycles of size 2 work (approach: become aware of the turn they were played on)
 ;; TODO: make hover highlighting work (approach: third top-level activity)
 ;; TODO: make cycle collapse work

@@ -28,11 +27,11 @@
    ;; A cell
   {:entanglements {0 {:player 0
                       :turn 0
-                      :pair 1
+                      :pair [4 2]
                       :focus false
                       :collapsing true}
                    1 {:player 1
-                      :pair 2
+                      :pair [4 2]
                       :turn 1
                       :focus true}}
    :classical {:player 0
@@ -53,9 +52,9 @@
   [game cell]
   (->> (get-in game [:board cell :entanglements])
     (vals)
-    (keep (fn [e] (when (and (:pair e)
-                         (not (get-in game [:board (:pair e) :classical])))
-                   [(:pair e) (:turn e)])))))
+    (keep (fn [e] (when-let [[pair-cell pair-subcell] (:pair e)]
+                    (when-not (get-in game [:board pair-cell :classical])
+                      [pair-cell (:turn e)]))))))

 (defn index-of
   "Return the index of an item in a vector, if present. If not present return nil"
@@ -93,7 +92,7 @@
         (reduce (fn [g cell]
                   (let [collapsing-subcells
                         (keep
-                          (fn [[sub e]] (when (contains? collapsing-cells (:pair e)) sub))
+                          (fn [[sub e]] (when (contains? collapsing-cells (first (:pair e))) sub))
                           (get-in g [:board cell :entanglements]))]
                     (reduce #(assoc-in %1 [:board cell :entanglements %2 :collapsing] true) g collapsing-subcells)))
           (assoc game :collapsing true)
@@ -116,12 +115,12 @@
       (assoc-in [:board cell :entanglements subcell]
         {:player (:player game)
          :turn (:turn game)
-         :pair pair-cell
+         :pair [pair-cell pair-subcell]
          :focus *speculative*})
       ;; update the entangled spooky mark
       (update-in [:board pair-cell :entanglements pair-subcell] assoc
         :focus *speculative*
-        :pair cell)
+        :pair [cell subcell])
       ;; remove the pair tracker
       (dissoc :pair)
       ;; change the player
@@ -151,13 +150,24 @@
            :turn (:turn game)
            :focus true})))))

+(defn highlight
+  "Focus the subcell and its entanglement"
+  [game cell subcell]
+  (-> (if-let [[pair-cell pair-subcell]
+               (get-in game [:board cell :entanglements subcell :pair])]
+        (assoc-in game [:board pair-cell :entanglements pair-subcell :focus] true)
+        game)
+    (assoc-in [:board cell :entanglements subcell :focus] true)))
+
 (defn play
   "Play an action at the given cell and subcell.
    What the action is depends on the game context."
   [game cell subcell]
   (if (:collapsing game)
     (resolve-collapse game cell subcell)
-    (spooky-mark game cell subcell)))
+    (if (and *speculative* (get-in game [:board cell :entanglements subcell]))
+      (highlight game cell subcell)
+      (spooky-mark game cell subcell))))

 (defn speculate
   "Make a play, but store the previous game state so the 'play' can be easily reverted"


Remove snakecase from function name

Remove snakecase from function name

--- src-cljs/parser.cljs
+++ src-cljs/parser.cljs
@@ -5,7 +5,7 @@
   )

-(defn cat_two_first[array]
+(defn cat-two-first[array]
   (conj (rest (rest array)) (clojure.string/join [(first array) (second array)] ))
 )

@@ -26,7 +26,7 @@
   (let [first-char (str (first (first array)))]

    (if (skippable-char? first-char)
-    (cat_two_first array)
+    (cat-two-first array)
     array
     )
   )


index page goes to top group in sidebar

index page goes to top group in sidebar

--- src/braid/client/routes.cljs
+++ src/braid/client/routes.cljs
@@ -1,6 +1,7 @@
 (ns braid.client.routes
   (:require [secretary.core :as secretary :refer-macros [defroute]]
             [braid.client.store :as store]
+            [braid.client.state :as state]
             [braid.client.router :as router])
   (:import [goog.history Html5History]
            [goog Uri]))
@@ -53,7 +54,12 @@
   (store/set-group-and-page! nil {:type (keyword page-id)}))

 (defroute index-path "/" {}
-  (when-let [group-id (-> (@store/app-state :groups) vals first :id)]
+  (when-let [group-id (->> @store/app-state
+                           ((juxt (comp vals :groups)
+                                  (comp :groups-order :preferences)))
+                           (apply state/order-groups)
+                           first
+                           :id)]
     (go-to! (inbox-page-path {:group-id group-id}))))

 (defn current-group []


define web-instance

define web-instance

--- src/ca_recipe/tnywb/core.clj
+++ src/ca_recipe/tnywb/core.clj
@@ -50,3 +50,4 @@
   {"/greeting" {:controller handle-greeting :view greeting-view}})

 (def filters [logging-filter])
+(def tinyweb-instance (tinyweb request-handlers filters))


Add some missing type hints.

Add some missing type hints.

--- src/clojure/parkour/conf.clj
+++ src/clojure/parkour/conf.clj
@@ -44,6 +44,7 @@

 (defn clone
   "Return new Hadoop `Configuration`, cloning `conf`."
+  {:tag `Configuration}
   [conf] (Configuration. (configuration conf)))

 (defmacro with-default
@@ -81,6 +82,7 @@

 (defn assoc!
   "Set `conf` parameter `key` to `val`."
+  {:tag `Configuration}
   ([conf] conf)
   ([conf key val]
      (returning conf
@@ -91,12 +93,13 @@
          conf
          (recur conf (first kvs) (second kvs) (nnext kvs))))))

-(def set!
+(def ^{:tag `Configuration} set!
   "Alias for `assoc!`."
   assoc!)

 (defn merge!
   "Merge `coll` of key-value pairs into Hadoop configuration `conf`."
+  {:tag `Configuration}
   [conf coll]
   (apply assoc! conf (apply concat coll)))


Stash the netty server state in a map instead of a vector

--- src/clojure/picard/netty.clj
+++ src/clojure/picard/netty.clj
@@ -294,7 +294,7 @@
        pipeline-fn)))))

 (defn shutdown
-  [[bootstrap channel-group]]
+  [{bootstrap :bootstrap channel-group :channel-group}]
   (let [close-future (.close channel-group)]
     (.awaitUninterruptibly close-future)
     (.releaseExternalResources bootstrap)))
@@ -306,7 +306,7 @@
         ch-group  (configure-bootstrap
                    bootstrap merge-netty-server-opts pipeline-fn options)]
     (.add ch-group (.bind bootstrap (mk-socket-addr [host port])))
-    [bootstrap ch-group]))
+    {:bootstrap bootstrap :channel-group ch-group}))

 (defn mk-client-factory
   [pipeline-fn options]


fix get-permissions on windows

fix get-permissions on windows

--- src/com/brainbot/real_fs.clj
+++ src/com/brainbot/real_fs.clj
@@ -3,10 +3,14 @@
    [clojure.string :as string])
   (:import [java.io File IOException FileNotFoundException]
            [java.nio.file Files Path LinkOption Paths]
-           [java.nio.file.attribute AclFileAttributeView PosixFilePermissions PosixFilePermission BasicFileAttributes PosixFileAttributes])
+
+           [java.nio.file.attribute UserPrincipal GroupPrincipal AclEntryType AclEntryPermission AclFileAttributeView PosixFilePermissions PosixFilePermission BasicFileAttributes PosixFileAttributes])

   (:require [com.brainbot.vfs :as vfs]))

+
+(def ^:private is-windows
+  (= "\\" File/separator))

 (def ^:private no-follow-links
   (into-array [LinkOption/NOFOLLOW_LINKS]))
@@ -15,11 +19,9 @@
   [path & args]
   (Paths/get path (into-array String args)))

-
 (defn- read-attributes
   [path]
   (Files/readAttributes (get-path path) PosixFileAttributes no-follow-links))
-

 (defn- type-from-attribute
   [attr]
@@ -32,7 +34,6 @@
       :symbolic-link
     :else
       :other))
-

 (defn- acl-from-posix-perm
   [owner-name group-name others-name perm]
@@ -56,12 +57,46 @@
     (acl-from-posix-perm owner-name group-name "GROUP:AUTHENTICATED_USERS" perm)))

+
+(defn- raw-windows-acls
+  [path]
+  (-> path
+      get-path
+      (Files/getFileAttributeView AclFileAttributeView (into-array LinkOption []))
+      .getAcl
+      seq))
+
+(defn- convert-raw-windows-sid
+  [sid]
+  (let [name (.getName sid)]
+    (cond
+      (instance? UserPrincipal sid)
+        (str "USER:" name)
+      (instance? GroupPrincipal sid)
+        (str "GROUP:" name))))
+
+
+(defn- convert-raw-windows-ace
+  [ace]
+  (if (contains? (.permissions ace) AclEntryPermission/READ_DATA)
+    {:allow (= AclEntryType/ALLOW (.type ace))
+     :sid (convert-raw-windows-sid (.principal ace))}))
+
+(defn- windows-acl-from-path
+  [path]
+  (remove nil? (map convert-raw-windows-ace (raw-windows-acls path))))
+
+(defn- posix-acl-from-path
+  [path]
+  (acl-from-attribute (read-attributes path)))
+
 (defrecord RealFilesystem [root]
   vfs/Filesystem
   (get-permissions [fs entry]
-    (let [fp (string/join "/" [(:root fs) entry])
-          attr (read-attributes fp)]
-      (acl-from-attribute attr)))
+    (let [fp (string/join "/" [(:root fs) entry])]
+      (if is-windows
+        (windows-acl-from-path fp)
+        (posix-acl-from-path fp))))

   (stat [fs entry]
     (let [fp (string/join "/" [(:root fs) entry])


Update src/com/puppetlabs/utils.clj

Update src/com/puppetlabs/utils.clj

Update docstrings to clarify meaning of 'bound' parameter.

--- src/com/puppetlabs/utils.clj
+++ src/com/puppetlabs/utils.clj
@@ -472,8 +472,8 @@
       (digest-func "sha-1" [bytes]))))

 (defn bounded-memoize
-  "Similar to memoize, but the cache will be reset if it exceeds the specified
-  `bound`."
+  "Similar to memoize, but the cache will be reset if the number of entries
+  exceeds the specified `bound`."
   [f bound]
   {:pre [(integer? bound)
          (pos? bound)]}


select text when you edit

select text when you edit

--- src-cljs/frontend/components/hud.cljs
+++ src-cljs/frontend/components/hud.cljs
@@ -10,6 +10,7 @@
             [frontend.state :as state]
             [frontend.utils :as utils :include-macros true]
             [goog.dom]
+            [goog.dom.Range]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
   (:require-macros [sablono.core :refer (html)])
@@ -137,7 +138,8 @@
     (did-update [_ _ _]
       (when (and (om/get-state owner :editing-name?)
                  (om/get-node owner "name-edit"))
-        (.focus (om/get-node owner "name-edit"))))
+        (.focus (om/get-node owner "name-edit"))
+        (.select (goog.dom.Range/createFromNodeContents (om/get-node owner "name-edit")))))
     om/IRenderState
     (render-state [_ {:keys [editing-name? new-name]}]
       (let [{:keys [cast! db]} (om/get-shared owner)


(MAINT) remove unused namespaces in test

--- test/puppetlabs/trapperkeeper/internal_test.clj
+++ test/puppetlabs/trapperkeeper/internal_test.clj
@@ -1,12 +1,8 @@
 (ns puppetlabs.trapperkeeper.internal-test
   (:require [clojure.test :refer :all]
             [puppetlabs.trapperkeeper.core :as tk]
-            [puppetlabs.kitchensink.testutils :as ks-testutils]
             [puppetlabs.trapperkeeper.app :as tk-app]
-            [puppetlabs.trapperkeeper.config :as config]
-            [puppetlabs.trapperkeeper.internal :as internal]
-            [puppetlabs.trapperkeeper.testutils.bootstrap :refer [with-app-with-empty-config]]))
-
+            [puppetlabs.trapperkeeper.internal :as internal]))

 (deftest test-queued-restarts
   (testing "main lifecycle and calls to `restart-tk-apps` are not executed concurrently"


(MAINT) assert parent directory does not exist

--- test/puppetlabs/trapperkeeper/services_test.clj
+++ test/puppetlabs/trapperkeeper/services_test.clj
@@ -121,6 +121,7 @@
                             []
                             (service1-fn [this] "hi"))
           temp-file (fs/file (kitchensink/temp-dir "foo") "bar" "baz" "counter")]
+      (is (false? (fs/exists? (fs/parent temp-file))))
       (is (false? (fs/exists? temp-file)))
       (with-app-with-config app [service1] {:global {:restart-file temp-file}}
         (is (= (slurp temp-file) "1"))))))


fix problem restarting when there are active swank connections

--- bake/bake.clj
+++ bake/bake.clj
@@ -10,8 +10,9 @@
       (eval form))))

 (defn quit []
-  (when (= 0 (swank/num-connections))
-    (server/quit)))
+  (if (= 0 (swank/num-connections))
+    (server/quit)
+    (println "refusing to quit because there are active swank connections")))

 (defn start-server [port]
   (server/create port eval-multi :quit quit)


bump default number of audio busses to 512

--- src/overtone/sc/machinery/server/args.clj
+++ src/overtone/sc/machinery/server/args.clj
@@ -12,7 +12,7 @@
   {:port                     {:default 57711             :desc "Port number"}
    :udp?                     {:default 1                 :desc "1 means use UDP, 0 means use TCP"}
    :max-control-bus          {:default 4096   :flag "-c" :desc "Number of control bus channels"}
-   :max-audio-bus            {:default 128    :flag "-a" :desc "Number of audio bus channels"}
+   :max-audio-bus            {:default 512    :flag "-a" :desc "Number of audio bus channels"}
    :max-input-bus            {:default 8      :flag "-i" :desc "Number of input bus channels"}
    :max-output-bus           {:default 8      :flag "-o" :desc "Number of output bus channels"}
    :block-size               {:default 64     :flag "-z" :desc "Block size"}


CLJS-415: Speed up cljsc by exiting after output has been printed

--- bin/cljsc.clj
+++ bin/cljsc.clj
@@ -18,4 +18,7 @@
     {:source source :options (merge {:output-to :print} options)}))

 (let [args (transform-cl-args *command-line-args*)]
-  (closure/build (:source args) (:options args)))
+  (closure/build (:source args) (:options args))
+  (.flush *out*)
+  (shutdown-agents)
+  (System/exit 0))


(println) -> (newline)

(println) -> (newline)

--- src/cyanite_fetcher/core.clj
+++ src/cyanite_fetcher/core.clj
@@ -39,7 +39,7 @@
   (println (format "Cleaning data with %s..." name))
   (let [cdata (time (doall (f data)))]
     (println "Number of rows:" (count cdata))
-    (println)
+    (newline)
     cdata))

 (defn flatter
@@ -48,7 +48,7 @@
   (println (format "Flatting data with %s..." name))
   (let [fdata (time (doall (f data)))]
     (println "Number of rows:" (count fdata))
-    (println)
+    (newline)
     fdata))

 (defn par-fetch [session fetch! paths tenant rollup period from to]
@@ -75,7 +75,7 @@
     (println "Getting data form Cassandra...")
     (let [data (time (doall (par-fetch session fetch! paths tenant rollup
                                        period from to)))]
-      (println)
+      (newline)
       data)))

 ;;------------------------------------------------------------------------------
@@ -141,7 +141,7 @@
   (println "Getting paths form ElasticSearch...")
   (let [paths (time (doall (lookup host tenant path)))]
     (println "Number of paths:" (count paths))
-    (println)
+    (newline)
     paths))

 ;;------------------------------------------------------------------------------
@@ -209,18 +209,18 @@
         tenant (or tenant "NONE")
         to (if to (Long/parseLong (str to)) (now))
         from (Long/parseLong (str from))]
-    (println)
+    (newline)
     (println "Cassandra host:    " chost)
     (println "ElasticSearch host:" eshost)
-    (println)
+    (newline)
     (println "Path:  " path)
     (println "Tenant:" tenant)
     (println "From:  " from)
     (println "To:    " to)
-    (println)
+    (newline)
     (println "Rollup:" rollup)
     (println "Period:" period)
-    (println)
+    (newline)
     (let [paths (es-get-paths eshost path tenant)
           data (c-get-data chost paths tenant rollup period from to)
           reduce-fdata (flatter data (fn [data] (reduce into data)) "reduce")


Pull with-show out of loops for efficiency.

--- src/afterglow/effects/cues.clj
+++ src/afterglow/effects/cues.clj
@@ -304,15 +304,15 @@
                                        [id (:key (controllers/cue-at (:cue-grid show) x y))]))))]
     (Effect. name
              (fn [show snapshot]  ; We are still running if any of the nested effects we launched are.
-               (some (fn [[id k]]
-                       (with-show show
+               (with-show show
+                 (some (fn [[id k]]
                          (when-let [effect (show/find-effect k)]
-                           (= (:id effect) id))))
-                      running))
+                           (= (:id effect) id)))
+                       running)))
              (fn [show snapshot] nil)  ; We do not assign any values; only the nested effects do.
              (fn [show snapshot]  ; Tell all our launched effects to end.
-               (doseq [[id k] running]
-                 (with-show show
+               (with-show show
+                 (doseq [[id k] running]
                    (show/end-effect! k :when-id id)))))))


Prevent duplicate filter strings

Prevent duplicate filter strings

--- src/day8/re_frame/trace.cljs
+++ src/day8/re_frame/trace.cljs
@@ -147,11 +147,12 @@
       (< (:query query) (:duration trace)))))

 (defn add-filter [filter-items filter-input filter-type]
-  (swap! filter-items conj {:id (random-uuid)
-                            :query (if (= filter-type :contains)
-                                     (str/lower-case filter-input)
-                                     (js/parseFloat filter-input))
-                            :filter-type filter-type}))
+  (if-not (some #(= filter-input (:query %)) @filter-items)
+    (swap! filter-items conj {:id (random-uuid)
+                              :query (if (= filter-type :contains)
+                                       (str/lower-case filter-input)
+                                       (js/parseFloat filter-input))
+                              :filter-type filter-type})))

 (defn render-traces [showing-traces filter-items filter-input trace-detail-expansions]
   (doall


Replace accidentally removed rule

Replace accidentally removed rule

--- resources/languages/en/rules/time.clj
+++ resources/languages/en/rules/time.clj
@@ -617,6 +617,10 @@
         (assoc :form :time-of-day))
       true))

+  "between <time-of-day> and <time-of-day> (interval)"
+  [#"(?i)between" {:form :time-of-day} #"and" {:form :time-of-day}]
+  (interval %2 %4 true)
+
   "between <time-of-day-latent> and <time-of-day-latent> (interval) am|pm"
   [#"(?i)between" #(and (= :time-of-day (:form %)) (:latent %)) #"and" #(and (= :time-of-day (:form %)) (:latent %)) #"(?i)([ap])\.?m?\.?"]
   (let [[p meridiem] (if (= "a" (-> %5 :groups first clojure.string/lower-case))


add imperial units

add imperial units

--- resources/picsou/rules/en.measure.clj
+++ resources/picsou/rules/en.measure.clj
@@ -1,5 +1,15 @@
 (
 	;; Distance
+	;; NEED TO PUSH THE NORMALIZATION IN THE HELPER + CREATE Function to combine distance
+
+ 	; "two distance tokens in a row"
+ 	; [(dim :distance #(not (:latent %))) (dim :distance #(not (:latent %)))] ; sequence of two tokens with a distance dimension
+ 	; (combine-distance %1 %2)
+
+  ; 	; same thing, with "and" in between like "3 feets and 2 inches"
+ 	; "two distance tokens separated by and"
+ 	; [(dim :distance #(not (:latent %))) #"(?i)and" (dim :distance #(not (:latent %)))] ; sequence of two tokens with a time fn
+ 	; (combine-distance %1 %3)

 	; latent distance
 	"number as distance"
@@ -14,6 +24,30 @@
 	    (dissoc  :latent)
 	   	(merge {:unit "kilometre"
 	    		:normalized {:value (* 1000 (-> %1 :value))
+	    					 :unit "metre"}}))
+
+	"<latent dist> feet"
+	[(dim :distance) #"(?i)(′|f(oo|ee)?ts?)"]
+	(-> %1
+	    (dissoc  :latent)
+	   	(merge {:unit "foot"
+	    		:normalized {:value (* 0.3048 (-> %1 :value))
+	    					 :unit "metre"}}))
+
+	"<latent dist> inch"
+	[(dim :distance) #"(?i)(′′|inch(es)?)"]
+	(-> %1
+	    (dissoc  :latent)
+	   	(merge {:unit "inch"
+	    		:normalized {:value (* 0.0254 (-> %1 :value))
+	    					 :unit "metre"}}))
+
+	"<latent dist> yard"
+	[(dim :distance) #"(?i)y(ar)?ds?"]
+	(-> %1
+	    (dissoc  :latent)
+	   	(merge {:unit "yard"
+	    		:normalized {:value (* 0.9144 (-> %1 :value))
 	    					 :unit "metre"}}))

 	"<dist> meters"


Assert columns more friendly

Assert columns more friendly

--- src/clj_simple_chart/eurostat/data/icao_airport_code.clj
+++ src/clj_simple_chart/eurostat/data/icao_airport_code.clj
@@ -1,6 +1,7 @@
 (ns clj-simple-chart.eurostat.data.icao-airport-code
   (:require [clj-http.client :as client]
             [clj-simple-chart.csv.csvmap :as csvmap]
+            [clojure.set :as sets]
             [clojure.test :as test]))

@@ -9,18 +10,19 @@

 (defonce response (client/get url))
 (def csv (csvmap/csv-map (:body response)))
-(test/is (= [:ident
-             :type
-             :name
-             :coordinates
-             :elevation_ft
-             :continent
-             :iso_country
-             :iso_region
-             :municipality
-             :gps_code
-             :iata_code
-             :local_code] (:columns csv)))
+
+(csvmap/assert-columns [:ident
+                        :type
+                        :name
+                        :coordinates
+                        :elevation_ft
+                        :continent
+                        :iso_country
+                        :iso_region
+                        :municipality
+                        :gps_code
+                        :iata_code
+                        :local_code] csv)

 (def data (:data csv))


Removing old code

Removing old code

--- src/cljs/wombats_web_client/components/cards/wombat.cljs
+++ src/cljs/wombats_web_client/components/cards/wombat.cljs
@@ -11,12 +11,9 @@

 (defn open-edit-wombat-modal [id name url]
   (fn []
-    (let [edit-submit-fn #(on-submit-form-valid? cmpnt-state wombat-id)])
     (re-frame/dispatch [:set-modal {:fn #(wombat-modal {:wombat-id id
-                                                        :name name
-                                                        :url url
-                                                        :submit-info {:text "SAVE"
-                                                                      :fn #(on-submit-form-valid? cmpnt-state wombat-id)}})
+                                                               :name name
+                                                               :url url})
                                     :show-overlay? true}])))

 (defn wombat-information