├── .gitignore ├── Main.ml ├── TodoListComponent.mli ├── EditorMain.ml ├── VCR.mli ├── TodoList.mli ├── TodoList.ml ├── todo.html ├── Makefile ├── README.markdown ├── VCR.ml ├── TodoListComponent.ml ├── editor.html ├── OCamlMVC.mli ├── js └── modernizr.js ├── css ├── normalize.css └── foundation.min.css ├── Editor.ml └── OCamlMVC.ml /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmi 2 | *.cmo 3 | todo.js 4 | editor.js 5 | *~ 6 | *.byte 7 | /.ocamldeps 8 | -------------------------------------------------------------------------------- /Main.ml: -------------------------------------------------------------------------------- 1 | let _ = 2 | OCamlMVC.attach ~parent_id:"demo" 3 | (module VCR.Of 4 | (TodoListComponent) 5 | (TodoListComponent.ActionFilter)) 6 | -------------------------------------------------------------------------------- /TodoListComponent.mli: -------------------------------------------------------------------------------- 1 | include OCamlMVC.Component 2 | 3 | val string_of_action : action -> string 4 | 5 | module ActionFilter : VCR.Filter with type t = action 6 | -------------------------------------------------------------------------------- /EditorMain.ml: -------------------------------------------------------------------------------- 1 | let _ = 2 | OCamlMVC.attach ~parent_id:"editor" 3 | (module VCR.Of 4 | (Editor) 5 | (struct 6 | type t = Editor.action 7 | let relevant = function 8 | | Editor.Movement _ -> false 9 | | _ -> true 10 | end)) 11 | -------------------------------------------------------------------------------- /VCR.mli: -------------------------------------------------------------------------------- 1 | module type Component = sig 2 | include OCamlMVC.Component 3 | val string_of_action : action -> string 4 | end 5 | 6 | module type Filter = sig 7 | type t 8 | val relevant : t -> bool 9 | end 10 | 11 | module Of 12 | (Inner : Component) 13 | (Filter : Filter with type t = Inner.action) 14 | : OCamlMVC.Component 15 | -------------------------------------------------------------------------------- /TodoList.mli: -------------------------------------------------------------------------------- 1 | type status = TODO | DONE 2 | 3 | type todo_item = 4 | { label : string; status : status; } 5 | 6 | type t = 7 | { items : todo_item list; pending_item : string; } 8 | 9 | val empty : t 10 | 11 | val add_pending_item : t -> t 12 | 13 | val set : int -> status -> t -> t 14 | 15 | val clear : t -> t 16 | 17 | val update_pending : string -> t -> t 18 | -------------------------------------------------------------------------------- /TodoList.ml: -------------------------------------------------------------------------------- 1 | type status = TODO | DONE 2 | 3 | type todo_item = 4 | { label : string; status : status } 5 | 6 | type t = 7 | { items : todo_item list; pending_item : string } 8 | 9 | let empty = 10 | { items = [ ]; pending_item = "" } 11 | 12 | (* FIXME: use some kind of random-access list thing: Phil Bagwell's VLists? *) 13 | let modify i f l = 14 | let rec loop i l = match i, l with 15 | | _, [] -> [] 16 | | 0, x::xs -> f x::xs 17 | | n, x::xs -> x::loop (i-1) xs 18 | in 19 | loop i l 20 | 21 | let add_pending_item ({items;pending_item} as todo_list) = 22 | if pending_item = "" then 23 | todo_list 24 | else 25 | let item = {label = pending_item; status = TODO} in 26 | { items = item::items; pending_item = "" } 27 | 28 | let set idx status ({items} as todo_list) = 29 | { todo_list 30 | with items = modify idx (fun item -> {item with status}) items} 31 | 32 | let clear ({items} as todo_list) = 33 | { todo_list 34 | with items = List.filter (fun item -> item.status = TODO) items} 35 | 36 | let update_pending new_pending_item todo_list = 37 | { todo_list with pending_item = new_pending_item } 38 | -------------------------------------------------------------------------------- /todo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OCamlMVC 6 | 7 | 8 | 9 | 16 | 17 | 18 |
19 |
20 |

VCR.Of (TodoListComponent)

21 |
22 | 23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 | 31 |
32 |

About

33 | 34 |

This is a demo of OCamlMVC, an experimental OCaml library 35 | for writing Model-View-Controller based reactive user 36 | interfaces for web pages.

37 | 38 |

Source: https://github.com/bobatkey/ocamlmvc

39 |
40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TODO_SRC := OCamlMVC.mli OCamlMVC.ml VCR.mli VCR.ml TodoList.mli TodoList.ml TodoListComponent.mli TodoListComponent.ml Main.ml 2 | TODO_CMO := $(patsubst %.ml,%.cmo,$(filter-out %.mli,$(TODO_SRC))) 3 | 4 | EDITOR_SRC := OCamlMVC.mli OCamlMVC.ml VCR.mli VCR.ml TodoList.mli TodoList.ml TodoListComponent.mli TodoListComponent.ml Editor.ml EditorMain.ml 5 | EDITOR_CMO := $(patsubst %.ml,%.cmo,$(filter-out %.mli,$(EDITOR_SRC))) 6 | 7 | SRC := $(TODO_SRC) $(EDITOR_SRC) 8 | 9 | all: todo.js editor.js 10 | 11 | ###################################################################### 12 | todo.byte: $(TODO_CMO) 13 | @echo Linking $@ 14 | @ocamlfind ocamlc -package js_of_ocaml -linkpkg -o $@ $^ 15 | 16 | editor.byte: $(EDITOR_CMO) 17 | @echo Linking $@ 18 | @ocamlfind ocamlc -package js_of_ocaml -linkpkg -o $@ $^ 19 | 20 | ###################################################################### 21 | clean: 22 | rm -f *.cmo *.cmi 23 | rm -f todo.byte todo.js 24 | rm -f editor.byte editor.js 25 | rm -f *~ 26 | 27 | ###################################################################### 28 | %.cmo: %.ml 29 | @echo Compiling $< 30 | @ocamlfind ocamlc -package js_of_ocaml \ 31 | -package js_of_ocaml.syntax \ 32 | -syntax camlp4o \ 33 | -c $< 34 | 35 | %.cmi: %.mli 36 | @echo Compiling $< 37 | @ocamlfind ocamlc -package js_of_ocaml \ 38 | -package js_of_ocaml.syntax \ 39 | -syntax camlp4o \ 40 | -c $< 41 | 42 | %.js: %.byte 43 | @echo Compiling $< to $@ 44 | @js_of_ocaml --opt 2 $< 45 | 46 | ###################################################################### 47 | .ocamldeps: $(SRC) 48 | @ocamlfind ocamldep -package js_of_ocaml.syntax \ 49 | -syntax camlp4o \ 50 | $(SRC) >.ocamldeps 51 | -include .ocamldeps 52 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # OcamlMVC 2 | 3 | A cheap and cheerful MVC library for writing interactive web pages 4 | with [Ocaml](http://ocaml.org) that are compiled into Javascript with 5 | [js_of_ocaml](http://ocsigen.org/js_of_ocaml/). 6 | 7 | [Live demo](http://bentnib.org/ocamlmvc-demo/todo.html). 8 | 9 | **Warning:** everything will change. 10 | 11 | ## Basic design notes 12 | 13 | The library (such as it is) is based around a single `Component` 14 | module signature: 15 | 16 | ````ocaml 17 | module type Component = sig 18 | type state 19 | type action 20 | 21 | val render : state -> action html 22 | val update : action -> state -> state 23 | val initial : state 24 | end 25 | ```` 26 | 27 | The type `state` represents the set of all possible states that the 28 | component can be in, and the type `action` represents all the possible 29 | actions that can be peformed by the user. For each possible state, the 30 | `render` function generates a reactive HTML document that can be 31 | manipulated by the use to generate actions. The `update` function is 32 | then used to translate an action into a state transformation 33 | function. The `initial` value is used as the initial state of the 34 | component. 35 | 36 | The functions `render` and `update` are intended to be purely 37 | functional. 38 | 39 | The HTML tree generated by the `render` function is translated into 40 | DOM nodes using an algorithm similar to (but as yet less sophisticated 41 | than) the one used by 42 | [React.js](http://calendar.perfplanet.com/2013/diff/). This ensures 43 | that OCamlMVC can maintain the illusion of writing a whole new HTML 44 | tree to the interface on every state update, while remaining 45 | reasonably efficient. 46 | 47 | ## Demo 48 | 49 | There is one demo at the moment: a very simple todo list application, 50 | with undo/redo capability added by a generic “VCR” functor. A compiled 51 | version of the demo can be seen 52 | [on my website](http://bentnib.org/ocamlmvc-demo/todo.html). 53 | 54 | This application is constructed in layers: 55 | 56 | 1. There is a pure OCaml core (i.e., with no Javascript-specific 57 | stuff), implemented in the module `TodoList`. 58 | 59 | 2. The todo list data structure is then used as the ‘model’ for an 60 | OCamlMVC `Component` as described above. This is implemented in the 61 | `TodoListComponent` module, and primarily consists of code to 62 | render the state of a todo list as an HTML tree (using the 63 | combinators provded by the `OCamlMVC.HTML` module), and to route 64 | the actions generated by user interaction back to the model. 65 | 66 | 3. The Undo/Redo functionality is then added by using the `VCR.Of` 67 | functor that maps `Component`s to `Component`s, adding a history 68 | and a future to the state of the underlying component, and 69 | augmenting the UI with “Undo” and “Redo” buttons. 70 | 71 | 4. The `Main` module then attaches the composed component to a 72 | specified element in the DOM. 73 | 74 | The styling is provided by the 75 | [Zurb Foundation CSS framework](http://foundation.zurb.com). 76 | 77 | ## Compiling the demo 78 | 79 | I think this will work: 80 | 81 | 1. Install [Ocaml](http://ocaml.org/docs/install.html) and the 82 | [OPAM](http://opam.ocaml.org) package manager. 83 | 84 | 2. Run `opam install js_of_ocaml` to compile and install the OCaml 85 | bytecode to Javascript compiler. 86 | 87 | 3. Run `make` to generate the file `todo.js`. 88 | 89 | 4. Load `todo.html` into the browser of your choice (only tested in 90 | Firefox 26.0). 91 | -------------------------------------------------------------------------------- /VCR.ml: -------------------------------------------------------------------------------- 1 | module type Component = sig 2 | include OCamlMVC.Component 3 | val string_of_action : action -> string 4 | end 5 | 6 | module type Filter = sig 7 | type t 8 | val relevant : t -> bool 9 | end 10 | 11 | module Of 12 | (Inner : Component) 13 | (Filter : Filter with type t = Inner.action) 14 | : OCamlMVC.Component 15 | = 16 | struct 17 | open OCamlMVC 18 | 19 | type state = 20 | { history : (Inner.state * Inner.action) list 21 | ; now : Inner.state 22 | ; future : (Inner.action * Inner.state) list 23 | } 24 | 25 | type action = 26 | | Inner of Inner.action 27 | | Undo 28 | | Redo 29 | 30 | let render_truncated_list ~f ~limit list = 31 | let open Html in 32 | let render_item x = 33 | li (span ~attrs:[A.class_ "small"] (text x)) 34 | in 35 | let rec loop i = function 36 | | [] -> empty 37 | | x::xs when i = limit -> render_item "..." 38 | | x::xs -> render_item (f x) ^^ loop (i+1) xs 39 | in 40 | loop 0 list 41 | 42 | let render {history;now;future} = 43 | let open Html in 44 | let have_history = history <> [] in 45 | let have_future = future <> [] in 46 | let div ~classes children = 47 | div ~attrs:[A.class_ (String.concat " " classes)] children 48 | in 49 | let ul ~classes children = 50 | ul ~attrs:[A.class_ (String.concat " " classes)] children 51 | in 52 | let button ~enabled ~onclick label = 53 | button ~attrs:[A.enabled enabled; E.onclick onclick] (text label) 54 | in 55 | div ~classes:["row"] begin 56 | div ~classes:["columns";"large-7"] begin 57 | map (fun action -> Inner action) (Inner.render now) 58 | end 59 | ^^ 60 | div ~classes:["columns";"large-5"] begin 61 | div ~classes:["row"] begin 62 | div ~classes:["small-centered";"small-12";"columns"] begin 63 | ul ~classes:["button-group";"radius"] begin 64 | li (button ~enabled:have_history ~onclick:Undo "« Undo") 65 | ^^ 66 | li (button ~enabled:have_future ~onclick:Redo "Redo »") 67 | end 68 | end 69 | end 70 | ^^ 71 | div ~classes:["row"] begin 72 | div ~classes:["small-6";"columns"] begin 73 | h6 (text "History") 74 | ^^ 75 | ul ~classes:["no-bullet"] begin 76 | history 77 | |> render_truncated_list 78 | ~f:(fun (_,act) -> Inner.string_of_action act) 79 | ~limit:10 80 | end 81 | end 82 | ^^ 83 | div ~classes:["small-6";"columns"] begin 84 | h6 (text "Future") 85 | ^^ 86 | ul ~classes:["no-bullet"] begin 87 | future 88 | |> render_truncated_list 89 | ~f:(fun (act,_) -> Inner.string_of_action act) 90 | ~limit:10 91 | end 92 | end 93 | end 94 | end 95 | end 96 | 97 | let update = function 98 | | Inner action when Filter.relevant action -> 99 | (fun {history;now} -> 100 | { history = (now,action)::history 101 | ; now = Inner.update action now 102 | ; future = [] 103 | }) 104 | | Inner action -> 105 | (fun ({now} as t) -> 106 | {t with now = Inner.update action now}) 107 | | Undo -> 108 | (function 109 | | {history=[]} as state -> state 110 | | {history=(prev,action)::history; now; future} -> 111 | {history; now=prev; future=(action,now)::future}) 112 | | Redo -> 113 | (function 114 | | {future=[]} as state -> state 115 | | {future=(action,next)::future; now; history} -> 116 | {history=(now,action)::history; now=next; future}) 117 | 118 | let initial = 119 | { history = []; now = Inner.initial; future = [] } 120 | end 121 | -------------------------------------------------------------------------------- /TodoListComponent.ml: -------------------------------------------------------------------------------- 1 | open OCamlMVC 2 | open Printf 3 | 4 | let (<.>) f g x = f (g x) 5 | 6 | (**********************************************************************) 7 | type state = TodoList.t 8 | 9 | type action = 10 | | Add 11 | | Set of int * TodoList.status 12 | | Clear 13 | | UpdatePending of string 14 | 15 | let string_of_action = function 16 | | Add -> "Add" 17 | | Set (i, TodoList.TODO) -> sprintf "Set (%d, TODO)" i 18 | | Set (i, TodoList.DONE) -> sprintf "Set (%d, DONE)" i 19 | | Clear -> "Clear" 20 | | UpdatePending s -> sprintf "UpdatePending %S" s 21 | 22 | (**********************************************************************) 23 | let render_item idx {TodoList.label=l;status} = 24 | let id = sprintf "checkbox%d" idx in 25 | let open Html in 26 | let open TodoList in 27 | let checkbox ~id ~onchange ~state = 28 | let attrs = 29 | [ A.type_ "checkbox"; A.id id; E.onchange (fun ~value -> onchange) ] 30 | in 31 | let attrs = 32 | if state then A.checked true::attrs else attrs 33 | in 34 | input ~attrs Html.empty 35 | in 36 | match status with 37 | | DONE -> 38 | checkbox ~id ~onchange:(Set (idx, TODO)) ~state:true 39 | ^^ 40 | label ~attrs:[A.for_control id] (span ~attrs:[A.class_ "done"] (text l)) 41 | | TODO -> 42 | checkbox ~id ~onchange:(Set (idx, DONE)) ~state:false 43 | ^^ 44 | label ~attrs:[A.for_control id] (text l) 45 | 46 | let render_items = let open Html in function 47 | | [] -> 48 | em (text "Items will appear here") 49 | | items -> 50 | ul ~attrs:[A.class_ "no-bullet"] begin 51 | of_list (List.mapi (fun i -> li <.> render_item i) items) 52 | end 53 | 54 | let render {TodoList.items;pending_item} = 55 | let open Html in 56 | let div ~classes html = 57 | div ~attrs:[A.class_ (String.concat " " classes)] html 58 | in 59 | let text_input ~classes ~onenter ~oninput ~placeholder value = 60 | input 61 | ~attrs:[ A.class_ (String.concat " " classes) 62 | ; A.type_ "text" 63 | ; A.value value 64 | ; A.placeholder placeholder 65 | ; E.oninput oninput 66 | ; E.onkeypress (fun key_code char_code -> 67 | if key_code = Keycode.return 68 | then Some onenter else None) 69 | ] 70 | empty 71 | and button ~classes ~enabled ~onclick label = 72 | let classes = 73 | ["button"] 74 | @ (if enabled then [] else ["disabled"]) 75 | @ classes 76 | in 77 | button ~attrs:[ A.class_ (String.concat " " classes) 78 | ; E.onclick onclick 79 | ] 80 | (text label) 81 | in 82 | div ~classes:["panel";"radius"] begin 83 | div ~classes:["row";"collapse"] begin 84 | div ~classes:["small-8";"columns"] begin 85 | text_input 86 | ~classes:["radius"] 87 | ~onenter:Add 88 | ~oninput:(fun ~value -> UpdatePending value) 89 | ~placeholder:"Enter new item here" 90 | pending_item 91 | end 92 | ^^ 93 | div ~classes:["small-2";"columns"] begin 94 | button 95 | ~classes:["postfix"] 96 | ~enabled:(pending_item <> "") 97 | ~onclick:Add 98 | "Add" 99 | end 100 | ^^ 101 | div ~classes:["small-2";"columns"] begin 102 | button 103 | ~classes:["radius";"postfix";"alert"] 104 | ~enabled:(List.exists (fun item -> item.TodoList.status = TodoList.DONE) items) 105 | ~onclick:Clear 106 | "Clear" 107 | end 108 | ^^ 109 | render_items items 110 | ^^ 111 | hr () 112 | ^^ 113 | div ~classes:["row"] begin 114 | div ~classes:["small-12";"columns"] begin 115 | let num_items = List.length items in 116 | let num_done_items = 117 | List.length (List.filter (fun i -> i.TodoList.status = TodoList.DONE) items) 118 | in 119 | text (sprintf "%d item%s with %d completed" 120 | num_items 121 | (if num_items = 1 then "" else "s") 122 | num_done_items) 123 | end 124 | end 125 | end 126 | end 127 | 128 | let update = let open TodoList in function 129 | | Add -> add_pending_item 130 | | Set (idx, status) -> set idx status 131 | | Clear -> clear 132 | | UpdatePending text -> update_pending text 133 | 134 | let initial = 135 | TodoList.empty 136 | 137 | module ActionFilter = struct 138 | type t = action 139 | let relevant = function 140 | | UpdatePending _ -> false 141 | | _ -> true 142 | end 143 | -------------------------------------------------------------------------------- /editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OCamlMVC Editor demo 6 | 7 | 8 | 9 | 10 | 81 | 82 | 83 |
84 |
85 |

OCamlMVC Text Editor

86 |
87 | 88 |
89 |
90 | 91 |
92 |
93 | 94 |
95 |
96 | 97 |
98 |

About

99 | 100 |

101 | This is a demo of a simple text editor, written 102 | in OCaml and compiled to 103 | JavaScript 104 | using js_of_ocaml. The OCamlMVC 105 | library is used to provide a quick, and easy way to build 106 | interactive web pages. 107 |

108 | 109 |

110 | The point of this demo is to show off 111 | the generic 112 | undo/redo component of OCamlMVC, which supplies the 113 | ‘Undo’ and ‘Redo’ buttons above the text editor, and the 114 | history and future stacks below the editor pane. Given any 115 | OCamlMVC component, undo and redo can be added simply by 116 | applying an OCaml functor. Here is the code constructing the 117 | component displayed on this page: 118 |

119 | 120 |
121 | let _ =
122 |   OCamlMVC.attach
123 |     ~parent_id:"editor"
124 |     (module VCR.Of
125 |         (Editor)
126 |         (struct
127 |           let relevant = function
128 |             | Editor.Movement _ ->
129 |               false
130 |             | _ ->
131 |               true
132 |          end))
133 | 
134 | 135 |

136 | The functor VCR.Of takes two parameters: (1) 137 | the underlying component (in this case Editor); 138 | and (2) a function that determines which user actions are to 139 | be deemed relevant for the purposes of adding to the undo 140 | stack. In this case, movement actions are irrelevant, while 141 | all other actions are relevant. 142 |

143 | 144 |

145 | Adding a generic Undo/redo feature is to any component is as 146 | straightforward as applying an OCaml functor due to the use 147 | of persistent data structures to represent the state of the 148 | text editor. This was inspired 149 | by David 150 | Nolen's blog post on how the use of persistent data 151 | structures in React/Om enabled a straightforward 152 | implementation of time travel. 153 |

154 | 155 |

156 | An additional feature 157 | of OCamlMVC 158 | is that it makes the actions that can be performed by the 159 | user interacting with the UI completely explicit. Being 160 | explicit about the individual actions that can be performed 161 | means that generating a UI representation of the undo/redo 162 | stack is also straightforward. 163 |

164 | 165 |

166 | The text editor component itself is relatively featureless 167 | at the moment. Only the following features are implemented: 168 |

169 | 170 | 175 | 176 |

177 | Nevertheless, once more features are added to the underlying 178 | text editor component, the generic Undo/redo functor will 179 | automatically pick them up without having to do anything 180 | special. 181 |

182 |
183 |
184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /OCamlMVC.mli: -------------------------------------------------------------------------------- 1 | (** An MVC library for writing reactive webpages *) 2 | 3 | module Html : sig 4 | type _ t 5 | 6 | type _ attribute 7 | 8 | val empty : 'action t 9 | val (^^) : 'action t -> 'action t -> 'action t 10 | val of_list : 'action t list -> 'action t 11 | 12 | val map : ('inner_action -> 'action) -> 'inner_action t -> 'action t 13 | 14 | (* Text nodes *) 15 | val text : string -> 'a t 16 | 17 | (* 4.3 Sections *) 18 | val body : ?attrs:'action attribute list -> 'action t -> 'action t 19 | val article : ?attrs:'action attribute list -> 'action t -> 'action t 20 | val section : ?attrs:'action attribute list -> 'action t -> 'action t 21 | val nav : ?attrs:'action attribute list -> 'action t -> 'action t 22 | val aside : ?attrs:'action attribute list -> 'action t -> 'action t 23 | val h1 : ?attrs:'action attribute list -> 'action t -> 'action t 24 | val h2 : ?attrs:'action attribute list -> 'action t -> 'action t 25 | val h3 : ?attrs:'action attribute list -> 'action t -> 'action t 26 | val h4 : ?attrs:'action attribute list -> 'action t -> 'action t 27 | val h5 : ?attrs:'action attribute list -> 'action t -> 'action t 28 | val h6 : ?attrs:'action attribute list -> 'action t -> 'action t 29 | val header : ?attrs:'action attribute list -> 'action t -> 'action t 30 | val footer : ?attrs:'action attribute list -> 'action t -> 'action t 31 | val address : ?attrs:'action attribute list -> 'action t -> 'action t 32 | 33 | (* 4.4 Grouping content *) 34 | val p : ?attrs:'action attribute list -> 'action t -> 'action t 35 | val hr : ?attrs:'action attribute list -> unit -> 'action t 36 | val pre : ?attrs:'action attribute list -> 'action t -> 'action t 37 | val blockquote : ?attrs:'action attribute list -> 'action t -> 'action t 38 | val ol : ?attrs:'action attribute list -> 'action t -> 'action t 39 | val ul : ?attrs:'action attribute list -> 'action t -> 'action t 40 | val li : ?attrs:'action attribute list -> 'action t -> 'action t 41 | val dl : ?attrs:'action attribute list -> 'action t -> 'action t 42 | val dt : ?attrs:'action attribute list -> 'action t -> 'action t 43 | val dd : ?attrs:'action attribute list -> 'action t -> 'action t 44 | val figure : ?attrs:'action attribute list -> 'action t -> 'action t 45 | val figcaption : ?attrs:'action attribute list -> 'action t -> 'action t 46 | val div : ?attrs:'action attribute list -> 'action t -> 'action t 47 | val main : ?attrs:'action attribute list -> 'action t -> 'action t 48 | 49 | (* 4.5 Text level semantics *) 50 | val a : ?attrs:'action attribute list -> 'action t -> 'action t 51 | val em : ?attrs:'action attribute list -> 'action t -> 'action t 52 | val strong : ?attrs:'action attribute list -> 'action t -> 'action t 53 | val small : ?attrs:'action attribute list -> 'action t -> 'action t 54 | val s : ?attrs:'action attribute list -> 'action t -> 'action t 55 | val cite : ?attrs:'action attribute list -> 'action t -> 'action t 56 | val q : ?attrs:'action attribute list -> 'action t -> 'action t 57 | val dfn : ?attrs:'action attribute list -> 'action t -> 'action t 58 | val abbr : ?attrs:'action attribute list -> 'action t -> 'action t 59 | val data : ?attrs:'action attribute list -> 'action t -> 'action t 60 | val time : ?attrs:'action attribute list -> 'action t -> 'action t 61 | val code : ?attrs:'action attribute list -> 'action t -> 'action t 62 | val var : ?attrs:'action attribute list -> 'action t -> 'action t 63 | val samp : ?attrs:'action attribute list -> 'action t -> 'action t 64 | val kbd : ?attrs:'action attribute list -> 'action t -> 'action t 65 | val sub : ?attrs:'action attribute list -> 'action t -> 'action t 66 | val sup : ?attrs:'action attribute list -> 'action t -> 'action t 67 | val i : ?attrs:'action attribute list -> 'action t -> 'action t 68 | val b : ?attrs:'action attribute list -> 'action t -> 'action t 69 | val u : ?attrs:'action attribute list -> 'action t -> 'action t 70 | val mark : ?attrs:'action attribute list -> 'action t -> 'action t 71 | val ruby : ?attrs:'action attribute list -> 'action t -> 'action t 72 | val rb : ?attrs:'action attribute list -> 'action t -> 'action t 73 | val rt : ?attrs:'action attribute list -> 'action t -> 'action t 74 | val rtc : ?attrs:'action attribute list -> 'action t -> 'action t 75 | val rp : ?attrs:'action attribute list -> 'action t -> 'action t 76 | val bdi : ?attrs:'action attribute list -> 'action t -> 'action t 77 | val bdo : ?attrs:'action attribute list -> 'action t -> 'action t 78 | val span : ?attrs:'action attribute list -> 'action t -> 'action t 79 | val br : ?attrs:'action attribute list -> unit -> 'action t 80 | val wbr : ?attrs:'action attribute list -> unit -> 'action t 81 | 82 | (* 4.6 Edits *) 83 | val ins : ?attrs:'action attribute list -> 'action t -> 'action t 84 | val del : ?attrs:'action attribute list -> 'action t -> 'action t 85 | 86 | (* 4.7 Embedded content *) 87 | val img : ?attrs:'action attribute list -> 'action t -> 'action t 88 | (* FIXME... *) 89 | 90 | (* 4.9 Tabular data *) 91 | val table : ?attrs:'action attribute list -> 'action t -> 'action t 92 | val caption : ?attrs:'action attribute list -> 'action t -> 'action t 93 | val colgroup : ?attrs:'action attribute list -> 'action t -> 'action t 94 | val col : ?attrs:'action attribute list -> 'action t -> 'action t 95 | val tbody : ?attrs:'action attribute list -> 'action t -> 'action t 96 | val thead : ?attrs:'action attribute list -> 'action t -> 'action t 97 | val tfoot : ?attrs:'action attribute list -> 'action t -> 'action t 98 | val tr : ?attrs:'action attribute list -> 'action t -> 'action t 99 | val td : ?attrs:'action attribute list -> 'action t -> 'action t 100 | val th : ?attrs:'action attribute list -> 'action t -> 'action t 101 | 102 | (* 4.10 Forms *) 103 | val form : ?attrs:'action attribute list -> 'action t -> 'action t 104 | val label : ?attrs:'action attribute list -> 'action t -> 'action t 105 | val input : ?attrs:'action attribute list -> 'action t -> 'action t 106 | val button : ?attrs:'action attribute list -> 'action t -> 'action t 107 | 108 | (* 4.11 Scripting *) 109 | 110 | (* Attributes *) 111 | module A : sig 112 | (* Global attributes (3.2.5) *) 113 | val accesskey : string -> _ attribute 114 | val class_ : string -> _ attribute 115 | val contenteditable : bool -> _ attribute 116 | val dir : [`ltr | `rtl | `auto] -> _ attribute 117 | val hidden : bool -> _ attribute 118 | val id : string -> _ attribute 119 | val lang : string -> _ attribute 120 | val spellcheck : bool -> _ attribute 121 | val style : string -> _ attribute 122 | val tabindex : int -> _ attribute 123 | val title : string -> _ attribute 124 | val translate : bool -> _ attribute 125 | 126 | (* 'a' attributes *) 127 | val href : string -> _ attribute 128 | val target : string -> _ attribute 129 | val download : string -> _ attribute 130 | val rel : string -> _ attribute 131 | val hreflang : string -> _ attribute 132 | val type_ : string -> _ attribute 133 | 134 | (* 'img' attributes *) 135 | val src : string -> _ attribute 136 | 137 | (* 'form' attributes *) 138 | val accept_charset : string -> _ attribute 139 | val action : string -> _ attribute 140 | val autocomplete : string -> _ attribute 141 | val enctype : string -> _ attribute 142 | val http_method : string -> _ attribute 143 | val name : string -> _ attribute 144 | val novalidate : string -> _ attribute 145 | val target : string -> _ attribute 146 | 147 | (* 'label' attributes *) 148 | val form : string -> _ attribute 149 | val for_control : string -> _ attribute 150 | 151 | (* 'input' attributes *) 152 | val enabled : bool -> _ attribute 153 | val checked : bool -> _ attribute 154 | val value : string -> _ attribute 155 | val placeholder : string -> _ attribute 156 | end 157 | 158 | module E : sig 159 | val onkeypress : (int -> int -> 'action option) -> 'action attribute 160 | val onclick : 'action -> 'action attribute 161 | val ondoubleclick : 'action -> 'action attribute 162 | val oninput : (value:string -> 'action) -> 'action attribute 163 | val onchange : (value:string -> 'action) -> 'action attribute 164 | end 165 | end 166 | 167 | module type Component = sig 168 | type state 169 | type action 170 | 171 | val render : state -> action Html.t 172 | val update : action -> state -> state 173 | val initial : state 174 | end 175 | 176 | type component = (module Component) 177 | type 'action component' = (module Component with type action = 'action) 178 | 179 | val attach : parent_id:string -> component -> unit 180 | -------------------------------------------------------------------------------- /js/modernizr.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.6.2 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-inlinesvg-svg-svgclippaths-touch-shiv-mq-cssclasses-teststyles-prefixes-ie8compat-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function y(a){j.cssText=a}function z(a,b){return y(m.join(a+";")+(b||""))}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={svg:"http://www.w3.org/2000/svg"},o={},p={},q={},r=[],s=r.slice,t,u=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},v=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return u("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},w={}.hasOwnProperty,x;!A(w,"undefined")&&!A(w.call,"undefined")?x=function(a,b){return w.call(a,b)}:x=function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=s.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(s.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(s.call(arguments)))};return e}),o.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:u(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},o.svg=function(){return!!b.createElementNS&&!!b.createElementNS(n.svg,"svg").createSVGRect},o.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==n.svg},o.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(l.call(b.createElementNS(n.svg,"clipPath")))};for(var D in o)x(o,D)&&(t=D.toLowerCase(),e[t]=o[D](),r.push((e[t]?"":"no-")+t));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=m,e.mq=v,e.testStyles=u,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+r.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f a 6 | | Some a -> a 7 | end 8 | 9 | (**********************************************************************) 10 | type current_line = 11 | { characters_before : string 12 | ; characters_after : string 13 | } 14 | 15 | type state = 16 | { lines_before : string list 17 | ; current_line : current_line 18 | ; cursor_col : int option 19 | ; lines_after : string list 20 | } 21 | 22 | let lines string = 23 | let l = String.length string in 24 | let rec loop acc i = 25 | match try Some (String.index_from string i '\n') with Not_found -> None with 26 | | None -> 27 | let s = String.sub string i (l - i) in 28 | List.rev (s::acc) 29 | | Some j -> 30 | let s = String.sub string i (j - i) in 31 | loop (s::acc) (j+1) 32 | in 33 | loop [] 0 34 | 35 | let of_string string = 36 | match lines string with 37 | | [] -> 38 | { lines_before = [] 39 | ; current_line = { characters_before = "" 40 | ; characters_after = "" } 41 | ; cursor_col = None 42 | ; lines_after = [] 43 | } 44 | | line::lines_after -> 45 | { lines_before = [ ] 46 | ; current_line = { characters_before = "" 47 | ; characters_after = line } 48 | ; cursor_col = None 49 | ; lines_after 50 | } 51 | 52 | let string_of_current_line {characters_before;characters_after} = 53 | (String.length characters_before, 54 | characters_before ^ characters_after) 55 | 56 | let current_line_of_string i string = 57 | if i > String.length string then 58 | { characters_before = string 59 | ; characters_after = "" 60 | } 61 | else 62 | { characters_before = String.sub string 0 i 63 | ; characters_after = String.sub string i (String.length string - i) 64 | } 65 | 66 | let move_up ({lines_before;current_line;cursor_col;lines_after} as t) = 67 | match lines_before with 68 | | [] -> t 69 | | new_current_line::lines_before -> 70 | let pos, line = string_of_current_line current_line in 71 | let pos = Option.default pos cursor_col in 72 | let current_line = current_line_of_string pos new_current_line in 73 | { lines_before 74 | ; current_line 75 | ; cursor_col = Some pos 76 | ; lines_after = line::lines_after 77 | } 78 | 79 | let move_down ({lines_before;current_line;cursor_col;lines_after} as t) = 80 | match lines_after with 81 | | [] -> 82 | let {characters_before;characters_after} = current_line in 83 | {t with current_line = 84 | { characters_before = characters_before ^ characters_after 85 | ; characters_after = "" 86 | } 87 | } 88 | | new_current_line::lines_after -> 89 | let pos, line = string_of_current_line current_line in 90 | let pos = Option.default pos cursor_col in 91 | let current_line = current_line_of_string pos new_current_line in 92 | { lines_before = line::lines_before 93 | ; cursor_col = Some pos 94 | ; current_line 95 | ; lines_after 96 | } 97 | 98 | let move_left ({current_line} as t) = 99 | let {characters_before;characters_after} = current_line in 100 | let l = String.length characters_before in 101 | if l = 0 then 102 | let {lines_before;lines_after} = t in 103 | (match lines_before with 104 | | [] -> t 105 | | line::lines_before -> 106 | let _, line_after = string_of_current_line current_line in 107 | { lines_before 108 | ; current_line = { characters_before = line; characters_after = "" } 109 | ; cursor_col = None 110 | ; lines_after = line_after::lines_after 111 | }) 112 | else 113 | {t with current_line = 114 | { characters_before = String.sub characters_before 0 (l - 1) 115 | ; characters_after = String.sub characters_before (l-1) 1 ^ characters_after 116 | }; 117 | cursor_col = None 118 | } 119 | 120 | let move_right ({current_line} as t) = 121 | let {characters_before;characters_after} = current_line in 122 | let l = String.length characters_after in 123 | if l = 0 then 124 | let {lines_before;lines_after} = t in 125 | (match lines_after with 126 | | [] -> t 127 | | line::lines_after -> 128 | let _, line_before = string_of_current_line current_line in 129 | { lines_before = line_before::lines_before 130 | ; current_line = { characters_after = line; characters_before = "" } 131 | ; cursor_col = None 132 | ; lines_after 133 | }) 134 | else 135 | {t with current_line = 136 | { characters_before = characters_before ^ String.sub characters_after 0 1 137 | ; characters_after = String.sub characters_after 1 (l-1) 138 | }; 139 | cursor_col = None 140 | } 141 | 142 | let insert c ({current_line} as t) = 143 | let {characters_before;characters_after} = current_line in 144 | {t with current_line = 145 | { characters_before = characters_before ^ String.make 1 c 146 | ; characters_after 147 | }; 148 | cursor_col = None 149 | } 150 | 151 | let insert_before c ({current_line} as t) = 152 | let {characters_before;characters_after} = current_line in 153 | {t with current_line = 154 | { characters_before 155 | ; characters_after = String.make 1 c ^ characters_after 156 | }; 157 | cursor_col = None 158 | } 159 | 160 | let newline ({lines_before;current_line} as t) = 161 | {t with 162 | lines_before = current_line.characters_before :: lines_before; 163 | current_line = { current_line with characters_before = "" }; 164 | cursor_col = None} 165 | 166 | let delete_backwards ({current_line} as t) = 167 | let {characters_before;characters_after} = current_line in 168 | if String.length characters_before = 0 then 169 | let {lines_before;lines_after} = t in 170 | (match lines_before with 171 | | [] -> 172 | t 173 | | line::lines_before -> 174 | { lines_before 175 | ; current_line = { characters_before = line; characters_after } 176 | ; lines_after 177 | ; cursor_col = None 178 | }) 179 | else 180 | {t with current_line = 181 | { characters_before = String.sub characters_before 0 (String.length characters_before - 1) 182 | ; characters_after 183 | }; 184 | cursor_col = None 185 | } 186 | 187 | let delete_forwards ({current_line} as t) = 188 | let {characters_before;characters_after} = current_line in 189 | if String.length characters_after = 0 then 190 | let {lines_before;lines_after} = t in 191 | (match lines_after with 192 | | [] -> 193 | t 194 | | line::lines_after -> 195 | { lines_before 196 | ; current_line = { characters_after = line; characters_before } 197 | ; lines_after 198 | ; cursor_col = None 199 | }) 200 | else 201 | {t with 202 | current_line = 203 | {current_line with 204 | characters_after = String.sub characters_after 1 (String.length characters_after - 1) 205 | }; 206 | cursor_col = None 207 | } 208 | 209 | (* TODO *) 210 | (* 1. More navigation: 211 | - start of line 212 | - end of line 213 | - start of buffer 214 | - end of buffer 215 | - search for text? *) 216 | (* 2. Selection mode 217 | - "mark set" 218 | - basically, the cursor'd region becomes a sequence instead of a single character 219 | - movement changes the 'point' 220 | - making any edit *) 221 | (* 3. Syntax highlight/semantic analysis 222 | - state-based analysis 223 | - assignment of spans to pieces of text in the buffer (or just characters? emacs does characters) 224 | - *) 225 | 226 | (**********************************************************************) 227 | 228 | (* rendering: 229 | 230 | - each line becomes a
 element
231 |    - the character currently under the cursor is wrapped in a 
232 |    - line numbers?
233 | 
234 |    unicode? combining characters? graphemes? what should cursor
235 |    movement/deletion do?
236 | *)
237 | 
238 | type action =
239 |   | Insert of char
240 |   | Backspace
241 |   | Newline
242 |   | Delete
243 |   | Movement of [`Up|`Down|`Left|`Right]
244 | 
245 | let string_of_action = function
246 |   | Insert c  -> Printf.sprintf "Insert %C" c
247 |   | Backspace -> "Backspace"
248 |   | Movement `Up    -> "Up"
249 |   | Movement `Down  -> "Down"
250 |   | Movement `Left  -> "Left"
251 |   | Movement `Right -> "Right"
252 |   | Newline   -> "Newline"
253 |   | Delete    -> "Delete"
254 | 
255 | let line ?(current=false) children =
256 |   let classes =
257 |     List.concat [ ["line"]
258 |                 ; if current then ["current-line"] else []
259 |                 ]
260 |   in
261 |   Html.(pre ~attrs:[ A.class_ (String.concat " " classes) ] children)
262 | 
263 | let render_current_line {characters_before;characters_after} =
264 |   let open Html in
265 |   line ~current:true begin
266 |     text characters_before
267 |     ^^
268 |     if String.length characters_after = 0 then
269 |       span ~attrs:[A.class_ "cursor"] (text " ")
270 |     else begin
271 |       span ~attrs:[A.class_ "cursor"] (text (String.sub characters_after 0 1))
272 |       ^^
273 |       text (String.sub characters_after 1 (String.length characters_after - 1))
274 |     end
275 |   end
276 | 
277 | let render state =
278 |   let open Html in
279 |   let onkeypress key_code char_code =
280 |     if key_code = Keycode.up then Some (Movement `Up)
281 |     else if key_code = Keycode.down then Some (Movement `Down)
282 |     else if key_code = Keycode.left then Some (Movement `Left)
283 |     else if key_code = Keycode.right then Some (Movement `Right)
284 |     else if key_code = Keycode.backspace then Some Backspace
285 |     else if key_code = Keycode.return then Some Newline
286 |     else if key_code = Keycode.delete then Some Delete
287 |     else if char_code <> 0 then Some (Insert (Char.chr char_code))
288 |     else None
289 |   in
290 |   let line s =
291 |     if s = "" then line (text " ")
292 |     else line (text s)
293 |   in
294 |   div
295 |     ~attrs:[ A.tabindex 1
296 |            ; A.class_ "editor"
297 |            ; E.onkeypress onkeypress
298 |            ]
299 |     begin
300 |       of_list (List.rev_map line state.lines_before)
301 |       ^^
302 |       render_current_line state.current_line
303 |       ^^
304 |       of_list (List.map line state.lines_after)
305 |     end
306 | 
307 | let update = function
308 |   | Movement `Up    -> move_up
309 |   | Movement `Down  -> move_down
310 |   | Movement `Left  -> move_left
311 |   | Movement `Right -> move_right
312 |   | Insert c        -> insert c
313 |   | Backspace       -> delete_backwards
314 |   | Newline         -> newline
315 |   | Delete          -> delete_forwards
316 | 
317 | let initial =
318 |   of_string "## Basic design notes
319 | 
320 | The library (such as it is) is based around a single `Component`
321 | module signature:
322 | 
323 | ````ocaml
324 | module type Component = sig
325 |     type state
326 |     type action
327 | 
328 |     val render  : state -> action html
329 |     val update  : action -> state -> state
330 |     val initial : state
331 | end
332 | ````
333 | 
334 | The type `state` represents the set of all possible states that the
335 | component can be in, and the type `action` represents all the possible
336 | actions that can be peformed by the user. For each possible state, the
337 | `render` function generates a reactive HTML document that can be
338 | manipulated by the use to generate actions. The `update` function is
339 | then used to translate an action into a state transformation
340 | function. The `initial` value is used as the initial state of the
341 | component.
342 | "
343 | 


--------------------------------------------------------------------------------
/OCamlMVC.ml:
--------------------------------------------------------------------------------
  1 | let ( !$ ) x = Js.string x
  2 | let ( >>?= ) = Js.Opt.iter
  3 | let identity x = x
  4 | let (<.>) f g x = f (g x)
  5 | 
  6 | (**********************************************************************)
  7 | module StringMap = Map.Make (String)
  8 | 
  9 | type attributes = string StringMap.t
 10 | 
 11 | (**********************************************************************)
 12 | type 'action event =
 13 |   | Event : ('e #Dom.event Js.t as 'b) Dom.Event.typ
 14 |             * (Dom_html.element Js.t -> 'b -> 'action option)
 15 |     -> 'action event
 16 | 
 17 | type 'action events = 'action event list
 18 | 
 19 | (**********************************************************************)
 20 | type 'action node =
 21 |   | Map  : ('inner_action -> 'action) * 'inner_action node     -> 'action node
 22 |   | El   : string * attributes * 'action events * 'action html -> 'action node
 23 |   | Text : string                                              -> 'action node
 24 | and 'action html =
 25 |   'action node list
 26 | (*
 27 |   Idea: the function and the data are stored in the generated tree,
 28 |   and if they are both equal next time, then the generated tree
 29 |   underneath is assumed to be the same. Use physical equality.
 30 | 
 31 |   | Cacheable : 'a * ('a -> 'action html)                         -> 'action html
 32 | *)
 33 | 
 34 | (**********************************************************************)
 35 | module Html = struct
 36 |   (* FIXME:
 37 |      - Merge adjacent text nodes? (didn't do this before)
 38 |      - More efficient concatenation? just have a 'Concat' constructor?
 39 |      - Let the update function deal with the associativity?
 40 |   *)
 41 |   type 'a t = 'a html
 42 | 
 43 |   type 'action attribute =
 44 |     | A_Simple of string * string
 45 |     | A_Event : ('a #Dom.event Js.t as 'b) Dom.Event.typ
 46 |               * (Dom_html.element Js.t -> 'b -> 'action option)
 47 |       -> 'action attribute
 48 | 
 49 |   let empty = []
 50 | 
 51 |   let (^^) html1 html2 =
 52 |     html1 @ html2
 53 | 
 54 | 
 55 |   let of_list nodess =
 56 |     List.concat nodess
 57 | 
 58 |   let map f t =
 59 |     List.map (fun node -> Map (f, node)) t
 60 | 
 61 |   let attributes_and_handlers list =
 62 |     let attributes, handlers =
 63 |       List.fold_left
 64 |         (fun (attributes, handlers) surface_attr ->
 65 |            match surface_attr with
 66 |              | A_Simple (name, value) ->
 67 |                 (StringMap.add name value attributes, handlers)
 68 |              | A_Event (typ, h) ->
 69 |                 (attributes, Event (typ, h)::handlers))
 70 |         (StringMap.empty, [])
 71 |         list
 72 |     in
 73 |     (attributes, List.rev handlers)
 74 | 
 75 |   let elt name ?(attrs=[]) children =
 76 |     let attributes, handlers = attributes_and_handlers attrs in
 77 |     [El (name, attributes, handlers, children)]
 78 | 
 79 |   let elt_empty name ?attrs () =
 80 |     elt name ?attrs []
 81 | 
 82 |   let text text =
 83 |     [Text text]
 84 | 
 85 |   (* 4.1 The root element *)
 86 |   let html ?attrs = elt "html" ?attrs
 87 | 
 88 |   (* 4.2 Document metadata *)
 89 |   let head ?attrs = elt "head" ?attrs
 90 |   let title ?attrs = elt "title" ?attrs
 91 |   let base ?attrs = elt "base" ?attrs
 92 |   let link ?attrs = elt "link" ?attrs
 93 |   let meta ?attrs = elt "meta" ?attrs
 94 |   let style ?attrs = elt "style" ?attrs
 95 | 
 96 |   (* 4.3 Sections *)
 97 |   let body ?attrs = elt "body" ?attrs
 98 |   let article ?attrs = elt "article" ?attrs
 99 |   let section ?attrs = elt "section" ?attrs
100 |   let nav ?attrs = elt "nav" ?attrs
101 |   let aside ?attrs = elt "aside" ?attrs
102 |   let h1 ?attrs = elt "h1" ?attrs
103 |   let h2 ?attrs = elt "h2" ?attrs
104 |   let h3 ?attrs = elt "h3" ?attrs
105 |   let h4 ?attrs = elt "h4" ?attrs
106 |   let h5 ?attrs = elt "h5" ?attrs
107 |   let h6 ?attrs = elt "h6" ?attrs
108 |   let header ?attrs = elt "header" ?attrs
109 |   let footer ?attrs = elt "footer" ?attrs
110 |   let address ?attrs = elt "address" ?attrs
111 | 
112 |   (* 4.4 Grouping content *)
113 |   let p ?attrs = elt "p" ?attrs
114 |   let hr ?attrs = elt_empty "hr" ?attrs
115 |   let pre ?attrs = elt "pre" ?attrs
116 |   let blockquote ?attrs = elt "blockquote" ?attrs
117 |   let ol ?attrs = elt "ol" ?attrs
118 |   let ul ?attrs = elt "ul" ?attrs
119 |   let li ?attrs = elt "li" ?attrs
120 |   let dl ?attrs = elt "dl" ?attrs
121 |   let dt ?attrs = elt "dt" ?attrs
122 |   let dd ?attrs = elt "dd" ?attrs
123 |   let figure ?attrs = elt "figure" ?attrs
124 |   let figcaption ?attrs = elt "figcaption" ?attrs
125 |   let div ?attrs = elt "div" ?attrs
126 |   let main ?attrs = elt "main" ?attrs
127 | 
128 |   (* 4.5 Text level semantics *)
129 |   let a ?attrs = elt "a" ?attrs
130 |   let em ?attrs = elt "em" ?attrs
131 |   let strong ?attrs = elt "strong" ?attrs
132 |   let small ?attrs = elt "small" ?attrs
133 |   let s ?attrs = elt "s" ?attrs
134 |   let cite ?attrs = elt "cite" ?attrs
135 |   let q ?attrs = elt "q" ?attrs
136 |   let dfn ?attrs = elt "dfn" ?attrs
137 |   let abbr ?attrs = elt "abbr" ?attrs
138 |   let data ?attrs = elt "data" ?attrs
139 |   let time ?attrs = elt "time" ?attrs
140 |   let code ?attrs = elt "code" ?attrs
141 |   let var ?attrs = elt "var" ?attrs
142 |   let samp ?attrs = elt "samp" ?attrs
143 |   let kbd ?attrs = elt "kbd" ?attrs
144 |   let sub ?attrs = elt "sub" ?attrs
145 |   let sup ?attrs = elt "sup" ?attrs
146 |   let i ?attrs = elt "i" ?attrs
147 |   let b ?attrs = elt "b" ?attrs
148 |   let u ?attrs = elt "u" ?attrs
149 |   let mark ?attrs = elt "mark" ?attrs
150 |   let ruby ?attrs = elt "ruby" ?attrs
151 |   let rb ?attrs = elt "rb" ?attrs
152 |   let rt ?attrs = elt "rt" ?attrs
153 |   let rtc ?attrs = elt "rtc" ?attrs
154 |   let rp ?attrs = elt "rp" ?attrs
155 |   let bdi ?attrs = elt "bdi" ?attrs
156 |   let bdo ?attrs = elt "bdo" ?attrs
157 |   let span ?attrs = elt "span" ?attrs
158 |   let br ?attrs = elt_empty "br" ?attrs
159 |   let wbr ?attrs = elt_empty "wbr" ?attrs
160 | 
161 |   (* 4.6 Edits *)
162 |   let ins ?attrs = elt "ins" ?attrs
163 |   let del ?attrs = elt "del" ?attrs
164 | 
165 |   (* 4.7 Embedded content *)
166 |   let img ?attrs = elt "img" ?attrs
167 | 
168 |   (* 4.8 Links *)
169 | 
170 |   (* 4.9 Tabular data *)
171 |   let table ?attrs = elt "table" ?attrs
172 |   let caption ?attrs = elt "caption" ?attrs
173 |   let colgroup ?attrs = elt "colgroup" ?attrs
174 |   let col ?attrs = elt "col" ?attrs
175 |   let tbody ?attrs = elt "tbody" ?attrs
176 |   let thead ?attrs = elt "thead" ?attrs
177 |   let tfoot ?attrs = elt "tfoot" ?attrs
178 |   let tr ?attrs = elt "tr" ?attrs
179 |   let td ?attrs = elt "td" ?attrs
180 |   let th ?attrs = elt "th" ?attrs
181 | 
182 |   (* 4.10 Forms *)
183 |   let form ?attrs = elt "form" ?attrs
184 |   let label ?attrs = elt "label" ?attrs
185 |   let input ?attrs = elt "input" ?attrs
186 |   let button ?attrs = elt "button" ?attrs
187 |   let select ?attrs = elt "select" ?attrs
188 |   let datalist ?attrs = elt "datalist" ?attrs
189 |   let optgroup ?attrs = elt "optgroup" ?attrs
190 |   let option ?attrs = elt "option" ?attrs
191 |   let textarea ?attrs = elt "textarea" ?attrs
192 |   let keygen ?attrs = elt "keygen" ?attrs
193 |   let output ?attrs = elt "output" ?attrs
194 |   let progress ?attrs = elt "progress" ?attrs
195 |   let meter ?attrs = elt "meter" ?attrs
196 |   let fieldset ?attrs = elt "fieldset" ?attrs
197 |   let legend ?attrs = elt "legend" ?attrs
198 | 
199 |   (* 4.11 Scripting (which here just means 'canvas') *)
200 | 
201 |   (* Attributes *)
202 |   module A = struct
203 |     (* Global attributes (3.2.5) *)
204 |     let accesskey value =
205 |       A_Simple ("accesskey", value)
206 |     let class_ value =
207 |       A_Simple ("class", value)
208 |     let contenteditable value =
209 |       A_Simple ("contenteditable", if value then "true" else "false")
210 |     let dir value =
211 |       A_Simple ("dir", match value with `ltr -> "ltr" | `rtl -> "rtl" | `auto -> "auto")
212 |     let hidden value =
213 |       A_Simple ("hidden", if value then "true" else "false")
214 |     let id value =
215 |       A_Simple ("id", value)
216 |     let lang value =
217 |       A_Simple ("lang", value)
218 |     let spellcheck value =
219 |       A_Simple ("spellcheck", if value then "true" else "false")
220 |     let style value =
221 |       A_Simple ("style", value)
222 |     let tabindex value =
223 |       A_Simple ("tabindex", string_of_int value)
224 |     let title value =
225 |       A_Simple ("title", value)
226 |     let translate value =
227 |       A_Simple ("translate", if value then "yes" else "no")
228 | 
229 |     (* 'html' element attributes (4.1.1) *)
230 |     let manifest value =
231 |       A_Simple ("manifest", value)
232 | 
233 |     (* 'a' element attributes (4.5.1) *)
234 |     let href value =
235 |       A_Simple ("href", value)
236 |     let target value =
237 |       A_Simple ("target", value)
238 |     let download value =
239 |       A_Simple ("download", value)
240 |     let rel value =
241 |       A_Simple ("rel", value)
242 |     let hreflang value =
243 |       A_Simple ("hreflang", value)
244 |     let type_ value =
245 |       A_Simple ("type", value)
246 | 
247 |     (* For 'img' elements *)
248 |     let src value =
249 |       A_Simple ("src", value)
250 | 
251 |     (* For 'form' elements *)
252 |     let accept_charset value =
253 |       A_Simple ("accept-charset", value)
254 |     let action value =
255 |       A_Simple ("action", value)
256 |     let autocomplete value =
257 |       A_Simple ("autocomplete", value)
258 |     let enctype value =
259 |       A_Simple ("enctype", value)
260 |     let http_method value =
261 |       A_Simple ("method", value)
262 |     let name value =
263 |       A_Simple ("name", value)
264 |     let novalidate value = (*FIXME: boolean?*)
265 |       A_Simple ("novalidate", value)
266 |     let target value =
267 |       A_Simple ("target", value)
268 | 
269 |     (* For 'label' elements *)
270 |     let form value =
271 |       A_Simple ("form", value)
272 |     let for_control value =
273 |       A_Simple ("for", value)
274 | 
275 |     (* For 'input' elements *)
276 |     let accept value =
277 |       A_Simple ("accept", value)
278 |     let alt value =
279 |       A_Simple ("alt", value)
280 |     (* FIXME *)
281 |     let enabled value =
282 |       A_Simple ("enabled", if value then "yes" else "no")
283 |     let checked value =
284 |       A_Simple ("checked", if value then "yes" else "no")
285 |     let value value =
286 |       A_Simple ("value", value)
287 |     let placeholder value =
288 |       A_Simple ("placeholder", value)
289 |   end
290 | 
291 |   (* Events *)
292 |   module E = struct
293 |     let onkeypress f =
294 |       A_Event
295 |         (Dom_html.Event.keypress,
296 |          fun node ev ->
297 |            let char_code = Js.Optdef.get (ev##charCode) (fun () -> 0) in
298 |            (* FIXME: and all the other attributes of ev *)
299 | (*           let key =
300 |              Js.to_string @@
301 |              Js.Optdef.get (ev##keyIdentifier) (fun () -> Js.string "")
302 |            in*)
303 |            f (ev##keyCode) char_code)
304 | 
305 |     let onclick action =
306 |       A_Event
307 |         (Dom_html.Event.click,
308 |          (* FIXME: supply the event attributes properly *)
309 |          fun node ev -> Some action)
310 | 
311 |     let ondoubleclick action =
312 |       A_Event
313 |         (Dom_html.Event.dblclick,
314 |          fun node ev -> Some action)
315 | 
316 |     let oninput f =
317 |       A_Event
318 |         (Dom_html.Event.input,
319 |          fun node ev ->
320 |            let s =
321 |              Js.Optdef.get (* FIXME: this will return empty string if undefined *)
322 |                ((Js.Unsafe.coerce node)##value)
323 |                (fun _ -> Js.string "")
324 |            in
325 |            Some (f ~value:(Js.to_string s)))
326 | 
327 |     let onchange f =
328 |       A_Event
329 |         (Dom_html.Event.change,
330 |          fun node ev ->
331 |            let s =
332 |              Js.Optdef.get (* FIXME: this will return empty string if undefined *)
333 |                ((Js.Unsafe.coerce node)##value)
334 |                (fun _ -> Js.string "")
335 |            in
336 |            Some (f ~value:(Js.to_string s)))
337 |   end
338 | end
339 | 
340 | (**********************************************************************)
341 | type tree =
342 |   | El_existing
343 |     : Dom_html.element Js.t
344 |       * string
345 |       * attributes
346 |       * Dom.event_listener_id list
347 |       * trees
348 |     -> tree
349 |   | Text_existing : Dom.text Js.t * string -> tree
350 |   | Dummy : tree -> tree
351 | and trees =
352 |   tree list
353 | 
354 | let rec node_of_tree = function
355 |   | El_existing (node, _, _, _, _) -> (node :> Dom.node Js.t)
356 |   | Text_existing (node, _)        -> (node :> Dom.node Js.t)
357 |   | Dummy tree                     -> node_of_tree tree
358 | 
359 | let add_handler h node = function
360 |   | Event (typ, func) ->
361 |      let handler = Dom.handler (fun ev ->
362 |          match func node ev with
363 |            | None -> Js._true
364 |            | Some action -> h action)
365 |      in
366 |      Dom.addEventListener node typ handler Js._false
367 | 
368 | let rec create : 'a. ('a -> bool Js.t) -> Dom_html.element Js.t option -> 'a node -> tree =
369 |   fun h parent new_tree -> match new_tree with
370 |     | Map (f, child) ->
371 |        Dummy (create (h <.> f) parent child)
372 | 
373 |     | El (tag, attrs, events, children) ->
374 |        let node = Dom_html.document##createElement (!$tag) in
375 |        attrs |> StringMap.iter begin fun attr value ->
376 |          node##setAttribute (!$attr, !$value)
377 |        end;
378 |        let handler_ids = List.map (add_handler h node) events in
379 |        let children = create_nodes h (Some node) children in
380 |        (match parent with
381 |          | None -> () | Some parent -> Dom.appendChild parent node);
382 |        El_existing (node, tag, attrs, handler_ids, children)
383 | 
384 |     | Text text ->
385 |        let node = Dom_html.document##createTextNode (!$text) in
386 |        (match parent with
387 |          | None -> () | Some parent -> Dom.appendChild parent node);
388 |        Text_existing (node, text)
389 | 
390 | and create_nodes : 'a. ('a -> bool Js.t) -> Dom_html.element Js.t option -> 'a html -> trees =
391 |   fun h parent -> List.map (create h parent)
392 | 
393 | let update_attrs node existing_attrs new_attrs =
394 |   let added_attrs =
395 |     StringMap.fold
396 |       (fun attr value new_attrs ->
397 |          match StringMap.find attr new_attrs with
398 |            | exception Not_found ->
399 |               node##removeAttribute (!$attr);
400 |               new_attrs
401 |            | new_value when value = new_value ->
402 |               StringMap.remove attr new_attrs
403 |            | new_value ->
404 |               node##setAttribute (!$attr, !$new_value);
405 |               StringMap.remove attr new_attrs)
406 |       existing_attrs
407 |       new_attrs
408 |   in
409 |   added_attrs |> StringMap.iter (fun attr value ->
410 |     node##setAttribute (!$attr, !$value))
411 | 
412 | (* FIXME: make this better: what's so special about checkboxes? *)
413 | let set_input_props node attrs =
414 |   Dom_html.CoerceTo.input node        >>?= fun input_node ->
415 |   input_node##getAttribute (!$"type") >>?= fun s ->
416 |   match Js.to_string s with
417 |     | "checkbox" ->
418 |        input_node##checked <- Js.bool (StringMap.mem "checked" attrs)
419 |     | _ ->
420 |        (try input_node##value <- !$(StringMap.find "value" attrs)
421 |         with Not_found -> ())
422 | 
423 | let rec update_tree : 'a. ('a -> bool Js.t) -> Dom_html.element Js.t -> tree -> 'a node -> tree =
424 |   fun h parent existing_tree new_tree ->
425 |     match existing_tree, new_tree with
426 |       | Dummy existing, new_tree ->
427 |          update_tree h parent existing new_tree
428 | 
429 |       | existing, Map (f, new_tree) ->
430 |          update_tree (h <.> f) parent existing new_tree
431 | 
432 |       | El_existing (node, tag1, attrs1, handler_ids, children1), El (tag2, attrs2, events, children2) when tag1 = tag2 ->
433 |          List.iter Dom.removeEventListener handler_ids;
434 |          set_input_props node attrs2;
435 |          update_attrs node attrs1 attrs2;
436 |          let handler_ids = List.map (add_handler h node) events in
437 |          let children    = update_trees h node children1 children2 in
438 |          El_existing (node, tag2, attrs2, handler_ids, children)
439 | 
440 |       | Text_existing (node, text1), Text text2 when text1 = text2 ->
441 |          Text_existing (node, text1)
442 | 
443 |       | Text_existing (node, text1), Text text2 ->
444 |          node##data <- !$text2;
445 |          Text_existing (node, text2)
446 | 
447 |       | existing_tree, new_tree ->
448 |          let tree = create h None new_tree in
449 |          Dom.replaceChild parent
450 |            (node_of_tree tree)
451 |            (node_of_tree existing_tree);
452 |          tree
453 | 
454 | and update_trees : 'a. ('a -> bool Js.t) -> Dom_html.element Js.t -> trees -> 'a node list -> trees =
455 |   fun h parent existing_trees new_trees ->
456 |     match existing_trees, new_trees with
457 |       | existing_tree::existing_trees, new_tree::new_trees ->
458 |          update_tree h parent existing_tree new_tree::
459 |          update_trees h parent existing_trees new_trees
460 | 
461 |       | [], new_trees ->
462 |          new_trees |> List.map (create h (Some parent))
463 | 
464 |       | old_trees, [] ->
465 |          old_trees |> List.iter begin fun old_tree ->
466 |            Dom.removeChild parent (node_of_tree old_tree)
467 |          end;
468 |          []
469 | 
470 | (**********************************************************************)
471 | let run render update parent state =
472 |   let current_tree = ref None in
473 |   let rec loop state =
474 |     let handler action = loop (update action state) in
475 |     let html = render state in
476 |     (match !current_tree with
477 |       | None ->
478 |          current_tree := Some (create_nodes handler (Some parent) html)
479 |       | Some tree ->
480 |          current_tree := Some (update_trees handler parent tree html));
481 |     Js._false
482 |   in
483 |   loop state
484 | 
485 | (**********************************************************************)
486 | module type Component = sig
487 |   type state
488 |   type action
489 | 
490 |   val render  : state -> action html
491 |   val update  : action -> state -> state
492 |   val initial : state
493 | end
494 | 
495 | type component = (module Component)
496 | type 'action component' = (module Component with type action = 'action)
497 | 
498 | let attach ~parent_id (module C : Component) =
499 |   Dom_html.document##getElementById (!$parent_id) >>?= fun parent ->
500 |   ignore (run C.render C.update parent C.initial)
501 | 


--------------------------------------------------------------------------------
/css/foundation.min.css:
--------------------------------------------------------------------------------
1 | @import url("//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,700");meta.foundation-mq-small{font-family:"/only screen and (max-width: 40em)/";width:0em}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.063em) and (max-width:64em)/";width:40.063em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.063em)/";width:64.063em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.063em)/";width:90.063em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.063em)/";width:120.063em}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:#222;padding:0;margin:0;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-weight:normal;font-style:normal;line-height:1;position:relative;cursor:default}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}.hide{display:none}.antialiased{-webkit-font-smoothing:antialiased}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5rem;*zoom:1}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{position:relative;padding-left:0;padding-right:0;float:left}.row.collapse .row{margin-left:0;margin-right:0}.row .row{width:auto;margin-left:-0.9375rem;margin-right:-0.9375rem;margin-top:0;margin-bottom:0;max-width:none;*zoom:1}.row .row:before,.row .row:after{content:" ";display:table}.row .row:after{clear:both}.row .row.collapse{width:auto;margin:0;max-width:none;*zoom:1}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table}.row .row.collapse:after{clear:both}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;width:100%;float:left}@media only screen{.small-push-1{position:relative;left:8.33333%;right:auto}.small-pull-1{position:relative;right:8.33333%;left:auto}.small-push-2{position:relative;left:16.66667%;right:auto}.small-pull-2{position:relative;right:16.66667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.33333%;right:auto}.small-pull-4{position:relative;right:33.33333%;left:auto}.small-push-5{position:relative;left:41.66667%;right:auto}.small-pull-5{position:relative;right:41.66667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.33333%;right:auto}.small-pull-7{position:relative;right:58.33333%;left:auto}.small-push-8{position:relative;left:66.66667%;right:auto}.small-pull-8{position:relative;right:66.66667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.33333%;right:auto}.small-pull-10{position:relative;right:83.33333%;left:auto}.small-push-11{position:relative;left:91.66667%;right:auto}.small-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.small-1{position:relative;width:8.33333%}.small-2{position:relative;width:16.66667%}.small-3{position:relative;width:25%}.small-4{position:relative;width:33.33333%}.small-5{position:relative;width:41.66667%}.small-6{position:relative;width:50%}.small-7{position:relative;width:58.33333%}.small-8{position:relative;width:66.66667%}.small-9{position:relative;width:75%}.small-10{position:relative;width:83.33333%}.small-11{position:relative;width:91.66667%}.small-12{position:relative;width:100%}.small-offset-0{position:relative;margin-left:0%}.small-offset-1{position:relative;margin-left:8.33333%}.small-offset-2{position:relative;margin-left:16.66667%}.small-offset-3{position:relative;margin-left:25%}.small-offset-4{position:relative;margin-left:33.33333%}.small-offset-5{position:relative;margin-left:41.66667%}.small-offset-6{position:relative;margin-left:50%}.small-offset-7{position:relative;margin-left:58.33333%}.small-offset-8{position:relative;margin-left:66.66667%}.small-offset-9{position:relative;margin-left:75%}.small-offset-10{position:relative;margin-left:83.33333%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.column.small-centered,.columns.small-centered{position:relative;margin-left:auto;margin-right:auto;float:none !important}.column.small-uncentered,.columns.small-uncentered{margin-left:0;margin-right:0;float:left !important}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right !important}}@media only screen and (min-width: 40.063em){.medium-push-1{position:relative;left:8.33333%;right:auto}.medium-pull-1{position:relative;right:8.33333%;left:auto}.medium-push-2{position:relative;left:16.66667%;right:auto}.medium-pull-2{position:relative;right:16.66667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.33333%;right:auto}.medium-pull-4{position:relative;right:33.33333%;left:auto}.medium-push-5{position:relative;left:41.66667%;right:auto}.medium-pull-5{position:relative;right:41.66667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.33333%;right:auto}.medium-pull-7{position:relative;right:58.33333%;left:auto}.medium-push-8{position:relative;left:66.66667%;right:auto}.medium-pull-8{position:relative;right:66.66667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.33333%;right:auto}.medium-pull-10{position:relative;right:83.33333%;left:auto}.medium-push-11{position:relative;left:91.66667%;right:auto}.medium-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.medium-1{position:relative;width:8.33333%}.medium-2{position:relative;width:16.66667%}.medium-3{position:relative;width:25%}.medium-4{position:relative;width:33.33333%}.medium-5{position:relative;width:41.66667%}.medium-6{position:relative;width:50%}.medium-7{position:relative;width:58.33333%}.medium-8{position:relative;width:66.66667%}.medium-9{position:relative;width:75%}.medium-10{position:relative;width:83.33333%}.medium-11{position:relative;width:91.66667%}.medium-12{position:relative;width:100%}.medium-offset-0{position:relative;margin-left:0%}.medium-offset-1{position:relative;margin-left:8.33333%}.medium-offset-2{position:relative;margin-left:16.66667%}.medium-offset-3{position:relative;margin-left:25%}.medium-offset-4{position:relative;margin-left:33.33333%}.medium-offset-5{position:relative;margin-left:41.66667%}.medium-offset-6{position:relative;margin-left:50%}.medium-offset-7{position:relative;margin-left:58.33333%}.medium-offset-8{position:relative;margin-left:66.66667%}.medium-offset-9{position:relative;margin-left:75%}.medium-offset-10{position:relative;margin-left:83.33333%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.column.medium-centered,.columns.medium-centered{position:relative;margin-left:auto;margin-right:auto;float:none !important}.column.medium-uncentered,.columns.medium-uncentered{margin-left:0;margin-right:0;float:left !important}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right !important}.push-1{position:relative;left:8.33333%;right:auto}.pull-1{position:relative;right:8.33333%;left:auto}.push-2{position:relative;left:16.66667%;right:auto}.pull-2{position:relative;right:16.66667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.33333%;right:auto}.pull-4{position:relative;right:33.33333%;left:auto}.push-5{position:relative;left:41.66667%;right:auto}.pull-5{position:relative;right:41.66667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.33333%;right:auto}.pull-7{position:relative;right:58.33333%;left:auto}.push-8{position:relative;left:66.66667%;right:auto}.pull-8{position:relative;right:66.66667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.33333%;right:auto}.pull-10{position:relative;right:83.33333%;left:auto}.push-11{position:relative;left:91.66667%;right:auto}.pull-11{position:relative;right:91.66667%;left:auto}}@media only screen and (min-width: 64.063em){.large-push-1{position:relative;left:8.33333%;right:auto}.large-pull-1{position:relative;right:8.33333%;left:auto}.large-push-2{position:relative;left:16.66667%;right:auto}.large-pull-2{position:relative;right:16.66667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.33333%;right:auto}.large-pull-4{position:relative;right:33.33333%;left:auto}.large-push-5{position:relative;left:41.66667%;right:auto}.large-pull-5{position:relative;right:41.66667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.33333%;right:auto}.large-pull-7{position:relative;right:58.33333%;left:auto}.large-push-8{position:relative;left:66.66667%;right:auto}.large-pull-8{position:relative;right:66.66667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.33333%;right:auto}.large-pull-10{position:relative;right:83.33333%;left:auto}.large-push-11{position:relative;left:91.66667%;right:auto}.large-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.large-1{position:relative;width:8.33333%}.large-2{position:relative;width:16.66667%}.large-3{position:relative;width:25%}.large-4{position:relative;width:33.33333%}.large-5{position:relative;width:41.66667%}.large-6{position:relative;width:50%}.large-7{position:relative;width:58.33333%}.large-8{position:relative;width:66.66667%}.large-9{position:relative;width:75%}.large-10{position:relative;width:83.33333%}.large-11{position:relative;width:91.66667%}.large-12{position:relative;width:100%}.large-offset-0{position:relative;margin-left:0%}.large-offset-1{position:relative;margin-left:8.33333%}.large-offset-2{position:relative;margin-left:16.66667%}.large-offset-3{position:relative;margin-left:25%}.large-offset-4{position:relative;margin-left:33.33333%}.large-offset-5{position:relative;margin-left:41.66667%}.large-offset-6{position:relative;margin-left:50%}.large-offset-7{position:relative;margin-left:58.33333%}.large-offset-8{position:relative;margin-left:66.66667%}.large-offset-9{position:relative;margin-left:75%}.large-offset-10{position:relative;margin-left:83.33333%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.column.large-centered,.columns.large-centered{position:relative;margin-left:auto;margin-right:auto;float:none !important}.column.large-uncentered,.columns.large-uncentered{margin-left:0;margin-right:0;float:left !important}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right !important}}@media only screen and (min-width: 90.063em){.xlarge-push-1{position:relative;left:8.33333%;right:auto}.xlarge-pull-1{position:relative;right:8.33333%;left:auto}.xlarge-push-2{position:relative;left:16.66667%;right:auto}.xlarge-pull-2{position:relative;right:16.66667%;left:auto}.xlarge-push-3{position:relative;left:25%;right:auto}.xlarge-pull-3{position:relative;right:25%;left:auto}.xlarge-push-4{position:relative;left:33.33333%;right:auto}.xlarge-pull-4{position:relative;right:33.33333%;left:auto}.xlarge-push-5{position:relative;left:41.66667%;right:auto}.xlarge-pull-5{position:relative;right:41.66667%;left:auto}.xlarge-push-6{position:relative;left:50%;right:auto}.xlarge-pull-6{position:relative;right:50%;left:auto}.xlarge-push-7{position:relative;left:58.33333%;right:auto}.xlarge-pull-7{position:relative;right:58.33333%;left:auto}.xlarge-push-8{position:relative;left:66.66667%;right:auto}.xlarge-pull-8{position:relative;right:66.66667%;left:auto}.xlarge-push-9{position:relative;left:75%;right:auto}.xlarge-pull-9{position:relative;right:75%;left:auto}.xlarge-push-10{position:relative;left:83.33333%;right:auto}.xlarge-pull-10{position:relative;right:83.33333%;left:auto}.xlarge-push-11{position:relative;left:91.66667%;right:auto}.xlarge-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.xlarge-1{position:relative;width:8.33333%}.xlarge-2{position:relative;width:16.66667%}.xlarge-3{position:relative;width:25%}.xlarge-4{position:relative;width:33.33333%}.xlarge-5{position:relative;width:41.66667%}.xlarge-6{position:relative;width:50%}.xlarge-7{position:relative;width:58.33333%}.xlarge-8{position:relative;width:66.66667%}.xlarge-9{position:relative;width:75%}.xlarge-10{position:relative;width:83.33333%}.xlarge-11{position:relative;width:91.66667%}.xlarge-12{position:relative;width:100%}.xlarge-offset-0{position:relative;margin-left:0%}.xlarge-offset-1{position:relative;margin-left:8.33333%}.xlarge-offset-2{position:relative;margin-left:16.66667%}.xlarge-offset-3{position:relative;margin-left:25%}.xlarge-offset-4{position:relative;margin-left:33.33333%}.xlarge-offset-5{position:relative;margin-left:41.66667%}.xlarge-offset-6{position:relative;margin-left:50%}.xlarge-offset-7{position:relative;margin-left:58.33333%}.xlarge-offset-8{position:relative;margin-left:66.66667%}.xlarge-offset-9{position:relative;margin-left:75%}.xlarge-offset-10{position:relative;margin-left:83.33333%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.column.xlarge-centered,.columns.xlarge-centered{position:relative;margin-left:auto;margin-right:auto;float:none !important}.column.xlarge-uncentered,.columns.xlarge-uncentered{margin-left:0;margin-right:0;float:left !important}.column.xlarge-uncentered.opposite,.columns.xlarge-uncentered.opposite{float:right !important}}@media only screen and (min-width: 120.063em){.xxlarge-push-1{position:relative;left:8.33333%;right:auto}.xxlarge-pull-1{position:relative;right:8.33333%;left:auto}.xxlarge-push-2{position:relative;left:16.66667%;right:auto}.xxlarge-pull-2{position:relative;right:16.66667%;left:auto}.xxlarge-push-3{position:relative;left:25%;right:auto}.xxlarge-pull-3{position:relative;right:25%;left:auto}.xxlarge-push-4{position:relative;left:33.33333%;right:auto}.xxlarge-pull-4{position:relative;right:33.33333%;left:auto}.xxlarge-push-5{position:relative;left:41.66667%;right:auto}.xxlarge-pull-5{position:relative;right:41.66667%;left:auto}.xxlarge-push-6{position:relative;left:50%;right:auto}.xxlarge-pull-6{position:relative;right:50%;left:auto}.xxlarge-push-7{position:relative;left:58.33333%;right:auto}.xxlarge-pull-7{position:relative;right:58.33333%;left:auto}.xxlarge-push-8{position:relative;left:66.66667%;right:auto}.xxlarge-pull-8{position:relative;right:66.66667%;left:auto}.xxlarge-push-9{position:relative;left:75%;right:auto}.xxlarge-pull-9{position:relative;right:75%;left:auto}.xxlarge-push-10{position:relative;left:83.33333%;right:auto}.xxlarge-pull-10{position:relative;right:83.33333%;left:auto}.xxlarge-push-11{position:relative;left:91.66667%;right:auto}.xxlarge-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375rem;padding-right:0.9375rem;float:left}.xxlarge-1{position:relative;width:8.33333%}.xxlarge-2{position:relative;width:16.66667%}.xxlarge-3{position:relative;width:25%}.xxlarge-4{position:relative;width:33.33333%}.xxlarge-5{position:relative;width:41.66667%}.xxlarge-6{position:relative;width:50%}.xxlarge-7{position:relative;width:58.33333%}.xxlarge-8{position:relative;width:66.66667%}.xxlarge-9{position:relative;width:75%}.xxlarge-10{position:relative;width:83.33333%}.xxlarge-11{position:relative;width:91.66667%}.xxlarge-12{position:relative;width:100%}.xxlarge-offset-0{position:relative;margin-left:0%}.xxlarge-offset-1{position:relative;margin-left:8.33333%}.xxlarge-offset-2{position:relative;margin-left:16.66667%}.xxlarge-offset-3{position:relative;margin-left:25%}.xxlarge-offset-4{position:relative;margin-left:33.33333%}.xxlarge-offset-5{position:relative;margin-left:41.66667%}.xxlarge-offset-6{position:relative;margin-left:50%}.xxlarge-offset-7{position:relative;margin-left:58.33333%}.xxlarge-offset-8{position:relative;margin-left:66.66667%}.xxlarge-offset-9{position:relative;margin-left:75%}.xxlarge-offset-10{position:relative;margin-left:83.33333%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.column.xxlarge-centered,.columns.xxlarge-centered{position:relative;margin-left:auto;margin-right:auto;float:none !important}.column.xxlarge-uncentered,.columns.xxlarge-uncentered{margin-left:0;margin-right:0;float:left !important}.column.xxlarge-uncentered.opposite,.columns.xxlarge-uncentered.opposite{float:right !important}}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.063em)/";width:40.063em}.contain-to-grid{width:100%;background:#333}.contain-to-grid .top-bar{margin-bottom:0}.fixed{width:100%;left:0;position:fixed;top:0;z-index:99}.fixed.expanded:not(.top-bar){overflow-y:auto;height:auto;width:100%;max-height:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{z-index:98;margin-top:45px}.top-bar{overflow:hidden;height:45px;line-height:45px;position:relative;background:#333;margin-bottom:0}.top-bar ul{margin-bottom:0;list-style:none}.top-bar .row{max-width:none}.top-bar form,.top-bar input{margin-bottom:0}.top-bar input{height:auto;padding-top:.35rem;padding-bottom:.35rem;font-size:0.75rem}.top-bar .button{padding-top:.45rem;padding-bottom:.35rem;margin-bottom:0;font-size:0.75rem}.top-bar .title-area{position:relative;margin:0}.top-bar .name{height:45px;margin:0;font-size:16px}.top-bar .name h1{line-height:45px;font-size:1.0625rem;margin:0}.top-bar .name h1 a{font-weight:normal;color:#fff;width:50%;display:block;padding:0 15px}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;text-transform:uppercase;font-size:0.8125rem;font-weight:bold;position:relative;display:block;padding:0 15px;height:45px;line-height:45px}.top-bar .toggle-topbar.menu-icon{right:15px;top:50%;margin-top:-16px;padding-left:40px}.top-bar .toggle-topbar.menu-icon a{text-indent:-48px;width:34px;height:34px;line-height:33px;padding:0;color:#fff}.top-bar .toggle-topbar.menu-icon a span{position:absolute;right:0;display:block;width:16px;height:0;-webkit-box-shadow:0 10px 0 1px #fff,0 16px 0 1px #fff,0 22px 0 1px #fff;box-shadow:0 10px 0 1px #fff,0 16px 0 1px #fff,0 22px 0 1px #fff}.top-bar.expanded{height:auto;background:transparent}.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span{-webkit-box-shadow:0 10px 0 1px #888,0 16px 0 1px #888,0 22px 0 1px #888;box-shadow:0 10px 0 1px #888,0 16px 0 1px #888,0 22px 0 1px #888}.top-bar-section{left:0;position:relative;width:auto;-webkit-transition:left 300ms ease-out;-moz-transition:left 300ms ease-out;transition:left 300ms ease-out}.top-bar-section ul{width:100%;height:auto;display:block;background:#333;font-size:16px;margin:0}.top-bar-section .divider,.top-bar-section [role="separator"]{border-top:solid 1px #1a1a1a;clear:both;height:1px;width:100%}.top-bar-section ul li>a{display:block;width:100%;color:#fff;padding:12px 0 12px 0;padding-left:15px;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-size:0.8125rem;font-weight:normal;background:#333}.top-bar-section ul li>a.button{background:#008cba;font-size:0.8125rem;padding-right:15px;padding-left:15px}.top-bar-section ul li>a.button:hover{background:#006687}.top-bar-section ul li>a.button.secondary{background:#e7e7e7}.top-bar-section ul li>a.button.secondary:hover{background:#cecece}.top-bar-section ul li>a.button.success{background:#43ac6a}.top-bar-section ul li>a.button.success:hover{background:#358753}.top-bar-section ul li>a.button.alert{background:#f04124}.top-bar-section ul li>a.button.alert:hover{background:#d32a0e}.top-bar-section ul li:hover>a{background:#272727;color:#fff}.top-bar-section ul li.active>a{background:#008cba;color:#fff}.top-bar-section ul li.active>a:hover{background:#0079a1}.top-bar-section .has-form{padding:15px}.top-bar-section .has-dropdown{position:relative}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:transparent transparent transparent rgba(255,255,255,0.4);border-left-style:solid;margin-right:15px;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{display:block}.top-bar-section .dropdown{position:absolute;left:100%;top:0;display:none;z-index:99}.top-bar-section .dropdown li{width:100%;height:auto}.top-bar-section .dropdown li a{font-weight:normal;padding:8px 15px}.top-bar-section .dropdown li a.parent-link{font-weight:normal}.top-bar-section .dropdown li.title h5{margin-bottom:0}.top-bar-section .dropdown li.title h5 a{color:#fff;line-height:22.5px;display:block}.top-bar-section .dropdown label{padding:8px 15px 2px;margin-bottom:0;text-transform:uppercase;color:#777;font-weight:bold;font-size:0.625rem}.js-generated{display:block}@media only screen and (min-width: 40.063em){.top-bar{background:#333;*zoom:1;overflow:visible}.top-bar:before,.top-bar:after{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .title-area{float:left}.top-bar .name h1 a{width:auto}.top-bar input,.top-bar .button{font-size:0.875rem;position:relative;top:7px}.top-bar.expanded{background:#333}.contain-to-grid .top-bar{max-width:62.5rem;margin:0 auto;margin-bottom:0}.top-bar-section{-webkit-transition:none 0 0;-moz-transition:none 0 0;transition:none 0 0;left:0 !important}.top-bar-section ul{width:auto;height:auto !important;display:inline}.top-bar-section ul li{float:left}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background:#272727;color:#fff}.top-bar-section li a:not(.button){padding:0 15px;line-height:45px;background:#333}.top-bar-section li a:not(.button):hover{background:#272727}.top-bar-section .has-dropdown>a{padding-right:35px !important}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:rgba(255,255,255,0.4) transparent transparent transparent;border-top-style:solid;margin-top:-2.5px;top:22.5px}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{display:none}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown{display:block}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:1rem;margin-top:-2px;right:5px}.top-bar-section .dropdown{left:0;top:auto;background:transparent;min-width:100%}.top-bar-section .dropdown li a{color:#fff;line-height:1;white-space:nowrap;padding:12px 15px;background:#333}.top-bar-section .dropdown li label{white-space:nowrap;background:#333}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role="separator"]{border-bottom:none;border-top:none;border-right:solid 1px #4d4d4d;clear:none;height:45px;width:0}.top-bar-section .has-form{background:#333;padding:0 15px;height:45px}.top-bar-section ul.right li .dropdown{left:auto;right:0}.top-bar-section ul.right li .dropdown li .dropdown{right:100%}.no-js .top-bar-section ul li:hover>a{background:#272727;color:#fff}.no-js .top-bar-section ul li:active>a{background:#008cba;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown{display:block}}.breadcrumbs{display:block;padding:0.5625rem 0.875rem 0.5625rem;overflow:hidden;margin-left:0;list-style:none;border-style:solid;border-width:1px;background-color:#f4f4f4;border-color:#dadada;-webkit-border-radius:3px;border-radius:3px}.breadcrumbs>*{margin:0;float:left;font-size:0.6875rem;text-transform:uppercase}.breadcrumbs>*:hover a,.breadcrumbs>*:focus a{text-decoration:underline}.breadcrumbs>* a,.breadcrumbs>* span{text-transform:uppercase;color:#008cba}.breadcrumbs>*.current{cursor:default;color:#333}.breadcrumbs>*.current a{cursor:default;color:#333}.breadcrumbs>*.current:hover,.breadcrumbs>*.current:hover a,.breadcrumbs>*.current:focus,.breadcrumbs>*.current:focus a{text-decoration:none}.breadcrumbs>*.unavailable{color:#999}.breadcrumbs>*.unavailable a{color:#999}.breadcrumbs>*.unavailable:hover,.breadcrumbs>*.unavailable:hover a,.breadcrumbs>*.unavailable:focus,.breadcrumbs>*.unavailable a:focus{text-decoration:none;color:#999;cursor:default}.breadcrumbs>*:before{content:"/";color:#aaa;margin:0 0.75rem;position:relative;top:1px}.breadcrumbs>*:first-child:before{content:" ";margin:0}.alert-box{border-style:solid;border-width:1px;display:block;font-weight:normal;margin-bottom:1.25rem;position:relative;padding:0.875rem 1.5rem 0.875rem 0.875rem;font-size:0.8125rem;background-color:#008cba;border-color:#0079a1;color:#fff}.alert-box .close{font-size:1.375rem;padding:9px 6px 4px;line-height:0;position:absolute;top:50%;margin-top:-0.6875rem;right:0.25rem;color:#333;opacity:0.3}.alert-box .close:hover,.alert-box .close:focus{opacity:0.5}.alert-box.radius{-webkit-border-radius:3px;border-radius:3px}.alert-box.round{-webkit-border-radius:1000px;border-radius:1000px}.alert-box.success{background-color:#43ac6a;border-color:#3c9a5f;color:#fff}.alert-box.alert{background-color:#f04124;border-color:#ea2f10;color:#fff}.alert-box.secondary{background-color:#e7e7e7;border-color:#dadada;color:#4e4e4e}.alert-box.warning{background-color:#f08a24;border-color:#ea7d10;color:#fff}.alert-box.info{background-color:#a0d3e8;border-color:#8bc9e3;color:#4e4e4e}.inline-list{margin:0 auto 1.0625rem auto;margin-left:-1.375rem;margin-right:0;padding:0;list-style:none;overflow:hidden}.inline-list>li{list-style:none;float:left;margin-left:1.375rem;display:block}.inline-list>li>*{display:block}button,.button{cursor:pointer;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-weight:normal;line-height:normal;margin:0 0 1.25rem;position:relative;text-decoration:none;text-align:center;display:inline-block;padding-top:1rem;padding-right:2rem;padding-bottom:1.0625rem;padding-left:2rem;font-size:1rem;background-color:#008cba;border-color:#0079a1;color:#fff;-webkit-transition:background-color 300ms ease-out;-moz-transition:background-color 300ms ease-out;transition:background-color 300ms ease-out;padding-top:1.0625rem;padding-bottom:1rem;-webkit-appearance:none;border:none;font-weight:normal !important}button:hover,button:focus,.button:hover,.button:focus{background-color:#0079a1}button:hover,button:focus,.button:hover,.button:focus{color:#fff}button.secondary,.button.secondary{background-color:#e7e7e7;border-color:#dadada;color:#333}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{background-color:#dadada}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{color:#333}button.success,.button.success{background-color:#43ac6a;border-color:#3c9a5f;color:#fff}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{background-color:#3c9a5f}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{color:#fff}button.alert,.button.alert{background-color:#f04124;border-color:#ea2f10;color:#fff}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{background-color:#ea2f10}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{color:#fff}button.large,.button.large{padding-top:1.125rem;padding-right:2.25rem;padding-bottom:1.1875rem;padding-left:2.25rem;font-size:1.25rem}button.small,.button.small{padding-top:0.875rem;padding-right:1.75rem;padding-bottom:0.9375rem;padding-left:1.75rem;font-size:0.8125rem}button.tiny,.button.tiny{padding-top:0.625rem;padding-right:1.25rem;padding-bottom:0.6875rem;padding-left:1.25rem;font-size:0.6875rem}button.expand,.button.expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:0.75rem}button.right-align,.button.right-align{text-align:right;padding-right:0.75rem}button.radius,.button.radius{-webkit-border-radius:3px;border-radius:3px}button.round,.button.round{-webkit-border-radius:1000px;border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled]{background-color:#008cba;border-color:#0079a1;color:#fff;cursor:default;opacity:0.7;-webkit-box-shadow:none;box-shadow:none}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#0079a1}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{color:#fff}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#008cba}button.disabled.secondary,button[disabled].secondary,.button.disabled.secondary,.button[disabled].secondary{background-color:#e7e7e7;border-color:#dadada;color:#333;cursor:default;opacity:0.7;-webkit-box-shadow:none;box-shadow:none}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#dadada}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{color:#333}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#e7e7e7}button.disabled.success,button[disabled].success,.button.disabled.success,.button[disabled].success{background-color:#43ac6a;border-color:#3c9a5f;color:#fff;cursor:default;opacity:0.7;-webkit-box-shadow:none;box-shadow:none}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#3c9a5f}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{color:#fff}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#43ac6a}button.disabled.alert,button[disabled].alert,.button.disabled.alert,.button[disabled].alert{background-color:#f04124;border-color:#ea2f10;color:#fff;cursor:default;opacity:0.7;-webkit-box-shadow:none;box-shadow:none}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#ea2f10}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{color:#fff}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#f04124}@media only screen and (min-width: 40.063em){button,.button{display:inline-block}}.button-group{list-style:none;margin:0;*zoom:1}.button-group:before,.button-group:after{content:" ";display:table}.button-group:after{clear:both}.button-group>*{margin:0;float:left}.button-group>*>button,.button-group>* .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group>*:first-child{margin-left:0}.button-group.radius>*>button,.button-group.radius>* .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.radius>*:first-child,.button-group.radius>*:first-child>a,.button-group.radius>*:first-child>button,.button-group.radius>*:first-child>.button{-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.button-group.radius>*:last-child,.button-group.radius>*:last-child>a,.button-group.radius>*:last-child>button,.button-group.radius>*:last-child>.button{-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.button-group.round>*>button,.button-group.round>* .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.round>*:first-child,.button-group.round>*:first-child>a,.button-group.round>*:first-child>button,.button-group.round>*:first-child>.button{-moz-border-radius-bottomleft:1000px;-moz-border-radius-topleft:1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.button-group.round>*:last-child,.button-group.round>*:last-child>a,.button-group.round>*:last-child>button,.button-group.round>*:last-child>.button{-moz-border-radius-topright:1000px;-moz-border-radius-bottomright:1000px;-webkit-border-top-right-radius:1000px;-webkit-border-bottom-right-radius:1000px;border-top-right-radius:1000px;border-bottom-right-radius:1000px}.button-group.even-2 li{width:50%}.button-group.even-2 li>button,.button-group.even-2 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-2 li button,.button-group.even-2 li .button{width:100%}.button-group.even-3 li{width:33.33333%}.button-group.even-3 li>button,.button-group.even-3 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-3 li button,.button-group.even-3 li .button{width:100%}.button-group.even-4 li{width:25%}.button-group.even-4 li>button,.button-group.even-4 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-4 li button,.button-group.even-4 li .button{width:100%}.button-group.even-5 li{width:20%}.button-group.even-5 li>button,.button-group.even-5 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-5 li button,.button-group.even-5 li .button{width:100%}.button-group.even-6 li{width:16.66667%}.button-group.even-6 li>button,.button-group.even-6 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-6 li button,.button-group.even-6 li .button{width:100%}.button-group.even-7 li{width:14.28571%}.button-group.even-7 li>button,.button-group.even-7 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-7 li button,.button-group.even-7 li .button{width:100%}.button-group.even-8 li{width:12.5%}.button-group.even-8 li>button,.button-group.even-8 li .button{border-right:1px solid;border-color:rgba(255,255,255,0.5)}.button-group.even-8 li button,.button-group.even-8 li .button{width:100%}.button-bar{*zoom:1}.button-bar:before,.button-bar:after{content:" ";display:table}.button-bar:after{clear:both}.button-bar .button-group{float:left;margin-right:0.625rem}.button-bar .button-group div{overflow:hidden}.panel{border-style:solid;border-width:1px;border-color:#d9d9d9;margin-bottom:1.25rem;padding:1.25rem;background:#f2f2f2}.panel>:first-child{margin-top:0}.panel>:last-child{margin-bottom:0}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6,.panel p{color:#333}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6{line-height:1;margin-bottom:0.625rem}.panel h1.subheader,.panel h2.subheader,.panel h3.subheader,.panel h4.subheader,.panel h5.subheader,.panel h6.subheader{line-height:1.4}.panel.callout{border-style:solid;border-width:1px;border-color:#baeeff;margin-bottom:1.25rem;padding:1.25rem;background:#edfbff}.panel.callout>:first-child{margin-top:0}.panel.callout>:last-child{margin-bottom:0}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6,.panel.callout p{color:#333}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6{line-height:1;margin-bottom:0.625rem}.panel.callout h1.subheader,.panel.callout h2.subheader,.panel.callout h3.subheader,.panel.callout h4.subheader,.panel.callout h5.subheader,.panel.callout h6.subheader{line-height:1.4}.panel.callout a{color:#008cba}.panel.radius{-webkit-border-radius:3px;border-radius:3px}.dropdown.button{position:relative;padding-right:3.5625rem}.dropdown.button:before{position:absolute;content:"";width:0;height:0;display:block;border-style:solid;border-color:#fff transparent transparent transparent;top:50%}.dropdown.button:before{border-width:0.375rem;right:1.40625rem;margin-top:-0.15625rem}.dropdown.button:before{border-color:#fff transparent transparent transparent}.dropdown.button.tiny{padding-right:2.625rem}.dropdown.button.tiny:before{border-width:0.375rem;right:1.125rem;margin-top:-0.125rem}.dropdown.button.tiny:before{border-color:#fff transparent transparent transparent}.dropdown.button.small{padding-right:3.0625rem}.dropdown.button.small:before{border-width:0.4375rem;right:1.3125rem;margin-top:-0.15625rem}.dropdown.button.small:before{border-color:#fff transparent transparent transparent}.dropdown.button.large{padding-right:3.625rem}.dropdown.button.large:before{border-width:0.3125rem;right:1.71875rem;margin-top:-0.15625rem}.dropdown.button.large:before{border-color:#fff transparent transparent transparent}.dropdown.button.secondary:before{border-color:#333 transparent transparent transparent}div.switch{position:relative;padding:0;display:block;overflow:hidden;border-style:solid;border-width:1px;margin-bottom:1.25rem;height:2.25rem;background:#fff;border-color:#ccc}div.switch label{position:relative;left:0;z-index:2;float:left;width:50%;height:100%;margin:0;font-weight:bold;text-align:left;-webkit-transition:all 0.1s ease-out;-moz-transition:all 0.1s ease-out;transition:all 0.1s ease-out}div.switch input{position:absolute;z-index:3;opacity:0;width:100%;height:100%;-moz-appearance:none}div.switch input:hover,div.switch input:focus{cursor:pointer}div.switch span:last-child{position:absolute;top:-1px;left:-1px;z-index:1;display:block;padding:0;border-width:1px;border-style:solid;-webkit-transition:all 0.1s ease-out;-moz-transition:all 0.1s ease-out;transition:all 0.1s ease-out}div.switch input:not(:checked)+label{opacity:0}div.switch input:checked{display:none !important}div.switch input{left:0;display:block !important}div.switch input:first-of-type+label,div.switch input:first-of-type+span+label{left:-50%}div.switch input:first-of-type:checked+label,div.switch input:first-of-type:checked+span+label{left:0%}div.switch input:last-of-type+label,div.switch input:last-of-type+span+label{right:-50%;left:auto;text-align:right}div.switch input:last-of-type:checked+label,div.switch input:last-of-type:checked+span+label{right:0%;left:auto}div.switch span.custom{display:none !important}form.custom div.switch .hidden-field{margin-left:auto;position:absolute;visibility:visible}div.switch label{padding:0;line-height:2.3rem;font-size:0.875rem}div.switch input:first-of-type:checked ~ span:last-child{left:100%;margin-left:-2.1875rem}div.switch span:last-child{width:2.25rem;height:2.25rem}div.switch span:last-child{border-color:#b3b3b3;background:#fff;background:-moz-linear-gradient(top, #fff 0%, #f2f2f2 100%);background:-webkit-linear-gradient(top, #fff 0%, #f2f2f2 100%);background:linear-gradient(to bottom, #fff 0%, #f2f2f2 100%);-webkit-box-shadow:2px 0 10px 0 rgba(0,0,0,0.07),1000px 0 0 1000px #f3fbf6,-2px 0 10px 0 rgba(0,0,0,0.07),-1000px 0 0 1000px #f5f5f5;box-shadow:2px 0 10px 0 rgba(0,0,0,0.07),1000px 0 0 980px #f3fbf6,-2px 0 10px 0 rgba(0,0,0,0.07),-1000px 0 0 1000px #f5f5f5}div.switch:hover span:last-child,div.switch:focus span:last-child{background:#fff;background:-moz-linear-gradient(top, #fff 0%, #e6e6e6 100%);background:-webkit-linear-gradient(top, #fff 0%, #e6e6e6 100%);background:linear-gradient(to bottom, #fff 0%, #e6e6e6 100%)}div.switch:active{background:transparent}div.switch.large{height:2.75rem}div.switch.large label{padding:0;line-height:2.3rem;font-size:1.0625rem}div.switch.large input:first-of-type:checked ~ span:last-child{left:100%;margin-left:-2.6875rem}div.switch.large span:last-child{width:2.75rem;height:2.75rem}div.switch.small{height:1.75rem}div.switch.small label{padding:0;line-height:2.1rem;font-size:0.75rem}div.switch.small input:first-of-type:checked ~ span:last-child{left:100%;margin-left:-1.6875rem}div.switch.small span:last-child{width:1.75rem;height:1.75rem}div.switch.tiny{height:1.375rem}div.switch.tiny label{padding:0;line-height:1.9rem;font-size:0.6875rem}div.switch.tiny input:first-of-type:checked ~ span:last-child{left:100%;margin-left:-1.3125rem}div.switch.tiny span:last-child{width:1.375rem;height:1.375rem}div.switch.radius{-webkit-border-radius:4px;border-radius:4px}div.switch.radius span:last-child{-webkit-border-radius:3px;border-radius:3px}div.switch.round{-webkit-border-radius:1000px;border-radius:1000px}div.switch.round span:last-child{-webkit-border-radius:999px;border-radius:999px}div.switch.round label{padding:0 0.5625rem}@-webkit-keyframes webkitSiblingBugfix{from{position:relative}to{position:relative}}.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px rgba(0,0,0,0.2);box-shadow:0 0 0 1px rgba(0,0,0,0.2);-webkit-transition:all 200ms ease-out;-moz-transition:all 200ms ease-out;transition:all 200ms ease-out}.th:hover,.th:focus{-webkit-box-shadow:0 0 6px 1px rgba(0,140,186,0.5);box-shadow:0 0 6px 1px rgba(0,140,186,0.5)}.th.radius{-webkit-border-radius:3px;border-radius:3px}a.th{display:inline-block;max-width:100%}.pricing-table{border:solid 1px #ddd;margin-left:0;margin-bottom:1.25rem}.pricing-table *{list-style:none;line-height:1}.pricing-table .title{background-color:#333;padding:0.9375rem 1.25rem;text-align:center;color:#eee;font-weight:normal;font-size:1rem;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif}.pricing-table .price{background-color:#f6f6f6;padding:0.9375rem 1.25rem;text-align:center;color:#333;font-weight:normal;font-size:2rem;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif}.pricing-table .description{background-color:#fff;padding:0.9375rem;text-align:center;color:#777;font-size:0.75rem;font-weight:normal;line-height:1.4;border-bottom:dotted 1px #ddd}.pricing-table .bullet-item{background-color:#fff;padding:0.9375rem;text-align:center;color:#333;font-size:0.875rem;font-weight:normal;border-bottom:dotted 1px #ddd}.pricing-table .cta-button{background-color:#fff;text-align:center;padding:1.25rem 1.25rem 0}@-webkit-keyframes rotate{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(360deg)}}@-moz-keyframes rotate{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(360deg)}}@-o-keyframes rotate{from{-o-transform:rotate(0deg)}to{-o-transform:rotate(360deg)}}@keyframes rotate{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.slideshow-wrapper{position:relative}.slideshow-wrapper ul{list-style-type:none;margin:0}.slideshow-wrapper ul li,.slideshow-wrapper ul li .orbit-caption{display:none}.slideshow-wrapper ul li:first-child{display:block}.slideshow-wrapper .orbit-container{background-color:transparent}.slideshow-wrapper .orbit-container li{display:block}.slideshow-wrapper .orbit-container li .orbit-caption{display:block}.preloader{display:block;width:40px;height:40px;position:absolute;top:50%;left:50%;margin-top:-20px;margin-left:-20px;border:solid 3px;border-color:#555 #fff;-webkit-border-radius:1000px;border-radius:1000px;-webkit-animation-name:rotate;-webkit-animation-duration:1.5s;-webkit-animation-iteration-count:infinite;-webkit-animation-timing-function:linear;-moz-animation-name:rotate;-moz-animation-duration:1.5s;-moz-animation-iteration-count:infinite;-moz-animation-timing-function:linear;-o-animation-name:rotate;-o-animation-duration:1.5s;-o-animation-iteration-count:infinite;-o-animation-timing-function:linear;animation-name:rotate;animation-duration:1.5s;animation-iteration-count:infinite;animation-timing-function:linear}.orbit-container{overflow:hidden;width:100%;position:relative;background:none}.orbit-container .orbit-slides-container{list-style:none;margin:0;padding:0;position:relative}.orbit-container .orbit-slides-container img{display:block;max-width:100%}.orbit-container .orbit-slides-container>*{position:absolute;top:0;width:100%;margin-left:100%}.orbit-container .orbit-slides-container>*:first-child{margin-left:0%}.orbit-container .orbit-slides-container>* .orbit-caption{position:absolute;bottom:0;background-color:rgba(51,51,51,0.8);color:#fff;width:100%;padding:10px 14px;font-size:0.875rem}.orbit-container .orbit-slide-number{position:absolute;top:10px;left:10px;font-size:12px;color:#fff;background:rgba(0,0,0,0);z-index:10}.orbit-container .orbit-slide-number span{font-weight:700;padding:0.3125rem}.orbit-container .orbit-timer{position:absolute;top:12px;right:10px;height:6px;width:100px;z-index:10}.orbit-container .orbit-timer .orbit-progress{height:3px;background-color:rgba(255,255,255,0.3);display:block;width:0%;position:relative;right:20px;top:5px}.orbit-container .orbit-timer>span{display:none;position:absolute;top:0px;right:0;width:11px;height:14px;border:solid 4px #fff;border-top:none;border-bottom:none}.orbit-container .orbit-timer.paused>span{right:-4px;top:0px;width:11px;height:14px;border:inset 8px;border-right-style:solid;border-color:transparent transparent transparent #fff}.orbit-container .orbit-timer.paused>span.dark{border-color:transparent transparent transparent #333}.orbit-container:hover .orbit-timer>span{display:block}.orbit-container .orbit-prev,.orbit-container .orbit-next{position:absolute;top:45%;margin-top:-25px;width:36px;height:60px;line-height:50px;color:white;text-indent:-9999px !important;z-index:10}.orbit-container .orbit-prev:hover,.orbit-container .orbit-next:hover{background-color:rgba(0,0,0,0.3)}.orbit-container .orbit-prev>span,.orbit-container .orbit-next>span{position:absolute;top:50%;margin-top:-10px;display:block;width:0;height:0;border:inset 10px}.orbit-container .orbit-prev{left:0}.orbit-container .orbit-prev>span{border-right-style:solid;border-color:transparent;border-right-color:#fff}.orbit-container .orbit-prev:hover>span{border-right-color:#fff}.orbit-container .orbit-next{right:0}.orbit-container .orbit-next>span{border-color:transparent;border-left-style:solid;border-left-color:#fff;left:50%;margin-left:-4px}.orbit-container .orbit-next:hover>span{border-left-color:#fff}.orbit-bullets-container{text-align:center}.orbit-bullets{margin:0 auto 30px auto;overflow:hidden;position:relative;top:10px;float:none;text-align:center;display:inline-block}.orbit-bullets li{display:block;width:0.5625rem;height:0.5625rem;background:#ccc;float:left;margin-right:6px;-webkit-border-radius:1000px;border-radius:1000px}.orbit-bullets li.active{background:#999}.orbit-bullets li:last-child{margin-right:0}.touch .orbit-container .orbit-prev,.touch .orbit-container .orbit-next{display:none}.touch .orbit-bullets{display:none}@media only screen and (min-width: 40.063em){.touch .orbit-container .orbit-prev,.touch .orbit-container .orbit-next{display:inherit}.touch .orbit-bullets{display:block}}@media only screen and (max-width: 40em){.orbit-stack-on-small .orbit-slides-container{height:auto !important}.orbit-stack-on-small .orbit-slides-container>*{position:relative;margin-left:0% !important}.orbit-stack-on-small .orbit-timer,.orbit-stack-on-small .orbit-next,.orbit-stack-on-small .orbit-prev,.orbit-stack-on-small .orbit-bullets{display:none}}[data-magellan-expedition]{background:#fff;z-index:50;min-width:100%;padding:10px}[data-magellan-expedition] .sub-nav{margin-bottom:0}[data-magellan-expedition] .sub-nav dd{margin-bottom:0}[data-magellan-expedition] .sub-nav .active{line-height:1.8em}.tabs{*zoom:1;margin-bottom:0 !important}.tabs:before,.tabs:after{content:" ";display:table}.tabs:after{clear:both}.tabs dd{position:relative;margin-bottom:0 !important;top:1px;float:left}.tabs dd>a{display:block;background:#efefef;color:#222;padding-top:1rem;padding-right:2rem;padding-bottom:1.0625rem;padding-left:2rem;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-size:1rem}.tabs dd>a:hover{background:#e2e2e2}.tabs dd.active a{background:#fff}.tabs.radius dd:first-child a{-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.tabs.radius dd:last-child a{-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.tabs.vertical dd{position:inherit;float:none;display:block;top:auto}.tabs-content{*zoom:1;margin-bottom:1.5rem}.tabs-content:before,.tabs-content:after{content:" ";display:table}.tabs-content:after{clear:both}.tabs-content>.content{display:none;float:left;padding:0.9375rem 0}.tabs-content>.content.active{display:block}.tabs-content>.content.contained{padding:0.9375rem}.tabs-content.vertical{display:block}.tabs-content.vertical>.content{padding:0 0.9375rem}@media only screen and (min-width: 40.063em){.tabs.vertical{width:20%;float:left;margin-bottom:1.25rem}.tabs-content.vertical{width:80%;float:left;margin-left:-1px}}ul.pagination{display:block;height:1.5rem;margin-left:-0.3125rem}ul.pagination li{height:1.5rem;color:#222;font-size:0.875rem;margin-left:0.3125rem}ul.pagination li a{display:block;padding:0.0625rem 0.625rem 0.0625rem;color:#999;-webkit-border-radius:3px;border-radius:3px}ul.pagination li:hover a,ul.pagination li a:focus{background:#e6e6e6}ul.pagination li.unavailable a{cursor:default;color:#999}ul.pagination li.unavailable:hover a,ul.pagination li.unavailable a:focus{background:transparent}ul.pagination li.current a{background:#008cba;color:#fff;font-weight:bold;cursor:default}ul.pagination li.current a:hover,ul.pagination li.current a:focus{background:#008cba}ul.pagination li{float:left;display:block}.pagination-centered{text-align:center}.pagination-centered ul.pagination li{float:none;display:inline-block}.side-nav{display:block;margin:0;padding:0.875rem 0;list-style-type:none;list-style-position:inside;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif}.side-nav li{margin:0 0 0.4375rem 0;font-size:0.875rem}.side-nav li a{display:block;color:#008cba}.side-nav li.active>a:first-child{color:#4d4d4d;font-weight:normal;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif}.side-nav li.divider{border-top:1px solid;height:0;padding:0;list-style:none;border-top-color:#e6e6e6}.accordion{*zoom:1;margin-bottom:0}.accordion:before,.accordion:after{content:" ";display:table}.accordion:after{clear:both}.accordion dd{display:block;margin-bottom:0 !important}.accordion dd.active a{background:#e7e7e7}.accordion dd>a{background:#efefef;color:#222;padding:1rem;display:block;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-size:1rem}.accordion dd>a:hover{background:#e2e2e2}.accordion .content{display:none;padding:0.9375rem}.accordion .content.active{display:block;background:#fff}p.lead{font-size:1.21875rem;line-height:1.6}.subheader{line-height:1.4;color:#6f6f6f;font-weight:300;margin-top:0.2rem;margin-bottom:0.5rem}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#008cba;text-decoration:none;line-height:inherit}a:hover,a:focus{color:#0079a1}a img{border:none}p{font-family:inherit;font-weight:normal;font-size:1rem;line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p aside{font-size:0.875rem;line-height:1.35;font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-weight:300;font-style:normal;color:#222;text-rendering:optimizeLegibility;margin-top:0.2rem;margin-bottom:0.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-size:60%;color:#6f6f6f;line-height:0}h1{font-size:2.125rem}h2{font-size:1.6875rem}h3{font-size:1.375rem}h4{font-size:1.125rem}h5{font-size:1.125rem}h6{font-size:1rem}hr{border:solid #ddd;border-width:1px 0 0;clear:both;margin:1.25rem 0 1.1875rem;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:Consolas,"Liberation Mono",Courier,monospace;font-weight:bold;color:#bb260d}ul,ol,dl{font-size:1rem;line-height:1.6;margin-bottom:1.25rem;list-style-position:outside;font-family:inherit}ul{margin-left:1.1rem}ul.no-bullet{margin-left:0}ul.no-bullet li ul,ul.no-bullet li ol{margin-left:1.25rem;margin-bottom:0;list-style:none}ul li ul,ul li ol{margin-left:1.25rem;margin-bottom:0;font-size:1rem}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square;margin-left:1.1rem}ul.circle{list-style-type:circle;margin-left:1.1rem}ul.disc{list-style-type:disc;margin-left:1.1rem}ul.no-bullet{list-style:none}ol{margin-left:1.4rem}ol li ul,ol li ol{margin-left:1.25rem;margin-bottom:0}dl dt{margin-bottom:0.3rem;font-weight:bold}dl dd{margin-bottom:0.75rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;border-bottom:1px dotted #ddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25rem;padding:0.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:0.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #ddd;padding:0.625rem 0.75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:bold;font-size:0.9375rem}.vevent .summary{font-weight:bold}.vevent abbr{cursor:default;text-decoration:none;font-weight:bold;border:none;padding:0 0.0625rem}@media only screen and (min-width: 40.063em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:2.75rem}h2{font-size:2.3125rem}h3{font-size:1.6875rem}h4{font-size:1.4375rem}}.print-only{display:none !important}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}.split.button{position:relative;padding-right:5.0625rem}.split.button span{display:block;height:100%;position:absolute;right:0;top:0;border-left:solid 1px}.split.button span:before{position:absolute;content:"";width:0;height:0;display:block;border-style:inset;top:50%;left:50%}.split.button span:active{background-color:rgba(0,0,0,0.1)}.split.button span{border-left-color:rgba(255,255,255,0.5)}.split.button span{width:3.09375rem}.split.button span:before{border-top-style:solid;border-width:0.375rem;top:48%;margin-left:-0.375rem}.split.button span:before{border-color:#fff transparent transparent transparent}.split.button.secondary span{border-left-color:rgba(255,255,255,0.5)}.split.button.secondary span:before{border-color:#fff transparent transparent transparent}.split.button.alert span{border-left-color:rgba(255,255,255,0.5)}.split.button.success span{border-left-color:rgba(255,255,255,0.5)}.split.button.tiny{padding-right:3.75rem}.split.button.tiny span{width:2.25rem}.split.button.tiny span:before{border-top-style:solid;border-width:0.375rem;top:48%;margin-left:-0.375rem}.split.button.small{padding-right:4.375rem}.split.button.small span{width:2.625rem}.split.button.small span:before{border-top-style:solid;border-width:0.4375rem;top:48%;margin-left:-0.375rem}.split.button.large{padding-right:5.5rem}.split.button.large span{width:3.4375rem}.split.button.large span:before{border-top-style:solid;border-width:0.3125rem;top:48%;margin-left:-0.375rem}.split.button.expand{padding-left:2rem}.split.button.secondary span:before{border-color:#333 transparent transparent transparent}.split.button.radius span{-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.split.button.round span{-moz-border-radius-topright:1000px;-moz-border-radius-bottomright:1000px;-webkit-border-top-right-radius:1000px;-webkit-border-bottom-right-radius:1000px;border-top-right-radius:1000px;border-bottom-right-radius:1000px}.reveal-modal-bg{position:fixed;height:100%;width:100%;background:#000;background:rgba(0,0,0,0.45);z-index:98;display:none;top:0;left:0}.reveal-modal{visibility:hidden;display:none;position:absolute;left:50%;z-index:99;height:auto;margin-left:-40%;width:80%;background-color:#fff;padding:1.25rem;border:solid 1px #666;-webkit-box-shadow:0 0 10px rgba(0,0,0,0.4);box-shadow:0 0 10px rgba(0,0,0,0.4);top:50px}.reveal-modal .column,.reveal-modal .columns{min-width:0}.reveal-modal>:first-child{margin-top:0}.reveal-modal>:last-child{margin-bottom:0}.reveal-modal .close-reveal-modal{font-size:1.375rem;line-height:1;position:absolute;top:0.5rem;right:0.6875rem;color:#aaa;font-weight:bold;cursor:pointer}@media only screen and (min-width: 40.063em){.reveal-modal{padding:1.875rem;top:6.25rem}.reveal-modal.tiny{margin-left:-15%;width:30%}.reveal-modal.small{margin-left:-20%;width:40%}.reveal-modal.medium{margin-left:-30%;width:60%}.reveal-modal.large{margin-left:-35%;width:70%}.reveal-modal.xlarge{margin-left:-47.5%;width:95%}}@media print{.reveal-modal{background:#fff !important}}.has-tip{border-bottom:dotted 1px #ccc;cursor:help;font-weight:bold;color:#333}.has-tip:hover,.has-tip:focus{border-bottom:dotted 1px #003f54;color:#008cba}.has-tip.tip-left,.has-tip.tip-right{float:none !important}.tooltip{display:none;position:absolute;z-index:999;font-weight:normal;font-size:0.875rem;line-height:1.3;padding:0.75rem;max-width:85%;left:50%;width:100%;color:#fff;background:#333;-webkit-border-radius:3px;border-radius:3px}.tooltip>.nub{display:block;left:5px;position:absolute;width:0;height:0;border:solid 5px;border-color:transparent transparent #333 transparent;top:-10px}.tooltip.opened{color:#008cba !important;border-bottom:dotted 1px #003f54 !important}.tap-to-close{display:block;font-size:0.625rem;color:#777;font-weight:normal}@media only screen and (min-width: 40.063em){.tooltip>.nub{border-color:transparent transparent #333 transparent;top:-10px}.tooltip.tip-top>.nub{border-color:#333 transparent transparent transparent;top:auto;bottom:-10px}.tooltip.tip-left,.tooltip.tip-right{float:none !important}.tooltip.tip-left>.nub{border-color:transparent transparent transparent #333;right:-10px;left:auto;top:50%;margin-top:-5px}.tooltip.tip-right>.nub{border-color:transparent #333 transparent transparent;right:auto;left:-10px;top:50%;margin-top:-5px}}[data-clearing]{*zoom:1;margin-bottom:0;margin-left:0;list-style:none}[data-clearing]:before,[data-clearing]:after{content:" ";display:table}[data-clearing]:after{clear:both}[data-clearing] li{float:left;margin-right:10px}.clearing-blackout{background:#333;position:fixed;width:100%;height:100%;top:0;left:0;z-index:998}.clearing-blackout .clearing-close{display:block}.clearing-container{position:relative;z-index:998;height:100%;overflow:hidden;margin:0}.visible-img{height:95%;position:relative}.visible-img img{position:absolute;left:50%;top:50%;margin-left:-50%;max-height:100%;max-width:100%}.clearing-caption{color:#ccc;font-size:0.875em;line-height:1.3;margin-bottom:0;text-align:center;bottom:0;background:#333;width:100%;padding:10px 30px 20px;position:absolute;left:0}.clearing-close{z-index:999;padding-left:20px;padding-top:10px;font-size:30px;line-height:1;color:#ccc;display:none}.clearing-close:hover,.clearing-close:focus{color:#ccc}.clearing-assembled .clearing-container{height:100%}.clearing-assembled .clearing-container .carousel>ul{display:none}.clearing-feature li{display:none}.clearing-feature li.clearing-featured-img{display:block}@media only screen and (min-width: 40.063em){.clearing-main-prev,.clearing-main-next{position:absolute;height:100%;width:40px;top:0}.clearing-main-prev>span,.clearing-main-next>span{position:absolute;top:50%;display:block;width:0;height:0;border:solid 12px}.clearing-main-prev>span:hover,.clearing-main-next>span:hover{opacity:0.8}.clearing-main-prev{left:0}.clearing-main-prev>span{left:5px;border-color:transparent;border-right-color:#ccc}.clearing-main-next{right:0}.clearing-main-next>span{border-color:transparent;border-left-color:#ccc}.clearing-main-prev.disabled,.clearing-main-next.disabled{opacity:0.3}.clearing-assembled .clearing-container .carousel{background:rgba(51,51,51,0.8);height:120px;margin-top:10px;text-align:center}.clearing-assembled .clearing-container .carousel>ul{display:inline-block;z-index:999;height:100%;position:relative;float:none}.clearing-assembled .clearing-container .carousel>ul li{display:block;width:120px;min-height:inherit;float:left;overflow:hidden;margin-right:0;padding:0;position:relative;cursor:pointer;opacity:0.4}.clearing-assembled .clearing-container .carousel>ul li.fix-height img{height:100%;max-width:none}.clearing-assembled .clearing-container .carousel>ul li a.th{border:none;-webkit-box-shadow:none;box-shadow:none;display:block}.clearing-assembled .clearing-container .carousel>ul li img{cursor:pointer !important;width:100% !important}.clearing-assembled .clearing-container .carousel>ul li.visible{opacity:1}.clearing-assembled .clearing-container .carousel>ul li:hover{opacity:0.8}.clearing-assembled .clearing-container .visible-img{background:#333;overflow:hidden;height:85%}.clearing-close{position:absolute;top:10px;right:20px;padding-left:0;padding-top:0}}.progress{background-color:#f6f6f6;height:1.5625rem;border:1px solid #ccc;padding:0.125rem;margin-bottom:0.625rem}.progress .meter{background:#008cba;height:100%;display:block}.progress.secondary .meter{background:#e7e7e7;height:100%;display:block}.progress.success .meter{background:#43ac6a;height:100%;display:block}.progress.alert .meter{background:#f04124;height:100%;display:block}.progress.radius{-webkit-border-radius:3px;border-radius:3px}.progress.radius .meter{-webkit-border-radius:2px;border-radius:2px}.progress.round{-webkit-border-radius:1000px;border-radius:1000px}.progress.round .meter{-webkit-border-radius:999px;border-radius:999px}.sub-nav{display:block;width:auto;overflow:hidden;margin:-0.25rem 0 1.125rem;padding-top:0.25rem;margin-right:0;margin-left:-0.75rem}.sub-nav dt{text-transform:uppercase}.sub-nav dt,.sub-nav dd,.sub-nav li{float:left;display:inline;margin-left:1rem;margin-bottom:0.625rem;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-weight:normal;font-size:0.875rem;color:#999}.sub-nav dt a,.sub-nav dd a,.sub-nav li a{text-decoration:none;color:#999}.sub-nav dt a:hover,.sub-nav dd a:hover,.sub-nav li a:hover{color:#0079a1}.sub-nav dt.active a,.sub-nav dd.active a,.sub-nav li.active a{-webkit-border-radius:3px;border-radius:3px;font-weight:normal;background:#008cba;padding:0.1875rem 1rem;cursor:default;color:#fff}.sub-nav dt.active a:hover,.sub-nav dd.active a:hover,.sub-nav li.active a:hover{background:#0079a1}.joyride-list{display:none}.joyride-tip-guide{display:none;position:absolute;background:#333;color:#fff;z-index:101;top:0;left:2.5%;font-family:inherit;font-weight:normal;width:95%}.lt-ie9 .joyride-tip-guide{max-width:800px;left:50%;margin-left:-400px}.joyride-content-wrapper{width:100%;padding:1.125rem 1.25rem 1.5rem}.joyride-content-wrapper .button{margin-bottom:0 !important}.joyride-tip-guide .joyride-nub{display:block;position:absolute;left:22px;width:0;height:0;border:10px solid #333}.joyride-tip-guide .joyride-nub.top{border-top-style:solid;border-color:#333;border-top-color:transparent !important;border-left-color:transparent !important;border-right-color:transparent !important;top:-20px}.joyride-tip-guide .joyride-nub.bottom{border-bottom-style:solid;border-color:#333 !important;border-bottom-color:transparent !important;border-left-color:transparent !important;border-right-color:transparent !important;bottom:-20px}.joyride-tip-guide .joyride-nub.right{right:-20px}.joyride-tip-guide .joyride-nub.left{left:-20px}.joyride-tip-guide h1,.joyride-tip-guide h2,.joyride-tip-guide h3,.joyride-tip-guide h4,.joyride-tip-guide h5,.joyride-tip-guide h6{line-height:1.25;margin:0;font-weight:bold;color:#fff}.joyride-tip-guide p{margin:0 0 1.125rem 0;font-size:0.875rem;line-height:1.3}.joyride-timer-indicator-wrap{width:50px;height:3px;border:solid 1px #555;position:absolute;right:1.0625rem;bottom:1rem}.joyride-timer-indicator{display:block;width:0;height:inherit;background:#666}.joyride-close-tip{position:absolute;right:12px;top:10px;color:#777 !important;text-decoration:none;font-size:24px;font-weight:normal;line-height:0.5 !important}.joyride-close-tip:hover,.joyride-close-tip:focus{color:#eee !important}.joyride-modal-bg{position:fixed;height:100%;width:100%;background:transparent;background:rgba(0,0,0,0.5);z-index:100;display:none;top:0;left:0;cursor:pointer}.joyride-expose-wrapper{background-color:#ffffff;position:absolute;border-radius:3px;z-index:102;-moz-box-shadow:0 0 30px #fff;-webkit-box-shadow:0 0 15px #fff;box-shadow:0 0 15px #fff}.joyride-expose-cover{background:transparent;border-radius:3px;position:absolute;z-index:9999;top:0;left:0}@media only screen and (min-width: 40.063em){.joyride-tip-guide{width:300px;left:inherit}.joyride-tip-guide .joyride-nub.bottom{border-color:#333 !important;border-bottom-color:transparent !important;border-left-color:transparent !important;border-right-color:transparent !important;bottom:-20px}.joyride-tip-guide .joyride-nub.right{border-color:#333 !important;border-top-color:transparent !important;border-right-color:transparent !important;border-bottom-color:transparent !important;top:22px;left:auto;right:-20px}.joyride-tip-guide .joyride-nub.left{border-color:#333 !important;border-top-color:transparent !important;border-left-color:transparent !important;border-bottom-color:transparent !important;top:22px;left:-20px;right:auto}}.label{font-weight:normal;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;text-align:center;text-decoration:none;line-height:1;white-space:nowrap;display:inline-block;position:relative;margin-bottom:inherit;padding:0.25rem 0.5rem 0.375rem;font-size:0.6875rem;background-color:#008cba;color:#fff}.label.radius{-webkit-border-radius:3px;border-radius:3px}.label.round{-webkit-border-radius:1000px;border-radius:1000px}.label.alert{background-color:#f04124;color:#fff}.label.success{background-color:#43ac6a;color:#fff}.label.secondary{background-color:#e7e7e7;color:#333}p.lead{font-size:1.21875rem;line-height:1.6}.subheader{line-height:1.4;color:#6f6f6f;font-weight:300;margin-top:0.2rem;margin-bottom:0.5rem}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.063em)/";width:40.063em}.off-canvas-wrap,.inner-wrap,nav.tab-bar,.left-off-canvas-menu,.left-off-canvas-menu *,.right-off-canvas-menu,.move-right a.exit-off-canvas,.move-left a.exit-off-canvas{-webkit-backface-visibility:hidden}.off-canvas-wrap,.inner-wrap{position:relative;width:100%}.left-off-canvas-menu,.right-off-canvas-menu{width:250px;top:0;bottom:0;height:100%;position:absolute;overflow-y:auto;background:#333;z-index:1001;box-sizing:content-box}section.left-small,section.right-small{width:2.8125rem;height:2.8125rem;position:absolute;top:0}.off-canvas-wrap{overflow:hidden}.inner-wrap{*zoom:1;-webkit-transition:-webkit-transform 500ms ease;-moz-transition:-moz-transform 500ms ease;-ms-transition:-ms-transform 500ms ease;-o-transition:-o-transform 500ms ease;transition:transform 500ms ease}.inner-wrap:before,.inner-wrap:after{content:" ";display:table}.inner-wrap:after{clear:both}nav.tab-bar{background:#333;color:#fff;height:2.8125rem;line-height:2.8125rem;position:relative}nav.tab-bar h1,nav.tab-bar h2,nav.tab-bar h3,nav.tab-bar h4,nav.tab-bar h5,nav.tab-bar h6{color:#fff;font-weight:bold;line-height:2.8125rem;margin:0}nav.tab-bar h1,nav.tab-bar h2,nav.tab-bar h3,nav.tab-bar h4{font-size:1.125rem}section.left-small{border-right:solid 1px #1a1a1a;box-shadow:1px 0 0 #4d4d4d;left:0}section.right-small{border-left:solid 1px #4d4d4d;box-shadow:-1px 0 0 #1a1a1a;right:0}section.tab-bar-section{padding:0 0.625rem;position:absolute;text-align:center;height:2.8125rem;top:0}@media only screen and (min-width: 40.063em){section.tab-bar-section{text-align:left}}section.tab-bar-section.left{left:0;right:2.8125rem}section.tab-bar-section.right{left:2.8125rem;right:0}section.tab-bar-section.middle{left:2.8125rem;right:2.8125rem}a.menu-icon{text-indent:2.1875rem;width:2.8125rem;height:2.8125rem;display:block;line-height:2.0625rem;padding:0;color:#fff;position:relative}a.menu-icon span{position:absolute;display:block;width:1rem;height:0;left:0.8125rem;top:0.3125rem;-webkit-box-shadow:0 10px 0 1px #fff,0 16px 0 1px #fff,0 22px 0 1px #fff;box-shadow:0 10px 0 1px #fff,0 16px 0 1px #fff,0 22px 0 1px #fff}a.menu-icon:hover span{-webkit-box-shadow:0 10px 0 1px #b3b3b3,0 16px 0 1px #b3b3b3,0 22px 0 1px #b3b3b3;box-shadow:0 10px 0 1px #b3b3b3,0 16px 0 1px #b3b3b3,0 22px 0 1px #b3b3b3}.left-off-canvas-menu{-webkit-transform:translate3d(-100%, 0, 0);-moz-transform:translate3d(-100%, 0, 0);-ms-transform:translate3d(-100%, 0, 0);-o-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0)}.right-off-canvas-menu{-webkit-transform:translate3d(100%, 0, 0);-moz-transform:translate3d(100%, 0, 0);-ms-transform:translate3d(100%, 0, 0);-o-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);right:0}ul.off-canvas-list{list-style-type:none;padding:0;margin:0}ul.off-canvas-list li label{padding:0.3rem 0.9375rem;color:#999;text-transform:uppercase;font-weight:bold;background:#444;border-top:1px solid #5e5e5e;border-bottom:none;margin:0}ul.off-canvas-list li a{display:block;padding:0.66667rem;color:rgba(255,255,255,0.7);border-bottom:1px solid #262626}.move-right>.inner-wrap{-webkit-transform:translate3d(250px, 0, 0);-moz-transform:translate3d(250px, 0, 0);-ms-transform:translate3d(250px, 0, 0);-o-transform:translate3d(250px, 0, 0);transform:translate3d(250px, 0, 0)}.move-right a.exit-off-canvas{transition:background 300ms ease;cursor:pointer;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);display:block;position:absolute;background:rgba(255,255,255,0.2);top:0;bottom:0;left:0;right:0;z-index:1002}@media only screen and (min-width: 40.063em){.move-right a.exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.move-left>.inner-wrap{-webkit-transform:translate3d(-250px, 0, 0);-moz-transform:translate3d(-250px, 0, 0);-ms-transform:translate3d(-250px, 0, 0);-o-transform:translate3d(-250px, 0, 0);transform:translate3d(-250px, 0, 0)}.move-left a.exit-off-canvas{transition:background 300ms ease;cursor:pointer;box-shadow:-4px 0 4px rgba(0,0,0,0.5),4px 0 4px rgba(0,0,0,0.5);display:block;position:absolute;background:rgba(255,255,255,0.2);top:0;bottom:0;left:0;right:0;z-index:1002}@media only screen and (min-width: 40.063em){.move-left a.exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.lt-ie10 .left-off-canvas-menu{left:-250px}.lt-ie10 .right-off-canvas-menu{right:-250px}.lt-ie10 .move-left>.inner-wrap{right:250px}.lt-ie10 .move-right>.inner-wrap{left:250px}@media only screen and (max-width: 40em){.f-dropdown{max-width:100%;left:0}}.f-dropdown{position:absolute;top:-9999px;list-style:none;margin-left:0;width:100%;max-height:none;height:auto;background:#fff;border:solid 1px #ccc;font-size:16px;z-index:99;margin-top:2px;max-width:200px}.f-dropdown>*:first-child{margin-top:0}.f-dropdown>*:last-child{margin-bottom:0}.f-dropdown:before{content:"";display:block;width:0;height:0;border:inset 6px;border-color:transparent transparent #fff transparent;border-bottom-style:solid;position:absolute;top:-12px;left:10px;z-index:99}.f-dropdown:after{content:"";display:block;width:0;height:0;border:inset 7px;border-color:transparent transparent #ccc transparent;border-bottom-style:solid;position:absolute;top:-14px;left:9px;z-index:98}.f-dropdown.right:before{left:auto;right:10px}.f-dropdown.right:after{left:auto;right:9px}.f-dropdown li{font-size:0.875rem;cursor:pointer;line-height:1.125rem;margin:0}.f-dropdown li:hover,.f-dropdown li:focus{background:#eee}.f-dropdown li a{display:block;padding:0.5rem;color:#555}.f-dropdown.content{position:absolute;top:-9999px;list-style:none;margin-left:0;padding:1.25rem;width:100%;height:auto;max-height:none;background:#fff;border:solid 1px #ccc;font-size:16px;z-index:99;max-width:200px}.f-dropdown.content>*:first-child{margin-top:0}.f-dropdown.content>*:last-child{margin-bottom:0}.f-dropdown.tiny{max-width:200px}.f-dropdown.small{max-width:300px}.f-dropdown.medium{max-width:500px}.f-dropdown.large{max-width:800px}table{background:#fff;margin-bottom:1.25rem;border:solid 1px #ddd}table thead,table tfoot{background:#f5f5f5;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:0.5rem 0.625rem 0.625rem;font-size:0.875rem;color:#222;text-align:left}table tr th,table tr td{padding:0.5625rem 0.625rem;font-size:0.875rem;color:#222}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f9f9f9}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.125rem}form{margin:0 0 1rem}form .row .row{margin:0 -0.5rem}form .row .row .column,form .row .row .columns{padding:0 0.5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-moz-border-radius-bottomright:0;-moz-border-radius-topright:0;-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:0.5rem}label{font-size:0.875rem;color:#4d4d4d;cursor:pointer;display:block;font-weight:normal;margin-bottom:0.5rem}label.right{float:none;text-align:right}label.inline{margin:0 0 1rem 0;padding:0.625rem 0}label small{text-transform:capitalize;color:#666}select{-webkit-appearance:none !important;background:#fafafa url("data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iM3B4IiB2aWV3Qm94PSIwIDAgNiAzIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2IDMiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIHBvaW50cz0iNS45OTIsMCAyLjk5MiwzIC0wLjAwOCwwICIvPjwvc3ZnPg==") no-repeat;background-position-x:97%;background-position-y:center;border:1px solid #ccc;padding:0.5rem;font-size:0.875rem;-webkit-border-radius:0;border-radius:0}select.radius{-webkit-border-radius:3px;border-radius:3px}select:hover{background:#f2f2f2 url("data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iM3B4IiB2aWV3Qm94PSIwIDAgNiAzIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2IDMiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIHBvaW50cz0iNS45OTIsMCAyLjk5MiwzIC0wLjAwOCwwICIvPjwvc3ZnPg==") no-repeat;background-position-x:97%;background-position-y:center;border-color:#999}@-moz-document url-prefix(){select{background:#fafafa}select:hover{background:#f2f2f2}}.prefix,.postfix{display:block;position:relative;z-index:2;text-align:center;width:100%;padding-top:0;padding-bottom:0;border-style:solid;border-width:1px;overflow:hidden;font-size:0.875rem;height:2.3125rem;line-height:2.3125rem}.postfix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;line-height:2.125rem;border:none}.prefix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;line-height:2.125rem;border:none}.prefix.button.radius{-webkit-border-radius:0;border-radius:0;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.postfix.button.radius{-webkit-border-radius:0;border-radius:0;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.prefix.button.round{-webkit-border-radius:0;border-radius:0;-moz-border-radius-bottomleft:1000px;-moz-border-radius-topleft:1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.postfix.button.round{-webkit-border-radius:0;border-radius:0;-moz-border-radius-topright:1000px;-moz-border-radius-bottomright:1000px;-webkit-border-top-right-radius:1000px;-webkit-border-bottom-right-radius:1000px;border-top-right-radius:1000px;border-bottom-right-radius:1000px}span.prefix,label.prefix{background:#f2f2f2;border-color:#d9d9d9;border-right:none;color:#333}span.prefix.radius,label.prefix.radius{-webkit-border-radius:0;border-radius:0;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}span.postfix,label.postfix{background:#f2f2f2;border-color:#ccc;border-left:none;color:#333}span.postfix.radius,label.postfix.radius{-webkit-border-radius:0;border-radius:0;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.input-group.radius>*:first-child,.input-group.radius>*:first-child *{-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group.radius>*:last-child,.input-group.radius>*:last-child *{-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px;-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}.input-group.round>*:first-child,.input-group.round>*:first-child *{-moz-border-radius-bottomleft:1000px;-moz-border-radius-topleft:1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.input-group.round>*:last-child,.input-group.round>*:last-child *{-moz-border-radius-topright:1000px;-moz-border-radius-bottomright:1000px;-webkit-border-top-right-radius:1000px;-webkit-border-bottom-right-radius:1000px;border-top-right-radius:1000px;border-bottom-right-radius:1000px}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],textarea{-webkit-appearance:none;-webkit-border-radius:0;border-radius:0;background-color:#fff;font-family:inherit;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:rgba(0,0,0,0.75);display:block;font-size:0.875rem;margin:0 0 1rem 0;padding:0.5rem;height:2.3125rem;width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:-webkit-box-shadow 0.45s,border-color 0.45s ease-in-out;-moz-transition:-moz-box-shadow 0.45s,border-color 0.45s ease-in-out;transition:box-shadow 0.45s,border-color 0.45s ease-in-out}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,textarea:focus{-webkit-box-shadow:0 0 5px #999;-moz-box-shadow:0 0 5px #999;box-shadow:0 0 5px #999;border-color:#999}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:none}input[type="text"][disabled],input[type="password"][disabled],input[type="date"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="month"][disabled],input[type="week"][disabled],input[type="email"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="time"][disabled],input[type="url"][disabled],textarea[disabled]{background-color:#ddd}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:0.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}fieldset{border:solid 1px #ddd;padding:1.25rem;margin:1.125rem 0}fieldset legend{font-weight:bold;background:#fff;padding:0 0.1875rem;margin:0;margin-left:-0.1875rem}[data-abide] .error small.error,[data-abide] span.error,[data-abide] small.error{display:block;padding:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.75rem;font-weight:normal;font-style:italic;background:#f04124;color:#fff}[data-abide] span.error,[data-abide] small.error{display:none}span.error,small.error{display:block;padding:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.75rem;font-weight:normal;font-style:italic;background:#f04124;color:#fff}.error input,.error textarea,.error select{margin-bottom:0}.error label,.error label.error{color:#f04124}.error>small,.error small.error{display:block;padding:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.75rem;font-weight:normal;font-style:italic;background:#f04124;color:#fff}.error span.error-message{display:block}input.error,textarea.error{margin-bottom:0}label.error{color:#f04124}[class*="block-grid-"]{display:block;padding:0;margin:0 -0.625rem;*zoom:1}[class*="block-grid-"]:before,[class*="block-grid-"]:after{content:" ";display:table}[class*="block-grid-"]:after{clear:both}[class*="block-grid-"]>li{display:inline;height:auto;float:left;padding:0 0.625rem 1.25rem}@media only screen{.small-block-grid-1>li{width:100%;padding:0 0.625rem 1.25rem}.small-block-grid-1>li:nth-of-type(n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{width:50%;padding:0 0.625rem 1.25rem}.small-block-grid-2>li:nth-of-type(n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{width:33.33333%;padding:0 0.625rem 1.25rem}.small-block-grid-3>li:nth-of-type(n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{width:25%;padding:0 0.625rem 1.25rem}.small-block-grid-4>li:nth-of-type(n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{width:20%;padding:0 0.625rem 1.25rem}.small-block-grid-5>li:nth-of-type(n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{width:16.66667%;padding:0 0.625rem 1.25rem}.small-block-grid-6>li:nth-of-type(n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{width:14.28571%;padding:0 0.625rem 1.25rem}.small-block-grid-7>li:nth-of-type(n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{width:12.5%;padding:0 0.625rem 1.25rem}.small-block-grid-8>li:nth-of-type(n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{width:11.11111%;padding:0 0.625rem 1.25rem}.small-block-grid-9>li:nth-of-type(n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{width:10%;padding:0 0.625rem 1.25rem}.small-block-grid-10>li:nth-of-type(n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{width:9.09091%;padding:0 0.625rem 1.25rem}.small-block-grid-11>li:nth-of-type(n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{width:8.33333%;padding:0 0.625rem 1.25rem}.small-block-grid-12>li:nth-of-type(n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 40.063em){.medium-block-grid-1>li{width:100%;padding:0 0.625rem 1.25rem}.medium-block-grid-1>li:nth-of-type(n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{width:50%;padding:0 0.625rem 1.25rem}.medium-block-grid-2>li:nth-of-type(n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{width:33.33333%;padding:0 0.625rem 1.25rem}.medium-block-grid-3>li:nth-of-type(n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{width:25%;padding:0 0.625rem 1.25rem}.medium-block-grid-4>li:nth-of-type(n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{width:20%;padding:0 0.625rem 1.25rem}.medium-block-grid-5>li:nth-of-type(n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{width:16.66667%;padding:0 0.625rem 1.25rem}.medium-block-grid-6>li:nth-of-type(n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{width:14.28571%;padding:0 0.625rem 1.25rem}.medium-block-grid-7>li:nth-of-type(n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{width:12.5%;padding:0 0.625rem 1.25rem}.medium-block-grid-8>li:nth-of-type(n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{width:11.11111%;padding:0 0.625rem 1.25rem}.medium-block-grid-9>li:nth-of-type(n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{width:10%;padding:0 0.625rem 1.25rem}.medium-block-grid-10>li:nth-of-type(n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{width:9.09091%;padding:0 0.625rem 1.25rem}.medium-block-grid-11>li:nth-of-type(n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{width:8.33333%;padding:0 0.625rem 1.25rem}.medium-block-grid-12>li:nth-of-type(n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 64.063em){.large-block-grid-1>li{width:100%;padding:0 0.625rem 1.25rem}.large-block-grid-1>li:nth-of-type(n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{width:50%;padding:0 0.625rem 1.25rem}.large-block-grid-2>li:nth-of-type(n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{width:33.33333%;padding:0 0.625rem 1.25rem}.large-block-grid-3>li:nth-of-type(n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{width:25%;padding:0 0.625rem 1.25rem}.large-block-grid-4>li:nth-of-type(n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{width:20%;padding:0 0.625rem 1.25rem}.large-block-grid-5>li:nth-of-type(n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{width:16.66667%;padding:0 0.625rem 1.25rem}.large-block-grid-6>li:nth-of-type(n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{width:14.28571%;padding:0 0.625rem 1.25rem}.large-block-grid-7>li:nth-of-type(n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{width:12.5%;padding:0 0.625rem 1.25rem}.large-block-grid-8>li:nth-of-type(n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{width:11.11111%;padding:0 0.625rem 1.25rem}.large-block-grid-9>li:nth-of-type(n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{width:10%;padding:0 0.625rem 1.25rem}.large-block-grid-10>li:nth-of-type(n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{width:9.09091%;padding:0 0.625rem 1.25rem}.large-block-grid-11>li:nth-of-type(n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{width:8.33333%;padding:0 0.625rem 1.25rem}.large-block-grid-12>li:nth-of-type(n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}.flex-video{position:relative;padding-top:1.5625rem;padding-bottom:67.5%;height:0;margin-bottom:1rem;overflow:hidden}.flex-video.widescreen{padding-bottom:57.25%}.flex-video.vimeo{padding-top:0}.flex-video iframe,.flex-video object,.flex-video embed,.flex-video video{position:absolute;top:0;left:0;width:100%;height:100%}.keystroke,kbd{background-color:#ededed;border-color:#dbdbdb;color:#222;border-style:solid;border-width:1px;margin:0;font-family:"Consolas","Menlo","Courier",monospace;font-size:0.875rem;padding:0.125rem 0.25rem 0;-webkit-border-radius:3px;border-radius:3px}.show-for-small,.show-for-small-only,.show-for-medium-down,.show-for-large-down,.hide-for-medium,.hide-for-medium-up,.hide-for-medium-only,.hide-for-large,.hide-for-large-up,.hide-for-large-only,.hide-for-xlarge,.hide-for-xlarge-up,.hide-for-xlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge-only{display:inherit !important}.hide-for-small,.hide-for-small-only,.hide-for-medium-down,.show-for-medium,.show-for-medium-up,.show-for-medium-only,.hide-for-large-down,.show-for-large,.show-for-large-up,.show-for-large-only,.show-for-xlarge,.show-for-xlarge-up,.show-for-xlarge-only,.show-for-xxlarge-up,.show-for-xxlarge-only{display:none !important}table.show-for-small,table.show-for-small-only,table.show-for-medium-down,table.show-for-large-down,table.hide-for-medium,table.hide-for-medium-up,table.hide-for-medium-only,table.hide-for-large,table.hide-for-large-up,table.hide-for-large-only,table.hide-for-xlarge,table.hide-for-xlarge-up,table.hide-for-xlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge-only{display:table}thead.show-for-small,thead.show-for-small-only,thead.show-for-medium-down,thead.show-for-large-down,thead.hide-for-medium,thead.hide-for-medium-up,thead.hide-for-medium-only,thead.hide-for-large,thead.hide-for-large-up,thead.hide-for-large-only,thead.hide-for-xlarge,thead.hide-for-xlarge-up,thead.hide-for-xlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge-only{display:table-header-group !important}tbody.show-for-small,tbody.show-for-small-only,tbody.show-for-medium-down,tbody.show-for-large-down,tbody.hide-for-medium,tbody.hide-for-medium-up,tbody.hide-for-medium-only,tbody.hide-for-large,tbody.hide-for-large-up,tbody.hide-for-large-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge-only{display:table-row-group !important}tr.show-for-small,tr.show-for-small-only,tr.show-for-medium-down,tr.show-for-large-down,tr.hide-for-medium,tr.hide-for-medium-up,tr.hide-for-medium-only,tr.hide-for-large,tr.hide-for-large-up,tr.hide-for-large-only,tr.hide-for-xlarge,tr.hide-for-xlarge-up,tr.hide-for-xlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge-only{display:table-row !important}td.show-for-small,td.show-for-small-only,td.show-for-medium-down td.show-for-large-down,td.hide-for-medium,td.hide-for-medium-up,td.hide-for-large,td.hide-for-large-up,td.hide-for-xlarge td.hide-for-xlarge-up,td.hide-for-xxlarge-up,th.show-for-small,th.show-for-small-only,th.show-for-medium-down th.show-for-large-down,th.hide-for-medium,th.hide-for-medium-up,th.hide-for-large,th.hide-for-large-up,th.hide-for-xlarge th.hide-for-xlarge-up,th.hide-for-xxlarge-up{display:table-cell !important}@media only screen and (min-width: 40.063em){.hide-for-small,.hide-for-small-only,.show-for-medium,.show-for-medium-down,.show-for-medium-up,.show-for-medium-only,.hide-for-large,.hide-for-large-up,.hide-for-large-only,.hide-for-xlarge,.hide-for-xlarge-up,.hide-for-xlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge-only{display:inherit !important}.show-for-small,.show-for-small-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-up,.hide-for-medium-only,.hide-for-large-down,.show-for-large,.show-for-large-up,.show-for-large-only,.show-for-xlarge,.show-for-xlarge-up,.show-for-xlarge-only,.show-for-xxlarge-up,.show-for-xxlarge-only{display:none !important}table.hide-for-small,table.hide-for-small-only,table.show-for-medium,table.show-for-medium-down,table.show-for-medium-up,table.show-for-medium-only,table.hide-for-large,table.hide-for-large-up,table.hide-for-large-only,table.hide-for-xlarge,table.hide-for-xlarge-up,table.hide-for-xlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge-only{display:table}thead.hide-for-small,thead.hide-for-small-only,thead.show-for-medium,thead.show-for-medium-down,thead.show-for-medium-up,thead.show-for-medium-only,thead.hide-for-large,thead.hide-for-large-up,thead.hide-for-large-only,thead.hide-for-xlarge,thead.hide-for-xlarge-up,thead.hide-for-xlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge-only{display:table-header-group !important}tbody.hide-for-small,tbody.hide-for-small-only,tbody.show-for-medium,tbody.show-for-medium-down,tbody.show-for-medium-up,tbody.show-for-medium-only,tbody.hide-for-large,tbody.hide-for-large-up,tbody.hide-for-large-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge-only{display:table-row-group !important}tr.hide-for-small,tr.hide-for-small-only,tr.show-for-medium,tr.show-for-medium-down,tr.show-for-medium-up,tr.show-for-medium-only,tr.hide-for-large,tr.hide-for-large-up,tr.hide-for-large-only,tr.hide-for-xlarge,tr.hide-for-xlarge-up,tr.hide-for-xlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge-only{display:table-row !important}td.hide-for-small,td.hide-for-small-only,td.show-for-medium,td.show-for-medium-down,td.show-for-medium-up,td.show-for-medium-only,td.hide-for-large,td.hide-for-large-up,td.hide-for-large-only,td.hide-for-xlarge,td.hide-for-xlarge-up,td.hide-for-xlarge-only,td.hide-for-xxlarge-up,td.hide-for-xxlarge-only,th.hide-for-small,th.hide-for-small-only,th.show-for-medium,th.show-for-medium-down,th.show-for-medium-up,th.show-for-medium-only,th.hide-for-large,th.hide-for-large-up,th.hide-for-large-only,th.hide-for-xlarge,th.hide-for-xlarge-up,th.hide-for-xlarge-only,th.hide-for-xxlarge-up,th.hide-for-xxlarge-only{display:table-cell !important}}@media only screen and (min-width: 64.063em){.hide-for-small,.hide-for-small-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.show-for-medium-up,.show-for-large,.show-for-large-up,.show-for-large-only,.hide-for-xlarge,.hide-for-xlarge-up,.hide-for-xlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge-only{display:inherit !important}.show-for-small-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.hide-for-large,.hide-for-large-up,.hide-for-large-only,.show-for-xlarge,.show-for-xlarge-up,.show-for-xlarge-only,.show-for-xxlarge-up,.show-for-xxlarge-only{display:none !important}table.hide-for-small,table.hide-for-small-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.show-for-medium-up,table.show-for-large,table.show-for-large-up,table.show-for-large-only,table.hide-for-xlarge,table.hide-for-xlarge-up,table.hide-for-xlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge-only{display:table}thead.hide-for-small,thead.hide-for-small-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.show-for-large,thead.show-for-large-up,thead.show-for-large-only,thead.hide-for-xlarge,thead.hide-for-xlarge-up,thead.hide-for-xlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge-only{display:table-header-group !important}tbody.hide-for-small,tbody.hide-for-small-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.show-for-large,tbody.show-for-large-up,tbody.show-for-large-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge-only{display:table-row-group !important}tr.hide-for-small,tr.hide-for-small-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.show-for-large,tr.show-for-large-up,tr.show-for-large-only,tr.hide-for-xlarge,tr.hide-for-xlarge-up,tr.hide-for-xlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge-only{display:table-row !important}td.hide-for-small,td.hide-for-small-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.show-for-medium-up,td.show-for-large,td.show-for-large-up,td.show-for-large-only,td.hide-for-xlarge,td.hide-for-xlarge-up,td.hide-for-xlarge-only,td.hide-for-xxlarge-up,td.hide-for-xxlarge-only,th.hide-for-small,th.hide-for-small-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.show-for-medium-up,th.show-for-large,th.show-for-large-up,th.show-for-large-only,th.hide-for-xlarge,th.hide-for-xlarge-up,th.hide-for-xlarge-only,th.hide-for-xxlarge-up,th.hide-for-xxlarge-only{display:table-cell !important}}@media only screen and (min-width: 90.063em){.hide-for-small,.hide-for-small-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.show-for-medium-up,.show-for-large-up,.show-for-xlarge,.show-for-xlarge-up,.show-for-xlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge-only{display:inherit !important}.show-for-small-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-large,.show-for-large-only,.show-for-large-down,.hide-for-xlarge,.hide-for-xlarge-up,.hide-for-xlarge-only,.show-for-xxlarge-up,.show-for-xxlarge-only{display:none !important}table.hide-for-small,table.hide-for-small-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.show-for-medium-up,table.show-for-large-up,table.show-for-xlarge,table.show-for-xlarge-up,table.show-for-xlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge-only{display:table}thead.hide-for-small,thead.hide-for-small-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.show-for-large-up,thead.show-for-xlarge,thead.show-for-xlarge-up,thead.show-for-xlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge-only{display:table-header-group !important}tbody.hide-for-small,tbody.hide-for-small-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.show-for-large-up,tbody.show-for-xlarge,tbody.show-for-xlarge-up,tbody.show-for-xlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge-only{display:table-row-group !important}tr.hide-for-small,tr.hide-for-small-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.show-for-large-up,tr.show-for-xlarge,tr.show-for-xlarge-up,tr.show-for-xlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge-only{display:table-row !important}td.hide-for-small,td.hide-for-small-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.show-for-medium-up,td.show-for-large-up,td.show-for-xlarge,td.show-for-xlarge-up,td.show-for-xlarge-only,td.hide-for-xxlarge-up,td.hide-for-xxlarge-only,th.hide-for-small,th.hide-for-small-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.show-for-medium-up,th.show-for-large-up,th.show-for-xlarge,th.show-for-xlarge-up,th.show-for-xlarge-only,th.hide-for-xxlarge-up,th.hide-for-xxlarge-only{display:table-cell !important}}@media only screen and (min-width: 120.063em){.hide-for-small,.hide-for-small-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.show-for-medium-up,.show-for-large-up,.show-for-xlarge-up,.show-for-xxlarge-up,.show-for-xxlarge-only{display:inherit !important}.show-for-small-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-large,.show-for-large-only,.show-for-large-down,.hide-for-xlarge,.show-for-xlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge-only{display:none !important}table.hide-for-small,table.hide-for-small-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.show-for-medium-up,table.show-for-large-up,table.show-for-xlarge-up,table.show-for-xxlarge-up,table.show-for-xxlarge-only{display:table}thead.hide-for-small,thead.hide-for-small-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.show-for-large-up,thead.show-for-xlarge-up,thead.show-for-xxlarge-up,thead.show-for-xxlarge-only{display:table-header-group !important}tbody.hide-for-small,tbody.hide-for-small-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.show-for-large-up,tbody.show-for-xlarge-up,tbody.show-for-xxlarge-up,tbody.show-for-xxlarge-only{display:table-row-group !important}tr.hide-for-small,tr.hide-for-small-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.show-for-large-up,tr.show-for-xlarge-up,tr.show-for-xxlarge-up,tr.show-for-xxlarge-only{display:table-row !important}td.hide-for-small,td.hide-for-small-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.show-for-medium-up,td.show-for-large-up,td.show-for-xlarge-up,td.show-for-xxlarge-up,td.show-for-xxlarge-only,th.hide-for-small,th.hide-for-small-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.show-for-medium-up,th.show-for-large-up,th.show-for-xlarge-up,th.show-for-xxlarge-up,th.show-for-xxlarge-only{display:table-cell !important}}.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.hide-for-landscape,table.show-for-portrait{display:table}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group !important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group !important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row !important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell !important}@media only screen and (orientation: landscape){.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.show-for-landscape,table.hide-for-portrait{display:table}thead.show-for-landscape,thead.hide-for-portrait{display:table-header-group !important}tbody.show-for-landscape,tbody.hide-for-portrait{display:table-row-group !important}tr.show-for-landscape,tr.hide-for-portrait{display:table-row !important}td.show-for-landscape,td.hide-for-portrait,th.show-for-landscape,th.hide-for-portrait{display:table-cell !important}}@media only screen and (orientation: portrait){.show-for-portrait,.hide-for-landscape{display:inherit !important}.hide-for-portrait,.show-for-landscape{display:none !important}table.show-for-portrait,table.hide-for-landscape{display:table}thead.show-for-portrait,thead.hide-for-landscape{display:table-header-group !important}tbody.show-for-portrait,tbody.hide-for-landscape{display:table-row-group !important}tr.show-for-portrait,tr.hide-for-landscape{display:table-row !important}td.show-for-portrait,td.hide-for-landscape,th.show-for-portrait,th.hide-for-landscape{display:table-cell !important}}.show-for-touch{display:none !important}.hide-for-touch{display:inherit !important}.touch .show-for-touch{display:inherit !important}.touch .hide-for-touch{display:none !important}table.hide-for-touch{display:table}.touch table.show-for-touch{display:table}thead.hide-for-touch{display:table-header-group !important}.touch thead.show-for-touch{display:table-header-group !important}tbody.hide-for-touch{display:table-row-group !important}.touch tbody.show-for-touch{display:table-row-group !important}tr.hide-for-touch{display:table-row !important}.touch tr.show-for-touch{display:table-row !important}td.hide-for-touch{display:table-cell !important}.touch td.show-for-touch{display:table-cell !important}th.hide-for-touch{display:table-cell !important}.touch th.show-for-touch{display:table-cell !important}
2 | 


--------------------------------------------------------------------------------