code: func (t *File_Template) Render(params map[string]*Value) (string, error) {
  	sSet := stringset.New(len(params))
  	replacementSlice := make([]string, 0, len(t.Param)*2)
  	for k, param := range t.Param {
  		replacementSlice = append(replacementSlice, k)
  		if newVal, ok := params[k]; ok {
  			if err := param.Accepts(newVal); err != nil {
  				return "", fmt.Errorf("param %q: %s", k, err)
  			}
  			sSet.Add(k)
  			replacementSlice = append(replacementSlice, newVal.JSONRender())
  		} else if param.Default != nil {
  			replacementSlice = append(replacementSlice, param.Default.JSONRender())
  		} else {
  			return "", fmt.Errorf("param %q: missing", k)
  		}
  	}
  	if len(params) != sSet.Len() {
  		unknown := make([]string, 0, len(params))
  		for k := range params {
  			if !sSet.Has(k) {
  				unknown = append(unknown, k)
  			}
  		}
  		sort.Strings(unknown)
  		return "", fmt.Errorf("unknown parameters: %q", unknown)
  	}
  
  	r := strings.NewReplacer(replacementSlice...)
  
  	return r.Replace(t.Body), nil
  }
docs: // Render turns the Template into a JSON document, filled with the given
  // parameters. It does not validate that the output is valid JSON, but if you
  // called Normalize on this Template already, then it WILL be valid JSON.