 ;; --- Specs
 
 (s/def ::shape-attrs ::cp/shape-attrs)
+
 (s/def ::set-of-uuid
   (s/every uuid? :kind set?))
+(s/def ::set-of-string
+  (s/every string? :kind set?))
 
 ;; --- Expose inner functions
 

;; Shapes events
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; --- Add shape to Workspace

(defn impl-retrieve-used-names
  [objects]
  (into #{} (map :name) (vals objects)))

(defn extract-numeric-suffix
  [basename]
  (if-let [[match p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
    [p1 (+ 1 (d/parse-integer p2))]
    [basename 1]))

(defn impl-generate-unique-name
  "A unique name generator"
  [objects basename]
  (let [used (impl-retrieve-used-names objects)
        [prefix initial] (extract-numeric-suffix basename)]
    (loop [counter initial]
      (let [candidate (str prefix "-" counter)]
        (if (contains? used candidate)


            page-id (::page-id state)
            unames (-> (get-in state [:workspace-data page-id :objects])
                       (retrieve-used-names))

            rchanges (prepare-duplicate-changes objects unames selected delta)
            uchanges (mapv #(array-map :type :del-obj :id (:id %))
