Sign in with your account

Don't have an account? Sign up now.
Fatal error [0]: Unclosed regex pattern at position: 200899
Triggered in /lib/G/classes/class.minify.php at line 709

Stack trace:
#0 /lib/G/classes/class.minify.php(433): G\Minify->saveRegex()
#1 /lib/G/classes/class.minify.php(339): G\Minify->loop()
#2 /lib/G/classes/class.minify.php(312): G\Minify->minifyDirectToOutput('/**
* Peafowl JS
* Copyright 2016 Rodolfo Berrios
*/

/**
* Peafowl DOM functions and event listeners
*/
$(function() {
var ajaxSetup = {
url: PF.obj.config.json_api,
cache: false,
dataType: "json",
data: { auth_token: PF.obj.config.auth_token }
};
if (typeof PF.obj.config.session_id !== typeof undefined) {
ajaxSetup.data.session_id = PF.obj.config.session_id;
}
$.ajaxSetup(ajaxSetup);

/**
* WINDOW LISTENERS
* -------------------------------------------------------------------------------------------------
*/
$(window).bind("beforeunload", function() {
if (
$("form", PF.obj.modal.selectors.root).data("beforeunload") == "continue"
)
return;
if (
$(PF.obj.modal.selectors.root).is(":visible") &&
PF.fn.form_modal_has_changed()
) {
return PF.fn._s(
"All the changes that you have made will be lost if you continue."
);
}
});

$(window).bind("hashchange", function() {
// Call edit modal on #edit
if (
window.location.hash == "#edit" &&
!$(PF.obj.modal.selectors.root).exists()
)
$("[data-modal=edit]")
.first()
.click();
});

// Blind the tipTips on load
PF.fn.bindtipTip();

var resizeTimer,
scrollTimer,
width = $(window).width();
// Fluid width on resize
$(window).on("resize", function() {
PF.fn.growl.fixPosition();
PF.fn.modal.fixScrollbars();

var device = PF.fn.getDeviceName(),
handled = ["phone", "phablet"],
desktop = ["tablet", "laptop", "desktop"];

clearTimeout(resizeTimer);
clearTimeout(scrollTimer);

scrollTimer = setTimeout(function() {
$(".follow-scroll-wrapper, .follow-scroll-placeholder")
.removeClass("position-fixed")
.attr("style", "");
if ($("html").hasScrollBar().vertical) {
PF.obj.follow_scroll.set(true);
PF.obj.follow_scroll.process(true);
}
}, 25);

//PF.fn.window_to_device(); // handled by window event parent
var new_device = PF.fn.getDeviceName();

if (
(new_device !== device &&
($.inArray(device, handled) >= 0 &&
$.inArray(new_device, handled) == -1)) ||
($.inArray(device, desktop) >= 0 && $.inArray(new_device, desktop) == -1)
) {
PF.fn.close_pops();
}

$(".top-bar").css("top", "");
$(PF.fn.topMenu.vars.menu).css("height", $(window).height());

$("body").css({ position: "", height: "" });

$(".antiscroll")
.removeClass("jsly")
.data("antiscroll", ""); // Destroy for this?
$(".antiscroll-inner").css({ height: "", width: "", maxheight: "" }); // .pop-box, .pop-box-inner ?

PF.fn.list_fluid_width();

if (width !== $(window).width()) {
if (
$("[data-action=top-bar-menu-full]", "#top-bar").hasClass("current")
) {
PF.fn.topMenu.hide(0);
}

var cols_fn = function() {
PF.fn.listing.columnizer(true, 0);
$(PF.obj.listing.selectors.list_item).show();
};
cols_fn();
}

width = $(window).width();
});

// Close the opened pop-boxes on HTML click
$(document).on("click", "html", function() {
PF.fn.close_pops();
});

/**
* SMALL HELPERS AND THINGS --> "things" que chucha yo en ese tiempo wn
* -------------------------------------------------------------------------------------------------
*/

// Attemp to replace .svg with .png for browsers that doesn't support it
if ($("html").hasClass("no-svg")) {
$("img.replace-svg").replace_svg();
}

// Keydown numeric input (prevents non numeric keys)
$(document).on("keydown", ".numeric-input", function(e) {
e.keydown_numeric();
});

// The handly data-scrollto. IT will scroll the elements to the target
$(document).on("click", "[data-scrollto]", function(e) {
var target = $(this).data("scrollto"),
$target = $(!target.match(/^\#|\./) ? "#" + target : target);

if ($target.exists()) {
PF.fn.scroll($target);
} else {
console.log("PF scrollto error: target doesn't exists", $target);
}
});

$(document).on(
"click focus",
"[data-login-needed], [data-user-logged=must]",
function(e) {
if (!PF.fn.is_user_logged()) {
e.preventDefault();
e.stopPropagation();
window.location.href = PF.obj.vars.urls.login;
return false;
}
}
);

// The handly data-trigger. It will trigger click for elements with data-trigger
$(document).on("click", "[data-trigger]", function(e) {
if (e.isPropagationStopped()) {
return false;
}

var trigger = $(this).data("trigger"),
$target = $(!trigger.match(/^\#|\./) ? "#" + trigger : trigger);

if ($target.exists()) {
e.stopPropagation();
e.preventDefault();
if (!$target.closest(PF.obj.modal.selectors.root).length) {
PF.fn.modal.close();
}
$target.click();
} else {
console.log("PF trigger error: target doesn't exists", $target);
}
});

// Fix the auth_token inputs
$("form[method=post]").each(function() {
if (!$("input[name=auth_token]", this).exists()) {
$(this).append(
$("", {
type: "hidden",
name: "auth_token",
value: PF.obj.config.auth_token
})
);
}
});

// Clear form like magic
$(document).on("click", ".clear-form", function() {
$(this)
.closest("form")[0]
.reset();
});

$(document).on("submit", "form[data-action=validate]", function(e) {
var type = $(this).data("type"),
errors = false,
$validate = $(this).find("[required], [data-validate]");

$validate.each(function() {
var input_type = $(this).attr("type"),
pattern = $(this).attr("pattern"),
errorFn = function(el) {
$(el).highlight();
errors = true;
};

if ($(this).is("[required]") && $(this).val() == "") {
if ($(this).is(":hidden")) {
var $hidden_target = $(
$($(this).data("highlight")).exists()
? $(this).data("highlight")
: "#" + $(this).data("highlight")
);
$($hidden_target).highlight();
}
errorFn(this);
}

if (
typeof pattern == "undefined" &&
/mail|url/.test(input_type) == false
) {
return true;
}

if (pattern) {
pattern = new RegExp(pattern);
if (!pattern.test($(this).val())) {
errorFn(this);
}
}

if (
input_type == "email" &&
!$(this)
.val()
.isEmail()
) {
errorFn(this);
}
});

if (errors) {
PF.fn.growl.expirable(
PF.fn._s("Check the errors in the form to continue.")
);
return false;
}
});

// Co-combo breaker
$(document).on("change", "select[data-combo]", function() {
var $combo = $("#" + $(this).data("combo"));

if ($combo.exists()) {
$combo.children(".switch-combo").hide();
}

var $combo_container = $(
"#" +
$(this)
.closest("select")
.data("combo")
),
$combo_target = $(
"[data-combo-value~=" + $("option:selected", this).attr("value") + "]",
$combo_container
);

if ($combo_target.exists()) {
$combo_target
.show()
.find("[data-required]")
.each(function() {
$(this).attr("required", "required"); // re-enable any disabled required
});
}

// Disable [required] in hidden combos
$(".switch-combo", $combo_container).each(function() {
if ($(this).is(":visible")) return;
$("[required]", this)
.attr("data-required", true)
.removeAttr("required");
});
});

// Y COMO DICE: ESCAPE FROM THE PLANET OF THE APES
$(document).on("keyup", function(e) {
$this = $(e.target);
if (e.keyCode == 27) {
if (
$(PF.obj.modal.selectors.root).is(":visible") &&
!$this.is(":input")
) {
$(
"[data-action=cancel],[data-action=close-modal]",
PF.obj.modal.selectors.root
)
.first()
.click();
}
}
});

// Input events
$(document).on("change", ":input", function(e) {
PF.fn.growl.close();
});
$(document).on("keyup", ":input", function(e) {
$(".input-warning", $(this).closest(".input-label")).html("");
});
$(document).on("blur", ":input", function() {
var this_val = $.trim($(this).prop("value"));
$(this).prop("value", this_val);
});

// Select all on an input type
$(document).on("click", ":input[data-focus=select-all]", function() {
this.select();
});

// Input password strength
$(document).on("keyup change blur", ":input[type=password]", function() {
var password = testPassword($(this).val()),
$parent = $(this).closest("div");

if ($(this).val() == "") {
password.percent = 0;
password.verdict = "";
}

$("[data-content=password-meter-bar]", $parent)
.attr("data-veredict", password.verdict.replace(/ /g, "-"))
.width(password.percent);
$("[data-text=password-meter-message]", $parent)
.removeClass("red-warning")
.text(password.verdict !== "" ? PF.fn._s(password.verdict) : "");
});

// Popup links
$(document).on("click", "[rel=popup-link], .popup-link", function(e) {
e.preventDefault();
var href = $(this)[
typeof $(this).attr("href") !== "undefined" ? "attr" : "data"
]("href");
if (typeof href == "undefined") {
return;
}
if (
href.substring(0, 6) == "mailto" &&
PF.fn.isDevice(["phone", "phablet"])
) {
window.location = href;
return false;
}
PF.fn.popup({ href: href });
});

/**
* FOWLLOW SCROLL
* -------------------------------------------------------------------------------------------------
*/
$(window).scroll(function() {
PF.obj.follow_scroll.process(); // todo:optimize
});

/**
* MODAL
* -------------------------------------------------------------------------------------------------
*/

// Call plain simple HTML modal
$(document).on("click", "[data-modal=simple],[data-modal=html]", function() {
var $target = $(
"[data-modal=" + $(this).data("target") + "], #" + $(this).data("target")
).first();
PF.fn.modal.call({ template: $target.html(), buttons: false });
});

// Prevent modal submit form since we only use the form in the modal to trigger HTML5 validation
$(document).on("submit", PF.obj.modal.selectors.root + " form", function(e) {
if ($(this).data("prevented")) return false; // Don't send the form if is prevented
if (typeof $(this).attr("method") !== "undefined") return; // Don't bind anything extra if is normal form
return false; // Prevent default form handling
});

// Form/editable/confirm modal
$(document).on(
"click",
"[data-modal=edit],[data-modal=form],[data-confirm]",
function(e) {
e.preventDefault();

var $this = $(this);
var $target;

if ($this.is("[data-confirm]")) {
$target = $this;
PF.obj.modal.type = "confirm";
} else {
$target = $(
"[data-modal=" + $this.data("target") + "], #" + $this.data("target")
).first();

if ($target.length == 0) {
$target = $("[data-modal=form-modal], #form-modal").first();
}

if ($target.length == 0) {
console.log("PF Error: Modal target doesn't exists.");
}

PF.obj.modal.type = $this.data("modal");
}

var args = $this.data("args"),
submit_function = window[$target.data("submit-fn")],
cancel_function = window[$target.data("cancel-fn")],
onload_function = window[$target.data("load-fn")],
submit_done_msg = $target.data("submit-done"),
ajax = {
url:
$target.data("ajax-url") ||
(typeof $target.data("is-xhr") !== typeof undefined
? PF.obj.config.json_api
: null),
deferred: window[$target.data("ajax-deferred")]
};

// Window functions failed? Maybe those are named fn...
if (typeof submit_function !== "function" && $target.data("submit-fn")) {
var submit_fn_split = $target.data("submit-fn").split(".");
submit_function = window;
for (var i = 0; i < submit_fn_split.length; i++) {
submit_function = submit_function[submit_fn_split[i]];
}
}
if (typeof cancel_function !== "function" && $target.data("cancel-fn")) {
var cancel_fn_split = $target.data("cancel-fn").split(".");
cancel_function = window;
for (var i = 0; i < cancel_fn_split.length; i++) {
cancel_function = cancel_function[cancel_fn_split[i]];
}
}
if (typeof load_function !== "function" && $target.data("load-fn")) {
var load_fn_split = $target.data("load-fn").split(".");
load_function = window;
for (var i = 0; i < load_fn_split.length; i++) {
load_function = load_function[load_fn_split[i]];
}
}

if (typeof ajax.deferred !== "object" && $target.data("ajax-deferred")) {
var deferred_obj_split = $target.data("ajax-deferred").split(".");
ajax.deferred = window;
for (var i = 0; i < deferred_obj_split.length; i++) {
ajax.deferred = ajax.deferred[deferred_obj_split[i]];
}
}

// Before fn
var fn_before = window[$target.data("before-fn")];
if (typeof fn_before !== "function" && $target.data("before-fn")) {
var before_obj_split = $target.data("before-fn").split(".");
fn_before = window;
for (var i = 0; i < before_obj_split.length; i++) {
fn_before = fn_before[before_obj_split[i]];
}
}
if (typeof fn_before == "function") {
fn_before(e);
}

var inline_options = $(this).data("options") || {};

// Confirm modal
if ($this.is("[data-confirm]")) {
var default_options = {
message: $this.data("confirm"),
confirm:
typeof submit_function == "function" ? submit_function(args) : "",
cancel:
typeof cancel_function == "function" ? cancel_function(args) : "",
ajax: ajax
};

if ($this.attr("href") && default_options.confirm == "") {
default_options.confirm = function() {
return window.location.replace($this.attr("href"));
};
}

PF.fn.modal.confirm($.extend(default_options, inline_options));
} else {
// Form/editable
var default_options = {
template: $target.html(),
button_submit: $(this).is("[data-modal=edit]")
? PF.fn._s("Save changes")
: PF.fn._s("Submit"),
confirm: function() {
var form_modal_has_changed = PF.fn.form_modal_has_changed();

// Conventional form handling
var $form = $("form", PF.obj.modal.selectors.root);
if (typeof $form.attr("action") !== "undefined") {
$form.data("prevented", !form_modal_has_changed);
PF.fn.modal.close();
return;
}

// Handle the required thing for non-visible elements
$(":input[name]", $form).each(function() {
if (!$(this).is(":visible")) {
var input_attr = $(this).attr("required");
if (
typeof input_attr !== typeof undefined &&
input_attr !== false
) {
$(this)
.prop("required", false)
.attr("data-required", "required");
}
} else {
if ($(this).attr("data-required") == "required") {
$(this).prop("required", true);
}
}
});

// Detect HTML5 validation
if (!$form[0].checkValidity()) {
return false;
}

// Run the full function only when the form changes
if (!form_modal_has_changed && !inline_options.forced) {
PF.fn.modal.close();
return;
}

if (typeof submit_function == "function")
submit_fn = submit_function(args);
if (typeof submit_fn !== "undefined" && submit_fn == false) {
return false;
}

$(":input", PF.obj.modal.selectors.root).each(function() {
$(this).val($.trim($(this).val()));
});

if ($this.is("[data-modal=edit]")) {
// Set the input values before cloning the html
$target.html(
$(
PF.obj.modal.selectors.body,
$(PF.obj.modal.selectors.root).bindFormData()
)
.html()
.replace(/rel=[\'"]tooltip[\'"]/g, 'rel="template-tooltip"')
);
}

if (typeof ajax.url !== "undefined") {
return true;
} else {
PF.fn.modal.close(function() {
if (typeof submit_done_msg !== "undefined") {
PF.fn.growl.expirable(
submit_done_msg !== ""
? submit_done_msg
: PF.fn._s("Changes saved successfully.")
);
}
});
}
},
cancel: function() {
if (typeof cancel_fn == "function") cancel_fn = cancel_fn();
if (typeof cancel_fn !== "undefined" && cancel_fn == false) {
return false;
}
// nota: falta template aca
if (
$target.data("prompt") != "skip" &&
PF.fn.form_modal_has_changed()
) {
if ($(PF.obj.modal.selectors.changes_confirm).exists()) return;
$(PF.obj.modal.selectors.box, PF.obj.modal.selectors.root)
.css({ transition: "none" })
.hide();
$(PF.obj.modal.selectors.root).append(
'
'">

' +
PF.fn._s(
"All the changes that you have made will be lost if you continue."
) +
'

' margin-bottom-0"> ' +
PF.fn._s("or") +
' ' +
PF.fn._s("continue anyway") +
"
"
);
$(PF.obj.modal.selectors.changes_confirm)
.css(
"margin-top",
-$(PF.obj.modal.selectors.changes_confirm).outerHeight(true) /
2
)
.hide()
.fadeIn("fast");
} else {
PF.fn.modal.close();
if (window.location.hash == "#edit") window.location.hash = "";
}
},
load: function() {
if (typeof load_function == "function") load_function();
},
callback: function() {},
ajax: ajax
};
PF.fn.modal.call($.extend(default_options, inline_options));
}
}
);

// Check user login modal -> Must be login to continue
if (!PF.fn.is_user_logged()) {
$("[data-login-needed]:input, [data-user-logged=must]:input").each(
function() {
$(this).attr("readonly", true);
}
);
}

// Modal form keydown listener
$(document).on("keydown", PF.obj.modal.selectors.root + " input", function(
e
) {
// nota: solia ser keyup
var $this = $(e.target),
key = e.charCode || e.keyCode;
if (key !== 13) {
PF.fn.growl.close();
return;
}
if (
key == 13 &&
$("[data-action=submit]", PF.obj.modal.selectors.root).exists() &&
!$this.is(".prevent-submit")
) {
// 13 == enter key
$("[data-action=submit]", PF.obj.modal.selectors.root).click();
}
});

// Trigger modal edit on hash #edit
// It must be placed after the event listener
if (window.location.hash && window.location.hash == "#edit") {
$("[data-modal=edit]")
.first()
.click();
}

/**
* MOBILE TOP BAR MENU
* -------------------------------------------------------------------------------------------------
*/
$(document).on("click", "[data-action=top-bar-menu-full]", function() {
var hasClass = $("[data-action=top-bar-menu-full]", "#top-bar").hasClass(
"current"
);
PF.fn.topMenu[hasClass ? "hide" : "show"]();
});

/**
* SEARCH INPUT
* -------------------------------------------------------------------------------------------------
*/

// Top-search feature
$(document).on("click", "[data-action=top-bar-search]", function() {
$("[data-action=top-bar-search-input]", ".top-bar")
.removeClass("hidden")
.show();
$("[data-action=top-bar-search-input]:visible input")
.first()
.focus();
if (
is_ios() &&
!$(this)
.closest(PF.fn.topMenu.vars.menu)
.exists()
) {
$(".top-bar").css("position", "absolute");
}
$("[data-action=top-bar-search]", ".top-bar").hide();
});

// Search icon click -> focus input
$(document).on("click", ".input-search .icon-search", function(e) {
$("input", e.currentTarget.offsetParent).focus();
});

// Clean search input
$(document).on(
"click",
".input-search .icon-close, .input-search [data-action=clear-search]",
function(e) {
var $input = $("input", e.currentTarget.offsetParent);

if ($input.val() == "") {
if (
$(this)
.closest("[data-action=top-bar-search-input]")
.exists()
) {
$("[data-action=top-bar-search-input]", ".top-bar").hide();
$("[data-action=top-bar-search]", ".top-bar")
.removeClass("opened")
.show();
if (
is_ios() &&
$(this)
.closest("#top-bar")
.css("position") !== "fixed"
) {
$(".top-bar").css("position", "fixed");
}
}
} else {
if (
!$(this)
.closest("[data-action=top-bar-search-input]")
.exists()
) {
$(this).hide();
}
$input.val("").change();
}
}
);

// Input search clear search toggle
$(document).on("keyup change", "input.search", function(e) {
var $input = $(this),
$div = $(this).closest(".input-search");
if (
!$(this)
.closest("[data-action=top-bar-search-input]")
.exists()
) {
var todo = $input.val() == "" ? "hide" : "show";
$(".icon-close, [data-action=clear-search]", $div)[todo]();
}
});

/**
* POP BOXES (MENUS)
* -------------------------------------------------------------------------------------------------
*/
$(document)
.on("click mouseenter", ".pop-btn", function(e) {
if (
PF.fn.isDevice(["phone", "phablet"]) &&
(e.type == "mouseenter" || $(this).hasClass("pop-btn-desktop"))
) {
return;
}

var $this_click = $(e.target);
var $pop_btn;
var $pop_box;
var devices = $.makeArray(["phone", "phablet"]);
var $this = $(this);

if (e.type == "mouseenter" && !$(this).hasClass("pop-btn-auto")) return;
if (
$(this).hasClass("disabled") ||
($this_click.closest(".current").exists() &&
!PF.fn.isDevice("phone") &&
!$this_click.closest(".pop-btn-show").exists())
) {
return;
}

PF.fn.growl.close();

e.stopPropagation();

$pop_btn = $(this);
$pop_box = $(".pop-box", $pop_btn);
$pop_btn.addClass("opened");

$(".pop-box-inner", $pop_box).css("max-height", "");

if (PF.fn.isDevice(devices)) {
var text = $(".btn-text,.text,.pop-btn-text", $pop_btn)
.first()
.text();
if (typeof text == "undefined" || text == "") {
text = PF.fn._s("Select");
}
if (!$(".pop-box-header", $pop_box).exists()) {
$pop_box.prepend(
$("
", {
class: "pop-box-header",
html: text + ''
})
);
}
} else {
$(".pop-box-header", $pop_box).remove();
$pop_box.css({ bottom: "" });
}
if (
$pop_box.hasClass("anchor-center") &&
typeof $pop_box.data("guidstr") == typeof undefined
) {
if (!PF.fn.isDevice(devices)) {
$pop_box.css("margin-left", -($pop_box.width() / 2));
} else {
$pop_box.css("margin-left", "");
}
}

// Pop button changer
if ($this_click.is("[data-change]")) {
$("li", $pop_box).removeClass("current");
$this_click.closest("li").addClass("current");
$("[data-text-change]", $pop_btn).text(
$("li.current a", $pop_box).text()
);
e.preventDefault();
}

if (!$pop_box.exists()) return;

// Click inside the bubble only for .pop-keep-click
var $this = e.istriggered ? $(e.target) : $(this);
if (
$pop_box.is(":visible") &&
$(e.target)
.closest(".pop-box-inner")
.exists() &&
$this.hasClass("pop-keep-click")
) {
return;
}

$(".pop-box:visible")
.not($pop_box)
.hide()
.closest(".pop-btn")
.removeClass("opened");

var callback = function($pop_box) {
if (!$pop_box.is(":visible")) {
var guidstr = $pop_box.attr("data-guidstr");
$pop_box
.css("marginLeft", "")
.removeClass(guidstr)
.removeAttr("data-guidstr")
.closest(".pop-btn")
.removeClass("opened");
if (typeof guidstr !== typeof undefined) {
$("style#" + guidstr).remove();
}
} else {
if (!PF.fn.isDevice(devices)) {
var posMargin = $pop_box.css("marginLeft");
if (typeof posMargin !== typeof undefined) {
posMargin = parseFloat(posMargin);
$pop_box.css("marginLeft", "");
}
var cutoff = $pop_box.getWindowCutoff();
if (
cutoff &&
(cutoff.left || cutoff.right) &&
cutoff.right < posMargin
) {
var guidstr = "guid-" + PF.fn.guid();
$pop_box
.css("marginLeft", cutoff.right + "px")
.addClass(guidstr)
.attr("data-guidstr", guidstr);
var posArrow =
$this.outerWidth() / 2 +
$this.offset().left -
$pop_box.offset().left;
var selectors = [];
$.each(["top", "bottom"], function(i, v) {
$.each(["after", "before"], function(ii, vv) {
selectors.push("." + guidstr + ".arrow-box-" + v + ":" + vv);
});
});
$(
'"
).appendTo("head");
} else {
$pop_box.css("marginLeft", posMargin + "px");
}
$(".antiscroll-wrap:not(.jsly):visible", $pop_box)
.addClass("jsly")
.antiscroll();
} else {
$(".antiscroll-inner", $pop_box).height("100%");
}
}
};

if (PF.fn.isDevice(devices)) {
if ($(this).is("[data-action=top-bar-notifications]")) {
$pop_box.css({ height: $(window).height() });
}
var pop_box_h = $pop_box.height() + "px";

var menu_top =
parseInt($(".top-bar").outerHeight()) +
parseInt($(".top-bar").css("top")) +
parseInt($(".top-bar").css("margin-top")) +
parseInt($(".top-bar").css("margin-bottom")) +
"px";

// hide
if ($pop_box.is(":visible")) {
$("#pop-box-mask").css({ opacity: 0 });
$pop_box.css({ transform: "none" });
if ($this.closest(PF.fn.topMenu.vars.menu).exists()) {
$(".top-bar").css({ transform: "none" });
$(PF.fn.topMenu.vars.menu).css({
height: $(window).height() + parseInt(menu_top)
});
}
setTimeout(function() {
$pop_box.hide().attr("style", "");
$("#pop-box-mask").remove();
callback($pop_box);
if ($this.closest(PF.fn.topMenu.vars.menu).exists()) {
$(PF.fn.topMenu.vars.menu).css({
height: ""
});
$(PF.fn.topMenu.vars.menu).animate(
{ scrollTop: PF.fn.topMenu.vars.scrollTop },
PF.obj.config.animation.normal / 2
);
}
}, PF.obj.config.animation.normal);
if (!$("body").data("hasOverflowHidden")) {
$("body").removeClass("overflow-hidden");
}
} else {
// show
$("#pop-box-mask").remove();
$pop_box.parent().prepend(
$("
", {
id: "pop-box-mask",
class: "fullscreen soft-black"
}).css({
zIndex: 400,
display: "block"
})
);
PF.fn.topMenu.vars.scrollTop = $(PF.fn.topMenu.vars.menu).scrollTop();
setTimeout(function() {
$("#pop-box-mask").css({ opacity: 1 });
setTimeout(function() {
$pop_box.show().css({
bottom: "-" + pop_box_h,
maxHeight: $(window).height(),
zIndex: 1000,
transform: "translate(0,0)"
});

setTimeout(function() {
$pop_box.css({ transform: "translate(0,-" + pop_box_h + ")" });
}, 1);

setTimeout(function() {
callback($pop_box);
}, PF.obj.config.animation.normal);

if ($("body").hasClass("overflow-hidden")) {
$("body").data("hasOverflowHidden", 1);
} else {
$("body").addClass("overflow-hidden");
}

if ($this.closest(PF.fn.topMenu.vars.menu).exists()) {
$(".top-bar").css({
transform: "translate(0, -" + menu_top + ")"
});
$(PF.fn.topMenu.vars.menu).css({
height: $(window).height() + parseInt(menu_top)
});
}
$(".pop-box-inner", $pop_box).css(
"height",
$pop_box.height() -
$(".pop-box-header", $pop_box).outerHeight(true)
);
}, 1);
}, 1);
}
} else {
$pop_box[$pop_box.is(":visible") ? "hide" : "show"](0, function() {
callback($pop_box);
});
}
})
.on("mouseleave", ".pop-btn", function() {
if (!PF.fn.isDevice(["laptop", "desktop"])) {
return;
}
var $pop_btn = $(this),
$pop_box = $(".pop-box", $pop_btn);

if (
!$pop_btn.hasClass("pop-btn-auto") ||
(PF.fn.isDevice(["phone", "phablet"]) &&
$pop_btn.hasClass("pop-btn-auto"))
) {
return;
}

if (
!PF.fn.isDevice(["phone", "phablet", "tablet"]) &&
$(this).hasClass("pop-btn-delayed")
) {
$(this).removeClass("pop-btn-auto");
}

$pop_box
.hide()
.closest(".pop-btn")
.removeClass("opened");
});

$(".pop-btn-delayed").delayedAction({
delayedAction: function($element) {
if (PF.fn.isDevice(["phone", "phablet", "tablet"])) return;
var $el = $(".pop-box-inner", $element);
if ($el.is(":hidden")) {
$element.addClass("pop-btn-auto").click();
}
},
hoverTime: 2000
});

/**
* TABS
* -------------------------------------------------------------------------------------------------
*/

// Hash on load (static tabs) changer
if (window.location.hash) {
/*
var $hash_node = $("[href="+ window.location.hash +"]");

if($hash_node.exists()) {
$.each($("[href="+ window.location.hash +"]")[0].attributes, function(){
PF.obj.tabs.hashdata[this.name] = this.value;
});
PF.obj.tabs.hashdata.pushed = "tabs";
History.replaceState({
href: window.location.hash,
"data-tab": $("[href="+ window.location.hash +"]").data("tab"),
pushed: "tabs",
statenum: 0
}, null, null);
}
*/
}

// Stock tab onload data
if ($(".content-tabs").exists() /* && !window.location.hash*/) {
var $tab = $("a", ".content-tabs .current");
History.replaceState(
{
href: $tab.attr("href"),
"data-tab": $tab.data("tab"),
pushed: "tabs",
statenum: 0
},
null,
null
);
}

// Keep scroll position (history.js)
var State = History.getState();
if (typeof State.data == "undefined") {
History.replaceState(
{ scrollTop: 0 },
document.title,
window.location.href
); // Stock initial scroll
}
History.Adapter.bind(window, "popstate", function() {
var State = History.getState();
if (State.data && typeof State.data.scrollTop !== "undefined") {
if ($(window).scrollTop() !== State.data.scrollTop) {
$(window).scrollTop(State.data.scrollTop);
}
}
return;
});

// Toggle tab display
$("a", ".content-tabs").click(function(e) {
if ($(this).data("link") == true) {
$(this).data("tab", false);
}

if (
$(this)
.closest(".current,.disabled")
.exists()
) {
e.preventDefault();
return;
}
if (typeof $(this).data("tab") == "undefined") return;

var dataTab = {};
$.each(this.attributes, function() {
dataTab[this.name] = this.value;
});
dataTab.pushed = "tabs";

// This helps to avoid issues on ?same and ?same#else
/*dataTab.statenum = 0;
console.log({
data: History.getState().data,
state: History.getState().data.statenum
})
if(History.getState().data && typeof History.getState().data.statenum !== "undefined") {
dataTab.statenum = History.getState().data.statenum + 1
}*/

/*if($(this).attr("href") && $(this).attr("href").indexOf("#") === 0) { // to ->#Hash
PF.obj.tabs.hashdata = dataTab;
if(typeof e.originalEvent == "undefined") {
window.location.hash = PF.obj.tabs.hashdata.href.substring(1);
}
} else { // to ->?anything
if($("#" + dataTab["data-tab"]).data("load") != "classic") {
History.pushState(dataTab, document.title, $(this).attr("href"));
e.preventDefault();
}
}
*/
if ($("#" + dataTab["data-tab"]).data("load") != "classic") {
if (window.location.hash) {
var url = window.location.href;
url = url.replace(window.location.hash, "");
}
History.pushState(
dataTab,
document.title,
typeof url !== "undefined" ? url : $(this).attr("href")
);
e.preventDefault();
}

var $tab_menu = $("[data-action=tab-menu]", $(this).closest(".header"));

$tab_menu.find("[data-content=current-tab-label]").text($(this).text());

if ($tab_menu.is(":visible")) {
$tab_menu.click();
}
});

$(document).on("click", "[data-action=tab-menu]", function() {
var $tabs = $(this)
.closest(".header")
.find(".content-tabs"),
visible = $tabs.is(":visible"),
$this = $(this);
if (!visible) {
$tabs.data("classes", $tabs.attr("class"));
$tabs.removeClass(function(index, css) {
return (css.match(/\b\w+-hide/g) || []).join(" ");
});
$tabs.hide();
}
if (!visible) {
$this.removeClass("current");
}
$tabs[visible ? "hide" : "show"]();
if (visible) {
$tabs.css("display", "").addClass($tabs.data("classes"));
$this.addClass("current");
}
});

// On state change bind tab changes
$(window).bind("statechange", function(e) {
PF.fn.growl.close();
var dataTab;
dataTab = History.getState().data;
if (dataTab && dataTab.pushed == "tabs") {
PF.fn.show_tab(dataTab["data-tab"]);
}
});

/**
* LISTING
* -------------------------------------------------------------------------------------------------
*/

// Stock the scroll position on list element click
$(document).on("click", ".list-item a", function(e) {
if ($(this).attr("src") == "") return;
History.replaceState(
{ scrollTop: $(window).scrollTop() },
document.title,
window.location.href
);
});

// Load more (listing +1 page)
$(document).on("click", "[data-action=load-more]", function(e) {
$(this)
.closest(".content-listing-more")
.hide();

if (
!PF.fn.is_listing() ||
$(this)
.closest(PF.obj.listing.selectors.content_listing)
.is(":hidden") ||
$(this)
.closest("#content-listing-template")
.exists() ||
PF.obj.listing.calling
)
return;

PF.fn.listing.queryString.stock_new();

// Seek hack
PF.obj.listing.query_string.seek = $(this).attr("data-seek");

// Page hack
PF.obj.listing.query_string.page = $(
PF.obj.listing.selectors.content_listing_visible
).data("page");
PF.obj.listing.query_string.page++;

// Offset hack
// var offset = $(PF.obj.listing.selectors.content_listing_visible).data("offset");

// if(typeof offset !== "undefined") {
// PF.obj.listing.query_string.offset = offset;
// if(typeof PF.obj.listing.params_hidden == "undefined") {
// PF.obj.listing.params_hidden = {};
// }
// PF.obj.listing.params_hidden.offset = offset;
// } else {
// if(typeof PF.obj.listing.query_string.offset !== "undefined") {
// delete PF.obj.listing.query_string.offset;
// }
// if(PF.obj.listing.params_hidden && typeof PF.obj.listing.params_hidden.offset !== "undefined") {
// delete PF.obj.listing.params_hidden.offset;
// }
// }

PF.fn.listing.ajax();
e.preventDefault();
});

// List found on load html -> Do the columns!
if ($(PF.obj.listing.selectors.list_item).length > 0) {
PF.fn.listing.show();

// Bind the infinte scroll
$(window).scroll(function() {
var $loadMore = $(
PF.obj.listing.selectors.content_listing_load_more,
PF.obj.listing.selectors.content_listing_visible
).find("button[data-action=load-more]");
// console.log($loadMore.length);
if (
$loadMore.length > 0 &&
$(window).scrollTop() + $(window).innerHeight() >
$(document).height() - 300 &&
PF.obj.listing.calling == false
) {
$loadMore.click();
}
});
}

// Multi-selection tools
$(document).on(
"click",
PF.obj.modal.selectors.root + " [data-switch]",
function() {
var $this_modal = $(this).closest(PF.obj.modal.selectors.root);
$("[data-view=switchable]", $this_modal).hide();
$("#" + $(this).attr("data-switch"), $this_modal).show();
}
);

$(document).on("click", "[data-toggle]", function() {
var $target = $("[data-content=" + $(this).data("toggle") + "]");
var show = !$target.is(":visible");
$(this).html($(this).data("html-" + (show ? "on" : "off")));
$target.toggle();
});

// Cookie law thing
$(document).on("click", "[data-action=cookie-law-close]", function() {
var $cookie = $(this).closest("#cookie-law-banner");
var cookieName =
typeof $cookie.data("cookie") !== typeof undefined
? $cookie.data("cookie")
: "PF_COOKIE_LAW_DISPLAY";
Cookies.set(cookieName, 0, { expires: 365 });
$cookie.remove();
});

// One-click input copy
Clipboard = new Clipboard("[data-action=copy]", {
text: function(trigger) {
var $target = $(trigger.getAttribute("data-action-target"));
var text = $target.is(":input") ? $target.val() : $target.text();
return text.trim();
}
});
Clipboard.on("success", function(e) {
var $target = $(e.trigger.getAttribute("data-action-target"));
$target.highlight();
e.clearSelection();
});
});

/**
* PEAFOWL OBJECT
* -------------------------------------------------------------------------------------------------
*/
var PF = { fn: {}, str: {}, obj: {} };

/**
* PEAFOWL CONFIG
* -------------------------------------------------------------------------------------------------
*/
PF.obj.config = {
base_url: "",
json_api: "/json/",
listing: {
items_per_page: 24
},
animation: {
easingFn: "ease",
normal: 400,
fast: 250
}
};

/**
* WINDOW VARS
* -------------------------------------------------------------------------------------------------
*/

/**
* LANGUAGE FUNCTIONS
* -------------------------------------------------------------------------------------------------
*/
PF.obj.l10n = {};

/**
* Get lang string by key
* @argument string (lang key string)
*/
// pf: get_pf_lang
PF.fn._s = function(string, s) {
var string;
if (typeof string == "undefined") {
return string;
}
if (
typeof PF.obj.l10n !== "undefined" &&
typeof PF.obj.l10n[string] !== "undefined"
) {
string = PF.obj.l10n[string][0];
if (typeof string == "undefined") {
string = string;
}
} else {
string = string;
}
string = string.toString();
if (typeof s !== "undefined") {
string = sprintf(string, s);
}
return string;
};

PF.fn._n = function(singular, plural, n) {
var string;
if (
typeof PF.obj.l10n !== "undefined" &&
typeof PF.obj.l10n[singular] !== "undefined"
) {
string = PF.obj.l10n[singular][n == 1 ? 0 : 1];
} else {
string = n == 1 ? singular : plural;
}
string = typeof string == "undefined" ? singular : string.toString();
if (typeof n !== "undefined") {
string = sprintf(string, n);
}
return string;
};

/**
* Extend Peafowl lang
* Useful to add or replace strings
* @argument strings obj
*/
// pf: extend_pf_lang
PF.fn.extend_lang = function(strings) {
$.each(PF.obj.lang_strings, function(i, v) {
if (typeof strings[i] !== "undefined") {
$.extend(PF.obj.lang_strings[i], strings[i]);
}
});
};

/**
* HELPER FUNCTIONS
* -------------------------------------------------------------------------------------------------
*/

PF.fn.get_url_vars = function() {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function(s) {
return decodeURIComponent(escape(s.replace(pl, " ")));
},
query = window.location.search.substring(1),
urlParams = {};

while ((match = search.exec(query))) {
urlParams[decode(match[1])] = decode(match[2]);
}

return urlParams;
};

PF.fn.get_url_var = function(name) {
return PF.fn.get_url_vars()[name];
};

PF.fn.is_user_logged = function() {
return $("#top-bar-user").exists(); // nota: default version
// It should use backend conditional
};

PF.fn.generate_random_string = function(len) {
if (typeof len == "undefined") len = 5;
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < len; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};

PF.fn.getDateTime = function() {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
if (month.toString().length == 1) {
var month = "0" + month;
}
if (day.toString().length == 1) {
var day = "0" + day;
}
if (hour.toString().length == 1) {
var hour = "0" + hour;
}
if (minute.toString().length == 1) {
var minute = "0" + minute;
}
if (second.toString().length == 1) {
var second = "0" + second;
}
var dateTime =
year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
return dateTime;
};

PF.fn.htmlEncode = function(value) {
return $("
")
.text($.trim(value))
.html();
};

PF.fn.htmlDecode = function(value) {
return $("
")
.html($.trim(value))
.text();
};

PF.fn.nl2br = function(str) {
var breakTag = "
";
return (str + "").replace(
/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g,
"$1" + breakTag + "$2"
);
};

// https://raw.githubusercontent.com/johndwells/phpjs/master/functions/info/version_compare.js
PF.fn.versionCompare = function(v1, v2, operator) {
this.php_js = this.php_js || {};
this.php_js.ENV = this.php_js.ENV || {};
// END REDUNDANT
// Important: compare must be initialized at 0.
var i = 0,
x = 0,
compare = 0,
// vm maps textual PHP versions to negatives so they're less than 0.
// PHP currently defines these as CASE-SENSITIVE. It is important to
// leave these as negatives so that they can come before numerical versions
// and as if no letters were there to begin with.
// (1alpha is < 1 and < 1.1 but > 1dev1)
// If a non-numerical value can't be mapped to this table, it receives
// -7 as its value.
vm = {
dev: -6,
alpha: -5,
a: -5,
beta: -4,
b: -4,
RC: -3,
rc: -3,
"#": -2,
p: 1,
pl: 1
},
// This function will be called to prepare each version argument.
// It replaces every _, -, and + with a dot.
// It surrounds any nonsequence of numbers/dots with dots.
// It replaces sequences of dots with a single dot.
// version_compare('4..0', '4.0') == 0
// Important: A string of 0 length needs to be converted into a value
// even less than an unexisting value in vm (-7), hence [-8].
// It's also important to not strip spaces because of this.
// version_compare('', ' ') == 1
prepVersion = function(v) {
v = ("" + v).replace(/[_\-+]/g, ".");
v = v.replace(/([^.\d]+)/g, ".$1.").replace(/\.{2,}/g, ".");
return !v.length ? [-8] : v.split(".");
};
// This converts a version component to a number.
// Empty component becomes 0.
// Non-numerical component becomes a negative number.
// Numerical component becomes itself as an integer.
numVersion = function(v) {
return !v ? 0 : isNaN(v) ? vm[v] || -7 : parseInt(v, 10);
};
v1 = prepVersion(v1);
v2 = prepVersion(v2);
x = Math.max(v1.length, v2.length);
for (i = 0; i < x; i++) {
if (v1[i] == v2[i]) {
continue;
}
v1[i] = numVersion(v1[i]);
v2[i] = numVersion(v2[i]);
if (v1[i] < v2[i]) {
compare = -1;
break;
} else if (v1[i] > v2[i]) {
compare = 1;
break;
}
}
if (!operator) {
return compare;
}

// Important: operator is CASE-SENSITIVE.
// "No operator" seems to be treated as "<."
// Any other values seem to make the function return null.
switch (operator) {
case ">":
case "gt":
return compare > 0;
case ">=":
case "ge":
return compare >= 0;
case "<=":
case "le":
return compare <= 0;
case "==":
case "=":
case "eq":
return compare === 0;
case "<>":
case "!=":
case "ne":
return compare !== 0;
case "":
case "<":
case "lt":
return compare < 0;
default:
return null;
}
};

/**
* Basename
* http://stackoverflow.com/questions/3820381/need-a-basename-function-in-javascript
*/
PF.fn.baseName = function(str) {
var base = new String(str).substring(str.lastIndexOf("/") + 1);
if (base.lastIndexOf(".") != -1) {
base = base.substring(0, base.lastIndexOf("."));
}
return base;
};

// https://stackoverflow.com/a/8809472
PF.fn.guid = function() {
var d = new Date().getTime();
if (
typeof performance !== "undefined" &&
typeof performance.now === "function"
) {
d += performance.now(); //use high-precision timer if available
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
});
};

PF.fn.md5 = function(string) {
return SparkMD5.hash(string);
};

/**
* dataURI to BLOB
* http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
*/
PF.fn.dataURItoBlob = function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(",")[0].indexOf("base64") >= 0) {
byteString = atob(dataURI.split(",")[1]);
} else {
byteString = unescape(dataURI.split(",")[1]);
}
// separate out the mime component
var mimeString = dataURI
.split(",")[0]
.split(":")[1]
.split(";")[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mimeString });
};

PF.fn.clean_facebook_hash = function() {
if (window.location.hash == "#_=_") {
window.location.hash = "";
}
};
PF.fn.clean_facebook_hash();

/**
* Get the min and max value from 1D array
*/
Array.min = function(array) {
return Math.min.apply(Math, array);
};
Array.max = function(array) {
return Math.max.apply(Math, array);
};

/**
* Return the sum of all the values in a 1D array
*/
Array.sum = function(array) {
return array.reduce(function(pv, cv) {
return cv + pv;
});
};

/**
* Return the size of an object
*/
Object.size = function(obj) {
var size = 0,
key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};

/**
* Flatten an object
*/
Object.flatten = function(obj, prefix) {
if (typeof prefix == "undefined") var prefix = "";

var result = {};

$.each(obj, function(key, value) {
if (!value) return;
if (typeof value == "object") {
result = $.extend({}, result, Object.flatten(value, prefix + key + "_"));
} else {
result[prefix + key] = value;
}
});

return result;
};

/**
* Tells if the string is a number or not
*/
String.prototype.isNumeric = function() {
return !isNaN(parseFloat(this)) && isFinite(this);
};

/**
* Repeats an string
*/
String.prototype.repeat = function(num) {
return new Array(num + 1).join(this);
};

/**
* Ucfirst
*/
String.prototype.capitalizeFirstLetter = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};

/**
* Replace all
*/
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, "g"), replacement);
};

/**
* Tells if the string is a email or not
*/
String.prototype.isEmail = function() {
var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(this);
};

// http://phpjs.org/functions/round/
String.prototype.getRounded = function(precision, mode) {
var m, f, isHalf, sgn; // helper variables
precision |= 0; // making sure precision is integer
m = Math.pow(10, precision);
value = this;
value *= m;
sgn = (value > 0) | -(value < 0); // sign of the number
isHalf = value % 1 === 0.5 * sgn;
f = Math.floor(value);

if (isHalf) {
switch (mode) {
case "PHP_ROUND_HALF_DOWN":
value = f + (sgn < 0); // rounds .5 toward zero
break;
case "PHP_ROUND_HALF_EVEN":
value = f + (f % 2) * sgn; // rouds .5 towards the next even integer
break;
case "PHP_ROUND_HALF_ODD":
value = f + !(f % 2); // rounds .5 towards the next odd integer
break;
default:
value = f + (sgn > 0); // rounds .5 away from zero
}
}

return (isHalf ? value : Math.round(value)) / m;
};

/**
* Return bytes from Size + Suffix like "10 MB"
*/
String.prototype.getBytes = function() {
var units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
suffix = this.toUpperCase().substr(-2);
if (units.indexOf(suffix) == -1) {
return this;
}
var pow_factor = units.indexOf(suffix) + 1;
return parseFloat(this) * Math.pow(1000, pow_factor);
};

/**
* Return size formatted from size bytes
*/
String.prototype.formatBytes = function(round) {
var bytes = parseInt(this),
units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
if (!$.isNumeric(this)) {
return false;
}
if (bytes < 1000) return bytes + " B";
if (typeof round == "undefined") var round = 2;
for (var i = 0; i < units.length; i++) {
var multiplier = Math.pow(1000, i + 1),
threshold = multiplier * 1000;
if (bytes < threshold) {
var size = bytes / multiplier;
return this.getRounded.call(size, round) + " " + units[i];
}
}
};

/**
* Returns the image url.matches (multiple)
*/
String.prototype.match_image_urls = function() {
return this.match(
/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\.(?:jpe?g|gif|png|bmp)\b/gim
);
};

String.prototype.match_urls = function() {
return this.match(
/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\b/gim
);
};

// Add ECMA262-5 Array methods if not supported natively
if (!("indexOf" in Array.prototype)) {
Array.prototype.indexOf = function(find, i /*opt*/) {
if (i === undefined) i = 0;
if (i < 0) i += this.length;
if (i < 0) i = 0;
for (var n = this.length; i < n; i++) {
if (i in this && this[i] === find) {
return i;
}
}
return -1;
};
}

/**
* Removes all the array duplicates without loosing the array order.
*/
Array.prototype.array_unique = function() {
var result = [];
$.each(this, function(i, e) {
if ($.inArray(e, result) == -1) result.push(e);
});
return result;
};

PF.fn.deparam = function(querystring) {
if (typeof querystring == "undefined" || !querystring) return;
// Get rid of the URL part
var querystring = querystring.substring(querystring.indexOf("?") + 1);
var obj = {},
pairs = querystring
.replace(/^[\?|&]*/, "")
.replace(/[&|\?]*$/, "")
.split("&");
for (var i = 0; i < pairs.length; i++) {
var split = pairs[i].split("=");
var key = decodeURIComponent(split[0]);
var value = split[1] ? decodeURIComponent(split[1]) : null;
// Aready in the object?
if (obj.hasOwnProperty(key) && !value) {
continue;
}
obj[key] = value;
}
return obj;
};

// http://stackoverflow.com/a/1634841/1145912
String.prototype.removeURLParameter = function(key) {
var url = "",
deparam = PF.fn.deparam(this);
if (typeof deparam[key] !== "undefined") {
delete deparam[key];
}
return decodeURIComponent($.param(deparam));
};

String.prototype.changeURLParameterValue = function(key, value) {
var base = this.substring(0, this.indexOf("?"));
var res = "";
var deparam = PF.fn.deparam(this);
if (typeof deparam[key] !== "undefined") {
deparam[key] = value;
}
return base + "?" + decodeURIComponent($.param(deparam));
};

/**
* Truncate the middle of the URL just like Firebug
* From http://stackoverflow.com/questions/10903002/shorten-url-for-display-with-beginning-and-end-preserved-firebug-net-panel-st
*/
String.prototype.truncate_middle = function(l) {
var l = typeof l != "undefined" ? l : 40,
chunk_l = l / 2,
url = this.replace(/https?:\/\//g, "");

if (url.length <= l) {
return url;
}

function shortString(s, l, reverse) {
var stop_chars = [" ", "/", "&"],
acceptable_shortness = l * 0.8, // When to start looking for stop characters
reverse = typeof reverse != "undefined" ? reverse : false,
s = reverse
? s
.split("")
.reverse()
.join("")
: s,
short_s = "";

for (var i = 0; i < l - 1; i++) {
short_s += s[i];
if (i >= acceptable_shortness && stop_chars.indexOf(s[i]) >= 0) {
break;
}
}
if (reverse) {
return short_s
.split("")
.reverse()
.join("");
}
return short_s;
}

return (
shortString(url, chunk_l, false) + "..." + shortString(url, chunk_l, true)
);
};

/**
* Compare 2 arrays/objects
* http://stackoverflow.com/questions/1773069/using-jquery-to-compare-two-arrays
*/
jQuery.extend({
compare: function(a, b) {
var obj_str = "[object Object]",
arr_str = "[object Array]",
a_type = Object.prototype.toString.apply(a),
b_type = Object.prototype.toString.apply(b);
if (a_type !== b_type) {
return false;
} else if (a_type === obj_str) {
return $.compareObject(a, b);
} else if (a_type === arr_str) {
return $.compareArray(a, b);
}
return a === b;
},
compareArray: function(arrayA, arrayB) {
var a, b, i, a_type, b_type;
if (arrayA === arrayB) {
return true;
}
if (arrayA.length != arrayB.length) {
return false;
}
a = jQuery.extend(true, [], arrayA);
b = jQuery.extend(true, [], arrayB);
a.sort();
b.sort();
for (i = 0, l = a.length; i < l; i += 1) {
a_type = Object.prototype.toString.apply(a[i]);
b_type = Object.prototype.toString.apply(b[i]);
if (a_type !== b_type) {
return false;
}
if ($.compare(a[i], b[i]) === false) {
return false;
}
}
return true;
},
compareObject: function(objA, objB) {
var i, a_type, b_type;
// Compare if they are references to each other
if (objA === objB) {
return true;
}
if (Object.keys(objA).length !== Object.keys(objB).length) {
return false;
}
for (i in objA) {
if (objA.hasOwnProperty(i)) {
if (typeof objB[i] === "undefined") {
return false;
} else {
a_type = Object.prototype.toString.apply(objA[i]);
b_type = Object.prototype.toString.apply(objB[i]);
if (a_type !== b_type) {
return false;
}
}
}
if ($.compare(objA[i], objB[i]) === false) {
return false;
}
}
return true;
}
});

/**
* Tells if a selector exits in the dom
*/
jQuery.fn.exists = function() {
return this.length > 0;
};

/**
* Replace .svg for .png
*/
jQuery.fn.replace_svg = function() {
if (!this.attr("src")) return;
$(this).each(function() {
$(this).attr(
"src",
$(this)
.attr("src")
.replace(".svg", ".png")
);
});
};

/**
* Detect fluid layout
* nota: deberia ir en PF
*/
jQuery.fn.is_fluid = function() {
return true;
};

/**
* jQueryfy the form data
* Bind the attributes and values of form data to be manipulated by DOM fn
*/
jQuery.fn.bindFormData = function() {
$(":input", this).each(function() {
var safeVal = PF.fn.htmlEncode($(this).val());

if ($(this).is("input")) {
this.setAttribute("value", this.value);
if (this.checked) {
this.setAttribute("checked", "checked");
} else {
this.removeAttribute("checked");
}
}
if ($(this).is("textarea")) {
$(this).html(safeVal);
}
if ($(this).is("select")) {
var index = this.selectedIndex,
i = 0;
$(this)
.children("option")
.each(function() {
if (i++ != index) {
this.removeAttribute("selected");
} else {
this.setAttribute("selected", "selected");
}
});
}
});
return this;
};

/** jQuery.formValues: get or set all of the name/value pairs from child input controls
* @argument data {array} If included, will populate all child controls.
* @returns element if data was provided, or array of values if not
* http://stackoverflow.com/questions/1489486/jquery-plugin-to-serialize-a-form-and-also-restore-populate-the-form
*/
jQuery.fn.formValues = function(data) {
var els = $(":input", this);
if (typeof data != "object") {
data = {};
$.each(els, function() {
if (
this.name &&
!this.disabled &&
(this.checked ||
/select|textarea/i.test(this.nodeName) ||
/color|date|datetime|datetime-local|email|month|range|search|tel|time|url|week|text|number|hidden|password/i.test(
this.type
))
) {
if (this.name.match(/^.*\[\]$/) && this.checked) {
if (typeof data[this.name] == "undefined") {
data[this.name] = [];
}
data[this.name].push($(this).val());
} else {
data[this.name] = $(this).val();
}
}
});
return data;
} else {
$.each(els, function() {
if (this.name.match(/^.*\[\]$/) && typeof data[this.name] == "object") {
$(this).prop("checked", data[this.name].indexOf($(this).val()) !== -1);
} else {
if (this.name && data[this.name]) {
if (/checkbox|radio/i.test(this.type)) {
$(this).prop("checked", data[this.name] == $(this).val());
} else {
$(this).val(data[this.name]);
}
} else if (/checkbox|radio/i.test(this.type)) {
$(this).removeProp("checked");
}
}
});
return $(this);
}
};

jQuery.fn.storeformData = function(dataname) {
if (
typeof dataname == "undefined" &&
typeof $(this).attr("id") !== "undefined"
) {
dataname = $(this).attr("id");
}
if (typeof dataname !== "undefined")
$(this).data(dataname, $(this).formValues());
return this;
};

/**
* Compare the $.data values against the current DOM values
* It relies in using $.data to store the previous value
* Data must be stored using $.formValues()
*
* @argument dataname string name for the data key
*/
jQuery.fn.is_sameformData = function(dataname) {
var $this = $(this);
if (typeof dataname == "undefined") dataname = $this.attr("id");
return jQuery.compare($this.formValues(), $this.data(dataname));
};

/**
* Prevent non-numeric keydown
* Allows only numeric keys to be entered on the target event
*/
jQuery.Event.prototype.keydown_numeric = function() {
var e = this;

if (e.shiftKey) {
e.preventDefault();
return false;
}

var key = e.charCode || e.keyCode,
target = e.target,
value = $(target).val() == "" ? 0 : parseInt($(target).val());

if (key == 13) {
// Allow enter key
return true;
}

if (
key == 46 ||
key == 8 ||
key == 9 ||
key == 27 ||
// Allow: Ctrl+A
(key == 65 && e.ctrlKey === true) ||
// Allow: home, end, left, right
(key >= 35 && key <= 40)
) {
// let it happen, don't do anything
return true;
} else {
// Ensure that it is a number and stop the keypress
if ((key < 48 || key > 57) && (key < 96 || key > 105)) {
e.preventDefault();
}
}
};

/**
* Detect canvas support
*/
PF.fn.is_canvas_supported = function() {
var elem = document.createElement("canvas");
return !!(elem.getContext && elem.getContext("2d"));
};

/**
* Detect validity support
*/
PF.fn.is_validity_supported = function() {
var i = document.createElement("input");
return typeof i.validity === "object";
};

PF.fn.getScrollBarWidth = function() {
var inner = document.createElement("p");
inner.style.width = "100%";
inner.style.height = "200px";

var outer = document.createElement("div");
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);

document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = "scroll";
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;

document.body.removeChild(outer);

return w1 - w2;
};

PF.str.ScrollBarWidth = PF.fn.getScrollBarWidth();

/**
* Updates the notifications button
*/
PF.fn.top_notifications_viewed = function() {
var $top_bar_notifications = $("[data-action=top-bar-notifications]"),
$notifications_lists = $(
".top-bar-notifications-list",
$top_bar_notifications
),
$notifications_count = $(".top-btn-number", $top_bar_notifications);

if ($(".persistent", $top_bar_notifications).exists()) {
$notifications_count
.text($(".persistent", $top_bar_notifications).length)
.addClass("on");
} else {
$notifications_count.removeClass("on");
}
};

/**
* bind tipTip for the $target with options
* @argument $target selector or jQuery obj
* @argument options obj
*/
PF.fn.bindtipTip = function($target, options) {
if (typeof $target == "undefined") $target = $("body");
if ($target instanceof jQuery == false) $target = $($target);
var bindtipTipoptions = {
delay: 0,
content: false,
fadeIn: 0
};
if (typeof options !== "undefined") {
if (typeof options.delay !== "undefined")
bindtipTipoptions.delay = options.delay;
if (typeof options.content !== "undefined")
bindtipTipoptions.content = options.content;
if (typeof options.content !== "undefined")
bindtipTipoptions.fadeIn = options.fadeIn;
}
if ($target.attr("rel") !== "tooltip") $target = $("[rel=tooltip]", $target);

$target.each(function() {
if (
(typeof $(this).attr("href") !== "undefined" ||
typeof $(this).data("href") !== "undefined") &&
PF.fn.isDevice(["phone", "phablet", "tablet"])
) {
return true;
}
var position =
typeof $(this).data("tiptip") == "undefined"
? "bottom"
: $(this).data("tiptip");
if (PF.fn.isDevice(["phone", "phablet"])) {
position = "top";
}
$(this).tipTip({
delay: bindtipTipoptions.delay,
defaultPosition: position,
content: bindtipTipoptions.content,
fadeIn: bindtipTipoptions.fadeIn,
fadeOut: 0
});
});
};

/**
* form modal changed
* Detects if the form modal (fullscreen) has changed or not
* Note: It relies in that you save a serialized data to the
*/
PF.fn.form_modal_has_changed = function() {
if ($(PF.obj.modal.selectors.root).is(":hidden")) return;
if (typeof $("html").data("modal-form-values") == typeof undefined) return;

var data_stored = $("html").data("modal-form-values");
var data_modal = PF.fn.deparam(
$(":input:visible", PF.obj.modal.selectors.root).serialize()
);
var has_changed = false;
var keys = $.extend({}, data_stored, data_modal);

for (var k in keys) {
if (data_stored[k] !== data_modal[k]) {
has_changed = true;
break;
}
}

return has_changed;
};

/**
* PEAFOWL CONDITIONALS
* -------------------------------------------------------------------------------------------------
*/

PF.fn.is_listing = function() {
return $(PF.obj.listing.selectors.content_listing).exists();
};

PF.fn.is_tabs = function() {
return $(".content-tabs").exists();
};

/**
* PEAFOWL EFFECTS
* -------------------------------------------------------------------------------------------------
*/

/**
* Shake effect
* Shakes the element using CSS animations.
* @argument callback fn
*/
jQuery.fn.shake = function(callback) {
this.each(function(init) {
var jqNode = $(this),
jqNode_position = jqNode.css("position");

if (!jqNode_position.match("relative|absolute|fixed"))
jqNode.css({ position: "relative" });

var jqNode_left = parseInt(jqNode.css("left"));

if (!jqNode_left.toString().isNumeric()) jqNode_left = 0;

if (!jqNode.is(":animated")) {
for (var x = 1; x <= 2; x++) {
jqNode
.animate(
{
left: jqNode_left - 10
},
0
)
.animate(
{
left: jqNode_left
},
30
)
.animate(
{
left: jqNode_left + 10
},
30
)
.animate(
{
left: jqNode_left
},
30
);
}
if (jqNode_position !== "static")
jqNode.css({ position: jqNode_position });
}
});
if (typeof callback == "function") callback();
return this;
};

/**
* Highlight effect
* Changes the background of the element to a highlight color and revert to original
* @argument string (yellow|red|hex-color)
*/
jQuery.fn.highlight = function(color) {
if (this.is(":animated") || !this.exists()) return this;
if (typeof color == "undefined") color = "yellow";

var fadecolor = color;

switch (color) {
case "yellow":
fadecolor = "#FFFBA2";
break;
case "red":
fadecolor = "#FF7F7F";
break;
default:
fadecolor = color;
break;
}
var base_background_color = $(this).css("background-color"),
base_background = $(this).css("background");

$(this)
.css({ background: "", backgroundColor: fadecolor })
.animate({ backgroundColor: base_background_color }, 800, function() {
$(this).css("background", "");
});
return this;
};

/**
* Peafowl slidedown effect
* Bring the element using slideDown-type effect
* @argument speed (fast|normal|slow|int)
* @argument callback fn
*/
jQuery.fn.pf_slideDown = function(speed, callback) {
var default_speed = "normal",
this_length = $(this).length,
css_prechanges,
css_animation,
animation_speed;

if (typeof speed == "function") {
callback = speed;
speed = default_speed;
}
if (typeof speed == "undefined") {
speed = default_speed;
}

$(this).each(function(index) {
var this_css_top = parseInt($(this).css("top")),
to_top = this_css_top > 0 ? this_css_top : 0;

if (speed == 0) {
(css_prechanges = { display: "block", opacity: 0 }),
(css_animation = { opacity: 1 }),
(animation_speed = jQuery.speed("fast").duration);
} else {
css_prechanges = {
top: -$(this).outerHeight(true),
opacity: 1,
display: "block"
};
css_animation = { top: to_top };
animation_speed = jQuery.speed(speed).duration;
}

$(this).data("originalTop", $(this).css("top"));
$(this)
.css(css_prechanges)
.animate(css_animation, animation_speed, function() {
if (index == this_length - 1) {
if (typeof callback == "function") {
callback();
}
}
});
});

return this;
};

/**
* Peafowl slideUp effect
* Move the element using slideUp-type effect
* @argument speed (fast|normal|slow|int)
* @argument callback fn
*/
jQuery.fn.pf_slideUp = function(speed, callback) {
var default_speed = "normal",
this_length = $(this).length;

if (typeof speed == "function") {
callback = speed;
speed = default_speed;
}
if (typeof speed == "undefined") {
speed = default_speed;
}

$(this).each(function(index) {
$(this).animate(
{ top: -$(this).outerHeight(true) },
jQuery.speed(speed).duration,
function() {
$(this).css({ display: "none", top: $(this).data("originalTop") });
if (index == this_length - 1) {
if (typeof callback == "function") {
callback();
}
}
}
);
});

return this;
};

/**
* Peafowl visible on viewport
*/
jQuery.fn.is_in_viewport = function() {
var rect = $(this)[0].getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight ||
document.documentElement.clientHeight) /*or $(window).height() */ &&
rect.right <=
(window.innerWidth ||
document.documentElement.clientWidth) /*or $(window).width() */
);
};

/**
* Visible on current window stuff
*/
jQuery.fn.getWindowCutoff = function() {
var rect = {
top: $(this).offset().top,
left: $(this).offset().left,
width: $(this).outerWidth(),
height: $(this).outerHeight()
};
rect.right = rect.left + rect.width;
rect.bottom = rect.top + rect.height;
var detected = false;
var cutoff = {
top: rect.top > 0 ? 0 : rect.top,
right: document.body.clientWidth - rect.right,
bottom: document.body.clientHeight - rect.bottom,
left: rect.left > 0 ? 0 : rect.left
};
for (var key in cutoff) {
if (cutoff[key] < 0) {
detected = true;
} else {
cutoff[key] = 0;
}
}
if (!detected) return null;
return cutoff;
};

/**
* Scroll the window to the target.
* @argument target selector
* @argument callback fn
*/
PF.fn.scroll = function(target, callback) {
if (typeof target == "function") {
var callback = target,
target = "";
}

var pxtop = parseInt($("body").css("margin-top"));
if (pxtop == 0 && $(".top-bar-placeholder").exists()) {
pxtop = $(".top-bar-placeholder").height();
}

if (!$(target).exists()) target = "html";
$("body,html").animate(
{ scrollTop: $(target).offset().top - pxtop },
"normal",
function() {
if (typeof callback == "function") callback();
}
);
};

PF.fn.close_pops = function(e) {
$(".pop-box:visible").each(function() {
$(this)
.closest(".pop-btn")
.click();
});
};

/**
* Bring up a nice growl-like alert
*/
PF.fn.growl = {
selectors: {
root: "#growl"
},

str: {
timeout: null,
timeoutcall: false
},

/**
* Fires the growl
* @argument options object
*/
call: function(options) {
if (typeof options == "undefined") return;
if (typeof options == "string") {
options = { message: options };
}
if (typeof options.message == "undefined") return;

var growl_options, $growl, growl_class, growl_color;

growl_options = {
message: options.message,
insertTo: "body",
where: "before",
color: "default",
css: {},
classes: "",
expires: 0,
callback: function() {}
};

for (key in growl_options) {
if (typeof options[key] !== "undefined") {
if (key.match("/^(callback)$/")) {
if (typeof options[key] == "function") {
growl_options[key] = options[key];
}
} else {
growl_options[key] = options[key];
}
}
}

if (!$(growl_options.insertTo).exists()) {
growl_options.insertTo = "body";
}

if ($(PF.fn.growl.selectors.root).exists()) {
if ($(PF.fn.growl.selectors.root).text() == growl_options.message) {
$(PF.fn.growl.selectors.root).shake();
return;
}
$(PF.fn.growl.selectors.root).remove();
}

$growl = $(
'
'" class="growl">' +
growl_options.message +
'
'
)
.css(growl_options.css)
.addClass(growl_options.classes);

growl_class = growl_options.insertTo !== "body" ? "static" : "";

switch (growl_options.color) {
case "dark":
growl_color = "dark";
break;
default:
growl_color = "";
break;
}

$growl.addClass(growl_class + " " + growl_color);

if (growl_options.where == "before") {
$(growl_options.insertTo).prepend($growl.hide());
} else {
$(growl_options.insertTo).append($growl.hide());
}

if ($(".fullscreen").is(":visible")) {
$growl.css({ "z-index": parseInt($(".fullscreen").css("z-index")) + 1 });
}

if ($(PF.obj.modal.selectors.root).is(":visible")) {
var $modal_box = $(
PF.obj.modal.selectors.box,
PF.obj.modal.selectors.root
);
$growl.show();
$growl.css(
"top",
($("#top-bar").outerHeight(true) - $growl.outerHeight(true)) / 2
);

PF.fn.growl.fixPosition();

$growl.hide();
}

$growl.pf_slideDown(growl_class == "static" ? 0 : 200, function() {
if (typeof growl_options.callback == "function") {
growl_options.callback();
}
});

$(document).on("click", ".growl", function(e) {
if (
PF.fn.isDevice(["phone", "phablet"]) ||
$(e.target).is("[data-action=close]")
) {
PF.fn.growl.close(true);
}
});

if (growl_options.expires > 0) {
if (typeof this.str.timeout == "number") {
clearTimeout(this.str.timeout);
}
this.str.timeout = setTimeout(function() {
PF.fn.growl.str.timeoutcall = true;
PF.fn.growl.close();
}, growl_options.expires);
}

console.log(growl_options.message);
},

/**
* Fires an expirable growl (will close after time)
* @argument msg string
* @argument time int (ms)
*/
expirable: function(msg, time) {
if (typeof msg == "undefined") return;
if (typeof time == "undefined") time = 5000;
PF.fn.growl.call({ message: msg, expires: time });
},

/**
* Closes the growl
* @argument callback fn
*/
close: function(forced, callback) {
var $growl = $(PF.fn.growl.selectors.root);

if (forced) {
this.str.timeout = null;
this.str.timeoutcall = false;
clearTimeout(this.str.timeout);
}

if (
!$growl.exists() ||
(typeof this.str.timeout == "number" && !this.str.timeoutcall)
) {
return;
}

$growl.fadeOut("fast", function() {
$(this).remove();
if (typeof callback == "function") {
callback();
}
});
},

fixPosition: function() {
var $growl = $(PF.fn.growl.selectors.root);

if (!$growl.exists() || !$(PF.obj.modal.selectors.root).exists()) {
return;
}

if (
$growl.data("fixedPosition") == "scrollbar" &&
$(PF.obj.modal.selectors.root).hasScrollBar().vertical
) {
return;
}

var offsetX = {
modal: $(PF.obj.modal.selectors.box).offset().left,
growl: $growl.offset().left
},
growlCompensate = offsetX.modal - offsetX.growl,
marginLeft =
growlCompensate < 0
? "-=" + Math.abs(growlCompensate)
: "-" + parseInt($growl.css("width")) / 2;

if (!PF.fn.isDevice(["phone", "phablet"])) {
$growl.css("marginLeft", marginLeft + "px");
}

$growl.data(
"fixedPosition",
$(PF.obj.modal.selectors.root).hasScrollBar().vertical
? "scrollbar"
: "no-scrollbar"
);
}
};

/**
* Bring up a nice fullscreen modal
*/
PF.obj.modal = {
type: "",
selectors: {
root: "#fullscreen-modal",
box: "#fullscreen-modal-box",
body: "#fullscreen-modal-body",
login: "[data-modal=login]",
changes_confirm: "#fullscreen-changes-confirm",
btn_container: ".btn-container",
close_buttons:
".close-modal,.cancel-modal,[data-action=cancel],[data-action-close]",
submit_button: "[data-action=submit]",
growl_placeholder: "#fullscreen-growl-placeholder"
},
ajax: {
url: "",
deferred: {}
},
locked: false,
form_data: {},
XHR: {},
prevented: false
};
PF.obj.modal.$close_buttons = $(
PF.obj.modal.selectors.close_buttons,
PF.obj.modal.selectors.root
);
PF.obj.modal.$submit_button = $(
PF.obj.modal.selectors.submit_button,
PF.obj.modal.selectors.root
);

PF.fn.modal = {
str: {
transition: "all " + PF.obj.config.animation.fast + "ms ease"
},

/**
* Fires the modal
* @argument options object
*/
call: function(options) {
var modal_options, modal_base_template, modal_message;

if (typeof options == "undefined") return;
if (
typeof options.template !== "undefined" &&
typeof options.type == "undefined"
)
options.type = "html";
if (
(typeof options.title == "undefined" ||
typeof options.message == "undefined") &&
(options.type !== "login" && options.type !== "html")
)
return;

PF.fn.growl.close();

modal_options = {
forced: false,
type: "confirm",
title: options.title,
message: options.message,
html: false,
template: options.template,
buttons: true,
button_submit: PF.fn._s("Submit"),
txt_or: PF.fn._s("or"),
button_cancel: PF.fn._s("cancel"),
ajax: { url: null, data: null, deferred: {} },
confirm: function() {},
cancel: function() {
PF.fn.modal.close();
},
load: function() {},
callback: function() {}
};

for (key in modal_options) {
if (typeof options[key] !== "undefined") {
if (/^cancel|confirm|callback$/.test(key)) {
if (typeof options[key] == "function") {
modal_options[key] = options[key];
}
} else {
modal_options[key] = options[key];
}
}
}

if (
typeof options.ajax !== "undefined" &&
!options.ajax.url &&
options.ajax.deferred
) {
modal_options.ajax.url = PF.obj.config.json_api;
}

if (modal_options.type == "login") {
modal_options.buttons = false;
}

if (modal_options.type == "confirm") {
modal_options.button_submit = PF.fn._s("Confirm");
}

var overlay_background = "soft-black";
if ($("html").hasClass("tone-dark")) {
overlay_background = "black";
}

var modal_base_template = [
'
'"class="fullscreen ' + overlay_background + '">
'"class="clickable">
'">%MODAL_BODY%
%MODAL_BUTTONS%
'
].join("");

var modal_buttons = modal_options.buttons
? [
'
'"> ',
modal_options.txt_or,
'',
modal_options.button_cancel,
"
"
].join("")
: "";

if (modal_options.type == "login") {
modal_options.template =
typeof modal_options.template == "undefined"
? $(PF.obj.modal.selectors.login).html()
: modal_options.template;
}

var modalBodyHTML;

switch (modal_options.type) {
case "html":
case "login":
modalBodyHTML = modal_options.template;
break;
case "confirm":
default:
modal_message = modal_options.message;
if (!modal_options.html) {
modal_message = "

" + modal_message + "

";
}
modalBodyHTML = "

" + modal_options.title + "

" + modal_message;
break;
}

if (typeof modalBodyHTML == "undefined") {
console.log("PF Error: Modal content is empty");
return;
}

modal_base_template = modal_base_template
.replace("%MODAL_BODY%", modalBodyHTML)
.replace("%MODAL_BUTTONS%", modal_buttons)
.replace(/template-tooltip/g, "tooltip");

$(PF.obj.modal.selectors.root).remove();

$("body").data("overflow-hidden", $("body").hasClass("overflow-hidden"));
$("body")
.prepend(modal_base_template)
.addClass("overflow-hidden");

this.fixScrollbars();

$("[rel=tooltip]", PF.obj.modal.selectors.root).each(function() {
PF.fn.bindtipTip(this, { content: $(this).data("title") });
});

if (
$(
":button, input[type=submit], input[type=reset]",
PF.obj.modal.selectors.root
).length > 0
) {
var $form = $("form", PF.obj.modal.selectors.root);
if ($form.exists()) {
$form.append(
$(
$(
PF.obj.modal.selectors.btn_container,
PF.obj.modal.selectors.root
).html()
).wrapInner(PF.obj.modal.selectors.btn_container.replace(".", ""))
);
$(
PF.obj.modal.selectors.btn_container,
PF.obj.modal.selectors.root
).each(function() {
if (
!$(this)
.closest("form")
.exists()
) {
$(this).remove();
}
});
} else {
$(PF.obj.modal.selectors.box, PF.obj.modal.selectors.root).wrapInner(
"
"
);
}
}

modal_options.callback();

$(PF.obj.modal.selectors.box).css({
transform: "scale(0.7)",
opacity: 0,
transition: PF.fn.modal.str.transition
});
$(PF.obj.modal.selectors.root).css({ display: "block" });
setTimeout(function() {
$(PF.obj.modal.selectors.root).css({ opacity: 1 });
$(PF.obj.modal.selectors.box).css({ transform: "scale(1)", opacity: 1 });
if (typeof PFrecaptchaCallback !== typeof undefined) {
PFrecaptchaCallback();
}
setTimeout(function() {
// Stock default modal values
$("html").data(
"modal-form-values",
PF.fn.deparam(
$(":input:visible", PF.obj.modal.selectors.root).serialize()
)
);
if (typeof modal_options.load == "function") {
modal_options.load();
}
}, PF.obj.config.animation.fast);
}, 1);

// Bind the modal events
$(PF.obj.modal.selectors.root).click(function(e) {
var $this = $(e.target),
_this = this;

if (PF.obj.modal.locked) {
return;
}

// Changes confirm?
if (
$this.closest(PF.obj.modal.selectors.changes_confirm).exists() &&
($this.is(PF.obj.modal.selectors.close_buttons) ||
$this.is(PF.obj.modal.selectors.submit_button))
) {
$(PF.obj.modal.selectors.changes_confirm).remove();

if ($this.is(PF.obj.modal.selectors.close_buttons)) {
$(PF.obj.modal.selectors.box, _this).fadeIn("fast", function() {
$(this).css("transition", PF.fn.modal.str.transition);
});
} else {
PF.fn.modal.close();
}

// Modal
} else {
if (
!$this.closest(".clickable").exists() ||
$this.is(PF.obj.modal.selectors.close_buttons)
) {
PF.fn.growl.close();
modal_options.cancel();
}

if ($this.is(PF.obj.modal.selectors.submit_button)) {
if (modal_options.confirm() === false) {
return;
}

var modal_submit_continue = true;
if (
$("input, textarea, select", PF.obj.modal.selectors.root).not(
":input[type=button], :input[type=submit], :input[type=reset]"
).length > 0 &&
!PF.fn.form_modal_has_changed() &&
!modal_options.forced
) {
modal_submit_continue = false;
}

if (modal_submit_continue) {
if (modal_options.ajax.url) {
var $btn_container = $(
PF.obj.modal.selectors.btn_container,
PF.obj.modal.selectors.root
);
PF.obj.modal.locked = true;

$btn_container
.first()
.clone()
.height($btn_container.height())
.html("")
.addClass("loading")
.appendTo(PF.obj.modal.selectors.root + " form");
$btn_container.hide();

PF.obj.modal.$close_buttons.hide();

var modal_loading_msg;

switch (PF.obj.modal.type) {
case "edit":
modal_loading_msg = PF.fn._s("Saving");
break;
case "confirm":
case "form":
default:
modal_loading_msg = PF.fn._s("Sending");
break;
}

PF.fn.loading.inline(
$(
PF.obj.modal.selectors.btn_container + ".loading",
PF.obj.modal.selectors.root
),
{ size: "small", message: modal_loading_msg, valign: "center" }
);

$(PF.obj.modal.selectors.root).disableForm();

if (
!$.isEmptyObject(PF.obj.modal.form_data) ||
(typeof options.ajax !== "undefined" &&
typeof options.ajax.data == "undefined")
) {
modal_options.ajax.data = PF.obj.modal.form_data;
}
PF.obj.modal.XHR = $.ajax({
url: modal_options.ajax.url,
type: "POST",
data: modal_options.ajax.data //PF.obj.modal.form_data // $.param ?
}).complete(function(XHR) {
PF.obj.modal.locked = false;

if (XHR.status == 200) {
var success_fn =
typeof modal_options.ajax.deferred !== "undefined" &&
typeof modal_options.ajax.deferred.success !== "undefined"
? modal_options.ajax.deferred.success
: null;

if (typeof success_fn == "function") {
PF.fn.modal.close(function() {
if (typeof success_fn == "function") {
success_fn(XHR);
}
});
} else if (typeof success_fn == "object") {
if (typeof success_fn.before == "function") {
success_fn.before(XHR);
}
if (typeof success_fn.done == "function") {
success_fn.done(XHR);
}
}
} else {
$(PF.obj.modal.selectors.root).enableForm();
$(
PF.obj.modal.selectors.btn_container + ".loading",
PF.obj.modal.selectors.root
).remove();
$btn_container.css("display", "");

if (
typeof modal_options.ajax.deferred !== "undefined" &&
typeof modal_options.ajax.deferred.error == "function"
) {
modal_options.ajax.deferred.error(XHR);
} else {
var message = PF.fn._s(
"An error occurred. Please try again later."
);
/*
if(XHR.responseJSON.error.message) {
message = XHR.responseJSON.error.message;
}
*/
PF.fn.growl.call(message);
}
}
});
} else {
// No ajax behaviour
PF.fn.modal.close(modal_options.callback());
}
}
}
}
});
},

/**
* Fires a confirm modal
* @argument options object
*/
confirm: function(options) {
options.type = "confirm";
if (typeof options.title == "undefined") {
options.title = PF.fn._s("Confirm action");
}
PF.fn.modal.call(options);
},

/**
* Fires a simple info modal
*/
simple: function(options) {
if (typeof options == "string") options = { message: options };
if (typeof options.buttons == "undefined") options.buttons = false;
if (typeof options.title == "undefined")
options.title = PF.fn._s("information");
PF.fn.modal.call(options);
},

fixScrollbars: function() {
if (!$(PF.obj.modal.selectors.root).exists()) {
return;
}
var $targets = {
padding: $(".top-bar, .fixed, .position-fixed"),
margin: $("html")
};
var properties = {};
if (
PF.str.ScrollBarWidth > 0 &&
$("html").hasScrollBar().vertical &&
!$("body").data("overflow-hidden")
) {
properties.padding = PF.str.ScrollBarWidth + "px";
properties.margin = PF.str.ScrollBarWidth + "px";
} else {
properties.padding = "";
properties.margin = "";
}
$targets.padding.css({ paddingRight: properties.padding });
$targets.margin.css({ marginRight: properties.margin });
},

/**
* Closes the modal
* @argument callback fn
*/
close: function(callback) {
if (!$(PF.obj.modal.selectors.root).exists()) {
return;
}
PF.fn.growl.close(true);
$("[rel=tooltip]", PF.obj.modal.selectors.root).tipTip("hide");
$(PF.obj.modal.selectors.box).css({ transform: "scale(0.5)", opacity: 0 });
$(PF.obj.modal.selectors.root).css({ opacity: 0 });
setTimeout(function() {
if (PF.str.ScrollBarWidth > 0 && $("html").hasScrollBar().vertical) {
$(".top-bar, .fixed, .position-fixed").css({ paddingRight: "" });
}
$("html").css({ marginRight: "" });
if (!$("body").data("overflow-hidden")) {
$("body").removeClass("overflow-hidden");
}
$("body").removeData("overflow-hidden");
$(PF.obj.modal.selectors.root).remove();
if (typeof callback == "function") callback();
}, PF.obj.config.animation.normal);
}
};

/**
* Peafowlesque popups
*/
PF.fn.popup = function(options) {
var settings = {
height: options.height || 500,
width: options.width || 650,
scrollTo: 0,
resizable: 0,
scrollbars: 0,
location: 0
};

settings.top = screen.height / 2 - settings.height / 2;
settings.left = screen.width / 2 - settings.width / 2;

var settings_ = "";
for (var key in settings) {
settings_ += key + "=" + settings[key] + ",";
}
settings_ = settings_.slice(0, -1); // remove the last comma

window.open(options.href, "Popup", settings_);
return;
};

/**
* PEAFOWL FLUID WIDTH FIXER
* -------------------------------------------------------------------------------------------------
*/
PF.fn.list_fluid_width = function() {
if (!$("body").is_fluid()) return;

var $content_listing = $(PF.obj.listing.selectors.content_listing_visible),
$pad_content_listing = $(
PF.obj.listing.selectors.pad_content,
$content_listing
),
$list_item = $(PF.obj.listing.selectors.list_item, $content_listing),
list_item_width = $list_item.outerWidth(true),
list_item_gutter = $list_item.outerWidth(true) - $list_item.width();

PF.obj.listing.content_listing_ratio = parseInt(
($content_listing.width() + list_item_gutter) / list_item_width
);

if ($list_item.length < PF.obj.listing.content_listing_ratio) {
$pad_content_listing.css("width", "100%");
return;
}

if (PF.fn.isDevice(["tablet", "laptop", "desktop"])) {
// $pad_content_listing.width((PF.obj.listing.content_listing_ratio * list_item_width) - list_item_gutter);
}

if (PF.obj.follow_scroll.$node.hasClass("position-fixed")) {
PF.obj.follow_scroll.$node.width(
$(".content-width")
.first()
.width()
);
}
};

/**
* PEAFOWL TABS
* -------------------------------------------------------------------------------------------------
*/

PF.obj.tabs = {
hashdata: {}
};

PF.fn.show_tab = function(tab) {
if (typeof tab == "undefined") return;
var $this = $("a[data-tab=" + tab + "]", ".content-tabs");

$("li", $this.closest("ul")).removeClass("current");
$this.closest("li").addClass("current");

var $tab_content_group = $("#tabbed-content-group");
$target = $("#" + $this.data("tab"));

$(".tabbed-content", $tab_content_group)
.removeClass("visible")
.hide();
$($target, $tab_content_group)
.addClass("visible")
.show();

// Show/hide the listing sorting
$("[data-content=list-selection]")
.removeClass("visible")
.addClass("hidden");
$("[data-content=list-selection][data-tab=" + $this.data("tab") + "]")
.removeClass("hidden")
.addClass("visible");

if ($tab_content_group.exists()) {
var $list_item_target = $(
PF.obj.listing.selectors.list_item + ":not(.jsly)",
$target
),
target_fade = !$target.hasClass("jsly");

if (
$target.data("load") == "ajax" &&
$target.data("empty") !== "true" &&
!$(PF.obj.listing.selectors.list_item, $target).exists()
) {
PF.fn.listing.queryString.stock_load();
$target.html(PF.obj.listing.template.fill);
PF.fn.loading.inline(
$(PF.obj.listing.selectors.content_listing_loading, $target)
);
PF.fn.listing.queryString.stock_new();
PF.fn.listing.ajax();
} else {
PF.fn.listing.queryString.stock_current();
PF.fn.listing.columnizer(false, 0, false);
$list_item_target[target_fade ? "fadeIn" : "show"]();
}
}

PF.fn.listing.columnizerQueue();

if (
$(PF.obj.listing.selectors.content_listing_visible).data("queued") == true
) {
PF.fn.listing.columnizer(true, 0);
}
};

/**
* PEAFOWL LISTINGS
* -------------------------------------------------------------------------------------------------
*/
PF.obj.listing = {
columns: "",
columns_number: 1,
current_column: "",
current_column: "",
XHR: {},
query_string: PF.fn.get_url_vars(),
calling: false,
content_listing_ratio: 1,
selectors: {
sort: ".sort-listing .current [data-sort]",
content_listing: ".content-listing",
content_listing_visible: ".content-listing:visible",
content_listing_loading: ".content-listing-loading",
content_listing_load_more: ".content-listing-more",
content_listing_pagination: ".content-listing-pagination",
empty_icon: ".icon icon-drawer",
pad_content: ".pad-content-listing",
list_item: ".list-item"
},
template: {
fill: $("[data-template=content-listing]").html(),
empty: $("[data-template=content-listing-empty]").html(),
loading: $("[data-template=content-listing-loading]").html()
}
};

PF.fn.listing = {};

PF.fn.listing.show = function(response, callback) {
$content_listing = $("#content-listing-tabs").exists()
? $(
PF.obj.listing.selectors.content_listing_visible,
"#content-listing-tabs"
)
: $(PF.obj.listing.selectors.content_listing);

PF.fn.loading.inline(PF.obj.listing.selectors.content_listing_loading);

$(PF.obj.listing.selectors.list_item + ":not(.jsly)", $content_listing).each(
function() {
$(this).imagesLoaded(function(i) {
var items = PF.obj.listing.selectors.list_item,
$subjects = $(
items + ":visible",
PF.obj.listing.selectors.content_listing_visible
),
$targets = $(i.elements);

if (
(typeof response !== "undefined" &&
$(response.html).length < PF.obj.config.listing.items_per_page) ||
$(PF.obj.listing.selectors.list_item, $content_listing).length <
PF.obj.config.listing.items_per_page
) {
PF.fn.listing.removeLoader($content_listing);
}

if (
$(
PF.obj.listing.selectors.content_listing_pagination,
$content_listing
).is("[data-type=classic]") ||
!$("[data-action=load-more]", $content_listing).exists()
) {
$(
PF.obj.listing.selectors.content_listing_loading,
$content_listing
).remove();
}

if ($subjects.length == 0) {
$targets.show();
PF.fn.listing.columnizer(false, 0);
PF.obj.listing.recolumnize = true;
}

//var animation_time = $subjects.length == 0 ? 0 : null;
var animation_time = 0;

PF.fn.listing.columnizer(
PF.obj.listing.recolumnize,
animation_time,
$subjects.length == 0
);

$targets.hide();
PF.obj.listing.recolumnize = false;

if (PF.fn.isDevice(["laptop", "desktop"])) {
$targets.each(function() {
// too much CPU for this

$(this)
.show()
.find(".image-container")
.hide();

var callTime = $.now();
var $this = $(this);
var $target = $(".image-container", $this);

$(".image-container", this).imagesLoaded(function() {
var loadTime = $.now() - callTime;

if ($subjects.length == 0) {
if (loadTime > PF.obj.config.animation.normal) {
$target.fadeIn(PF.obj.config.animation.normal);
} else {
$target.show();
}
} else {
$target.fadeIn(PF.obj.config.animation.normal);
}
});
});
} else {
$targets.show();
}

PF.obj.listing.calling = false;

var visible_loading =
$(
PF.obj.listing.selectors.content_listing_loading,
$content_listing
).exists() &&
$(
PF.obj.listing.selectors.content_listing_loading,
$content_listing
).is_in_viewport();
if (typeof PF.obj.listing.show_load_more == typeof undefined) {
PF.obj.listing.show_load_more = visible_loading;
}

$(PF.obj.listing.selectors.content_listing_loading, $content_listing)[
(visible_loading ? "add" : "remove") + "Class"
]("visibility-hidden");
$(PF.obj.listing.selectors.content_listing_load_more, $content_listing)[
PF.obj.listing.show_load_more ? "show" : "hide"
]();

var State = History.getState();
if (State.data && typeof State.data.scrollTop !== "undefined") {
if ($(window).scrollTop() !== State.data.scrollTop) {
//$(window).scrollTop(State.data.scrollTop);
}
}

if (typeof callback == "function") {
callback();
}
});
}
);
};

PF.fn.listing.removeLoader = function(obj) {
var remove = [
PF.obj.listing.selectors.content_listing_load_more,
PF.obj.listing.selectors.content_listing_loading
];

if (
$(PF.obj.listing.selectors.content_listing_pagination, $content_listing).is(
"[data-type=endless]"
)
) {
remove.push(PF.obj.listing.selectors.content_listing_pagination);
}

$.each(remove, function(i, v) {
$(v, obj).remove();
});
};

PF.fn.listing.queryString = {
// Stock the querystring values from initial load
stock_load: function() {
var $content_listing = $(PF.obj.listing.selectors.content_listing_visible),
params = PF.fn.deparam($content_listing.data("params"));

PF.obj.listing.params_hidden =
typeof $content_listing.data("params-hidden") !== "undefined"
? PF.fn.deparam($content_listing.data("params-hidden"))
: null;

if (typeof PF.obj.listing.query_string.action == "undefined") {
PF.obj.listing.query_string.action =
$content_listing.data("action") || "list";
}
if (typeof PF.obj.listing.query_string.list == "undefined") {
PF.obj.listing.query_string.list = $content_listing.data("list");
}
if (typeof PF.obj.listing.query_string.sort == "undefined") {
if (typeof params !== "undefined" && typeof params.sort !== "undefined") {
PF.obj.listing.query_string.sort = params.sort;
} else {
PF.obj.listing.query_string.sort = $(
":visible" + PF.obj.listing.selectors.sort
).data("sort");
}
}
if (typeof PF.obj.listing.query_string.page == "undefined") {
PF.obj.listing.query_string.page = 1;
}
$content_listing.data("page", PF.obj.listing.query_string.page);

// Stock the real ajaxed hrefs for ajax loads
$(PF.obj.listing.selectors.content_listing + "[data-load=ajax]").each(
function() {
var $sortable_switch = $(
"[data-tab=" +
$(this).attr("id") +
"]" +
PF.obj.listing.selectors.sort
);
var dataParams = PF.fn.deparam($(this).data("params")),
dataParamsHidden = PF.fn.deparam($(this).data("params-hidden")),
params = {
q: dataParams && dataParams.q ? dataParams.q : null,
list: $(this).data("list"),
sort: $sortable_switch.exists()
? $sortable_switch.data("sort")
: dataParams && dataParams.sort
? dataParams.sort
: null,
page: dataParams && dataParams.page ? dataParams.page : 1
};

if (dataParamsHidden && dataParamsHidden.list) {
delete params.list;
}

for (var k in params) {
if (!params[k]) delete params[k];
}
}
);

// The additional params setted in data-params=""
for (var k in params) {
if (/action|list|sort|page/.test(k) == false) {
PF.obj.listing.query_string[k] = params[k];
}
}

if (typeof PF.obj.listing.params_hidden !== typeof undefined) {
// The additional params setted in data-hidden-params=""
for (var k in PF.obj.listing.params_hidden) {
if (/action|list|sort|page/.test(k) == false) {
PF.obj.listing.query_string[k] = PF.obj.listing.params_hidden[k];
}
}
PF.obj.listing.query_string["params_hidden"] =
PF.obj.listing.params_hidden;
PF.obj.listing.params_hidden["params_hidden"] = null; // Add this key for legacy, params_hidden v3.9.0 intro*
}
},

// Stock new querystring values for initial ajax call
stock_new: function() {
var $content_listing = $(PF.obj.listing.selectors.content_listing_visible),
params = PF.fn.deparam($content_listing.data("params"));

if ($content_listing.data("offset")) {
PF.obj.listing.query_string.offset = $content_listing.data("offset");
} else {
delete PF.obj.listing.query_string.offset;
}

PF.obj.listing.query_string.action =
$content_listing.data("action") || "list";
PF.obj.listing.query_string.list = $content_listing.data("list");

if (typeof params !== "undefined" && typeof params.sort !== "undefined") {
PF.obj.listing.query_string.sort = params.sort;
} else {
PF.obj.listing.query_string.sort = $(
":visible" + PF.obj.listing.selectors.sort
).data("sort");
}

PF.obj.listing.query_string.page = 1;
},

// Stock querystring values for static tab change
stock_current: function() {
this.stock_new();
PF.obj.listing.query_string.page = $(
PF.obj.listing.selectors.content_listing_visible
).data("page");
}
};

// Initial load -> Stock the current querystring
PF.fn.listing.queryString.stock_load();

PF.fn.listing.ajax = function() {
if (PF.obj.listing.calling == true) {
return;
}

PF.obj.listing.calling = true;

var $content_listing = $(PF.obj.listing.selectors.content_listing_visible);
var $pad_content_listing = $(
PF.obj.listing.selectors.pad_content,
$content_listing
);
var $content_listing_load_more = $(
PF.obj.listing.selectors.content_listing_load_more,
$content_listing
);

$content_listing_load_more.hide();
$(PF.obj.listing.selectors.content_listing_loading, $content_listing)
.removeClass("visibility-hidden")
.show();

PF.obj.listing.XHR = $.ajax({
type: "POST",
data: $.param(
$.extend({}, PF.obj.listing.query_string, $.ajaxSettings.data)
)
}).complete(function(XHR) {
var response = XHR.responseJSON;
var removePagination = function() {
$(
PF.obj.listing.selectors.content_listing_loading +
"," +
PF.obj.listing.selectors.content_listing_pagination +
":not([data-visibility=visible])",
$content_listing
).remove();
},
setEmptyTemplate = function() {
$content_listing
.data("empty", "true")
.html(PF.obj.listing.template.empty);
$(
"[data-content=list-selection][data-tab=" +
$content_listing.attr("id") +
"]"
).addClass("disabled");
};

if (XHR.readyState == 4 && typeof response !== "undefined") {
$(
"[data-content=list-selection][data-tab=" +
$content_listing.attr("id") +
"]"
).removeClass("disabled");

// Bad Request Bad Request what you gonna do when they come for ya?
if (XHR.status !== 200) {
// This is here to inherit the emptys
var response_output =
typeof response.error !== "undefined" &&
typeof response.error.message !== "undefined"
? response.error.message
: "Bad request";
PF.fn.growl.call("Error: " + response_output);
$content_listing.data("load", "");
}
// Empty HTML
if (
(typeof response.html == "undefined" || response.html == "") &&
$(PF.obj.listing.selectors.list_item, $content_listing).length == 0
) {
setEmptyTemplate();
}
// End of the line
if (typeof response.html == "undefined" || response.html == "") {
removePagination();
PF.obj.listing.calling = false;
if (typeof PF.fn.listing_end == "function") {
PF.fn.listing_end();
}
return;
}

// Listing stuff
$content_listing.data({
load: "",
page: PF.obj.listing.query_string.page
});

var url_object = $.extend({}, PF.obj.listing.query_string);
for (var k in PF.obj.listing.params_hidden) {
if (typeof url_object[k] !== "undefined") {
delete url_object[k];
}
}

delete url_object["action"];

for (var k in url_object) {
if (!url_object[k]) delete url_object[k];
}

// get the fancy URL with scrollTop attached
if (document.URL.indexOf("?" + $.param(url_object)) == -1) {
var url = window.location.href;
url = url.split("?")[0].replace(/\/$/, "") + "/?" + $.param(url_object);
if (window.location.hash) {
url = url.replace(window.location.hash, "");
}
History.pushState(
{ pushed: "pagination", scrollTop: $(window).scrollTop() },
document.title,
url
);
}

$("a[data-tab=" + $content_listing.attr("id") + "]").attr(
"href",
document.URL
);

$pad_content_listing.append(response.html);

$("[data-action=load-more]", $content_listing_load_more).attr(
"data-seek",
response.seekEnd
);

PF.fn.listing.show(response, function() {
$(
PF.obj.listing.selectors.content_listing_loading,
$content_listing
).addClass("visibility-hidden");
});
} else {
// Network error, abort or something similar
PF.obj.listing.calling = false;
$content_listing.data("load", "");
removePagination();
if ($(PF.obj.listing.selectors.list_item, $content_listing).length == 0) {
setEmptyTemplate();
}
if (XHR.readyState !== 0) {
PF.fn.growl.call(
PF.fn._s("An error occurred. Please try again later.")
);
}
}

if (typeof PF.fn.listing.ajax.callback == "function") {
PF.fn.listing.ajax.callback(XHR);
}
});
};

PF.fn.listing.columnizerQueue = function() {
$(PF.obj.listing.selectors.content_listing + ":hidden").data("queued", true);
};

PF.fn.listing.refresh = function(animation_time) {
PF.fn.listing.columnizer(true, animation_time, false);
$(PF.obj.listing.selectors.list_item).show();
};

// Peafowl's masonry approach... Just because godlike.
var width = $(window).width();
PF.fn.listing.columnizer = function(forced, animation_time, hard_forced) {
var device_to_columns = {
// default
phone: 1,
phablet: 3,
tablet: 4,
laptop: 5,
desktop: 6,
largescreen: 7
};

if (typeof forced !== "boolean") var forced = false;
if (typeof PF.obj.listing.mode == "undefined") forced = true;
if (typeof hard_forced !== "boolean") {
var hard_forced = false,
default_hard_forced = true;
} else {
var default_hard_forced = false;
}
if (!hard_forced && default_hard_forced) {
if (width !== $(window).width() || forced) {
hard_forced = true;
}
}

if (typeof animation_time == typeof undefined)
var animation_time = PF.obj.config.animation.normal;

//animation_time = 0;

var $container = $("#content-listing-tabs").exists()
? $(
PF.obj.listing.selectors.content_listing_visible,
"#content-listing-tabs"
)
: $(PF.obj.listing.selectors.content_listing),
$pad_content_listing = $(PF.obj.listing.selectors.pad_content, $container),
list_mode = "responsive",
$list_item = $(
forced || hard_forced
? PF.obj.listing.selectors.list_item
: PF.obj.listing.selectors.list_item + ":not(.jsly)",
$container
);

$container.addClass("jsly");

// Get the device columns from global config
if (typeof PF.obj.config.listing.device_to_columns !== "undefined") {
device_to_columns = $.extend(
{},
device_to_columns,
PF.obj.config.listing.device_to_columns
);
}

// Get the device columns from the dom
if ($container.data("device-columns")) {
device_to_columns = $.extend(
{},
device_to_columns,
$container.data("device-columns")
);
}

PF.obj.listing.mode = list_mode;
PF.obj.listing.device = PF.fn.getDeviceName();

if (!$list_item.exists()) return;

if (
typeof $container.data("columns") !== "undefined" &&
!forced &&
!hard_forced
) {
PF.obj.listing.columns = $container.data("columns");
PF.obj.listing.columns_number = $container.data("columns").length - 1;
PF.obj.listing.current_column = $container.data("current_column");
} else {
var $list_item_1st = $list_item.first();
$list_item_1st.css("width", "");
PF.obj.listing.columns = new Array();
PF.obj.listing.columns_number = device_to_columns[PF.fn.getDeviceName()];
for (i = 0; i < PF.obj.listing.columns_number; i++) {
PF.obj.listing.columns[i + 1] = 0;
}
PF.obj.listing.current_column = 1;
}

var special_margin = PF.obj.listing.columns_number == 1 ? "-10px" : "";

$("#tabbed-content-group").css({
marginLeft: special_margin,
marginRight: special_margin
});

$container
.removeClass("small-cols")
.addClass(PF.obj.listing.columns_number > 6 ? "small-cols" : "");

$pad_content_listing.css("width", "100%");

var delay = 0;

$list_item.each(function(index) {
$(this).addClass("jsly");

var $list_item_img = $(".list-item-image", this),
$list_item_src = $(".list-item-image img", this),
$list_item_thumbs = $(".list-item-thumbs", this),
isJslyLoaded = $list_item_src.hasClass("jsly-loaded");

$list_item_src.show();

if (hard_forced) {
$(this).css({ top: "", left: "", height: "", position: "" });
$list_item_img.css({ maxHeight: "", height: "" });
$list_item_src
.removeClass("jsly")
.css({ width: "", height: "" })
.parent()
.css({
marginLeft: "",
marginTop: ""
});
$("li", $list_item_thumbs).css({ width: "", height: "" });
}

var width_responsive =
PF.obj.listing.columns_number == 1
? "100%"
: parseInt(
(1 / PF.obj.listing.columns_number) *
($container.width() - 10 * (PF.obj.listing.columns_number - 1)) +
"px"
);
$(this).css("width", width_responsive);

if (PF.obj.listing.current_column > PF.obj.listing.columns_number) {
PF.obj.listing.current_column = 1;
}

$(this).attr("data-col", PF.obj.listing.current_column);

if (!$list_item_src.exists()) {
var empty = true;
$list_item_src = $(".image-container .empty", this);
}

var already_shown = $(this).is(":visible");
$list_item.show();

var isFixed = $list_item_img.hasClass("fixed-size");

var image = {
w: parseInt($list_item_src.attr("width")),
h: parseInt($list_item_src.attr("height"))
};
image.ratio = image.w / image.h;

//$list_item_src.removeAttr("width height"); // para fixed

if (hard_forced && PF.obj.listing.columns_number > 1) {
$list_item_src.css({ width: "auto", height: "auto" });
$(".image-container:not(.list-item-avatar-cover)", this).css({
width: "",
height: "auto"
});
} else {
if (image.w > $container.width()) {
$(".image-container:not(.list-item-avatar-cover)", this).css(
image.ratio < 1
? { maxWidth: "100%", height: "auto" }
: { height: "100%", width: "auto" }
);
$list_item_src.css(
image.ratio < 1
? { maxWidth: "100%", height: "auto" }
: { height: "100%", width: "auto" }
);
}
}

// Meet the minHeight?

if (
empty ||
($list_item_img.css("min-height") && !$list_item_src.hasClass("jsly"))
) {
var list_item_img_min_height = parseInt($list_item_img.css("height")),
col = {
w: $(this).width(),
h: isFixed ? $(this).width() : null
},
magicWidth = Math.min(image.w, image.w < col.w ? image.w : col.w);

if (isFixed) {
$list_item_img.css({ height: col.w }); // Sets the item container height
if (image.ratio <= 3 && (image.ratio > 1 || image.ratio == 1)) {
// Landscape or square
image.h = Math.min(image.h, image.w < col.w ? image.w : col.w);
image.w = image.h * image.ratio;
} else {
// Portrait
image.w = magicWidth;
image.h = image.w / image.ratio;
}
var list_item_img_min_h = parseInt($list_item_img.css("min-height"));
$list_item_img.css("min-height", 0);
} else {
// Fluid height
image.w = magicWidth;
if (image.ratio >= 3 || image.ratio < 1 || image.ratio == 1) {
// Portrait or square
image.h = image.w / image.ratio;
} else {
// Landscape
image.h = Math.min(image.h, image.w);
image.w = image.h * image.ratio;
}
if (empty) {
image.h = col.w;
}
$list_item_img.css({ height: image.h }); // Fill some gaps
}
$list_item_src.css({ width: image.w, height: image.h });

if ($list_item_src.width() == 0) {
$list_item_src.css({
width: magicWidth,
height: magicWidth / image.ratio
});
}

if ($(".image-container", this).is(".list-item-avatar-cover")) {
$list_item_src.css(
isFixed
? { width: "auto", height: "100%" }
: { width: "100%", height: "auto" }
);
}
if (
$list_item_src.height() !== 0 &&
($list_item_img.height() > $list_item_src.height() || isFixed)
) {
$list_item_src.parent().css({
marginTop:
($list_item_img.outerHeight() - $list_item_src.height()) / 2
});
}
if ($list_item_img.width() < $list_item_src.width()) {
$list_item_src.parent().css({
marginLeft:
-(($list_item_src.outerWidth() - $list_item_img.width()) / 2) + "px"
});
}

var list_item_src_pitfall_x = Math.max(
$list_item_src.position().left * 2,
0
),
list_item_src_pitfall_y = Math.max(
$list_item_src.position().top * 2,
0
);

// Do we need upscale? It is safe to upscale?
if (
PF.obj.listing.columns_number > 6 &&
(list_item_src_pitfall_x > 0 || list_item_src_pitfall_y > 0)
) {
var pitfall_ratio_x = list_item_src_pitfall_x / $list_item_img.width(),
pitfall_ratio_y = list_item_src_pitfall_y / $list_item_img.height(),
pitfall = {};
if (pitfall_ratio_x <= 0.25 && pitfall_ratio_y <= 0.25) {
if (pitfall_ratio_x > pitfall_ratio_y) {
pitfall.width = list_item_src_pitfall_x + $list_item_img.width();
pitfall.height = pitfall.width / image.ratio;
} else {
pitfall.height = list_item_src_pitfall_y + $list_item_src.height();
pitfall.width = pitfall.height * image.ratio;
}
$list_item_src.css(pitfall);
$list_item_src.parent().css({
marginLeft: -(
($list_item_src.width() - $list_item_img.width()) /
2
),
marginTop: 0
});
}
}

if ($list_item_thumbs.exists()) {
$("li", $list_item_thumbs)
.css({ width: 100 / $("li", $list_item_thumbs).length + "%" })
.css({ height: $("li", $list_item_thumbs).width() });
}

if (!already_shown) {
$list_item.hide();
}
}

//$pad_content_listing.css("visibility", "visible");

if (!$list_item_src.hasClass("jsly") && $(this).is(":hidden")) {
$(this).css("top", "100%");
}

PF.obj.listing.columns[PF.obj.listing.current_column] += $(
this
).outerHeight(true);

if (PF.obj.listing.columns_number == 1) {
$(this).removeClass("position-absolute");
} else {
if ($(this).is(":animated")) {
animation_time = 0;
}
$(this).addClass("position-absolute");

var new_left =
$(this).outerWidth(true) * (PF.obj.listing.current_column - 1);
var must_change_left = parseInt($(this).css("left")) != new_left;
if (must_change_left) {
animate_grid = true;
$(this).animate(
{
left: new_left
},
animation_time
);
}

var new_top =
PF.obj.listing.columns[PF.obj.listing.current_column] -
$(this).outerHeight(true);
if (parseInt($(this).css("top")) != new_top) {
animate_grid = true;
$(this).animate(
{
top: new_top
},
animation_time
);
if (must_change_left) {
delay = 1;
}
}
}

if (already_shown) {
$list_item.show();
}

if (!isJslyLoaded) {
$list_item_src
.addClass("jsly")
.hide()
.imagesLoaded(function(i) {
$(i.elements)
.show()
.addClass("jsly-loaded");
});
}

// Fill the shortest column (fluid view only)
if (!isFixed) {
var minCol, minH, currentH;
for (var i = 1; i <= PF.obj.listing.columns_number; i++) {
currentH = PF.obj.listing.columns[i];

if (typeof minH == "undefined") {
minH = currentH;
minCol = i;
}

if (PF.obj.listing.columns[i] == 0) {
minCol = i;
break;
}
if (currentH < minH) {
minH = PF.obj.listing.columns[i];
minCol = i;
}
}

PF.obj.listing.current_column = minCol;
} else {
PF.obj.listing.current_column++;
}
});

$container.data({
columns: PF.obj.listing.columns,
current_column: PF.obj.listing.current_column
});

var content_listing_height = 0;
$.each(PF.obj.listing.columns, function(i, v) {
if (v > content_listing_height) {
content_listing_height = v;
}
});

if (content_listing_height > 10) {
content_listing_height -= 10;
}

PF.obj.listing.width = $container.width();

if (typeof PF.obj.listing.height !== typeof undefined) {
var old_listing_height = PF.obj.listing.height;
}
PF.obj.listing.height = content_listing_height;

var do_listing_h_resize =
typeof old_listing_height !== typeof undefined &&
old_listing_height !== PF.obj.listing.height;

if (!do_listing_h_resize) {
$pad_content_listing.height(content_listing_height);
PF.fn.list_fluid_width();
}

// Magic!
if (do_listing_h_resize) {
$pad_content_listing.height(old_listing_height);
setTimeout(function() {
$pad_content_listing.animate(
{ height: content_listing_height },
animation_time,
function() {
PF.fn.list_fluid_width();
}
);
}, animation_time * delay);
}

$container.data("list-mode", PF.obj.listing.mode);
$(PF.obj.listing.selectors.content_listing_visible).data("queued", false);
};

/**
* PEAFOWL LOADERS
* -------------------------------------------------------------------------------------------------
*/
PF.fn.loading = {
spin: {
small: {
lines: 11,
length: 0,
width: 3,
radius: 7,
speed: 1,
trail: 45,
blocksize: 20
}, // 20x20
normal: {
lines: 11,
length: 0,
width: 5,
radius: 10,
speed: 1,
trail: 45,
blocksize: 30
}, // 30x30
big: {
lines: 11,
length: 0,
width: 7,
radius: 13,
speed: 1,
trail: 45,
blocksize: 40
}, // 40x40
huge: {
lines: 11,
length: 0,
width: 9,
radius: 16,
speed: 1,
trail: 45,
blocksize: 50
} // 50x50
},
inline: function($target, options) {
if (typeof $target == "undefined") return;

if ($target instanceof jQuery == false) {
var $target = $($target);
}

var defaultoptions = {
size: "normal",
color: $("body").css("color"),
center: false,
position: "absolute",
shadow: false,
valign: "top"
};

if (typeof options == "undefined") {
options = defaultoptions;
} else {
for (var k in defaultoptions) {
if (typeof options[k] == "undefined") {
options[k] = defaultoptions[k];
}
}
}

var size = PF.fn.loading.spin[options.size];

PF.fn.loading.spin[options.size].color = options.color;
PF.fn.loading.spin[options.size].shadow = options.shadow;

$target
.html(
'' +
(typeof options.message !== "undefined"
? '' + options.message + ""
: "")
)
.css({
"line-height": PF.fn.loading.spin[options.size].blocksize + "px"
});

$(".loading-indicator", $target)
.css({
width: PF.fn.loading.spin[options.size].blocksize,
height: PF.fn.loading.spin[options.size].blocksize
})
.spin(PF.fn.loading.spin[options.size]);

if (options.center) {
$(".loading-indicator", $target.css("textAlign", "center")).css({
position: options.position,
top: "50%",
left: "50%",
marginTop: -(PF.fn.loading.spin[options.size].blocksize / 2),
marginLeft: -(PF.fn.loading.spin[options.size].blocksize / 2)
});
}
if (options.valign == "center") {
$(".loading-indicator,.loading-text", $target).css(
"marginTop",
($target.height() - PF.fn.loading.spin[options.size].blocksize) / 2 +
"px"
);
}

$(".spinner", $target).css({
top: PF.fn.loading.spin[options.size].blocksize / 2 + "px",
left: PF.fn.loading.spin[options.size].blocksize / 2 + "px"
});
},
fullscreen: function() {
$("body").append(
'
' +
PF.fn._s("loading") +
"
"
);
$(".fullscreen-loader", "#pf-fullscreen-loader").spin(
PF.fn.loading.spin.huge
);
$("#pf-fullscreen-loader").css("opacity", 1);
},
destroy: function($target) {
var $loader_fs = $("#pf-fullscreen-loader"),
$loader_os = $("#pf-onscreen-loader");

if ($target == "fullscreen") $target = $loader_fs;
if ($target == "onscreen") $target = $loader_os;

if (typeof $target !== "undefined") {
$target.remove();
} else {
$loader_fs.remove();
$loader_os.remove();
}
}
};

/**
* PEAFOWL FORM HELPERS
* -------------------------------------------------------------------------------------------------
*/
jQuery.fn.disableForm = function() {
$(this).data("disabled", true);
$(":input", this).each(function() {
$(this).attr("disabled", true);
});
return this;
};
jQuery.fn.enableForm = function() {
$(this).data("disabled", false);
$(":input", this).removeAttr("disabled");
return this;
};

/**
* PEAFOWL FOLLOW SCROLL
* -------------------------------------------------------------------------------------------------
*/
PF.obj.follow_scroll = {
Y: 0,
y: 0,
$node: $(".follow-scroll"),
node_h: 0,
base_h: $(".follow-scroll").outerHeight(),
set: function(reset) {
if (reset) {
PF.obj.follow_scroll.base_h = $(".follow-scroll").outerHeight();
}
var exists = PF.obj.follow_scroll.$node
.closest(".follow-scroll-wrapper")
.exists();
if (exists) {
PF.obj.follow_scroll.$node
.closest(".follow-scroll-wrapper")
.css("position", "static");
}
PF.obj.follow_scroll.y = PF.obj.follow_scroll.$node.exists()
? PF.obj.follow_scroll.$node.offset().top
: null;
PF.obj.follow_scroll.node_h = PF.obj.follow_scroll.$node.outerHeight();
if (exists) {
PF.obj.follow_scroll.$node
.closest(".follow-scroll-wrapper")
.css("position", "");
}
},
checkDocumentHeight: function() {
var lastHeight = document.body.clientHeight,
newHeight,
timer;
(function run() {
newHeight = document.body.clientHeight;
if (lastHeight != newHeight) {
PF.obj.follow_scroll.set();
}
lastHeight = newHeight;
timer = setTimeout(run, 200);
})();
}
};
PF.obj.follow_scroll.set();
//PF.obj.follow_scroll.checkDocumentHeight();

PF.obj.follow_scroll.process = function(forced) {
if (forced) {
PF.obj.follow_scroll.node_h = PF.obj.follow_scroll.base_h;
}

if (!PF.obj.follow_scroll.$node.exists()) return; // Nothing to do here

var $parent = PF.obj.follow_scroll.$node.closest(
"[data-content=follow-scroll-parent]"
);
if (!$parent.exists()) {
$parent = PF.obj.follow_scroll.$node.closest(".content-width");
}

var $wrapper = PF.obj.follow_scroll.$node.closest(".follow-scroll-wrapper");

var top = PF.obj.follow_scroll.node_h;
var cond = $(window).scrollTop() > PF.obj.follow_scroll.y - top;

if ($("#top-bar").css("position") !== "fixed") {
PF.obj.follow_scroll.Y -= $(window).scrollTop();
if (PF.obj.follow_scroll.Y < 0) PF.obj.follow_scroll.Y = 0;
cond = cond && $(window).scrollTop() > PF.obj.follow_scroll.y;
}

if (
(cond && $wrapper.hasClass("position-fixed")) ||
(!cond && !$wrapper.hasClass("position-fixed"))
) {
return;
}

if (!$wrapper.exists()) {
PF.obj.follow_scroll.$node.wrapAll('