(function() {
  var $, SF, _base, _ref;
  var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }, __slice = Array.prototype.slice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };

  $ = jQuery;

  if (!(typeof JSON !== "undefined" && JSON !== null)) {
    $.ajax({
      url: "third-party/JSONJS/json2.js",
      dataType: "script",
      async: false,
      cache: true
    });
  }

  if ((_ref = (_base = Array.prototype).reduce) == null) {
    _base.reduce = function(accumulator) {
      var curr, i, l;
      l = this.length;
      if (typeof accumulator !== "function") {
        throw new TypeError("First argument is not callable");
      }
      if ((l === 0 || l === null) && (arguments.length <= 1)) {
        throw new TypeError("Array length is 0 and no second argument");
      }
      if (arguments.length <= 1) {
        curr = this[0];
        i = 1;
      } else {
        curr = arguments[1];
      }
      i = i || 0;
      while (i < l) {
        if (i in this) curr = accumulator.call(undefined, curr, this[i], i, this);
        ++i;
      }
      return curr;
    };
  }

  Array.prototype.unique = function() {
    return this.reduce(function(acc, value) {
      if (__indexOf.call(acc, value) < 0) acc.push(value);
      return acc;
    }, []);
  };

  Array.prototype.merge = function(other) {
    return Array.prototype.push.apply(this, other);
  };

  Function.prototype.delay = function(delay) {
    var timeout;
    timeout = null;
    return __bind(function() {
      var args, current_timeout;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      if (timeout !== null) clearTimeout(timeout);
      current_timeout = timeout = setTimeout(__bind(function() {
        current_timeout = timeout = null;
        return this.apply(null, args);
      }, this), delay);
      return function() {
        if (current_timeout !== null) return clearTimeout(current_timeout);
      };
    }, this);
  };

  Function.prototype.fix = function() {
    var f;
    return f = __bind(function() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      return this.apply(null, [f].concat(__slice.call(args)));
    }, this);
  };

  Function.prototype.curry = function() {
    var args;
    args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
    return __bind(function() {
      var args2;
      args2 = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      return this.apply(null, __slice.call(args).concat(__slice.call(args2)));
    }, this);
  };

  Function.prototype.lazy = function() {
    return __bind(function() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      if (args.length === 0) {
        return this();
      } else {
        return this.curry.apply(this, args).lazy();
      }
    }, this);
  };

  Function.prototype.unlazy = function() {
    return __bind(function() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      if (args.length === 0) {
        return this();
      } else {
        return this.apply(null, args)();
      }
    }, this);
  };

  Function.prototype.composition = function(func) {
    return __bind(function() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      return this(func.apply(null, args));
    }, this);
  };

  $.fn.getClasses = function() {
    var class_list, class_name, element, element_class_list, _i, _j, _len, _len2, _ref2;
    class_list = {};
    for (_i = 0, _len = this.length; _i < _len; _i++) {
      element = this[_i];
      element_class_list = (_ref2 = $(element).attr('class')) != null ? _ref2.split(/\s+/) : void 0;
      if (element_class_list != null) {
        for (_j = 0, _len2 = element_class_list.length; _j < _len2; _j++) {
          class_name = element_class_list[_j];
          class_list[class_name] = null;
        }
      }
    }
    return Object.keys(class_list);
  };

  $.fn.smartAppend = function(content) {
    if (SF.html.isElement(content) || (content.constructor === $)) {
      return this.append(content);
    } else {
      return this.text(content);
    }
  };

  SF = window.SF = {};

  SF.proto = {};

  SF.proto.build = function(prototype, data_array, closure) {
    var new_prototype, value, _i, _len, _results;
    if (!prototype.hasClass("su_prototype")) throw "incorrect prototype";
    if (closure == null) closure = SF.proto.defaultClosure;
    prototype.siblings(".__su_prototype_child").remove();
    _results = [];
    for (_i = 0, _len = data_array.length; _i < _len; _i++) {
      value = data_array[_i];
      new_prototype = prototype.clone(true);
      closure(new_prototype, value);
      new_prototype.removeClass("su_prototype").addClass("__su_prototype_child");
      _results.push(prototype.before(new_prototype));
    }
    return _results;
  };

  SF.proto.defaultClosure = function(prototype, data) {
    var key, target, value, _results;
    _results = [];
    for (key in data) {
      value = data[key];
      if (key === "id") prototype.attr("data-id", value);
      target = $(".su_prototype_" + key, prototype);
      if (!target.length) throw "bad data " + key + ": " + value;
      if (target.get(0).tagName === "img") {
        _results.push(target.attr("src", value));
      } else if (target.get(0).tagName === "A") {
        _results.push(target.attr("href", target.attr("href") + value));
      } else {
        _results.push(target.text(value));
      }
    }
    return _results;
  };

  SF.macro = (function() {

    function macro(selector, trigger_closure) {
      var subselector_cache;
      this.trigger_closure = trigger_closure != null ? trigger_closure : function() {};
      this.setStateWithTrigger = __bind(this.setStateWithTrigger, this);
      if (!selector.hasClass(this.selectorClass())) {
        throw "Bad selector for macro class " + (this.selectorClass());
      }
      this.selector = function() {
        return selector;
      };
      subselector_cache = {};
      this.subselector = function(subselector) {
        if (!(__indexOf.call(subselector_cache, subselector) >= 0)) {
          subselector_cache[subselector] = $(subselector, this.selector());
        }
        return subselector_cache[subselector];
      };
    }

    macro.prototype.selectorClass = function() {
      return "su_macro";
    };

    macro.prototype.setState = function(state_) {
      var should_update;
      should_update = JSON.stringify(state_) !== JSON.stringify(this.state);
      if (should_update) this.state = state_;
      return should_update;
    };

    macro.prototype.updateState = function(state_delta) {
      return this.setState($.extend({}, this.state, state_delta));
    };

    macro.prototype.state = {};

    macro.prototype.setStateWithTrigger = function(state) {
      if (this.setState(state)) return this.trigger_closure(state);
    };

    return macro;

  })();

  SF.macro.proto = (function() {

    __extends(proto, SF.macro);

    function proto(selector, build_closure) {
      this.build_closure = build_closure != null ? build_closure : SF.proto.defaultClosure;
      proto.__super__.constructor.call(this, selector, function() {});
    }

    proto.prototype.selectorClass = function() {
      return "su_macro_prototype";
    };

    proto.prototype.clear = function() {
      return this.getChildren().remove();
    };

    proto.prototype.build = function(data) {
      var new_prototype;
      new_prototype = this.subselector("> .su_prototype").clone(true);
      this.build_closure(new_prototype, data);
      new_prototype.removeClass("su_prototype").addClass("__su_prototype_child");
      return new_prototype;
    };

    proto.prototype.fromArray = function(data_array, callback) {
      this.clear();
      return this.appendArray(data_array, callback);
    };

    proto.prototype.prepend = function(data, callback) {
      if (callback) {
        return callback(this.build(data).hide().prependTo(this.selector()));
      } else {
        return this.build(data).prependTo(this.selector());
      }
    };

    proto.prototype.prependArray = function(data_array, callback) {
      var data, _i, _len, _ref2, _results;
      _ref2 = data_array.reverse();
      _results = [];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        data = _ref2[_i];
        _results.push(this.prepend(data, callback));
      }
      return _results;
    };

    proto.prototype.append = function(data, callback) {
      if (callback) {
        return callback(this.build(data).hide().appendTo(this.selector()));
      } else {
        return this.build(data).appendTo(this.selector());
      }
    };

    proto.prototype.appendArray = function(data_array, callback) {
      var data, _i, _len, _results;
      _results = [];
      for (_i = 0, _len = data_array.length; _i < _len; _i++) {
        data = data_array[_i];
        _results.push(this.append(data, callback));
      }
      return _results;
    };

    proto.prototype.getChildren = function() {
      return this.selector().children(".__su_prototype_child");
    };

    return proto;

  })();

  SF.macro.suggest = (function() {
    var timeout;

    __extends(suggest, SF.macro);

    function suggest(selector, input_selector, suggest_url, suggest_build_closure, onSelection) {
      var _this;
      this.input_selector = input_selector;
      this.suggest_url = suggest_url;
      this.suggest_build_closure = suggest_build_closure;
      this.onSelection = onSelection;
      this.hide = __bind(this.hide, this);
      suggest.__super__.constructor.call(this, selector, function() {});
      this.prototype_macro = new SF.macro.proto(this.subselector(".su_macro_prototype"), function(prototype, data) {
        prototype.attr("data-id", data.Id);
        if (this.suggest_build_closure) {
          return this.suggest_build_closure(prototype, data);
        } else {
          return prototype.find(".name").text(data.Name);
        }
      });
      this.input_selector.blur(__bind(function() {
        return setTimeout(this.hide, 250);
      }, this));
      _this = this;
      this.subselector(".su_prototype").click(function() {
        return _this.suggestionSelected($(this).text());
      });
    }

    suggest.prototype.selectorClass = function() {
      return "su_macro_suggestion";
    };

    suggest.prototype.suggestionSelected = function(val) {
      this.input_selector.val("");
      this.hide();
      if (this.onSelection) this.onSelection(val);
      return this.input_selector.focus();
    };

    suggest.prototype.setSuggestions = function(term) {
      return __bind(function() {
        return SF.action.post(this.suggest_url, {
          term: term
        }, __bind(function(data) {
          this.prototype_macro.fromArray(data.results);
          return this.selector().toggle(data.results.length > 0);
        }, this));
      }, this);
    };

    timeout = null;

    suggest.prototype.setDelayedSuggestions = function(term) {
      if (timeout) clearTimeout(timeout);
      return timeout = setTimeout(this.setSuggestions(term), 200);
    };

    suggest.prototype.hide = function() {
      return this.selector().hide();
    };

    return suggest;

  })();

  SF.macro.pagination = {};

  SF.macro.pagination.basic = (function() {

    __extends(basic, SF.macro);

    function basic() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      this.setState = __bind(this.setState, this);
      basic.__super__.constructor.apply(this, args);
      this.setState({
        page: null,
        page_max: null
      });
    }

    basic.prototype.selectorClass = function() {
      return "su_macro_pagination";
    };

    basic.prototype.setState = function(state) {
      var enabled, first_page, last_page, page, page_max, selector, target_page, _i, _j, _len, _ref2, _ref3, _results;
      if (!basic.__super__.setState.call(this, (page = state.page, page_max = state.page_max, state))) {
        return false;
      }
      _ref2 = [
        {
          target_page: page - 1,
          selector: this.subselector(".su_prev"),
          enabled: page > 1
        }, {
          target_page: page + 1,
          selector: this.subselector(".su_next"),
          enabled: page < page_max
        }
      ];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        _ref3 = _ref2[_i], target_page = _ref3.target_page, selector = _ref3.selector, enabled = _ref3.enabled;
        selector.unbind("click");
        SF.html.setEnabledState(selector.parent("li"), enabled);
        if (enabled) {
          __bind(function(target_page) {
            return selector.click(__bind(function() {
              return this.setStateWithTrigger({
                page: target_page,
                page_max: page_max
              });
            }, this));
          }, this)(target_page);
        }
      }
      if (page_max === 0) page_max = 1;
      first_page = 1;
      last_page = page_max;
      if (page_max > 11) {
        if (page >= page_max - 5) {
          first_page = page_max - 11;
        } else if (page - 5 > 0) {
          first_page = page - 5;
        } else {
          first_page = 1;
        }
        last_page = page < 6 ? 10 : first_page + 11;
      }
      SF.proto.build(this.subselector(".su_prototype"), (function() {
        _results = [];
        for (var _j = first_page; first_page <= last_page ? _j <= last_page : _j >= last_page; first_page <= last_page ? _j++ : _j--){ _results.push(_j); }
        return _results;
      }).apply(this), __bind(function(prototype, page_) {
        var link;
        link = $("a", prototype);
        link.text(page_);
        if (page_ === page) link.parent("li").addClass("active");
        return link.click(__bind(function() {
          return this.setStateWithTrigger({
            page: page_,
            page_max: page_max
          });
        }, this));
      }, this));
      this.selector().toggle(page_max !== 1);
      return true;
    };

    return basic;

  })();

  SF.macro.pagination.flow = (function() {
    var ajax_call;

    __extends(flow, SF.macro);

    function flow(selector, trigger_closure, prototype_closure, init_params) {
      var checkClosure, toggle_closure;
      if (init_params == null) init_params = {};
      flow.__super__.constructor.call(this, selector, trigger_closure);
      if (prototype_closure == null) prototype_closure = SF.proto.defaultClosure;
      this.duration = 30000;
      this.prototype_macro = new SF.macro.proto(this.subselector(".su_macro_prototype"), function(prototype, data) {
        prototype.attr("data-id", data.Id);
        return prototype_closure(prototype, data);
      });
      this.setState({
        autoflow: false,
        params: init_params
      });
      this.subselector(".su_macro_pagination_flow_seemore").click(__bind(function() {
        return this.getOldRows();
      }, this));
      this.subselector(".su_macro_pagination_flow_getnew").click(__bind(function() {
        return this.getNewRows();
      }, this));
      this.getOldRows();
      toggle_closure = __bind(function(autoflow) {
        this.state.autoflow = autoflow;
        this.subselector(".su_macro_pagination_flow_getnew").toggle(!this.state.autoflow);
        this.subselector(".su_macro_pagination_flow_autoflow_enable").toggle(!this.state.autoflow);
        this.subselector(".su_macro_pagination_flow_autoflow_disable").toggle(this.state.autoflow);
        if (this.state.autoflow) return this.getNewRows();
      }, this);
      this.subselector(".su_macro_pagination_flow_autoflow_enable").click(__bind(function() {
        return toggle_closure(true);
      }, this));
      this.subselector(".su_macro_pagination_flow_autoflow_disable").click(__bind(function() {
        return toggle_closure(false);
      }, this));
      checkClosure = (__bind(function() {
        if (this.state.autoflow) {
          this.getNewRows();
        } else {
          this.getNewCount();
        }
        return checkClosure();
      }, this)).delay(this.duration);
      checkClosure();
    }

    flow.prototype.selectorClass = function() {
      return "su_macro_pagination_flow";
    };

    flow.prototype.getNewestId = function() {
      return this.prototype_macro.getChildren().first().attr("data-id");
    };

    flow.prototype.getOldestId = function() {
      return this.prototype_macro.getChildren().last().attr("data-id");
    };

    ajax_call = null;

    flow.prototype.setState = function(state) {
      var autoflow, params, require_reset;
      require_reset = (this.state.params != null) && JSON.stringify(state.params) !== JSON.stringify(this.state.params);
      if (!flow.__super__.setState.call(this, (autoflow = state.autoflow, params = state.params, state))) {
        return false;
      }
      if (require_reset) {
        if (ajax_call) ajax_call.abort();
        this.prototype_macro.clear();
        return this.getOldRows();
      }
    };

    flow.prototype.getOldRows = function() {
      var before_id, params;
      this.subselector(".su_macro_pagination_flow_seemore").button('loading');
      before_id = this.getOldestId();
      params = this.state.params;
      if (before_id != null) {
        params = $.extend({
          before_id: before_id
        }, params);
      }
      return ajax_call = SF.action.post(this.selector().attr("data-controller-url") + "/block/list", params, __bind(function(data) {
        if (!data.is_more) {
          this.subselector(".su_macro_pagination_flow_seemore_div").hide();
        }
        this.prototype_macro.appendArray(data.results);
        return this.subselector(".su_macro_pagination_flow_seemore").button('reset');
      }, this));
    };

    flow.prototype.getNewCount = function() {
      var newest_id, params;
      newest_id = this.getNewestId();
      if (!newest_id) return;
      params = $.extend({
        after_id: newest_id
      }, this.state.params);
      return SF.action.post(this.selector().attr("data-controller-url") + "/new/count", params, __bind(function(data) {
        if (data.count > 0) {
          this.subselector(".su_macro_pagination_flow_getnew_div").slideDown();
        }
        return this.subselector(".su_macro_pagination_flow_getnew").text("" + data.count + " New");
      }, this));
    };

    flow.prototype.getNewRows = function() {
      var newest_id, params;
      newest_id = this.getNewestId();
      if (!newest_id) return;
      params = $.extend({
        after_id: newest_id
      }, this.state.params);
      return SF.action.post(this.selector().attr("data-controller-url") + "/new/list", params, __bind(function(data) {
        this.subselector(".su_macro_pagination_flow_getnew_div").hide();
        if (this.state.autoflow) {
          return this.prependAnimateResults(data.results, Math.min((this.duration - 2000) / data.results.length, 3000));
        } else {
          return this.prototype_macro.prependArray(data.results, function(obj) {
            return obj.fadeIn(3000);
          });
        }
      }, this));
    };

    flow.prototype.prependAnimateResults = function(results, duration) {
      var result;
      if (results.length <= 0 || !this.state.autoflow) return;
      result = results.pop();
      return this.prototype_macro.prepend(result, __bind(function(obj) {
        return obj.fadeIn(duration, __bind(function() {
          return this.prependAnimateResults(results, duration);
        }, this));
      }, this));
    };

    return flow;

  })();

  SF.macro.navigation = {};

  SF.macro.navigation.drill = (function() {

    __extends(drill, SF.macro);

    function drill(selector, navigation_forest, trigger_closure, prototype_closure) {
      this.setState = __bind(this.setState, this);
      var navigation_forest_flattened, root_node_name;
      drill.__super__.constructor.call(this, selector, trigger_closure);
      this.navigation_forest = function() {
        return navigation_forest;
      };
      this.prototype_closure = function() {
        return prototype_closure;
      };
      navigation_forest_flattened = (function(f, forest, parent_id) {
        var flattened_forest, tree, _i, _len;
        flattened_forest = {};
        for (_i = 0, _len = forest.length; _i < _len; _i++) {
          tree = forest[_i];
          flattened_forest[tree.id] = tree;
          tree.parent_id = parent_id;
          flattened_forest = $.extend(flattened_forest, f(tree.children, tree.id));
        }
        return flattened_forest;
      }).fix()($.extend(true, [], navigation_forest), null);
      this.navigation_forest_flattened = function() {
        return navigation_forest_flattened;
      };
      root_node_name = selector.attr("data-root-node-name");
      this.root_node_name = function() {
        return root_node_name;
      };
      this.setState({
        id: null
      });
    }

    drill.prototype.selectorClass = function() {
      return "su_macro_navigation_drill";
    };

    drill.prototype.setState = function(state) {
      var current_navigation_forest, current_node, current_span, id, parent_node, parent_span;
      if (!drill.__super__.setState.call(this, (id = state.id, state))) {
        return false;
      }
      current_span = this.subselector("span.su_macro_navigation_drill_current").removeClass("sf_hidden");
      parent_span = this.subselector("span.su_macro_navigation_drill_parent").removeClass("sf_hidden");
      if (id > 0) {
        current_node = this.navigation_forest_flattened()[id];
        current_span.text(current_node.name);
        parent_node = (current_node.parent_id ? this.navigation_forest_flattened()[current_node.parent_id] : {
          id: 0,
          name: this.root_node_name()
        });
        this.subselector(".su_macro_navigation_drill_parent > a").text(parent_node.name).unbind("click").click(__bind(function() {
          return this.setStateWithTrigger({
            id: parent_node.id
          });
        }, this));
        parent_span.show();
        current_navigation_forest = current_node.children;
      } else {
        current_span.text(this.root_node_name());
        parent_span.hide();
        current_navigation_forest = this.navigation_forest();
      }
      if (current_navigation_forest !== null && current_navigation_forest.length > 0) {
        return SF.proto.build(this.subselector(".su_prototype"), current_navigation_forest, __bind(function(prototype, data) {
          prototype.attr("data-id", data["id"]);
          this.prototype_closure()(prototype, data);
          return prototype.click(__bind(function() {
            return this.setStateWithTrigger({
              id: data["id"]
            });
          }, this));
        }, this));
      } else {
        return this.subselector(".su_prototype").siblings().removeClass("su_selected").filter("[data-id='" + id + "']").addClass("su_selected");
      }
    };

    return drill;

  })();

  SF.macro.sortby = (function() {

    __extends(sortby, SF.macro);

    function sortby() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      this.setState = __bind(this.setState, this);
      sortby.__super__.constructor.apply(this, args);
      this.subselector("a").click(__bind(function(eventObject) {
        var clicked_type, key, should_ascending;
        clicked_type = $(eventObject.target).closest(".su_macro_sortby_type");
        should_ascending = clicked_type.hasClass("su_selected_descending") || !clicked_type.hasClass("su_selected_ascending");
        key = clicked_type.attr("data-key");
        return this.setStateWithTrigger({
          key: key,
          is_ascending: should_ascending
        });
      }, this));
      true;
    }

    sortby.prototype.selectorClass = function() {
      return "su_macro_sortby";
    };

    sortby.prototype.setState = function(state) {
      var class_to_add, is_ascending, key;
      if (!sortby.__super__.setState.call(this, (key = state.key, is_ascending = state.is_ascending, state))) {
        return false;
      }
      class_to_add = is_ascending ? "su_selected_ascending" : "su_selected_descending";
      this.subselector(".su_macro_sortby_type").removeClass("su_selected_ascending su_selected_descending").filter("[data-key='" + key + "']").addClass(class_to_add);
      return true;
    };

    return sortby;

  })();

  SF.macro.filterby = {};

  SF.macro.filterby.checkbox = (function() {

    __extends(checkbox, SF.macro);

    function checkbox() {
      var args;
      args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
      this.setState = __bind(this.setState, this);
      checkbox.__super__.constructor.apply(this, args);
      this.subselector("input:checkbox").click(__bind(function(eventObject) {
        var values;
        values = [];
        $(eventObject.target).closest(".filterby_options").find("input:checked").each(function(i, option) {
          return values.push($(option).val());
        });
        return this.setStateWithTrigger({
          values: values
        });
      }, this));
      true;
    }

    checkbox.prototype.selectorClass = function() {
      return "su_macro_filterby_checkbox";
    };

    checkbox.prototype.setState = function(state) {
      var value, values, _i, _len;
      if (!checkbox.__super__.setState.call(this, (values = state.values, state))) {
        return false;
      }
      for (_i = 0, _len = values.length; _i < _len; _i++) {
        value = values[_i];
        this.subselector("input:checkbox[value='" + value + "']").prop("checked", true);
      }
      return true;
    };

    return checkbox;

  })();

  SF.macro.search = (function() {

    __extends(search, SF.macro);

    function search(selector, trigger_closure) {
      this.setState = __bind(this.setState, this);
      var cancel_closure, delayedUpdateWithValue, updateWithValue;
      search.__super__.constructor.call(this, selector, trigger_closure);
      cancel_closure = null;
      updateWithValue = __bind(function(value) {
        return this.setStateWithTrigger({
          value: value
        });
      }, this);
      delayedUpdateWithValue = updateWithValue.delay(250);
      selector.keyup(function(event_object) {
        var _ref2;
        if ((_ref2 = event_object.which) !== 13 && _ref2 !== 16 && _ref2 !== 17 && _ref2 !== 18 && _ref2 !== 20 && _ref2 !== 37 && _ref2 !== 38 && _ref2 !== 39 && _ref2 !== 40 && _ref2 !== 91 && _ref2 !== 93) {
          return cancel_closure = delayedUpdateWithValue(selector.val());
        }
      });
      selector.keydown(function(event_object) {
        if (cancel_closure !== null) cancel_closure();
        if (event_object.which === 13) return updateWithValue(selector.val());
      });
      this.setState({
        value: ""
      });
    }

    search.prototype.selectorClass = function() {
      return "su_macro_search";
    };

    search.prototype.setState = function(state) {
      var value;
      if (!search.__super__.setState.call(this, (value = state.value, state))) {
        return false;
      }
      this.selector().val(value);
      return true;
    };

    return search;

  })();

  SF.macro.html = {};

  SF.macro.html.tags = (function() {

    __extends(tags, SF.macro);

    function tags(selector, trigger_closure, suggest_url, suggest_proto_closure, is_case_sensitive) {
      var backspace_event_enabled, make_inactive, _this;
      this.suggest_url = suggest_url;
      this.suggest_proto_closure = suggest_proto_closure;
      this.is_case_sensitive = is_case_sensitive != null ? is_case_sensitive : false;
      this.inArray = __bind(this.inArray, this);
      this.setInitTags = __bind(this.setInitTags, this);
      this.addTagFromInput = __bind(this.addTagFromInput, this);
      tags.__super__.constructor.call(this, selector, trigger_closure);
      this.setState({
        added_tags: [],
        removed_tags: [],
        init_tags: []
      });
      if (this.suggest_url) {
        this.suggest = new SF.macro.suggest(this.subselector(".su_macro_suggestion"), this.subselector("input.su_tag_input"), this.suggest_url, this.suggest_proto_closure, __bind(function(tag) {
          return this.addTag(tag);
        }, this));
      }
      this.selector().closest("form").find("input").keypress(function(e) {
        switch (e.keyCode) {
          case 13:
            return false;
          default:
            return true;
        }
      });
      _this = this;
      this.subselector(".su_post_tag .su_delete_tag").click(function() {
        var tag;
        tag = $(this).closest(".su_post_tag").attr("data-tag");
        return _this.deleteTag(tag);
      });
      backspace_event_enabled = true;
      this.subselector("input.su_tag_input").keydown(__bind(function(e) {
        backspace_event_enabled = this.subselector("input.su_tag_input").val().length === 0;
        return true;
      }, this));
      this.subselector("input.su_tag_input").keyup(__bind(function(e) {
        var tag;
        tag = this.subselector("input.su_tag_input").val();
        switch (e.keyCode) {
          case 13:
          case 32:
            this.addTagFromInput();
            break;
          case 8:
            if (backspace_event_enabled) {
              tag = this.subselector(".su_post_tag:not(.su_prototype)").last().attr("data-tag");
              this.deleteTag(tag);
              this.subselector("input.su_tag_input").val(tag);
            }
            if (this.suggest) this.suggest.setDelayedSuggestions(tag);
            break;
          default:
            if (this.suggest) this.suggest.setDelayedSuggestions(tag);
        }
        return true;
      }, this));
      this.subselector("input.su_tag_input").focus(__bind(function() {
        return this.selector().addClass("active");
      }, this));
      make_inactive = __bind(function() {
        if (!this.subselector("input.su_tag_input").is(":focus")) {
          return this.selector().removeClass("active");
        }
      }, this);
      this.subselector("input.su_tag_input").blur(__bind(function() {
        setTimeout(this.addTagFromInput, 250);
        return setTimeout(make_inactive, 250);
      }, this));
      this.selector().click(__bind(function() {
        return this.subselector("input.su_tag_input").focus();
      }, this));
    }

    tags.prototype.selectorClass = function() {
      return "su_macro_html_tags";
    };

    tags.prototype.getTags = function() {
      var added_tags, removed_tags, _ref2;
      return _ref2 = this.state, added_tags = _ref2.added_tags, removed_tags = _ref2.removed_tags, _ref2;
    };

    tags.prototype.addTag = function(tag, add_to_state) {
      var new_proto, prototype;
      if (add_to_state == null) add_to_state = true;
      tag = $.trim(tag);
      if (tag === "" || this.inArray(tag, this.state.added_tags)) return;
      if (this.subselector(".su_post_tag[data-tag='" + tag + "']").length > 0) {
        return;
      }
      prototype = this.subselector(".su_post_tag.su_prototype");
      new_proto = prototype.clone(true);
      new_proto.removeClass("su_prototype");
      new_proto.attr("data-tag", tag);
      new_proto.find(".su_tag").text(tag);
      prototype.before(new_proto);
      if (this.suggest) this.suggest.hide();
      if (add_to_state) {
        if (this.inArray(tag, this.state.removed_tags)) {
          return this.state.removed_tags.splice(this.state.removed_tags.indexOf(tag), 1);
        } else {
          if (!this.inArray(tag, this.state.init_tags)) {
            return this.state.added_tags.push(tag);
          }
        }
      }
    };

    tags.prototype.addTagFromInput = function() {
      this.addTag(this.subselector("input.su_tag_input").val());
      return this.subselector("input.su_tag_input").val("");
    };

    tags.prototype.deleteTag = function(tag) {
      if (this.inArray(tag, this.state.added_tags)) {
        this.state.added_tags.splice(this.state.added_tags.indexOf(tag), 1);
      } else {
        if (!this.inArray(tag, this.state.removed_tags)) {
          this.state.removed_tags.push(tag);
        }
      }
      return this.subselector(".su_post_tag[data-tag='" + tag + "']").remove();
    };

    tags.prototype.setInitTags = function(tags) {
      var tag, _i, _len;
      this.clearTags();
      for (_i = 0, _len = tags.length; _i < _len; _i++) {
        tag = tags[_i];
        this.addTag(tag, false);
      }
      return this.state.init_tags = tags;
    };

    tags.prototype.clearTags = function() {
      this.updateState({
        added_tags: [],
        removed_tags: []
      });
      return this.subselector(".su_post_tag:not(.su_prototype)").remove();
    };

    tags.prototype.inArray = function(value, array) {
      var item, _i, _j, _len, _len2;
      if (this.is_case_sensitive) {
        for (_i = 0, _len = array.length; _i < _len; _i++) {
          item = array[_i];
          if (value === item) return true;
        }
      } else {
        for (_j = 0, _len2 = array.length; _j < _len2; _j++) {
          item = array[_j];
          if (value.toLowerCase() === item.toLowerCase()) return true;
        }
      }
      return false;
    };

    tags.prototype.setState = function(state) {
      var added_tags, removed_tags;
      if (!tags.__super__.setState.call(this, (added_tags = state.added_tags, removed_tags = state.removed_tags, state))) {
        return false;
      }
      return true;
    };

    return tags;

  })();

  SF.html = {};

  SF.html.setEnabledState = function(obj, is_enabled) {
    return obj.toggleClass("disabled", !is_enabled);
  };

  SF.html.getDisplayValue = function(element) {
    switch ($(element)[0].tagName) {
      case "INPUT":
        switch ($(element).attr("type")) {
          case "radio":
          case "checkbox":
            return $(element).parent().text();
          default:
            return $(element).val();
        }
        break;
      case "SELECT":
        return $("option:selected", element).attr("label");
      default:
        throw "bad tag type " + ($(element)[0].tagName);
    }
  };

  SF.html.truncate = function(obj, original_text, truncate_length) {
    if (original_text.length > truncate_length) {
      obj.text(original_text.substring(0, truncate_length) + "...");
      return obj.attr("title", original_text);
    } else {
      return obj.text(original_text);
    }
  };

  SF.html.isElement = function(object) {
    if (typeof HTMLElement === "object") {
      return object instanceof HTMLElement;
    } else {
      return typeof object === "object" && object.nodeType === 1 && typeof object.nodeName === "string";
    }
  };

  SF.html.redirect = function(href) {
    window.location.href = $.browser.msie && !href.match(/^[A-Za-z]+:\/\//) ? $("base").attr("href") + href : href;
  };

  SF.html.getScriptParent = function(callback) {
    var hook_id;
    hook_id = "__script_hook_" + (Math.floor(Math.random() * 100000));
    document.write("<div style='display:none;' id='" + hook_id + "'></div>");
    return $(function() {
      var hook, parent;
      hook = $("#" + hook_id);
      parent = hook.parent();
      hook.remove();
      return callback(parent);
    });
  };

  SF.html.formatDate = function(format, date_string) {
    var date;
    date = new Date(date_string.replace(/\-/g, '\/').replace(/[T|Z]/g, ' '));
    return $.datepicker.formatDate(format, date);
  };

  SF.history = new function() {
    var should_use_persistent_history;
    should_use_persistent_history = true;
    this.disablePersistentState = function() {
      return should_use_persistent_history = false;
    };
    this.init = function(default_params) {
      var current_query_pieces, file, registered_params, stateChange, stateChargeWithNewQueryState, updateQuery, _i, _len, _ref2;
      this.disablePersistentState = function() {
        if (is_init) throw "history has already been init'ed";
      };
      _ref2 = ["history.adapter.jquery.js", "history.js"];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        file = _ref2[_i];
        $.ajax({
          url: "third-party/HistoryJS/scripts/compressed/" + file,
          dataType: "script",
          async: false,
          cache: true
        });
      }
      should_use_persistent_history &= window.History.enabled;
      registered_params = {};
      current_query_pieces = {};
      stateChargeWithNewQueryState = function(query_state) {
        var current_closure, key, run_closure, run_closures, unprocessed_query_keys, value, _j, _k, _l, _len2, _len3, _len4, _ref3, _results;
        unprocessed_query_keys = ((function() {
          var _results;
          _results = [];
          for (key in query_state) {
            value = query_state[key];
            if (value !== current_query_pieces[key]) _results.push(key);
          }
          return _results;
        })()).unique();
        current_query_pieces = query_state;
        run_closures = [];
        for (_j = 0, _len2 = unprocessed_query_keys.length; _j < _len2; _j++) {
          key = unprocessed_query_keys[_j];
          if (registered_params[key]) {
            _ref3 = registered_params[key];
            for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
              current_closure = _ref3[_k];
              if (!(__indexOf.call(run_closures, current_closure) >= 0)) {
                run_closures.push(current_closure);
              }
            }
          }
        }
        _results = [];
        for (_l = 0, _len4 = run_closures.length; _l < _len4; _l++) {
          run_closure = run_closures[_l];
          _results.push(run_closure(current_query_pieces));
        }
        return _results;
      };
      if (should_use_persistent_history) {
        updateQuery = function(param_array) {
          var function_name, key, value;
          function_name = Object.keys(current_query_pieces).length > 0 ? "pushState" : "replaceState";
          return window.History[function_name]({}, "", ("" + location.pathname + "?") + ((function() {
            var _results;
            _results = [];
            for (key in param_array) {
              value = param_array[key];
              _results.push("" + key + "=" + value);
            }
            return _results;
          })()).join("&"));
        };
        stateChange = function() {
          var key, qindex, query, query_piece, query_state, state, value, _j, _len2, _ref3, _ref4;
          state = window.History.getState().hash;
          qindex = state.indexOf("?");
          if (qindex === -1) {
            updateQuery({});
            return;
          }
          query = state.substr(qindex + 1);
          query_state = {};
          if (query !== "") {
            _ref3 = query.split("&");
            for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
              query_piece = _ref3[_j];
              _ref4 = query_piece.split("="), key = _ref4[0], value = _ref4[1];
              query_state[key] = value;
            }
          }
          return stateChargeWithNewQueryState(query_state);
        };
      } else {
        updateQuery = function(query_state) {
          return stateChargeWithNewQueryState($.extend({}, query_state));
        };
      }
      this.get = function() {
        return $.extend({}, current_query_pieces);
      };
      this.getKey = function(key) {
        return current_query_pieces[key];
      };
      this.register = function(key_array, closure) {
        var call_obj, key, _j, _len2;
        call_obj = {};
        for (_j = 0, _len2 = key_array.length; _j < _len2; _j++) {
          key = key_array[_j];
          call_obj[key] = current_query_pieces[key];
          if (!registered_params[key]) registered_params[key] = [];
          registered_params[key].push(closure);
        }
        return closure(call_obj);
      };
      this.set = function(key_value_map) {
        return updateQuery($.extend({}, current_query_pieces, key_value_map));
      };
      this.unset = function(key) {
        var new_query_pieces;
        if (!current_query_pieces[key]) throw "bad key " + key;
        new_query_pieces = $.extend({}, current_query_pieces);
        delete new_query_pieces[key];
        return updateQuery(new_query_pieces);
      };
      if (should_use_persistent_history) {
        $(window).bind("statechange", stateChange);
        stateChange();
      }
      return this.set($.extend({}, default_params, this.get()));
    };
    return this;
  };

  SF.less = {};

  SF.less.refresh = function() {
    if (window.less.refresh) {
      $(window.less.sheets).addClass("__less_processed__");
      window.less.sheets = $("link[rel='stylesheet/less']:not(.__less_processed__)");
      return window.less.refresh();
    }
  };

  SF.action = {};

  SF.action.handle = function(success_closure, error_closure) {
    return function(data) {
      if (!data.success) {
        if (error_closure) {
          error_closure(data.error);
        } else {
          if (data.error.message) alert(data.error.message);
        }
        return;
      }
      if (success_closure) return success_closure(data);
    };
  };

  SF.action.post = function(action, action_data, success_closure, error_closure) {
    return $.ajax({
      type: 'POST',
      url: action,
      data: action_data,
      success: SF.action.handle(success_closure, error_closure),
      dataType: "json"
    });
  };

  SF.action.jsonp = function(action, action_data, success_closure, error_closure) {
    return $.ajax({
      type: 'GET',
      url: action,
      data: action_data,
      success: SF.action.handle(success_closure, error_closure),
      dataType: "jsonp"
    });
  };

  SF.bootstrap = {};

  SF.bootstrap.alert = {};

  SF.bootstrap.alert.basic = function(message, type) {
    var element, possible_types;
    if (type == null) type = 'error';
    possible_types = ['error', 'warning', 'success', 'info'];
    if (__indexOf.call(possible_types, type) < 0) {
      throw "" + type + " not a valid type. Possible types are " + possible_types;
    }
    element = $("<div class='alert alert-" + type + " fade in'><a class='close' href='javascript:void(0)' data-dismiss='alert'>&times;</a><div class='su_body'></div></div>");
    element.find("div.su_body").smartAppend(message);
    return element;
  };

  SF.bootstrap.alert.block = (function() {

    function block(message, type, title) {
      var possible_types;
      if (type == null) type = 'error';
      if (title == null) title = null;
      possible_types = ['error', 'warning', 'success', 'info'];
      if (__indexOf.call(possible_types, type) < 0) {
        throw "" + type + " not a valid type. Possible types are " + possible_types;
      }
      title = title ? "<h4 class='alert-heading'>" + title + "</h4>" : "";
      this.element = $("<div class='alert alert-block alert-" + type + " fade in'><a class='close' href='javascript:void(0)' data-dismiss='alert'>&times;</a>" + title + "<p class='su_body'></p><p class='alert-actions'></p></div>");
      this.element.find(".su_body").smartAppend(message);
    }

    block.prototype.addButton = function(message, button_class, click_closure) {
      var button;
      if (button_class == null) button_class = '';
      button = $("<span><a href='javascript:void(0)' class='btn " + button_class + "'>" + message + "</a>&nbsp;</span>");
      if (click_closure) button.bind("click", click_closure);
      this.element.find(".alert-actions").append(button);
      return button.find("a");
    };

    return block;

  })();

  $(function() {
    var syncCheckBox;
    if ($.fn.placeholder != null) {
      $('.su_bootstrap_safe input, .su_bootstrap_safe textarea').placeholder();
    }
    if ($.fn.chosen != null) $('.su_bootstrap_safe select:not(.no-chzn)').chosen();
    if ($("pre.prettyprint, code.prettyprint, xmp.prettyprint").length) {
      $('head').append('<link rel="stylesheet" href="third-party/Bootstrap/docs/assets/js/google-code-prettify/prettify.css" type="text/css" />');
      $.ajax({
        url: "third-party/Bootstrap/docs/assets/js/google-code-prettify/prettify.js",
        dataType: "script",
        async: true,
        cache: true,
        success: function() {
          return prettyPrint();
        }
      });
    }
    if ($.fn.tooltip) {
      $(".su_bootstrap_safe a[rel=tooltip]").tooltip({
        live: true
      });
    }
    if ($.fn.popover) {
      $(".su_bootstrap_safe a[rel=popover]").popover({
        offset: 10
      });
    }
    syncCheckBox = function() {
      return $(this).parents(".add-on").toggleClass('active', $(this).is(":checked"));
    };
    return $('.su_bootstrap_safe .add-on :checkbox').each(syncCheckBox).click(syncCheckBox);
  });

}).call(this);
