Reverts change to :form-params. Adds converting function of vector or list to comma separated string.

--- src/clj_spotify/core.clj
+++ src/clj_spotify/core.clj
@@ -44,6 +44,39 @@
     (build-new-url "" split-url act-tmplt-keys)
     )))

+(defn comma-separate
+  "If v is a sequence, convert to a comma separated string."
+  [k v]
+  (prn k v)
+  (if (or (seq? v) (vector? v))
+    [k (string/join "," v)]
+    [k v]
+    )
+  )
+
+(defn convert-values
+  "Convert values in query-params to match spotifys api."
+  [m]
+  (into {} (for [[k v] m] (comma-separate k v)))
+  )
+
+(defn remove-path-keys
+  "Remove keys that are used in modifying the path."
+  [m]
+  (apply dissoc m template-keys)
+  )
+
+(defn modify-form-params
+  "Do nescessary conversion of form parameters."
+  [m]
+  (->
+    m
+    (remove-path-keys)
+    (convert-values)
+    )
+  )
+
+;TODO - solve json data in request body on put/post etc.
 ;TODO - better doc string
 (defmacro def-spotify-api-call
   "Creates a function f with doc-string d that calls the http-verb verb for url url."
@@ -52,7 +85,8 @@
      ~doc-string
      ([m#] (~f m# nil))
      ([m# t#]
-      (let [query-params# {:form-params (apply dissoc m# template-keys) :oauth-token t# :content-type :json}]
+      (let [query-params# {:query-params (modify-form-params m#) :oauth-token t# :content-type :json}]
+        (prn query-params#)
         (->
           (try
             (~verb (replace-url-values m# ~url) query-params#)
@@ -61,356 +95,355 @@
           (response-to-map)
           )))))

-;TODO - Replace all comma separated strings with seqs?
 ;Albums
 (def-spotify-api-call get-an-album client/get (str spotify-api-url "albums/id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id, optional key is :market.
-    :id has to have the value of an existing album's id.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-an-album {:id \"0MnG7y5F1n4Wns63RjEItx\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id, optional key is :market.
+  :id has to have the value of an existing album's id.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-an-album {:id \"0MnG7y5F1n4Wns63RjEItx\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-several-albums client/get (str spotify-api-url "albums")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids, optional key is :market.
-    :ids has to be a comma separated string of spotify album ids.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-several-albums {:ids \"4hTil0JVdMyxK2vH11ZbiX,4RjjFbiqFaO8mKTDM2Kzna\" :market \"SE\"} \"BQBw-JtC..._7GvA\") ")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids, optional key is :market.
+  :ids has to be a comma separated string of spotify album ids.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-several-albums {:ids \"4hTil0JVdMyxK2vH11ZbiX,4RjjFbiqFaO8mKTDM2Kzna\" :market \"SE\"} \"BQBw-JtC..._7GvA\") ")

 (def-spotify-api-call get-tracks-of-album client/get (str spotify-api-url "albums/id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id, optional keys are :limit, :offset and :market.
-    :id has to have the value of an existing album's id.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-tracks-of-album {:id \"3XCGFOBqESirxxICswSity\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id, optional keys are :limit, :offset and :market.
+  :id has to have the value of an existing album's id.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-tracks-of-album {:id \"3XCGFOBqESirxxICswSity\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 ;Artists
 (def-spotify-api-call get-an-artist client/get (str spotify-api-url "artists/id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id.
-    :id has to have the value of an existing artist's id.
-
-    Example: (get-an-artist {:id \"5CE2IfdYZEQGIDsfiRm8SI\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id.
+  :id has to have the value of an existing artist's id.
+
+  Example: (get-an-artist {:id \"5CE2IfdYZEQGIDsfiRm8SI\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-several-artists client/get (str spotify-api-url "artists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids.
-    :ids has to be a comma separated string of spotify artist ids.
-
-    Example: (get-several-artists {:ids \"1kK2LYgoP3raZNngbb1qMT,2RitCPbwEYyYNw5LkbXTGv\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids.
+  :ids has to be a comma separated string of spotify artist ids.
+
+  Example: (get-several-artists {:ids \"1kK2LYgoP3raZNngbb1qMT,2RitCPbwEYyYNw5LkbXTGv\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-an-artists-albums client/get (str spotify-api-url "artists/id/albums")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id, optional keys are :album_type, :market, :limit and :offset.
-    :id has to have the value of an existing artist's id.
-    :album_type a comma-separated list of one or several of the following:
-     album, single, appears_on and compilation. Default is to query for all types.
-    :market is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-an-artists-albums {:id \"7lOJ7WXyopaxri0dbOiZkd\" :album_type \"album, single\" :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id, optional keys are :album_type, :market, :limit and :offset.
+  :id has to have the value of an existing artist's id.
+  :album_type a comma-separated list of one or several of the following:
+  album, single, appears_on and compilation. Default is to query for all types.
+  :market is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-an-artists-albums {:id \"7lOJ7WXyopaxri0dbOiZkd\" :album_type \"album, single\" :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-an-artists-top-tracks client/get (str spotify-api-url "artists/id/top-tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :id and :country.
-    :id has to be a spotify artist id.
-    :country is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-an-artists-top-tracks {:id \"7hCsRnXtcbez8msLPfjbkz\" :country \"SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :id and :country.
+  :id has to be a spotify artist id.
+  :country is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-an-artists-top-tracks {:id \"7hCsRnXtcbez8msLPfjbkz\" :country \"SE\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-an-artists-related-artists client/get (str spotify-api-url "artists/id/related-artists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id.
-    :id has to be a spotify artist id.
-
-    Example: (get-an-artists-related-artists {:id \"4EF5vIcCYKMM61oYOG2Tqa\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id.
+  :id has to be a spotify artist id.
+
+  Example: (get-an-artists-related-artists {:id \"4EF5vIcCYKMM61oYOG2Tqa\"} \"BQBw-JtC..._7GvA\")")

 ;Browse
 (def-spotify-api-call get-a-list-of-featured-playlists client/get (str spotify-api-url "browse/featured-playlists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    There are no compulsary keys in m, optional keys are :locale, :country, :timestamp, :limit and :offset.
-    :locale is an ISO 639 language code and a ISO 3166-1 alpha-2 country code joined with an underscore.
-    :country is an ISO 3166-1 alpha-2 country code.
-    :timestamp is ISO 8601 formatted timestamp.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-list-of-featured-playlists {:locale \"sv_SE\" :country \"SE\" :timestamp \"2015-10-23T09:00:00\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  There are no compulsary keys in m, optional keys are :locale, :country, :timestamp, :limit and :offset.
+  :locale is an ISO 639 language code and a ISO 3166-1 alpha-2 country code joined with an underscore.
+  :country is an ISO 3166-1 alpha-2 country code.
+  :timestamp is ISO 8601 formatted timestamp.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-list-of-featured-playlists {:locale \"sv_SE\" :country \"SE\" :timestamp \"2015-10-23T09:00:00\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-a-list-of-new-releases client/get (str spotify-api-url "browse/new-releases")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    There are no compulsary keys in m, optional keys are :country, :limit and :offset.
-    :country is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-list-of-new-releases {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  There are no compulsary keys in m, optional keys are :country, :limit and :offset.
+  :country is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-list-of-new-releases {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-a-list-of-categories client/get (str spotify-api-url "browse/categories")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    There are no compulsary keys in m, optional keys are :country, :limit and :offset.
-    :country is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-list-of-categories {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  There are no compulsary keys in m, optional keys are :country, :limit and :offset.
+  :country is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-list-of-categories {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-a-category client/get (str spotify-api-url "browse/categories/category_id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :category_id, optional keys are :country and :locale.
-    :category_id has to be a spotify category id.
-    :country is an ISO 3166-1 alpha-2 country code.
-    :locale is an ISO 639 language code and a ISO 3166-1 alpha-2 country code joined with an underscore.
-
-    Example: (get-a-category {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :category_id, optional keys are :country and :locale.
+  :category_id has to be a spotify category id.
+  :country is an ISO 3166-1 alpha-2 country code.
+  :locale is an ISO 639 language code and a ISO 3166-1 alpha-2 country code joined with an underscore.
+
+  Example: (get-a-category {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-a-categorys-playlists client/get (str spotify-api-url "browse/categories/category_id/playlists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :category_id, optional keys are :country, :limit and :offset.
-    :category_id has to be a spotify category id.
-    :country is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-categorys-playlist {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :category_id, optional keys are :country, :limit and :offset.
+  :category_id has to be a spotify category id.
+  :country is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-categorys-playlist {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")

 ;Follow
 (def-spotify-api-call get-users-followed-artists client/get (str spotify-api-url "me/following")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :type, optional keys are :limit and :after.
-    :type has to be set to \"artist\".
-    :limit is the maxium number of items to return, default is 20.
-    :after the last artist id retrieved from a previous request. Use this to get next set of artists.
-
-    Example: (get-users-followed-artists {:type \"artist\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :type, optional keys are :limit and :after.
+  :type has to be set to \"artist\".
+  :limit is the maxium number of items to return, default is 20.
+  :after the last artist id retrieved from a previous request. Use this to get next set of artists.
+
+  Example: (get-users-followed-artists {:type \"artist\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")

 (def-spotify-api-call follow-artists-or-users client/put (str spotify-api-url "me/following")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :type and :ids.
-    :type has to be set to \"artist\" or \"user\".
-    :ids has to be a comma separated list of users or artists.
-
-    Example: (follow-artists-or-users {:type \"artist\" :ids \"2933wDUojoQmvqSdTAE5NB,1AUCkAIfT6Ig8lOegDGK3Z\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :type and :ids.
+  :type has to be set to \"artist\" or \"user\".
+  :ids has to be a comma separated list of users or artists.
+
+  Example: (follow-artists-or-users {:type \"artist\" :ids \"2933wDUojoQmvqSdTAE5NB,1AUCkAIfT6Ig8lOegDGK3Z\" } \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call unfollow-artists-or-users client/delete (str spotify-api-url "me/following")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :type and :ids.
-    :type has to be set to \"artist\" or \"user\".
-    :ids has to be a comma separated list of users or artists.
-
-    Example: (unfollow-artists-or-users {:type \"artist\" :ids \"0uCCBpmg6MrPb1KY2msceF,1WsMRWV5KEC2AxpYkeb2Cf\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :type and :ids.
+  :type has to be set to \"artist\" or \"user\".
+  :ids has to be a comma separated list of users or artists.
+
+  Example: (unfollow-artists-or-users {:type \"artist\" :ids \"0uCCBpmg6MrPb1KY2msceF,1WsMRWV5KEC2AxpYkeb2Cf\" } \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call user-following-artists-or-users? client/get (str spotify-api-url "me/following/contains")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :type and :ids.
-    :type has to be set to \"artist\" or \"user\".
-    :ids has to be a comma separated list of users or artists.
-
-    Example: (user-following-artists-or-users? {:type \"artist\" :ids \"3H6Js0rhywEhHda3UwuhGW,4r8bVMyYyGyARs9OfBvyj4\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :type and :ids.
+  :type has to be set to \"artist\" or \"user\".
+  :ids has to be a comma separated list of users or artists.
+
+  Example: (user-following-artists-or-users? {:type \"artist\" :ids \"3H6Js0rhywEhHda3UwuhGW,4r8bVMyYyGyARs9OfBvyj4\" } \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call follow-a-playlist client/put (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :owner_id and :playlist_id.
-    :owner_id has to be the spotify user id of the user owning the playlist.
-    :playlist_id the spotify playlist id.
-
-    Example: (follow-a-playlist {:owner_id \"sondre_lerche\" :playlist_id \"7q8QuE0YbAgbvzR0NJVwV8\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :owner_id and :playlist_id.
+  :owner_id has to be the spotify user id of the user owning the playlist.
+  :playlist_id the spotify playlist id.
+
+  Example: (follow-a-playlist {:owner_id \"sondre_lerche\" :playlist_id \"7q8QuE0YbAgbvzR0NJVwV8\" } \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call unfollow-a-playlist client/delete (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :owner_id and :playlist_id.
-    :owner_id has to be the spotify user id of the user owning the playlist.
-    :playlist_id the spotify playlist id.
-
-    Example: (unfollow-a-playlist {:owner_id \"ulyssestone\" :playlist_id \"3WG4abOpUpocexRakPioAg\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :owner_id and :playlist_id.
+  :owner_id has to be the spotify user id of the user owning the playlist.
+  :playlist_id the spotify playlist id.
+
+  Example: (unfollow-a-playlist {:owner_id \"ulyssestone\" :playlist_id \"3WG4abOpUpocexRakPioAg\" } \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call user-following-playlist? client/get (str spotify-api-url "users/owner_id/playlists/playlist_id/followers/contains")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :owner_id and :playlist_id.
-    :owner_id has to be the spotify user id of the user owning the playlist.
-    :playlist_id the spotify playlist id.
-
-    Example: (user-following-playlist? {:owner_id \"lecowboy\" :playlist_id \"2PftXV7dgcxFjMWe75GuSG\" } \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :owner_id and :playlist_id.
+  :owner_id has to be the spotify user id of the user owning the playlist.
+  :playlist_id the spotify playlist id.
+
+  Example: (user-following-playlist? {:owner_id \"lecowboy\" :playlist_id \"2PftXV7dgcxFjMWe75GuSG\" } \"BQBw-JtC..._7GvA\")")

 ;Library
 (def-spotify-api-call save-tracks-for-user client/put (str spotify-api-url "me/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids.
-    :ids has to be a comma separated list of spotify track ids.
-
-    Example: (save-tracks-for-user {:ids \"3BSpuy2yHhoEazfXVU7WGq,0BcaWLANkstu2v9kghrCAj\"} \"BQBw-JtC..._7GvA\")")
-
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids.
+  :ids has to be a comma separated list of spotify track ids.
+
+  Example: (save-tracks-for-user {:ids \"3BSpuy2yHhoEazfXVU7WGq,0BcaWLANkstu2v9kghrCAj\"} \"BQBw-JtC..._7GvA\")")
+
 (def-spotify-api-call get-users-saved-tracks client/get (str spotify-api-url "me/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    There are no compulsory keys in m, optional keys are :market, :limit and :offset.
-    :market is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-users-saved-tracks {:market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  There are no compulsory keys in m, optional keys are :market, :limit and :offset.
+  :market is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-users-saved-tracks {:market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call remove-users-saved-tracks client/delete (str spotify-api-url "me/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids.
-    :ids has to be a comma separated list of spotify track ids.
-
-    Example: (remove-users-saved-tracks {:ids \"1RyZgkIghj1eL2U1zlYOoE,6NwbeybX6TDtXlpXvnUOZC\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids.
+  :ids has to be a comma separated list of spotify track ids.
+
+  Example: (remove-users-saved-tracks {:ids \"1RyZgkIghj1eL2U1zlYOoE,6NwbeybX6TDtXlpXvnUOZC\"} \"BQBw-JtC..._7GvA\")")

 ;TODO - better name for this function
 (def-spotify-api-call check-users-saved-tracks client/get (str spotify-api-url "me/tracks/contains")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids.
-    :ids has to be a comma separated list of spotify track ids.
-
-    Example: (check-users-saved-tracks {:ids \"28nlyt9KhVZQ0lGQsg8Yht,09ZGF6mwJVzw5jxqbtT53E\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids.
+  :ids has to be a comma separated list of spotify track ids.
+
+  Example: (check-users-saved-tracks {:ids \"28nlyt9KhVZQ0lGQsg8Yht,09ZGF6mwJVzw5jxqbtT53E\"} \"BQBw-JtC..._7GvA\")")

 ;Playlists
 (def-spotify-api-call get-a-list-of-a-users-playlists client/get (str spotify-api-url "users/user_id/playlists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in  m is :user_id, optional keys are :limit and :offset.
-    :user_id is the users spotify id.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-list-of-a-users-playlists {:user_id \"elkalel\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in  m is :user_id, optional keys are :limit and :offset.
+  :user_id is the users spotify id.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-list-of-a-users-playlists {:user_id \"elkalel\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 ;TODO - Change this fields string to be a map?
 (def-spotify-api-call get-a-playlist client/get (str spotify-api-url "users/user_id/playlists/playlist_id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :market, :limit and :offset.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :fields is a comma-separated string of fields to return from the playlist.
-     See developer.spotify.com for a full list of field names.
-    :market is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :market, :limit and :offset.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :fields is a comma-separated string of fields to return from the playlist.
+  See developer.spotify.com for a full list of field names.
+  :market is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (get-a-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-a-playlists-tracks client/get (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :limit and :offset and :market.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :fields is a comma-separated string of fields to return from the playlist.
-     See developer.spotify.com for a full list of field names.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\":limit 50 :offset 50 :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :limit and :offset and :market.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :fields is a comma-separated string of fields to return from the playlist.
+  See developer.spotify.com for a full list of field names.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\":limit 50 :offset 50 :market \"SE\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call create-a-playlist client/post (str spotify-api-url "users/user_id/playlists")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :user_id and :name, optional key is :public.
-    :user_id is the users spotify id.
-    :name is the name for the new playlist.
-    :public is set to true if a playlist should be public and false if not.
-
-    Example: (create-a-playlist {:user_id \"elkalel\" :name \"The songs you didn't know you liked.\" :public true} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :user_id and :name, optional key is :public.
+  :user_id is the users spotify id.
+  :name is the name for the new playlist.
+  :public is set to true if a playlist should be public and false if not.
+
+  Example: (create-a-playlist {:user_id \"elkalel\" :name \"The songs you didn't know you liked.\" :public true} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call add-tracks-to-a-playlist client/post (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :uris a list of spotify track uris.
-    :position the position to insert the tracks.
-
-    Example: (add-tracks-to-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
-spotify:track:1301WleyT98MSxVHPZCA6M\" :position 2} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :uris a list of spotify track uris.
+  :position the position to insert the tracks.
+
+  Example: (add-tracks-to-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
+  spotify:track:1301WleyT98MSxVHPZCA6M\" :position 2} \"BQBw-JtC..._7GvA\")")

 ;TODO - Deal with correct formatting of :tracks.
 ;TODO - Additional doc string with optional and required values in :tracks.
 (def-spotify-api-call remove-tracks-from-a-playlist client/delete (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m are :user_id, :playlist_id and :tracks, optional keys is :snapshot_id.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :tracks an array of objects containing spotify URI strings and corresponding position maps.
-    :snapshot_id a playlist snapshot ID.
-     See the spotify developer API for the logic behind deleting tracks.
-
-    Example: (remove-tracks-from-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :tracks [{:uri \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh\", :positions [2]} {:uri \"spotify:track:1301WleyT98MSxVHPZCA6M\", :positions [7]}]}  \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m are :user_id, :playlist_id and :tracks, optional keys is :snapshot_id.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :tracks an array of objects containing spotify URI strings and corresponding position maps.
+  :snapshot_id a playlist snapshot ID.
+  See the spotify developer API for the logic behind deleting tracks.
+
+  Example: (remove-tracks-from-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :tracks [{:uri \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh\", :positions [2]} {:uri \"spotify:track:1301WleyT98MSxVHPZCA6M\", :positions [7]}]}  \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call reorder-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m are :user_id, :playlist_id, :range_start and :insert_before, optional keys are :range_length and :snapshot_id.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :range_start the position of the first track to be reordered.
-    :insert_before the positions where the tracks should be inserted.
-    :range_length the amount of tracks to be reordered.
-    :snapshot_id a playlist snapshot ID.
-
-    Example: (reorder-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :range_start 1 :range_length 2 :insert_before 3} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m are :user_id, :playlist_id, :range_start and :insert_before, optional keys are :range_length and :snapshot_id.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :range_start the position of the first track to be reordered.
+  :insert_before the positions where the tracks should be inserted.
+  :range_length the amount of tracks to be reordered.
+  :snapshot_id a playlist snapshot ID.
+
+  Example: (reorder-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :range_start 1 :range_length 2 :insert_before 3} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call replace-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :uris a list of spotify track uris.
-
-    Example: (replace-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
-spotify:track:1301WleyT98MSxVHPZCA6M\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :uris a list of spotify track uris.
+
+  Example: (replace-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
+  spotify:track:1301WleyT98MSxVHPZCA6M\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call change-a-playlists-details client/put (str spotify-api-url "users/user_id/playlists/playlist_id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m are :user_id and :playlist_id, optional keys are :name and :public.
-    :user_id is the users spotify id.
-    :playlist_id is the playlist spotify id.
-    :name is the name for the new playlist.
-    :public is set to true if a playlist should be public and false if not.
-
-    Example: (change-a-playlists-details {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :name \"Fantastic playlist\" :public true} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m are :user_id and :playlist_id, optional keys are :name and :public.
+  :user_id is the users spotify id.
+  :playlist_id is the playlist spotify id.
+  :name is the name for the new playlist.
+  :public is set to true if a playlist should be public and false if not.
+
+  Example: (change-a-playlists-details {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :name \"Fantastic playlist\" :public true} \"BQBw-JtC..._7GvA\")")

 ;Profiles
 (def-spotify-api-call get-a-users-profile client/get (str spotify-api-url "users/user_id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :user_id.
-    :user_id has to be a spotify user id.
-
-    Example: (get-a-users-profile {:user_id \"elkalel\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :user_id.
+  :user_id has to be a spotify user id.
+
+  Example: (get-a-users-profile {:user_id \"elkalel\"} \"BQBw-JtC..._7GvA\")")

 ;TODO - what happens when map is not present or nil?
 (def-spotify-api-call get-current-users-profile client/get (str spotify-api-url "me")
-" Takes an oauth-token t.
-
-    Example: (get-current-users-profile {} \"BQBw-JtC..._7GvA\")")
+  " Takes an oauth-token t.
+
+  Example: (get-current-users-profile {} \"BQBw-JtC..._7GvA\")")

 ;Search
 (def-spotify-api-call search client/get (str spotify-api-url "search")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory keys in m are :q and :type, optional keys are :market, :limit and :offset.
-    :q is the search string.
-    :type is a comma separated list of items types to search for, album, artist, playlist and track.
-    :market is an ISO 3166-1 alpha-2 country code.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (search {:q \"Gerry Rafferty\" :type \"artist\"  :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory keys in m are :q and :type, optional keys are :market, :limit and :offset.
+  :q is the search string.
+  :type is a comma separated list of items types to search for, album, artist, playlist and track.
+  :market is an ISO 3166-1 alpha-2 country code.
+  :limit is the maxium number of tracks to return, default is 20.
+  :offset is the index of the first track to return, default is 0.
+
+  Example: (search {:q \"Gerry Rafferty\" :type \"artist\"  :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

 ;Tracks
 (def-spotify-api-call get-a-track client/get (str spotify-api-url "tracks/id")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :id, optional key is :market.
-    :id has to have the value of an existing track's id.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-a-track {:id \"3BEmmHuv5jm0tbCUVI6ceD\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :id, optional key is :market.
+  :id has to have the value of an existing track's id.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-a-track {:id \"3BEmmHuv5jm0tbCUVI6ceD\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")

 (def-spotify-api-call get-several-tracks client/get (str spotify-api-url "tracks")
-" Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in m is :ids, optional key is :market.
-    :ids has to be a comma separated string of spotify track ids.
-    :market is an ISO 3166-1 alpha-2 country code.
-
-    Example: (get-several-tracks {:ids \"2Dlo9QsN9ohaz9kASYkKmv,6XYvLpqJFebcjnOTolwkGw\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+  " Takes two arguments, a map m with query parameters and an optional oauth-token t.
+  Compulsory key in m is :ids, optional key is :market.
+  :ids has to be a comma separated string of spotify track ids.
+  :market is an ISO 3166-1 alpha-2 country code.
+
+  Example: (get-several-tracks {:ids \"2Dlo9QsN9ohaz9kASYkKmv,6XYvLpqJFebcjnOTolwkGw\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")


tested in the REPL cuz that's how I roll

--- src/cljs/bmihw/core.cljs
+++ src/cljs/bmihw/core.cljs
@@ -27,7 +27,7 @@
 ;; Views
 (defn home-page []
   [:div [:h2 "Welcome to bmihw"]
-   [:input {:type "button" :value "Auth me!"
+   [:input {:type "button" :value "Login"
             :on-click #(auth-twitter)}]
    [:div @stuff]
    [:div [:a {:href "#/about"} "go to about page"]]])


Kind of obvious missing check that we can actually call the primtive method

--- src/cljs/go/compiler.clj
+++ src/cljs/go/compiler.clj
@@ -700,6 +700,7 @@
        (emits f "(" (comma-sep args)  ")")

        has-primitives?
+       ;; We need to double check that our args match the receiver, otherwise fall down to :else, or convert them here.
        (emits f ".Arity" arity primitive-sig "(" (comma-sep args) ")")

        :else


fix alert rendering/removal

fix alert rendering/removal

--- src/cljs/clj_money/bootstrap.cljs
+++ src/cljs/clj_money/bootstrap.cljs
@@ -67,15 +67,15 @@
            (nav-item item))]])]]])

 (defn- alert
-  [{:keys [id message severity]
-    :or {severity :info}}
+  [{:keys [message severity]
+    :or {severity :info}
+    :as alert}
    remove-fn]
-  ^{:key id}
   [:div {:class ["alert" (str "alert-" (name severity))]
          :role "alert"}
    [:button.close {:type :button
                    :aria-label "Close"
-                   :on-click remove-fn}
+                   :on-click (fn [_] (remove-fn alert))}
     [:span.glyphicon.glyphicon-remove {:aria-hidden "true"}]]
    message])

@@ -88,4 +88,4 @@
     [:div#notifications.row
      [:div.col-md-6.col-md-offset-3
       (for [a @alerts]
-        [alert a remove-fn])]]))
+        (with-meta [alert a remove-fn] {:key (:id a)}))]]))


Add AdminId to Organization Create

Add AdminId to Organization Create

--- src/cljs/elevent_client/core.cljs
+++ src/cljs/elevent_client/core.cljs
@@ -2102,7 +2102,7 @@
             (fn [form]
               (fn [callback]
                 (organizations-endpoint :create
-                                        form
+                                        (assoc form :AdminId (get-in @session [:user :UserId]))
                                         #(do
                                            (callback)
                                            (js/location.replace (organizations-route))))))]


Revert "GAWB-2103 redirect user after registration (#821)" (#826)

This reverts commit a826947f1cac44a10645ed5aaaa7eadd9a34815d.
Merged too soon, oops...

--- src/cljs/main/broadfcui/main.cljs
+++ src/cljs/main/broadfcui/main.cljs
@@ -78,46 +78,40 @@
                                                   :text [:span {} "FireCloud Forum" icons/external-link-icon]}]})]
           (when (= :registered (:registration-status @state))
             [header/GlobalSubmissionStatus])]]
-        (let [original-destination (aget js/window "location" "hash")
-              on-done (fn [fall-through]
-                        (when (empty? original-destination)
-                          (nav/go-to-path fall-through))
-                        (this :-get-registration-status))]
-          (case (:registration-status @state)
-            nil [:div {:style {:margin "2em 0" :textAlign "center"}}
-                 [comps/Spinner {:text "Loading user information..."}]]
-            :error [:div {:style {:margin "2em 0"}}
-                    (style/create-server-error-message (.-errorMessage this))]
-            :not-registered (profile-page/render
-                             {:new-registration? true
-                              :on-done #(on-done :library)})
-            :update-registered (profile-page/render
-                                {:update-registration? true
-                                 :on-done #(on-done :workspaces)})
-            :registered
-            (if component
-              [component (make-props)]
-              [:h2 {} "Page not found."])))]))
+        (case (:registration-status @state)
+          nil [:div {:style {:margin "2em 0" :textAlign "center"}}
+               [comps/Spinner {:text "Loading user information..."}]]
+          :error [:div {:style {:margin "2em 0"}}
+                  (style/create-server-error-message (.-errorMessage this))]
+          :not-registered (profile-page/render
+                           {:new-registration? true
+                            :on-done #(do (nav/go-to-path :library)
+                                          (js-invoke (aget js/window "location") "reload"))})
+          :update-registered (profile-page/render
+                              {:update-registration? true
+                               :on-done #(do (nav/go-to-path :workspaces)
+                                             (js-invoke (aget js/window "location") "reload"))})
+          :registered
+          (if component
+            [component (make-props)]
+            [:h2 {} "Page not found."]))]))
    :component-did-mount
    (fn [{:keys [this state]}]
      (when (nil? (:registration-status @state))
-       (this :-get-registration-status)))
-   :-load-registration-status
-   (fn [{:keys [this state]}]
-     (endpoints/profile-get
-      (fn [{:keys [success? status-text get-parsed-response]}]
-        (let [parsed-values (when success? (common/parse-profile (get-parsed-response false)))]
-          (cond
-            (and success? (>= (int (:isRegistrationComplete parsed-values)) 3))
-            (swap! state assoc :registration-status :registered)
-            (and success? (some? (:isRegistrationComplete parsed-values))) ; partial profile case
-            (swap! state assoc :registration-status :update-registered)
-            success?                                        ; unregistered case
-            (swap! state assoc :registration-status :not-registered)
-            :else
-            (do
-              (set! (.-errorMessage this) status-text)
-              (swap! state assoc :registration-status :error)))))))})
+       (endpoints/profile-get
+        (fn [{:keys [success? status-text get-parsed-response]}]
+          (let [parsed-values (when success? (common/parse-profile (get-parsed-response false)))]
+            (cond
+              (and success? (>= (int (:isRegistrationComplete parsed-values)) 3))
+              (swap! state assoc :registration-status :registered)
+              (and success? (some? (:isRegistrationComplete parsed-values))) ; partial profile case
+              (swap! state assoc :registration-status :update-registered)
+              success? ; unregistered case
+              (swap! state assoc :registration-status :not-registered)
+              :else
+              (do
+                (set! (.-errorMessage this) status-text)
+                (swap! state assoc :registration-status :error))))))))})

 (defn- show-system-status-dialog [maintenance-mode?]
   (comps/push-ok-cancel-modal


remove useless checks

remove useless checks

--- src/cljs/triboard/logic/move.cljs
+++ src/cljs/triboard/logic/move.cljs
@@ -36,8 +36,6 @@
    :looser :red,
    :taken [[8 5] [9 5]]}"
   [board [xi yi :as coord] [dx dy]]
-  {:pre [(board/board? board) (board/coord? coord)]
-   :post [(or (nil? %) (move? %))]}
   (loop [x (+ xi dx)
          y (+ yi dy)
          looser nil


maved details back

maved details back

--- src/cljs/work_sessions/views.cljs
+++ src/cljs/work_sessions/views.cljs
@@ -54,7 +54,7 @@
                     }
                    [:span
                     (:text header)]
-                   #_[:span.visible-hovered
+                   [:span.visible-hovered
                     (condp = (:details header)
                       :schedule
                       (gstring/unescapeEntities " -> Schedule -> ")


Added generator-as-set to constrain pixel output for downsample in static.


Rename fix.

Rename fix.


Use if-not to kill a set of braces.

Use if-not to kill a set of braces.

--- src/overtunes/songs/canone_alla_quarta.clj
+++ src/overtunes/songs/canone_alla_quarta.clj
@@ -30,7 +30,7 @@

 (defn sum-n [series n] (reduce + (take n series)))
 (defn scale [intervals]
-  #(if (not (neg? %))
+  #(if-not (neg? %)
      (sum-n (cycle intervals) %)
      (=> % - (scale (reverse intervals)) -)))

@@ -122,7 +122,7 @@
     (=> melody (skew pitch -) (shift [7/2 -3]) play-now#)))

 ;((bpm 120) 2)
-(canone-alla-quarta#)
+;(canone-alla-quarta#)


add docstring to genkey and update fns

add docstring to genkey and update fns

--- src/asphalt/core.clj
+++ src/asphalt/core.clj
@@ -300,6 +300,8 @@

 (defn genkey
+  "Execute an update statement returning the keys generated by the statement. The generated keys are extracted from a
+  java.sql.ResultSet instance using the optional result-set-worker argument."
   ([data-source-or-connection sql-or-template params]
     (genkey i/set-params! fetch-single-value data-source-or-connection sql-or-template params))
   ([result-set-worker data-source-or-connection sql-or-template params]
@@ -319,6 +321,7 @@

 (defn update
+  "Execute an update statement returning the number of rows impacted."
   ([data-source-or-connection sql-or-template params]
     (update i/set-params! data-source-or-connection sql-or-template params))
   ([params-setter data-source-or-connection sql-or-template params]


more breaking it out

more breaking it out

--- src/advent/core.clj
+++ src/advent/core.clj
@@ -233,6 +233,26 @@
       (bit-not-unsigned value)
       (bit-not-unsigned (callable (keyword value) circuit)))))

+(defn handle-ops [signal circuit callable]
+  (case (count (signal circuit))
+    2 (handle-not (last (signal circuit)) circuit callable)
+    ; handle LSHIFT RSHIFT AND OR
+    3 (let [[left-val-raw opcode right-val-raw] (signal circuit)
+            left-val-parsed (parse-int-if-possible left-val-raw)
+            right-val-parsed (parse-int-if-possible right-val-raw)
+            left-val (if (number? left-val-parsed)
+                       left-val-parsed
+                       (callable (keyword left-val-parsed) circuit))
+            right-val (if (number? right-val-parsed)
+                        right-val-parsed
+                        (callable (keyword right-val-parsed) circuit))]
+        (case opcode
+          "LSHIFT" (bit-shift-left left-val right-val)
+          "RSHIFT" (bit-shift-right left-val right-val)
+          "AND" (bit-and left-val right-val)
+          "OR" (bit-or left-val right-val))
+        )))
+
 (def ^{:doc "returns the value of signal (keyword) within a circuit (map)\n  Usage: (find-signal :i sample-built-circuit)"}
   find-signal
   (memoize (fn
@@ -241,25 +261,7 @@
                (signal circuit)
                (if (string? (signal circuit))  ; either a string, "lx", or array, ["x" "LSHIFT" "y"] or ["NOT" "x"]
                  (find-signal (keyword (signal circuit)) circuit)
-                 (case (count (signal circuit))
-                   ; handle NOT
-                   2 (handle-not (last (signal circuit)) circuit find-signal)
-                   ; handle LSHIFT RSHIFT AND OR
-                   3 (let [[left-val-raw opcode right-val-raw] (signal circuit)
-                           left-val-parsed (parse-int-if-possible left-val-raw)
-                           right-val-parsed (parse-int-if-possible right-val-raw)
-                           left-val (if (number? left-val-parsed)
-                                      left-val-parsed
-                                      (find-signal (keyword left-val-parsed) circuit))
-                           right-val (if (number? right-val-parsed)
-                                       right-val-parsed
-                                       (find-signal (keyword right-val-parsed) circuit))]
-                       (case opcode
-                         "LSHIFT" (bit-shift-left left-val right-val)
-                         "RSHIFT" (bit-shift-right left-val right-val)
-                         "AND" (bit-and left-val right-val)
-                         "OR" (bit-or left-val right-val))
-                       )))))))
+                 (handle-ops signal circuit find-signal))))))

 ; Timing: the memozied version copletes in 0.055178 msecs, the non-memoized version never completed
 ; as it probably went into swap


Add make-fixture for stress testing.

Add make-fixture for stress testing.

--- src/clj/com/draines/postal/message.clj
+++ src/clj/com/draines/postal/message.clj
@@ -1,7 +1,7 @@
 (ns com.draines.postal.message
   (:use [clojure.test :only [run-tests deftest is]]
         [com.draines.postal.date :only [make-date]])
-  (:import [java.util Properties]
+  (:import [java.util Properties UUID]
            [javax.mail Session Message$RecipientType]
            [javax.mail.internet MimeMessage InternetAddress]))

@@ -77,6 +77,14 @@
          (.setSentDate (or date (make-date)))
          (add-body! body)))))

+(defn make-fixture [from to & {:keys [tag]}]
+  (let [uuid (str (UUID/randomUUID))
+        tag (or tag "[POSTAL]")]
+    {:from from
+     :to to
+     :subject (format "%s Test -- %s" tag uuid)
+     :body (format "Test %s" uuid)}))
+
 (deftest test-simple
   (let [m {:from "fee@bar.dom"
            :to "Foo Bar <foo@bar.dom>"
@@ -125,5 +133,10 @@
     (is (= "tempfile" (re-find #"tempfile" (message->str m))))
     (.delete f1)))

-(comment
-  (run-tests))
+(deftest test-fixture
+  (let [from "foo@bar.dom"
+        to "baz@bar.dom"
+        tag "[TEST]"]
+    (is (re-find #"^\[TEST" (:subject (make-fixture from to :tag tag))))))
+
+


minor refactors

minor refactors

--- src/cljs/om_datagrid_example/core.cljs
+++ src/cljs/om_datagrid_example/core.cljs
@@ -14,10 +14,17 @@
                                   {:first "Eva" :last "Ator" :email "eval@mit.edu"}
                                   {:first "Louis" :last "Reasoner" :email "prolog@mit.edu"}
                                   {:first "Cy" :last "Effect" :email "bugs@mit.edu"}
-                                  {:first "Lem" :last "Tweakit" :email "morebugs@mit.edu"}]}))
+                                  {:first "Lem" :last "Tweakit" :email "morebugs@mit.edu"}
+                                  {:first "John" :last "Wein" :email "wein@mit.edu"}
+                                  {:first "Laura" :last "Mit" :email "aphacker@mit.edu"}
+                                  {:first "Vicky" :last "Gold" :email "gold@mit.edu"}
+                                  {:first "Louis" :last "Amstrong" :email "prolog@mit.edu"}
+                                  {:first "Carol" :last "Corner" :email "corner@mit.edu"}
+                                  {:first "Jason" :last "Smith" :email "smith@mit.edu"}]}))

-(defn view-row [contact]
-  (map #(d/td nil %) contact))
+
+(defn get-headers [data]
+  (keys (stringify-keys (first data))))

 (defn main []
   (om/root
@@ -31,9 +38,9 @@
                         (table {:striped? true :bordered? true :condensed? true :hover? true}
                                (d/thead
                                  (d/tr
-                                   (map #(d/th nil %) (keys (stringify-keys (first (:data @app-state)))))))
+                                   (map #(d/th nil %) (get-headers (:data app)))))
                                (d/tbody
-                                 (for [row (:data @app-state)]
+                                 (for [row (:data app)]
                                    (d/tr
                                      (for [col row]
                                        (d/td (last col)))))


fix port issue

fix port issue

--- src/clj/bulldog/core.clj
+++ src/clj/bulldog/core.clj
@@ -92,8 +92,9 @@
     state))

 (defn -main [& args]
-  (start-all-services (or (Integer/parseInt (System/getenv "PORT")) 8080) "bamboozle")
-  (println "Server startet at localhost:8080"))
+  (let [port (second args)]
+    (start-all-services (if port (Integer/parseInt port) 8080) "bamboozle")
+    (println "Server startet at localhost:8080")))

 (comment

@@ -122,6 +123,7 @@
        test-articles
        )
       <!!)
+  bamboozle

   (-> state deref :store (-get-in [:articles]) <!! vals)


Added application/iso19115+xml to supported mime-types for bulk indexing.

--- src/cmr/indexer/data/elasticsearch.clj
+++ src/cmr/indexer/data/elasticsearch.clj
@@ -19,6 +19,11 @@
             [cmr.common.time-keeper :as tk]
             [cheshire.core :as json]))

+(def supported-formats
+  "Defines the set of supported concept forms, new forms shold be added once it is supported."
+  #{"application/echo10+xml" "application/dif+xml" "application/iso:smap+xml"
+    "application/iso19115+xml"})
+
 (defmulti concept->elastic-doc
   "Returns elastic json that can be used to insert into Elasticsearch for the given concept"
   (fn [context concept umm-concept]
@@ -156,10 +161,6 @@
   "Returns the elastic config in the context"
   [context]
   (get-in context [:system :db :config]))
-
-(def supported-formats
-  "Defines the set of supported concept forms, new forms shold be added once it is supported."
-  #{"application/echo10+xml" "application/dif+xml" "application/iso:smap+xml"})

 (defn prepare-batch
   "Convert a batch of concepts into elastic docs for bulk indexing."


add some missing source-map customization flags to optimized builds

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -663,8 +663,10 @@
                      :lines (+ (:lineCount sm-json) preamble-line-count 2)
                      :file (:file sm-json)
                      :output-dir (util/output-directory opts)
+                     :source-map (:source-map opts)
                      :source-map-path (:source-map-path opts)
-                     :source-map (:source-map opts)
+                     :source-map-timestamp (:source-map-timestamp opts)
+                     :source-map-pretty-print (:source-map-pretty-print opts)
                      :relpaths relpaths}))))))
         source)
       (report-failure result))))


s/trace/debug/

s/trace/debug/

--- src/babel/parse.cljc
+++ src/babel/parse.cljc
@@ -61,7 +61,7 @@
                    spans)))))

 (defn parses [input n model span-map]
-  (log/trace (str "calling parses " n "; span-maps: " (get span-map n)))
+  (log/debug (str "(parses " n "; span-maps: " (get span-map n) ")"))
   (cond
     (= n 1) input
     (> n 1)


Added rough timeseries function.

Added rough timeseries function.

--- src/clj/forma/trends.clj
+++ src/clj/forma/trends.clj
@@ -1,3 +1,13 @@
 ;; This is where we'll be implementing OLS regression.

-(ns forma.trends)+(ns forma.trends
+  (:use cascalog.api))
+
+(defaggregateop timeseries
+  ^{:doc "Takes in a number of vectors, pre-sorted by time period,
+representing the same MODIS chunk within a dataset, and aggregates
+them by building a time series vector of vectors. Entering chunks
+should be sorted in descending order."}
+  ([] [])
+  ([ts val] (conj ts (vec val)))
+  ([ts] ts))


Fix some reflection

Fix some reflection

--- src/clj_similar/core.clj
+++ src/clj_similar/core.clj
@@ -8,7 +8,7 @@
   [v->idx s]
   (let [ts (TreeSet.)]
     (doseq [c s]
-      (.add ts (get v->idx c (int 0))))
+      (.add ^TreeSet ts (get v->idx c (int 0))))
     ts))

 (defn index-sets
@@ -38,7 +38,7 @@
         sets (index-sets v->idx coll)

         hasher (MinHash. error (int dict-size))
-        hash-fn #(into [] (.signature hasher %))
+        hash-fn #(into [] (.signature ^MinHash hasher %))
         h (minhash-sets hash-fn sets)
         tree (kdtree/build-tree h)]
     (Similar. v->idx tree hash-fn)))


Neater, better error message.

Neater, better error message.

--- src/asid/accept.clj
+++ src/asid/accept.clj
@@ -9,18 +9,22 @@
             [clojure.tools.logging :as log]))

 (defn- meet-challenge? [conn-req wallet]
-  (let [challenge-set (set (:pool-challenge conn-req))]
+  (let [challenge-set (set (:pool-challenge conn-req))
+        bag-key-set (-> wallet :bag keys set)]
     (log/debug "Challenge: " (cs/join ", " challenge-set))
-    (log/debug "Bag: " (cs/join ", " (-> wallet :bag keys set)))
-    (if (set/subset? challenge-set (-> wallet :bag keys set))
+    (log/debug "Bag keys: " (cs/join ", " bag-key-set))
+    (if (set/subset? challenge-set bag-key-set)
       conn-req
-      (ed/precondition-failed (str "Must have in bag: " (cs/join ", " challenge-set))))))
+      (ed/precondition-failed (str "Missing from bag: "
+                                   (cs/join ", " (set/difference challenge-set
+                                                                 bag-key-set)))))))

 (fact "unable to meet the challenge"
   (let [conn-req {:pool-challenge ["dob"]}
         wallet {:bag {"name" "a-name"}}
         challenged (meet-challenge? conn-req wallet)]
-    (:status challenged) => 412))
+    (:status challenged) => 412
+    (:message challenged) => "Missing from bag: dob"))

 (defn accept [conn-req wallet updates]
   (fail-> (meet-challenge? conn-req wallet)))


fix bug in write-edn-file-by

fix bug in write-edn-file-by

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -847,7 +847,7 @@
    (let [opts (assoc options :label (str "write-edn-file-to-" (clean-filename to))
                      :coder nil)]
      (apply-transform pcoll (write-edn-file-transform to opts)
-                      (merge base-schema text-writer-schema) opts)))
+                      named-schema opts)))
   ([to pcoll] (write-edn-file to {} pcoll)))

 (defn make-partition-mapping
@@ -882,7 +882,7 @@
   ([encoder f mapping to options ^PCollection pcoll]
    (let [opts (assoc options :label "write-edn-file-by" :coder nil)
          ptrans (write-text-file-by-transform encoder f mapping to opts)]
-     (apply-transform pcoll ptrans (merge base-schema text-writer-schema) opts)))
+     (apply-transform pcoll ptrans named-schema opts)))
   ([encoder f mapping to pcoll] (write-file-by encoder f  mapping to {} pcoll)))

 (def write-edn-file-by (partial write-file-by write-edn-file))


add id back in

add id back in

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/aurora/ast.cljs
+++ src/aurora/ast.cljs
@@ -87,6 +87,7 @@
          (every? #(branch! index %) (:branches x))))

 (deftraced step! [index x] [x]
+  (check (id! index (:id x)))
   (case (:type x)
     :call (call! index x)
     :constant (constant! index x)
@@ -98,6 +99,7 @@

 (deftraced page! [index x] [x]
   (check (= :page (:type x))
+         (id! index (:id x))
          (sequential? (:args x))
          (every? #(page-arg! index (get index %)) (:args x))
          (sequential? (:steps x))
@@ -105,6 +107,7 @@

 (deftraced notebook! [index x] [x]
   (check (= :notebook (:type x))
+         (id! index (:id x))
          (sequential? (:pages x))
          (every? #(page! index (get index %)) (:pages x))))

@@ -112,21 +115,27 @@

 (def example-a
   {"example_a" {:type :notebook
+                :id "example_a"
                 :pages ["root"]}
    "root" {:type :page
+           :id "root"
            :args ["a" "b" "c"]
            :steps ["b_squared" "four" "four_a_c" "result"]}
    "b_squared" {:type :call
+                :id "b_squared"
                 :ref {:type :ref/js
                       :js "cljs.core._STAR_"}
                 :args [{:type :ref/id :id "b"} {:type :ref/id :id "b"}]}
    "four" {:type :constant
+           :id "four"
            :data 4}
    "four_a_c" {:type :call
+               :id "four_a_c"
                :ref {:type :ref/js
                      :js "cljs.core._STAR_"}
                :args [{:type :ref/id :id "four"} {:type :ref/id :id "a"} {:type :ref/id :id "c"}]}
    "result" {:type :call
+             :id "result"
              :ref {:type :ref/js
                    :js "cljs.core._"}
              :args [{:type :ref/id :id "b_squared"} {:type :ref/id :id "four_a_c"}]}})
@@ -135,8 +144,10 @@

 (def example-b
   {"example_b" {:type :notebook
+                :id "example_b"
                :pages ["root"]}
    "root" {:type :page
+           :id "root"
            :args ["x"]
            :steps ["result"]}
    "result" {:id "result"


CTH-130 rename handle-delivery-exception

Rename handle-delivery-exception -> handle-delivery-failure and add a failure
reason to its signature.  This reflects that we may not always be dealing with
an exception, but we are always dealing with a failure to deliver.

--- src/puppetlabs/cthun/connection_states.clj
+++ src/puppetlabs/cthun/connection_states.clj
@@ -58,17 +58,19 @@
   [host ws]
   (= (get-in @connection-map [ws :status]) "ready"))

-(defn- handle-delivery-exception
-  [message]
+(defn- handle-delivery-failure
+  [message reason]
+  "If the message is not expired schedule for a future redelivery by adding to the redeliver queue"
   (let [expires (time-coerce/to-date-time (:expires message))
         now     (time/now)]
     (if (time/after? expires now)
       (do
-        (log/info "Failed to deliver message" message)
+        (log/info "Failed to deliver message" message reason)
         (let [difference     (time/in-seconds (time/interval now expires))
               sleep-duration (if (<= (/ difference 2) 1) 1 (float (/ difference 2)))
               message        (message/add-hop message "redelivery")]
-          (log/info "Moving message back to the accept queue in " sleep-duration " seconds")
+          (log/info "Moving message to the redeliver queue in " sleep-duration " seconds")
+          ;; TODO(richardc): we should queue for future delivery, not sleep
           (Thread/sleep (* sleep-duration 1000))
           (activemq/queue-message "redeliver" message)))
       (log/warn "Message " message " has expired. Dropping message"))))
@@ -86,8 +88,8 @@
                  (let [message (message/add-hop message "deliver")]
                    (jetty-adapter/send! websocket (byte-array (map byte (message/encode message))))))
       (catch Exception e
-        (.start (Thread. (fn [] (handle-delivery-exception message))))))
-    (.start (Thread. (fn [] (handle-delivery-exception message))))))
+        (.start (Thread. (fn [] (handle-delivery-failure message e))))))
+    (.start (Thread. (fn [] (handle-delivery-failure message "not connected"))))))

 (defn messages-to-destinations
   "Returns a sequence of messages, each with a single endpoint in


read `(+|-)?Infinity` and `NaN` as per #CLJ-1074

--- src/blind/reader.clj
+++ src/blind/reader.clj
@@ -423,6 +423,9 @@
       "true" true
       "false" false
       "/" '/
+      "NaN" Double/NaN
+      "-Infinity" Double/NEGATIVE_INFINITY
+      ("Infinity" "+Infinity") Double/POSITIVE_INFINITY

       (or (when-let [p (parse-symbol token)]
             (symbol (p 0) (p 1)))


Tundra: fix conn defaults overriding given conn

--- src/taoensso/carmine/tundra.clj
+++ src/taoensso/carmine/tundra.clj
@@ -222,8 +222,8 @@
             (timbre/trace "Worker job running:" wopts)
             (let [kdset (tkey :dirty)
                   kcset (tkey :cleaning)
-                  [ks-dirty ks-cleaning] (wcar {} (car/smembers kdset)
-                                                  (car/smembers kcset))
+                  [ks-dirty ks-cleaning] (wcar conn (car/smembers kdset)
+                                                    (car/smembers kcset))

                   ;; Grab ks from both dirty AND cleaning sets (the
                   ;; latter will be empty unless prev work-fn failed):
@@ -231,9 +231,9 @@

               (when-not (empty? ks-to-freeze)
                 (timbre/trace "Freezing keys:" ks-to-freeze)
-                (wcar {} (mapv (partial car/smove kdset kcset) ks-to-freeze))
+                (wcar conn (mapv (partial car/smove kdset kcset) ks-to-freeze))
                 (let [dumps ; [<raw-data-or-nil> ...]
-                      (wcar {} (car/parse-raw (mapv car/dump ks-to-freeze)))
+                      (wcar conn (car/parse-raw (mapv car/dump ks-to-freeze)))

                       keyed-data ; {<existing-redis-key> <frozen-data> ...}
                       (let [thawed-data
@@ -256,7 +256,7 @@
                           ks-failed    (vec (reduce disj (set ks-to-freeze)
                                                     ks-succeeded))]

-                      (wcar {} (mapv (partial car/srem kcset) ks-succeeded))
+                      (wcar conn (mapv (partial car/srem kcset) ks-succeeded))
                       (when-not (empty? ks-failed) ; Don't rethrow!
                         (let [ex (ex-info "Failed to freeze some key(s)"
                                           {:failed-ks ks-failed})]


adding min lein version

adding min lein version

--- src/leiningen/new/devcards/project.clj
+++ src/leiningen/new/devcards/project.clj
@@ -4,6 +4,8 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}

+  :min-lein-version "2.5.3"
+
   :dependencies [[org.clojure/clojure "1.7.0"]
                  [org.clojure/clojurescript "1.7.170"]
                  [devcards "0.2.1-5"]
@@ -17,7 +19,7 @@

                  #_[org.omcljs/om "0.9.0"]
                  #_[reagent "0.5.1"]]
-
+
   :plugins [[lein-figwheel "0.5.0-5"]
             [lein-cljsbuild "1.1.2" :exclusions [org.clojure/clojure]]]


Remove scan-size helper.

Remove scan-size helper.

--- src/blocks/core.clj
+++ src/blocks/core.clj
@@ -246,11 +246,3 @@
         (drop-while #(pos? (compare after (multihash/hex (:id %)))))
       limit
         (take limit))))
-
-
-(defn scan-size
-  "Scans the blocks in a store to determine the total stored content size."
-  [store]
-  (->> (-list store nil)
-       (map (comp :size (partial stat store)))
-       (reduce + 0N)))


Add alias for common known names of types.


fix unbatched brace from bad merge

fix unbatched brace from bad merge

--- src/cake/server.clj
+++ src/cake/server.clj
@@ -131,7 +131,7 @@
                             *env*     (:env vars)
                             *opts*    (:opts vars)
                             *script*  (:script vars)
-                            *context* (get-in *project* [:environments (get-env vars)])]]
+                            *context* (get-in *project* [:environments (get-env vars)])]
                     (if (keyword? form)
                       (when-let [command (or (commands form) (default-commands form))]
                         (command))


Transpose shouldn't drop probes with missing values.

--- src/cgdata/core.clj
+++ src/cgdata/core.clj
@@ -300,8 +300,12 @@
   (let [lines (ammend-lines lines)]
     (chunked-pmap #(data-line features (tabbed %)) lines)))

-(defn- transpose [lines]
-  (apply mapv vector lines))
+(defn- transpose
+  "Transpose cells of a tsv, using the first row to fix the number of columns."
+  [lines]
+  (let [pcount (count (first lines))]
+    (into [] (for [i (range pcount)]
+               (mapv #(get % i "") lines)))))

 (defmethod matrix-data "clinicalMatrix"
   [metadata features lines]


Adjust call order in 'using-once'

Adjust call order in 'using-once'

--- src/main/clojure/lazytest/describe.clj
+++ src/main/clojure/lazytest/describe.clj
@@ -98,12 +98,12 @@
     (assert (even? (count bindings)))
     `(let ~bindings
        (suite (fn []
-		(add-context
-		 (test-seq
+		(test-seq
+		 (add-context
 		  (with-meta
 		    (flatten (list ~@children))
-		    ~metadata))
-		 ~@binding-symbols))))))
+		    ~metadata)
+		  ~@binding-symbols)))))))

 (defmacro it
   "Defines a single test case.


fix user supplied configuration

fix user supplied configuration

--- src/chessground.cljs
+++ src/chessground.cljs
@@ -3,7 +3,8 @@
             [chessground.common :refer [pp]]
             [chessground.api :as api]
             [chessground.render :as render]
-            [chessground.data :as data])
+            [chessground.data :as data]
+            [clojure.walk :refer [keywordize-keys]])
   (:require-macros [cljs.core.async.macros :as am]))

 (defn load-app
@@ -46,7 +47,7 @@
 (defn ^:export main
   "Application entry point; returns the public JavaScript API"
   [dom-element config]
-  (let [app (load-app dom-element (or config {}))]
+  (let [app (load-app dom-element (or (keywordize-keys (js->clj config)) {}))]
     (init-updates app)
     (render/request-render app)
     (api/build (:channels app))))


Correct var name

Correct var name

--- src/day8/re_frame/trace/view/subs.cljs
+++ src/day8/re_frame/trace/view/subs.cljs
@@ -234,11 +234,11 @@
    :children [[rc/label :label "There are no subscriptions to show"]]])

 (defn pod-section []
-  (let [all-subs       @(rf/subscribe [:subs/visible-subs])
+  (let [visible-subs   @(rf/subscribe [:subs/visible-subs])
         sub-expansions @(rf/subscribe [:subs/sub-expansions])
         all-subs       (if @(rf/subscribe [:settings/debug?])
-                         (cons {:id "debug" :value @(rf/subscribe [:subs/current-epoch-sub-state])} all-subs)
-                         all-subs)]
+                         (cons {:id "debug" :value @(rf/subscribe [:subs/current-epoch-sub-state])} visible-subs)
+                         visible-subs)]
     [rc/v-box
      :size "1"
      ;:gap pod-gap


reset level back to 0

reset level back to 0

--- src/client/core.cljs
+++ src/client/core.cljs
@@ -50,7 +50,7 @@
                   :board empty-board

                   :score 0
-                  :level 3
+                  :level 0
                   :level-lines 0
                   :total-lines 0


docstrings

docstrings

--- src/clj/protobuf.clj
+++ src/clj/protobuf.clj
@@ -4,22 +4,31 @@
            (com.google.protobuf Descriptors$Descriptor Descriptors$FieldDescriptor CodedInputStream)
            (java.io InputStream OutputStream)))

-(defn protobuf? [obj]
+(defn protobuf?
+  "Is the given object a PersistentProtocolBufferMap?"
+  [obj]
   (instance? PersistentProtocolBufferMap obj))

-(defn protodef? [obj]
+(defn protodef?
+  "Is the given object a PersistentProtocolBufferMap$Def?"
+  [obj]
   (instance? PersistentProtocolBufferMap$Def obj))

-(defn protodef [class]
+(defn protodef
+  "Create a protodef from a string or protobuf class."
+  [class]
   (if (or (protodef? class) (nil? class))
     class
     (PersistentProtocolBufferMap$Def/create class)))

-(defmacro defprotobuf [sym & args]
+(defmacro defprotobuf
+  "Helper macro for defining a protodef object."
+  [sym & args]
   (let [class (apply str (interpose "$" (map name args)))]
     `(def ~sym (protodef ~class))))

 (defn protobuf
+  "Construct a protobuf of the given type."
   ([^PersistentProtocolBufferMap$Def type]
      (PersistentProtocolBufferMap/construct type {}))
   ([^PersistentProtocolBufferMap$Def type m]
@@ -27,11 +36,15 @@
   ([^PersistentProtocolBufferMap$Def type k v & kvs]
      (PersistentProtocolBufferMap/construct type (apply array-map k v kvs))))

-(defn protodefault [type key]
+(defn protodefault
+  "Return the default empty protobuf of the given type."
+  [type key]
   (let [type ^PersistentProtocolBufferMap$Def (protodef type)]
     (.defaultValue type key)))

-(defn protofields [type]
+(defn protofields
+  "Return a map of the protobuf fields to the clojure.protobuf.Extensions metadata for each field."
+  [type]
   (let [type ^PersistentProtocolBufferMap$Def (protodef type)
         type ^Descriptors$Descriptor (.getMessageType type)]
     (into {}
@@ -41,6 +54,7 @@
           [field-name (when-not (empty? meta-string) (read-string meta-string))])))))

 (defn protobuf-load
+  "Load a protobuf of the given type from an array of bytes."
   ([^PersistentProtocolBufferMap$Def type ^bytes data]
      (when data
        (PersistentProtocolBufferMap/create type data)))
@@ -50,22 +64,30 @@
          (PersistentProtocolBufferMap/parseFrom type in)))))

-(defn protobuf-dump [^PersistentProtocolBufferMap p]
+(defn protobuf-dump
+  "Return the byte representation of the given protobuf."
+  [^PersistentProtocolBufferMap p]
   (.toByteArray p))

-(defn protobuf-seq [^PersistentProtocolBufferMap$Def type in]
+(defn protobuf-seq
+  "Lazily read a sequence of length-delimited protobufs of the specified type from the given input stream."
+  [^PersistentProtocolBufferMap$Def type in]
   (lazy-seq
    (io!
     (let [^InputStream in (input-stream in)]
       (when-let [p (PersistentProtocolBufferMap/parseDelimitedFrom type in)]
         (cons p (protobuf-seq type in)))))))

-(defn protobuf-write [out & ps]
+(defn protobuf-write
+  "Write the given protobufs to the given output stream, prefixing each with its length to delimit them."
+  [out & ps]
   (io!
    (let [^OutputStream out (output-stream out)]
      (doseq [^PersistentProtocolBufferMap p ps]
        (.writeDelimitedTo p out))
      (.flush out))))

-(defn append [^PersistentProtocolBufferMap p map]
+(defn append
+  "Merge the given map into the protobuf. Equivalent to appending the byte representations."
+  [^PersistentProtocolBufferMap p map]
   (.append p map))


Use fn-args as completion hint.

Use fn-args as completion hint.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -71,7 +71,7 @@
         arg-completers (reduce
                          (fn [v k]
                            (conj v (ArgumentCompleter. [(StringsCompleter. (conj (vec (map name (cmd-aliases k))) (name k)))
-                                                        (StringsCompleter. ["foo" "bar" "baz"])])))
+                                                        (StringsCompleter. [(str (get-in cmds [k :fn-args]))])])))
                          []
                          (keys cmd-aliases))
         _ (doseq [arg-compl arg-completers]


phone.clj formatting

phone.clj formatting

--- clojure/phone-number/phone.clj
+++ clojure/phone-number/phone.clj
@@ -1,4 +1,5 @@
-(ns phone (:require [clojure.string :as str]))
+(ns phone
+  (:require [clojure.string :as str]))

 (def phone-number-length 10)


Make s3 compilable

Make s3 compilable

--- src/clj/inky/s3.clj
+++ src/clj/inky/s3.clj
@@ -9,7 +9,10 @@
 (def secret-key (env/str :aws-secret-access-key))
 (def bucket (env/str :aws-bucket))

-(def client (AmazonS3Client. (BasicAWSCredentials. access-id secret-key)))
+(defn client []
+  (AmazonS3Client. (BasicAWSCredentials. access-id secret-key)))
+
+(def client (memoize client))

 (defn upload-hash [hash base-path]
   (doseq [file (->> base-path
@@ -18,4 +21,4 @@
                     (remove #(.isDirectory %)))]
     (let [name (.getAbsolutePath file)
           key (str hash (.replace name base-path ""))]
-      (.putObject client (PutObjectRequest. bucket key file)))))
+      (.putObject (client) (PutObjectRequest. bucket key file)))))


Just a little more cleanup.

Just a little more cleanup.

--- src/cljs/wombats_web_client/panels/game_play.cljs
+++ src/cljs/wombats_web_client/panels/game_play.cljs
@@ -21,6 +21,9 @@
 (defonce canvas-container-id "wombat-arena")
 (defonce canvas-id "arena-canvas")

+;; This is how long "ROUND x OVER" will show for (between rounds)
+(defonce transition-time 3000)
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Helper Methods
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -63,12 +66,31 @@
     (re-frame/dispatch [:set-modal {:fn #(winner-modal winners)
                                     :show-overlay true}])))

+(defn- get-next-round-text
+  [{:keys [:game/round-intermission]
+    {:keys [:frame/round-number]} :game/frame}
+   millis-left
+   timeout-fn]
+  ;; The first 3 seconds of a round ending, show transition text
+  (let [time-since-round-end (- round-intermission
+                                millis-left)
+        transition-time-left (- 3000 time-since-round-end)]
+    (if (and (> round-number 1)
+             (pos? transition-time-left))
+      (do
+        (timeout-fn transition-time-left)
+        (str "ROUND " (dec round-number) " OVER"))
+      ;; When we need to transition to show "READY"
+      (let [show-ready-ms (- millis-left transition-time)]
+        (when (pos? show-ready-ms)
+          (timeout-fn show-ready-ms))
+        nil))))
+
 (defn- get-transition-text
-  [{:keys [:game/round-intermission
-           :game/start-time
+  [{:keys [:game/start-time
            :game/status]
-    {:keys [:frame/round-number
-            :frame/round-start-time]} :game/frame}
+    {:keys [:frame/round-start-time]} :game/frame
+    :as game}
    cmpnt-state]
   (let [millis-left (* (time/seconds-until (or round-start-time
                                                start-time))
@@ -84,21 +106,10 @@
         3000 (do (timeout-fn 1000) "READY")
         2000 (do (timeout-fn 1000) "SET")
         (0 1000) (do (timeout-fn 1000) "GO!")
-
-        ;; The first 3 seconds of a round ending, show transition text
-        (let [time-since-round-end (- round-intermission
-                                      millis-left)
-              transition-time-left (- 3000 time-since-round-end)]
-          (if (and (> round-number 1)
-                   (pos? transition-time-left))
-            (do
-              (timeout-fn transition-time-left)
-              (str "ROUND " (dec round-number) " OVER"))
-            ;; When we need to transition to show "READY"
-            (let [show-ready-ms (- millis-left 3000)]
-              (when (pos? show-ready-ms)
-                (timeout-fn show-ready-ms))
-              nil)))))))
+        (get-next-round-text game
+                             millis-left
+                             timeout-fn)))))
+

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Lifecycle Methods


Sprinkle some destructuring on run too.

Sprinkle some destructuring on run too.

--- src/overtunes/songs/canone_alla_quarta.clj
+++ src/overtunes/songs/canone_alla_quarta.clj
@@ -54,13 +54,13 @@
 ;; Structure                                    ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn run [[from & tos]]
+(defn run [[from to & tos]]
   (let [up-or-down (fn [start end]
           (if (<= start end)
             (range start end)
             (reverse (range (inc end) (inc start)))))]
-    (if tos
-      (concat (up-or-down from (first tos)) (run tos))
+    (if to
+      (concat (up-or-down from to) (run (cons to tos)))
       [from])))

 ;(demo# (map g-major


Remove editor after renaming file

Remove editor after renaming file

--- src/net/sekao/nightcode/controller.clj
+++ src/net/sekao/nightcode/controller.clj
@@ -90,6 +90,7 @@
           (.mkdirs (.getParentFile new-file))
           (.renameTo (io/file selected-path) new-file)
           (u/delete-parents-recursively! (:project-set @pref-state) selected-path)
+          (e/remove-editors! selected-path runtime-state)
           (p/update-project-tree! pref-state project-tree new-path))))))

 (defn -onRename [this ^ActionEvent event]


Fix App Name in Service Document

Fix App Name in Service Document

--- src/lens/routes.clj
+++ src/lens/routes.clj
@@ -28,7 +28,7 @@
   It should be print to #inst."
   [version last-loaded]
   (ring-resp/response
-   {:name "Lens"
+   {:name "Lens Warehouse"
     :version version
     :last-loaded last-loaded
     :links


be more sophisticated about positioning keys into view

--- src/strictly_specking/annotated_pprint.clj
+++ src/strictly_specking/annotated_pprint.clj
@@ -95,14 +95,61 @@
     (pprint-map-with-pointer* amap)
     (orig-pprint-map amap)))

+;; adjusting keys into view
+
+(defn key-position [map k]
+  (or (some identity
+        (map-indexed (fn [i [a _]]
+                       (when (= a k) i)) map))
+      400))
+
+(defn move-comments-into-view [amap]
+  (let [length (or *print-length* 4)]
+    (if-let [comments (-> amap meta :comments)]
+      (if (or (<= (count amap) length)
+              (every? (comp
+                       (fnil (partial >= (dec length)) (inc length))
+                       (partial key-position amap))
+                      (keys comments)))
+        amap
+        (let [comment-parts (select-keys amap (keys comments))
+              r (apply dissoc amap (keys comments))
+              [comment-parts r] (if (and (>= (count r) 1)
+                                         (<= (count comments) (dec length)))
+                                  [(cons (first r) comment-parts) (rest r)]
+                                  [comment-parts r])]
+          (with-meta (into {} (reduce #(cons %2 %1) r (reverse comment-parts)))
+            (meta amap))))
+      amap)))
+
+#_(move-comments-into-view (with-meta {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7}
+                             {:comments {:b {:comment "yo"} :f {:comment "hi"}}}))
+#_(> 3 (apply max (map (partial key-position {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7})
+                     [:a :rr])))
+
+(defn calc-map-length [amap]
+  (max
+   (if-let [comments (-> amap meta :comments)]
+     (let [max-pos (apply max (map #(or (key-position amap %) 400)
+                                   (keys comments)))]
+       (if (> 9 max-pos)
+         (+ 3 max-pos)
+         (inc (count comments))))
+     4)
+   4))
+
+#_(calc-map-length (with-meta {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7}
+                     {:comments {:b {:comment "yo"} :d {:comment "hi"}}}))
+
 (defn abbrev-pprint-map-with-pointer [amap]
   (if-let [abr-level  (-> amap meta :abbrev)]
-    (let [length (if (= :tight abr-level) 2 4)
+    (let [length (if (= :tight abr-level) 2
+                     (calc-map-length amap))
           level  (if (= :tight abr-level) 2 3)]
       (binding [*print-level* (+ level
                                  (or @(resolve 'clojure.pprint/*current-level*) 0))
                 *print-length* length]
-        (pprint-map-with-pointer amap)))
+        (pprint-map-with-pointer (move-comments-into-view amap))))
     (pprint-map-with-pointer amap)))

 (let [pprint-message (pp/formatter-out "^---- ~5I~@{~a~^ ~_~}~0I")]


added a note to see sample server

added a note to see sample server

--- src/guide/untangled/ui/Forms__15_File_Upload.cljs
+++ src/guide/untangled/ui/Forms__15_File_Upload.cljs
@@ -65,6 +65,8 @@
 (defcard-doc
   "# Forms – File Upload

+  SEE: upload_server.clj and the devcards in this file for an example.
+
   There are a few steps for setting up a working file upload control:

   1. Install file upload server support in your server's Ring stack and add logic for dealing with
@@ -188,7 +190,7 @@
           :failed (dom/span nil \"FAILED!\")
           :done (dom/span nil \"Ready.\")
           (dom/span nil \"Sending...\" progress \"%\"))
-        (dom/img #js {:width \"100px\" :ref (fn [c] (.setFile js-file))})
+        (dom/img #js {:width \"100px\" :ref (fn [c] (.setFile c js-file))})
         (e/ui-icon {:onClick #(onCancel id)
                     :glyph   :cancel}))))))


Fixing test case

Fixing test case

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

--- src/conexp/tests/fca/contexts.clj
+++ src/conexp/tests/fca/contexts.clj
@@ -47,7 +47,7 @@
 (def test-ctx-04 (make-context #{} #{} #{}))
 (def test-ctx-05 (make-context (set-of-range 0 50)
                                (set-of-range 0 50)
-                               (fn [_ _] (< 0.5 (rand)))))
+                               (memoize (fn [_ _] (< 0.5 (rand))))))
 (def test-ctx-06 (make-context (set-of-range 0 10)
                                (cross-product (set-of-range 0 10)
                                               (set-of-range 0 10))


Cluster name can be a symbol rather than keyword

--- src/control/core.clj
+++ src/control/core.clj
@@ -266,8 +266,9 @@
     :arglists '([name & options])
     :added "0.1"}
   defcluster [name & args]
-  `(let [m# (apply hash-map ~(cons 'list (unquote-cluster args)))]
-     (swap! clusters assoc ~name (assoc m# :name ~name))))
+  (let [name (keyword name)]
+    `(let [m# (apply hash-map ~(cons 'list (unquote-cluster args)))]
+     (swap! clusters assoc ~name (assoc m# :name ~name)))))

 (defmacro ^:private when-exit
   ([test error]


remove debug print

remove debug print

--- src/control/main.clj
+++ src/control/main.clj
@@ -12,6 +12,5 @@
   [file & args]
   (do
     (load-control-file file)
-    (println args)
     (do-begin args)))


added refining option

added refining option

--- src/crawler/main.clj
+++ src/crawler/main.clj
@@ -19,7 +19,9 @@
     "--num-docs N"
     "Specify a number of documents you want"
     :default 500
-    :parse-fn #(Integer/parseInt %)]])
+    :parse-fn #(Integer/parseInt %)]
+   [nil "--refine" "Refine a model file"]
+   [nil "--corpus CORPUS" "Specify a corpus"]])

 (defn dump-state-model-corpus
   "Creates a dated file _prefix_-yr-month-day-hr-min.corpus/state/model"
@@ -108,6 +110,11 @@
             (execute-model-crawler start-url
                                    model
                                    num-leaves))
+
+          (:refine options)
+          (let [model-file (:model options)
+                corpus     (:corpus options)]
+            (crawler-model/plan-dump-model model-file corpus-file))

           :else
           (println "Pick one bruh"))))


Fix CMD in latest image

Fix CMD in latest image

This defaults to clj (tools.deps) entrypoint so it needs a working default REPL invoker CMD

--- src/docker_clojure/dockerfile.clj
+++ src/docker_clojure/dockerfile.clj
@@ -36,7 +36,7 @@
             (get-in variant [:build-tool-versions "tools-deps"])))
     [""]
     (entrypoint variant)
-    ["" "CMD [\"repl\"]"]))
+    ["" "CMD [\"-M\", \"--repl\"]"]))

 (defn contents [installer-hashes {:keys [build-tool] :as variant}]
   (str/join "\n"


Add :opts option. Currently it's not doing anything. Need to add parameters in opts-applet-params.

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -6,7 +6,8 @@
            [java.awt.event WindowListener])
   (:require [quil.util :refer [resolve-constant-key no-fn absolute-path]]
             [clojure.stacktrace :refer [print-cause-trace]]
-            [clojure.string :as string]))
+            [clojure.string :as string]
+            [clojure.set :as clj-set]))

 (defn applet-safe-exit
   "Sets 'finished' field in applet to true. Main run loop in applet
@@ -279,6 +280,14 @@
     (.registerMethod applet "dispose" listener-obj)
     applet))

+(def ^{:private true}
+  opts-applet-params
+  #{})
+
+
+(defn make-hmap [lst key-val]
+  (reduce #(assoc %1 %2 key-val) {} (filter keyword? lst)))
+
 (defn applet
   "Create and start a new visualisation applet.

@@ -351,6 +360,11 @@
                                   :target :frame
                                   :safe-draw-fn true}
                                  (apply hash-map opts))
+
+        opts              (make-hmap (filter opts-applet-params (:opts options)) true)
+
+        options           (merge (dissoc options :opts) opts)
+
         decor             (:decor opts (not= :fullscreen (:size options)))
         size              (process-size (:size options))
         target            (validate-target! (:target options))
@@ -378,6 +392,8 @@
         looping?          (atom true)
         listeners         (into {} (for [name listeners]
                                      [name (or (options name) no-fn)]))
+
+
         applet-state      (merge options
                                  {:state state
                                   :target-obj target-obj


Updated the server module, new functions: finish-processing-product-list, finish-processing-chapter-list, display-list-of-products, display-list-of-chapters

--- src/hurvinek/server.clj
+++ src/hurvinek/server.clj
@@ -19,6 +19,7 @@
 (require '[clojure.data.csv       :as csv])

 (require '[hurvinek.html-renderer :as html-renderer])
+(require '[hurvinek.db-interface  :as db-interface])

 (defn println-and-flush
     "Original (println) has problem with syncing when it's called from more threads.
@@ -39,18 +40,52 @@
         :server
         :url-prefix))

-(defn finish-processing
+(defn finish-processing-front-page
     [request title]
     (let [params        (:params request)
           url-prefix    (get-url-prefix request)]
           (-> (http-response/response (html-renderer/render-front-page url-prefix title))
               (http-response/content-type "text/html"))))

+(defn finish-processing-product-list
+    [request title product-list]
+    (let [params        (:params request)
+          url-prefix    (get-url-prefix request)]
+          (-> (http-response/response (html-renderer/render-product-list url-prefix title product-list))
+              (http-response/content-type "text/html"))))
+
+(defn finish-processing-chapter-list
+    [request title product-id chapter-list]
+    (let [params        (:params request)
+          url-prefix    (get-url-prefix request)]
+          (-> (http-response/response (html-renderer/render-chapter-list url-prefix title product-id chapter-list))
+              (http-response/content-type "text/html"))))
+
+(defn display-list-of-products
+    [request title]
+    (let [product-list (db-interface/read-products)]
+        (println product-list)
+        (finish-processing-product-list request title product-list)
+    ))
+
+(defn display-list-of-chapters
+    [request title product-id]
+    (let [chapter-list (db-interface/read-chapters product-id)]
+        (println chapter-list)
+        (finish-processing-chapter-list request title product-id chapter-list)))
+
 (defn process-front-page
     "Function that prepares data for the front page."
     [request title]
-    (let [params         (:params request)]
-        (finish-processing request title)))
+    (let [params         (:params request)
+          product-id     (get params "product-id")
+          chapter-id     (get params "chapter-id")]
+          (println "Product ID" product-id)
+          (println "Chapter ID" chapter-id)
+          (cond
+              (not product-id) (display-list-of-products request title)
+              (not chapter-id) (display-list-of-chapters request title product-id)
+              :else (finish-processing-front-page request title))))

 (defn return-file
     "Creates HTTP response containing content of specified file.


Formatting

Formatting

--- src/kixi/hecuba/web/resources.clj
+++ src/kixi/hecuba/web/resources.clj
@@ -38,9 +38,7 @@
                               [:tr
                                [:td [:a {:href (:href p)} (:name p)]]
                                (for [k fields] [:td (str (k p))])
-                               (when debug [:td (pr-str p)])])]]
-
-                          ]))
+                               (when debug [:td (pr-str p)])])]]]))
                  "application/edn" (pr-str (vec projects))
                  projects))
   :post! (fn [{{body :body} :request}]


Made Atom elements private in lambda-blog.templates.rss.

--- src/lambda_blog/templates/rss.clj
+++ src/lambda_blog/templates/rss.clj
@@ -4,10 +4,18 @@
             [lambda-blog.utils :refer [pathcat]]
             [s-html.tags :refer [deftags link xml] :as tags]))

-(deftags [author category entry feed id name published summary updated])
+(deftags [^:private author
+          ^:private category
+          ^:private entry
+          ^:private feed
+          ^:private id
+          ^:private name
+          ^:private published
+          ^:private summary
+          ^:private updated])

-(def _author author) ;; FIXME Loose the _.
-(def _summary summary)
+(def ^:private _author author) ;; FIXME Loose the _.
+(def ^:private _summary summary)

 (defn rss-feed [{:keys [entries path title url]}]
   [(xml)


Add missing require for 'plumbing.map'

Add missing require for 'plumbing.map'

--- src/puppetlabs/trapperkeeper/utils.clj
+++ src/puppetlabs/trapperkeeper/utils.clj
@@ -1,4 +1,5 @@
-(ns puppetlabs.trapperkeeper.utils)
+(ns puppetlabs.trapperkeeper.utils
+  (:require [plumbing.map]))

 (def ^{:doc "Alias for plumbing.map/map-leaves-and-path, which is named inconsistently
             with Clojure conventions as it doesn't behave like other `map` functions.