//// Copyright (c) 2020, Andy Frank// Licensed under the MIT License//// History:// 30 July 2020 Andy Frank Creation//using concurrent*************************************************************************** Fanbars*************************************************************************constclass Fanbars{** Compile the template into a 'Fanbars' instance, where** 'template' can be an 'InStream', 'Str', or 'File'.staticnew compile(Obj template){ InStream? in := template as InStreamtry{// get our instreamif(template is Str) in = ((Str)template).inif(template is File) in = ((File)template).inif(in == null)throw ArgErr("Invalid 'template' argument")// parse template an return instance def := Parser(in).parsereturn Fanbars {it.defRef = AtomicRef(Unsafe(def))}}finally{ in?.close }}** Render template to a 'Str' instance. Str renderStr(Str:Obj map){ buf := StrBuf() render(buf.out, map)return buf.toStr}** Render template to given OutStream. Void render(OutStream out, Str:Obj map){ def := (defRef.val as Unsafe).val Renderer.render(def, map, out)}** Private ctor.privatenew make(|This| f){ f(this)}// TODO FIXIT: until we can get our AST to be const :(privateconst AtomicRef defRef}