YUI.add("squarespace-json-template", function (b) {
  function f(a) {
    return a.replace(/([\{\}\(\)\[\]\|\^\$\-\+\?])/g, "\\$1")
  }

  function a(a, b) {
    var c = r[a + b];
    void 0 === c && (c = "(" + f(a) + "\\S.*?" + f(b) + "\n?)", c = RegExp(c, "g"));
    return c
  }

  function c(a, b) {
    var c = [{context: a, index: -1}];
    return {
      PushSection: function (a) {
        if (void 0 ===
            a || null === a)return null;
        a = "@" == a ? c[c.length - 1].context : c[c.length - 1].context[a] || null;
        c.push({context: a, index: -1});
        return a
      }, Pop: function () {
        c.pop()
      }, next: function () {
        var a = c[c.length - 1];
        -1 == a.index && (a = {context: null, index: 0}, c.push(a));
        var b = c[c.length - 2].context;
        if (a.index == b.length)c.pop(); else return a.context = b[a.index++], !0
      }, _Undefined: function (a) {
        return void 0 === b ? null : b
      }, _LookUpStack: function (a) {
        for (var b = c.length - 1; ;) {
          var g = c[b];
          if ("@index" == a) {
            if (-1 != g.index)return g.index
          } else if (g = g.context,
              "object" === typeof g && (g = g[a], void 0 !== g))return g;
          b--;
          if (-1 >= b)return this._Undefined(a)
        }
      }, get: function (a) {
        if ("@" == a)return c[c.length - 1].context;
        var b = a.split("."), g = this._LookUpStack(b[0]);
        if (1 < b.length)for (var e = 1; e < b.length; e++) {
          if (null === g)return "[JSONT: Can't resolve '" + a + "'.]";
          g = g[b[e]];
          if (void 0 === g)return this._Undefined(b[e])
        }
        return g
      }
    }
  }

  function d(a, b, c) {
    for (var g = 0; g < a.length; g++) {
      var e = a[g];
      if ("string" == typeof e)c(e); else(0, e[0])(e[1], b, c)
    }
  }

  function e(a, b, c) {
    var g;
    g = b.get(a.name);
    for (var e =
        0; e < a.formatters.length; e++) {
      var h = a.formatters[e];
      g = (0, h[0])(g, b, h[1])
    }
    c(g)
  }

  function h(a, b, c) {
    var g = b.PushSection(a.section_name), e = !1;
    g && (e = !0);
    g && 0 === g.length && (e = !1);
    e ? (d(a.Statements(), b, c), b.Pop()) : (b.Pop(), d(a.Statements("or"), b, c))
  }

  function g(a, b, c) {
    for (var g = b.get("@"), e = 0; e < a.clauses.length; e++) {
      var h = a.clauses[e], q = h[1];
      if ((0, h[0][0])(g, b, h[0][1])) {
        d(q, b, c);
        break
      }
    }
  }

  function q(a, b, c) {
    var g = b.PushSection(a.section_name);
    if (g && 0 < g.length) {
      var g = g.length - 1, e = a.Statements();
      a = a.Statements("alternate");
      for (var h = 0; void 0 !== b.next(); h++)d(e, b, c), h != g && d(a, b, c)
    } else d(a.Statements("or"), b, c);
    b.Pop()
  }

  function v(c, d) {
    function f(a) {
      if (a.startsWith(l)) {
        var c = d.partials[a.substr(l.length)];
        if (c)return [function (a, g, e) {
          return b.JSONTemplate.evaluateJsonTemplate(c, a)
        }, null];
        throw{
          name: "BadPartialInclude",
          message: a.substr(l) + " is not a valid partial. Remember, loops are not supported (a partial include cannot be included inside itself)."
        };
      }
      var g = t.lookup(a);
      if (!g[0])throw{name: "BadFormatter", message: a + " is not a valid formatter"};
      return g
    }

    function v(a) {
      var b = r.lookup(a);
      if (!b[0])throw{name: "BadPredicate", message: a + " is not a valid predicate"};
      return b
    }

    var t = new u([n(b.JSONTemplate.DEFAULT_FORMATTERS), p(b.JSONTemplate.DEFAULT_PREFIX_FORMATTERS)]), r = u([n(b.JSONTemplate.DEFAULT_PREDICATES), p(b.JSONTemplate.DEFAULT_PARAMETRIC_PREDICATES)]), H = d.format_char || "|";
    if (":" != H && "|" != H)throw{
      name: "ConfigurationError",
      message: "Only format characters : and | are accepted"
    };
    var D = d.meta || "{}", E = D.length;
    if (1 == E % 2)throw{
      name: "ConfigurationError",
      message: D + " has an odd number of metacharacters"
    };
    for (var I = D.substring(0, E / 2), D = D.substring(E / 2, E), E = a(I, D), y = w({}), B = [y], J = I.length, x, s, G = 0; ;) {
      x = E.exec(c);
      if (null === x)break; else s = x[0];
      x.index > G && (G = c.slice(G, x.index), y.Append(G));
      G = E.lastIndex;
      x = !1;
      "\n" == s.slice(-1) && (s = s.slice(null, -1), x = !0);
      s = s.slice(J, -J);
      if ("#" != s.charAt(0)) {
        if ("." == s.charAt(0)) {
          s = s.substring(1, s.length);
          var z = {"meta-left": I, "meta-right": D, space: " ", tab: "\t", newline: "\n"}[s];
          if (void 0 !== z) {
            y.Append(z);
            continue
          }
          if (z = s.match(L)) {
            s =
                z[3];
            z[1] ? (x = q, s = A({section_name: s})) : (x = h, s = w({section_name: s}));
            y.Append([x, s]);
            B.push(s);
            y = s;
            continue
          }
          var C;
          if (z = s.match(k)) {
            x = (C = z[1]) ? v(C) : null;
            y.NewOrClause(x);
            continue
          }
          var z = !1, F = s.match(m);
          if (F) {
            if (C = F[1], z = !0, -1 == C.indexOf("?")) {
              x = [function (a) {
                return function (b, c) {
                  var g, e, h;
                  if (-1 !== a.indexOf(" || ")) {
                    g = a.split("||");
                    for (h = 0; h < g.length; h++)if (e = g[h].trim(), c.get(e))return !0;
                    return !1
                  }
                  if (-1 !== a.indexOf(" && ")) {
                    g = a.split(" && ");
                    for (h = 0; h < g.length; h++)if (e = g[h].trim(), !c.get(e))return !1;
                    return !0
                  }
                  return c.get(a)
                }
              }(C),
                null];
              s = K();
              s.NewOrClause(x);
              y.Append([g, s]);
              B.push(s);
              y = s;
              continue
            }
          } else if ("?" == s.charAt(s.length - 1) || "?" == s.split(" ")[0].charAt(s.split(" ")[0].length - 1))C = s, z = !0;
          if (z) {
            x = C ? v(C) : null;
            s = K();
            s.NewOrClause(x);
            y.Append([g, s]);
            B.push(s);
            y = s;
            continue
          }
          if ("alternates with" == s) {
            y.AlternatesWith();
            continue
          }
          if ("end" == s) {
            B.pop();
            if (0 < B.length)y = B[B.length - 1]; else throw{
              name: "TemplateSyntaxError",
              message: "Got too many {end} statements"
            };
            continue
          }
        }
        F = s.split(H);
        if (1 == F.length)z = [f("str")]; else {
          z = [];
          for (s = 1; s <
          F.length; s++)z.push(f(F[s]));
          s = F[0]
        }
        y.Append([e, {name: s, formatters: z}]);
        x && y.Append("\n")
      }
    }
    y.Append(c.slice(G));
    if (1 !== B.length)throw{name: "TemplateSyntaxError", message: "Got too few {end} statements."};
    return y
  }

  b.namespace("JSONTemplate");
  var l = "apply ", r = {};
  b.JSONTemplate.DEFAULT_FORMATTERS = b.Squarespace.TEMPLATE_FORMATTERS;
  b.JSONTemplate.DEFAULT_PREFIX_FORMATTERS = [].concat(b.Squarespace.TEMPLATE_PREFIX_FORMATTERS, [{
    name: "pluralize", func: function (a, b, c) {
      switch (c.length) {
        case 0:
          b = "";
          c = "s";
          break;
        case 1:
          b =
              "";
          c = c[0];
          break;
        case 2:
          b = c[0];
          c = c[1];
          break;
        default:
          throw{name: "EvaluationError", message: "pluralize got too many args"};
      }
      return 1 == a ? b : c
    }
  }, {
    name: "encode-space", func: function (a, b, c) {
      return a.replace(/\s/g, " ")
    }
  }, {
    name: "truncate", func: function (a, b, c) {
      b = c[0] || 100;
      c = c[1] || "...";
      a && a.length > b && (a = a.substring(0, b), a = a.replace(/\w+$/, ""), a += c);
      return a
    }
  }, {
    name: "date", func: function (a, c, g) {
      var e = 0, e = (new Date(a)).getTimezoneOffset();
      if (!b.Lang.isNumber(a))return "Invalid date.";
      if ("undefined" !== typeof TimezoneJS) {
        var h;
        try {
          h = new TimezoneJS.Date(a, c.get("website.timeZone"))
        } catch (d) {
          return "Invalid Timezone"
        }
        e = (isNaN(h.getTimezoneOffset()) ? 0 : h.getTimezoneOffset()) - e
      } else c = -parseInt(c.get("website.timeZoneOffset"), 10) / 6E4, h = (new Date).getTimezoneOffset(), e = c - h;
      a = new Date(a - 6E4 * e);
      g = g.join(" ");
      return b.DataType.Date.format(a, {format: g})
    }
  }, {
    name: "image", func: function (a, c, g) {
      var e;
      a.mediaFocalPoint && (e = a.mediaFocalPoint.x + "," + a.mediaFocalPoint.y);
      return '<img class="' + (g[0] ? g[0] : "thumb-image") + '" ' + (a.title ? 'alt="' +
          b.Squarespace.Escaping.escapeForHtmlTag(a.title) + '" ' : "") + ' data-image="' + a.assetUrl + '" data-image-dimensions="' + a.originalSize + '" data-image-focal-point="' + e + '"/>'
    }
  }, {
    name: "timesince", func: function (a, c, g) {
      if (!b.Lang.isNumber(a))return "Invalid date.";
      g.join(" ");
      return '<span class="timesince" data-date="' + a + '">' + b.Squarespace.DateUtils.humanizeDate(a) + "</span>"
    }
  }, {
    name: "resizedHeightForWidth", func: function (a, b, c) {
      b = a.split("x");
      if (2 != b.length)return "Invalid source parameter.  Pass in 'originalSize'.";
      a = parseInt(b[0], 10);
      b = parseInt(b[1], 10);
      c = parseInt(c[0], 10) / a;
      return parseInt(b * c, 10)
    }
  }, {
    name: "resizedWidthForHeight", func: function (a, b, c) {
      b = a.split("x");
      if (2 != b.length)return "Invalid source parameter.  Pass in 'originalSize'.";
      a = parseInt(b[0], 10);
      b = parseInt(b[1], 10);
      c = parseInt(c[0], 10) / b;
      return parseInt(a * c, 10)
    }
  }, {
    name: "squarespaceThumbnailForWidth", func: function (a, c, g) {
      return b.Squarespace.Rendering.getSquarespaceSizeForWidth(parseInt(g[0], 10))
    }
  }, {
    name: "squarespaceThumbnailForHeight", func: function (a,
                                                           c, g) {
      c = a.split("x");
      if (2 != c.length)return "Invalid source parameter.  Pass in 'originalSize'.";
      a = parseInt(c[0], 10);
      c = parseInt(c[1], 10);
      g = parseInt(g[0], 10) / c;
      g = parseInt(a * g, 10);
      return b.Squarespace.Rendering.getSquarespaceSizeForWidth(g)
    }
  }, {
    name: "cycle", func: function (a, b, c) {
      return c[(a - 1) % c.length]
    }
  }]);
  var n = function (a) {
    return {
      lookup: function (b) {
        return [a[b] || null, null]
      }
    }
  }, p = function (a) {
    return {
      lookup: function (b) {
        for (var c = 0; c < a.length; c++) {
          var g = a[c].name, e = a[c].func;
          if (b.slice(0, g.length) == g)return c =
              b.charAt(g.length), b = "" === c ? [] : b.split(c).slice(1), [e, b]
        }
        return [null, null]
      }
    }
  }, u = function (a) {
    return {
      lookup: function (b) {
        for (var c = 0; c < a.length; c++) {
          var g = a[c].lookup(b);
          if (g[0])return g
        }
        return [null, null]
      }
    }
  }, t = function (a) {
    var b = {
      current_clause: [], Append: function (a) {
        b.current_clause.push(a)
      }, AlternatesWith: function () {
        throw{
          name: "TemplateSyntaxError",
          message: "{.alternates with} can only appear with in {.repeated section ...}"
        };
      }, NewOrClause: function (a) {
        throw{name: "NotImplemented"};
      }
    };
    return b
  }, w = function (a) {
    var b =
        t(a);
    b.statements = {"default": b.current_clause};
    b.section_name = a.section_name;
    b.Statements = function (a) {
      return b.statements[a || "default"] || []
    };
    b.NewOrClause = function (a) {
      if (a)throw{
        name: "TemplateSyntaxError",
        message: "{.or} clause only takes a predicate inside predicate blocks"
      };
      b.current_clause = [];
      b.statements.or = b.current_clause
    };
    return b
  }, A = function (a) {
    var b = w(a);
    b.AlternatesWith = function () {
      b.current_clause = [];
      b.statements.alternate = b.current_clause
    };
    return b
  }, K = function (a) {
    var b = t(a);
    b.clauses = [];
    b.NewOrClause = function (a) {
      a = a || [function (a) {
            return !0
          }, null];
      b.current_clause = [];
      b.clauses.push([a, b.current_clause])
    };
    return b
  }, L = /(repeated)?\s*(section)\s+(\S+)?/, k = /^or(?:[\s\-]+(.+))?/, m = /^if(?:[\s\-]+(.+))?/;
  b.JSONTemplate.Template = Class.create({
    initialize: function (a, b, c) {
      a = this.removeMultilineComments(a);
      this._options = b || {};
      this._program = v(a, this._options)
    }, removeMultilineComments: function (a) {
      for (var b = a.search("{##"), c; 0 <= b;)c = a.substr(b), a = a.substr(0, b) + c.substr(c.search("##}") + 3), b = a.search("{##");
      return a
    }, render: function (a, b) {
      var g = c(a, this._options.undefined_str);
      d(this._program.Statements(), g, b)
    }, expand: function (a) {
      var b = [];
      this.render(a, function (a) {
        b.push(a)
      });
      return b.join("")
    }
  });
  b.JSONTemplate.DEFAULT_PREDICATES = b.Squarespace.TEMPLATE_PREDICATES;
  b.JSONTemplate.DEFAULT_PARAMETRIC_PREDICATES = b.Squarespace.TEMPLATE_PARAMETRIC_PREDICATES;
  b.JSONTemplate.evaluateJsonTemplate = function (a, c, g) {
    return "string" != typeof a ? "JSON Template Error: Processing failed because no input was provided. (type: " + typeof a + ", template: " + JSON.stringify(a) + ", dictionary: " + JSON.stringify(c) + ", partials: " + JSON.stringify(g) + ")" : (new b.JSONTemplate.Template(a, {partials: g})).expand(c)
  }
}, "1.0", {requires: "json squarespace-common squarespace-date-utils squarespace-rendering squarespace-template-helpers squarespace-util".split(" ")})