         (with-fen (:fen config))
         (dissoc :fen))))
 
-(defn clear [state]
+(sm/defn clear :- ChessState
+  [state :- ChessState]
   (-> state
       (assoc :chess chess/clear)
       (assoc-in [:movable :dests] nil)))
 
-(defn is-movable? [state key]
+(sm/defn is-movable? :- Bool
   "Piece on this square may be moved somewhere, if the validation allows it"
+  [state :- ChessState
+   key :- Str]
   (let [owner (chess/owner-color (:chess state) key)
         movable (:movable state)
         color (:color movable)]
     (and owner (or (= color "both") (= color owner)))))
 
-(defn can-move? [state orig dest]
+(sm/defn can-move? :- Bool
   "The piece on orig can definitely be moved to dest"
+  [state :- ChessState
+   orig :- Str
+   dest :- Str]
   (and (is-movable? state orig)
        (or (-> state :movable :free)
            (common/set-contains? (get-in state [:movable :dests orig]) dest))))
 
-(defn dests-of [state orig]
+(sm/defn dests-of :- (s/maybe [Square])
   "List of destinations square keys for this origin"
+  [state :- ChessState
+   orig :- Str]
   (when (is-movable? state orig)
     (if (-> state :movable :free)
       (for [rank (range 1 9)

   :spare-pieces false ; provide extra pieces to put on the board)
   })

(defn with-fen [state fen] (assoc state :chess (chess/make fen)))

(defn make [js-config]
  (let [config (-> js-config
                   common/keywordize-keys
                   (common/keywordize-keys-in [:movable])

(ns chessground.data
  "Representation and manipulation of the application data"
  (:require [chessground.common :as common :refer [pp]]
            [chessground.chess :as chess]
            [chessground.schemas :refer [ChessState]]
            [schema.core :as s :refer [Str Bool]])
  (:require-macros [schema.macros :as sm :refer [defschema]]))

(sm/def defaults :- ChessState
  "Default state, overridable by user configuration"
  {:fen nil ; replaced by :chess by data/make
   :chess {} ; representation of a chess game
