anchor.diff:              e.RemoveAttribute("ws-attr")
               match fw.TryGetValue(name) with
               | true, TemplateHole.Attribute (_, attr) -> addAttr e attr
  -            | _ -> Console.Warn("Unfilled attr", name)
  +            | true, _ -> Console.Warn("Attribute hole filled with non-attribute data", name)
  +            | false, _ -> ()
   
           DomUtility.IterSelector el "[ws-on]" <| fun e ->
               e.GetAttribute("ws-on").Split([|' '|], StringSplitOptions.RemoveEmptyEntries)
  
positive.code:             | true, TemplateHole.VarIntUnchecked (_, v) -> Some (Doc'.TextView (v.View.Map string))
              | true, TemplateHole.VarFloat (_, v) -> Some (Doc'.TextView (v.View.Map (fun i -> i.Input)))
              | true, TemplateHole.VarFloatUnchecked (_, v) -> Some (Doc'.TextView (v.View.Map string))
              | _ -> None
  
          DomUtility.IterSelector el "[ws-hole]" <| fun p ->
              let name = p.GetAttribute("ws-hole")
  
negative.code:         DomUtility.IterSelector el "[ws-replace]" <| fun e ->
              let name = e.GetAttribute("ws-replace")
              match tryGetAsDoc name with
              | None -> ()
              | Some doc ->
                  let p = e.ParentElement
                  let after = JS.Document.CreateTextNode("") :> Dom.Node
  