').appendTo($(wrapper).find(".layout-main"));
-
+
frappe.modules_setup.refresh_page();
}
frappe.modules_setup = {
refresh_page: function() {
$('#modules-list').empty();
-
+
var wrapper = $('
').appendTo("#modules-list");
$.each(keys(frappe.modules).sort(), function(i, m) {
- if(m!="Setup" && frappe.modules[m].link) {
+ if(m!="Setup") {
var row = $('
")
.appendTo(row.find(".check-area"));
@@ -42,7 +42,7 @@ frappe.modules_setup = {
$('#modules-list [data-module]:checkbox:not(:checked)').each(function() {
ml.push($(this).attr('data-module'));
});
-
+
return frappe.call({
method: 'frappe.core.page.modules_setup.modules_setup.update',
args: {
@@ -54,5 +54,5 @@ frappe.modules_setup = {
btn: btn
});
}
-
+
}
diff --git a/frappe/core/page/permission_manager/permission_manager.js b/frappe/core/page/permission_manager/permission_manager.js
index 4e274c5ed1..36ff5b7e8d 100644
--- a/frappe/core/page/permission_manager/permission_manager.js
+++ b/frappe/core/page/permission_manager/permission_manager.js
@@ -1,13 +1,14 @@
frappe.pages['permission-manager'].onload = function(wrapper) {
frappe.ui.make_app_page({
parent: wrapper,
- title: __('Permission Manager'),
+ title: __('Role Permissions Manager'),
icon: "icon-lock",
single_column: true
});
$(wrapper).find(".layout-main").html("
"
+ permissions_help);
wrapper.permission_engine = new frappe.PermissionEngine(wrapper);
+
}
frappe.pages['permission-manager'].refresh = function(wrapper) {
@@ -35,17 +36,18 @@ frappe.PermissionEngine = Class.extend({
me.setup_appframe();
}
});
+
},
setup_appframe: function() {
var me = this;
this.doctype_select
- = this.wrapper.appframe.add_select("doctypes",
+ = this.wrapper.appframe.add_select(__("Document Types"),
[{value: "", label: __("Select Document Type")+"..."}].concat(this.options.doctypes))
.change(function() {
frappe.set_route("permission-manager", $(this).val());
});
this.role_select
- = this.wrapper.appframe.add_select("roles",
+ = this.wrapper.appframe.add_select(__("Roles"),
[__("Select Role")+"..."].concat(this.options.roles))
.change(function() {
me.refresh();
@@ -85,46 +87,37 @@ frappe.PermissionEngine = Class.extend({
}
return false;
},
- make_reset_button: function() {
+ reset_std_permissions: function(data) {
var me = this;
- me.reset_button = me.wrapper.appframe.set_title_right("Reset Permissions", function() {
- me.get_standard_permissions(function(data) {
- var d = frappe.confirm(__("Reset Permissions for {0}?", [me.get_doctype()]), function() {
- return frappe.call({
- module:"frappe.core",
- page:"permission_manager",
- method:"reset",
- args: {
- doctype:me.get_doctype(),
- },
- callback: function() { me.refresh(); }
- });
- });
+ var d = frappe.confirm(__("Reset Permissions for {0}?", [me.get_doctype()]), function() {
+ return frappe.call({
+ module:"frappe.core",
+ page:"permission_manager",
+ method:"reset",
+ args: {
+ doctype: me.get_doctype(),
+ },
+ callback: function() { me.refresh(); }
+ });
+ });
- // show standard permissions
- var $d = $(d.wrapper).find(".msgprint").append("
").appendTo($d);
- $.each(data.message, function(i, d) {
- d.rights = [];
- $.each(me.rights, function(i, r) {
- if(d[r]===1) {
- if(r==="restrict") {
- d.rights.push(__("Can Restrict Others"));
- } else if(r==="restricted") {
- d.rights.push(__("Only Restricted Documents"));
- } else {
- d.rights.push(__(toTitle(r)));
- }
- }
- });
- d.rights = d.rights.join(", ");
- $wrapper.append(repl('
', d));
- });
+ // show standard permissions
+ var $d = $(d.wrapper).find(".frappe-confirm-message").append("
").appendTo($d);
+ $.each(data.message, function(i, d) {
+ d.rights = [];
+ $.each(me.rights, function(i, r) {
+ if(d[r]===1) {
+ d.rights.push(__(toTitle(r.replace("_", " "))));
+ }
});
- }).toggle(false);
+ d.rights = d.rights.join(", ");
+ $wrapper.append(repl('
', d));
+ });
+
},
get_doctype: function() {
var doctype = this.doctype_select.val();
@@ -137,7 +130,7 @@ frappe.PermissionEngine = Class.extend({
refresh: function() {
var me = this;
if(!me.doctype_select) {
- this.body.html("
Loading...
" + __("Loading") + "...
");
return;
}
if(!me.get_doctype() && !me.get_role()) {
@@ -157,7 +150,6 @@ frappe.PermissionEngine = Class.extend({
me.render(r.message);
}
});
- me.reset_button.toggle(me.get_doctype() ? true : false);
},
render: function(perm_list) {
this.body.empty();
@@ -169,8 +161,10 @@ frappe.PermissionEngine = Class.extend({
this.show_permission_table(this.perm_list);
}
this.show_add_rule();
+ this.make_reset_button();
},
show_permission_table: function(perm_list) {
+
var me = this;
this.table = $("
").appendTo(this.body);
- $.each([["Document Type", 150], ["Role", 150], ["Level", 40],
- ["Permissions", 370], ["", 40]], function(i, col) {
+ $.each([[__("Document Type"), 150], [__("Role"), 170], [__("Level"), 40],
+ [__("Permissions"), 350], ["", 40]], function(i, col) {
$("
").appendTo(me.table.find("tbody"));
- add_cell(row, d, "parent");
- me.set_show_users(add_cell(row, d, "role"), d.role);
+ me.add_cell(row, d, "parent");
+ var role_cell = me.add_cell(row, d, "role");
+ me.set_show_users(role_cell, d.role);
+
+ if (d.permlevel===0) {
+ me.setup_user_permissions(d, role_cell);
+ }
- var cell = add_cell(row, d, "permlevel");
+ var cell = me.add_cell(row, d, "permlevel");
if(d.permlevel==0) {
cell.css("font-weight", "bold");
row.addClass("warning");
}
- var perm_cell = add_cell(row, d, "permissions").css("padding-top", 0);
+ var perm_cell = me.add_cell(row, d, "permissions").css("padding-top", 0);
var perm_container = $("
").appendTo(perm_cell);
$.each(me.rights, function(i, r) {
- if(r==="restrict") {
- add_check(perm_container, d, "restrict", "Can Restrict Others");
- } else if(r==="restricted") {
- add_check(perm_container, d, "restricted", "Only Restricted Documents");
- } else {
- add_check(perm_container, d, r);
- }
- })
+ me.add_check(perm_container, d, r);
+ });
// buttons
me.add_delete_button(row, d);
});
},
+
+ add_cell: function(row, d, fieldname) {
+ return $("").appendTo(row)
+ .attr("data-fieldname", fieldname)
+ .html(__(d[fieldname]));
+ },
+
+ add_check: function(cell, d, fieldname, label) {
+ var me = this;
+
+ if(!label) label = toTitle(fieldname.replace(/_/g, " "));
+ if(d.permlevel > 0 && ["read", "write"].indexOf(fieldname)==-1) {
+ return;
+ }
+
+ var checkbox = $("").appendTo(cell)
+ .attr("data-fieldname", fieldname);
+
+ checkbox.find("input")
+ .prop("checked", d[fieldname] ? true: false)
+ .attr("data-ptype", fieldname)
+ .attr("data-name", d.name)
+ .attr("data-doctype", d.parent)
+
+ checkbox.find("label")
+ .css("text-transform", "capitalize");
+
+ return checkbox;
+ },
+
+ setup_user_permissions: function(d, role_cell) {
+ var me = this;
+ d.help = frappe.render('', {});
+
+ var checkbox = this.add_check(role_cell, d, "apply_user_permissions")
+ .removeClass("col-md-4")
+ .css({"margin-top": "15px"});
+
+ checkbox.find(".show-user-permission-doctypes").on("click", function() {
+ me.show_user_permission_doctypes(d);
+ });
+
+ var toggle_user_permissions = function() {
+ checkbox.find(".user-permission-help").toggleClass("hidden", !checkbox.find("input").prop("checked"));
+ };
+
+ toggle_user_permissions();
+ checkbox.find("input").on('click', function() {
+ toggle_user_permissions();
+ });
+
+ d.help = "";
+ },
+
rights: ["read", "write", "create", "delete", "submit", "cancel", "amend",
- "report", "import", "export", "print", "email", "restricted", "restrict"],
+ "print", "email", "report", "import", "export", "set_user_permissions"],
set_show_users: function(cell, role) {
- cell.html(""+role+" ")
+ cell.html(""+__(role)+" ")
.find("a")
.attr("data-role", role)
.click(function() {
@@ -260,7 +287,7 @@ frappe.PermissionEngine = Class.extend({
return $.format('{1} ', [p, p]);
})
msgprint(__("Users with role {0}:", [role])
- + r.message.join(" "));
+ + " " + r.message.join(" "));
}
})
return false;
@@ -293,6 +320,12 @@ frappe.PermissionEngine = Class.extend({
},
add_check_events: function() {
var me = this;
+
+ this.body.on("click", ".show-user-permissions", function() {
+ frappe.route_options = { doctype: me.get_doctype() || "" };
+ frappe.set_route("user-permissions");
+ });
+
this.body.on("click", "input[type='checkbox']", function() {
var chk = $(this);
var args = {
@@ -319,20 +352,21 @@ frappe.PermissionEngine = Class.extend({
},
show_add_rule: function() {
var me = this;
- $(""+__("Add A New Rule")+" ")
- .appendTo($("").appendTo(this.body))
+ $(" "
+ +__("Add A New Rule")+" ")
+ .appendTo($("
").appendTo(this.body))
.click(function() {
var d = new frappe.ui.Dialog({
title: __("Add New Permission Rule"),
fields: [
- {fieldtype:"Select", label:"Document Type",
+ {fieldtype:"Select", label:__("Document Type"),
options:me.options.doctypes, reqd:1, fieldname:"parent"},
- {fieldtype:"Select", label:"Role",
+ {fieldtype:"Select", label:__("Role"),
options:me.options.roles, reqd:1},
- {fieldtype:"Select", label:"Permission Level",
+ {fieldtype:"Select", label:__("Permission Level"),
options:[0,1,2,3,4,5,6,7,8,9], reqd:1, fieldname: "permlevel",
description: __("Level 0 is for document level permissions, higher levels for field level permissions.")},
- {fieldtype:"Button", label:"Add"},
+ {fieldtype:"Button", label:__("Add")},
]
});
if(me.get_doctype()) {
@@ -367,6 +401,95 @@ frappe.PermissionEngine = Class.extend({
d.show();
});
},
+
+ show_user_permission_doctypes: function(d) {
+ if (!d.dialog) {
+ var fields = [];
+ for (var i=0, l=d.linked_doctypes.length; i\
+ ' + __("Restore Original Permissions") + '')
+ .appendTo(this.body.find(".permission-toolbar"))
+ .on("click", function() {
+ me.get_standard_permissions(function(data) {
+ me.reset_std_permissions(data);
+ });
+ })
+ },
+
get_perm: function(name) {
return $.map(this.perm_list, function(d) { if(d.name==name) return d; })[0];
},
@@ -383,14 +506,14 @@ frappe.PermissionEngine = Class.extend({
}
})
-var permissions_help = ['',
+var permissions_help = ['',
'',
' ',
__('Quick Help for Setting Permissions'),
': ',
'',
'',
- __('Permissions are set on Roles and Document Types (called DocTypes) by setting rights like Read, Write, Create, Delete, Submit, Cancel, Amend, Report, Import, Export, Print, Email, Only Restricted Documents and Can Restrict Others.'),
+ __('Permissions are set on Roles and Document Types (called DocTypes) by setting rights like Read, Write, Create, Delete, Submit, Cancel, Amend, Report, Import, Export, Print, Email and Set User Permissions.'),
' ',
'',
__('Permissions get applied on Users based on what Roles they are assigned.'),
@@ -442,7 +565,7 @@ var permissions_help = ['',
'',
__('You can use Customize Form to set levels on fields.')
@@ -452,27 +575,21 @@ var permissions_help = [' ',
- __('Restricting Users'),
+ __('User Permissions'),
':',
'',
'',
- __("To give acess to a role for only specific records, check the 'Restricted' perimssion. User Restriction Records are used to restrict users with such role to specific records.")
- + ' (' + __('Setup > User Restriction') + ' )',
- ' ',
- '',
- __("If 'Restricted' is not checked, you can still restrict permissions based on certain values, like Company or Territory in a document by setting User Restrictions. But unless any restriction is set, a user will have permissions based on the Role."),
- ' ',
- '',
- __("Permissions at higher levels are 'Field Level' permissions. All Fields have a 'Permission Level' set against them and the rules defined at that permissions apply to the field. This is useful in case you want to hide or make certain field read-only."),
+ __("To give acess to a role for only specific records, check the 'Apply User Permissions'. User Permissions are used to limit users with such role to specific records.")
+ + ' (' + __('Setup > User Permissions Manager') + ' )',
' ',
'',
- __("If 'Restricted' is checked, the owner is always allowed based on Role."),
+ __("Select Document Types to set which User Permissions are used to limit access."),
' ',
'',
- __("Once you have set this, the users will only be able access documents where the link (e.g Company) exists."),
+ __("Once you have set this, the users will only be able access documents (eg. Blog Post) where the link exists (eg. Blogger)."),
' ',
'',
- __("Apart from System Manager, roles with 'Can Restrict Others' permission can restrict other users for that Document Type."),
+ __("Apart from System Manager, roles with 'Set User Permissions' right can set permissions for other users for that Document Type."),
' ',
' ',
'',
diff --git a/frappe/core/page/permission_manager/permission_manager.json b/frappe/core/page/permission_manager/permission_manager.json
index db0a3129e3..9eb5b3a8d6 100644
--- a/frappe/core/page/permission_manager/permission_manager.json
+++ b/frappe/core/page/permission_manager/permission_manager.json
@@ -16,5 +16,5 @@
}
],
"standard": "Yes",
- "title": "Permission Manager"
+ "title": "Role Permissions Manager"
}
\ No newline at end of file
diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py
index 5e2bd5dd1e..43c8531791 100644
--- a/frappe/core/page/permission_manager/permission_manager.py
+++ b/frappe/core/page/permission_manager/permission_manager.py
@@ -5,10 +5,13 @@ from __future__ import unicode_literals
import frappe
import frappe.defaults
from frappe.modules.import_file import get_file_path, read_doc_from_file
+from frappe.translate import send_translations
+from frappe.core.doctype.notification_count.notification_count import delete_notification_count_for
@frappe.whitelist()
def get_roles_and_doctypes():
frappe.only_for("System Manager")
+ send_translations(frappe.get_lang_dict("doctype", "DocPerm"))
return {
"doctypes": [d[0] for d in frappe.db.sql("""select name from `tabDocType` dt where
ifnull(istable,0)=0 and
@@ -21,12 +24,27 @@ def get_roles_and_doctypes():
@frappe.whitelist()
def get_permissions(doctype=None, role=None):
frappe.only_for("System Manager")
- return frappe.db.sql("""select * from tabDocPerm
+ out = frappe.db.sql("""select * from tabDocPerm
where %s%s order by parent, permlevel, role""" %
(doctype and (" parent='%s'" % doctype.replace("'", "\'")) or "",
role and ((doctype and " and " or "") + " role='%s'" % role.replace("'", "\'")) or ""),
as_dict=True)
+ def get_linked_doctypes(dt):
+ return list(set([dt] + [d.options for d in
+ frappe.get_meta(dt).get("fields", {
+ "fieldtype":"Link",
+ "ignore_user_permissions":("!=", 1),
+ "options": ("!=", "[Select]")
+ })
+ ]))
+
+ linked_doctypes = {}
+ for d in out:
+ d.linked_doctypes = linked_doctypes.setdefault(d.parent, get_linked_doctypes(d.parent))
+
+ return out
+
@frappe.whitelist()
def remove(doctype, name):
frappe.only_for("System Manager")
@@ -50,7 +68,7 @@ def add(parent, role, permlevel):
validate_and_reset(parent)
@frappe.whitelist()
-def update(name, doctype, ptype, value=0):
+def update(name, doctype, ptype, value=None):
frappe.only_for("System Manager")
frappe.db.sql("""update tabDocPerm set `%s`=%s where name=%s"""\
% (ptype, '%s', '%s'), (value, name))
@@ -69,6 +87,7 @@ def reset(doctype):
def clear_doctype_cache(doctype):
frappe.clear_cache(doctype=doctype)
+ delete_notification_count_for(doctype)
for user in frappe.db.sql_list("""select distinct tabUserRole.parent from tabUserRole, tabDocPerm
where tabDocPerm.parent = %s
and tabDocPerm.role = tabUserRole.role""", doctype):
@@ -86,6 +105,7 @@ def get_users_with_role(role):
@frappe.whitelist()
def get_standard_permissions(doctype):
+ frappe.only_for("System Manager")
module = frappe.db.get_value("DocType", doctype, "module")
path = get_file_path(module, "DocType", doctype)
return read_doc_from_file(path).get("permissions")
diff --git a/frappe/core/page/user_properties/README.md b/frappe/core/page/user_permissions/README.md
similarity index 100%
rename from frappe/core/page/user_properties/README.md
rename to frappe/core/page/user_permissions/README.md
diff --git a/frappe/core/page/user_properties/__init__.py b/frappe/core/page/user_permissions/__init__.py
similarity index 100%
rename from frappe/core/page/user_properties/__init__.py
rename to frappe/core/page/user_permissions/__init__.py
diff --git a/frappe/core/page/user_permissions/user_permissions.js b/frappe/core/page/user_permissions/user_permissions.js
new file mode 100644
index 0000000000..e9c18ed4c4
--- /dev/null
+++ b/frappe/core/page/user_permissions/user_permissions.js
@@ -0,0 +1,345 @@
+frappe.pages['user-permissions'].onload = function(wrapper) {
+ frappe.ui.make_app_page({
+ parent: wrapper,
+ title: "User Permissions Manager",
+ icon: "icon-shield",
+ single_column: true
+ });
+
+ $(wrapper).find(".layout-main").html("
\
+ \
+ Edit Role Permissions \
+
\
+ \
+ \
+ "+__("Quick Help for User Permissions")+": \
+ \
+ "
+ + __("Apart from Role based Permission Rules, you can apply User Permissions based on DocTypes.")
+ + " "
+
+ + ""
+ + __("These permissions will apply for all transactions where the permitted record is linked. For example, if Company C is added to User Permissions of user X, user X will only be able to see transactions that has company C as a linked value.")
+ + " "
+
+ + ""
+ + __("These will also be set as default values for those links, if only one such permission record is defined.")
+ + " "
+
+ + ""
+ + __("A user can be permitted to multiple records of the same DocType.")
+ + " \
+ \
+ \
+
");
+ wrapper.user_permissions = new frappe.UserPermissions(wrapper);
+}
+
+frappe.pages['user-permissions'].refresh = function(wrapper) {
+ wrapper.user_permissions.set_from_route();
+}
+
+frappe.UserPermissions = Class.extend({
+ init: function(wrapper) {
+ this.wrapper = wrapper;
+ this.body = $(this.wrapper).find(".user-settings");
+ this.filters = {};
+ this.make();
+ this.refresh();
+ },
+ make: function() {
+ var me = this;
+
+ $(this.wrapper).find(".view-role-permissions").on("click", function() {
+ frappe.route_options = { doctype: me.get_doctype() || "" };
+ frappe.set_route("permission-manager");
+ })
+
+ return frappe.call({
+ module:"frappe.core",
+ page:"user_permissions",
+ method: "get_users_and_links",
+ callback: function(r) {
+ me.options = r.message;
+
+ me.filters.user = me.wrapper.appframe.add_field({
+ fieldname: "user",
+ label: __("User"),
+ fieldtype: "Select",
+ options: (["Select User..."].concat(r.message.users)).join("\n")
+ });
+
+ me.filters.doctype = me.wrapper.appframe.add_field({
+ fieldname: "doctype",
+ label: __("DocType"),
+ fieldtype: "Select",
+ options: (["Select DocType..."].concat(me.get_link_names())).join("\n")
+ });
+
+ me.filters.user_permission = me.wrapper.appframe.add_field({
+ fieldname: "user_permission",
+ label: __("Name"),
+ fieldtype: "Link",
+ options: "[Select]"
+ });
+
+ if(user_roles.indexOf("System Manager")!==-1) {
+ me.download = me.wrapper.appframe.add_field({
+ fieldname: "download",
+ label: __("Download"),
+ fieldtype: "Button",
+ icon: "icon-download"
+ });
+
+ me.upload = me.wrapper.appframe.add_field({
+ fieldname: "upload",
+ label: __("Upload"),
+ fieldtype: "Button",
+ icon: "icon-upload"
+ });
+ }
+
+ // bind change event
+ $.each(me.filters, function(k, f) {
+ f.$input.on("change", function() {
+ me.refresh();
+ });
+ });
+
+ // change options in user_permission link
+ me.filters.doctype.$input.on("change", function() {
+ me.filters.user_permission.df.options = me.get_doctype();
+ });
+
+ me.set_from_route();
+ me.setup_download_upload();
+ }
+ });
+ },
+ setup_download_upload: function() {
+ var me = this;
+ me.download.$input.on("click", function() {
+ window.location.href = frappe.urllib.get_base_url()
+ + "/api/method/frappe.core.page.user_permissions.user_permissions.get_user_permissions_csv";
+ });
+
+ me.upload.$input.on("click", function() {
+ var d = new frappe.ui.Dialog({
+ title: "Upload User Permissions",
+ fields: [
+ {
+ fieldtype:"HTML",
+ options: ''+
+ ""+__("Upload CSV file containing all user permissions in the same format as Download.")+" "+
+ ""+__("Any existing permission will be deleted / overwritten.")+" "+
+ ' '
+ },
+ {
+ fieldtype:"Attach", fieldname:"attach",
+ }
+ ],
+ primary_action_label: __("Upload and Sync"),
+ primary_action: function() {
+ frappe.call({
+ method:"frappe.core.page.user_permissions.user_permissions.import_user_permissions",
+ args: {
+ filedata: d.fields_dict.attach.get_value()
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ msgprint("Permissions Updated");
+ d.hide();
+ }
+ }
+ });
+ }
+ });
+ d.show();
+ })
+ },
+ get_link_names: function() {
+ return this.options.link_fields;
+ },
+ set_from_route: function() {
+ var me = this;
+ if(frappe.route_options && this.filters && !$.isEmptyObject(this.filters)) {
+ $.each(frappe.route_options, function(key, value) {
+ if(me.filters[key] && frappe.route_options[key]!=null)
+ me.set_filter(key, value);
+ });
+ frappe.route_options = null;
+ }
+ this.refresh();
+ },
+ set_filter: function(key, value) {
+ this.filters[key].$input.val(value);
+ },
+ get_user: function() {
+ var user = this.filters.user.$input.val();
+ return user=="Select User..." ? null : user;
+ },
+ get_doctype: function() {
+ var doctype = this.filters.doctype.$input.val();
+ return doctype=="Select DocType..." ? null : doctype;
+ },
+ get_user_permission: function() {
+ // autosuggest hack!
+ var user_permission = this.filters.user_permission.$input.val();
+ return (user_permission === "%") ? null : user_permission;
+ },
+ render: function(prop_list) {
+ this.body.empty();
+ this.prop_list = prop_list;
+ if(!prop_list || !prop_list.length) {
+ this.add_message(__("No User Permissions found."));
+ } else {
+ this.show_user_permissions_table();
+ }
+ this.show_add_user_permission();
+ },
+ add_message: function(txt) {
+ $('' + txt + '
').appendTo(this.body);
+ },
+ refresh: function() {
+ var me = this;
+ if(!me.filters.user) {
+ this.body.html(""+__("Loading")+"...
");
+ return;
+ }
+ if(!me.get_user() && !me.get_doctype()) {
+ this.body.html(""+__("Select User or DocType to start.")+"
");
+ return;
+ }
+ // get permissions
+ return frappe.call({
+ module: "frappe.core",
+ page: "user_permissions",
+ method: "get_permissions",
+ args: {
+ parent: me.get_user(),
+ defkey: me.get_doctype(),
+ defvalue: me.get_user_permission()
+ },
+ callback: function(r) {
+ me.render(r.message);
+ }
+ });
+ },
+ show_user_permissions_table: function() {
+ var me = this;
+ this.table = $("").appendTo(this.body);
+
+ $.each([[__("User"), 150], [__("DocType"), 150], [__("User Permission"),150], ["", 50]],
+ function(i, col) {
+ $("").html(col[0]).css("width", col[1]+"px")
+ .appendTo(me.table.find("thead tr"));
+ });
+
+
+ $.each(this.prop_list, function(i, d) {
+ var row = $(" ").appendTo(me.table.find("tbody"));
+
+ $("").html(''
+ +d.parent+' ').appendTo(row);
+ $(" ").html(d.defkey).appendTo(row);
+ $(" ").html(d.defvalue).appendTo(row);
+
+ me.add_delete_button(row, d);
+ });
+
+ },
+ add_delete_button: function(row, d) {
+ var me = this;
+ $(" ")
+ .appendTo($(" ").appendTo(row))
+ .attr("data-name", d.name)
+ .attr("data-user", d.parent)
+ .attr("data-defkey", d.defkey)
+ .attr("data-defvalue", d.defvalue)
+ .click(function() {
+ return frappe.call({
+ module: "frappe.core",
+ page: "user_permissions",
+ method: "remove",
+ args: {
+ name: $(this).attr("data-name"),
+ user: $(this).attr("data-user"),
+ defkey: $(this).attr("data-defkey"),
+ defvalue: $(this).attr("data-defvalue")
+ },
+ callback: function(r) {
+ if(r.exc) {
+ msgprint(__("Did not remove"));
+ } else {
+ me.refresh();
+ }
+ }
+ })
+ });
+ },
+
+ show_add_user_permission: function() {
+ var me = this;
+ $(""+__("Add A User Permission")+" ")
+ .appendTo($("").appendTo(this.body))
+ .click(function() {
+ var d = new frappe.ui.Dialog({
+ title: "Add New User Permission",
+ fields: [
+ {fieldtype:"Select", label:__("User"),
+ options:me.options.users, reqd:1, fieldname:"user"},
+ {fieldtype:"Select", label: __("DocType"), fieldname:"defkey",
+ options:me.get_link_names(), reqd:1},
+ {fieldtype:"Link", label:__("Value"), fieldname:"defvalue",
+ options:'[Select]', reqd:1},
+ {fieldtype:"Button", label: __("Add"), fieldname:"add"},
+ ]
+ });
+ if(me.get_user()) {
+ d.set_value("user", me.get_user());
+ d.get_input("user").prop("disabled", true);
+ }
+ if(me.get_doctype()) {
+ d.set_value("defkey", me.get_doctype());
+ d.get_input("defkey").prop("disabled", true);
+ }
+ if(me.get_user_permission()) {
+ d.set_value("defvalue", me.get_user_permission());
+ d.get_input("defvalue").prop("disabled", true);
+ }
+
+ d.fields_dict["defvalue"].get_query = function(txt) {
+ return {
+ doctype: d.get_value("defkey")
+ }
+ };
+
+ d.get_input("add").click(function() {
+ var args = d.get_values();
+ if(!args) {
+ return;
+ }
+ frappe.call({
+ module: "frappe.core",
+ page: "user_permissions",
+ method: "add",
+ args: args,
+ callback: function(r) {
+ if(r.exc) {
+ msgprint("Did not add");
+ } else {
+ me.refresh();
+ }
+ }
+ })
+ d.hide();
+ });
+ d.show();
+ });
+ }
+})
diff --git a/frappe/core/page/user_permissions/user_permissions.json b/frappe/core/page/user_permissions/user_permissions.json
new file mode 100644
index 0000000000..f4e5d95ae5
--- /dev/null
+++ b/frappe/core/page/user_permissions/user_permissions.json
@@ -0,0 +1,19 @@
+{
+ "content": null,
+ "creation": "2013-01-01 18:50:55",
+ "docstatus": 0,
+ "doctype": "Page",
+ "icon": "icon-user",
+ "idx": 1,
+ "modified": "2014-05-28 16:53:43.103533",
+ "modified_by": "Administrator",
+ "module": "Core",
+ "name": "user-permissions",
+ "owner": "Administrator",
+ "page_name": "user-permissions",
+ "roles": [],
+ "script": null,
+ "standard": "Yes",
+ "style": null,
+ "title": "User Permissions Manager"
+}
\ No newline at end of file
diff --git a/frappe/core/page/user_permissions/user_permissions.py b/frappe/core/page/user_permissions/user_permissions.py
new file mode 100644
index 0000000000..ef5a86c2b7
--- /dev/null
+++ b/frappe/core/page/user_permissions/user_permissions.py
@@ -0,0 +1,108 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+import frappe.defaults
+import frappe.permissions
+from frappe.core.doctype.user.user import get_system_users
+from frappe.utils.csvutils import UnicodeWriter, read_csv_content_from_uploaded_file
+from frappe.defaults import clear_default
+
+@frappe.whitelist()
+def get_users_and_links():
+ return {
+ "users": get_system_users(),
+ "link_fields": get_doctypes_for_user_permissions()
+ }
+
+@frappe.whitelist()
+def get_permissions(parent=None, defkey=None, defvalue=None):
+ if defkey and not frappe.permissions.can_set_user_permissions(defkey, defvalue):
+ raise frappe.PermissionError
+
+ conditions, values = _build_conditions(locals())
+
+ permissions = frappe.db.sql("""select name, parent, defkey, defvalue
+ from tabDefaultValue
+ where parent not in ('__default', '__global')
+ and substr(defkey,1,1)!='_'
+ and parenttype='User Permission'
+ {conditions}
+ order by parent, defkey""".format(conditions=conditions), values, as_dict=True)
+
+ if not defkey:
+ out = []
+ doctypes = get_doctypes_for_user_permissions()
+ for p in permissions:
+ if p.defkey in doctypes:
+ out.append(p)
+ permissions = out
+
+ return permissions
+
+def _build_conditions(filters):
+ conditions = []
+ values = {}
+ for key, value in filters.items():
+ if filters.get(key):
+ conditions.append("and `{key}`=%({key})s".format(key=key))
+ values[key] = value
+
+ return "\n".join(conditions), values
+
+@frappe.whitelist()
+def remove(user, name, defkey, defvalue):
+ if not frappe.permissions.can_set_user_permissions(defkey, defvalue):
+ frappe.throw(_("Cannot remove permission for DocType: {0} and Name: {1}").format(
+ defkey, defvalue), frappe.PermissionError)
+
+ frappe.permissions.remove_user_permission(defkey, defvalue, user, name)
+
+@frappe.whitelist()
+def add(user, defkey, defvalue):
+ if not frappe.permissions.can_set_user_permissions(defkey, defvalue):
+ frappe.throw(_("Cannot set permission for DocType: {0} and Name: {1}").format(
+ defkey, defvalue), frappe.PermissionError)
+
+ frappe.permissions.add_user_permission(defkey, defvalue, user, with_message=True)
+
+def get_doctypes_for_user_permissions():
+ user_roles = frappe.get_roles()
+ condition = ""
+ values = []
+ if "System Manager" not in user_roles:
+ condition = """and exists(select `tabDocPerm`.name from `tabDocPerm`
+ where `tabDocPerm`.parent=`tabDocType`.name and `tabDocPerm`.`set_user_permissions`=1
+ and `tabDocPerm`.role in ({roles}))""".format(roles=", ".join(["%s"]*len(user_roles)))
+ values = user_roles
+
+ return frappe.db.sql_list("""select name from tabDocType
+ where ifnull(issingle,0)=0 and ifnull(istable,0)=0 {condition}""".format(condition=condition),
+ tuple(values))
+
+@frappe.whitelist()
+def get_user_permissions_csv():
+ out = [["User Permissions"], ["User", "Document Type", "Value"]]
+ out += [[a.parent, a.defkey, a.defvalue] for a in get_permissions()]
+
+ csv = UnicodeWriter()
+ for row in out:
+ csv.writerow(row)
+
+ frappe.response['result'] = str(csv.getvalue())
+ frappe.response['type'] = 'csv'
+ frappe.response['doctype'] = "User Permissions"
+
+@frappe.whitelist()
+def import_user_permissions():
+ frappe.only_for("System Manager")
+ rows = read_csv_content_from_uploaded_file(ignore_encoding=True)
+ clear_default(parenttype="User Permission")
+
+ if rows[0][0]!="User Permissions" and rows[1][0] != "User":
+ frappe.throw(frappe._("Please upload using the same template as download."))
+
+ for row in rows[2:]:
+ frappe.permissions.add_user_permission(row[1], row[2], row[0])
diff --git a/frappe/core/page/user_properties/user_properties.js b/frappe/core/page/user_properties/user_properties.js
deleted file mode 100644
index 88f9e5088e..0000000000
--- a/frappe/core/page/user_properties/user_properties.js
+++ /dev/null
@@ -1,261 +0,0 @@
-frappe.pages['user-properties'].onload = function(wrapper) {
- frappe.ui.make_app_page({
- parent: wrapper,
- title: 'User Permission Restrictions',
- single_column: true
- });
- $(wrapper).find(".layout-main").html("
\
- \
- \
- "+__("Quick Help for Permission Restrictions")+": \
- \
- "+__("Apart from the existing Permission Rules, you can apply addition restriction based on Type.")+" \
- "+__("These restrictions will apply for all transactions linked to the restricted record.")
- +__("For example, if user X is restricted to company C, user X will not be able to see any transaction that has company C as a linked value.")+" \
- "+__("These will also be set as default values for those links.")+" \
- "+__("A user can be restricted to multiple records of the same type.")+" \
- \
- \
-
");
- wrapper.user_properties = new frappe.UserProperties(wrapper);
-}
-
-frappe.pages['user-properties'].refresh = function(wrapper) {
- wrapper.user_properties.set_from_route();
-}
-
-frappe.UserProperties = Class.extend({
- init: function(wrapper) {
- this.wrapper = wrapper;
- this.body = $(this.wrapper).find(".user-settings");
- this.filters = {};
- this.make();
- this.refresh();
- },
- make: function() {
- var me = this;
- return frappe.call({
- module:"frappe.core",
- page:"user_properties",
- method: "get_users_and_links",
- callback: function(r) {
- me.options = r.message;
-
- me.filters.user = me.wrapper.appframe.add_field({
- fieldname: "user",
- label: __("User"),
- fieldtype: "Select",
- options: (["Select User..."].concat(r.message.users)).join("\n")
- });
-
- me.filters.property = me.wrapper.appframe.add_field({
- fieldname: "property",
- label: __("Property"),
- fieldtype: "Select",
- options: (["Select Property..."].concat(me.get_link_names())).join("\n")
- });
-
- me.filters.restriction = me.wrapper.appframe.add_field({
- fieldname: "restriction",
- label: __("Restriction"),
- fieldtype: "Link",
- options: "[Select]"
- });
-
- // bind change event
- $.each(me.filters, function(k, f) {
- f.$input.on("change", function() {
- me.refresh();
- });
- });
-
- // change options in restriction link
- me.filters.property.$input.on("change", function() {
- me.filters.restriction.df.options = $(this).val();
- });
-
- me.set_from_route();
- }
- });
- },
- get_link_names: function() {
- return this.options.link_fields;
- },
- set_from_route: function() {
- var me = this;
- if(frappe.route_options && this.filters && !$.isEmptyObject(this.filters)) {
- $.each(frappe.route_options, function(key, value) {
- if(me.filters[key] && frappe.route_options[key]!=null)
- me.set_filter(key, value);
- });
- frappe.route_options = null;
- }
- this.refresh();
- },
- set_filter: function(key, value) {
- this.filters[key].$input.val(value);
- },
- get_user: function() {
- var user = this.filters.user.$input.val();
- return user=="Select User..." ? null : user;
- },
- get_property: function() {
- var property = this.filters.property.$input.val();
- return property=="Select Property..." ? null : property;
- },
- get_restriction: function() {
- // autosuggest hack!
- var restriction = this.filters.restriction.$input.val();
- return (restriction === "%") ? null : restriction;
- },
- render: function(prop_list) {
- this.body.empty();
- this.prop_list = prop_list;
- if(!prop_list || !prop_list.length) {
- this.body.html(""+__("No User Restrictions found.")+"
");
- } else {
- this.show_property_table();
- }
- this.show_add_property();
- },
- refresh: function() {
- var me = this;
- if(!me.filters.user) {
- this.body.html(""+__("Loading")+"...
");
- return;
- }
- if(!me.get_user() && !me.get_property()) {
- this.body.html(""+__("Select User or Property to start.")+"
");
- return;
- }
- // get permissions
- return frappe.call({
- module: "frappe.core",
- page: "user_properties",
- method: "get_properties",
- args: {
- parent: me.get_user(),
- defkey: me.get_property(),
- defvalue: me.get_restriction()
- },
- callback: function(r) {
- me.render(r.message);
- }
- });
- },
- show_property_table: function() {
- var me = this;
- this.table = $("").appendTo(this.body);
-
- $.each([[__("User"), 150], [__("Type"), 150], [__("Restricted To"),150], ["", 50]],
- function(i, col) {
- $(" ").html(col[0]).css("width", col[1]+"px")
- .appendTo(me.table.find("thead tr"));
- });
-
-
- $.each(this.prop_list, function(i, d) {
- var row = $(" ").appendTo(me.table.find("tbody"));
-
- $("").html(''
- +d.parent+' ').appendTo(row);
- $(" ").html(d.defkey).appendTo(row);
- $(" ").html(d.defvalue).appendTo(row);
-
- me.add_delete_button(row, d);
- });
-
- },
- add_delete_button: function(row, d) {
- var me = this;
- $(" ")
- .appendTo($(" ").appendTo(row))
- .attr("data-name", d.name)
- .attr("data-user", d.parent)
- .attr("data-defkey", d.defkey)
- .attr("data-defvalue", d.defvalue)
- .click(function() {
- return frappe.call({
- module: "frappe.core",
- page: "user_properties",
- method: "remove",
- args: {
- name: $(this).attr("data-name"),
- user: $(this).attr("data-user"),
- defkey: $(this).attr("data-defkey"),
- defvalue: $(this).attr("data-defvalue")
- },
- callback: function(r) {
- if(r.exc) {
- msgprint(__("Did not remove"));
- } else {
- me.refresh();
- }
- }
- })
- });
- },
-
- show_add_property: function() {
- var me = this;
- $(""+__("Add A Restriction")+" ")
- .appendTo($("").appendTo(this.body))
- .click(function() {
- var d = new frappe.ui.Dialog({
- title: "Add New Property",
- fields: [
- {fieldtype:"Select", label:__("User"),
- options:me.options.users, reqd:1, fieldname:"user"},
- {fieldtype:"Select", label: __("Property"), fieldname:"defkey",
- options:me.get_link_names(), reqd:1},
- {fieldtype:"Link", label:__("Value"), fieldname:"defvalue",
- options:'[Select]', reqd:1},
- {fieldtype:"Button", label: __("Add"), fieldname:"add"},
- ]
- });
- if(me.get_user()) {
- d.set_value("user", me.get_user());
- d.get_input("user").prop("disabled", true);
- }
- if(me.get_property()) {
- d.set_value("defkey", me.get_property());
- d.get_input("defkey").prop("disabled", true);
- }
- if(me.get_restriction()) {
- d.set_value("defvalue", me.get_restriction());
- d.get_input("defvalue").prop("disabled", true);
- }
-
- d.fields_dict["defvalue"].get_query = function(txt) {
- return {
- doctype: d.get_value("defkey")
- }
- };
-
- d.get_input("add").click(function() {
- var args = d.get_values();
- if(!args) {
- return;
- }
- frappe.call({
- module: "frappe.core",
- page: "user_properties",
- method: "add",
- args: args,
- callback: function(r) {
- if(r.exc) {
- msgprint("Did not add");
- } else {
- me.refresh();
- }
- }
- })
- d.hide();
- });
- d.show();
- });
- }
-})
diff --git a/frappe/core/page/user_properties/user_properties.json b/frappe/core/page/user_properties/user_properties.json
deleted file mode 100644
index 414b7a5b8d..0000000000
--- a/frappe/core/page/user_properties/user_properties.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "creation": "2013-01-01 18:50:55.000000",
- "docstatus": 0,
- "doctype": "Page",
- "icon": "icon-user",
- "idx": 1,
- "modified": "2014-03-13 11:11:56.000000",
- "modified_by": "Administrator",
- "module": "Core",
- "name": "user-properties",
- "owner": "Administrator",
- "page_name": "user-properties",
- "roles": [
- {
- "role": "System Manager"
- }
- ],
- "standard": "Yes",
- "title": "User Properties"
-}
\ No newline at end of file
diff --git a/frappe/core/page/user_properties/user_properties.py b/frappe/core/page/user_properties/user_properties.py
deleted file mode 100644
index 303329dc62..0000000000
--- a/frappe/core/page/user_properties/user_properties.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-import frappe.defaults
-import frappe.permissions
-from frappe.core.doctype.user.user import get_system_users
-
-@frappe.whitelist()
-def get_users_and_links():
- return {
- "users": get_system_users(),
- "link_fields": get_restrictable_doctypes()
- }
-
-@frappe.whitelist()
-def get_properties(parent=None, defkey=None, defvalue=None):
- if defkey and not frappe.permissions.can_restrict(defkey, defvalue):
- raise frappe.PermissionError
-
- conditions, values = _build_conditions(locals())
-
- properties = frappe.db.sql("""select name, parent, defkey, defvalue
- from tabDefaultValue
- where parent not in ('__default', '__global')
- and substr(defkey,1,1)!='_'
- and parenttype='Restriction'
- {conditions}
- order by parent, defkey""".format(conditions=conditions), values, as_dict=True)
-
- if not defkey:
- out = []
- doctypes = get_restrictable_doctypes()
- for p in properties:
- if p.defkey in doctypes:
- out.append(p)
- properties = out
-
- return properties
-
-def _build_conditions(filters):
- conditions = []
- values = {}
- for key, value in filters.items():
- if filters.get(key):
- conditions.append("and `{key}`=%({key})s".format(key=key))
- values[key] = value
-
- return "\n".join(conditions), values
-
-@frappe.whitelist()
-def remove(user, name, defkey, defvalue):
- if not frappe.permissions.can_restrict_user(user, defkey, defvalue):
- raise frappe.PermissionError("Cannot Remove Restriction for User: {user} on DocType: {doctype} and Name: {name}".format(
- user=user, doctype=defkey, name=defvalue))
-
- frappe.defaults.clear_default(key=defkey, value=defvalue, parent=user, name=name)
-
-def clear_restrictions(doctype):
- frappe.defaults.clear_default(parenttype="Restriction", key=doctype)
-
-@frappe.whitelist()
-def add(user, defkey, defvalue):
- if not frappe.permissions.can_restrict_user(user, defkey, defvalue):
- raise frappe.PermissionError("Cannot Restrict User: {user} for DocType: {doctype} and Name: {name}".format(
- user=user, doctype=defkey, name=defvalue))
-
- # check if already exists
- d = frappe.db.sql("""select name from tabDefaultValue
- where parent=%s and parenttype='Restriction' and defkey=%s and defvalue=%s""", (user, defkey, defvalue))
-
- if not d:
- frappe.defaults.add_default(defkey, defvalue, user, "Restriction")
-
-def get_restrictable_doctypes():
- user_roles = frappe.get_roles()
- condition = ""
- values = []
- if "System Manager" not in user_roles:
- condition = """and exists(select `tabDocPerm`.name from `tabDocPerm`
- where `tabDocPerm`.parent=`tabDocType`.name and `tabDocPerm`.`restrict`=1
- and `tabDocPerm`.role in ({roles}))""".format(roles=", ".join(["%s"]*len(user_roles)))
- values = user_roles
-
- return frappe.db.sql_list("""select name from tabDocType
- where ifnull(issingle,0)=0 and ifnull(istable,0)=0 {condition}""".format(condition=condition),
- tuple(values))
diff --git a/frappe/core/report/permitted_documents_for_user/__init__.py b/frappe/core/report/permitted_documents_for_user/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js
new file mode 100644
index 0000000000..f379963284
--- /dev/null
+++ b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+// MIT License. See license.txt
+
+frappe.query_reports["Permitted Documents For User"] = {
+ "filters": [
+ {
+ "fieldname": "user",
+ "label": __("User"),
+ "fieldtype": "Link",
+ "options": "User",
+ "reqd": 1
+ },
+ {
+ "fieldname": "doctype",
+ "label": __("DocType"),
+ "fieldtype": "Link",
+ "options": "DocType",
+ "reqd": 1,
+ "get_query": function() {
+ return {
+ "query": "frappe.core.report.permitted_documents_for_user.permitted_documents_for_user.query_doctypes",
+ "filters": {
+ "user": frappe.query_report.filters_by_name.user.get_value()
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.json b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.json
new file mode 100644
index 0000000000..458baa936c
--- /dev/null
+++ b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.json
@@ -0,0 +1,15 @@
+{
+ "apply_user_permissions": 1,
+ "creation": "2014-06-03 05:20:35.218263",
+ "docstatus": 0,
+ "doctype": "Report",
+ "is_standard": "Yes",
+ "modified": "2014-06-03 07:18:17.218526",
+ "modified_by": "Administrator",
+ "module": "Core",
+ "name": "Permitted Documents For User",
+ "owner": "Administrator",
+ "ref_doctype": "User",
+ "report_name": "Permitted Documents For User",
+ "report_type": "Script Report"
+}
\ No newline at end of file
diff --git a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py
new file mode 100644
index 0000000000..22777957b8
--- /dev/null
+++ b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _, throw
+import frappe.utils.user
+from frappe.permissions import check_admin_or_system_manager
+from frappe.model.db_schema import type_map
+
+def execute(filters=None):
+ user, doctype = filters.get("user"), filters.get("doctype")
+ validate(user, doctype)
+
+ columns, fields = get_columns_and_fields(doctype)
+ data = frappe.get_list(doctype, fields=fields, as_list=True, user=user)
+
+ return columns, data
+
+def validate(user, doctype):
+ # check if current user is System Manager
+ check_admin_or_system_manager()
+
+ if not user:
+ throw(_("Please specify user"))
+
+ if not doctype:
+ throw(_("Please specify doctype"))
+
+def get_columns_and_fields(doctype):
+ columns = ["Name:Link/{}:200".format(doctype)]
+ fields = ["name"]
+ for df in frappe.get_meta(doctype).fields:
+ if df.in_list_view and df.fieldtype in type_map:
+ fields.append(df.fieldname)
+ fieldtype = "Link/{}".format(df.options) if df.fieldtype=="Link" else df.fieldtype
+ columns.append("{label}:{fieldtype}:{width}".format(label=df.label, fieldtype=fieldtype, width=df.width or 100))
+
+ return columns, fields
+
+def query_doctypes(doctype, txt, searchfield, start, page_len, filters):
+ user = filters.get("user")
+ user_obj = frappe.utils.user.User(user)
+ user_obj.build_permissions()
+ can_read = user_obj.can_read
+
+ single_doctypes = [d[0] for d in frappe.db.get_values("DocType", {"issingle": 1})]
+
+ out = []
+ for dt in can_read:
+ if txt.lower().replace("%", "") in dt.lower() and dt not in single_doctypes:
+ out.append([dt])
+
+ return out
diff --git a/frappe/core/report/todo/todo.js b/frappe/core/report/todo/todo.js
index ff6cb20556..e69de29bb2 100644
--- a/frappe/core/report/todo/todo.js
+++ b/frappe/core/report/todo/todo.js
@@ -1 +0,0 @@
-__("Test") // for test case
\ No newline at end of file
diff --git a/frappe/core/report/todo/todo.json b/frappe/core/report/todo/todo.json
index 768162f126..f808571789 100644
--- a/frappe/core/report/todo/todo.json
+++ b/frappe/core/report/todo/todo.json
@@ -1,10 +1,11 @@
{
- "creation": "2013-02-25 14:26:30.000000",
+ "apply_user_permissions": 1,
+ "creation": "2013-02-25 14:26:30",
"docstatus": 0,
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
- "modified": "2014-03-07 15:30:27.000000",
+ "modified": "2014-06-03 07:18:17.374222",
"modified_by": "Administrator",
"module": "Core",
"name": "ToDo",
diff --git a/frappe/core/report/todo/todo.py b/frappe/core/report/todo/todo.py
index 0c5012962b..87f9496f6d 100644
--- a/frappe/core/report/todo/todo.py
+++ b/frappe/core/report/todo/todo.py
@@ -9,28 +9,28 @@ from frappe.utils import getdate
def execute(filters=None):
priority_map = {"High": 3, "Medium": 2, "Low": 1}
-
+
todo_list = runreport(doctype="ToDo", fields=["name", "date", "description",
- "priority", "reference_type", "reference_name", "assigned_by", "owner"],
- filters=[["ToDo", "checked", "!=", 1]])
-
- todo_list.sort(key=lambda todo: (priority_map.get(todo.priority, 0),
+ "priority", "reference_type", "reference_name", "assigned_by", "owner"],
+ filters=[["ToDo", "status", "=", "Open"]])
+
+ todo_list.sort(key=lambda todo: (priority_map.get(todo.priority, 0),
todo.date and getdate(todo.date) or getdate("1900-01-01")), reverse=True)
-
- columns = [_("ID")+":Link/ToDo:90", _("Priority")+"::60", _("Date")+ ":Date",
- _("Description")+"::150", _("Assigned To/Owner") + ":Data:120",
+
+ columns = [_("ID")+":Link/ToDo:90", _("Priority")+"::60", _("Date")+ ":Date",
+ _("Description")+"::150", _("Assigned To/Owner") + ":Data:120",
_("Assigned By")+":Data:120", _("Reference")+"::200"]
result = []
for todo in todo_list:
if todo.owner==frappe.session.user or todo.assigned_by==frappe.session.user:
if todo.reference_type:
- todo.reference = """%s: %s """ % (todo.reference_type,
+ todo.reference = """%s: %s """ % (todo.reference_type,
todo.reference_name, todo.reference_type, todo.reference_name)
else:
todo.reference = None
result.append([todo.name, todo.priority, todo.date, todo.description,
todo.owner, todo.assigned_by, todo.reference])
-
+
return columns, result
-
+
diff --git a/frappe/country_info.json b/frappe/country_info.json
index 318ecc2ec1..1624f330f4 100644
--- a/frappe/country_info.json
+++ b/frappe/country_info.json
@@ -1,2629 +1,2627 @@
{
"Afghanistan": {
- "code": "af",
- "currency_fraction": "Pul",
- "currency_fraction_units": 100,
- "currency_symbol": "\u060b",
- "number_format": "#,###.##",
+ "code": "af",
+ "currency_fraction": "Pul",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u060b",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Kabul"
]
- },
+ },
"Albania": {
- "code": "al",
- "currency": "ALL",
- "currency_fraction": "Qindark\u00eb",
- "currency_fraction_units": 100,
- "currency_name": "Lek",
- "currency_symbol": "L",
- "number_format": "#,###.##",
+ "code": "al",
+ "currency": "ALL",
+ "currency_fraction": "Qindark\u00eb",
+ "currency_fraction_units": 100,
+ "currency_name": "Lek",
+ "currency_symbol": "L",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Tirane"
]
- },
+ },
"Algeria": {
- "code": "dz",
- "currency": "DZD",
- "currency_fraction": "Santeem",
- "currency_fraction_units": 100,
- "currency_name": "Algerian Dinar",
- "currency_symbol": "\u062f.\u062c",
- "number_format": "#,###.##",
+ "code": "dz",
+ "currency": "DZD",
+ "currency_fraction": "Santeem",
+ "currency_fraction_units": 100,
+ "currency_name": "Algerian Dinar",
+ "currency_symbol": "\u062f.\u062c",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Algiers"
]
- },
+ },
"American Samoa": {
- "code": "as",
+ "code": "as",
"number_format": "#,###.##"
- },
+ },
"Andorra": {
- "code": "ad",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "ad",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Andorra"
]
- },
+ },
"Angola": {
- "code": "ao",
- "currency_fraction": "C\u00eantimo",
- "currency_fraction_units": 100,
- "currency_symbol": "Kz",
- "number_format": "#,###.##",
+ "code": "ao",
+ "currency_fraction": "C\u00eantimo",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Kz",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Luanda"
]
- },
+ },
"Anguilla": {
- "code": "ai",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ai",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Anguilla"
]
- },
+ },
"Antarctica": {
- "code": "aq",
- "number_format": "#,###.##",
- "timezones": [
- "Antarctica/Casey",
- "Antarctica/Davis",
- "Antarctica/DumontDUrville",
- "Antarctica/Macquarie",
- "Antarctica/Mawson",
- "Antarctica/McMurdo",
- "Antarctica/Palmer",
- "Antarctica/Rothera",
- "Antarctica/South_Pole",
- "Antarctica/Syowa",
+ "code": "aq",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Antarctica/Casey",
+ "Antarctica/Davis",
+ "Antarctica/DumontDUrville",
+ "Antarctica/Macquarie",
+ "Antarctica/Mawson",
+ "Antarctica/McMurdo",
+ "Antarctica/Palmer",
+ "Antarctica/Rothera",
+ "Antarctica/Syowa",
"Antarctica/Vostok"
]
- },
+ },
"Antigua and Barbuda": {
- "code": "ag",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ag",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Antigua"
]
- },
+ },
"Argentina": {
- "code": "ar",
- "currency": "ARS",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Argentine Peso",
- "currency_symbol": "$",
- "number_format": "#.###,##",
- "timezones": [
- "America/Argentina/Buenos_Aires",
- "America/Argentina/Catamarca",
- "America/Argentina/Cordoba",
- "America/Argentina/Jujuy",
- "America/Argentina/La_Rioja",
- "America/Argentina/Mendoza",
- "America/Argentina/Rio_Gallegos",
- "America/Argentina/Salta",
- "America/Argentina/San_Juan",
- "America/Argentina/San_Luis",
- "America/Argentina/Tucuman",
+ "code": "ar",
+ "currency": "ARS",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Argentine Peso",
+ "currency_symbol": "$",
+ "number_format": "#.###,##",
+ "timezones": [
+ "America/Argentina/Buenos_Aires",
+ "America/Argentina/Catamarca",
+ "America/Argentina/Cordoba",
+ "America/Argentina/Jujuy",
+ "America/Argentina/La_Rioja",
+ "America/Argentina/Mendoza",
+ "America/Argentina/Rio_Gallegos",
+ "America/Argentina/Salta",
+ "America/Argentina/San_Juan",
+ "America/Argentina/San_Luis",
+ "America/Argentina/Tucuman",
"America/Argentina/Ushuaia"
]
- },
+ },
"Armenia": {
- "code": "am",
- "currency": "AMD",
- "currency_fraction": "Luma",
- "currency_fraction_units": 100,
- "currency_name": "Armenian Dram",
- "currency_symbol": "\u058f",
- "number_format": "#,###.##",
+ "code": "am",
+ "currency": "AMD",
+ "currency_fraction": "Luma",
+ "currency_fraction_units": 100,
+ "currency_name": "Armenian Dram",
+ "currency_symbol": "\u058f",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Yerevan"
]
- },
+ },
"Aruba": {
- "code": "aw",
- "currency": "AWG",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Aruban Florin",
- "currency_symbol": "Afl",
- "number_format": "#,###.##",
+ "code": "aw",
+ "currency": "AWG",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Aruban Florin",
+ "currency_symbol": "Afl",
+ "number_format": "#,###.##",
"timezones": [
"America/Aruba"
]
- },
+ },
"Australia": {
- "code": "au",
- "currency": "AUD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Australian Dollar",
- "currency_symbol": "$",
- "number_format": "# ###.##",
- "timezones": [
- "Australia/Adelaide",
- "Australia/Brisbane",
- "Australia/Broken_Hill",
- "Australia/Currie",
- "Australia/Darwin",
- "Australia/Eucla",
- "Australia/Hobart",
- "Australia/Lindeman",
- "Australia/Lord_Howe",
- "Australia/Melbourne",
- "Australia/Perth",
+ "code": "au",
+ "currency": "AUD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Australian Dollar",
+ "currency_symbol": "$",
+ "number_format": "# ###.##",
+ "timezones": [
+ "Australia/Adelaide",
+ "Australia/Brisbane",
+ "Australia/Broken_Hill",
+ "Australia/Currie",
+ "Australia/Darwin",
+ "Australia/Eucla",
+ "Australia/Hobart",
+ "Australia/Lindeman",
+ "Australia/Lord_Howe",
+ "Australia/Melbourne",
+ "Australia/Perth",
"Australia/Sydney"
]
- },
+ },
"Austria": {
- "code": "at",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "at",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Vienna"
]
- },
+ },
"Azerbaijan": {
- "code": "az",
- "currency_fraction": "Q\u0259pik",
- "currency_fraction_units": 100,
- "currency_symbol": "",
- "number_format": "#,###.##",
+ "code": "az",
+ "currency_fraction": "Q\u0259pik",
+ "currency_fraction_units": 100,
+ "currency_symbol": "",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Baku"
]
- },
+ },
"Bahamas": {
- "code": "bs",
- "currency": "BSD",
- "currency_name": "Bahamian Dollar",
- "number_format": "#,###.##",
+ "code": "bs",
+ "currency": "BSD",
+ "currency_name": "Bahamian Dollar",
+ "number_format": "#,###.##",
"timezones": [
"America/Nassau"
]
- },
+ },
"Bahrain": {
- "code": "bh",
- "currency": "BHD",
- "currency_fraction": "Fils",
- "currency_fraction_units": 1000,
- "currency_name": "Bahraini Dinar",
- "currency_symbol": ".\u062f.\u0628",
- "number_format": "#,###.###",
+ "code": "bh",
+ "currency": "BHD",
+ "currency_fraction": "Fils",
+ "currency_fraction_units": 1000,
+ "currency_name": "Bahraini Dinar",
+ "currency_symbol": ".\u062f.\u0628",
+ "number_format": "#,###.###",
"timezones": [
"Asia/Bahrain"
]
- },
+ },
"Bangladesh": {
- "code": "bd",
- "currency": "BDT",
- "currency_fraction": "Paisa",
- "currency_fraction_units": 100,
- "currency_name": "Taka",
- "currency_symbol": "\u09f3",
- "number_format": "#,###.##",
+ "code": "bd",
+ "currency": "BDT",
+ "currency_fraction": "Paisa",
+ "currency_fraction_units": 100,
+ "currency_name": "Taka",
+ "currency_symbol": "\u09f3",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Dhaka"
]
- },
+ },
"Barbados": {
- "code": "bb",
- "currency": "BBD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Barbados Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "bb",
+ "currency": "BBD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Barbados Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Barbados"
]
- },
+ },
"Belarus": {
- "code": "by",
- "currency_fraction": "Kapyeyka",
- "currency_fraction_units": 100,
- "currency_symbol": "Br",
- "number_format": "#,###.##",
+ "code": "by",
+ "currency_fraction": "Kapyeyka",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Br",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Minsk"
]
- },
+ },
"Belgium": {
- "code": "be",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "be",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Brussels"
]
- },
+ },
"Belize": {
- "code": "bz",
- "currency": "BZD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Belize Dollar",
- "currency_symbol": "$",
- "date_format": "mm-dd-yyyy",
- "number_format": "#,###.##",
+ "code": "bz",
+ "currency": "BZD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Belize Dollar",
+ "currency_symbol": "$",
+ "date_format": "mm-dd-yyyy",
+ "number_format": "#,###.##",
"timezones": [
"America/Belize"
]
- },
+ },
"Benin": {
- "code": "bj",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "bj",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Porto-Novo"
]
- },
+ },
"Bermuda": {
- "code": "bm",
- "currency": "BMD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Bermudian Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "bm",
+ "currency": "BMD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Bermudian Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Atlantic/Bermuda"
]
- },
+ },
"Bhutan": {
- "code": "bt",
- "currency": "BTN",
- "currency_fraction": "Chetrum",
- "currency_fraction_units": 100,
- "currency_name": "Ngultrum",
- "currency_symbol": "Nu.",
- "number_format": "#,###.##",
+ "code": "bt",
+ "currency": "BTN",
+ "currency_fraction": "Chetrum",
+ "currency_fraction_units": 100,
+ "currency_name": "Ngultrum",
+ "currency_symbol": "Nu.",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Thimphu"
]
- },
+ },
"Bolivia, Plurinational State of": {
- "code": "bo",
- "currency": "BOB",
- "currency_name": "Boliviano",
+ "code": "bo",
+ "currency": "BOB",
+ "currency_name": "Boliviano",
"number_format": "#,###.##"
- },
+ },
"Bonaire, Sint Eustatius and Saba": {
- "code": "bq",
+ "code": "bq",
"number_format": "#,###.##"
- },
+ },
"Bosnia and Herzegovina": {
- "code": "ba",
- "currency_fraction": "Fening",
- "currency_fraction_units": 100,
- "currency_symbol": "KM or \u041a\u041c",
- "number_format": "#,###.##",
+ "code": "ba",
+ "currency_fraction": "Fening",
+ "currency_fraction_units": 100,
+ "currency_symbol": "KM or \u041a\u041c",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Sarajevo"
+ "Europe/Belgrade"
]
- },
+ },
"Botswana": {
- "code": "bw",
- "currency": "BWP",
- "currency_fraction": "Thebe",
- "currency_fraction_units": 100,
- "currency_name": "Pula",
- "currency_symbol": "P",
- "number_format": "#,###.##",
+ "code": "bw",
+ "currency": "BWP",
+ "currency_fraction": "Thebe",
+ "currency_fraction_units": 100,
+ "currency_name": "Pula",
+ "currency_symbol": "P",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Gaborone"
]
- },
+ },
"Bouvet Island": {
- "code": "bv",
+ "code": "bv",
"number_format": "#,###.##"
- },
+ },
"Brazil": {
- "code": "br",
- "currency": "BRL",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_symbol": "R$",
- "date_format": "dd/mm/yyyy",
- "number_format": "#.###,##",
- "timezones": [
- "America/Araguaina",
- "America/Bahia",
- "America/Belem",
- "America/Boa_Vista",
- "America/Campo_Grande",
- "America/Cuiaba",
- "America/Eirunepe",
- "America/Fortaleza",
- "America/Maceio",
- "America/Manaus",
- "America/Noronha",
- "America/Porto_Velho",
- "America/Recife",
- "America/Rio_Branco",
- "America/Santarem",
+ "code": "br",
+ "currency": "BRL",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_symbol": "R$",
+ "date_format": "dd/mm/yyyy",
+ "number_format": "#.###,##",
+ "timezones": [
+ "America/Araguaina",
+ "America/Bahia",
+ "America/Belem",
+ "America/Boa_Vista",
+ "America/Campo_Grande",
+ "America/Cuiaba",
+ "America/Eirunepe",
+ "America/Fortaleza",
+ "America/Maceio",
+ "America/Manaus",
+ "America/Noronha",
+ "America/Porto_Velho",
+ "America/Recife",
+ "America/Rio_Branco",
+ "America/Santarem",
"America/Sao_Paulo"
]
- },
+ },
"British Indian Ocean Territory": {
- "code": "io",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "io",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Chagos"
]
- },
+ },
"Brunei Darussalam": {
- "code": "bn",
- "currency": "BND",
- "currency_name": "Brunei Dollar",
- "number_format": "#,###.##",
+ "code": "bn",
+ "currency": "BND",
+ "currency_name": "Brunei Dollar",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Brunei"
]
- },
+ },
"Bulgaria": {
- "code": "bg",
- "currency_fraction": "Stotinka",
- "currency_fraction_units": 100,
- "currency_symbol": "\u043b\u0432",
- "number_format": "#,###.##",
+ "code": "bg",
+ "currency_fraction": "Stotinka",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u043b\u0432",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Sofia"
]
- },
+ },
"Burkina Faso": {
- "code": "bf",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "bf",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Ouagadougou"
]
- },
+ },
"Burundi": {
- "code": "bi",
- "currency": "BIF",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Burundi Franc",
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "bi",
+ "currency": "BIF",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Burundi Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Bujumbura"
]
- },
+ },
"Cambodia": {
- "code": "kh",
- "currency": "KHR",
- "currency_fraction": "Sen",
- "currency_fraction_units": 100,
- "currency_name": "Riel",
- "currency_symbol": "\u17db",
- "number_format": "#,###.##",
+ "code": "kh",
+ "currency": "KHR",
+ "currency_fraction": "Sen",
+ "currency_fraction_units": 100,
+ "currency_name": "Riel",
+ "currency_symbol": "\u17db",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Phnom_Penh"
]
- },
+ },
"Cameroon": {
- "code": "cm",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "cm",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Douala"
]
- },
+ },
"Canada": {
- "code": "ca",
- "currency": "CAD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Canadian Dollar",
- "currency_symbol": "$",
- "date_format": "mm-dd-yyyy",
- "number_format": "#,###.##",
- "timezones": [
- "America/Atikokan",
- "America/Blanc-Sablon",
- "America/Cambridge_Bay",
- "America/Creston",
- "America/Dawson",
- "America/Dawson_Creek",
- "America/Edmonton",
- "America/Glace_Bay",
- "America/Goose_Bay",
- "America/Halifax",
- "America/Inuvik",
- "America/Iqaluit",
- "America/Moncton",
- "America/Montreal",
- "America/Nipigon",
- "America/Pangnirtung",
- "America/Rainy_River",
- "America/Rankin_Inlet",
- "America/Regina",
- "America/Resolute",
- "America/St_Johns",
- "America/Swift_Current",
- "America/Thunder_Bay",
- "America/Toronto",
- "America/Vancouver",
- "America/Whitehorse",
- "America/Winnipeg",
+ "code": "ca",
+ "currency": "CAD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Canadian Dollar",
+ "currency_symbol": "$",
+ "date_format": "mm-dd-yyyy",
+ "number_format": "#,###.##",
+ "timezones": [
+ "America/Atikokan",
+ "America/Blanc-Sablon",
+ "America/Cambridge_Bay",
+ "America/Creston",
+ "America/Dawson",
+ "America/Dawson_Creek",
+ "America/Edmonton",
+ "America/Glace_Bay",
+ "America/Goose_Bay",
+ "America/Halifax",
+ "America/Inuvik",
+ "America/Iqaluit",
+ "America/Moncton",
+ "America/Montreal",
+ "America/Nipigon",
+ "America/Pangnirtung",
+ "America/Rainy_River",
+ "America/Rankin_Inlet",
+ "America/Regina",
+ "America/Resolute",
+ "America/St_Johns",
+ "America/Swift_Current",
+ "America/Thunder_Bay",
+ "America/Toronto",
+ "America/Vancouver",
+ "America/Whitehorse",
+ "America/Winnipeg",
"America/Yellowknife"
]
- },
+ },
"Cape Verde": {
- "code": "cv",
- "currency": "CVE",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Cape Verde Escudo",
- "currency_symbol": "Esc or $",
- "number_format": "#,###.##",
+ "code": "cv",
+ "currency": "CVE",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Cape Verde Escudo",
+ "currency_symbol": "Esc or $",
+ "number_format": "#,###.##",
"timezones": [
"Atlantic/Cape_Verde"
]
- },
+ },
"Cayman Islands": {
- "code": "ky",
- "currency": "KYD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Cayman Islands Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ky",
+ "currency": "KYD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Cayman Islands Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Cayman"
]
- },
+ },
"Central African Republic": {
- "code": "cf",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "cf",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Bangui"
]
- },
+ },
"Chad": {
- "code": "td",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "td",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Ndjamena"
]
- },
+ },
"Chile": {
- "code": "cl",
- "currency": "CLP",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Chilean Peso",
- "currency_symbol": "$",
- "number_format": "#.###",
- "timezones": [
- "America/Santiago",
+ "code": "cl",
+ "currency": "CLP",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Chilean Peso",
+ "currency_symbol": "$",
+ "number_format": "#.###",
+ "timezones": [
+ "America/Santiago",
"Pacific/Easter"
]
- },
+ },
"China": {
- "code": "cn",
- "currency": "CNY",
- "currency_name": "Yuan Renminbi",
- "date_format": "yyyy-mm-dd",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Chongqing",
- "Asia/Harbin",
- "Asia/Kashgar",
- "Asia/Shanghai",
+ "code": "cn",
+ "currency": "CNY",
+ "currency_name": "Yuan Renminbi",
+ "date_format": "yyyy-mm-dd",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Chongqing",
+ "Asia/Harbin",
+ "Asia/Kashgar",
+ "Asia/Shanghai",
"Asia/Urumqi"
]
- },
+ },
"Christmas Island": {
- "code": "cx",
- "number_format": "#,###.##",
+ "code": "cx",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Christmas"
]
- },
+ },
"Cocos (Keeling) Islands": {
- "code": "cc",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "cc",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Cocos"
]
- },
+ },
"Colombia": {
- "code": "co",
- "currency": "COP",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Colombian Peso",
- "currency_symbol": "$",
- "number_format": "#.###,##",
+ "code": "co",
+ "currency": "COP",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Colombian Peso",
+ "currency_symbol": "$",
+ "number_format": "#.###,##",
"timezones": [
"America/Bogota"
]
- },
+ },
"Comoros": {
- "code": "km",
- "currency": "KMF",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Comoro Franc",
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "km",
+ "currency": "KMF",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Comoro Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Comoro"
]
- },
+ },
"Congo": {
- "code": "cg",
+ "code": "cg",
"number_format": "#,###.##"
- },
+ },
"Congo, The Democratic Republic of the": {
"number_format": "#,###.##"
- },
+ },
"Cook Islands": {
- "code": "ck",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ck",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Rarotonga"
]
- },
+ },
"Costa Rica": {
- "code": "cr",
- "currency": "CRC",
- "currency_fraction": "C\u00e9ntimo",
- "currency_fraction_units": 100,
- "currency_name": "Costa Rican Colon",
- "currency_symbol": "\u20a1",
- "number_format": "#.###,##",
+ "code": "cr",
+ "currency": "CRC",
+ "currency_fraction": "C\u00e9ntimo",
+ "currency_fraction_units": 100,
+ "currency_name": "Costa Rican Colon",
+ "currency_symbol": "\u20a1",
+ "number_format": "#.###,##",
"timezones": [
"America/Costa_Rica"
]
- },
+ },
"Croatia": {
- "code": "hr",
- "currency": "HRK",
- "currency_fraction": "Lipa",
- "currency_fraction_units": 100,
- "currency_name": "Croatian Kuna",
- "currency_symbol": "kn",
- "number_format": "#.###,##",
+ "code": "hr",
+ "currency": "HRK",
+ "currency_fraction": "Lipa",
+ "currency_fraction_units": 100,
+ "currency_name": "Croatian Kuna",
+ "currency_symbol": "kn",
+ "number_format": "#.###,##",
"timezones": [
- "Europe/Zagreb"
+ "Europe/Belgrade"
]
- },
+ },
"Cuba": {
- "code": "cu",
- "currency": "CUP",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Cuban Peso",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "cu",
+ "currency": "CUP",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Cuban Peso",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Havana"
]
- },
+ },
"Cura\u00e7ao": {
- "code": "cw",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u0192",
+ "code": "cw",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u0192",
"number_format": "#,###.##"
- },
+ },
"Cyprus": {
- "code": "cy",
- "currency": "CYP",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Cyprus Pound",
- "currency_symbol": "\u20ac",
- "number_format": "#.###,##",
+ "code": "cy",
+ "currency": "CYP",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Cyprus Pound",
+ "currency_symbol": "\u20ac",
+ "number_format": "#.###,##",
"timezones": [
"Asia/Nicosia"
]
- },
+ },
"Czech Republic": {
- "code": "cz",
- "currency": "CZK",
- "currency_fraction": "Hal\u00e9\u0159",
- "currency_fraction_units": 100,
- "currency_name": "Czech Koruna",
- "currency_symbol": "K\u010d",
- "number_format": "#.###,##",
+ "code": "cz",
+ "currency": "CZK",
+ "currency_fraction": "Hal\u00e9\u0159",
+ "currency_fraction_units": 100,
+ "currency_name": "Czech Koruna",
+ "currency_symbol": "K\u010d",
+ "number_format": "#.###,##",
"timezones": [
"Europe/Prague"
]
- },
+ },
"Denmark": {
- "code": "dk",
- "currency": "DKK",
- "currency_fraction": "\u00d8re",
- "currency_fraction_units": 100,
- "currency_name": "Danish Krone",
- "currency_symbol": "kr",
- "number_format": "#.###,##",
+ "code": "dk",
+ "currency": "DKK",
+ "currency_fraction": "\u00d8re",
+ "currency_fraction_units": 100,
+ "currency_name": "Danish Krone",
+ "currency_symbol": "kr",
+ "number_format": "#.###,##",
"timezones": [
"Europe/Copenhagen"
]
- },
+ },
"Djibouti": {
- "code": "dj",
- "currency": "DJF",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Djibouti Franc",
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "dj",
+ "currency": "DJF",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Djibouti Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Djibouti"
]
- },
+ },
"Dominica": {
- "code": "dm",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "dm",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Dominica"
]
- },
+ },
"Dominican Republic": {
- "code": "do",
- "currency": "DOP",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Dominican Peso",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "do",
+ "currency": "DOP",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Dominican Peso",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Santo_Domingo"
]
- },
+ },
"Ecuador": {
- "code": "ec",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ec",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
- "America/Guayaquil",
+ "America/Guayaquil",
"Pacific/Galapagos"
]
- },
+ },
"Egypt": {
- "code": "eg",
- "currency": "EGP",
- "currency_fraction": "Piastre[F]",
- "currency_fraction_units": 100,
- "currency_name": "Egyptian Pound",
- "currency_symbol": "\u00a3 or \u062c.\u0645",
- "number_format": "#,###.##",
+ "code": "eg",
+ "currency": "EGP",
+ "currency_fraction": "Piastre[F]",
+ "currency_fraction_units": 100,
+ "currency_name": "Egyptian Pound",
+ "currency_symbol": "\u00a3 or \u062c.\u0645",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Cairo"
]
- },
+ },
"El Salvador": {
- "code": "sv",
- "currency": "SVC",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "El Salvador Colon",
- "currency_symbol": "\u20a1",
- "number_format": "#,###.##",
+ "code": "sv",
+ "currency": "SVC",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "El Salvador Colon",
+ "currency_symbol": "\u20a1",
+ "number_format": "#,###.##",
"timezones": [
"America/El_Salvador"
]
- },
+ },
"Equatorial Guinea": {
- "code": "gq",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "gq",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Malabo"
]
- },
+ },
"Eritrea": {
- "code": "er",
- "currency": "ERN",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Nakfa",
- "currency_symbol": "Nfk",
- "number_format": "#,###.##",
- "timezones": [
- "Africa/Asmara",
- "Africa/Asmera"
- ]
- },
+ "code": "er",
+ "currency": "ERN",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Nakfa",
+ "currency_symbol": "Nfk",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Africa/Asmara"
+ ]
+ },
"Estonia": {
- "code": "ee",
- "currency": "EEK",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Kroon",
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "ee",
+ "currency": "EEK",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Kroon",
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Tallinn"
]
- },
+ },
"Ethiopia": {
- "code": "et",
- "currency_fraction": "Santim",
- "currency_fraction_units": 100,
- "currency_symbol": "Br",
- "number_format": "#,###.##",
+ "code": "et",
+ "currency_fraction": "Santim",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Br",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Addis_Ababa"
]
- },
+ },
"Falkland Islands (Malvinas)": {
- "code": "fk",
- "currency": "FKP",
- "currency_name": "Falkland Islands Pound",
+ "code": "fk",
+ "currency": "FKP",
+ "currency_name": "Falkland Islands Pound",
"number_format": "#,###.##"
- },
+ },
"Faroe Islands": {
- "code": "fo",
- "currency_fraction": "\u00d8re",
- "currency_fraction_units": 100,
- "currency_symbol": "kr",
- "number_format": "#,###.##",
+ "code": "fo",
+ "currency_fraction": "\u00d8re",
+ "currency_fraction_units": 100,
+ "currency_symbol": "kr",
+ "number_format": "#,###.##",
"timezones": [
"Atlantic/Faroe"
]
- },
+ },
"Fiji": {
- "code": "fj",
- "currency": "FJD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Fiji Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "fj",
+ "currency": "FJD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Fiji Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Fiji"
]
- },
+ },
"Finland": {
- "code": "fi",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "fi",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Helsinki"
]
- },
+ },
"France": {
- "code": "fr",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "fr",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Paris"
]
- },
+ },
"French Guiana": {
- "code": "gf",
- "number_format": "#,###.##",
+ "code": "gf",
+ "number_format": "#,###.##",
"timezones": [
"America/Cayenne"
]
- },
+ },
"French Polynesia": {
- "code": "pf",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
- "timezones": [
- "Pacific/Gambier",
- "Pacific/Marquesas",
+ "code": "pf",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Pacific/Gambier",
+ "Pacific/Marquesas",
"Pacific/Tahiti"
]
- },
+ },
"French Southern Territories": {
- "code": "tf",
+ "code": "tf",
"number_format": "#,###.##"
- },
+ },
"Gabon": {
- "code": "ga",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "ga",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Libreville"
]
- },
+ },
"Gambia": {
- "code": "gm",
- "currency": "GMD",
- "currency_name": "Dalasi",
- "number_format": "#,###.##",
+ "code": "gm",
+ "currency": "GMD",
+ "currency_name": "Dalasi",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Banjul"
]
- },
+ },
"Georgia": {
- "code": "ge",
- "currency_fraction": "Tetri",
- "currency_fraction_units": 100,
- "currency_symbol": "\u10da",
- "number_format": "#,###.##",
+ "code": "ge",
+ "currency_fraction": "Tetri",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u10da",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Tbilisi"
]
- },
+ },
"Germany": {
- "code": "de",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "de",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Berlin"
]
- },
+ },
"Ghana": {
- "code": "gh",
- "currency_fraction": "Pesewa",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20b5",
- "number_format": "#,###.##",
+ "code": "gh",
+ "currency_fraction": "Pesewa",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20b5",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Accra"
]
- },
+ },
"Gibraltar": {
- "code": "gi",
- "currency": "GIP",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_name": "Gibraltar Pound",
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "gi",
+ "currency": "GIP",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_name": "Gibraltar Pound",
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Gibraltar"
]
- },
+ },
"Greece": {
- "code": "gr",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "gr",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Athens"
]
- },
+ },
"Greenland": {
- "code": "gl",
- "number_format": "#,###.##",
+ "code": "gl",
+ "number_format": "#,###.##",
"timezones": [
- "America/Danmarkshavn",
- "America/Godthab",
- "America/Scoresbysund",
+ "America/Danmarkshavn",
+ "America/Godthab",
+ "America/Scoresbysund",
"America/Thule"
]
- },
+ },
"Grenada": {
- "code": "gd",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "gd",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Grenada"
]
- },
+ },
"Guadeloupe": {
- "code": "gp",
- "number_format": "#,###.##",
+ "code": "gp",
+ "number_format": "#,###.##",
"timezones": [
"America/Guadeloupe"
]
- },
+ },
"Guam": {
- "code": "gu",
- "number_format": "#,###.##",
+ "code": "gu",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Guam"
]
- },
+ },
"Guatemala": {
- "code": "gt",
- "currency": "GTQ",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Quetzal",
- "currency_symbol": "Q",
- "number_format": "#,###.##",
+ "code": "gt",
+ "currency": "GTQ",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Quetzal",
+ "currency_symbol": "Q",
+ "number_format": "#,###.##",
"timezones": [
"America/Guatemala"
]
- },
+ },
"Guernsey": {
- "code": "gg",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "gg",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Guernsey"
+ "Europe/London"
]
- },
+ },
"Guinea": {
- "code": "gn",
- "currency": "GNF",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Guinea Franc",
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "gn",
+ "currency": "GNF",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Guinea Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Conakry"
]
- },
+ },
"Guinea-Bissau": {
- "code": "gw",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "gw",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Bissau"
]
- },
+ },
"Guyana": {
- "code": "gy",
- "currency": "GYD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Guyana Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "gy",
+ "currency": "GYD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Guyana Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Guyana"
]
- },
+ },
"Haiti": {
- "code": "ht",
- "currency": "HTG",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Gourde",
- "currency_symbol": "G",
- "number_format": "#,###.##",
- "timezones": [
- "America/Guatemala",
+ "code": "ht",
+ "currency": "HTG",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Gourde",
+ "currency_symbol": "G",
+ "number_format": "#,###.##",
+ "timezones": [
+ "America/Guatemala",
"America/Port-au-Prince"
]
- },
+ },
"Heard Island and McDonald Islands": {
- "code": "hm",
+ "code": "hm",
"number_format": "#,###.##"
- },
+ },
"Holy See (Vatican City State)": {
- "code": "va",
+ "code": "va",
"number_format": "#,###.##"
- },
+ },
"Honduras": {
- "code": "hn",
- "currency": "HNL",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Lempira",
- "currency_symbol": "L",
- "number_format": "#,###.##",
+ "code": "hn",
+ "currency": "HNL",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Lempira",
+ "currency_symbol": "L",
+ "number_format": "#,###.##",
"timezones": [
"America/Tegucigalpa"
]
- },
+ },
"Hong Kong": {
- "code": "hk",
- "currency": "HKD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Hong Kong Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "hk",
+ "currency": "HKD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Hong Kong Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Hong_Kong"
]
- },
+ },
"Hungary": {
- "code": "hu",
- "currency": "HUF",
- "currency_fraction": "Fill\u00e9r",
- "currency_fraction_units": 100,
- "currency_name": "Forint",
- "currency_symbol": "Ft",
- "date_format": "yyyy-mm-dd",
- "number_format": "#.###",
+ "code": "hu",
+ "currency": "HUF",
+ "currency_fraction": "Fill\u00e9r",
+ "currency_fraction_units": 100,
+ "currency_name": "Forint",
+ "currency_symbol": "Ft",
+ "date_format": "yyyy-mm-dd",
+ "number_format": "#.###",
"timezones": [
"Europe/Budapest"
]
- },
+ },
"Iceland": {
- "code": "is",
- "currency": "ISK",
- "currency_fraction": "Eyrir",
- "currency_fraction_units": 100,
- "currency_name": "Iceland Krona",
- "currency_symbol": "kr",
- "number_format": "#.###",
+ "code": "is",
+ "currency": "ISK",
+ "currency_fraction": "Eyrir",
+ "currency_fraction_units": 100,
+ "currency_name": "Iceland Krona",
+ "currency_symbol": "kr",
+ "number_format": "#.###",
"timezones": [
"Atlantic/Reykjavik"
]
- },
+ },
"India": {
- "code": "in",
- "currency": "INR",
- "currency_fraction": "Paisa",
- "currency_fraction_units": 100,
- "currency_name": "Indian Rupee",
- "currency_symbol": "\u20b9",
- "number_format": "#,##,###.##",
- "timezones": [
- "Asia/Calcutta",
+ "code": "in",
+ "currency": "INR",
+ "currency_fraction": "Paisa",
+ "currency_fraction_units": 100,
+ "currency_name": "Indian Rupee",
+ "currency_symbol": "\u20b9",
+ "number_format": "#,##,###.##",
+ "timezones": [
"Asia/Kolkata"
]
- },
+ },
"Indonesia": {
- "code": "id",
- "currency": "IDR",
- "currency_fraction": "Sen",
- "currency_fraction_units": 100,
- "currency_name": "Rupiah",
- "currency_symbol": "Rp",
- "number_format": "#.###,##",
- "timezones": [
- "Asia/Jakarta",
- "Asia/Jayapura",
- "Asia/Makassar",
+ "code": "id",
+ "currency": "IDR",
+ "currency_fraction": "Sen",
+ "currency_fraction_units": 100,
+ "currency_name": "Rupiah",
+ "currency_symbol": "Rp",
+ "number_format": "#.###,##",
+ "timezones": [
+ "Asia/Jakarta",
+ "Asia/Jayapura",
+ "Asia/Makassar",
"Asia/Pontianak"
]
- },
+ },
"Iran, Islamic Republic of": {
- "code": "ir",
- "currency": "IRR",
- "currency_name": "Iranian Rial",
+ "code": "ir",
+ "currency": "IRR",
+ "currency_name": "Iranian Rial",
"number_format": "#,###.##"
- },
+ },
"Iraq": {
- "code": "iq",
- "currency": "IQD",
- "currency_fraction": "Fils",
- "currency_fraction_units": 1000,
- "currency_name": "Iraqi Dinar",
- "currency_symbol": "\u0639.\u062f",
- "number_format": "#,###.###",
+ "code": "iq",
+ "currency": "IQD",
+ "currency_fraction": "Fils",
+ "currency_fraction_units": 1000,
+ "currency_name": "Iraqi Dinar",
+ "currency_symbol": "\u0639.\u062f",
+ "number_format": "#,###.###",
"timezones": [
"Asia/Baghdad"
]
- },
+ },
"Ireland": {
- "code": "ie",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "ie",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Dublin"
]
- },
+ },
"Isle of Man": {
- "code": "im",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "im",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Isle_of_Man"
+ "Europe/London"
]
- },
+ },
"Israel": {
- "code": "il",
- "currency": "ILS",
- "currency_fraction": "Agora",
- "currency_fraction_units": 100,
- "currency_name": "New Israeli Sheqel",
- "currency_symbol": "\u20aa",
- "number_format": "#,###.##",
+ "code": "il",
+ "currency": "ILS",
+ "currency_fraction": "Agora",
+ "currency_fraction_units": 100,
+ "currency_name": "New Israeli Sheqel",
+ "currency_symbol": "\u20aa",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Jerusalem"
]
- },
+ },
"Italy": {
- "code": "it",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "it",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Rome"
]
- },
+ },
"Ivory Coast": {
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
"number_format": "#,###.##"
- },
+ },
"Jamaica": {
- "code": "jm",
- "currency": "JMD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Jamaican Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "jm",
+ "currency": "JMD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Jamaican Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Jamaica"
]
- },
+ },
"Japan": {
- "code": "jp",
- "currency": "JPY",
- "currency_fraction": "Sen[G]",
- "currency_fraction_units": 100,
- "currency_name": "Yen",
- "currency_symbol": "\u00a5",
- "number_format": "#,###",
+ "code": "jp",
+ "currency": "JPY",
+ "currency_fraction": "Sen[G]",
+ "currency_fraction_units": 100,
+ "currency_name": "Yen",
+ "currency_symbol": "\u00a5",
+ "number_format": "#,###",
"timezones": [
"Asia/Tokyo"
]
- },
+ },
"Jersey": {
- "code": "je",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "je",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Jersey"
+ "Europe/London"
]
- },
+ },
"Jordan": {
- "code": "jo",
- "currency": "JOD",
- "currency_fraction": "Piastre[H]",
- "currency_fraction_units": 100,
- "currency_name": "Jordanian Dinar",
- "currency_symbol": "\u062f.\u0627",
- "number_format": "#,###.###",
+ "code": "jo",
+ "currency": "JOD",
+ "currency_fraction": "Piastre[H]",
+ "currency_fraction_units": 100,
+ "currency_name": "Jordanian Dinar",
+ "currency_symbol": "\u062f.\u0627",
+ "number_format": "#,###.###",
"timezones": [
"Asia/Amman"
]
- },
+ },
"Kazakhstan": {
- "code": "kz",
- "currency": "KZT",
- "currency_fraction": "T\u00ef\u0131n",
- "currency_fraction_units": 100,
- "currency_name": "Tenge",
- "currency_symbol": "\u20b8",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Almaty",
- "Asia/Aqtau",
- "Asia/Aqtobe",
- "Asia/Oral",
+ "code": "kz",
+ "currency": "KZT",
+ "currency_fraction": "T\u00ef\u0131n",
+ "currency_fraction_units": 100,
+ "currency_name": "Tenge",
+ "currency_symbol": "\u20b8",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Almaty",
+ "Asia/Aqtau",
+ "Asia/Aqtobe",
+ "Asia/Oral",
"Asia/Qyzylorda"
]
- },
+ },
"Kenya": {
- "code": "ke",
- "currency": "KES",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Kenyan Shilling",
- "currency_symbol": "Sh",
- "number_format": "#,###.##",
+ "code": "ke",
+ "currency": "KES",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Kenyan Shilling",
+ "currency_symbol": "Sh",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Nairobi"
]
- },
+ },
"Kiribati": {
- "code": "ki",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
- "timezones": [
- "Pacific/Enderbury",
- "Pacific/Kiritimati",
+ "code": "ki",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Pacific/Enderbury",
+ "Pacific/Kiritimati",
"Pacific/Tarawa"
]
- },
+ },
"Korea, Democratic Peoples Republic of": {
- "currency": "KPW",
- "currency_name": "North Korean Won",
+ "currency": "KPW",
+ "currency_name": "North Korean Won",
"number_format": "#,###.##"
- },
+ },
"Korea, Republic of": {
- "code": "kr",
- "currency": "KRW",
- "currency_name": "Won",
+ "code": "kr",
+ "currency": "KRW",
+ "currency_name": "Won",
"number_format": "#,###"
- },
+ },
"Kuwait": {
- "code": "kw",
- "currency": "KWD",
- "currency_fraction": "Fils",
- "currency_fraction_units": 1000,
- "currency_name": "Kuwaiti Dinar",
- "currency_symbol": "\u062f.\u0643",
- "number_format": "#,###.###",
+ "code": "kw",
+ "currency": "KWD",
+ "currency_fraction": "Fils",
+ "currency_fraction_units": 1000,
+ "currency_name": "Kuwaiti Dinar",
+ "currency_symbol": "\u062f.\u0643",
+ "number_format": "#,###.###",
"timezones": [
"Asia/Kuwait"
]
- },
+ },
"Kyrgyzstan": {
- "code": "kg",
- "currency": "KGS",
- "currency_fraction": "Tyiyn",
- "currency_fraction_units": 100,
- "currency_name": "Som",
- "currency_symbol": "\u043b\u0432",
- "number_format": "#,###.##",
+ "code": "kg",
+ "currency": "KGS",
+ "currency_fraction": "Tyiyn",
+ "currency_fraction_units": 100,
+ "currency_name": "Som",
+ "currency_symbol": "\u043b\u0432",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Bishkek"
]
- },
+ },
"Lao Peoples Democratic Republic": {
- "currency": "LAK",
- "currency_name": "Kip",
+ "currency": "LAK",
+ "currency_name": "Kip",
"number_format": "#,###.##"
- },
+ },
"Latvia": {
- "code": "lv",
- "currency": "LVL",
- "currency_fraction": "Sant\u012bms",
- "currency_fraction_units": 100,
- "currency_name": "Latvian Lats",
- "currency_symbol": "Ls",
- "number_format": "#,###.##",
+ "code": "lv",
+ "currency": "LVL",
+ "currency_fraction": "Sant\u012bms",
+ "currency_fraction_units": 100,
+ "currency_name": "Latvian Lats",
+ "currency_symbol": "Ls",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Riga"
]
- },
+ },
"Lebanon": {
- "code": "lb",
- "currency": "LBP",
- "currency_fraction": "Piastre",
- "currency_fraction_units": 100,
- "currency_name": "Lebanese Pound",
- "currency_symbol": "\u0644.\u0644",
- "number_format": "#,###.##",
+ "code": "lb",
+ "currency": "LBP",
+ "currency_fraction": "Piastre",
+ "currency_fraction_units": 100,
+ "currency_name": "Lebanese Pound",
+ "currency_symbol": "\u0644.\u0644",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Beirut"
]
- },
+ },
"Lesotho": {
- "code": "ls",
- "currency": "LSL",
- "currency_fraction": "Sente",
- "currency_fraction_units": 100,
- "currency_name": "Loti",
- "currency_symbol": "L",
- "number_format": "#,###.##",
+ "code": "ls",
+ "currency": "LSL",
+ "currency_fraction": "Sente",
+ "currency_fraction_units": 100,
+ "currency_name": "Loti",
+ "currency_symbol": "L",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Maseru"
]
- },
+ },
"Liberia": {
- "code": "lr",
- "currency": "LRD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Liberian Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "lr",
+ "currency": "LRD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Liberian Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Monrovia"
]
- },
+ },
"Libya": {
- "code": "ly",
- "currency": "LYD",
- "currency_fraction": "Dirham",
- "currency_fraction_units": 1000,
- "currency_name": "Libyan Dinar",
- "currency_symbol": "\u0644.\u062f",
- "number_format": "#,###.###",
+ "code": "ly",
+ "currency": "LYD",
+ "currency_fraction": "Dirham",
+ "currency_fraction_units": 1000,
+ "currency_name": "Libyan Dinar",
+ "currency_symbol": "\u0644.\u062f",
+ "number_format": "#,###.###",
"timezones": [
"Africa/Tripoli"
]
- },
+ },
"Liechtenstein": {
- "code": "li",
- "currency_fraction": "Rappen",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "li",
+ "currency_fraction": "Rappen",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Vaduz"
]
- },
+ },
"Lithuania": {
- "code": "lt",
- "currency": "LTL",
- "currency_fraction": "Centas",
- "currency_fraction_units": 100,
- "currency_name": "Lithuanian Litas",
- "currency_symbol": "Lt",
- "date_format": "yyyy-mm-dd",
- "number_format": "# ###,##",
+ "code": "lt",
+ "currency": "LTL",
+ "currency_fraction": "Centas",
+ "currency_fraction_units": 100,
+ "currency_name": "Lithuanian Litas",
+ "currency_symbol": "Lt",
+ "date_format": "yyyy-mm-dd",
+ "number_format": "# ###,##",
"timezones": [
"Europe/Vilnius"
]
- },
+ },
"Luxembourg": {
- "code": "lu",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "lu",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Luxembourg"
]
- },
+ },
"Macao": {
- "code": "mo",
- "currency": "MOP",
- "currency_name": "Pataca",
+ "code": "mo",
+ "currency": "MOP",
+ "currency_name": "Pataca",
"number_format": "#,###.##"
- },
+ },
"Macedonia, Republic of": {
- "currency": "MKD",
- "currency_fraction": "Deni",
- "currency_fraction_units": 100,
- "currency_name": "Denar",
- "currency_symbol": "\u0434\u0435\u043d",
+ "currency": "MKD",
+ "currency_fraction": "Deni",
+ "currency_fraction_units": 100,
+ "currency_name": "Denar",
+ "currency_symbol": "\u0434\u0435\u043d",
"number_format": "#,###.##"
- },
+ },
"Madagascar": {
- "code": "mg",
- "currency_fraction": "Iraimbilanja",
- "currency_fraction_units": 5,
- "currency_symbol": "Ar",
- "number_format": "#,###.##",
+ "code": "mg",
+ "currency_fraction": "Iraimbilanja",
+ "currency_fraction_units": 5,
+ "currency_symbol": "Ar",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Antananarivo"
]
- },
+ },
"Malawi": {
- "code": "mw",
- "currency": "MWK",
- "currency_fraction": "Tambala",
- "currency_fraction_units": 100,
- "currency_name": "Kwacha",
- "currency_symbol": "MK",
- "number_format": "#,###.##",
+ "code": "mw",
+ "currency": "MWK",
+ "currency_fraction": "Tambala",
+ "currency_fraction_units": 100,
+ "currency_name": "Kwacha",
+ "currency_symbol": "MK",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Blantyre"
]
- },
+ },
"Malaysia": {
- "code": "my",
- "currency": "MYR",
- "currency_fraction": "Sen",
- "currency_fraction_units": 100,
- "currency_name": "Malaysian Ringgit",
- "currency_symbol": "RM",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Kuala_Lumpur",
+ "code": "my",
+ "currency": "MYR",
+ "currency_fraction": "Sen",
+ "currency_fraction_units": 100,
+ "currency_name": "Malaysian Ringgit",
+ "currency_symbol": "RM",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Kuala_Lumpur",
"Asia/Kuching"
]
- },
+ },
"Maldives": {
- "code": "mv",
- "currency": "MVR",
- "currency_fraction": "Laari",
- "currency_fraction_units": 100,
- "currency_name": "Rufiyaa",
- "currency_symbol": ".\u0783",
- "number_format": "#,###.##",
+ "code": "mv",
+ "currency": "MVR",
+ "currency_fraction": "Laari",
+ "currency_fraction_units": 100,
+ "currency_name": "Rufiyaa",
+ "currency_symbol": ".\u0783",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Maldives"
]
- },
+ },
"Mali": {
- "code": "ml",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "ml",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Bamako"
]
- },
+ },
"Malta": {
- "code": "mt",
- "currency": "MTL",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Maltese Lira",
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "mt",
+ "currency": "MTL",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Maltese Lira",
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Malta"
]
- },
+ },
"Marshall Islands": {
- "code": "mh",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "mh",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
- "Pacific/Kwajalein",
+ "Pacific/Kwajalein",
"Pacific/Majuro"
]
- },
+ },
"Martinique": {
- "code": "mq",
- "number_format": "#,###.##",
+ "code": "mq",
+ "number_format": "#,###.##",
"timezones": [
"America/Martinique"
]
- },
+ },
"Mauritania": {
- "code": "mr",
- "currency": "MRO",
- "currency_fraction": "Khoums",
- "currency_fraction_units": 5,
- "currency_name": "Ouguiya",
- "currency_symbol": "UM",
- "number_format": "#,###.##",
+ "code": "mr",
+ "currency": "MRO",
+ "currency_fraction": "Khoums",
+ "currency_fraction_units": 5,
+ "currency_name": "Ouguiya",
+ "currency_symbol": "UM",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Nouakchott"
]
- },
+ },
"Mauritius": {
- "code": "mu",
- "currency": "MUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Mauritius Rupee",
- "currency_symbol": "\u20a8",
- "number_format": "#,###",
+ "code": "mu",
+ "currency": "MUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Mauritius Rupee",
+ "currency_symbol": "\u20a8",
+ "number_format": "#,###",
"timezones": [
"Indian/Mauritius"
]
- },
+ },
"Mayotte": {
- "code": "yt",
- "number_format": "#,###.##",
+ "code": "yt",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Mayotte"
]
- },
+ },
"Mexico": {
- "code": "mx",
- "currency": "MXN",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Mexican Peso",
- "currency_symbol": "$",
- "number_format": "#,###.##",
- "timezones": [
- "America/Bahia_Banderas",
- "America/Cancun",
- "America/Chihuahua",
- "America/Hermosillo",
- "America/Matamoros",
- "America/Mazatlan",
- "America/Merida",
- "America/Mexico_City",
- "America/Monterrey",
- "America/Ojinaga",
- "America/Santa_Isabel",
+ "code": "mx",
+ "currency": "MXN",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Mexican Peso",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
+ "timezones": [
+ "America/Bahia_Banderas",
+ "America/Cancun",
+ "America/Chihuahua",
+ "America/Hermosillo",
+ "America/Matamoros",
+ "America/Mazatlan",
+ "America/Merida",
+ "America/Mexico_City",
+ "America/Monterrey",
+ "America/Ojinaga",
+ "America/Santa_Isabel",
"America/Tijuana"
]
- },
+ },
"Micronesia, Federated States of": {
- "code": "fm",
+ "code": "fm",
"number_format": "#,###.##"
- },
+ },
"Moldova, Republic of": {
- "code": "md",
- "currency": "MDL",
- "currency_name": "Moldovan Leu",
+ "code": "md",
+ "currency": "MDL",
+ "currency_name": "Moldovan Leu",
"number_format": "#,###.##"
- },
+ },
"Monaco": {
- "code": "mc",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "mc",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Monaco"
]
- },
+ },
"Mongolia": {
- "code": "mn",
- "currency": "MNT",
- "currency_fraction": "M\u00f6ng\u00f6",
- "currency_fraction_units": 100,
- "currency_name": "Tugrik",
- "currency_symbol": "\u20ae",
- "date_format": "yyyy-mm-dd",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Choibalsan",
- "Asia/Hovd",
+ "code": "mn",
+ "currency": "MNT",
+ "currency_fraction": "M\u00f6ng\u00f6",
+ "currency_fraction_units": 100,
+ "currency_name": "Tugrik",
+ "currency_symbol": "\u20ae",
+ "date_format": "yyyy-mm-dd",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Choibalsan",
+ "Asia/Hovd",
"Asia/Ulaanbaatar"
]
- },
+ },
"Montenegro": {
- "code": "me",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "me",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Podgorica"
+ "Europe/Belgrade"
]
- },
+ },
"Montserrat": {
- "code": "ms",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "ms",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Montserrat"
]
- },
+ },
"Morocco": {
- "code": "ma",
- "currency": "MAD",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Moroccan Dirham",
- "currency_symbol": "\u062f.\u0645.",
- "number_format": "#,###.##",
+ "code": "ma",
+ "currency": "MAD",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Moroccan Dirham",
+ "currency_symbol": "\u062f.\u0645.",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Casablanca"
]
- },
+ },
"Mozambique": {
- "code": "mz",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_symbol": "MT",
- "number_format": "#,###.##",
+ "code": "mz",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_symbol": "MT",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Maputo"
]
- },
+ },
"Myanmar": {
- "code": "mm",
- "currency": "MMK",
- "currency_name": "Kyat",
- "number_format": "#,###.##",
+ "code": "mm",
+ "currency": "MMK",
+ "currency_name": "Kyat",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Rangoon"
]
- },
+ },
"Namibia": {
- "code": "na",
- "currency": "NAD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Namibia Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "na",
+ "currency": "NAD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Namibia Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Windhoek"
]
- },
+ },
"Nauru": {
- "code": "nr",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "nr",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Nauru"
]
- },
+ },
"Nepal": {
- "code": "np",
- "currency": "NPR",
- "currency_fraction": "Paisa",
- "currency_fraction_units": 100,
- "currency_name": "Nepalese Rupee",
- "currency_symbol": "\u20a8",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Kathmandu",
- "Asia/Katmandu"
- ]
- },
+ "code": "np",
+ "currency": "NPR",
+ "currency_fraction": "Paisa",
+ "currency_fraction_units": 100,
+ "currency_name": "Nepalese Rupee",
+ "currency_symbol": "\u20a8",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Kathmandu"
+ ]
+ },
"Netherlands": {
- "code": "nl",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "nl",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Amsterdam"
]
- },
+ },
"New Caledonia": {
- "code": "nc",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "nc",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Noumea"
]
- },
+ },
"New Zealand": {
- "code": "nz",
- "currency": "NZD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "New Zealand Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
- "timezones": [
- "Pacific/Auckland",
+ "code": "nz",
+ "currency": "NZD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "New Zealand Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Pacific/Auckland",
"Pacific/Chatham"
]
- },
+ },
"Nicaragua": {
- "code": "ni",
- "currency": "NIO",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Cordoba Oro",
- "currency_symbol": "C$",
- "number_format": "#,###.##",
+ "code": "ni",
+ "currency": "NIO",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Cordoba Oro",
+ "currency_symbol": "C$",
+ "number_format": "#,###.##",
"timezones": [
"America/Managua"
]
- },
+ },
"Niger": {
- "code": "ne",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "ne",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Niamey"
]
- },
+ },
"Nigeria": {
- "code": "ng",
- "currency": "NGN",
- "currency_fraction": "Kobo",
- "currency_fraction_units": 100,
- "currency_name": "Naira",
- "currency_symbol": "\u20a6",
- "number_format": "#,###.##",
+ "code": "ng",
+ "currency": "NGN",
+ "currency_fraction": "Kobo",
+ "currency_fraction_units": 100,
+ "currency_name": "Naira",
+ "currency_symbol": "\u20a6",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Lagos"
]
- },
+ },
"Niue": {
- "code": "nu",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "nu",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Niue"
]
- },
+ },
"Norfolk Island": {
- "code": "nf",
- "number_format": "#,###.##",
+ "code": "nf",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Norfolk"
]
- },
+ },
"Northern Mariana Islands": {
- "code": "mp",
- "number_format": "#,###.##",
+ "code": "mp",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Saipan"
]
- },
+ },
"Norway": {
- "code": "no",
- "currency": "NOK",
- "currency_fraction": "\u00d8re",
- "currency_fraction_units": 100,
- "currency_name": "Norwegian Krone",
- "currency_symbol": "kr",
- "number_format": "#.###,##",
+ "code": "no",
+ "currency": "NOK",
+ "currency_fraction": "\u00d8re",
+ "currency_fraction_units": 100,
+ "currency_name": "Norwegian Krone",
+ "currency_symbol": "kr",
+ "number_format": "#.###,##",
"timezones": [
"Europe/Oslo"
]
- },
+ },
"Oman": {
- "code": "om",
- "currency": "OMR",
- "currency_fraction": "Baisa",
- "currency_fraction_units": 1000,
- "currency_name": "Rial Omani",
- "currency_symbol": "\u0631.\u0639.",
- "number_format": "#,###.###",
+ "code": "om",
+ "currency": "OMR",
+ "currency_fraction": "Baisa",
+ "currency_fraction_units": 1000,
+ "currency_name": "Rial Omani",
+ "currency_symbol": "\u0631.\u0639.",
+ "number_format": "#,###.###",
"timezones": [
"Asia/Muscat"
]
- },
+ },
"Pakistan": {
- "code": "pk",
- "currency": "PKR",
- "currency_fraction": "Paisa",
- "currency_fraction_units": 100,
- "currency_name": "Pakistan Rupee",
- "currency_symbol": "\u20a8",
- "number_format": "#,###.##",
+ "code": "pk",
+ "currency": "PKR",
+ "currency_fraction": "Paisa",
+ "currency_fraction_units": 100,
+ "currency_name": "Pakistan Rupee",
+ "currency_symbol": "\u20a8",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Karachi"
]
- },
+ },
"Palau": {
- "code": "pw",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "date_format": "mm-dd-yyyy",
- "number_format": "#,###.##",
+ "code": "pw",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "date_format": "mm-dd-yyyy",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Palau"
]
- },
+ },
"Palestinian Territory, Occupied": {
"number_format": "#,###.##"
- },
+ },
"Panama": {
- "code": "pa",
- "currency_fraction": "Cent\u00e9simo",
- "currency_fraction_units": 100,
- "currency_symbol": "B/.",
- "number_format": "#,###.##",
+ "code": "pa",
+ "currency_fraction": "Cent\u00e9simo",
+ "currency_fraction_units": 100,
+ "currency_symbol": "B/.",
+ "number_format": "#,###.##",
"timezones": [
"America/Panama"
]
- },
+ },
"Papua New Guinea": {
- "code": "pg",
- "currency": "PGK",
- "currency_fraction": "Toea",
- "currency_fraction_units": 100,
- "currency_name": "Kina",
- "currency_symbol": "K",
- "number_format": "#,###.##",
+ "code": "pg",
+ "currency": "PGK",
+ "currency_fraction": "Toea",
+ "currency_fraction_units": 100,
+ "currency_name": "Kina",
+ "currency_symbol": "K",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Port_Moresby"
]
- },
+ },
"Paraguay": {
- "code": "py",
- "currency": "PYG",
- "currency_fraction": "C\u00e9ntimo",
- "currency_fraction_units": 100,
- "currency_name": "Guarani",
- "currency_symbol": "\u20b2",
- "number_format": "#,###.##",
+ "code": "py",
+ "currency": "PYG",
+ "currency_fraction": "C\u00e9ntimo",
+ "currency_fraction_units": 100,
+ "currency_name": "Guarani",
+ "currency_symbol": "\u20b2",
+ "number_format": "#,###.##",
"timezones": [
"America/Asuncion"
]
- },
+ },
"Peru": {
- "code": "pe",
- "currency": "PEN",
- "currency_fraction": "C\u00e9ntimo",
- "currency_fraction_units": 100,
- "currency_name": "Nuevo Sol",
- "currency_symbol": "S/.",
- "number_format": "#,###.##",
+ "code": "pe",
+ "currency": "PEN",
+ "currency_fraction": "C\u00e9ntimo",
+ "currency_fraction_units": 100,
+ "currency_name": "Nuevo Sol",
+ "currency_symbol": "S/.",
+ "number_format": "#,###.##",
"timezones": [
"America/Lima"
]
- },
+ },
"Philippines": {
- "code": "ph",
- "currency": "PHP",
- "currency_fraction": "Centavo",
- "currency_fraction_units": 100,
- "currency_name": "Philippine Peso",
- "currency_symbol": "\u20b1",
- "date_format": "mm-dd-yyyy",
- "number_format": "#,###.##",
+ "code": "ph",
+ "currency": "PHP",
+ "currency_fraction": "Centavo",
+ "currency_fraction_units": 100,
+ "currency_name": "Philippine Peso",
+ "currency_symbol": "\u20b1",
+ "date_format": "mm-dd-yyyy",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Manila"
]
- },
+ },
"Pitcairn": {
- "code": "pn",
- "number_format": "#,###.##",
+ "code": "pn",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Pitcairn"
]
- },
+ },
"Poland": {
- "code": "pl",
- "currency_fraction": "Grosz",
- "currency_fraction_units": 100,
- "currency_symbol": "z\u0142",
- "number_format": "#,###.##",
+ "code": "pl",
+ "currency": "PLN",
+ "currency_fraction": "Grosz",
+ "currency_fraction_units": 100,
+ "currency_symbol": "z\u0142",
+ "number_format": "#.###,##",
"timezones": [
"Europe/Warsaw"
]
- },
+ },
"Portugal": {
- "code": "pt",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
- "timezones": [
- "Atlantic/Azores",
- "Atlantic/Madeira",
+ "code": "pt",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Atlantic/Azores",
+ "Atlantic/Madeira",
"Europe/Lisbon"
]
- },
+ },
"Puerto Rico": {
- "code": "pr",
- "number_format": "#,###.##",
+ "code": "pr",
+ "number_format": "#,###.##",
"timezones": [
"America/Puerto_Rico"
]
- },
+ },
"Qatar": {
- "code": "qa",
- "currency": "QAR",
- "currency_fraction": "Dirham",
- "currency_fraction_units": 100,
- "currency_name": "Qatari Rial",
- "currency_symbol": "\u0631.\u0642",
- "number_format": "#,###.##",
+ "code": "qa",
+ "currency": "QAR",
+ "currency_fraction": "Dirham",
+ "currency_fraction_units": 100,
+ "currency_name": "Qatari Rial",
+ "currency_symbol": "\u0631.\u0642",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Qatar"
]
- },
+ },
"Romania": {
- "code": "ro",
- "currency_fraction": "Ban",
- "currency_fraction_units": 100,
- "currency_symbol": "L",
- "number_format": "#,###.##",
+ "code": "ro",
+ "currency_fraction": "Ban",
+ "currency_fraction_units": 100,
+ "currency_symbol": "L",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Bucharest"
]
- },
+ },
"Russian Federation": {
- "code": "ru",
- "currency": "RUB",
- "currency_name": "Russian Ruble",
+ "code": "ru",
+ "currency": "RUB",
+ "currency_name": "Russian Ruble",
"number_format": "#.###,##"
- },
+ },
"Rwanda": {
- "code": "rw",
- "currency": "RWF",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_name": "Rwanda Franc",
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "rw",
+ "currency": "RWF",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_name": "Rwanda Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Kigali"
]
- },
+ },
"R\u00e9union": {
- "code": "re",
+ "code": "re",
"number_format": "#,###.##"
- },
+ },
"Saint Barth\u00e9lemy": {
- "code": "bl",
+ "code": "bl",
"number_format": "#,###.##"
- },
+ },
"Saint Helena, Ascension and Tristan da Cunha": {
- "code": "sh",
- "currency": "SHP",
- "currency_name": "Saint Helena Pound",
+ "code": "sh",
+ "currency": "SHP",
+ "currency_name": "Saint Helena Pound",
"number_format": "#,###.##"
- },
+ },
"Saint Kitts and Nevis": {
- "code": "kn",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "kn",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/St_Kitts"
]
- },
+ },
"Saint Lucia": {
- "code": "lc",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "lc",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/St_Lucia"
]
- },
+ },
"Saint Martin (French part)": {
- "code": "mf",
+ "code": "mf",
"number_format": "#,###.##"
- },
+ },
"Saint Pierre and Miquelon": {
- "code": "pm",
+ "code": "pm",
"number_format": "#,###.##"
- },
+ },
"Saint Vincent and the Grenadines": {
- "code": "vc",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "vc",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/St_Vincent"
]
- },
+ },
"Samoa": {
- "code": "ws",
- "currency": "WST",
- "currency_fraction": "Sene",
- "currency_fraction_units": 100,
- "currency_name": "Tala",
- "currency_symbol": "T",
- "number_format": "#,###.##",
+ "code": "ws",
+ "currency": "WST",
+ "currency_fraction": "Sene",
+ "currency_fraction_units": 100,
+ "currency_name": "Tala",
+ "currency_symbol": "T",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Apia"
]
- },
+ },
"San Marino": {
- "code": "sm",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "sm",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/San_Marino"
+ "Europe/Rome"
]
- },
+ },
"Sao Tome and Principe": {
- "code": "st",
- "currency": "STD",
- "currency_name": "Dobra",
+ "code": "st",
+ "currency": "STD",
+ "currency_name": "Dobra",
"number_format": "#,###.##"
- },
+ },
"Saudi Arabia": {
- "code": "sa",
- "currency": "SAR",
- "currency_fraction": "Halala",
- "currency_fraction_units": 100,
- "currency_name": "Saudi Riyal",
- "currency_symbol": "\u0631.\u0633",
- "number_format": "#,###.##",
+ "code": "sa",
+ "currency": "SAR",
+ "currency_fraction": "Halala",
+ "currency_fraction_units": 100,
+ "currency_name": "Saudi Riyal",
+ "currency_symbol": "\u0631.\u0633",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Riyadh"
]
- },
+ },
"Senegal": {
- "code": "sn",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "sn",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Dakar"
]
- },
+ },
"Serbia": {
- "code": "rs",
- "currency_fraction": "Para",
- "currency_fraction_units": 100,
- "currency_symbol": "\u0434\u0438\u043d. or din.",
- "number_format": "#,###.##",
+ "code": "rs",
+ "currency_fraction": "Para",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u0434\u0438\u043d. or din.",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Belgrade"
]
- },
+ },
"Seychelles": {
- "code": "sc",
- "currency": "SCR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Seychelles Rupee",
- "currency_symbol": "\u20a8",
- "number_format": "#,###.##",
+ "code": "sc",
+ "currency": "SCR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Seychelles Rupee",
+ "currency_symbol": "\u20a8",
+ "number_format": "#,###.##",
"timezones": [
"Indian/Mahe"
]
- },
+ },
"Sierra Leone": {
- "code": "sl",
- "currency": "SLL",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Leone",
- "currency_symbol": "Le",
- "number_format": "#,###.##",
+ "code": "sl",
+ "currency": "SLL",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Leone",
+ "currency_symbol": "Le",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Freetown"
]
- },
+ },
"Singapore": {
- "code": "sg",
- "currency": "SGD",
- "currency_fraction": "Sen",
- "currency_fraction_units": 100,
- "currency_name": "Singapore Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "sg",
+ "currency": "SGD",
+ "currency_fraction": "Sen",
+ "currency_fraction_units": 100,
+ "currency_name": "Singapore Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Singapore"
]
- },
+ },
"Sint Maarten (Dutch part)": {
- "code": "sx",
+ "code": "sx",
"number_format": "#,###.##"
- },
+ },
"Slovakia": {
- "code": "sk",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "sk",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Bratislava"
+ "Europe/Prague"
]
- },
+ },
"Slovenia": {
- "code": "si",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
+ "code": "si",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
"timezones": [
- "Europe/Ljubljana"
+ "Europe/Belgrade"
]
- },
+ },
"Solomon Islands": {
- "code": "sb",
- "currency": "SBD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Solomon Islands Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "sb",
+ "currency": "SBD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Solomon Islands Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Guadalcanal"
]
- },
+ },
"Somalia": {
- "code": "so",
- "currency": "SOS",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Somali Shilling",
- "currency_symbol": "Sh",
- "number_format": "#,###.##",
+ "code": "so",
+ "currency": "SOS",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Somali Shilling",
+ "currency_symbol": "Sh",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Mogadishu"
]
- },
+ },
"South Africa": {
- "code": "za",
- "currency": "ZAR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Rand",
- "currency_symbol": "R",
- "date_format": "yyyy-mm-dd",
- "number_format": "# ###.##",
+ "code": "za",
+ "currency": "ZAR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Rand",
+ "currency_symbol": "R",
+ "date_format": "yyyy-mm-dd",
+ "number_format": "# ###.##",
"timezones": [
"Africa/Johannesburg"
]
- },
+ },
"South Georgia and the South Sandwich Islands": {
- "code": "gs",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
+ "code": "gs",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
"number_format": "#,###.##"
- },
+ },
"South Sudan": {
- "code": "ss",
- "currency_fraction": "Piastre",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "ss",
+ "currency_fraction": "Piastre",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Juba"
]
- },
+ },
"Spain": {
- "code": "es",
- "currency": "EUR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20ac",
- "number_format": "#,###.##",
- "timezones": [
- "Africa/Ceuta",
- "Atlantic/Canary",
+ "code": "es",
+ "currency": "EUR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ac",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Africa/Ceuta",
+ "Atlantic/Canary",
"Europe/Madrid"
]
- },
+ },
"Sri Lanka": {
- "code": "lk",
- "currency": "LKR",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Sri Lanka Rupee",
- "currency_symbol": "Rs",
- "number_format": "#,###.##",
+ "code": "lk",
+ "currency": "LKR",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Sri Lanka Rupee",
+ "currency_symbol": "Rs",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Colombo"
]
- },
+ },
"Sudan": {
- "code": "sd",
- "currency_fraction": "Piastre",
- "currency_fraction_units": 100,
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "sd",
+ "currency_fraction": "Piastre",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Khartoum"
]
- },
+ },
"Suriname": {
- "code": "sr",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "sr",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Paramaribo"
]
- },
+ },
"Svalbard and Jan Mayen": {
- "code": "sj",
+ "code": "sj",
"number_format": "#,###.##"
- },
+ },
"Swaziland": {
- "code": "sz",
- "currency": "SZL",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Lilangeni",
- "currency_symbol": "L",
- "number_format": "#, ###.##",
+ "code": "sz",
+ "currency": "SZL",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Lilangeni",
+ "currency_symbol": "L",
+ "number_format": "#, ###.##",
"timezones": [
"Africa/Mbabane"
]
- },
+ },
"Sweden": {
- "code": "se",
- "currency": "SEK",
- "currency_fraction": "\u00d6re",
- "currency_fraction_units": 100,
- "currency_name": "Swedish Krona",
- "currency_symbol": "kr",
- "number_format": "#.###,##",
+ "code": "se",
+ "currency": "SEK",
+ "currency_fraction": "\u00d6re",
+ "currency_fraction_units": 100,
+ "currency_name": "Swedish Krona",
+ "currency_symbol": "kr",
+ "number_format": "#.###,##",
"timezones": [
"Europe/Stockholm"
]
- },
+ },
"Switzerland": {
- "code": "ch",
- "currency": "CHF",
- "currency_fraction": "Rappen[K]",
- "currency_fraction_units": 100,
- "currency_name": "Swiss Franc",
- "currency_symbol": "Fr",
- "number_format": "#'###.##",
+ "code": "ch",
+ "currency": "CHF",
+ "currency_fraction": "Rappen[K]",
+ "currency_fraction_units": 100,
+ "currency_name": "Swiss Franc",
+ "currency_symbol": "Fr",
+ "number_format": "#'###.##",
"timezones": [
"Europe/Zurich"
]
- },
+ },
"Syrian Arab Republic": {
- "code": "sy",
- "currency": "SYP",
- "currency_name": "Syrian Pound",
+ "code": "sy",
+ "currency": "SYP",
+ "currency_name": "Syrian Pound",
"number_format": "#,###.##"
- },
+ },
"Taiwan, Province of China": {
- "code": "tw",
- "date_format": "yyyy-mm-dd",
+ "code": "tw",
+ "date_format": "yyyy-mm-dd",
"number_format": "#,###.##"
- },
+ },
"Tajikistan": {
- "code": "tj",
- "currency_fraction": "Diram",
- "currency_fraction_units": 100,
- "currency_symbol": "\u0405\u041c",
- "number_format": "#,###.##",
+ "code": "tj",
+ "currency_fraction": "Diram",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u0405\u041c",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Dushanbe"
]
- },
+ },
"Tanzania, United Republic of": {
- "code": "tz",
- "currency": "TZS",
- "currency_name": "Tanzanian Shilling",
+ "code": "tz",
+ "currency": "TZS",
+ "currency_name": "Tanzanian Shilling",
"number_format": "#,###.##"
- },
+ },
"Thailand": {
- "code": "th",
- "currency": "THB",
- "currency_fraction": "Satang",
- "currency_fraction_units": 100,
- "currency_name": "Baht",
- "currency_symbol": "\u0e3f",
- "number_format": "#,###.##",
+ "code": "th",
+ "currency": "THB",
+ "currency_fraction": "Satang",
+ "currency_fraction_units": 100,
+ "currency_name": "Baht",
+ "currency_symbol": "\u0e3f",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Bangkok"
]
- },
+ },
"Timor-Leste": {
- "code": "tl",
+ "code": "tl",
"number_format": "#,###.##"
- },
+ },
"Togo": {
- "code": "tg",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
- "number_format": "#,###.##",
+ "code": "tg",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Lome"
]
- },
+ },
"Tokelau": {
- "code": "tk",
- "number_format": "#,###.##",
+ "code": "tk",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Fakaofo"
]
- },
+ },
"Tonga": {
- "code": "to",
- "currency": "TOP",
- "currency_fraction": "Seniti[L]",
- "currency_fraction_units": 100,
- "currency_name": "Pa'anga",
- "currency_symbol": "T$",
- "number_format": "#,###.##",
+ "code": "to",
+ "currency": "TOP",
+ "currency_fraction": "Seniti[L]",
+ "currency_fraction_units": 100,
+ "currency_name": "Pa'anga",
+ "currency_symbol": "T$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Tongatapu"
]
- },
+ },
"Trinidad and Tobago": {
- "code": "tt",
- "currency": "TTD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Trinidad and Tobago Dollar",
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "tt",
+ "currency": "TTD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Trinidad and Tobago Dollar",
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"America/Port_of_Spain"
]
- },
+ },
"Tunisia": {
- "code": "tn",
- "currency": "TND",
- "currency_fraction": "Millime",
- "currency_fraction_units": 1000,
- "currency_name": "Tunisian Dinar",
- "currency_symbol": "\u062f.\u062a",
- "number_format": "#,###.###",
+ "code": "tn",
+ "currency": "TND",
+ "currency_fraction": "Millime",
+ "currency_fraction_units": 1000,
+ "currency_name": "Tunisian Dinar",
+ "currency_symbol": "\u062f.\u062a",
+ "number_format": "#,###.###",
"timezones": [
"Africa/Tunis"
]
- },
+ },
"Turkey": {
- "code": "tr",
- "currency_fraction": "Kuru\u015f",
- "currency_fraction_units": 100,
- "currency_symbol": "",
- "number_format": "#,###.##",
+ "code": "tr",
+ "currency": "TRY",
+ "currency_fraction": "Kuru\u015f",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20ba",
+ "number_format": "#,###.##",
"timezones": [
"Europe/Istanbul"
]
- },
+ },
"Turkmenistan": {
- "code": "tm",
- "currency": "TMM",
- "currency_fraction": "Tennesi",
- "currency_fraction_units": 100,
- "currency_name": "Manat",
- "currency_symbol": "m",
- "number_format": "#,###.##",
+ "code": "tm",
+ "currency": "TMM",
+ "currency_fraction": "Tennesi",
+ "currency_fraction_units": 100,
+ "currency_name": "Manat",
+ "currency_symbol": "m",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Ashgabat"
]
- },
+ },
"Turks and Caicos Islands": {
- "code": "tc",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
+ "code": "tc",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
"number_format": "#,###.##"
- },
+ },
"Tuvalu": {
- "code": "tv",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_symbol": "$",
- "number_format": "#,###.##",
+ "code": "tv",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_symbol": "$",
+ "number_format": "#,###.##",
"timezones": [
"Pacific/Funafuti"
]
- },
+ },
"Uganda": {
- "code": "ug",
- "currency": "UGX",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "Uganda Shilling",
- "currency_symbol": "Sh",
- "number_format": "#,###.##",
+ "code": "ug",
+ "currency": "UGX",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "Uganda Shilling",
+ "currency_symbol": "Sh",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Kampala"
]
- },
+ },
"Ukraine": {
- "code": "ua",
- "currency_fraction": "Kopiyka",
- "currency_fraction_units": 100,
- "currency_symbol": "\u20b4",
- "number_format": "#,###.##",
- "timezones": [
- "Europe/Kiev",
- "Europe/Simferopol",
- "Europe/Uzhgorod",
+ "code": "ua",
+ "currency_fraction": "Kopiyka",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\u20b4",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Europe/Kiev",
+ "Europe/Simferopol",
+ "Europe/Uzhgorod",
"Europe/Zaporozhye"
]
- },
+ },
"United Arab Emirates": {
- "code": "ae",
- "currency": "AED",
- "currency_fraction": "Fils",
- "currency_fraction_units": 100,
- "currency_name": "UAE Dirham",
- "currency_symbol": "\u062f.\u0625",
- "number_format": "#,###.##",
+ "code": "ae",
+ "currency": "AED",
+ "currency_fraction": "Fils",
+ "currency_fraction_units": 100,
+ "currency_name": "UAE Dirham",
+ "currency_symbol": "\u062f.\u0625",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Dubai"
]
- },
+ },
"United Kingdom": {
- "code": "gb",
- "currency": "GBP",
- "currency_fraction": "Penny",
- "currency_fraction_units": 100,
- "currency_name": "Pound Sterling",
- "currency_symbol": "\u00a3",
- "number_format": "#,###.##",
+ "code": "gb",
+ "currency": "GBP",
+ "currency_fraction": "Penny",
+ "currency_fraction_units": 100,
+ "currency_name": "Pound Sterling",
+ "currency_symbol": "\u00a3",
+ "number_format": "#,###.##",
"timezones": [
"Europe/London"
]
- },
+ },
"United States": {
- "code": "us",
- "currency": "USD",
- "currency_fraction": "Cent",
- "currency_fraction_units": 100,
- "currency_name": "US Dollar",
- "currency_symbol": "$",
- "date_format": "mm-dd-yyyy",
- "number_format": "#,###.##",
- "timezones": [
- "America/Adak",
- "America/Anchorage",
- "America/Boise",
- "America/Chicago",
- "America/Denver",
- "America/Detroit",
- "America/Indiana/Indianapolis",
- "America/Indiana/Knox",
- "America/Indiana/Marengo",
- "America/Indiana/Petersburg",
- "America/Indiana/Tell_City",
- "America/Indiana/Vevay",
- "America/Indiana/Vincennes",
- "America/Indiana/Winamac",
- "America/Juneau",
- "America/Kentucky/Louisville",
- "America/Kentucky/Monticello",
- "America/Los_Angeles",
- "America/Menominee",
- "America/Metlakatla",
- "America/New_York",
- "America/Nome",
- "America/North_Dakota/Beulah",
- "America/North_Dakota/Center",
- "America/North_Dakota/New_Salem",
- "America/Phoenix",
- "America/Shiprock",
- "America/Sitka",
- "America/Yakutat",
+ "code": "us",
+ "currency": "USD",
+ "currency_fraction": "Cent",
+ "currency_fraction_units": 100,
+ "currency_name": "US Dollar",
+ "currency_symbol": "$",
+ "date_format": "mm-dd-yyyy",
+ "number_format": "#,###.##",
+ "timezones": [
+ "America/Adak",
+ "America/Anchorage",
+ "America/Boise",
+ "America/Chicago",
+ "America/Denver",
+ "America/Detroit",
+ "America/Indiana/Indianapolis",
+ "America/Indiana/Knox",
+ "America/Indiana/Marengo",
+ "America/Indiana/Petersburg",
+ "America/Indiana/Tell_City",
+ "America/Indiana/Vevay",
+ "America/Indiana/Vincennes",
+ "America/Indiana/Winamac",
+ "America/Juneau",
+ "America/Kentucky/Louisville",
+ "America/Kentucky/Monticello",
+ "America/Los_Angeles",
+ "America/Menominee",
+ "America/Metlakatla",
+ "America/New_York",
+ "America/Nome",
+ "America/North_Dakota/Beulah",
+ "America/North_Dakota/Center",
+ "America/North_Dakota/New_Salem",
+ "America/Phoenix",
+ "America/Denver",
+ "America/Sitka",
+ "America/Yakutat",
"Pacific/Honolulu"
]
- },
+ },
"United States Minor Outlying Islands": {
- "code": "um",
+ "code": "um",
"number_format": "#,###.##"
- },
+ },
"Uruguay": {
- "code": "uy",
- "currency": "UYU",
- "currency_fraction": "Cent\u00e9simo",
- "currency_fraction_units": 100,
- "currency_name": "Peso Uruguayo",
- "currency_symbol": "$",
- "number_format": "#.###,##",
+ "code": "uy",
+ "currency": "UYU",
+ "currency_fraction": "Cent\u00e9simo",
+ "currency_fraction_units": 100,
+ "currency_name": "Peso Uruguayo",
+ "currency_symbol": "$",
+ "number_format": "#.###,##",
"timezones": [
"America/Montevideo"
]
- },
+ },
"Uzbekistan": {
- "code": "uz",
- "currency": "UZS",
- "currency_fraction": "Tiyin",
- "currency_fraction_units": 100,
- "currency_name": "Uzbekistan Sum",
- "currency_symbol": "\u043b\u0432",
- "number_format": "#,###.##",
- "timezones": [
- "Asia/Samarkand",
+ "code": "uz",
+ "currency": "UZS",
+ "currency_fraction": "Tiyin",
+ "currency_fraction_units": 100,
+ "currency_name": "Uzbekistan Sum",
+ "currency_symbol": "\u043b\u0432",
+ "number_format": "#,###.##",
+ "timezones": [
+ "Asia/Samarkand",
"Asia/Tashkent"
]
- },
+ },
"Vanuatu": {
- "code": "vu",
- "currency": "VUV",
- "currency_fraction": "None",
- "currency_fraction_units": 0,
- "currency_name": "Vatu",
- "currency_symbol": "Vt",
- "number_format": "#,###",
+ "code": "vu",
+ "currency": "VUV",
+ "currency_fraction": "None",
+ "currency_fraction_units": 0,
+ "currency_name": "Vatu",
+ "currency_symbol": "Vt",
+ "number_format": "#,###",
"timezones": [
"Pacific/Efate"
]
- },
+ },
"Venezuela, Bolivarian Republic of": {
- "code": "ve",
+ "code": "ve",
"number_format": "#,###.##"
- },
- "Viet Nam": {
- "code": "vn",
- "currency": "VND",
- "currency_name": "Dong",
+ },
+ "Vietnam": {
+ "code": "vn",
+ "currency": "VND",
+ "currency_name": "Dong",
"number_format": "#.###"
- },
+ },
"Virgin Islands, British": {
- "code": "vg",
+ "code": "vg",
"number_format": "#,###.##"
- },
+ },
"Virgin Islands, U.S.": {
- "code": "vi",
+ "code": "vi",
"number_format": "#,###.##"
- },
+ },
"Wallis and Futuna": {
- "code": "wf",
- "currency_fraction": "Centime",
- "currency_fraction_units": 100,
- "currency_symbol": "Fr",
+ "code": "wf",
+ "currency_fraction": "Centime",
+ "currency_fraction_units": 100,
+ "currency_symbol": "Fr",
"number_format": "#,###.##"
- },
+ },
"Western Sahara": {
- "code": "eh",
- "number_format": "#,###.##",
+ "code": "eh",
+ "number_format": "#,###.##",
"timezones": [
"Africa/El_Aaiun"
]
- },
+ },
"Yemen": {
- "code": "ye",
- "currency_fraction": "Fils",
- "currency_fraction_units": 100,
- "currency_symbol": "\ufdfc",
- "number_format": "#,###.##",
+ "code": "ye",
+ "currency_fraction": "Fils",
+ "currency_fraction_units": 100,
+ "currency_symbol": "\ufdfc",
+ "number_format": "#,###.##",
"timezones": [
"Asia/Aden"
]
- },
+ },
"Zambia": {
- "code": "zm",
- "currency": "ZMK",
- "currency_fraction": "Ngwee",
- "currency_fraction_units": 100,
- "currency_name": "Zambian Kwacha",
- "currency_symbol": "ZK",
- "number_format": "#,###.##",
+ "code": "zm",
+ "currency": "ZMK",
+ "currency_fraction": "Ngwee",
+ "currency_fraction_units": 100,
+ "currency_name": "Zambian Kwacha",
+ "currency_symbol": "ZK",
+ "number_format": "#,###.##",
"timezones": [
"Africa/Lusaka"
]
- },
+ },
"Zimbabwe": {
- "code": "zw",
- "currency": "ZWD",
- "currency_fraction": "Thebe",
- "currency_fraction_units": 100,
- "currency_name": "Zimbabwe Dollar",
- "currency_symbol": "P",
- "number_format": "# ###.##",
+ "code": "zw",
+ "currency": "ZWD",
+ "currency_fraction": "Thebe",
+ "currency_fraction_units": 100,
+ "currency_name": "Zimbabwe Dollar",
+ "currency_symbol": "P",
+ "number_format": "# ###.##",
"timezones": [
"Africa/Harare"
]
- },
+ },
"\u00c5land Islands": {
- "code": "ax",
+ "code": "ax",
"number_format": "#,###.##"
}
-}
\ No newline at end of file
+}
diff --git a/frappe/country_info.py b/frappe/country_info.py
index 81b045acd3..d3a7c94504 100644
--- a/frappe/country_info.py
+++ b/frappe/country_info.py
@@ -5,13 +5,14 @@
from __future__ import unicode_literals
import os, json, frappe
+from frappe.utils.momentjs import get_all_timezones
def get_country_info(country=None):
data = get_all()
data = frappe._dict(data.get(country, {}))
if not 'date_format' in data:
data.date_format = "dd-mm-yyyy"
-
+
return data
def get_all():
@@ -19,26 +20,23 @@ def get_all():
all_data = json.loads(local_info.read())
return all_data
-@frappe.whitelist()
+@frappe.whitelist()
def get_country_timezone_info():
- import pytz
return {
"country_info": get_all(),
- "all_timezones": pytz.all_timezones
+ "all_timezones": get_all_timezones()
}
def update():
with open(os.path.join(os.path.dirname(__file__), "currency_info.json"), "r") as nformats:
nformats = json.loads(nformats.read())
-
+
all_data = get_all()
-
+
for country in all_data:
data = all_data[country]
- data["number_format"] = nformats.get(data.get("currency", "default"),
+ data["number_format"] = nformats.get(data.get("currency", "default"),
nformats.get("default"))["display"]
-
- print all_data
-
+
with open(os.path.join(os.path.dirname(__file__), "country_info.json"), "w") as local_info:
local_info.write(json.dumps(all_data, indent=1))
diff --git a/frappe/data/Framework.sql b/frappe/data/Framework.sql
index 79c0990491..5a2c1cd82d 100644
--- a/frappe/data/Framework.sql
+++ b/frappe/data/Framework.sql
@@ -35,7 +35,7 @@ CREATE TABLE `tabDocField` (
`trigger` varchar(255) DEFAULT NULL,
`depends_on` varchar(255) DEFAULT NULL,
`permlevel` int(11) DEFAULT '0',
- `ignore_restrictions` int(1) DEFAULT NULL,
+ `ignore_user_permissions` int(1) DEFAULT NULL,
`width` varchar(255) DEFAULT NULL,
`print_width` varchar(255) DEFAULT NULL,
`default` text,
@@ -130,7 +130,6 @@ CREATE TABLE `tabDocType` (
`allow_import` int(1) DEFAULT NULL,
`hide_toolbar` int(1) DEFAULT NULL,
`hide_heading` int(1) DEFAULT NULL,
- `allow_attach` int(1) DEFAULT NULL,
`use_template` int(1) DEFAULT NULL,
`max_attachments` int(11) DEFAULT NULL,
`print_outline` varchar(255) DEFAULT NULL,
diff --git a/frappe/data/languages.txt b/frappe/data/languages.txt
index ed686d7802..6337ae8439 100644
--- a/frappe/data/languages.txt
+++ b/frappe/data/languages.txt
@@ -6,13 +6,21 @@ es español
fr français
hi हिंदी
hr hrvatski
+id Indonesia
it italiano
+ja 日本語
kn ಕನ್ನಡ
+ko 한국의
nl nederlands
-pt-BR português brasileiro
+pl polski
pt português
+pt-BR português brasileiro
+ro român
+ru русский
sr српски
ta தமிழ்
th ไทย
+tr Türk
+vi việt
zh-cn 中国(简体)
zh-tw 中國(繁體)
diff --git a/frappe/data/sample_site_config.json b/frappe/data/sample_site_config.json
index 3c7c6e2c43..21f7f5910c 100644
--- a/frappe/data/sample_site_config.json
+++ b/frappe/data/sample_site_config.json
@@ -1,20 +1,20 @@
{
- "db_name": "testdb",
+ "db_name": "testdb",
"db_password": "password",
"mute_emails": true,
-
+
"developer_mode": 1,
"auto_cache_clear": true,
"disable_website_cache": true,
"max_file_size": 1000000,
-
+
"mail_server": "localhost",
"mail_login": null,
"mail_password": null,
"mail_port": 25,
"use_ssl": 0,
"auto_email_id": "hello@example.com",
-
+
"google_login": {
"client_id": "google_client_id",
"client_secret": "google_client_secret"
@@ -27,8 +27,9 @@
"client_id": "facebook_client_id",
"client_secret": "facebook_client_secret"
},
-
+
"celery_broker": "redis://localhost",
"celery_result_backend": null,
- "scheduler_interval": 300
-}
\ No newline at end of file
+ "scheduler_interval": 300,
+ "celery_queue_per_site": true
+}
diff --git a/frappe/database.py b/frappe/database.py
index a0fbe8c827..4f72cfdf6c 100644
--- a/frappe/database.py
+++ b/frappe/database.py
@@ -9,6 +9,7 @@ import MySQLdb
import warnings
import datetime
import frappe
+import re
import frappe.model.meta
from frappe.utils import now, get_datetime
from frappe import _
@@ -169,7 +170,7 @@ class Database:
if query[:6].lower() in ['update', 'insert']:
self.transaction_writes += 1
- if self.transaction_writes > 10000:
+ if self.transaction_writes > 20000:
if self.auto_commit_on_many_writes:
frappe.db.commit()
else:
@@ -367,16 +368,20 @@ class Database:
return frappe._dict(self.sql("""select field, value from
tabSingles where doctype=%s""", doctype))
+ def get_single_value(self, doctype, fieldname):
+ val = self.sql("""select value from
+ tabSingles where doctype=%s and field=%s""", (doctype, fieldname))
+ return val[0][0] if val else None
def get_values_from_table(self, fields, filters, doctype, as_dict, debug, order_by=None, update=None):
fl = []
if isinstance(fields, (list, tuple)):
for f in fields:
- if "(" in f: # function
+ if "(" in f or " as " in f: # function
fl.append(f)
else:
fl.append("`" + f + "`")
- fl = ", ".join(fields)
+ fl = ", ".join(fl)
else:
fl = fields
if fields=="*":
@@ -485,6 +490,9 @@ class Database:
def table_exists(self, tablename):
return tablename in [d[0] for d in self.sql("show tables")]
+ def a_row_exists(self, doctype):
+ return self.sql("select name from `tab{doctype}` limit 1".format(doctype=doctype))
+
def exists(self, dt, dn=None):
if isinstance(dt, basestring):
if dt!="DocType" and dt==dn:
@@ -529,10 +537,14 @@ class Database:
def add_index(self, doctype, fields, index_name=None):
if not index_name:
index_name = "_".join(fields) + "_index"
+
+ # remove index length if present e.g. (10) from index name
+ index_name = re.sub(r"\s*\([^)]+\)\s*", r"", index_name)
+
if not frappe.db.sql("""show index from `tab%s` where Key_name="%s" """ % (doctype, index_name)):
frappe.db.commit()
frappe.db.sql("""alter table `tab%s`
- add index %s(%s)""" % (doctype, index_name, ", ".join(fields)))
+ add index `%s`(%s)""" % (doctype, index_name, ", ".join(fields)))
def close(self):
if self._conn:
@@ -540,3 +552,6 @@ class Database:
self._conn.close()
self._cursor = None
self._conn = None
+
+ def escape(self, s):
+ return unicode(MySQLdb.escape_string((s or "").encode("utf-8")), "utf-8")
diff --git a/frappe/defaults.py b/frappe/defaults.py
index de368525d2..3f96d524bc 100644
--- a/frappe/defaults.py
+++ b/frappe/defaults.py
@@ -3,6 +3,10 @@
from __future__ import unicode_literals
import frappe
+from frappe.core.doctype.notification_count.notification_count import clear_notifications
+
+# Note: DefaultValue records are identified by parenttype
+# __default, __global or 'User Permission'
common_keys = ["__default", "__global"]
@@ -20,26 +24,25 @@ def get_user_default_as_list(key, user=None):
d = get_defaults(user or frappe.session.user).get(key, None)
return (not isinstance(d, list)) and [d] or d
-def get_restrictions(user=None):
+def get_user_permissions(user=None):
if not user:
user = frappe.session.user
- if user == frappe.session.user:
- if frappe.local.restrictions is None:
- frappe.local.restrictions = build_restrictions(user)
- return frappe.local.restrictions
- else:
- return build_restrictions(user)
+ return build_user_permissions(user)
-def build_restrictions(user):
- out = frappe.cache().get_value("restrictions:" + user)
+def build_user_permissions(user):
+ out = frappe.cache().get_value("user_permissions:" + user)
if out==None:
out = {}
- for key, value in frappe.db.sql("""select defkey, defvalue
- from tabDefaultValue where parent=%s and parenttype='Restriction'""", (user,)):
- out.setdefault(key, [])
- out[key].append(value)
- frappe.cache().set_value("restrictions:" + user, out)
+ for key, value in frappe.db.sql("""select defkey, ifnull(defvalue, '') as defvalue
+ from tabDefaultValue where parent=%s and parenttype='User Permission'""", (user,)):
+ out.setdefault(key, []).append(value)
+
+ # add profile match
+ if user not in out.get("User", []):
+ out.setdefault("User", []).append(user)
+
+ frappe.cache().set_value("user_permissions:" + user, out)
return out
def get_defaults(user=None):
@@ -91,45 +94,45 @@ def add_default(key, value, parent, parenttype=None):
"defvalue": value
})
d.db_insert()
- if parenttype=="Restriction":
- frappe.local.restrictions = None
_clear_cache(parent)
def clear_default(key=None, value=None, parent=None, name=None, parenttype=None):
conditions = []
values = []
- if key:
- conditions.append("defkey=%s")
- values.append(key)
-
- if value:
- conditions.append("defvalue=%s")
- values.append(value)
-
if name:
conditions.append("name=%s")
values.append(name)
+ else:
+ if key:
+ conditions.append("defkey=%s")
+ values.append(key)
+
+ if value:
+ conditions.append("defvalue=%s")
+ values.append(value)
+
+ if parent:
+ conditions.append("parent=%s")
+ values.append(parent)
+
+ if parenttype:
+ conditions.append("parenttype=%s")
+ values.append(parenttype)
+
if parent:
- conditions.append("parent=%s")
clear_cache(parent)
- values.append(parent)
else:
clear_cache("__default")
clear_cache("__global")
- if parenttype:
- conditions.append("parenttype=%s")
- values.append(parenttype)
- if parenttype=="Restriction":
- frappe.local.restrictions = None
-
if not conditions:
raise Exception, "[clear_default] No key specified."
frappe.db.sql("""delete from tabDefaultValue where {0}""".format(" and ".join(conditions)),
tuple(values))
+
_clear_cache(parent)
def get_defaults_for(parent="__default"):
@@ -159,6 +162,7 @@ def _clear_cache(parent):
if parent in common_keys:
frappe.clear_cache()
else:
+ clear_notifications(user=parent)
frappe.clear_cache(user=parent)
def clear_cache(user=None):
diff --git a/frappe/exceptions.py b/frappe/exceptions.py
index 805d68315b..76af10a8dd 100644
--- a/frappe/exceptions.py
+++ b/frappe/exceptions.py
@@ -5,6 +5,9 @@ from __future__ import unicode_literals
# BEWARE don't put anything in this file except exceptions
+from werkzeug.exceptions import NotFound
+from MySQLdb import ProgrammingError as SQLError
+
class ValidationError(Exception):
http_status_code = 417
@@ -40,7 +43,10 @@ class RateLimitExceededError(ValidationError): pass
class CannotChangeConstantError(ValidationError): pass
class UpdateAfterSubmitError(ValidationError): pass
class LinkValidationError(ValidationError): pass
+class CancelledLinkError(LinkValidationError): pass
class DocstatusTransitionError(ValidationError): pass
class TimestampMismatchError(ValidationError): pass
class EmptyTableError(ValidationError): pass
class LinkExistsError(ValidationError): pass
+class InvalidEmailAddressError(ValidationError): pass
+class TemplateNotFoundError(ValidationError): pass
diff --git a/frappe/handler.py b/frappe/handler.py
index 2762e51b9d..b9ed28f93c 100755
--- a/frappe/handler.py
+++ b/frappe/handler.py
@@ -69,6 +69,11 @@ def handle():
def execute_cmd(cmd):
"""execute a request as python module"""
+ for hook in frappe.get_hooks("override_whitelisted_methods", {}).get(cmd, []):
+ # override using the first hook
+ cmd = hook
+ break
+
method = get_attr(cmd)
# check if whitelisted
@@ -87,11 +92,6 @@ def execute_cmd(cmd):
if ret:
frappe.response['message'] = ret
- # update session
- if "session_obj" in frappe.local:
- frappe.local.session_obj.update()
-
-
def get_attr(cmd):
"""get method object from cmd"""
if '.' in cmd:
diff --git a/frappe/hooks.py b/frappe/hooks.py
index 95f2299710..d0b51a5da0 100644
--- a/frappe/hooks.py
+++ b/frappe/hooks.py
@@ -1,10 +1,11 @@
app_name = "frappe"
app_title = "Frappe Framework"
-app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors"
+app_publisher = "Web Notes Technologies Pvt. Ltd."
app_description = "Full Stack Web Application Framwork in Python"
app_icon = "assets/frappe/images/frappe.svg"
-app_version = "4.0.0-wip"
+app_version = "4.3.0"
app_color = "#3498db"
+app_email = "support@frappe.io"
before_install = "frappe.utils.install.before_install"
after_install = "frappe.utils.install.after_install"
@@ -24,7 +25,7 @@ web_include_css = [
"style_settings.css"
]
-website_clear_cache = "frappe.templates.generators.website_group.clear_cache"
+website_clear_cache = "frappe.website.doctype.website_group.website_group.clear_cache"
write_file_keys = ["file_url", "file_name"]
@@ -32,43 +33,55 @@ notification_config = "frappe.core.notifications.get_notification_config"
before_tests = "frappe.utils.install.before_tests"
+website_generators = ["Web Page", "Blog Post", "Website Group", "Blog Category", "Web Form"]
+
# permissions
permission_query_conditions = {
- "Event": "frappe.core.doctype.event.event.get_permission_query_conditions",
- "ToDo": "frappe.core.doctype.todo.todo.get_permission_query_conditions"
- }
+ "Event": "frappe.core.doctype.event.event.get_permission_query_conditions",
+ "ToDo": "frappe.core.doctype.todo.todo.get_permission_query_conditions",
+ "User": "frappe.core.doctype.user.user.get_permission_query_conditions"
+}
has_permission = {
- "Event": "frappe.core.doctype.event.event.has_permission",
- "ToDo": "frappe.core.doctype.todo.todo.has_permission"
- }
-
-# bean
+ "Event": "frappe.core.doctype.event.event.has_permission",
+ "ToDo": "frappe.core.doctype.todo.todo.has_permission",
+ "User": "frappe.core.doctype.user.user.has_permission"
+}
doc_events = {
- "*": {
- "on_update": "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications",
- "on_cancel": "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications",
- "on_trash": "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications"
- },
- "User Vote": {
- "after_insert": "frappe.templates.generators.website_group.clear_cache_on_doc_event"
- },
- "Website Route Permission": {
- "on_update": "frappe.templates.generators.website_group.clear_cache_on_doc_event"
- }
+ "*": {
+ "after_insert": "frappe.core.doctype.email_alert.email_alert.trigger_email_alerts",
+ "validate": "frappe.core.doctype.email_alert.email_alert.trigger_email_alerts",
+ "on_update": [
+ "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications",
+ "frappe.core.doctype.email_alert.email_alert.trigger_email_alerts"
+ ],
+ "after_rename": "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications",
+ "on_submit": "frappe.core.doctype.email_alert.email_alert.trigger_email_alerts",
+ "on_cancel": [
+ "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications",
+ "frappe.core.doctype.email_alert.email_alert.trigger_email_alerts"
+ ],
+ "on_trash": "frappe.core.doctype.notification_count.notification_count.clear_doctype_notifications"
+ },
+ "Website Route Permission": {
+ "on_update": "frappe.website.doctype.website_group.website_group.clear_cache_on_doc_event"
}
+}
scheduler_events = {
"all": ["frappe.utils.email_lib.bulk.flush"],
"daily": [
"frappe.utils.email_lib.bulk.clear_outbox",
- "frappe.core.doctype.notification_count.notification_count.delete_event_notification_count",
+ "frappe.core.doctype.notification_count.notification_count.clear_notifications",
"frappe.core.doctype.event.event.send_event_digest",
"frappe.sessions.clear_expired_sessions",
+ "frappe.core.doctype.email_alert.email_alert.trigger_daily_alerts",
],
"hourly": [
- "frappe.templates.generators.website_group.clear_event_cache"
+ "frappe.website.doctype.website_group.website_group.clear_event_cache"
]
}
+
+mail_footer = "frappe.core.doctype.outgoing_email_settings.outgoing_email_settings.get_mail_footer"
diff --git a/frappe/installer.py b/frappe/installer.py
index 2dc37116d1..96e04a7aff 100755
--- a/frappe/installer.py
+++ b/frappe/installer.py
@@ -10,10 +10,10 @@ import os, json
import frappe
import frappe.database
import getpass
-from frappe import _
from frappe.model.db_schema import DbManager
from frappe.model.sync import sync_for
from frappe.utils.fixtures import sync_fixtures
+from frappe.website import render, statics
def install_db(root_login="root", root_password=None, db_name=None, source_sql=None,
admin_password = 'admin', verbose=True, force=0, site_config=None, reinstall=False):
@@ -94,7 +94,7 @@ def install_app(name, verbose=False, set_as_patched=True):
if name in installed_apps:
print "App Already Installed"
- frappe.msgprint(_("App Already Installed"))
+ frappe.msgprint("App {0} already installed".format(name))
return
if name != "frappe":
@@ -116,20 +116,23 @@ def install_app(name, verbose=False, set_as_patched=True):
for after_install in app_hooks.after_install or []:
frappe.get_attr(after_install)()
- sync_fixtures()
+ print "Installing Fixtures..."
+ sync_fixtures(name)
frappe.flags.in_install_app = False
-def add_to_installed_apps(app_name, rebuild_sitemap=True):
+def add_to_installed_apps(app_name, rebuild_website=True):
installed_apps = frappe.get_installed_apps()
if not app_name in installed_apps:
installed_apps.append(app_name)
frappe.db.set_global("installed_apps", json.dumps(installed_apps))
frappe.db.commit()
- if rebuild_sitemap:
- from frappe.website.doctype.website_template.website_template import rebuild_website_template
- rebuild_website_template()
+ if rebuild_website:
+ render.clear_cache()
+ statics.sync().start()
+
+ frappe.db.commit()
frappe.clear_cache()
@@ -190,5 +193,5 @@ def add_module_defs(app):
for module in modules:
d = frappe.new_doc("Module Def")
d.app_name = app
- d.module_name = frappe.unscrub(module)
+ d.module_name = module
d.save()
diff --git a/frappe/model/__init__.py b/frappe/model/__init__.py
index 067df6bc27..f6d3af095f 100644
--- a/frappe/model/__init__.py
+++ b/frappe/model/__init__.py
@@ -7,9 +7,9 @@ import frappe
import json
-no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'Button', 'Image']
+no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'Button', 'Image', 'Fold']
default_fields = ['doctype','name','owner','creation','modified','modified_by','parent','parentfield','parenttype','idx','docstatus']
-integer_docfield_properties = ["reqd", "search_index", "in_list_view", "permlevel", "hidden", "read_only", "ignore_restrictions", "allow_on_submit", "report_hide", "in_filter", "no_copy", "print_hide"]
+integer_docfield_properties = ["reqd", "search_index", "in_list_view", "permlevel", "hidden", "read_only", "ignore_user_permissions", "allow_on_submit", "report_hide", "in_filter", "no_copy", "print_hide"]
def insert(doclist):
if not isinstance(doclist, list):
@@ -113,7 +113,7 @@ def rename_field(doctype, old_fieldname, new_fieldname):
where doc_type=%s and field_name=%s""", (new_fieldname, doctype, old_fieldname))
update_reports(doctype, old_fieldname, new_fieldname)
- update_users_report_view_settings(doctype, old_fieldname)
+ update_users_report_view_settings(doctype, old_fieldname, new_fieldname)
def update_reports(doctype, old_fieldname, new_fieldname):
def _get_new_sort_by(report_dict, report, key):
@@ -175,7 +175,7 @@ def update_reports(doctype, old_fieldname, new_fieldname):
frappe.db.sql("""update `tabReport` set `json`=%s where name=%s""", (new_val, r.name))
-def update_users_report_view_settings(doctype, ref_fieldname):
+def update_users_report_view_settings(doctype, ref_fieldname, new_fieldname):
user_report_cols = frappe.db.sql("""select defkey, defvalue from `tabDefaultValue` where
defkey like '_list_settings:%'""")
for key, value in user_report_cols:
@@ -183,8 +183,11 @@ def update_users_report_view_settings(doctype, ref_fieldname):
columns_modified = False
for field, field_doctype in json.loads(value):
if field == ref_fieldname and field_doctype == doctype:
- new_columns.append([field, field_doctype])
+ new_columns.append([new_fieldname, field_doctype])
columns_modified=True
+ else:
+ new_columns.append([field, field_doctype])
+
if columns_modified:
frappe.db.sql("""update `tabDefaultValue` set defvalue=%s
where defkey=%s""" % ('%s', '%s'), (json.dumps(new_columns), key))
diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py
index e723579bce..c8c264354a 100644
--- a/frappe/model/base_document.py
+++ b/frappe/model/base_document.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, json, sys
from frappe import _
-from frappe.utils import cint, flt, now
+from frappe.utils import cint, flt, now, cstr, strip_html
from frappe.model import default_fields
from frappe.model.naming import set_new_name
@@ -13,6 +13,7 @@ class BaseDocument(object):
def __init__(self, d):
self.update(d)
+ self.dont_update_if_missing = []
@property
def meta(self):
@@ -33,6 +34,8 @@ class BaseDocument(object):
for key, value in d.iteritems():
self.set(key, value)
+ return self
+
def update_if_missing(self, d):
if isinstance(d, BaseDocument):
d = d.get_valid_dict()
@@ -40,7 +43,8 @@ class BaseDocument(object):
if "doctype" in d:
self.set("doctype", d.get("doctype"))
for key, value in d.iteritems():
- if self.get(key) is None:
+ # dont_update_if_missing is a list of fieldnames, for which, you don't want to set default value
+ if (self.get(key) is None) and (value is not None) and (key not in self.dont_update_if_missing):
self.set(key, value)
def get_db_value(self, key):
@@ -79,6 +83,10 @@ class BaseDocument(object):
else:
self.__dict__[key] = value
+ def delete_key(self, key):
+ if key in self.__dict__:
+ del self.__dict__[key]
+
def append(self, key, value=None):
if value==None:
value={}
@@ -160,6 +168,9 @@ class BaseDocument(object):
if doc[k] is None:
del doc[k]
+ if self.get("_user_tags"):
+ doc["_user_tags"] = self.get("_user_tags")
+
if self.get("__islocal"):
doc["__islocal"] = 1
@@ -220,10 +231,15 @@ class BaseDocument(object):
def _fix_numeric_types(self):
for df in self.meta.get("fields"):
- if df.fieldtype in ("Int", "Check"):
+ if df.fieldtype == "Check":
self.set(df.fieldname, cint(self.get(df.fieldname)))
- elif df.fieldtype in ("Float", "Currency"):
- self.set(df.fieldname, flt(self.get(df.fieldname)))
+
+ elif self.get(df.fieldname) is not None:
+ if df.fieldtype == "Int":
+ self.set(df.fieldname, cint(self.get(df.fieldname)))
+
+ elif df.fieldtype in ("Float", "Currency", "Percent"):
+ self.set(df.fieldname, flt(self.get(df.fieldname)))
if self.docstatus is not None:
self.docstatus = cint(self.docstatus)
@@ -244,12 +260,12 @@ class BaseDocument(object):
missing = []
for df in self.meta.get("fields", {"reqd": 1}):
- if self.get(df.fieldname) in (None, []):
+ if self.get(df.fieldname) in (None, []) or not strip_html(cstr(self.get(df.fieldname))).strip():
missing.append((df.fieldname, get_msg(df)))
return missing
- def get_invalid_links(self):
+ def get_invalid_links(self, is_submittable=False):
def get_msg(df, docname):
if self.parentfield:
return "{} #{}: {}: {}".format(_("Row"), self.idx, _(df.label), docname)
@@ -257,17 +273,63 @@ class BaseDocument(object):
return "{}: {}".format(_(df.label), docname)
invalid_links = []
- for df in self.meta.get_link_fields():
- doctype = df.options
+ cancelled_links = []
+ for df in self.meta.get_link_fields() + self.meta.get("fields",
+ {"fieldtype":"Dynamic Link"}):
- if not doctype:
- frappe.throw(_("Options not set for link field {0}").format(df.fieldname))
docname = self.get(df.fieldname)
- if docname and not frappe.db.get_value(doctype, docname):
- invalid_links.append((df.fieldname, docname, get_msg(df, docname)))
+ if docname:
+ if df.fieldtype=="Link":
+ doctype = df.options
+ if not doctype:
+ frappe.throw(_("Options not set for link field {0}").format(df.fieldname))
+ else:
+ doctype = self.get(df.options)
+ if not doctype:
+ frappe.throw(_("{0} must be set first").format(self.meta.get_label(df.options)))
+
+ # MySQL is case insensitive. Preserve case of the original docname in the Link Field.
+ value = frappe.db.get_value(doctype, docname)
+ setattr(self, df.fieldname, value)
+
+ if not value:
+ invalid_links.append((df.fieldname, docname, get_msg(df, docname)))
+
+ elif (df.fieldname != "amended_from"
+ and (is_submittable or self.meta.is_submittable) and frappe.get_meta(doctype).is_submittable
+ and cint(frappe.db.get_value(doctype, docname, "docstatus"))==2):
+
+ cancelled_links.append((df.fieldname, docname, get_msg(df, docname)))
- return invalid_links
+ return invalid_links, cancelled_links
+
+ def _validate_selects(self):
+ if frappe.flags.in_import:
+ return
+
+ for df in self.meta.get_select_fields():
+ if df.fieldname=="naming_series" or not (self.get(df.fieldname) and df.options):
+ continue
+
+ options = (df.options or "").split("\n")
+
+ # if only empty options
+ if not filter(None, options):
+ continue
+
+ # strip and set
+ self.set(df.fieldname, cstr(self.get(df.fieldname)).strip())
+ value = self.get(df.fieldname)
+
+ if value not in options and not (frappe.flags.in_test and value.startswith("_T-")):
+ # show an elaborate message
+ prefix = _("Row #{0}:").format(self.idx) if self.get("parentfield") else ""
+ label = _(self.meta.get_label(df.fieldname))
+ comma_options = '", "'.join(_(each) for each in options)
+
+ frappe.throw(_('{0} {1} cannot be "{2}". It should be one of "{3}"').format(prefix, label,
+ value, comma_options))
def _validate_constants(self):
if frappe.flags.in_import:
@@ -290,6 +352,11 @@ class BaseDocument(object):
frappe.throw(_("Not allowed to change {0} after submission").format(df.label),
frappe.UpdateAfterSubmitError)
+ def get_formatted(self, fieldname, doc=None, currency=None):
+ from frappe.utils.formatters import format_value
+ return format_value(self.get(fieldname), self.meta.get_field(fieldname),
+ doc=doc or self, currency=currency)
+
def _filter(data, filters, limit=None):
"""pass filters as:
{"key": "val", "key": ["!=", "val"],
diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py
index ae3d12dc82..aa4f4983ee 100644
--- a/frappe/model/create_new.py
+++ b/frappe/model/create_new.py
@@ -9,6 +9,7 @@ Create a new document with defaults set
import frappe
from frappe.utils import nowdate, nowtime, cint, flt
import frappe.defaults
+from frappe.model.db_schema import type_map
def get_new_doc(doctype, parent_doc = None, parentfield = None):
doc = frappe.get_doc({
@@ -18,7 +19,7 @@ def get_new_doc(doctype, parent_doc = None, parentfield = None):
"docstatus": 0
})
- restrictions = frappe.defaults.get_restrictions()
+ user_permissions = frappe.defaults.get_user_permissions()
if parent_doc:
doc.parent = parent_doc.name
@@ -29,41 +30,64 @@ def get_new_doc(doctype, parent_doc = None, parentfield = None):
defaults = frappe.defaults.get_defaults()
- for d in doc.meta.get("fields"):
- default = defaults.get(d.fieldname)
-
- if (d.fieldtype=="Link") and d.ignore_restrictions != 1 and (d.options in restrictions)\
- and len(restrictions[d.options])==1:
- doc.set(d.fieldname, restrictions[d.options][0])
- elif default:
- doc.set(d.fieldname, default)
- elif d.get("default"):
- if d.default == "__user":
- doc.set(d.fieldname, frappe.session.user)
- elif d.default == "Today":
- doc.set(d.fieldname, nowdate())
-
- elif d.default.startswith(":"):
- ref_doctype = d.default[1:]
- ref_fieldname = ref_doctype.lower().replace(" ", "_")
- if parent_doc:
- ref_docname = parent_doc.get(ref_fieldname)
- else:
- ref_docname = frappe.db.get_default(ref_fieldname)
- doc.set(d.fieldname, frappe.db.get_value(ref_doctype, ref_docname, d.fieldname))
- else:
- doc.set(d.fieldname, d.default)
-
- # convert type of default
- if d.fieldtype in ("Int", "Check"):
- doc.set(d.fieldname, cint(doc.get(d.fieldname)))
- elif d.fieldtype in ("Float", "Currency"):
- doc.set(d.fieldname, flt(doc.get(d.fieldname)))
-
- elif d.fieldtype == "Time":
- doc.set(d.fieldname, nowtime())
-
- elif (d.fieldtype == "Select" and d.options and d.options != "[Select]"):
- doc.set(d.fieldname, d.options.split("\n")[0])
+ for df in doc.meta.get("fields"):
+ if df.fieldtype in type_map:
+ default_value = get_default_value(df, defaults, user_permissions, parent_doc)
+ doc.set(df.fieldname, default_value)
+
+ doc._fix_numeric_types()
return doc
+
+def get_default_value(df, defaults, user_permissions, parent_doc):
+ user_permissions_exist = (df.fieldtype=="Link"
+ and not getattr(df, "ignore_user_permissions", False)
+ and df.options in (user_permissions or []))
+
+ # don't set defaults for "User" link field using User Permissions!
+ if df.fieldtype == "Link" and df.options != "User":
+ # 1 - look in user permissions
+ if user_permissions_exist and len(user_permissions[df.options])==1:
+ return user_permissions[df.options][0]
+
+ # 2 - Look in user defaults
+ user_default = defaults.get(df.fieldname)
+ is_allowed_user_default = user_default and (not user_permissions_exist
+ or (user_default in user_permissions.get(df.options, [])))
+
+ # is this user default also allowed as per user permissions?
+ if is_allowed_user_default:
+ return user_default
+
+ # 3 - look in default of docfield
+ if df.get("default"):
+ if df.default == "__user":
+ return frappe.session.user
+
+ elif df.default == "Today":
+ return nowdate()
+
+ elif df.default.startswith(":"):
+ # default value based on another document
+ ref_doctype = df.default[1:]
+ ref_fieldname = ref_doctype.lower().replace(" ", "_")
+ ref_docname = parent_doc.get(ref_fieldname) if parent_doc else frappe.db.get_default(ref_fieldname)
+
+ default_value = frappe.db.get_value(ref_doctype, ref_docname, df.fieldname)
+ is_allowed_default_value = (not user_permissions_exist or
+ (default_value in user_permissions.get(df.options, [])))
+
+ # is this allowed as per user permissions
+ if is_allowed_default_value:
+ return default_value
+
+ # a static default value
+ is_allowed_default_value = (not user_permissions_exist or (df.default in user_permissions.get(df.options, [])))
+ if df.fieldtype!="Link" or df.options=="User" or is_allowed_default_value:
+ return df.default
+
+ elif df.fieldtype == "Time":
+ return nowtime()
+
+ elif (df.fieldtype == "Select" and df.options and df.options != "[Select]"):
+ return df.options.split("\n")[0]
diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py
index da49f92fde..6658a792bf 100644
--- a/frappe/model/db_query.py
+++ b/frappe/model/db_query.py
@@ -15,15 +15,16 @@ class DatabaseQuery(object):
self.doctype = doctype
self.tables = []
self.conditions = []
+ self.fields = ["`tab{0}`.`name`".format(doctype)]
+ self.user = None
self.ignore_permissions = False
- self.fields = ["name"]
def execute(self, query=None, filters=None, fields=None, or_filters=None,
docstatus=None, group_by=None, order_by=None, limit_start=0,
limit_page_length=20, as_list=False, with_childnames=False, debug=False,
- ignore_permissions=False):
- if not frappe.has_permission(self.doctype, "read"):
- raise frappe.PermissionError
+ ignore_permissions=False, user=None):
+ if not ignore_permissions and not frappe.has_permission(self.doctype, "read", user=user):
+ raise frappe.PermissionError, self.doctype
if fields:
self.fields = fields
@@ -38,7 +39,7 @@ class DatabaseQuery(object):
self.debug = debug
self.as_list = as_list
self.ignore_permissions = ignore_permissions
-
+ self.user = user or frappe.session.user
if query:
return self.run_custom_query(query)
@@ -49,8 +50,11 @@ class DatabaseQuery(object):
args = self.prepare_args()
args.limit = self.add_limit()
- query = """select %(fields)s from %(tables)s where %(conditions)s
- %(group_by)s order by %(order_by)s %(limit)s""" % args
+ if args.conditions:
+ args.conditions = "where " + args.conditions
+
+ query = """select %(fields)s from %(tables)s %(conditions)s
+ %(group_by)s %(order_by)s %(limit)s""" % args
return frappe.db.sql(query, as_dict=not self.as_list, debug=self.debug)
@@ -75,18 +79,18 @@ class DatabaseQuery(object):
args.fields = ', '.join(self.fields)
self.set_order_by(args)
+ self.check_sort_by_table(args.order_by)
+ args.order_by = args.order_by and (" order by " + args.order_by) or ""
args.group_by = self.group_by and (" group by " + self.group_by) or ""
- self.check_sort_by_table(args.order_by)
-
return args
def parse_args(self):
if isinstance(self.filters, basestring):
self.filters = json.loads(self.filters)
if isinstance(self.fields, basestring):
- self.filters = json.loads(self.fields)
+ self.fields = json.loads(self.fields)
if isinstance(self.filters, dict):
fdict = self.filters
self.filters = []
@@ -106,7 +110,8 @@ class DatabaseQuery(object):
# add tables from fields
if self.fields:
for f in self.fields:
- if "." not in f: continue
+ if ( not ("tab" in f and "." in f) ) or ("locate(" in f): continue
+
table_name = f.split('.')[0]
if table_name.lower().startswith('group_concat('):
@@ -127,19 +132,36 @@ class DatabaseQuery(object):
def remove_user_tags(self):
"""remove column _user_tags if not in table"""
columns = frappe.db.get_table_columns(self.doctype)
+
+ # remove from fields
to_remove = []
for fld in self.fields:
- for f in ("_user_tags", "_comments"):
+ for f in ("_user_tags", "_comments", "_assign"):
if f in fld and not f in columns:
to_remove.append(fld)
for fld in to_remove:
del self.fields[self.fields.index(fld)]
+ # remove from filters
+ to_remove = []
+ for each in self.filters:
+ if isinstance(each, basestring):
+ each = [each]
+
+ for element in each:
+ if element in ("_user_tags", "_comments", "_assign") and element not in columns:
+ to_remove.append(each)
+
+ for each in to_remove:
+ if isinstance(self.filters, dict):
+ del self.filters[each]
+ else:
+ self.filters.remove(each)
+
def build_conditions(self):
self.conditions = []
self.or_conditions = []
- self.add_docstatus_conditions()
self.build_filter_conditions(self.filters, self.conditions)
self.build_filter_conditions(self.or_filters, self.or_conditions)
@@ -151,13 +173,7 @@ class DatabaseQuery(object):
if not self.ignore_permissions:
match_conditions = self.build_match_conditions()
if match_conditions:
- self.conditions.append(match_conditions)
-
- def add_docstatus_conditions(self):
- if self.docstatus:
- self.conditions.append(self.tables[0] + '.docstatus in (' + ','.join(self.docstatus) + ')')
- else:
- self.conditions.append(self.tables[0] + '.docstatus < 2')
+ self.conditions.append("(" + match_conditions + ")")
def build_filter_conditions(self, filters, conditions):
"""build conditions from user filters"""
@@ -178,15 +194,20 @@ class DatabaseQuery(object):
opts = f[3]
if not isinstance(opts, (list, tuple)):
opts = f[3].split(",")
- opts = ["'" + t.strip().replace("'", "\\'") + "'" for t in opts]
- f[3] = "(" + ', '.join(opts) + ")"
- conditions.append('ifnull(' + tname + '.' + f[1] + ", '') " + f[2] + " " + f[3])
+ opts = [frappe.db.escape(t.strip()) for t in opts]
+ f[3] = '("{0}")'.format('", "'.join(opts))
+ conditions.append('ifnull({tname}.{fname}, "") {operator} {value}'.format(
+ tname=tname, fname=f[1], operator=f[2], value=f[3]))
else:
df = frappe.get_meta(f[0]).get("fields", {"fieldname": f[1]})
if f[2] == "like" or (isinstance(f[3], basestring) and
(not df or df[0].fieldtype not in ["Float", "Int", "Currency", "Percent"])):
- value, default_val = ("'" + f[3].replace("'", "\\'") + "'"), '""'
+ if f[2] == "like":
+ # because "like" uses backslash (\) for escaping
+ f[3] = f[3].replace("\\", "\\\\")
+
+ value, default_val = '"{0}"'.format(frappe.db.escape(f[3])), '""'
else:
value, default_val = flt(f[3]), 0
@@ -209,67 +230,68 @@ class DatabaseQuery(object):
def build_match_conditions(self, as_condition=True):
"""add match conditions if applicable"""
- self.match_filters = {}
+ self.match_filters = []
self.match_conditions = []
- self.match_or_conditions = []
if not self.tables: self.extract_tables()
- # explict permissions
- restricted_by_user = frappe.permissions.get_user_perms(frappe.get_meta(self.doctype)).restricted
+ meta = frappe.get_meta(self.doctype)
+ role_permissions = frappe.permissions.get_role_permissions(meta, user=self.user)
+ if not meta.istable and not role_permissions.get("read") and not getattr(self, "ignore_permissions", False):
+ frappe.throw(_("No permission to read {0}").format(self.doctype))
- # get restrictions
- restrictions = frappe.defaults.get_restrictions()
+ # apply user permissions?
+ if role_permissions.get("apply_user_permissions", {}).get("read"):
+ # get user permissions
+ user_permissions = frappe.defaults.get_user_permissions(self.user)
+ self.add_user_permissions(user_permissions,
+ user_permission_doctypes=role_permissions.get("user_permission_doctypes"))
- if restricted_by_user:
- self.match_or_conditions.append('`tab{doctype}`.`owner`="{user}"'.format(doctype=self.doctype,
- user=frappe.local.session.user))
- self.match_filters["owner"] = frappe.session.user
+ if as_condition:
+ conditions = ""
+ if self.match_conditions:
+ # will turn out like ((blog_post in (..) and blogger in (...)) or (blog_category in (...)))
+ conditions = "((" + ") or (".join(self.match_conditions) + "))"
- if restrictions:
- self.add_restrictions(restrictions)
+ doctype_conditions = self.get_permission_query_conditions()
+ if doctype_conditions:
+ conditions += (' and ' + doctype_conditions) if conditions else doctype_conditions
+
+ return conditions
- if as_condition:
- return self.build_match_condition_string()
else:
return self.match_filters
- def add_restrictions(self, restrictions):
- fields_to_check = frappe.get_meta(self.doctype).get_restricted_fields(restrictions.keys())
- if self.doctype in restrictions:
- fields_to_check.append(frappe._dict({"fieldname":"name", "options":self.doctype}))
+ def add_user_permissions(self, user_permissions, user_permission_doctypes=None):
+ user_permission_doctypes = frappe.permissions.get_user_permission_doctypes(user_permission_doctypes,
+ user_permissions)
+ meta = frappe.get_meta(self.doctype)
- # check in links
- for df in fields_to_check:
- self.match_conditions.append("""(ifnull(`tab{doctype}`.`{fieldname}`, "")="" or \
- `tab{doctype}`.`{fieldname}` in ({values}))""".format(doctype=self.doctype,
+ for doctypes in user_permission_doctypes:
+ match_filters = {}
+ match_conditions = []
+ # check in links
+ for df in meta.get_fields_to_check_permissions(doctypes):
+ match_conditions.append("""(ifnull(`tab{doctype}`.`{fieldname}`, "")=""
+ or `tab{doctype}`.`{fieldname}` in ({values}))""".format(
+ doctype=self.doctype,
fieldname=df.fieldname,
- values=", ".join([('"'+v.replace('"', '\"')+'"') \
- for v in restrictions[df.options]])))
- self.match_filters.setdefault(df.fieldname, [])
- self.match_filters[df.fieldname]= restrictions[df.options]
-
- def build_match_condition_string(self):
- conditions = " and ".join(self.match_conditions)
- doctype_conditions = self.get_permission_query_conditions()
- if doctype_conditions:
- conditions += ' and ' + doctype_conditions if conditions else doctype_conditions
-
- if self.match_or_conditions:
- if conditions:
- conditions = '({conditions}) or {or_conditions}'.format(conditions=conditions,
- or_conditions = ' or '.join(self.match_or_conditions))
- else:
- conditions = " or ".join(self.match_or_conditions)
+ values=", ".join([('"'+v.replace('"', '\"')+'"') for v in user_permissions[df.options]])
+ ))
+ match_filters[df.options] = user_permissions[df.options]
- return conditions
+ if match_conditions:
+ self.match_conditions.append(" and ".join(match_conditions))
+
+ if match_filters:
+ self.match_filters.append(match_filters)
def get_permission_query_conditions(self):
condition_methods = frappe.get_hooks("permission_query_conditions", {}).get(self.doctype, [])
if condition_methods:
conditions = []
for method in condition_methods:
- c = frappe.get_attr(method)()
+ c = frappe.call(frappe.get_attr(method), self.user)
if c:
conditions.append(c)
@@ -285,8 +307,23 @@ class DatabaseQuery(object):
if self.order_by:
args.order_by = self.order_by
else:
- args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype,
- meta.sort_field or "modified", meta.sort_order or "desc")
+ args.order_by = ""
+
+ # don't add order by from meta if a mysql group function is used without group by clause
+ group_function_without_group_by = (len(self.fields)==1 and
+ ( self.fields[0].lower().startswith("count(")
+ or self.fields[0].lower().startswith("min(")
+ or self.fields[0].lower().startswith("max(")
+ ) and not self.group_by)
+
+ if not group_function_without_group_by:
+
+ args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype,
+ meta.sort_field or "modified", meta.sort_order or "desc")
+
+ # draft docs always on top
+ if meta.is_submittable:
+ args.order_by = "`tab{0}`.docstatus asc, ".format(self.doctype) + args.order_by
def check_sort_by_table(self, order_by):
if "." in order_by:
diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py
index 127f2de333..7f2a013d8c 100644
--- a/frappe/model/db_schema.py
+++ b/frappe/model/db_schema.py
@@ -29,6 +29,7 @@ type_map = {
,'Text': ('text', '')
,'Data': ('varchar', '255')
,'Link': ('varchar', '255')
+ ,'Dynamic Link':('varchar', '255')
,'Password': ('varchar', '255')
,'Select': ('varchar', '255')
,'Read Only': ('varchar', '255')
@@ -77,8 +78,8 @@ class DbTable:
name varchar(255) not null primary key,
creation datetime(6),
modified datetime(6),
- modified_by varchar(40),
- owner varchar(60),
+ modified_by varchar(255),
+ owner varchar(255),
docstatus int(1) default '0',
parent varchar(255),
parentfield varchar(255),
@@ -197,6 +198,9 @@ class DbTable:
query.append("drop index `{}`".format(col.fieldname))
for col in list(set(self.set_default).difference(set(self.change_type))):
+ if col.fieldname=="name":
+ continue
+
if not col.default:
col_default = "null"
else:
@@ -390,7 +394,7 @@ def remove_all_foreign_keys():
frappe.db.sql("set foreign_key_checks = 0")
frappe.db.commit()
for t in frappe.db.sql("select name from tabDocType where ifnull(issingle,0)=0"):
- dbtab = frappe.model.db_schema.DbTable(t[0])
+ dbtab = DbTable(t[0])
try:
fklist = dbtab.get_foreign_keys()
except Exception, e:
diff --git a/frappe/model/delete_doc.py b/frappe/model/delete_doc.py
index 5314698194..a0d56f31f0 100644
--- a/frappe/model/delete_doc.py
+++ b/frappe/model/delete_doc.py
@@ -8,6 +8,8 @@ import frappe.model.meta
import frappe.defaults
from frappe.utils.file_manager import remove_all
from frappe import _
+from rename_doc import dynamic_link_queries
+from frappe.model.naming import revert_series_if_last
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
"""
@@ -20,54 +22,97 @@ def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reloa
doctype = frappe.form_dict.get('dt')
name = frappe.form_dict.get('dn')
- if not doctype:
- frappe.msgprint(_('Nothing to delete'), raise_exception =1)
+ names = name
+ if isinstance(name, basestring):
+ names = [name]
- # already deleted..?
- if not frappe.db.exists(doctype, name):
- return
+ for name in names or []:
- doc = frappe.get_doc(doctype, name)
+ # already deleted..?
+ if not frappe.db.exists(doctype, name):
+ return
- if not for_reload:
- check_permission_and_not_submitted(doc, ignore_permissions)
- doc.run_method("on_trash")
- # check if links exist
- if not force:
- check_if_doc_is_linked(doc)
+ # delete attachments
+ remove_all(doctype, name)
- try:
- if doctype!="DocType" and doctype==name:
- frappe.db.sql("delete from `tabSingles` where doctype=%s", name)
- else:
- frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,))
+ if doctype=="DocType":
+ if for_reload:
- for t in doc.meta.get_table_fields():
- if t.options not in ignore_doctypes:
- frappe.db.sql("delete from `tab%s` where parent = %s" % (t.options, '%s'), (name,))
+ try:
+ doc = frappe.get_doc(doctype, name)
+ except frappe.DoesNotExistError:
+ pass
+ else:
+ doc.run_method("before_reload")
- except Exception, e:
- if e.args[0]==1451:
- frappe.throw(_("Cannot delete {0} {1} is it is referenced in another record").format(doctype, name))
+ else:
+ frappe.db.sql("delete from `tabCustom Field` where dt = %s", name)
+ frappe.db.sql("delete from `tabCustom Script` where dt = %s", name)
+ frappe.db.sql("delete from `tabProperty Setter` where doc_type = %s", name)
+ frappe.db.sql("delete from `tabReport` where ref_doctype=%s", name)
- raise
+ delete_from_table(doctype, name, ignore_doctypes, None)
+
+ else:
+ doc = frappe.get_doc(doctype, name)
- # delete attachments
- remove_all(doctype, name)
+ if not for_reload:
+ check_permission_and_not_submitted(doc, ignore_permissions)
+ doc.run_method("on_trash")
- # delete restrictions
- frappe.defaults.clear_default(parenttype="Restriction", key=doctype, value=name)
+ delete_linked_todos(doc)
+ # check if links exist
+ if not force:
+ check_if_doc_is_linked(doc)
+ check_if_doc_is_dynamically_linked(doc)
+
+ update_naming_series(doc)
+ delete_from_table(doctype, name, ignore_doctypes, doc)
+
+ # delete user_permissions
+ frappe.defaults.clear_default(parenttype="User Permission", key=doctype, value=name)
return 'okay'
+def update_naming_series(doc):
+ if doc.meta.autoname:
+ if doc.meta.autoname.startswith("naming_series:") \
+ and getattr(doc, "naming_series", None):
+ revert_series_if_last(doc.naming_series, doc.name)
+
+ elif doc.meta.autoname.split(":")[0] not in ("Prompt", "field", "hash"):
+ revert_series_if_last(doc.meta.autoname, doc.name)
+
+def delete_from_table(doctype, name, ignore_doctypes, doc):
+ if doctype!="DocType" and doctype==name:
+ frappe.db.sql("delete from `tabSingles` where doctype=%s", name)
+ else:
+ frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,))
+
+ # get child tables
+ if doc:
+ tables = [d.options for d in doc.meta.get_table_fields()]
+
+ else:
+ def get_table_fields(field_doctype):
+ return frappe.db.sql_list("""select options from `tab{}` where fieldtype='Table'
+ and parent=%s""".format(field_doctype), doctype)
+
+ tables = get_table_fields("DocField") + get_table_fields("Custom Field")
+
+ # delete from child tables
+ for t in list(set(tables)):
+ if t not in ignore_doctypes:
+ frappe.db.sql("delete from `tab%s` where parenttype=%s and parent = %s" % (t, '%s', '%s'), (doctype, name))
+
def check_permission_and_not_submitted(doc, ignore_permissions=False):
# permission
if not ignore_permissions and frappe.session.user!="Administrator" and not doc.has_permission("delete"):
- frappe.msgprint(_("User not allowed to delete."), raise_exception=True)
+ frappe.msgprint(_("User not allowed to delete {0}: {1}").format(doc.doctype, doc.name), raise_exception=True)
# check if submitted
if doc.docstatus == 1:
- frappe.msgprint(_("Submitted Record cannot be deleted")+": "+doc.name+"("+doc.doctype+")",
+ frappe.msgprint(_("{0} {1}: Submitted Record cannot be deleted.").format(doc.doctype, doc.name),
raise_exception=True)
def check_if_doc_is_linked(doc, method="Delete"):
@@ -88,3 +133,25 @@ def check_if_doc_is_linked(doc, method="Delete"):
frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
doc.name, item.parent or item.name, item.parenttype if item.parent else link_dt),
frappe.LinkExistsError)
+
+def check_if_doc_is_dynamically_linked(doc):
+ for query in dynamic_link_queries:
+ for df in frappe.db.sql(query, as_dict=True):
+ if frappe.get_meta(df.parent).issingle:
+
+ # dynamic link in single doc
+ refdoc = frappe.get_singles_dict(df.parent)
+ if refdoc.get(df.options)==doc.doctype and refdoc.get(df.fieldname)==doc.name:
+ frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
+ doc.name, df.parent, ""), frappe.LinkExistsError)
+ else:
+
+ # dynamic link in table
+ for name in frappe.db.sql_list("""select name from `tab{parent}` where
+ {options}=%s and {fieldname}=%s""".format(**df), (doc.doctype, doc.name)):
+ frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
+ doc.name, df.parent, name), frappe.LinkExistsError)
+
+def delete_linked_todos(doc):
+ delete_doc("ToDo", frappe.db.sql_list("""select name from `tabToDo`
+ where reference_type=%s and reference_name=%s""", (doc.doctype, doc.name)))
diff --git a/frappe/model/document.py b/frappe/model/document.py
index 8ff78e119d..0993c19008 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -32,7 +32,7 @@ _classes = {}
def get_controller(doctype):
if not doctype in _classes:
module = load_doctype_module(doctype)
- classname = doctype.replace(" ", "")
+ classname = doctype.replace(" ", "").replace("-", "")
if hasattr(module, classname):
_class = getattr(module, classname)
if issubclass(_class, Document):
@@ -48,6 +48,7 @@ def get_controller(doctype):
class Document(BaseDocument):
def __init__(self, arg1, arg2=None):
self.doctype = self.name = None
+
if arg1 and isinstance(arg1, basestring):
if not arg2:
# single
@@ -58,7 +59,7 @@ class Document(BaseDocument):
# filter
self.name = frappe.db.get_value(arg1, arg2, "name")
if self.name is None:
- raise frappe.DoesNotExistError, (arg1, arg2)
+ frappe.throw(_("{0} {1} not found").format(_(arg1), arg2), frappe.DoesNotExistError)
else:
self.name = arg2
@@ -72,6 +73,11 @@ class Document(BaseDocument):
# incorrect arguments. let's not proceed.
raise frappe.DataError("Document({0}, {1})".format(arg1, arg2))
+ if hasattr(self, "__setup__"):
+ self.__setup__()
+
+ self.dont_update_if_missing = []
+
def load_from_db(self):
if not getattr(self, "_metaclass", False) and self.meta.issingle:
self.update(frappe.db.get_singles_dict(self.doctype))
@@ -81,7 +87,7 @@ class Document(BaseDocument):
else:
d = frappe.db.get_value(self.doctype, self.name, "*", as_dict=1)
if not d:
- frappe.throw(("{0} {1} not found").format(_(self.doctype), self.name), frappe.DoesNotExistError)
+ frappe.throw(_("{0} {1} not found").format(_(self.doctype), self.name), frappe.DoesNotExistError)
self.update(d)
if self.name=="DocType" and self.doctype=="DocType":
@@ -99,6 +105,10 @@ class Document(BaseDocument):
else:
self.set(df.fieldname, [])
+ def check_permission(self, permtype, permlabel=None):
+ if not self.has_permission(permtype):
+ self.raise_no_permission_to(permlabel or permtype)
+
def has_permission(self, permtype):
if getattr(self, "ignore_permissions", False):
return True
@@ -108,21 +118,26 @@ class Document(BaseDocument):
raise frappe.PermissionError("No permission to {} {} {}".format(perm_type, self.doctype, self.name or ""))
def insert(self, ignore_permissions=None):
+ if getattr(self, "in_print", False):
+ return
+
if ignore_permissions!=None:
self.ignore_permissions = ignore_permissions
self.set("__islocal", True)
- if not self.has_permission("create"):
- self.raise_no_permission_to("create")
+ self.check_permission("create")
self._set_defaults()
self._set_docstatus_user_and_timestamp()
self.check_if_latest()
- set_new_name(self)
+ self.set_new_name()
self.run_method("before_insert")
self.set_parent_in_children()
+
+ self.set("__in_insert", True)
self.run_before_save_methods()
self._validate()
+ self.delete_key("__in_insert")
# run validate, on update etc.
@@ -137,11 +152,16 @@ class Document(BaseDocument):
d.db_insert()
self.run_method("after_insert")
+ self.set("__in_insert", True)
self.run_post_save_methods()
+ self.delete_key("__in_insert")
return self
def save(self, ignore_permissions=None):
+ if getattr(self, "in_print", False):
+ return
+
if ignore_permissions!=None:
self.ignore_permissions = ignore_permissions
@@ -149,14 +169,16 @@ class Document(BaseDocument):
self.insert()
return
- if not self.has_permission("write"):
- self.raise_no_permission_to("save")
+ self.check_permission("write", "save")
self._set_docstatus_user_and_timestamp()
self.check_if_latest()
self.set_parent_in_children()
self.run_before_save_methods()
- self._validate()
+
+ if self._action != "cancel":
+ self._validate()
+
if self._action == "update_after_submit":
self.validate_update_after_submit()
@@ -189,6 +211,12 @@ class Document(BaseDocument):
return self
+ def set_new_name(self):
+ set_new_name(self)
+ # set name for children
+ for d in self.get_all_children():
+ set_new_name(d)
+
def update_single(self, d):
frappe.db.sql("""delete from tabSingles where doctype=%s""", self.doctype)
for field, value in d.iteritems():
@@ -219,8 +247,10 @@ class Document(BaseDocument):
def _validate(self):
self._validate_mandatory()
self._validate_links()
+ self._validate_selects()
self._validate_constants()
for d in self.get_all_children():
+ d._validate_selects()
d._validate_constants()
self._extract_images_from_text_editor()
@@ -278,20 +308,17 @@ class Document(BaseDocument):
self._action = "save"
elif self.docstatus==1:
self._action = "submit"
- if not self.has_permission("submit"):
- self.raise_no_permission_to("submit")
+ self.check_permission("submit")
else:
raise frappe.DocstatusTransitionError("Cannot change docstatus from 0 to 2")
elif docstatus==1:
if self.docstatus==1:
self._action = "update_after_submit"
- if not self.has_permission("submit"):
- self.raise_no_permission_to("submit")
+ self.check_permission("submit")
elif self.docstatus==2:
self._action = "cancel"
- if not self.has_permission("cancel"):
- self.raise_no_permission_to("cancel")
+ self.check_permission("cancel")
else:
raise frappe.DocstatusTransitionError("Cannot change docstatus from 1 to 0")
@@ -333,16 +360,22 @@ class Document(BaseDocument):
if self.get("ignore_links"):
return
- invalid_links = self.get_invalid_links()
+ invalid_links, cancelled_links = self.get_invalid_links()
+
for d in self.get_all_children():
- invalid_links.extend(d.get_invalid_links())
+ result = d.get_invalid_links(is_submittable=self.meta.is_submittable)
+ invalid_links.extend(result[0])
+ cancelled_links.extend(result[1])
- if not invalid_links:
- return
+ if invalid_links:
+ msg = ", ".join((each[2] for each in invalid_links))
+ frappe.throw(_("Could not find {0}").format(msg),
+ frappe.LinkValidationError)
- msg = ", ".join((each[2] for each in invalid_links))
- frappe.throw(_("Could not find {0}").format(msg),
- frappe.LinkValidationError)
+ if cancelled_links:
+ msg = ", ".join((each[2] for each in cancelled_links))
+ frappe.throw(_("Cannot link cancelled document: {0}").format(msg),
+ frappe.CancelledLinkError)
def get_all_children(self, parenttype=None):
ret = []
@@ -363,10 +396,14 @@ class Document(BaseDocument):
def run_method(self, method, *args, **kwargs):
"""run standard triggers, plus those in frappe"""
- if hasattr(self, method):
+ if hasattr(self, method) and hasattr(getattr(self, method), "__call__"):
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
- fn.__name__ = method.encode("utf-8")
- return Document.hook(fn)(self, *args, **kwargs)
+ else:
+ # hack! to run hooks even if method does not exist
+ fn = lambda self, *args, **kwargs: None
+
+ fn.__name__ = method.encode("utf-8")
+ return Document.hook(fn)(self, *args, **kwargs)
def submit(self):
self.docstatus = 1
@@ -376,6 +413,9 @@ class Document(BaseDocument):
self.docstatus = 2
self.save()
+ def delete(self):
+ frappe.delete_doc(self.doctype, self.name)
+
def run_before_save_methods(self):
if getattr(self, "ignore_validate", False):
return
@@ -389,7 +429,6 @@ class Document(BaseDocument):
elif self._action=="cancel":
self.run_method("before_cancel")
elif self._action=="update_after_submit":
- self.run_method("validate")
self.run_method("before_update_after_submit")
def run_post_save_methods(self):
@@ -398,11 +437,19 @@ class Document(BaseDocument):
elif self._action=="submit":
self.run_method("on_update")
self.run_method("on_submit")
+ self.add_comment("Submitted")
elif self._action=="cancel":
self.run_method("on_cancel")
+ self.check_no_back_links_exist()
+ self.add_comment("Cancelled")
elif self._action=="update_after_submit":
self.run_method("on_update_after_submit")
+ def check_no_back_links_exist(self):
+ from frappe.model.delete_doc import check_if_doc_is_linked
+ if not self.get("ignore_links"):
+ check_if_doc_is_linked(self, method="Cancel")
+
@staticmethod
def whitelist(f):
f.whitelisted = True
@@ -464,14 +511,14 @@ class Document(BaseDocument):
val1 = doc.get(fieldname)
- if df.fieldtype in ("Currency", "Float"):
+ if df.fieldtype in ("Currency", "Float", "Percent"):
val1 = flt(val1, self.precision(df.fieldname, doc.parentfield or None))
val2 = flt(val2, self.precision(df.fieldname, doc.parentfield or None))
elif df.fieldtype in ("Int", "Check"):
val1 = cint(val1)
val2 = cint(val2)
elif df.fieldtype in ("Data", "Text", "Small Text", "Long Text",
- "Text Editor", "Select", "Link"):
+ "Text Editor", "Select", "Link", "Dynamic Link"):
val1 = cstr(val1)
val2 = cstr(val2)
@@ -481,7 +528,7 @@ class Document(BaseDocument):
if doc.parentfield:
msg = _("Incorrect value in row {0}: {1} must be {2} {3}".format(doc.idx, label, condition_str, val2))
else:
- msg = _("Incorrect value: {1} must be {2} {3}".format(label, condition_str, val2))
+ msg = _("Incorrect value: {0} must be {1} {2}".format(label, condition_str, val2))
# raise passed exception or True
msgprint(msg, raise_exception=raise_exception or True)
@@ -494,7 +541,7 @@ class Document(BaseDocument):
def round_floats_in(self, doc, fieldnames=None):
if not fieldnames:
fieldnames = (df.fieldname for df in
- doc.meta.get("fields", {"fieldtype": ["in", ["Currency", "Float"]]}))
+ doc.meta.get("fields", {"fieldtype": ["in", ["Currency", "Float", "Percent"]]}))
for fieldname in fieldnames:
doc.set(fieldname, flt(doc.get(fieldname), self.precision(fieldname, doc.parentfield)))
@@ -505,23 +552,35 @@ class Document(BaseDocument):
if parentfield and not isinstance(parentfield, basestring):
parentfield = parentfield.parentfield
+ cache_key = parentfield or "main"
+
if not hasattr(self, "_precision"):
- self._precision = frappe._dict({
- "default": cint(frappe.db.get_default("float_precision")) or 3,
- "options": {}
- })
+ self._precision = frappe._dict()
+
+ if cache_key not in self._precision:
+ self._precision[cache_key] = frappe._dict()
+
+ if fieldname not in self._precision[cache_key]:
+ self._precision[cache_key][fieldname] = None
+
+ doctype = self.meta.get_field(parentfield).options if parentfield else self.doctype
+ df = frappe.get_meta(doctype).get_field(fieldname)
- if self._precision.setdefault(parentfield or "main", {}).get(fieldname) is None:
- meta = frappe.get_meta(self.meta.get_field(parentfield).options if parentfield else self.doctype)
- df = meta.get_field(fieldname)
+ if df.fieldtype in ("Currency", "Float", "Percent"):
+ self._precision[cache_key][fieldname] = get_field_precision(df, self)
- if df.fieldtype == "Currency" and df.options and not self._precision.options.get(df.options):
- self._precision.options[df.options] = get_field_precision(df, self)
+ return self._precision[cache_key][fieldname]
- if df.fieldtype == "Currency":
- self._precision[parentfield or "main"][fieldname] = cint(self._precision.options.get(df.options)) or \
- self._precision.default
- elif df.fieldtype == "Float":
- self._precision[parentfield or "main"][fieldname] = self._precision.default
+ def get_url(self):
+ return "/desk#Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name)
- return self._precision[parentfield or "main"][fieldname]
+ def add_comment(self, comment_type, text=None):
+ comment = frappe.get_doc({
+ "doctype":"Comment",
+ "comment_by": frappe.session.user,
+ "comment_type": comment_type,
+ "comment_doctype": self.doctype,
+ "comment_docname": self.name,
+ "comment": text or comment_type
+ }).insert(ignore_permissions=True)
+ return comment
diff --git a/frappe/model/mapper.py b/frappe/model/mapper.py
index 32992f1de2..13b85b3b4d 100644
--- a/frappe/model/mapper.py
+++ b/frappe/model/mapper.py
@@ -22,7 +22,7 @@ def get_mapped_doc(from_doctype, from_docname, table_maps, target_doc=None,
elif isinstance(target_doc, basestring):
target_doc = frappe.get_doc(json.loads(target_doc))
- if not target_doc.has_permission("create"):
+ if not ignore_permissions and not target_doc.has_permission("create"):
target_doc.raise_no_permission_to("create")
map_doc(source_doc, target_doc, table_maps[source_doc.doctype])
@@ -43,20 +43,18 @@ def get_mapped_doc(from_doctype, from_docname, table_maps, target_doc=None,
target_parentfield = target_doc.get_parentfield_of_doctype(target_child_doctype)
# does row exist for a parentfield?
- if df.fieldname not in row_exists_for_parentfield:
+ if target_parentfield not in row_exists_for_parentfield:
row_exists_for_parentfield[target_parentfield] = (True
if target_doc.get(target_parentfield) else False)
- if table_map.get("add_if_empty") and row_exists_for_parentfield.get(target_parentfield):
+ if table_map.get("add_if_empty") and \
+ row_exists_for_parentfield.get(target_parentfield):
continue
if table_map.get("filter") and table_map.get("filter")(source_d):
continue
- target_d = frappe.new_doc(target_child_doctype, target_doc, target_parentfield)
- map_doc(source_d, target_d, table_map, source_doc)
- target_d.idx = None
- target_doc.append(target_parentfield, target_d)
+ map_child_doc(source_d, target_doc, table_map, source_doc)
if postprocess:
postprocess(source_doc, target_doc)
@@ -64,11 +62,6 @@ def get_mapped_doc(from_doctype, from_docname, table_maps, target_doc=None,
return target_doc
def map_doc(source_doc, target_doc, table_map, source_parent=None):
- no_copy_fields = set([d.fieldname for d in source_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")]
- + [d.fieldname for d in target_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")]
- + default_fields
- + table_map.get("field_no_map", []))
-
if table_map.get("validation"):
for key, condition in table_map["validation"].items():
if condition[0]=="=":
@@ -76,13 +69,33 @@ def map_doc(source_doc, target_doc, table_map, source_parent=None):
frappe.throw(_("Cannot map because following condition fails: ")
+ key + "=" + cstr(condition[1]))
- # map same fields
+ map_fields(source_doc, target_doc, table_map, source_parent)
+
+ if "postprocess" in table_map:
+ table_map["postprocess"](source_doc, target_doc, source_parent)
+
+def map_fields(source_doc, target_doc, table_map, source_parent):
+ no_copy_fields = set([d.fieldname for d in source_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")]
+ + [d.fieldname for d in target_doc.meta.get("fields") if (d.no_copy==1 or d.fieldtype=="Table")]
+ + default_fields
+ + table_map.get("field_no_map", []))
+
for df in target_doc.meta.get("fields"):
if df.fieldname not in no_copy_fields:
+ # map same fields
val = source_doc.get(df.fieldname)
if val not in (None, ""):
target_doc.set(df.fieldname, val)
+ elif df.fieldtype == "Link":
+ if not target_doc.get(df.fieldname):
+ # map link fields having options == source doctype
+ if df.options == source_doc.doctype:
+ target_doc.set(df.fieldname, source_doc.name)
+
+ elif source_parent and df.options == source_parent.doctype:
+ target_doc.set(df.fieldname, source_parent.name)
+
# map other fields
field_map = table_map.get("field_map")
@@ -102,5 +115,35 @@ def map_doc(source_doc, target_doc, table_map, source_parent=None):
if source_doc.idx:
target_doc.idx = source_doc.idx
- if "postprocess" in table_map:
- table_map["postprocess"](source_doc, target_doc, source_parent)
+ # add fetch
+ for df in target_doc.meta.get("fields", {"fieldtype": "Link"}):
+ if target_doc.get(df.fieldname):
+ map_fetch_fields(target_doc, df, no_copy_fields)
+
+def map_fetch_fields(target_doc, df, no_copy_fields):
+ try:
+ linked_doc = frappe.get_doc(df.options, target_doc.get(df.fieldname))
+ except:
+ return
+
+ # options should be like "link_fieldname.fieldname_in_liked_doc"
+ for fetch_df in target_doc.meta.get("fields", {"options": "^{0}.".format(df.fieldname)}):
+ if not (fetch_df.fieldtype == "Read Only" or fetch_df.read_only):
+ continue
+
+ if not target_doc.get(fetch_df.fieldname) and fetch_df.fieldname not in no_copy_fields:
+ source_fieldname = fetch_df.options.split(".")[1]
+ val = linked_doc.get(source_fieldname)
+
+ if val not in (None, ""):
+ target_doc.set(fetch_df.fieldname, val)
+
+def map_child_doc(source_d, target_parent, table_map, source_parent=None):
+ target_child_doctype = table_map["doctype"]
+ target_parentfield = target_parent.get_parentfield_of_doctype(target_child_doctype)
+ target_d = frappe.new_doc(target_child_doctype, target_parent, target_parentfield)
+
+ map_doc(source_d, target_d, table_map, source_parent)
+ target_d.idx = None
+ target_parent.append(target_parentfield, target_d)
+ return target_d
diff --git a/frappe/model/meta.py b/frappe/model/meta.py
index c0e1ac0bca..0a65f5e4c5 100644
--- a/frappe/model/meta.py
+++ b/frappe/model/meta.py
@@ -61,6 +61,10 @@ class Meta(Document):
def get_link_fields(self):
return self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]})
+ def get_select_fields(self):
+ return self.get("fields", {"fieldtype": "Select", "options":["not in",
+ ["[Select]", "Loading...", "attach_files:"]]})
+
def get_table_fields(self):
if not hasattr(self, "_table_fields"):
if self.name!="DocType":
@@ -190,19 +194,26 @@ class Meta(Document):
self.set("fields", newlist)
- def get_restricted_fields(self, restricted_types):
- restricted_fields = self.get("fields", {
+ def get_fields_to_check_permissions(self, user_permission_doctypes):
+ fields = self.get("fields", {
"fieldtype":"Link",
"parent": self.name,
- "ignore_restrictions":("!=", 1),
- "options":("in", restricted_types)
+ "ignore_user_permissions":("!=", 1),
+ "options":("in", user_permission_doctypes)
})
- if self.name in restricted_types:
- restricted_fields.append(frappe._dict({
- "label":"Name", "fieldname":"name", "options": self.name
+
+ if self.name in user_permission_doctypes:
+ fields.append(frappe._dict({
+ "label":"Name",
+ "fieldname":"name",
+ "options": self.name
}))
- return restricted_fields
+ return fields
+
+ def is_print_hide(self, fieldname):
+ df = self.get_field(fieldname)
+ return df.get("__print_hide") or df.print_hide
doctype_table_fields = [
frappe._dict({"fieldname": "fields", "options": "DocField"}),
@@ -230,13 +241,16 @@ def get_field_currency(df, doc):
"""get currency based on DocField options and fieldvalue in doc"""
currency = None
- if ":" in cstr(df.options):
- split_opts = df.options.split(":")
+ if not df.get("options"):
+ return None
+
+ if ":" in cstr(df.get("options")):
+ split_opts = df.get("options").split(":")
if len(split_opts)==3:
currency = frappe.db.get_value(split_opts[0], doc.get(split_opts[1]),
split_opts[2])
else:
- currency = doc.get(df.options)
+ currency = doc.get(df.get("options"))
return currency
@@ -244,19 +258,23 @@ def get_field_precision(df, doc):
"""get precision based on DocField options and fieldvalue in doc"""
from frappe.utils import get_number_format_info
- number_format = None
+ precision = cint(df.precision) or cint(frappe.db.get_default("float_precision")) or 3
+
if df.fieldtype == "Currency":
+ number_format = None
currency = get_field_currency(df, doc)
+
+ if not currency:
+ # use default currency
+ currency = frappe.db.get_default("currency")
+
if currency:
number_format = frappe.db.get_value("Currency", currency, "number_format")
- if not number_format:
- number_format = frappe.db.get_default("number_format") or "#,###.##"
-
- decimal_str, comma_str, precision = get_number_format_info(number_format)
+ if not number_format:
+ number_format = frappe.db.get_default("number_format") or "#,###.##"
- if df.fieldtype == "Float":
- precision = cint(frappe.db.get_default("float_precision")) or 3
+ decimal_str, comma_str, precision = get_number_format_info(number_format)
return precision
diff --git a/frappe/model/naming.py b/frappe/model/naming.py
index 48b551f209..4f1f827758 100644
--- a/frappe/model/naming.py
+++ b/frappe/model/naming.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-
+from frappe import _
from frappe.utils import now_datetime, cint
def set_new_name(doc):
@@ -13,13 +13,11 @@ def set_new_name(doc):
# amendments
if getattr(doc, "amended_from", None):
return _get_amended_name(doc)
- else:
- tmp = getattr(doc, "autoname", None)
- if tmp and not isinstance(tmp, basestring):
- # autoname in a function, not a property
- doc.autoname()
- if doc.name:
- return
+
+ elif hasattr(doc, "run_method"):
+ doc.run_method("autoname")
+ if doc.name:
+ return
autoname = frappe.get_meta(doc.doctype).autoname
@@ -50,11 +48,16 @@ def set_new_name(doc):
# default name for table
elif doc.meta.istable:
- doc.name = make_autoname('#########', doc.doctype)
+ doc.name = make_autoname('hash', doc.doctype)
+
+ elif doc.meta.issingle:
+ doc.name = doc.doctype
# unable to determine a name, use global series
if not doc.name:
- doc.name = make_autoname('#########', doc.doctype)
+ doc.name = make_autoname('hash', doc.doctype)
+
+ doc.name = doc.name.strip()
validate_name(doc.doctype, doc.name)
@@ -120,6 +123,20 @@ def getseries(key, digits, doctype=''):
current = 1
return ('%0'+str(digits)+'d') % current
+def revert_series_if_last(key, name):
+ if ".#" in key:
+ prefix, hashes = key.rsplit(".", 1)
+ if "#" not in hashes:
+ return
+ else:
+ prefix = key
+
+ count = cint(name.replace(prefix, ""))
+ current = frappe.db.sql("select `current` from `tabSeries` where name=%s for update", (prefix,))
+
+ if current and current[0][0]==count:
+ frappe.db.sql("update tabSeries set current=current-1 where name=%s", prefix)
+
def get_default_naming_series(doctype):
"""get default value for `naming_series` property"""
naming_series = frappe.get_meta(doctype).get_field("naming_series").options or ""
@@ -132,10 +149,14 @@ def get_default_naming_series(doctype):
def validate_name(doctype, name, case=None, merge=False):
if not name: return 'No Name Specified for %s' % doctype
if name.startswith('New '+doctype):
- raise frappe.NameError, 'There were some errors setting the name, please contact the administrator'
+ frappe.throw(_('There were some errors setting the name, please contact the administrator'), frappe.NameError)
if case=='Title Case': name = name.title()
if case=='UPPER CASE': name = name.upper()
name = name.strip()
+
+ if not frappe.get_meta(doctype).get("issingle") and doctype == name:
+ frappe.throw(_("Name of {0} cannot be {1}").format(doctype, name), frappe.NameError)
+
return name
def _get_amended_name(doc):
diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py
index 1f4b5fb180..f3d0a961f4 100644
--- a/frappe/model/rename_doc.py
+++ b/frappe/model/rename_doc.py
@@ -22,8 +22,9 @@ def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=F
meta = frappe.get_meta(doctype)
# call before_rename
- out = frappe.get_doc(doctype, old).run_method("before_rename", old, new, merge) or {}
- new = (out.get("new") or new) if isinstance(out, dict) else new
+ old_doc = frappe.get_doc(doctype, old)
+ out = old_doc.run_method("before_rename", old, new, merge) or {}
+ new = (out.get("new") or new) if isinstance(out, dict) else (out or new)
new = validate_rename(doctype, new, meta, merge, force, ignore_permissions)
if not merge:
@@ -33,21 +34,29 @@ def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=F
link_fields = get_link_fields(doctype)
update_link_field_values(link_fields, old, new, doctype)
+ rename_dynamic_links(doctype, old, new)
+
if doctype=='DocType':
rename_doctype(doctype, old, new, force)
+ update_comments(doctype, old, new, force)
update_attachments(doctype, old, new)
if merge:
frappe.delete_doc(doctype, old)
# call after_rename
- frappe.get_doc(doctype, new).run_method("after_rename", old, new, merge)
+ new_doc = frappe.get_doc(doctype, new)
+
+ # copy any flags if required
+ new_doc._local = getattr(old_doc, "_local", None)
+
+ new_doc.run_method("after_rename", old, new, merge)
rename_versions(doctype, old, new)
- # update restrictions
- frappe.db.sql("""update tabDefaultValue set defvalue=%s where parenttype='Restriction'
+ # update user_permissions
+ frappe.db.sql("""update tabDefaultValue set defvalue=%s where parenttype='User Permission'
and defkey=%s and defvalue=%s""", (new, doctype, old))
frappe.clear_cache()
@@ -73,12 +82,12 @@ def rename_parent_and_child(doctype, old, new, meta):
update_child_docs(old, new, meta)
def validate_rename(doctype, new, meta, merge, force, ignore_permissions):
- exists = frappe.db.exists(doctype, new)
+ exists = frappe.db.get_value(doctype, new)
if merge and not exists:
frappe.msgprint(_("{0} {1} does not exist, select a new target to merge").format(doctype, new), raise_exception=1)
- if (not merge) and exists:
+ if (not merge) and exists == new:
frappe.msgprint(_("Another {0} with name {1} exists, select another name").format(doctype, new), raise_exception=1)
if not (ignore_permissions or frappe.has_permission(doctype, "write")):
@@ -94,7 +103,8 @@ def validate_rename(doctype, new, meta, merge, force, ignore_permissions):
def rename_doctype(doctype, old, new, force=False):
# change options for fieldtype Table
- update_parent_of_fieldtype_table(old, new)
+ update_options_for_fieldtype("Table", old, new)
+ update_options_for_fieldtype("Link", old, new)
# change options where select options are hardcoded i.e. listed
select_fields = get_select_fields(old, new)
@@ -108,6 +118,10 @@ def rename_doctype(doctype, old, new, force=False):
frappe.db.sql("""update tabComment set comment_doctype=%s where comment_doctype=%s""",
(new, old))
+def update_comments(doctype, old, new, force=False):
+ frappe.db.sql("""update `tabComment` set comment_docname=%s
+ where comment_doctype=%s and comment_docname=%s""", (new, doctype, old))
+
def update_child_docs(old, new, meta):
# update "parent"
for df in meta.get_table_fields():
@@ -167,17 +181,14 @@ def get_link_fields(doctype):
return link_fields
-def update_parent_of_fieldtype_table(old, new):
- frappe.db.sql("""\
- update `tabDocField` set options=%s
- where fieldtype='Table' and options=%s""", (new, old))
+def update_options_for_fieldtype(fieldtype, old, new):
+ frappe.db.sql("""update `tabDocField` set options=%s
+ where fieldtype=%s and options=%s""", (new, fieldtype, old))
- frappe.db.sql("""\
- update `tabCustom Field` set options=%s
- where fieldtype='Table' and options=%s""", (new, old))
+ frappe.db.sql("""update `tabCustom Field` set options=%s
+ where fieldtype=%s and options=%s""", (new, fieldtype, old))
- frappe.db.sql("""\
- update `tabProperty Setter` set value=%s
+ frappe.db.sql("""update `tabProperty Setter` set value=%s
where property='options' and value=%s""", (new, old))
def get_select_fields(old, new):
@@ -276,3 +287,27 @@ def update_parenttype_values(old, new):
update `tab%s` set parenttype=%s
where parenttype=%s""" % (doctype, '%s', '%s'),
(new, old))
+
+dynamic_link_queries = [
+ """select parent, fieldname, options from tabDocField where fieldtype='Dynamic Link'""",
+ """select dt as parent, fieldname, options from `tabCustom Field` where fieldtype='Dynamic Link'""",
+]
+
+def rename_dynamic_links(doctype, old, new):
+ for query in dynamic_link_queries:
+ for df in frappe.db.sql(query, as_dict=True):
+
+ # dynamic link in single, just one value to check
+ if frappe.get_meta(df.parent).issingle:
+ refdoc = frappe.get_singles_dict(df.parent)
+ if refdoc.get(df.options)==doctype and refdoc.get(df.fieldname)==old:
+
+ frappe.db.sql("""update tabSingles set value=%s where
+ field=%s and value=%s and doctype=%s""", (new, df.fieldname, old, df.parent))
+ else:
+ # replace for each value where renamed
+ for to_change in frappe.db.sql_list("""select name from `tab{parent}` where
+ {options}=%s and {fieldname}=%s""".format(**df), (doctype, old)):
+
+ frappe.db.sql("""update `tab{parent}` set {fieldname}=%s
+ where name=%s""".format(**df), (new, to_change))
diff --git a/frappe/model/sync.py b/frappe/model/sync.py
index 0c285f423a..a3d411797b 100644
--- a/frappe/model/sync.py
+++ b/frappe/model/sync.py
@@ -9,48 +9,55 @@ from __future__ import unicode_literals
import frappe
import os, sys
from frappe.modules.import_file import import_file_by_path
-from frappe.utils import get_path, cstr
+from frappe.modules.patch_handler import block_user
+from frappe.utils import update_progress_bar
def sync_all(force=0, verbose=False):
+ block_user(True)
+
for app in frappe.get_installed_apps():
sync_for(app, force, verbose=verbose)
+
+ block_user(False)
+
frappe.clear_cache()
def sync_for(app_name, force=0, sync_everything = False, verbose=False):
+ files = []
for module_name in frappe.local.app_modules.get(app_name) or []:
folder = os.path.dirname(frappe.get_module(app_name + "." + module_name).__file__)
- walk_and_sync(folder, force, sync_everything, verbose=verbose)
-
-def walk_and_sync(start_path, force=0, sync_everything = False, verbose=False):
- """walk and sync all doctypes and pages"""
+ files += get_doc_files(folder, force, sync_everything, verbose=verbose)
- modules = []
+ l = len(files)
+ if l:
+ for i, doc_path in enumerate(files):
+ import_file_by_path(doc_path, force=force)
+ #print module_name + ' | ' + doctype + ' | ' + name
- document_type = ['doctype', 'page', 'report', 'print_format']
+ frappe.db.commit()
- for path, folders, files in os.walk(start_path):
- # sort folders so that doctypes are synced before pages or reports
+ # show progress bar
+ update_progress_bar("Updating {0}".format(app_name), i, l)
- for dontwalk in (".git", "locale", "public"):
- if dontwalk in folders:
- folders.remove(dontwalk)
+ print ""
- folders.sort()
- if sync_everything or (os.path.basename(os.path.dirname(path)) in document_type):
- for f in files:
- f = cstr(f)
- if f.endswith(".json"):
- doc_name = f.split(".json")[0]
- if doc_name == os.path.basename(path):
+def get_doc_files(start_path, force=0, sync_everything = False, verbose=False):
+ """walk and sync all doctypes and pages"""
- module_name = path.split(os.sep)[-3]
- doctype = path.split(os.sep)[-2]
- name = path.split(os.sep)[-1]
+ out = []
+ document_type = ['doctype', 'page', 'report', 'print_format']
+ for doctype in document_type:
+ doctype_path = os.path.join(start_path, doctype)
+ if os.path.exists(doctype_path):
- if import_file_by_path(os.path.join(path, f), force=force) and verbose:
- print module_name + ' | ' + doctype + ' | ' + name
+ # Note: sorted is a hack because custom* and doc* need
+ # be synced first
- frappe.db.commit()
+ for docname in sorted(os.listdir(doctype_path)):
+ if os.path.isdir(os.path.join(doctype_path, docname)):
+ doc_path = os.path.join(doctype_path, docname, docname) + ".json"
+ if os.path.exists(doc_path):
+ out.append(doc_path)
- return modules
+ return out
diff --git a/frappe/modules.txt b/frappe/modules.txt
index 2287e7c2d4..8fe4b686dd 100644
--- a/frappe/modules.txt
+++ b/frappe/modules.txt
@@ -1,2 +1,2 @@
-core
-website
\ No newline at end of file
+Core
+Website
diff --git a/frappe/modules/__init__.py b/frappe/modules/__init__.py
index 9f8890c482..8ee6446001 100644
--- a/frappe/modules/__init__.py
+++ b/frappe/modules/__init__.py
@@ -7,6 +7,7 @@ from __future__ import unicode_literals
"""
import frappe, os
import frappe.utils
+from frappe import _
lower_case_files_for = ['DocType', 'Page', 'Report',
"Workflow", 'Module Def', 'Desktop Item', 'Workflow State', 'Workflow Action', 'Print Format']
@@ -44,13 +45,50 @@ def export_doc(doctype, name, module=None):
def get_doctype_module(doctype):
return frappe.db.get_value('DocType', doctype, 'module') or "core"
+doctype_python_modules = {}
def load_doctype_module(doctype, module=None, prefix=""):
if not module:
module = get_doctype_module(doctype)
- return frappe.get_module(get_module_name(doctype, module, prefix))
-def get_module_name(doctype, module, prefix=""):
- from frappe.modules import scrub
+ app = get_module_app(module)
+
+ key = (app, doctype, prefix)
+
+ if key not in doctype_python_modules:
+ doctype_python_modules[key] = frappe.get_module(get_module_name(doctype, module, prefix))
+
+ return doctype_python_modules[key]
+
+def get_module_name(doctype, module, prefix="", app=None):
return '{app}.{module}.doctype.{doctype}.{prefix}{doctype}'.format(\
- app = scrub(frappe.local.module_app[scrub(module)]),
- module = scrub(module), doctype = scrub(doctype), prefix=prefix)
+ app = scrub(app or get_module_app(module)),
+ module = scrub(module),
+ doctype = scrub(doctype),
+ prefix=prefix)
+
+def get_module_app(module):
+ return frappe.local.module_app[scrub(module)]
+
+def get_app_publisher(module):
+ app = frappe.local.module_app[scrub(module)]
+ if not app:
+ frappe.throw(_("App not found"))
+ app_publisher = frappe.get_hooks(hook="app_publisher", app_name=app)[0]
+ return app_publisher
+
+def make_boilerplate(template, doc, opts=None):
+ target_path = get_doc_path(doc.module, doc.doctype, doc.name)
+ template_name = template.replace("controller", scrub(doc.name))
+ target_file_path = os.path.join(target_path, template_name)
+
+ app_publisher = get_app_publisher(doc.module)
+
+ if not os.path.exists(target_file_path):
+ if not opts:
+ opts = {}
+
+ with open(target_file_path, 'w') as target:
+ with open(os.path.join(get_module_path("core"), "doctype", scrub(doc.doctype),
+ "boilerplate", template), 'r') as source:
+ target.write(source.read().format(app_publisher=app_publisher,
+ classname=doc.name.replace(" ", ""), doctype=doc.name, **opts))
diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py
index 87db8652aa..bb78544508 100644
--- a/frappe/modules/import_file.py
+++ b/frappe/modules/import_file.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe, os, json
-from frappe.modules import scrub, get_module_path, scrub_dt_dn
+from frappe.modules import get_module_path, scrub_dt_dn
from frappe.utils import get_datetime_str
def import_files(module, dt=None, dn=None, force=False):
@@ -74,6 +74,7 @@ def read_doc_from_file(path):
ignore_values = {
"Report": ["disabled"],
+ "Print Format": ["disabled"]
}
ignore_doctypes = ["Page Role", "DocPerm"]
@@ -106,5 +107,5 @@ def import_doc(docdict, force=False):
doc.ignore_validate = True
doc.ignore_permissions = True
doc.ignore_mandatory = True
- doc.ignore_restrictions = True
+ doc.ignore_user_permissions = True
doc.insert()
diff --git a/frappe/modules/patch_handler.py b/frappe/modules/patch_handler.py
index e7dbd01ff5..1a86cfebbf 100644
--- a/frappe/modules/patch_handler.py
+++ b/frappe/modules/patch_handler.py
@@ -53,9 +53,9 @@ def run_single(patchmodule=None, method=None, methodargs=None, force=False):
def execute_patch(patchmodule, method=None, methodargs=None):
"""execute the patch"""
- success = False
block_user(True)
frappe.db.begin()
+
try:
log('Executing {patch} in {site} ({db})'.format(patch=patchmodule or str(methodargs),
site=frappe.local.site, db=frappe.db.cur_db_name))
@@ -63,22 +63,21 @@ def execute_patch(patchmodule, method=None, methodargs=None):
if patchmodule.startswith("execute:"):
exec patchmodule.split("execute:")[1] in globals()
else:
- frappe.get_attr(patchmodule + ".execute")()
+ frappe.get_attr(patchmodule.split()[0] + ".execute")()
update_patch_log(patchmodule)
elif method:
method(**methodargs)
- frappe.db.commit()
- success = True
- except Exception, e:
+ except Exception:
frappe.db.rollback()
- tb = frappe.get_traceback()
- log(tb)
+ raise
- block_user(False)
- if success:
+ else:
+ frappe.db.commit()
+ block_user(False)
log('Success')
- return success
+
+ return True
def update_patch_log(patchmodule):
"""update patch_file in patch log"""
diff --git a/frappe/patches.txt b/frappe/patches.txt
index 3c8dbd23bd..6e8c2fa47e 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -1,32 +1,56 @@
-execute:import inlinestyler # new requirement
-
execute:frappe.db.sql("""update `tabPatch Log` set patch=replace(patch, '.4_0.', '.v4_0.')""") #2014-05-12
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2014-01-24
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2014-03-01
-execute:frappe.reload_doc('core', 'doctype', 'docperm') #2013-13-26
+execute:frappe.reload_doc('core', 'doctype', 'docperm') #2014-06-04
execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26
-execute:frappe.reload_doc('core', 'doctype', 'report') #2013-13-26
+execute:frappe.reload_doc('core', 'doctype', 'report') #2014-06-03
execute:frappe.reload_doc('core', 'doctype', 'version') #2014-02-21
+execute:frappe.reload_doc('core', 'doctype', 'email_alert') #2014-07-15
execute:frappe.db.sql("alter table `tabSessions` modify `user` varchar(255), engine=InnoDB")
+execute:frappe.db.sql("delete from `tabDocField` where parent='0'")
+frappe.patches.v4_0.change_varchar_length
-frappe.patches.v4_0.remove_old_parent
-frappe.patches.v4_0.remove_index_sitemap
-frappe.patches.v4_0.add_delete_permission
-frappe.patches.v4_0.move_match_to_restricted
-frappe.patches.v4_0.set_todo_checked_as_closed
-frappe.patches.v4_0.website_sitemap_hierarchy
frappe.patches.v4_0.webnotes_to_frappe
execute:frappe.reset_perms("Module Def")
-frappe.patches.v4_0.rename_sitemap_to_route
+execute:import frappe.installer;frappe.installer.make_site_dirs() #2014-02-19
frappe.patches.v4_0.rename_profile_to_user
+frappe.patches.v4_0.deprecate_control_panel
+frappe.patches.v4_0.remove_old_parent
+frappe.patches.v4_0.rename_sitemap_to_route
+frappe.patches.v4_0.website_sitemap_hierarchy
+frappe.patches.v4_0.remove_index_sitemap
frappe.patches.v4_0.set_website_route_idx
-execute:import frappe.installer;frappe.installer.make_site_dirs() #2014-02-19
+frappe.patches.v4_0.add_delete_permission
+frappe.patches.v4_0.set_todo_checked_as_closed
frappe.patches.v4_0.private_backups
frappe.patches.v4_0.set_module_in_report
frappe.patches.v4_0.update_datetime
-frappe.patches.v4_0.deprecate_control_panel
frappe.patches.v4_0.file_manager_hooks
execute:frappe.get_doc("User", "Guest").save()
+frappe.patches.v4_0.update_custom_field_insert_after
frappe.patches.v4_0.deprecate_link_selects
frappe.patches.v4_0.set_user_gravatar
-frappe.patches.v4_0.update_custom_field_insert_after
+frappe.patches.v4_0.set_user_permissions
+frappe.patches.v4_0.create_custom_field_for_owner_match
+frappe.patches.v4_0.enable_scheduler_in_system_settings
+execute:frappe.db.sql("update tabReport set apply_user_permissions=1") #2014-06-03
+frappe.patches.v4_0.replace_deprecated_timezones
+execute:import frappe.website.render; frappe.website.render.clear_cache("login"); #2014-06-10
+frappe.patches.v4_0.fix_attach_field_file_url
+execute:frappe.reset_perms("User") #2014-06-13
+execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')='' or ifnull(`role`, '')=''""") #2014-08-18
+frappe.patches.v4_0.remove_user_owner_custom_field
+execute:frappe.delete_doc("DocType", "Website Template")
+execute:frappe.db.sql("""update `tabProperty Setter` set property_type='Text' where property in ('options', 'default')""") #2014-06-20
+frappe.patches.v4_1.enable_outgoing_email_settings
+execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04
+frappe.patches.v4_1.enable_print_as_pdf #2014-06-17
+execute:frappe.db.sql("""update `tabDocPerm` set email=1 where parent='User' and permlevel=0 and `role`='All' and `read`=1 and apply_user_permissions=1""") #2014-07-15
+execute:frappe.db.sql("""update `tabPrint Format` set print_format_type='Client' where ifnull(print_format_type, '')=''""") #2014-07-28
+frappe.patches.v4_1.file_manager_fix
+frappe.patches.v4_2.print_with_letterhead
+execute:frappe.delete_doc("DocType", "Control Panel", force=1)
+execute:frappe.reload_doc('website', 'doctype', 'web_form') #2014-09-04
+execute:frappe.reload_doc('website', 'doctype', 'web_form_field') #2014-09-04
+frappe.patches.v4_2.refactor_website_routing
+frappe.patches.v4_2.set_assign_in_doc
diff --git a/frappe/patches/v4_0/change_varchar_length.py b/frappe/patches/v4_0/change_varchar_length.py
new file mode 100644
index 0000000000..d9da8221e9
--- /dev/null
+++ b/frappe/patches/v4_0/change_varchar_length.py
@@ -0,0 +1,23 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ for dt in frappe.db.sql_list("""select name from `tabDocType` where ifnull(issingle, 0)=0"""):
+ desc = dict((d["Field"], d) for d in frappe.db.sql("desc `tab{}`".format(dt), as_dict=True))
+ alter_table = []
+
+ if desc["name"]["Type"] != "varchar(255)":
+ alter_table.append("change `name` `name` varchar(255) not null")
+
+ for fieldname in ("modified_by", "owner", "parent", "parentfield", "parenttype"):
+ if desc[fieldname]["Type"] != "varchar(255)":
+ alter_table.append("change `{fieldname}` `{fieldname}` varchar(255)".format(fieldname=fieldname))
+
+ if alter_table:
+ alter_table_query = "alter table `tab{doctype}` {alter_table}".format(doctype=dt, alter_table=",\n".join(alter_table))
+ # print alter_table_query
+ frappe.db.sql_ddl(alter_table_query)
+
diff --git a/frappe/patches/v4_0/create_custom_field_for_owner_match.py b/frappe/patches/v4_0/create_custom_field_for_owner_match.py
new file mode 100644
index 0000000000..2ac51c18ef
--- /dev/null
+++ b/frappe/patches/v4_0/create_custom_field_for_owner_match.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.core.doctype.custom_field.custom_field import create_custom_field
+
+def execute():
+ if "match" in frappe.db.get_table_columns("DocPerm"):
+ create_custom_field_for_owner_match()
+
+def create_custom_field_for_owner_match():
+ frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1 where `match`='owner'""")
+
+ for dt in frappe.db.sql_list("""select distinct parent from `tabDocPerm`
+ where `match`='owner' and permlevel=0 and parent != 'User'"""):
+
+ # a link field pointing to User already exists
+ if (frappe.db.get_value("DocField", {"parent": dt, "fieldtype": "Link", "options": "User", "default": "__user"})
+ or frappe.db.get_value("Custom Field", {"dt": dt, "fieldtype": "Link", "options": "User", "default": "__user"})):
+ print "User link field already exists for", dt
+ continue
+
+ fieldname = "{}_owner".format(frappe.scrub(dt))
+
+ create_custom_field(dt, frappe._dict({
+ "permlevel": 0,
+ "label": "{} Owner".format(dt),
+ "fieldname": fieldname,
+ "fieldtype": "Link",
+ "options": "User",
+ "default": "__user"
+ }))
+
+ frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=owner""".format(doctype=dt,
+ fieldname=fieldname))
+
+ # commit is required so that we don't lose these changes because of an error in next loop's ddl
+ frappe.db.commit()
diff --git a/frappe/patches/v4_0/enable_scheduler_in_system_settings.py b/frappe/patches/v4_0/enable_scheduler_in_system_settings.py
new file mode 100644
index 0000000000..bc2f167ece
--- /dev/null
+++ b/frappe/patches/v4_0/enable_scheduler_in_system_settings.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils.scheduler import disable_scheduler, enable_scheduler
+from frappe.utils import cint
+
+def execute():
+ frappe.reload_doc("core", "doctype", "system_settings")
+ if cint(frappe.db.get_global("disable_scheduler")):
+ disable_scheduler()
+ else:
+ enable_scheduler()
diff --git a/frappe/patches/v4_0/fix_attach_field_file_url.py b/frappe/patches/v4_0/fix_attach_field_file_url.py
new file mode 100644
index 0000000000..3c5a6aa03c
--- /dev/null
+++ b/frappe/patches/v4_0/fix_attach_field_file_url.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ attach_fields = (frappe.db.sql("""select parent, fieldname from `tabDocField` where fieldtype='Attach'""") +
+ frappe.db.sql("""select dt, fieldname from `tabCustom Field` where fieldtype='Attach'"""))
+
+ for doctype, fieldname in attach_fields:
+ frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=concat("/", `{fieldname}`)
+ where `{fieldname}` like 'files/%'""".format(doctype=doctype, fieldname=fieldname))
diff --git a/frappe/patches/v4_0/remove_index_sitemap.py b/frappe/patches/v4_0/remove_index_sitemap.py
index 7f5124813c..00d37eaf2e 100644
--- a/frappe/patches/v4_0/remove_index_sitemap.py
+++ b/frappe/patches/v4_0/remove_index_sitemap.py
@@ -1,6 +1,4 @@
import frappe
def execute():
- if frappe.db.exists("Website Route", "index"):
- frappe.delete_doc("Website Route", "index", ignore_permissions=True)
-
\ No newline at end of file
+ pass
diff --git a/frappe/patches/v4_0/move_match_to_restricted.py b/frappe/patches/v4_0/remove_user_owner_custom_field.py
similarity index 54%
rename from frappe/patches/v4_0/move_match_to_restricted.py
rename to frappe/patches/v4_0/remove_user_owner_custom_field.py
index e21b12c034..4f3e478f98 100644
--- a/frappe/patches/v4_0/move_match_to_restricted.py
+++ b/frappe/patches/v4_0/remove_user_owner_custom_field.py
@@ -5,5 +5,6 @@ from __future__ import unicode_literals
import frappe
def execute():
- frappe.reload_doc("core", "doctype", "docperm")
- frappe.db.sql("""update `tabDocPerm` set restricted=1 where `match`='owner'""")
\ No newline at end of file
+ user_owner = frappe.db.get_value("Custom Field", {"fieldname": "user_owner"})
+ if user_owner:
+ frappe.delete_doc("Custom Field", user_owner)
diff --git a/frappe/patches/v4_0/rename_profile_to_user.py b/frappe/patches/v4_0/rename_profile_to_user.py
index 66b8752da6..bcb910b80a 100644
--- a/frappe/patches/v4_0/rename_profile_to_user.py
+++ b/frappe/patches/v4_0/rename_profile_to_user.py
@@ -13,4 +13,6 @@ def execute():
if "profile" in get_table_columns("Website Route Permission"):
rename_field("Website Route Permission", "profile", "user")
frappe.reload_doc("website", "doctype", "blogger")
- rename_field("Blogger", "profile", "user")
+
+ if "profile" in get_table_columns("Blogger"):
+ rename_field("Blogger", "profile", "user")
diff --git a/frappe/patches/v4_0/rename_sitemap_to_route.py b/frappe/patches/v4_0/rename_sitemap_to_route.py
index 823d5d4b2e..991edf1f7c 100644
--- a/frappe/patches/v4_0/rename_sitemap_to_route.py
+++ b/frappe/patches/v4_0/rename_sitemap_to_route.py
@@ -4,25 +4,28 @@ from frappe.model import rename_field
def execute():
tables = frappe.db.sql_list("show tables")
- if "tabWebsite Route" not in tables:
- frappe.rename_doc("DocType", "Website Sitemap", "Website Route", force=True)
-
- if "tabWebsite Template" not in tables:
- frappe.rename_doc("DocType", "Website Sitemap Config", "Website Template", force=True)
-
- try:
- if "tabWebsite Route Permission" not in tables:
- frappe.rename_doc("DocType", "Website Sitemap Permission", "Website Route Permission", force=True)
-
- for d in ("Blog Category", "Blog Post", "Web Page", "Website Route", "Website Group"):
- frappe.reload_doc("website", "doctype", frappe.scrub(d))
- rename_field(d, "parent_website_sitemap", "parent_website_route")
-
- rename_field("Website Route", "website_sitemap_config", "website_template")
- rename_field("Website Route Permission", "website_sitemap", "website_route")
+ for doctype in ("Website Sitemap", "Website Sitemap Config"):
+ if "tab{}".format(doctype) in tables:
+ frappe.delete_doc("DocType", doctype, force=1)
+ frappe.db.sql("drop table `tab{}`".format(doctype))
+
+ if "tabWebsite Route Permission" not in tables:
+ frappe.rename_doc("DocType", "Website Sitemap Permission", "Website Route Permission", force=True)
+
+ for d in ("Blog Category", "Blog Post", "Web Page", "Website Group"):
+ frappe.reload_doc("website", "doctype", frappe.scrub(d))
+ rename_field_if_exists(d, "parent_website_sitemap", "parent_website_route")
+
+ frappe.reload_doc("website", "doctype", "website_route_permission")
+
+ rename_field_if_exists("Website Route Permission", "website_sitemap", "website_route")
+
+ for d in ("blog_category", "blog_post", "web_page", "website_group", "post", "user_vote"):
+ frappe.reload_doc("website", "doctype", d)
+
+def rename_field_if_exists(doctype, old_fieldname, new_fieldname):
+ try:
+ rename_field(doctype, old_fieldname, new_fieldname)
except Exception, e:
if e.args[0] != 1054:
raise
-
- for d in ("blog_category", "blog_post", "web_page", "website_route", "website_group"):
- frappe.reload_doc("website", "doctype", d)
diff --git a/frappe/patches/v4_0/replace_deprecated_timezones.py b/frappe/patches/v4_0/replace_deprecated_timezones.py
new file mode 100644
index 0000000000..4574dc19f8
--- /dev/null
+++ b/frappe/patches/v4_0/replace_deprecated_timezones.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils.momentjs import data as momentjs_data
+
+def execute():
+ frappe.reload_doc("core", "doctype", "user")
+
+ ss = frappe.get_doc("System Settings", "System Settings")
+ if ss.time_zone in momentjs_data.get("links"):
+ ss.time_zone = momentjs_data["links"][ss.time_zone]
+ ss.ignore_mandatory = True
+ ss.save()
+
+ for user, time_zone in frappe.db.sql("select name, time_zone from `tabUser` where ifnull(time_zone, '')!=''"):
+ if time_zone in momentjs_data.get("links"):
+ user = frappe.get_doc("User", user)
+ user.time_zone = momentjs_data["links"][user.time_zone]
+ user.save()
diff --git a/frappe/patches/v4_0/set_user_permissions.py b/frappe/patches/v4_0/set_user_permissions.py
new file mode 100644
index 0000000000..b25f68c09c
--- /dev/null
+++ b/frappe/patches/v4_0/set_user_permissions.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+import frappe.permissions
+
+def execute():
+ frappe.reload_doc("core", "doctype", "docperm")
+ table_columns = frappe.db.get_table_columns("DocPerm")
+
+ if "restricted" in table_columns:
+ frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1 where ifnull(apply_user_permissions, 0)=0
+ and restricted=1""")
+
+ if "match" in table_columns:
+ frappe.db.sql("""update `tabDocPerm` set apply_user_permissions=1
+ where ifnull(apply_user_permissions, 0)=0 and ifnull(`match`, '')!=''""")
+
+ # change Restriction to User Permission in tabDefaultValue
+ frappe.db.sql("""update `tabDefaultValue` set parenttype='User Permission' where parenttype='Restriction'""")
+
+ frappe.clear_cache()
+
diff --git a/frappe/patches/v4_0/set_website_route_idx.py b/frappe/patches/v4_0/set_website_route_idx.py
index eb5fc1ebd6..82f64756a4 100644
--- a/frappe/patches/v4_0/set_website_route_idx.py
+++ b/frappe/patches/v4_0/set_website_route_idx.py
@@ -1,23 +1,24 @@
import frappe
def execute():
- from frappe.website.doctype.website_template.website_template import \
- get_pages_and_generators, get_template_controller
-
- frappe.reload_doc("website", "doctype", "website_template")
- frappe.reload_doc("website", "doctype", "website_route")
-
- for app in frappe.get_installed_apps():
- pages, generators = get_pages_and_generators(app)
- for g in generators:
- doctype = frappe.get_attr(get_template_controller(app, g["path"], g["fname"]) + ".doctype")
- module = frappe.db.get_value("DocType", doctype, "module")
- frappe.reload_doc(frappe.scrub(module), "doctype", frappe.scrub(doctype))
-
- frappe.db.sql("""update `tabBlog Category` set `title`=`name` where ifnull(`title`, '')=''""")
- frappe.db.sql("""update `tabWebsite Route` set idx=null""")
- for doctype in ["Blog Category", "Blog Post", "Web Page", "Website Group"]:
- frappe.db.sql("""update `tab{}` set idx=null""".format(doctype))
-
- from frappe.website.doctype.website_template.website_template import rebuild_website_template
- rebuild_website_template()
\ No newline at end of file
+ pass
+ # from frappe.website.doctype.website_template.website_template import \
+ # get_pages_and_generators, get_template_controller
+ #
+ # frappe.reload_doc("website", "doctype", "website_template")
+ # frappe.reload_doc("website", "doctype", "website_route")
+ #
+ # for app in frappe.get_installed_apps():
+ # pages, generators = get_pages_and_generators(app)
+ # for g in generators:
+ # doctype = frappe.get_attr(get_template_controller(app, g["path"], g["fname"]) + ".doctype")
+ # module = frappe.db.get_value("DocType", doctype, "module")
+ # frappe.reload_doc(frappe.scrub(module), "doctype", frappe.scrub(doctype))
+ #
+ # frappe.db.sql("""update `tabBlog Category` set `title`=`name` where ifnull(`title`, '')=''""")
+ # frappe.db.sql("""update `tabWebsite Route` set idx=null""")
+ # for doctype in ["Blog Category", "Blog Post", "Web Page", "Website Group"]:
+ # frappe.db.sql("""update `tab{}` set idx=null""".format(doctype))
+ #
+ # from frappe.website.doctype.website_template.website_template import rebuild_website_template
+ # rebuild_website_template()
diff --git a/frappe/patches/v4_0/webnotes_to_frappe.py b/frappe/patches/v4_0/webnotes_to_frappe.py
index 0fa8bdf1dc..c70b2fdbde 100644
--- a/frappe/patches/v4_0/webnotes_to_frappe.py
+++ b/frappe/patches/v4_0/webnotes_to_frappe.py
@@ -1,10 +1,11 @@
import frappe, json
def execute():
+ frappe.clear_cache()
installed = frappe.get_installed_apps()
if "webnotes" in installed:
installed.remove("webnotes")
if "frappe" not in installed:
installed = ["frappe"] + installed
frappe.db.set_global("installed_apps", json.dumps(installed))
- frappe.clear_cache()
\ No newline at end of file
+ frappe.clear_cache()
diff --git a/frappe/patches/v4_0/website_sitemap_hierarchy.py b/frappe/patches/v4_0/website_sitemap_hierarchy.py
index 90fead9502..324b13ea4a 100644
--- a/frappe/patches/v4_0/website_sitemap_hierarchy.py
+++ b/frappe/patches/v4_0/website_sitemap_hierarchy.py
@@ -6,19 +6,16 @@ from __future__ import unicode_literals
import frappe
def execute():
- frappe.reload_doc("website", "doctype", "website_template")
- frappe.reload_doc("website", "doctype", "website_route")
- frappe.reload_doc("website", "doctype", "website_route_permission")
- frappe.reload_doc("website", "doctype", "website_group")
- frappe.reload_doc("website", "doctype", "post")
- frappe.reload_doc("website", "doctype", "user_vote")
-
- frappe.db.sql("""update `tabWebsite Route` ws set ref_doctype=(select wsc.ref_doctype
- from `tabWebsite Template` wsc where wsc.name=ws.website_template)
- where ifnull(page_or_generator, '')!='Page'""")
-
+ # frappe.db.sql("""update `tabWebsite Route` ws set ref_doctype=(select wsc.ref_doctype
+ # from `tabWebsite Template` wsc where wsc.name=ws.website_template)
+ # where ifnull(page_or_generator, '')!='Page'""")
+
frappe.reload_doc("website", "doctype", "website_settings")
- home_page = frappe.db.get_value("Website Settings", "Website Settings", "home_page")
- home_page = frappe.db.get_value("Website Route", {"docname": home_page}) or home_page
- frappe.db.set_value("Website Settings", "Website Settings", "home_page",
- home_page)
+
+ # original_home_page = frappe.db.get_value("Website Settings", "Website Settings", "home_page")
+ #
+ # home_page = frappe.db.sql("""select name from `tabWebsite Route`
+ # where (name=%s or docname=%s) and name!='index'""", (original_home_page, original_home_page))
+ # home_page = home_page[0][0] if home_page else original_home_page
+ #
+ # frappe.db.set_value("Website Settings", "Website Settings", "home_page", home_page)
diff --git a/frappe/patches/v4_1/__init__.py b/frappe/patches/v4_1/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/patches/v4_1/enable_outgoing_email_settings.py b/frappe/patches/v4_1/enable_outgoing_email_settings.py
new file mode 100644
index 0000000000..472a8109e3
--- /dev/null
+++ b/frappe/patches/v4_1/enable_outgoing_email_settings.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doc("core", "doctype", "outgoing_email_settings")
+ if (frappe.db.get_value("Outgoing Email Settings", "Outgoing Email Settings", "mail_server") or "").strip():
+ frappe.db.set_value("Outgoing Email Settings", "Outgoing Email Settings", "enabled", 1)
diff --git a/frappe/patches/v4_1/enable_print_as_pdf.py b/frappe/patches/v4_1/enable_print_as_pdf.py
new file mode 100644
index 0000000000..877a2b61f7
--- /dev/null
+++ b/frappe/patches/v4_1/enable_print_as_pdf.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doc("core", "doctype", "print_settings")
+ print_settings = frappe.get_doc("Print Settings")
+ print_settings.print_style = "Modern"
+
+ try:
+ import pdfkit
+ except ImportError:
+ pass
+ else:
+ # if someone has already configured in Outgoing Email Settings
+ outgoing_email_settings = frappe.db.get_singles_dict("Outgoing Email Settings")
+ if "send_print_as_pdf" in outgoing_email_settings:
+ print_settings.send_print_as_pdf = outgoing_email_settings.send_print_as_pdf
+ print_settings.pdf_page_size = outgoing_email_settings.pdf_page_size
+
+ else:
+ print_settings.send_print_as_pdf = 1
+
+ print_settings.save()
diff --git a/frappe/patches/v4_1/file_manager_fix.py b/frappe/patches/v4_1/file_manager_fix.py
new file mode 100644
index 0000000000..5315284109
--- /dev/null
+++ b/frappe/patches/v4_1/file_manager_fix.py
@@ -0,0 +1,98 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+
+import frappe
+import os
+from frappe.utils.file_manager import get_content_hash, get_file, get_file_name
+from frappe.utils import get_files_path, get_site_path
+
+# The files missed by the previous patch might have been replaced with new files
+# with the same filename
+#
+# This patch does the following,
+# * Detect which files were replaced and rename them with name{hash:5}.extn and
+# update filedata record for the new file
+#
+# * make missing_files.txt in site dir with files that should be recovered from
+# a backup from a time before version 3 migration
+#
+# * Patch remaining unpatched file data records.
+
+def execute():
+ frappe.db.auto_commit_on_many_writes = True
+ rename_replacing_files()
+ for name, file_name, file_url in frappe.db.sql(
+ """select name, file_name, file_url from `tabFile Data`
+ where ifnull(file_name, '')!='' and ifnull(content_hash, '')=''"""):
+ b = frappe.get_doc('File Data', name)
+ old_file_name = b.file_name
+ b.file_name = os.path.basename(old_file_name)
+ if old_file_name.startswith('files/') or old_file_name.startswith('/files/'):
+ b.file_url = os.path.normpath('/' + old_file_name)
+ else:
+ b.file_url = os.path.normpath('/files/' + old_file_name)
+ try:
+ _file_name, content = get_file(name)
+ b.content_hash = get_content_hash(content)
+ except IOError:
+ print 'Warning: Error processing ', name
+ b.content_hash = None
+ b.ignore_duplicate_entry_error = True
+ b.save()
+ frappe.db.auto_commit_on_many_writes = False
+
+def get_replaced_files():
+ ret = []
+ new_files = dict(frappe.db.sql("select name, file_name from `tabFile Data` where file_name not like 'files/%'"))
+ old_files = dict(frappe.db.sql("select name, file_name from `tabFile Data` where ifnull(content_hash, '')=''"))
+ invfiles = invert_dict(new_files)
+
+ for nname, nfilename in new_files.iteritems():
+ if 'files/' + nfilename in old_files.values():
+ ret.append((nfilename, invfiles[nfilename]))
+ return ret
+
+def rename_replacing_files():
+ replaced_files = get_replaced_files()
+ if len(replaced_files):
+ missing_files = [v[0] for v in replaced_files]
+ with open(get_site_path('missing_files.txt'), 'w') as f:
+ f.write(('\n'.join(missing_files) + '\n').encode('utf-8'))
+
+ for file_name, file_datas in replaced_files:
+ print 'processing ' + file_name
+ content_hash = frappe.db.get_value('File Data', file_datas[0], 'content_hash')
+ if not content_hash:
+ continue
+ new_file_name = get_file_name(file_name, content_hash)
+ if os.path.exists(get_files_path(new_file_name)):
+ continue
+ print 'skipping ' + file_name
+ try:
+ os.rename(get_files_path(file_name), get_files_path(new_file_name))
+ except OSError:
+ print 'Error renaming ', file_name
+ for name in file_datas:
+ f = frappe.get_doc('File Data', name)
+ f.file_name = new_file_name
+ f.file_url = '/files/' + new_file_name
+ f.save()
+
+def invert_dict(ddict):
+ ret = {}
+ for k,v in ddict.iteritems():
+ if not ret.get(v):
+ ret[v] = [k]
+ else:
+ ret[v].append(k)
+ return ret
+
+def get_file_name(fname, hash):
+ if '.' in fname:
+ partial, extn = fname.rsplit('.', 1)
+ else:
+ partial = fname
+ extn = ''
+ return '{partial}{suffix}.{extn}'.format(partial=partial, extn=extn, suffix=hash[:5])
diff --git a/frappe/patches/v4_2/__init__.py b/frappe/patches/v4_2/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/patches/v4_2/print_with_letterhead.py b/frappe/patches/v4_2/print_with_letterhead.py
new file mode 100644
index 0000000000..ad2a144d95
--- /dev/null
+++ b/frappe/patches/v4_2/print_with_letterhead.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doc("core", "doctype", "print_settings")
+ print_settings = frappe.get_doc("Print Settings")
+ print_settings.with_letterhead = 1
+ print_settings.save()
diff --git a/frappe/patches/v4_2/refactor_website_routing.py b/frappe/patches/v4_2/refactor_website_routing.py
new file mode 100644
index 0000000000..b3ad5c8761
--- /dev/null
+++ b/frappe/patches/v4_2/refactor_website_routing.py
@@ -0,0 +1,7 @@
+import frappe
+
+def execute():
+ # clear all static web pages
+ frappe.delete_doc("DocType", "Website Route", force=1)
+ frappe.delete_doc("Page", "sitemap-browser", force=1)
+ frappe.db.sql("drop table `tabWebsite Route`")
diff --git a/frappe/patches/v4_2/set_assign_in_doc.py b/frappe/patches/v4_2/set_assign_in_doc.py
new file mode 100644
index 0000000000..664c997eaf
--- /dev/null
+++ b/frappe/patches/v4_2/set_assign_in_doc.py
@@ -0,0 +1,10 @@
+import frappe
+
+def execute():
+ for name in frappe.db.sql_list("""select name from `tabToDo`
+ where ifnull(reference_type, '')!='' and ifnull(reference_name, '')!=''"""):
+ try:
+ frappe.get_doc("ToDo", name).on_update()
+ except Exception, e:
+ if e.args[0]!=1146:
+ raise
diff --git a/frappe/permissions.py b/frappe/permissions.py
index 466318cd4f..30cdbee603 100644
--- a/frappe/permissions.py
+++ b/frappe/permissions.py
@@ -2,20 +2,23 @@
# MIT License. See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, copy, json
from frappe import _, msgprint
from frappe.utils import cint
-rights = ("read", "write", "create", "submit", "cancel", "amend",
- "report", "import", "export", "print", "email", "restrict", "delete", "restricted")
+rights = ("read", "write", "create", "delete", "submit", "cancel", "amend",
+ "print", "email", "report", "import", "export", "set_user_permissions")
-def check_admin_or_system_manager():
- if ("System Manager" not in frappe.get_roles()) and \
- (frappe.session.user!="Administrator"):
+def check_admin_or_system_manager(user=None):
+ if not user: user = frappe.session.user
+
+ if ("System Manager" not in frappe.get_roles(user)) and (user!="Administrator"):
frappe.throw(_("Not permitted"), frappe.PermissionError)
-def has_permission(doctype, ptype="read", doc=None, verbose=True):
+def has_permission(doctype, ptype="read", doc=None, verbose=True, user=None):
"""check if user has permission"""
+ if not user: user = frappe.session.user
+
if frappe.is_table(doctype):
return True
@@ -27,134 +30,173 @@ def has_permission(doctype, ptype="read", doc=None, verbose=True):
if ptype=="import" and not cint(meta.allow_import):
return False
- if frappe.session.user=="Administrator":
+ if user=="Administrator":
return True
- # get user permissions
- if not get_user_perms(meta).get(ptype):
+ role_permissions = get_role_permissions(meta, user=user)
+ if not role_permissions.get(ptype):
return False
if doc:
if isinstance(doc, basestring):
doc = frappe.get_doc(meta.name, doc)
- if not has_unrestricted_access(doc, verbose=verbose):
- return False
+ if role_permissions["apply_user_permissions"].get(ptype):
+ if not user_has_permission(doc, verbose=verbose, user=user,
+ user_permission_doctypes=role_permissions.get("user_permission_doctypes")):
+ return False
- if not has_controller_permissions(doc):
+ if not has_controller_permissions(doc, ptype, user=user):
return False
return True
-def get_user_perms(meta, user=None):
- if not user:
- user = frappe.session.user
+def get_doc_permissions(doc, verbose=False, user=None):
+ if not user: user = frappe.session.user
+
+ if frappe.is_table(doc.doctype):
+ return {"read":1, "write":1}
+
+ meta = frappe.get_meta(doc.doctype)
+
+ role_permissions = copy.deepcopy(get_role_permissions(meta, user=user))
+
+ if not cint(meta.is_submittable):
+ role_permissions["submit"] = 0
+
+ if not cint(meta.allow_import):
+ role_permissions["import"] = 0
+
+ if role_permissions.get("apply_user_permissions") and not user_has_permission(doc, verbose=verbose, user=user,
+ user_permission_doctypes=role_permissions.get("user_permission_doctypes")):
+ # no user permissions, switch off all user-level permissions
+ for ptype in role_permissions:
+ if role_permissions["apply_user_permissions"].get(ptype):
+ role_permissions[ptype] = 0
+
+ return role_permissions
+
+def get_role_permissions(meta, user=None):
+ if not user: user = frappe.session.user
cache_key = (meta.name, user)
- if not frappe.local.user_perms.get(cache_key):
- perms = frappe._dict()
+
+ if not frappe.local.role_permissions.get(cache_key):
+ perms = frappe._dict({ "apply_user_permissions": {} })
user_roles = frappe.get_roles(user)
for p in meta.permissions:
if cint(p.permlevel)==0 and (p.role in user_roles):
for ptype in rights:
- if ptype == "restricted":
- perms[ptype] = perms.get(ptype, 1) and cint(p.get(ptype))
- else:
- perms[ptype] = perms.get(ptype, 0) or cint(p.get(ptype))
-
- frappe.local.user_perms[cache_key] = perms
-
- return frappe.local.user_perms[cache_key]
-
-def has_unrestricted_access(doc, verbose=True):
- from frappe.defaults import get_restrictions
- restrictions = get_restrictions()
-
- meta = frappe.get_meta(doc.get("doctype"))
- user_perms = get_user_perms(meta)
- if get_user_perms(meta).restricted:
- if doc.owner == frappe.session.user:
- # owner is always allowed for restricted permissions
- return True
- elif not (restrictions and restrictions.get(doc.get("doctype"))):
- return False
- else:
- if not restrictions:
- return True
+ perms[ptype] = perms.get(ptype, 0) or cint(p.get(ptype))
+
+ if ptype != "set_user_permissions" and p.get(ptype):
+ perms["apply_user_permissions"][ptype] = (perms["apply_user_permissions"].get(ptype, 1)
+ and p.get("apply_user_permissions"))
+
+ if p.apply_user_permissions:
+ # set user_permission_doctypes in perms
+ user_permission_doctypes = (json.loads(p.user_permission_doctypes)
+ if p.user_permission_doctypes else None)
+
+ if user_permission_doctypes and user_permission_doctypes not in perms.get("user_permission_doctypes", []):
+ # perms["user_permission_doctypes"] would be a list of list like [["User", "Blog Post"], ["User"]]
+ perms.setdefault("user_permission_doctypes", []).append(user_permission_doctypes)
- def _has_unrestricted_access(d):
+ for key, value in perms.get("apply_user_permissions").items():
+ if not value:
+ del perms["apply_user_permissions"][key]
+
+ frappe.local.role_permissions[cache_key] = perms
+
+ return frappe.local.role_permissions[cache_key]
+
+def user_has_permission(doc, verbose=True, user=None, user_permission_doctypes=None):
+ from frappe.defaults import get_user_permissions
+ user_permissions = get_user_permissions(user)
+ user_permission_doctypes = get_user_permission_doctypes(user_permission_doctypes, user_permissions)
+
+ def check_user_permission(d):
meta = frappe.get_meta(d.get("doctype"))
+ end_result = False
+
+ messages = {}
- # evaluate specific restrictions
- fields_to_check = meta.get_restricted_fields(restrictions.keys())
+ # check multiple sets of user_permission_doctypes using OR condition
+ for doctypes in user_permission_doctypes:
+ result = True
- _has_restricted_data = False
- for df in fields_to_check:
- if d.get(df.fieldname) and d.get(df.fieldname) not in restrictions[df.options]:
- if verbose:
- msg = _("Not allowed to access {0} with {1} = {2}").format(df.options, _(df.label), d.get(df.fieldname))
+ for df in meta.get_fields_to_check_permissions(doctypes):
+ if (df.options in user_permissions and d.get(df.fieldname)
+ and d.get(df.fieldname) not in user_permissions[df.options]):
+ result = False
- if d.parentfield:
- msg = "{doctype}, {row} #{idx}, ".format(doctype=_(d.doctype),
- row=_("Row"), idx=d.idx) + msg
+ if verbose:
+ msg = _("Not allowed to access {0} with {1} = {2}").format(df.options, _(df.label), d.get(df.fieldname))
+ if d.parentfield:
+ msg = "{doctype}, {row} #{idx}, ".format(doctype=_(d.doctype),
+ row=_("Row"), idx=d.idx) + msg
- msgprint(msg)
+ messages[df.fieldname] = msg
- _has_restricted_data = True
+ end_result = end_result or result
- return _has_restricted_data
+ if not end_result and messages:
+ for fieldname, msg in messages.items():
+ msgprint(msg)
- has_restricted_data = _has_unrestricted_access(doc)
+ return end_result
+
+ _user_has_permission = check_user_permission(doc)
for d in doc.get_all_children():
- has_restricted_data = _has_unrestricted_access(d) or has_restricted_data
+ _user_has_permission = check_user_permission(d) and _user_has_permission
+
+ return _user_has_permission
- # check all restrictions before returning
- return False if has_restricted_data else True
+def has_controller_permissions(doc, ptype, user=None):
+ if not user: user = frappe.session.user
-def has_controller_permissions(doc):
for method in frappe.get_hooks("has_permission").get(doc.doctype, []):
- if not frappe.call(frappe.get_attr(method), doc=doc):
+ if not frappe.call(frappe.get_attr(method), doc=doc, ptype=ptype, user=user):
return False
return True
-def can_restrict_user(user, doctype, docname=None):
- if not can_restrict(doctype, docname):
- return False
-
- # check if target user does not have restrict permission
- if has_only_non_restrict_role(doctype, user):
- return True
-
- return False
-
-def can_restrict(doctype, docname=None):
- # System Manager can always restrict
+def can_set_user_permissions(doctype, docname=None):
+ # System Manager can always set user permissions
if "System Manager" in frappe.get_roles():
return True
+
meta = frappe.get_meta(doctype)
# check if current user has read permission for docname
if docname and not has_permission(doctype, "read", docname):
return False
- # check if current user has a role with restrict permission
- if not has_restrict_permission(meta):
+ # check if current user has a role that can set permission
+ if get_role_permissions(meta).set_user_permissions!=1:
return False
return True
-def has_restrict_permission(meta=None, user=None):
- return get_user_perms(meta, user).restrict==1
+def set_user_permission_if_allowed(doctype, name, user, with_message=False):
+ if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions!=1:
+ add_user_permission(doctype, name, user, with_message)
-def has_only_non_restrict_role(doctype, user):
- meta = frappe.get_meta(doctype)
- # check if target user does not have restrict permission
- if has_restrict_permission(meta, user):
- return False
+def add_user_permission(doctype, name, user, with_message=False):
+ if name not in frappe.defaults.get_user_permissions(user).get(doctype, []):
+ if not frappe.db.exists(doctype, name):
+ frappe.throw(_("{0} {1} not found").format(_(doctype), name), frappe.DoesNotExistError)
+
+ frappe.defaults.add_default(doctype, name, user, "User Permission")
+ elif with_message:
+ msgprint(_("Permission already set"))
- # and has non-restrict role
- return get_user_perms(meta, user).restrict==0
+def remove_user_permission(doctype, name, user, default_value_name=None):
+ frappe.defaults.clear_default(key=doctype, value=name, parent=user, parenttype="User Permission",
+ name=default_value_name)
+
+def clear_user_permissions_for_doctype(doctype):
+ frappe.defaults.clear_default(parenttype="User Permission", key=doctype)
def can_import(doctype, raise_exception=False):
if not ("System Manager" in frappe.get_roles() or has_permission(doctype, "import")):
@@ -171,3 +213,40 @@ def can_export(doctype, raise_exception=False):
else:
return False
return True
+
+def apply_user_permissions(doctype, ptype, user=None):
+ """Check if apply_user_permissions is checked for a doctype, perm type, user combination"""
+ role_permissions = get_role_permissions(frappe.get_meta(doctype), user=user)
+ return role_permissions.get("apply_user_permissions", {}).get(ptype)
+
+def get_user_permission_doctypes(user_permission_doctypes, user_permissions):
+ """returns a list of list like [["User", "Blog Post"], ["User"]]"""
+ if user_permission_doctypes:
+ # select those user permission doctypes for which user permissions exist!
+ user_permission_doctypes = [list(set(doctypes).intersection(set(user_permissions.keys())))
+ for doctypes in user_permission_doctypes]
+
+ else:
+ user_permission_doctypes = [user_permissions.keys()]
+
+
+ if len(user_permission_doctypes) > 1:
+ # OPTIMIZATION
+ # if intersection exists, use that to reduce the amount of querying
+ # for example, [["Blogger", "Blog Category"], ["Blogger"]], should only search in [["Blogger"]] as the first and condition becomes redundant
+
+ common = user_permission_doctypes[0]
+ for i in xrange(1, len(user_permission_doctypes), 1):
+ common = list(set(common).intersection(set(user_permission_doctypes[i])))
+ if not common:
+ break
+
+ if common:
+ # is common one of the user_permission_doctypes set?
+ for doctypes in user_permission_doctypes:
+ # are these lists equal?
+ if set(common) == set(doctypes):
+ user_permission_doctypes = [common]
+ break
+
+ return user_permission_doctypes
diff --git a/frappe/public/build.json b/frappe/public/build.json
index d108ce90d0..6c4b1acf11 100644
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -12,6 +12,7 @@
"public/js/lib/nprogress.js",
"public/js/frappe/translate.js",
"public/js/frappe/misc/pretty_date.js",
+ "public/js/lib/moment/moment.min.js",
"website/js/website.js",
"website/js/website_group.js"
],
@@ -32,8 +33,8 @@
"public/css/tag-it.css",
"public/css/bootstrap.css",
- "public/css/bootstrap-responsive.css",
"public/css/font-awesome.css",
+ "public/css/octicons/octicons.css",
"public/css/desk.css",
"public/css/appframe.css",
"public/css/app_icon.css",
@@ -52,6 +53,8 @@
"public/js/lib/bootstrap.min.js",
"public/js/lib/nprogress.js",
"public/js/lib/beautify-html.js",
+ "public/js/lib/moment/moment.min.js",
+ "public/js/lib/moment/moment-timezone.min.js",
"public/js/frappe/format.js",
"public/js/frappe/provide.js",
@@ -65,13 +68,15 @@
"public/js/frappe/router.js",
"public/js/frappe/desk.js",
"public/js/frappe/defaults.js",
+ "public/js/lib/microtemplate.js",
+
+ "public/html/print_template.html",
+ "public/html/list_info_template.html",
"public/js/legacy/globals.js",
"public/js/legacy/datatype.js",
- "public/js/legacy/datetime.js",
"public/js/legacy/dom.js",
"public/js/legacy/handler.js",
- "public/js/legacy/printElement.js",
"public/js/legacy/loaders.js",
"public/js/frappe/ui/appframe.js",
@@ -117,19 +122,17 @@
"public/js/frappe/views/test_runner.js",
"public/js/frappe/form/formatters.js",
- "public/js/legacy/layout.js",
-
"public/js/frappe/ui/toolbar/selector_dialog.js",
"public/js/frappe/ui/toolbar/new.js",
"public/js/frappe/ui/toolbar/search.js",
"public/js/frappe/ui/toolbar/report.js",
"public/js/frappe/ui/toolbar/recent.js",
"public/js/frappe/ui/toolbar/bookmarks.js",
+ "public/js/frappe/ui/toolbar/about.js",
"public/js/frappe/ui/toolbar/toolbar.js",
"public/js/frappe/ui/editor.js",
"public/js/legacy/form.js",
- "public/js/legacy/print_format.js",
"public/js/legacy/clientscriptAPI.js",
"public/js/frappe/form/toolbar.js",
@@ -146,7 +149,12 @@
"public/js/frappe/form/linked_with.js",
"public/js/frappe/form/workflow.js",
"public/js/frappe/form/assign_to.js",
- "public/js/frappe/print/print_table.js"
+ "public/js/frappe/form/print.js"
+ ],
+ "js/print_format_v3.min.js": [
+ "public/js/legacy/layout.js",
+ "public/js/legacy/print_table.js",
+ "public/js/legacy/print_format.js"
],
"js/slickgrid.min.js": [
"public/js/lib/slickgrid/jquery.event.drag.js",
diff --git a/frappe/public/css/appframe.css b/frappe/public/css/appframe.css
index 6101946ff7..e4c694526a 100644
--- a/frappe/public/css/appframe.css
+++ b/frappe/public/css/appframe.css
@@ -5,28 +5,41 @@
padding-bottom: 15px;
}
+.appframe-wrapper {
+ background-color: #fff;
+ min-height: 400px;
+ /*box-shadow: 1px 0px 1px rgba(0,0,0,0.4);*/
+}
+
.appframe-titlebar {
border-bottom: 1px solid #c7c7c7;
}
-.appframe-titlebar, .appframe-footer {
- background: url(/assets/frappe/images/ui/sos.png) repeat;
- -webkit-box-shadow: inset 0 0 7px rgba(0, 0, 0, .07);
- box-shadow: inset 0 0 7px rgba(0, 0, 0, .07);
+.appframe-titlebar, .appframe-iconbar, .appframe-form, .appframe-primary-actions {
+ /*background-color: rgba(255, 255, 255, 0.7);*/
+ background-color: #f9f9f9;
+}
+
+.appframe-primary-actions {
+ border-bottom: 1px solid #c7c7c7;
+}
+
+.appframe-primary-actions .btn {
+ margin: 10px;
+ margin-left: 0px;
}
.appframe-iconbar {
- border-bottom: 1px solid #eee;
+ border-bottom: 1px solid #c7c7c7;
}
.titlebar-item {
- padding-top: 15px;
- padding-bottom: 15px;
+ padding-top: 10px;
+ padding-bottom: 10px;
}
-.titlebar-item h2 {
+.titlebar-item h3 {
display: inline-block;
- font-weight: normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -34,9 +47,10 @@
margin: 0px;
}
-.titlebar-item.text-left {
-
+.titlebar-item.text-right {
+ margin-top: 3px;
}
+
.titlebar-left-item {
float: left;
width: 30px;
@@ -51,6 +65,13 @@ h2.titlebar-left-item {
width: 90%;
}
+.title-sub {
+ font-size: 50%;
+ color: #888;
+ margin-left: 34px;
+ margin-top: 4px;
+}
+
@media (max-width: 768px) {
.titlebar-center-item {
width: 80%;
@@ -101,7 +122,7 @@ h2.titlebar-left-item {
}
.appframe-form {
- padding: 5px 0px;
+ padding: 2px 0px 5px 0px;
}
.appframe-form input, .appframe-form select, .appframe-form label {
@@ -116,14 +137,19 @@ h2.titlebar-left-item {
.appframe-form .form-control {
height: 28px;
+ margin-top: 0px;
}
-
.iconbar {
display: inline-block;
padding: 9px 0px;
}
+.iconbar-4 {
+ border-left: 1px solid #c7c7c7;
+ padding-left: 4px;
+}
+
.iconbar ul {
list-style: none;
margin: 0 0 0 0;
@@ -157,11 +183,22 @@ h2.titlebar-left-item {
color: orange;
}
+.workflow-button-area {
+ margin-bottom: 15px;
+}
-.appframe-footer {
- margin-top: 15px;
+.appframe-control-label {
+ font-size: 75% !important;
+ margin: 0px auto !important;
+ padding: 0px 4px !important;
}
-.workflow-button-area {
- margin-bottom: 15px;
+.appframe-only-label {
+ margin-top: 21px !important;
+ text-align: center;
+}
+
+.appframe-form .checkbox {
+ margin-top: 15px !important;
+ margin-bottom: -7px !important;
}
diff --git a/frappe/public/css/avatar.css b/frappe/public/css/avatar.css
index a55cef4987..39af6d08b3 100644
--- a/frappe/public/css/avatar.css
+++ b/frappe/public/css/avatar.css
@@ -1,10 +1,12 @@
.avatar {
- display: inline-block;
+ display: inline-block;
vertical-align: middle;
- border-radius: 50%;
+ border-radius: 5px;
overflow: hidden;
background-color: #ddd;
border: 1px solid #eee;
+ width: 50px;
+ height: 50px;
}
.avatar img {
@@ -23,3 +25,12 @@
width: 72px;
height: 72px;
}
+
+.avatar-xs {
+ margin-right: 3px;
+ margin-top: -2px;
+ width: 17px;
+ height: 17px;
+ border: none;
+ border-radius: 3px;
+}
diff --git a/frappe/public/css/bootstrap.css b/frappe/public/css/bootstrap.css
index 49a9f383a1..c6e36fc3e6 100644
--- a/frappe/public/css/bootstrap.css
+++ b/frappe/public/css/bootstrap.css
@@ -1,12 +1,10 @@
-
/*!
- * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
-/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
-
+/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
@@ -96,8 +94,9 @@ figure {
}
hr {
height: 0;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
}
pre {
overflow: auto;
@@ -146,7 +145,9 @@ input {
}
input[type="checkbox"],
input[type="radio"] {
- box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
padding: 0;
}
input[type="number"]::-webkit-inner-spin-button,
@@ -188,10 +189,11 @@ th {
}
@media print {
* {
- color: #000 !important;
+/* color: #000 !important;*/
text-shadow: none !important;
- background: transparent !important;
- box-shadow: none !important;
+/* background: transparent !important;*/
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
}
a,
a:visited {
@@ -209,7 +211,7 @@ th {
}
pre,
blockquote {
- border: 1px solid #999;
+/* border: 1px solid #999;*/
page-break-inside: avoid;
}
@@ -239,2733 +241,2824 @@ th {
.navbar {
display: none;
}
- .table td,
+/* .table td,
.table th {
background-color: #fff !important;
}
- .btn > .caret,
+*/ .btn > .caret,
.dropup > .btn > .caret {
border-top-color: #000 !important;
}
- .label {
+/* .label {
border: 1px solid #000;
}
- .table {
+*/ .table {
border-collapse: collapse !important;
}
- .table-bordered th,
+ /*.table-bordered th,
.table-bordered td {
border: 1px solid #ddd !important;
- }
-}
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ }*/
}
-*:before,
-*:after {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
-html {
- font-size: 62.5%;
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
-body {
- font-family: "Open Sans", Helvetica, Arial, sans-serif;
- font-size: 14px;
- line-height: 1.6;
- /*line-height: 1.42857143;*/
- color: #333;
- background-color: #fff;
+.glyphicon-asterisk:before {
+ content: "\2a";
}
-input,
-button,
-select,
-textarea {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
+.glyphicon-plus:before {
+ content: "\2b";
}
-a {
- color: #2980b9;
- text-decoration: none;
+.glyphicon-euro:before {
+ content: "\20ac";
}
-a:hover,
-a:focus {
- color: #1b557a;
- text-decoration: underline;
+.glyphicon-minus:before {
+ content: "\2212";
}
-a:focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
+.glyphicon-cloud:before {
+ content: "\2601";
}
-figure {
- margin: 0;
+.glyphicon-envelope:before {
+ content: "\2709";
}
-img {
- vertical-align: middle;
+.glyphicon-pencil:before {
+ content: "\270f";
}
-.img-responsive {
- display: block;
- max-width: 100%;
- height: auto;
+.glyphicon-glass:before {
+ content: "\e001";
}
-.img-rounded {
- border-radius: 6px;
+.glyphicon-music:before {
+ content: "\e002";
}
-.img-thumbnail {
- display: inline-block;
- max-width: 100%;
- height: auto;
- padding: 4px;
- line-height: 1.42857143;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 4px;
- -webkit-transition: all .2s ease-in-out;
- transition: all .2s ease-in-out;
+.glyphicon-search:before {
+ content: "\e003";
}
-.img-circle {
- border-radius: 50%;
+.glyphicon-heart:before {
+ content: "\e005";
}
-hr {
- margin-top: 20px;
- margin-bottom: 20px;
- border: 0;
- border-top: 1px solid #eee;
+.glyphicon-star:before {
+ content: "\e006";
}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
+.glyphicon-star-empty:before {
+ content: "\e007";
}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-.h1,
-.h2,
-.h3,
-.h4,
-.h5,
-.h6 {
- font-family: inherit;
- font-weight: 500;
- line-height: 1.1;
- color: inherit;
+.glyphicon-user:before {
+ content: "\e008";
}
-h1 small,
-h2 small,
-h3 small,
-h4 small,
-h5 small,
-h6 small,
-.h1 small,
-.h2 small,
-.h3 small,
-.h4 small,
-.h5 small,
-.h6 small,
-h1 .small,
-h2 .small,
-h3 .small,
-h4 .small,
-h5 .small,
-h6 .small,
-.h1 .small,
-.h2 .small,
-.h3 .small,
-.h4 .small,
-.h5 .small,
-.h6 .small {
- font-weight: normal;
- line-height: 1;
- color: #999;
+.glyphicon-film:before {
+ content: "\e009";
}
-h1,
-.h1,
-h2,
-.h2,
-h3,
-.h3 {
- margin-top: 20px;
- margin-bottom: 10px;
+.glyphicon-th-large:before {
+ content: "\e010";
}
-h1 small,
-.h1 small,
-h2 small,
-.h2 small,
-h3 small,
-.h3 small,
-h1 .small,
-.h1 .small,
-h2 .small,
-.h2 .small,
-h3 .small,
-.h3 .small {
- font-size: 65%;
+.glyphicon-th:before {
+ content: "\e011";
}
-h4,
-.h4,
-h5,
-.h5,
-h6,
-.h6 {
- margin-top: 10px;
- margin-bottom: 10px;
+.glyphicon-th-list:before {
+ content: "\e012";
}
-h4 small,
-.h4 small,
-h5 small,
-.h5 small,
-h6 small,
-.h6 small,
-h4 .small,
-.h4 .small,
-h5 .small,
-.h5 .small,
-h6 .small,
-.h6 .small {
- font-size: 75%;
+.glyphicon-ok:before {
+ content: "\e013";
}
-h1,
-.h1 {
- font-size: 36px;
+.glyphicon-remove:before {
+ content: "\e014";
}
-h2,
-.h2 {
- font-size: 30px;
+.glyphicon-zoom-in:before {
+ content: "\e015";
}
-h3,
-.h3 {
- font-size: 24px;
+.glyphicon-zoom-out:before {
+ content: "\e016";
}
-h4,
-.h4 {
- font-size: 18px;
+.glyphicon-off:before {
+ content: "\e017";
}
-h5,
-.h5 {
- font-size: 14px;
+.glyphicon-signal:before {
+ content: "\e018";
}
-h6,
-.h6 {
- font-size: 12px;
+.glyphicon-cog:before {
+ content: "\e019";
}
-p {
- margin: 0 0 10px;
+.glyphicon-trash:before {
+ content: "\e020";
}
-.lead {
- margin-bottom: 20px;
- font-size: 16px;
- font-weight: 200;
- line-height: 1.4;
+.glyphicon-home:before {
+ content: "\e021";
}
-@media (min-width: 768px) {
- .lead {
- font-size: 21px;
- }
+.glyphicon-file:before {
+ content: "\e022";
}
-small,
-.small {
- font-size: 85%;
+.glyphicon-time:before {
+ content: "\e023";
}
-cite {
- font-style: normal;
+.glyphicon-road:before {
+ content: "\e024";
}
-.text-left {
- text-align: left;
+.glyphicon-download-alt:before {
+ content: "\e025";
}
-.text-right {
- text-align: right;
+.glyphicon-download:before {
+ content: "\e026";
}
-.text-center {
- text-align: center;
+.glyphicon-upload:before {
+ content: "\e027";
}
-.text-justify {
- text-align: justify;
+.glyphicon-inbox:before {
+ content: "\e028";
}
-.text-muted {
- color: #999;
+.glyphicon-play-circle:before {
+ content: "\e029";
}
-.text-primary {
- color: #2980b9;
+.glyphicon-repeat:before {
+ content: "\e030";
}
-a.text-primary:hover {
- color: #20638f;
+.glyphicon-refresh:before {
+ content: "\e031";
}
-.text-success {
- color: #3c763d;
+.glyphicon-list-alt:before {
+ content: "\e032";
}
-a.text-success:hover {
- color: #2b542c;
+.glyphicon-lock:before {
+ content: "\e033";
}
-.text-info {
- color: #31708f;
+.glyphicon-flag:before {
+ content: "\e034";
}
-a.text-info:hover {
- color: #245269;
+.glyphicon-headphones:before {
+ content: "\e035";
}
-.text-warning {
- color: #f39c12;
+.glyphicon-volume-off:before {
+ content: "\e036";
}
-a.text-warning:hover {
- color: #c87f0a;
+.glyphicon-volume-down:before {
+ content: "\e037";
}
-.text-danger {
- color: #c0392b;
+.glyphicon-volume-up:before {
+ content: "\e038";
}
-a.text-danger:hover {
- color: #962d22;
+.glyphicon-qrcode:before {
+ content: "\e039";
}
-.bg-primary {
- color: #fff;
- background-color: #2980b9;
+.glyphicon-barcode:before {
+ content: "\e040";
}
-a.bg-primary:hover {
- background-color: #20638f;
+.glyphicon-tag:before {
+ content: "\e041";
}
-.bg-success {
- background-color: #dff0d8;
+.glyphicon-tags:before {
+ content: "\e042";
}
-a.bg-success:hover {
- background-color: #c1e2b3;
+.glyphicon-book:before {
+ content: "\e043";
}
-.bg-info {
- background-color: #d9edf7;
+.glyphicon-bookmark:before {
+ content: "\e044";
}
-a.bg-info:hover {
- background-color: #afd9ee;
+.glyphicon-print:before {
+ content: "\e045";
}
-.bg-warning {
- background-color: #fcf8e3;
+.glyphicon-camera:before {
+ content: "\e046";
}
-a.bg-warning:hover {
- background-color: #f7ecb5;
+.glyphicon-font:before {
+ content: "\e047";
}
-.bg-danger {
- background-color: #f2dede;
+.glyphicon-bold:before {
+ content: "\e048";
}
-a.bg-danger:hover {
- background-color: #e4b9b9;
+.glyphicon-italic:before {
+ content: "\e049";
}
-.page-header {
- padding-bottom: 9px;
- margin: 40px 0 20px;
- border-bottom: 1px solid #eee;
+.glyphicon-text-height:before {
+ content: "\e050";
}
-ul,
-ol {
- margin-top: 0;
- margin-bottom: 10px;
+.glyphicon-text-width:before {
+ content: "\e051";
}
-ul ul,
-ol ul,
-ul ol,
-ol ol {
- margin-bottom: 0;
+.glyphicon-align-left:before {
+ content: "\e052";
}
-.list-unstyled {
- padding-left: 0;
- list-style: none;
+.glyphicon-align-center:before {
+ content: "\e053";
}
-.list-inline {
- padding-left: 0;
- list-style: none;
+.glyphicon-align-right:before {
+ content: "\e054";
}
-.list-inline > li {
- display: inline-block;
- padding-right: 5px;
- padding-left: 5px;
+.glyphicon-align-justify:before {
+ content: "\e055";
}
-.list-inline > li:first-child {
- padding-left: 0;
+.glyphicon-list:before {
+ content: "\e056";
}
-dl {
- margin-top: 0;
- margin-bottom: 20px;
+.glyphicon-indent-left:before {
+ content: "\e057";
}
-dt,
-dd {
- line-height: 1.42857143;
+.glyphicon-indent-right:before {
+ content: "\e058";
}
-dt {
- font-weight: bold;
+.glyphicon-facetime-video:before {
+ content: "\e059";
}
-dd {
- margin-left: 0;
+.glyphicon-picture:before {
+ content: "\e060";
}
-@media (min-width: 768px) {
- .dl-horizontal dt {
- float: left;
- width: 160px;
- overflow: hidden;
- clear: left;
- text-align: right;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .dl-horizontal dd {
- margin-left: 180px;
- }
+.glyphicon-map-marker:before {
+ content: "\e062";
}
-abbr[title],
-abbr[data-original-title] {
- cursor: help;
- border-bottom: 1px dotted #999;
+.glyphicon-adjust:before {
+ content: "\e063";
}
-.initialism {
- font-size: 90%;
- text-transform: uppercase;
+.glyphicon-tint:before {
+ content: "\e064";
}
-blockquote {
- padding: 10px 20px;
- margin: 0 0 20px;
- font-size: 17.5px;
- border-left: 5px solid #eee;
+.glyphicon-edit:before {
+ content: "\e065";
}
-blockquote p:last-child,
-blockquote ul:last-child,
-blockquote ol:last-child {
- margin-bottom: 0;
+.glyphicon-share:before {
+ content: "\e066";
}
-blockquote footer,
-blockquote small,
-blockquote .small {
- display: block;
- font-size: 80%;
- line-height: 1.42857143;
- color: #999;
+.glyphicon-check:before {
+ content: "\e067";
}
-blockquote footer:before,
-blockquote small:before,
-blockquote .small:before {
- content: '\2014 \00A0';
+.glyphicon-move:before {
+ content: "\e068";
}
-.blockquote-reverse,
-blockquote.pull-right {
- padding-right: 15px;
- padding-left: 0;
- text-align: right;
- border-right: 5px solid #eee;
- border-left: 0;
+.glyphicon-step-backward:before {
+ content: "\e069";
}
-.blockquote-reverse footer:before,
-blockquote.pull-right footer:before,
-.blockquote-reverse small:before,
-blockquote.pull-right small:before,
-.blockquote-reverse .small:before,
-blockquote.pull-right .small:before {
- content: '';
+.glyphicon-fast-backward:before {
+ content: "\e070";
}
-.blockquote-reverse footer:after,
-blockquote.pull-right footer:after,
-.blockquote-reverse small:after,
-blockquote.pull-right small:after,
-.blockquote-reverse .small:after,
-blockquote.pull-right .small:after {
- content: '\00A0 \2014';
+.glyphicon-backward:before {
+ content: "\e071";
}
-blockquote:before,
-blockquote:after {
- content: "";
+.glyphicon-play:before {
+ content: "\e072";
}
-address {
- margin-bottom: 20px;
- font-style: normal;
- line-height: 1.42857143;
+.glyphicon-pause:before {
+ content: "\e073";
}
-code,
-kbd,
-pre,
-samp {
- font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+.glyphicon-stop:before {
+ content: "\e074";
}
-code {
- padding: 2px 4px;
- font-size: 90%;
- color: #c7254e;
- white-space: nowrap;
- background-color: #f9f2f4;
- border-radius: 4px;
+.glyphicon-forward:before {
+ content: "\e075";
}
-kbd {
- padding: 2px 4px;
- font-size: 90%;
- color: #fff;
- background-color: #333;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+.glyphicon-fast-forward:before {
+ content: "\e076";
}
-pre {
- display: block;
- padding: 9.5px;
- margin: 0 0 10px;
- font-size: 13px;
- line-height: 1.42857143;
- color: #333;
- word-break: break-all;
- word-wrap: break-word;
- background-color: #f5f5f5;
- border: 1px solid #ccc;
- border-radius: 4px;
+.glyphicon-step-forward:before {
+ content: "\e077";
}
-pre code {
- padding: 0;
- font-size: inherit;
- color: inherit;
- white-space: pre-wrap;
- background-color: transparent;
- border-radius: 0;
+.glyphicon-eject:before {
+ content: "\e078";
}
-.pre-scrollable {
- max-height: 340px;
- overflow-y: scroll;
+.glyphicon-chevron-left:before {
+ content: "\e079";
}
-.container {
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
+.glyphicon-chevron-right:before {
+ content: "\e080";
}
-@media (min-width: 768px) {
- .container {
- width: 750px;
- }
+.glyphicon-plus-sign:before {
+ content: "\e081";
}
-@media (min-width: 992px) {
- .container {
- width: 970px;
- }
+.glyphicon-minus-sign:before {
+ content: "\e082";
}
-@media (min-width: 1200px) {
- .container {
- width: 1170px;
- }
+.glyphicon-remove-sign:before {
+ content: "\e083";
}
-.container-fluid {
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
+.glyphicon-ok-sign:before {
+ content: "\e084";
}
-.row {
- margin-right: -15px;
- margin-left: -15px;
+.glyphicon-question-sign:before {
+ content: "\e085";
}
-.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
- position: relative;
- min-height: 1px;
- padding-right: 15px;
- padding-left: 15px;
+.glyphicon-info-sign:before {
+ content: "\e086";
}
-.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
- float: left;
+.glyphicon-screenshot:before {
+ content: "\e087";
}
-.col-xs-12 {
- width: 100%;
+.glyphicon-remove-circle:before {
+ content: "\e088";
}
-.col-xs-11 {
- width: 91.66666667%;
+.glyphicon-ok-circle:before {
+ content: "\e089";
}
-.col-xs-10 {
- width: 83.33333333%;
+.glyphicon-ban-circle:before {
+ content: "\e090";
}
-.col-xs-9 {
- width: 75%;
+.glyphicon-arrow-left:before {
+ content: "\e091";
}
-.col-xs-8 {
- width: 66.66666667%;
+.glyphicon-arrow-right:before {
+ content: "\e092";
}
-.col-xs-7 {
- width: 58.33333333%;
+.glyphicon-arrow-up:before {
+ content: "\e093";
}
-.col-xs-6 {
- width: 50%;
+.glyphicon-arrow-down:before {
+ content: "\e094";
}
-.col-xs-5 {
- width: 41.66666667%;
+.glyphicon-share-alt:before {
+ content: "\e095";
}
-.col-xs-4 {
- width: 33.33333333%;
+.glyphicon-resize-full:before {
+ content: "\e096";
}
-.col-xs-3 {
- width: 25%;
+.glyphicon-resize-small:before {
+ content: "\e097";
}
-.col-xs-2 {
- width: 16.66666667%;
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
}
-.col-xs-1 {
- width: 8.33333333%;
+.glyphicon-gift:before {
+ content: "\e102";
}
-.col-xs-pull-12 {
- right: 100%;
+.glyphicon-leaf:before {
+ content: "\e103";
}
-.col-xs-pull-11 {
- right: 91.66666667%;
+.glyphicon-fire:before {
+ content: "\e104";
}
-.col-xs-pull-10 {
- right: 83.33333333%;
+.glyphicon-eye-open:before {
+ content: "\e105";
}
-.col-xs-pull-9 {
- right: 75%;
+.glyphicon-eye-close:before {
+ content: "\e106";
}
-.col-xs-pull-8 {
- right: 66.66666667%;
+.glyphicon-warning-sign:before {
+ content: "\e107";
}
-.col-xs-pull-7 {
- right: 58.33333333%;
+.glyphicon-plane:before {
+ content: "\e108";
}
-.col-xs-pull-6 {
- right: 50%;
+.glyphicon-calendar:before {
+ content: "\e109";
}
-.col-xs-pull-5 {
- right: 41.66666667%;
+.glyphicon-random:before {
+ content: "\e110";
}
-.col-xs-pull-4 {
- right: 33.33333333%;
+.glyphicon-comment:before {
+ content: "\e111";
}
-.col-xs-pull-3 {
- right: 25%;
+.glyphicon-magnet:before {
+ content: "\e112";
}
-.col-xs-pull-2 {
- right: 16.66666667%;
+.glyphicon-chevron-up:before {
+ content: "\e113";
}
-.col-xs-pull-1 {
- right: 8.33333333%;
+.glyphicon-chevron-down:before {
+ content: "\e114";
}
-.col-xs-pull-0 {
- right: 0;
+.glyphicon-retweet:before {
+ content: "\e115";
}
-.col-xs-push-12 {
- left: 100%;
+.glyphicon-shopping-cart:before {
+ content: "\e116";
}
-.col-xs-push-11 {
- left: 91.66666667%;
+.glyphicon-folder-close:before {
+ content: "\e117";
}
-.col-xs-push-10 {
- left: 83.33333333%;
+.glyphicon-folder-open:before {
+ content: "\e118";
}
-.col-xs-push-9 {
- left: 75%;
+.glyphicon-resize-vertical:before {
+ content: "\e119";
}
-.col-xs-push-8 {
- left: 66.66666667%;
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
}
-.col-xs-push-7 {
- left: 58.33333333%;
+.glyphicon-hdd:before {
+ content: "\e121";
}
-.col-xs-push-6 {
- left: 50%;
+.glyphicon-bullhorn:before {
+ content: "\e122";
}
-.col-xs-push-5 {
- left: 41.66666667%;
+.glyphicon-bell:before {
+ content: "\e123";
}
-.col-xs-push-4 {
- left: 33.33333333%;
+.glyphicon-certificate:before {
+ content: "\e124";
}
-.col-xs-push-3 {
- left: 25%;
+.glyphicon-thumbs-up:before {
+ content: "\e125";
}
-.col-xs-push-2 {
- left: 16.66666667%;
+.glyphicon-thumbs-down:before {
+ content: "\e126";
}
-.col-xs-push-1 {
- left: 8.33333333%;
+.glyphicon-hand-right:before {
+ content: "\e127";
}
-.col-xs-push-0 {
- left: 0;
+.glyphicon-hand-left:before {
+ content: "\e128";
}
-.col-xs-offset-12 {
- margin-left: 100%;
+.glyphicon-hand-up:before {
+ content: "\e129";
}
-.col-xs-offset-11 {
- margin-left: 91.66666667%;
+.glyphicon-hand-down:before {
+ content: "\e130";
}
-.col-xs-offset-10 {
- margin-left: 83.33333333%;
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
}
-.col-xs-offset-9 {
- margin-left: 75%;
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
}
-.col-xs-offset-8 {
- margin-left: 66.66666667%;
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
}
-.col-xs-offset-7 {
- margin-left: 58.33333333%;
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
}
-.col-xs-offset-6 {
- margin-left: 50%;
+.glyphicon-globe:before {
+ content: "\e135";
}
-.col-xs-offset-5 {
- margin-left: 41.66666667%;
+.glyphicon-wrench:before {
+ content: "\e136";
}
-.col-xs-offset-4 {
- margin-left: 33.33333333%;
+.glyphicon-tasks:before {
+ content: "\e137";
}
-.col-xs-offset-3 {
- margin-left: 25%;
+.glyphicon-filter:before {
+ content: "\e138";
}
-.col-xs-offset-2 {
- margin-left: 16.66666667%;
+.glyphicon-briefcase:before {
+ content: "\e139";
}
-.col-xs-offset-1 {
- margin-left: 8.33333333%;
+.glyphicon-fullscreen:before {
+ content: "\e140";
}
-.col-xs-offset-0 {
- margin-left: 0;
+.glyphicon-dashboard:before {
+ content: "\e141";
}
-@media (min-width: 768px) {
- .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
- float: left;
- }
- .col-sm-12 {
- width: 100%;
- }
- .col-sm-11 {
- width: 91.66666667%;
- }
- .col-sm-10 {
- width: 83.33333333%;
- }
- .col-sm-9 {
- width: 75%;
- }
- .col-sm-8 {
- width: 66.66666667%;
- }
- .col-sm-7 {
- width: 58.33333333%;
- }
- .col-sm-6 {
- width: 50%;
- }
- .col-sm-5 {
- width: 41.66666667%;
- }
- .col-sm-4 {
- width: 33.33333333%;
- }
- .col-sm-3 {
- width: 25%;
- }
- .col-sm-2 {
- width: 16.66666667%;
- }
- .col-sm-1 {
- width: 8.33333333%;
- }
- .col-sm-pull-12 {
- right: 100%;
- }
- .col-sm-pull-11 {
- right: 91.66666667%;
- }
- .col-sm-pull-10 {
- right: 83.33333333%;
- }
- .col-sm-pull-9 {
- right: 75%;
- }
- .col-sm-pull-8 {
- right: 66.66666667%;
- }
- .col-sm-pull-7 {
- right: 58.33333333%;
- }
- .col-sm-pull-6 {
- right: 50%;
- }
- .col-sm-pull-5 {
- right: 41.66666667%;
- }
- .col-sm-pull-4 {
- right: 33.33333333%;
- }
- .col-sm-pull-3 {
- right: 25%;
- }
- .col-sm-pull-2 {
- right: 16.66666667%;
- }
- .col-sm-pull-1 {
- right: 8.33333333%;
- }
- .col-sm-pull-0 {
- right: 0;
- }
- .col-sm-push-12 {
- left: 100%;
- }
- .col-sm-push-11 {
- left: 91.66666667%;
- }
- .col-sm-push-10 {
- left: 83.33333333%;
- }
- .col-sm-push-9 {
- left: 75%;
- }
- .col-sm-push-8 {
- left: 66.66666667%;
- }
- .col-sm-push-7 {
- left: 58.33333333%;
- }
- .col-sm-push-6 {
- left: 50%;
- }
- .col-sm-push-5 {
- left: 41.66666667%;
- }
- .col-sm-push-4 {
- left: 33.33333333%;
- }
- .col-sm-push-3 {
- left: 25%;
- }
- .col-sm-push-2 {
- left: 16.66666667%;
- }
- .col-sm-push-1 {
- left: 8.33333333%;
- }
- .col-sm-push-0 {
- left: 0;
- }
- .col-sm-offset-12 {
- margin-left: 100%;
- }
- .col-sm-offset-11 {
- margin-left: 91.66666667%;
- }
- .col-sm-offset-10 {
- margin-left: 83.33333333%;
- }
- .col-sm-offset-9 {
- margin-left: 75%;
- }
- .col-sm-offset-8 {
- margin-left: 66.66666667%;
- }
- .col-sm-offset-7 {
- margin-left: 58.33333333%;
- }
- .col-sm-offset-6 {
- margin-left: 50%;
- }
- .col-sm-offset-5 {
- margin-left: 41.66666667%;
- }
- .col-sm-offset-4 {
- margin-left: 33.33333333%;
- }
- .col-sm-offset-3 {
- margin-left: 25%;
- }
- .col-sm-offset-2 {
- margin-left: 16.66666667%;
- }
- .col-sm-offset-1 {
- margin-left: 8.33333333%;
- }
- .col-sm-offset-0 {
- margin-left: 0;
- }
+.glyphicon-paperclip:before {
+ content: "\e142";
}
-@media (min-width: 992px) {
- .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
- float: left;
- }
- .col-md-12 {
- width: 100%;
- }
- .col-md-11 {
- width: 91.66666667%;
- }
- .col-md-10 {
- width: 83.33333333%;
- }
- .col-md-9 {
- width: 75%;
- }
- .col-md-8 {
- width: 66.66666667%;
- }
- .col-md-7 {
- width: 58.33333333%;
- }
- .col-md-6 {
- width: 50%;
- }
- .col-md-5 {
- width: 41.66666667%;
- }
- .col-md-4 {
- width: 33.33333333%;
- }
- .col-md-3 {
- width: 25%;
- }
- .col-md-2 {
- width: 16.66666667%;
- }
- .col-md-1 {
- width: 8.33333333%;
- }
- .col-md-pull-12 {
- right: 100%;
- }
- .col-md-pull-11 {
- right: 91.66666667%;
- }
- .col-md-pull-10 {
- right: 83.33333333%;
- }
- .col-md-pull-9 {
- right: 75%;
- }
- .col-md-pull-8 {
- right: 66.66666667%;
- }
- .col-md-pull-7 {
- right: 58.33333333%;
- }
- .col-md-pull-6 {
- right: 50%;
- }
- .col-md-pull-5 {
- right: 41.66666667%;
- }
- .col-md-pull-4 {
- right: 33.33333333%;
- }
- .col-md-pull-3 {
- right: 25%;
- }
- .col-md-pull-2 {
- right: 16.66666667%;
- }
- .col-md-pull-1 {
- right: 8.33333333%;
- }
- .col-md-pull-0 {
- right: 0;
- }
- .col-md-push-12 {
- left: 100%;
- }
- .col-md-push-11 {
- left: 91.66666667%;
- }
- .col-md-push-10 {
- left: 83.33333333%;
- }
- .col-md-push-9 {
- left: 75%;
- }
- .col-md-push-8 {
- left: 66.66666667%;
- }
- .col-md-push-7 {
- left: 58.33333333%;
- }
- .col-md-push-6 {
- left: 50%;
- }
- .col-md-push-5 {
- left: 41.66666667%;
- }
- .col-md-push-4 {
- left: 33.33333333%;
- }
- .col-md-push-3 {
- left: 25%;
- }
- .col-md-push-2 {
- left: 16.66666667%;
- }
- .col-md-push-1 {
- left: 8.33333333%;
- }
- .col-md-push-0 {
- left: 0;
- }
- .col-md-offset-12 {
- margin-left: 100%;
- }
- .col-md-offset-11 {
- margin-left: 91.66666667%;
- }
- .col-md-offset-10 {
- margin-left: 83.33333333%;
- }
- .col-md-offset-9 {
- margin-left: 75%;
- }
- .col-md-offset-8 {
- margin-left: 66.66666667%;
- }
- .col-md-offset-7 {
- margin-left: 58.33333333%;
- }
- .col-md-offset-6 {
- margin-left: 50%;
- }
- .col-md-offset-5 {
- margin-left: 41.66666667%;
- }
- .col-md-offset-4 {
- margin-left: 33.33333333%;
- }
- .col-md-offset-3 {
- margin-left: 25%;
- }
- .col-md-offset-2 {
- margin-left: 16.66666667%;
- }
- .col-md-offset-1 {
- margin-left: 8.33333333%;
- }
- .col-md-offset-0 {
- margin-left: 0;
- }
+.glyphicon-heart-empty:before {
+ content: "\e143";
}
-@media (min-width: 1200px) {
- .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
- float: left;
- }
- .col-lg-12 {
- width: 100%;
- }
- .col-lg-11 {
- width: 91.66666667%;
- }
- .col-lg-10 {
- width: 83.33333333%;
- }
- .col-lg-9 {
- width: 75%;
- }
- .col-lg-8 {
- width: 66.66666667%;
- }
- .col-lg-7 {
- width: 58.33333333%;
- }
- .col-lg-6 {
- width: 50%;
- }
- .col-lg-5 {
- width: 41.66666667%;
- }
- .col-lg-4 {
- width: 33.33333333%;
- }
- .col-lg-3 {
- width: 25%;
- }
- .col-lg-2 {
- width: 16.66666667%;
- }
- .col-lg-1 {
- width: 8.33333333%;
- }
- .col-lg-pull-12 {
- right: 100%;
- }
- .col-lg-pull-11 {
- right: 91.66666667%;
- }
- .col-lg-pull-10 {
- right: 83.33333333%;
- }
- .col-lg-pull-9 {
- right: 75%;
- }
- .col-lg-pull-8 {
- right: 66.66666667%;
- }
- .col-lg-pull-7 {
- right: 58.33333333%;
- }
- .col-lg-pull-6 {
- right: 50%;
- }
- .col-lg-pull-5 {
- right: 41.66666667%;
- }
- .col-lg-pull-4 {
- right: 33.33333333%;
- }
- .col-lg-pull-3 {
- right: 25%;
- }
- .col-lg-pull-2 {
- right: 16.66666667%;
- }
- .col-lg-pull-1 {
- right: 8.33333333%;
- }
- .col-lg-pull-0 {
- right: 0;
- }
- .col-lg-push-12 {
- left: 100%;
- }
- .col-lg-push-11 {
- left: 91.66666667%;
- }
- .col-lg-push-10 {
- left: 83.33333333%;
- }
- .col-lg-push-9 {
- left: 75%;
- }
- .col-lg-push-8 {
- left: 66.66666667%;
- }
- .col-lg-push-7 {
- left: 58.33333333%;
- }
- .col-lg-push-6 {
- left: 50%;
- }
- .col-lg-push-5 {
- left: 41.66666667%;
- }
- .col-lg-push-4 {
- left: 33.33333333%;
- }
- .col-lg-push-3 {
- left: 25%;
- }
- .col-lg-push-2 {
- left: 16.66666667%;
- }
- .col-lg-push-1 {
- left: 8.33333333%;
- }
- .col-lg-push-0 {
- left: 0;
- }
- .col-lg-offset-12 {
- margin-left: 100%;
- }
- .col-lg-offset-11 {
- margin-left: 91.66666667%;
- }
- .col-lg-offset-10 {
- margin-left: 83.33333333%;
- }
- .col-lg-offset-9 {
- margin-left: 75%;
- }
- .col-lg-offset-8 {
- margin-left: 66.66666667%;
- }
- .col-lg-offset-7 {
- margin-left: 58.33333333%;
- }
- .col-lg-offset-6 {
- margin-left: 50%;
- }
- .col-lg-offset-5 {
- margin-left: 41.66666667%;
- }
- .col-lg-offset-4 {
- margin-left: 33.33333333%;
- }
- .col-lg-offset-3 {
- margin-left: 25%;
- }
- .col-lg-offset-2 {
- margin-left: 16.66666667%;
- }
- .col-lg-offset-1 {
- margin-left: 8.33333333%;
- }
- .col-lg-offset-0 {
- margin-left: 0;
- }
+.glyphicon-link:before {
+ content: "\e144";
}
-table {
- max-width: 100%;
- background-color: transparent;
+.glyphicon-phone:before {
+ content: "\e145";
}
-th {
- text-align: left;
+.glyphicon-pushpin:before {
+ content: "\e146";
}
-.table {
- width: 100%;
- margin-bottom: 20px;
+.glyphicon-usd:before {
+ content: "\e148";
}
-.table > thead > tr > th,
-.table > tbody > tr > th,
-.table > tfoot > tr > th,
-.table > thead > tr > td,
-.table > tbody > tr > td,
-.table > tfoot > tr > td {
- padding: 8px;
- line-height: 1.42857143;
- vertical-align: top;
- border-top: 1px solid #ddd;
+.glyphicon-gbp:before {
+ content: "\e149";
}
-.table > thead > tr > th {
- vertical-align: bottom;
- border-bottom: 2px solid #ddd;
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
}
-.table > caption + thead > tr:first-child > th,
-.table > colgroup + thead > tr:first-child > th,
-.table > thead:first-child > tr:first-child > th,
-.table > caption + thead > tr:first-child > td,
-.table > colgroup + thead > tr:first-child > td,
-.table > thead:first-child > tr:first-child > td {
- border-top: 0;
+.glyphicon-expand:before {
+ content: "\e158";
}
-.table > tbody + tbody {
- border-top: 2px solid #ddd;
+.glyphicon-collapse-down:before {
+ content: "\e159";
}
-.table .table {
- background-color: #fff;
+.glyphicon-collapse-up:before {
+ content: "\e160";
}
-.table-condensed > thead > tr > th,
-.table-condensed > tbody > tr > th,
-.table-condensed > tfoot > tr > th,
-.table-condensed > thead > tr > td,
-.table-condensed > tbody > tr > td,
-.table-condensed > tfoot > tr > td {
- padding: 5px;
+.glyphicon-log-in:before {
+ content: "\e161";
}
-.table-bordered {
- border: 1px solid #ddd;
+.glyphicon-flash:before {
+ content: "\e162";
}
-.table-bordered > thead > tr > th,
-.table-bordered > tbody > tr > th,
-.table-bordered > tfoot > tr > th,
-.table-bordered > thead > tr > td,
-.table-bordered > tbody > tr > td,
-.table-bordered > tfoot > tr > td {
- border: 1px solid #ddd;
+.glyphicon-log-out:before {
+ content: "\e163";
}
-.table-bordered > thead > tr > th,
-.table-bordered > thead > tr > td {
- border-bottom-width: 2px;
+.glyphicon-new-window:before {
+ content: "\e164";
}
-.table-striped > tbody > tr:nth-child(odd) > td,
-.table-striped > tbody > tr:nth-child(odd) > th {
- background-color: #f9f9f9;
+.glyphicon-record:before {
+ content: "\e165";
}
-.table-hover > tbody > tr:hover > td,
-.table-hover > tbody > tr:hover > th {
- background-color: #f5f5f5;
+.glyphicon-save:before {
+ content: "\e166";
}
-table col[class*="col-"] {
- position: static;
- display: table-column;
- float: none;
+.glyphicon-open:before {
+ content: "\e167";
}
-table td[class*="col-"],
-table th[class*="col-"] {
- position: static;
- display: table-cell;
- float: none;
+.glyphicon-saved:before {
+ content: "\e168";
}
-.table > thead > tr > td.active,
-.table > tbody > tr > td.active,
-.table > tfoot > tr > td.active,
-.table > thead > tr > th.active,
-.table > tbody > tr > th.active,
-.table > tfoot > tr > th.active,
-.table > thead > tr.active > td,
-.table > tbody > tr.active > td,
-.table > tfoot > tr.active > td,
-.table > thead > tr.active > th,
-.table > tbody > tr.active > th,
-.table > tfoot > tr.active > th {
- background-color: #f5f5f5;
+.glyphicon-import:before {
+ content: "\e169";
}
-.table-hover > tbody > tr > td.active:hover,
-.table-hover > tbody > tr > th.active:hover,
-.table-hover > tbody > tr.active:hover > td,
-.table-hover > tbody > tr.active:hover > th {
- background-color: #e8e8e8;
+.glyphicon-export:before {
+ content: "\e170";
}
-.table > thead > tr > td.success,
-.table > tbody > tr > td.success,
-.table > tfoot > tr > td.success,
-.table > thead > tr > th.success,
-.table > tbody > tr > th.success,
-.table > tfoot > tr > th.success,
-.table > thead > tr.success > td,
-.table > tbody > tr.success > td,
-.table > tfoot > tr.success > td,
-.table > thead > tr.success > th,
-.table > tbody > tr.success > th,
-.table > tfoot > tr.success > th {
- background-color: #dff0d8;
+.glyphicon-send:before {
+ content: "\e171";
}
-.table-hover > tbody > tr > td.success:hover,
-.table-hover > tbody > tr > th.success:hover,
-.table-hover > tbody > tr.success:hover > td,
-.table-hover > tbody > tr.success:hover > th {
- background-color: #d0e9c6;
+.glyphicon-floppy-disk:before {
+ content: "\e172";
}
-.table > thead > tr > td.info,
-.table > tbody > tr > td.info,
-.table > tfoot > tr > td.info,
-.table > thead > tr > th.info,
-.table > tbody > tr > th.info,
-.table > tfoot > tr > th.info,
-.table > thead > tr.info > td,
-.table > tbody > tr.info > td,
-.table > tfoot > tr.info > td,
-.table > thead > tr.info > th,
-.table > tbody > tr.info > th,
-.table > tfoot > tr.info > th {
- background-color: #d9edf7;
+.glyphicon-floppy-saved:before {
+ content: "\e173";
}
-.table-hover > tbody > tr > td.info:hover,
-.table-hover > tbody > tr > th.info:hover,
-.table-hover > tbody > tr.info:hover > td,
-.table-hover > tbody > tr.info:hover > th {
- background-color: #c4e3f3;
+.glyphicon-floppy-remove:before {
+ content: "\e174";
}
-.table > thead > tr > td.warning,
-.table > tbody > tr > td.warning,
-.table > tfoot > tr > td.warning,
-.table > thead > tr > th.warning,
-.table > tbody > tr > th.warning,
-.table > tfoot > tr > th.warning,
-.table > thead > tr.warning > td,
-.table > tbody > tr.warning > td,
-.table > tfoot > tr.warning > td,
-.table > thead > tr.warning > th,
-.table > tbody > tr.warning > th,
-.table > tfoot > tr.warning > th {
- background-color: #fcf8e3;
+.glyphicon-floppy-save:before {
+ content: "\e175";
}
-.table-hover > tbody > tr > td.warning:hover,
-.table-hover > tbody > tr > th.warning:hover,
-.table-hover > tbody > tr.warning:hover > td,
-.table-hover > tbody > tr.warning:hover > th {
- background-color: #faf2cc;
+.glyphicon-floppy-open:before {
+ content: "\e176";
}
-.table > thead > tr > td.danger,
-.table > tbody > tr > td.danger,
-.table > tfoot > tr > td.danger,
-.table > thead > tr > th.danger,
-.table > tbody > tr > th.danger,
-.table > tfoot > tr > th.danger,
-.table > thead > tr.danger > td,
-.table > tbody > tr.danger > td,
-.table > tfoot > tr.danger > td,
-.table > thead > tr.danger > th,
-.table > tbody > tr.danger > th,
-.table > tfoot > tr.danger > th {
- background-color: #f2dede;
+.glyphicon-credit-card:before {
+ content: "\e177";
}
-.table-hover > tbody > tr > td.danger:hover,
-.table-hover > tbody > tr > th.danger:hover,
-.table-hover > tbody > tr.danger:hover > td,
-.table-hover > tbody > tr.danger:hover > th {
- background-color: #ebcccc;
+.glyphicon-transfer:before {
+ content: "\e178";
}
-@media (max-width: 767px) {
- .table-responsive {
- width: 100%;
- margin-bottom: 15px;
- overflow-x: scroll;
- overflow-y: hidden;
- -webkit-overflow-scrolling: touch;
- -ms-overflow-style: -ms-autohiding-scrollbar;
- border: 1px solid #ddd;
- }
- .table-responsive > .table {
- margin-bottom: 0;
- }
- .table-responsive > .table > thead > tr > th,
- .table-responsive > .table > tbody > tr > th,
- .table-responsive > .table > tfoot > tr > th,
- .table-responsive > .table > thead > tr > td,
- .table-responsive > .table > tbody > tr > td,
- .table-responsive > .table > tfoot > tr > td {
- white-space: nowrap;
- }
- .table-responsive > .table-bordered {
- border: 0;
- }
- .table-responsive > .table-bordered > thead > tr > th:first-child,
- .table-responsive > .table-bordered > tbody > tr > th:first-child,
- .table-responsive > .table-bordered > tfoot > tr > th:first-child,
- .table-responsive > .table-bordered > thead > tr > td:first-child,
- .table-responsive > .table-bordered > tbody > tr > td:first-child,
- .table-responsive > .table-bordered > tfoot > tr > td:first-child {
- border-left: 0;
- }
- .table-responsive > .table-bordered > thead > tr > th:last-child,
- .table-responsive > .table-bordered > tbody > tr > th:last-child,
- .table-responsive > .table-bordered > tfoot > tr > th:last-child,
- .table-responsive > .table-bordered > thead > tr > td:last-child,
- .table-responsive > .table-bordered > tbody > tr > td:last-child,
- .table-responsive > .table-bordered > tfoot > tr > td:last-child {
- border-right: 0;
- }
- .table-responsive > .table-bordered > tbody > tr:last-child > th,
- .table-responsive > .table-bordered > tfoot > tr:last-child > th,
- .table-responsive > .table-bordered > tbody > tr:last-child > td,
- .table-responsive > .table-bordered > tfoot > tr:last-child > td {
- border-bottom: 0;
- }
+.glyphicon-cutlery:before {
+ content: "\e179";
}
-fieldset {
- min-width: 0;
- padding: 0;
- margin: 0;
- border: 0;
+.glyphicon-header:before {
+ content: "\e180";
}
-legend {
- display: block;
- width: 100%;
- padding: 0;
- margin-bottom: 20px;
- font-size: 21px;
- line-height: inherit;
- color: #333;
- border: 0;
- border-bottom: 1px solid #e5e5e5;
+.glyphicon-compressed:before {
+ content: "\e181";
}
-label {
- display: inline-block;
- margin-bottom: 5px;
- font-weight: bold;
+.glyphicon-earphone:before {
+ content: "\e182";
}
-input[type="search"] {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+.glyphicon-phone-alt:before {
+ content: "\e183";
}
-input[type="radio"],
-input[type="checkbox"] {
- margin: 4px 0 0;
- margin-top: 1px \9;
- /* IE8-9 */
- line-height: normal;
+.glyphicon-tower:before {
+ content: "\e184";
}
-input[type="file"] {
- display: block;
+.glyphicon-stats:before {
+ content: "\e185";
}
-input[type="range"] {
- display: block;
- width: 100%;
+.glyphicon-sd-video:before {
+ content: "\e186";
}
-select[multiple],
-select[size] {
- height: auto;
+.glyphicon-hd-video:before {
+ content: "\e187";
}
-input[type="file"]:focus,
-input[type="radio"]:focus,
-input[type="checkbox"]:focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
+.glyphicon-subtitles:before {
+ content: "\e188";
}
-output {
- display: block;
- padding-top: 7px;
- font-size: 14px;
- line-height: 1.42857143;
- color: #555;
+.glyphicon-sound-stereo:before {
+ content: "\e189";
}
-.form-control {
- display: block;
- width: 100%;
- height: 34px;
- padding: 6px 12px;
- font-size: 14px;
- line-height: 1.42857143;
- color: #555;
- background-color: #fff;
- background-image: none;
- border: 1px solid #ccc;
- border-radius: 4px;
+.glyphicon-sound-dolby:before {
+ content: "\e190";
}
-.form-control:focus {
- border-color: #000;
- outline: 0;
+.glyphicon-sound-5-1:before {
+ content: "\e191";
}
-.form-control:-moz-placeholder {
- color: #999;
+.glyphicon-sound-6-1:before {
+ content: "\e192";
}
-.form-control::-moz-placeholder {
- color: #999;
- opacity: 1;
+.glyphicon-sound-7-1:before {
+ content: "\e193";
}
-.form-control:-ms-input-placeholder {
- color: #999;
+.glyphicon-copyright-mark:before {
+ content: "\e194";
}
-.form-control::-webkit-input-placeholder {
- color: #999;
+.glyphicon-registration-mark:before {
+ content: "\e195";
}
-.form-control[disabled],
-.form-control[readonly],
-fieldset[disabled] .form-control {
- cursor: not-allowed;
- background-color: #eee;
- opacity: 1;
+.glyphicon-cloud-download:before {
+ content: "\e197";
}
-textarea.form-control {
- height: auto;
+.glyphicon-cloud-upload:before {
+ content: "\e198";
}
-input[type="date"] {
- line-height: 34px;
+.glyphicon-tree-conifer:before {
+ content: "\e199";
}
-.form-group {
- margin-bottom: 15px;
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
}
-.radio,
-.checkbox {
- display: block;
- min-height: 20px;
- padding-left: 20px;
- margin-top: 10px;
- margin-bottom: 10px;
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
-.radio label,
-.checkbox label {
- display: inline;
- font-weight: normal;
- cursor: pointer;
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
-.radio input[type="radio"],
-.radio-inline input[type="radio"],
-.checkbox input[type="checkbox"],
-.checkbox-inline input[type="checkbox"] {
- float: left;
- margin-left: -20px;
+html {
+ font-size: 62.5%;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
-.radio + .radio,
-.checkbox + .checkbox {
- margin-top: -5px;
+body {
+ font-family: "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
}
-.radio-inline,
-.checkbox-inline {
- display: inline-block;
- padding-left: 20px;
- margin-bottom: 0;
- font-weight: normal;
- vertical-align: middle;
- cursor: pointer;
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
}
-.radio-inline + .radio-inline,
-.checkbox-inline + .checkbox-inline {
- margin-top: 0;
- margin-left: 10px;
+a {
+ color: #000;
+ text-decoration: none;
}
-input[type="radio"][disabled],
-input[type="checkbox"][disabled],
-.radio[disabled],
-.radio-inline[disabled],
-.checkbox[disabled],
-.checkbox-inline[disabled],
-fieldset[disabled] input[type="radio"],
-fieldset[disabled] input[type="checkbox"],
-fieldset[disabled] .radio,
-fieldset[disabled] .radio-inline,
-fieldset[disabled] .checkbox,
-fieldset[disabled] .checkbox-inline {
- cursor: not-allowed;
+a:hover,
+a:focus {
+ color: #000;
+ text-decoration: underline;
}
-.input-sm {
- height: 30px;
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
}
-select.input-sm {
- height: 30px;
- line-height: 30px;
+figure {
+ margin: 0;
}
-textarea.input-sm,
-select[multiple].input-sm {
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
height: auto;
}
-.input-lg {
- height: 46px;
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.33;
+.img-rounded {
border-radius: 6px;
}
-select.input-lg {
- height: 46px;
- line-height: 46px;
-}
-textarea.input-lg,
-select[multiple].input-lg {
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
}
-.has-feedback {
- position: relative;
+.img-circle {
+ border-radius: 50%;
}
-.has-feedback .form-control {
- padding-right: 42.5px;
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
}
-.has-feedback .form-control-feedback {
+.sr-only {
position: absolute;
- top: 25px;
- right: 0;
- display: block;
- width: 34px;
- height: 34px;
- line-height: 34px;
- text-align: center;
-}
-.has-success .help-block,
-.has-success .control-label,
-.has-success .radio,
-.has-success .checkbox,
-.has-success .radio-inline,
-.has-success .checkbox-inline {
- color: #3c763d;
-}
-.has-success .form-control {
- border-color: #3c763d;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
}
-.has-success .form-control:focus {
- border-color: #2b542c;
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
}
-.has-success .input-group-addon {
- color: #3c763d;
- background-color: #dff0d8;
- border-color: #3c763d;
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
}
-.has-success .form-control-feedback {
- color: #3c763d;
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #999;
}
-.has-warning .help-block,
-.has-warning .control-label,
-.has-warning .radio,
-.has-warning .checkbox,
-.has-warning .radio-inline,
-.has-warning .checkbox-inline {
- color: #f39c12;
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
}
-.has-warning .form-control {
- border-color: #f39c12;
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
}
-.has-warning .form-control:focus {
- border-color: #c87f0a;
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
}
-.has-warning .input-group-addon {
- color: #f39c12;
- background-color: #fcf8e3;
- border-color: #f39c12;
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
}
-.has-warning .form-control-feedback {
- color: #f39c12;
+h1,
+.h1 {
+ font-size: 36px;
}
-.has-error .help-block,
-.has-error .control-label,
-.has-error .radio,
-.has-error .checkbox,
-.has-error .radio-inline,
-.has-error .checkbox-inline {
- color: #c0392b;
+h2,
+.h2 {
+ font-size: 30px;
}
-.has-error .form-control {
- border-color: #c0392b;
+h3,
+.h3 {
+ font-size: 24px;
}
-.has-error .form-control:focus {
- border-color: #962d22;
+h4,
+.h4 {
+ font-size: 18px;
}
-.has-error .input-group-addon {
- color: #c0392b;
- background-color: #f2dede;
- border-color: #c0392b;
+h5,
+.h5 {
+ font-size: 14px;
}
-.has-error .form-control-feedback {
- color: #c0392b;
+h6,
+.h6 {
+ font-size: 12px;
}
-.form-control-static {
- margin-bottom: 0;
+p {
+ margin: 0 0 10px;
}
-.help-block {
- display: block;
- margin-top: 5px;
- margin-bottom: 10px;
- color: #737373;
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
}
@media (min-width: 768px) {
- .form-inline .form-group {
- display: inline-block;
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .form-control {
- display: inline-block;
- width: auto;
- vertical-align: middle;
- }
- .form-inline .control-label {
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .radio,
- .form-inline .checkbox {
- display: inline-block;
- padding-left: 0;
- margin-top: 0;
- margin-bottom: 0;
- vertical-align: middle;
- }
- .form-inline .radio input[type="radio"],
- .form-inline .checkbox input[type="checkbox"] {
- float: none;
- margin-left: 0;
- }
- .form-inline .has-feedback .form-control-feedback {
- top: 0;
+ .lead {
+ font-size: 21px;
}
}
-.form-horizontal .control-label,
-.form-horizontal .radio,
-.form-horizontal .checkbox,
-.form-horizontal .radio-inline,
-.form-horizontal .checkbox-inline {
- padding-top: 7px;
- margin-top: 0;
- margin-bottom: 0;
-}
-.form-horizontal .radio,
-.form-horizontal .checkbox {
- min-height: 27px;
+small,
+.small {
+ font-size: 85%;
}
-.form-horizontal .form-group {
- margin-right: -15px;
- margin-left: -15px;
+cite {
+ font-style: normal;
}
-.form-horizontal .form-control-static {
- padding-top: 7px;
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
}
-@media (min-width: 768px) {
- .form-horizontal .control-label {
- text-align: right;
- }
+.text-left {
+ text-align: left;
}
-.form-horizontal .has-feedback .form-control-feedback {
- top: 0;
- right: 15px;
+.text-right {
+ text-align: right;
}
-.btn {
- display: inline-block;
- padding: 6px 12px;
- margin-bottom: 0;
- font-size: 14px;
- font-weight: normal;
- line-height: 1.42857143;
+.text-center {
text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- -o-user-select: none;
- user-select: none;
- background-image: none;
- border: 1px solid transparent;
- border-radius: 4px;
}
-.btn:focus {
- outline: thin dotted;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
+.text-justify {
+ text-align: justify;
+}
+.text-muted {
+ color: #999;
+}
+.text-primary {
+ color: #2980b9;
+}
+a.text-primary:hover {
+ color: #20638f;
}
-.btn:hover,
-.btn:focus {
- color: #333;
- text-decoration: none;
+.text-success {
+ color: #3c763d;
}
-.btn:active,
-.btn.active {
- background-image: none;
- outline: 0;
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+a.text-success:hover {
+ color: #2b542c;
}
-.btn.disabled,
-.btn[disabled],
-fieldset[disabled] .btn {
- pointer-events: none;
- cursor: not-allowed;
- filter: alpha(opacity=65);
- -webkit-box-shadow: none;
- box-shadow: none;
- opacity: .65;
+.text-info {
+ color: #31708f;
}
-.btn-default {
- color: #333;
- background-color: #fff;
- border-color: #ccc;
+a.text-info:hover {
+ color: #245269;
}
-.btn-default:hover,
-.btn-default:focus,
-.btn-default:active,
-.btn-default.active,
-.open .dropdown-toggle.btn-default {
- color: #333;
- background-color: #ebebeb;
- border-color: #adadad;
+.text-warning {
+ color: #f39c12;
}
-.btn-default:active,
-.btn-default.active,
-.open .dropdown-toggle.btn-default {
- background-image: none;
+a.text-warning:hover {
+ color: #c87f0a;
}
-.btn-default.disabled,
-.btn-default[disabled],
-fieldset[disabled] .btn-default,
-.btn-default.disabled:hover,
-.btn-default[disabled]:hover,
-fieldset[disabled] .btn-default:hover,
-.btn-default.disabled:focus,
-.btn-default[disabled]:focus,
-fieldset[disabled] .btn-default:focus,
-.btn-default.disabled:active,
-.btn-default[disabled]:active,
-fieldset[disabled] .btn-default:active,
-.btn-default.disabled.active,
-.btn-default[disabled].active,
-fieldset[disabled] .btn-default.active {
- background-color: #fff;
- border-color: #ccc;
+.text-danger {
+ color: #c0392b;
}
-.btn-default .badge {
- color: #fff;
- background-color: #333;
+a.text-danger:hover {
+ color: #962d22;
}
-.btn-primary {
+.bg-primary {
color: #fff;
background-color: #2980b9;
- border-color: #2472a4;
}
-.btn-primary:hover,
-.btn-primary:focus,
-.btn-primary:active,
-.btn-primary.active,
-.open .dropdown-toggle.btn-primary {
- color: #fff;
- background-color: #226998;
- border-color: #194f72;
+a.bg-primary:hover {
+ background-color: #20638f;
}
-.btn-primary:active,
-.btn-primary.active,
-.open .dropdown-toggle.btn-primary {
- background-image: none;
+.bg-success {
+ background-color: #dff0d8;
}
-.btn-primary.disabled,
-.btn-primary[disabled],
-fieldset[disabled] .btn-primary,
-.btn-primary.disabled:hover,
-.btn-primary[disabled]:hover,
-fieldset[disabled] .btn-primary:hover,
-.btn-primary.disabled:focus,
-.btn-primary[disabled]:focus,
-fieldset[disabled] .btn-primary:focus,
-.btn-primary.disabled:active,
-.btn-primary[disabled]:active,
-fieldset[disabled] .btn-primary:active,
-.btn-primary.disabled.active,
-.btn-primary[disabled].active,
-fieldset[disabled] .btn-primary.active {
- background-color: #2980b9;
- border-color: #2472a4;
+a.bg-success:hover {
+ background-color: #c1e2b3;
}
-.btn-primary .badge {
- color: #2980b9;
- background-color: #fff;
+.bg-info {
+ background-color: #d9edf7;
}
-.btn-success {
- color: #fff;
- background-color: #5cb85c;
- border-color: #4cae4c;
+a.bg-info:hover {
+ background-color: #afd9ee;
}
-.btn-success:hover,
-.btn-success:focus,
-.btn-success:active,
-.btn-success.active,
-.open .dropdown-toggle.btn-success {
- color: #fff;
- background-color: #47a447;
- border-color: #398439;
+.bg-warning {
+ background-color: #fcf8e3;
}
-.btn-success:active,
-.btn-success.active,
-.open .dropdown-toggle.btn-success {
- background-image: none;
+a.bg-warning:hover {
+ background-color: #f7ecb5;
}
-.btn-success.disabled,
-.btn-success[disabled],
-fieldset[disabled] .btn-success,
-.btn-success.disabled:hover,
-.btn-success[disabled]:hover,
-fieldset[disabled] .btn-success:hover,
-.btn-success.disabled:focus,
-.btn-success[disabled]:focus,
-fieldset[disabled] .btn-success:focus,
-.btn-success.disabled:active,
-.btn-success[disabled]:active,
-fieldset[disabled] .btn-success:active,
-.btn-success.disabled.active,
-.btn-success[disabled].active,
-fieldset[disabled] .btn-success.active {
- background-color: #5cb85c;
- border-color: #4cae4c;
+.bg-danger {
+ background-color: #f2dede;
}
-.btn-success .badge {
- color: #5cb85c;
- background-color: #fff;
+a.bg-danger:hover {
+ background-color: #e4b9b9;
}
-.btn-info {
- color: #fff;
- background-color: #5bc0de;
- border-color: #46b8da;
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
}
-.btn-info:hover,
-.btn-info:focus,
-.btn-info:active,
-.btn-info.active,
-.open .dropdown-toggle.btn-info {
- color: #fff;
- background-color: #39b3d7;
- border-color: #269abc;
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
}
-.btn-info:active,
-.btn-info.active,
-.open .dropdown-toggle.btn-info {
- background-image: none;
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
}
-.btn-info.disabled,
-.btn-info[disabled],
-fieldset[disabled] .btn-info,
-.btn-info.disabled:hover,
-.btn-info[disabled]:hover,
-fieldset[disabled] .btn-info:hover,
-.btn-info.disabled:focus,
-.btn-info[disabled]:focus,
-fieldset[disabled] .btn-info:focus,
-.btn-info.disabled:active,
-.btn-info[disabled]:active,
-fieldset[disabled] .btn-info:active,
-.btn-info.disabled.active,
-.btn-info[disabled].active,
-fieldset[disabled] .btn-info.active {
- background-color: #5bc0de;
- border-color: #46b8da;
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
}
-.btn-info .badge {
- color: #5bc0de;
- background-color: #fff;
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
}
-.btn-warning {
- color: #fff;
- background-color: #f39c12;
- border-color: #e08e0b;
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
}
-.btn-warning:hover,
-.btn-warning:focus,
-.btn-warning:active,
-.btn-warning.active,
-.open .dropdown-toggle.btn-warning {
- color: #fff;
- background-color: #d2850b;
- border-color: #a66908;
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
}
-.btn-warning:active,
-.btn-warning.active,
-.open .dropdown-toggle.btn-warning {
- background-image: none;
+dt,
+dd {
+ line-height: 1.42857143;
}
-.btn-warning.disabled,
-.btn-warning[disabled],
-fieldset[disabled] .btn-warning,
-.btn-warning.disabled:hover,
-.btn-warning[disabled]:hover,
-fieldset[disabled] .btn-warning:hover,
-.btn-warning.disabled:focus,
-.btn-warning[disabled]:focus,
-fieldset[disabled] .btn-warning:focus,
-.btn-warning.disabled:active,
-.btn-warning[disabled]:active,
-fieldset[disabled] .btn-warning:active,
-.btn-warning.disabled.active,
-.btn-warning[disabled].active,
-fieldset[disabled] .btn-warning.active {
- background-color: #f39c12;
- border-color: #e08e0b;
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
}
-.btn-warning .badge {
- color: #f39c12;
- background-color: #fff;
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #999;
}
-.btn-danger {
- color: #fff;
- background-color: #c0392b;
- border-color: #ab3326;
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
}
-.btn-danger:hover,
-.btn-danger:focus,
-.btn-danger:active,
-.btn-danger.active,
-.open .dropdown-toggle.btn-danger {
- color: #fff;
- background-color: #9f2f24;
- border-color: #79241b;
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
}
-.btn-danger:active,
-.btn-danger.active,
-.open .dropdown-toggle.btn-danger {
- background-image: none;
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
}
-.btn-danger.disabled,
-.btn-danger[disabled],
-fieldset[disabled] .btn-danger,
-.btn-danger.disabled:hover,
-.btn-danger[disabled]:hover,
-fieldset[disabled] .btn-danger:hover,
-.btn-danger.disabled:focus,
-.btn-danger[disabled]:focus,
-fieldset[disabled] .btn-danger:focus,
-.btn-danger.disabled:active,
-.btn-danger[disabled]:active,
-fieldset[disabled] .btn-danger:active,
-.btn-danger.disabled.active,
-.btn-danger[disabled].active,
-fieldset[disabled] .btn-danger.active {
- background-color: #c0392b;
- border-color: #ab3326;
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #999;
}
-.btn-danger .badge {
- color: #c0392b;
- background-color: #fff;
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
}
-.btn-link {
- font-weight: normal;
- color: #2980b9;
- cursor: pointer;
- border-radius: 0;
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
}
-.btn-link,
-.btn-link:active,
-.btn-link[disabled],
-fieldset[disabled] .btn-link {
- background-color: transparent;
- -webkit-box-shadow: none;
- box-shadow: none;
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
}
-.btn-link,
-.btn-link:hover,
-.btn-link:focus,
-.btn-link:active {
- border-color: transparent;
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
}
-.btn-link:hover,
-.btn-link:focus {
- color: #1b557a;
- text-decoration: underline;
- background-color: transparent;
+blockquote:before,
+blockquote:after {
+ content: "";
}
-.btn-link[disabled]:hover,
-fieldset[disabled] .btn-link:hover,
-.btn-link[disabled]:focus,
-fieldset[disabled] .btn-link:focus {
- color: #999;
- text-decoration: none;
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
}
-.btn-lg {
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.33;
- border-radius: 6px;
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}
-.btn-sm {
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
}
-.btn-xs {
- padding: 1px 5px;
- font-size: 12px;
- line-height: 1.5;
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
}
-.btn-block {
+pre {
display: block;
- width: 100%;
- padding-right: 0;
- padding-left: 0;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
}
-.btn-block + .btn-block {
- margin-top: 5px;
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
}
-input[type="submit"].btn-block,
-input[type="reset"].btn-block,
-input[type="button"].btn-block {
- width: 100%;
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
}
-.fade {
- opacity: 0;
- -webkit-transition: opacity .15s linear;
- transition: opacity .15s linear;
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
}
-.fade.in {
- opacity: 1;
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
}
-.collapse {
- display: none;
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
}
-.collapse.in {
- display: block;
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
}
-.collapsing {
- position: relative;
- height: 0;
- overflow: hidden;
- -webkit-transition: height .35s ease;
- transition: height .35s ease;
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
}
-@font-face {
- font-family: 'Glyphicons Halflings';
-
- src: url('../fonts/glyphicons-halflings-regular.eot');
- src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
}
-.glyphicon {
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
- top: 1px;
- display: inline-block;
- font-family: 'Glyphicons Halflings';
- font-style: normal;
- font-weight: normal;
- line-height: 1;
-
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
}
-.glyphicon-asterisk:before {
- content: "\2a";
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
}
-.glyphicon-plus:before {
- content: "\2b";
+.col-xs-12 {
+ width: 100%;
}
-.glyphicon-euro:before {
- content: "\20ac";
+.col-xs-11 {
+ width: 91.66666667%;
}
-.glyphicon-minus:before {
- content: "\2212";
+.col-xs-10 {
+ width: 83.33333333%;
}
-.glyphicon-cloud:before {
- content: "\2601";
+.col-xs-9 {
+ width: 75%;
}
-.glyphicon-envelope:before {
- content: "\2709";
+.col-xs-8 {
+ width: 66.66666667%;
}
-.glyphicon-pencil:before {
- content: "\270f";
+.col-xs-7 {
+ width: 58.33333333%;
}
-.glyphicon-glass:before {
- content: "\e001";
+.col-xs-6 {
+ width: 50%;
}
-.glyphicon-music:before {
- content: "\e002";
+.col-xs-5 {
+ width: 41.66666667%;
}
-.glyphicon-search:before {
- content: "\e003";
+.col-xs-4 {
+ width: 33.33333333%;
}
-.glyphicon-heart:before {
- content: "\e005";
+.col-xs-3 {
+ width: 25%;
}
-.glyphicon-star:before {
- content: "\e006";
+.col-xs-2 {
+ width: 16.66666667%;
}
-.glyphicon-star-empty:before {
- content: "\e007";
+.col-xs-1 {
+ width: 8.33333333%;
}
-.glyphicon-user:before {
- content: "\e008";
+.col-xs-pull-12 {
+ right: 100%;
}
-.glyphicon-film:before {
- content: "\e009";
+.col-xs-pull-11 {
+ right: 91.66666667%;
}
-.glyphicon-th-large:before {
- content: "\e010";
+.col-xs-pull-10 {
+ right: 83.33333333%;
}
-.glyphicon-th:before {
- content: "\e011";
+.col-xs-pull-9 {
+ right: 75%;
}
-.glyphicon-th-list:before {
- content: "\e012";
+.col-xs-pull-8 {
+ right: 66.66666667%;
}
-.glyphicon-ok:before {
- content: "\e013";
+.col-xs-pull-7 {
+ right: 58.33333333%;
}
-.glyphicon-remove:before {
- content: "\e014";
+.col-xs-pull-6 {
+ right: 50%;
}
-.glyphicon-zoom-in:before {
- content: "\e015";
+.col-xs-pull-5 {
+ right: 41.66666667%;
}
-.glyphicon-zoom-out:before {
- content: "\e016";
+.col-xs-pull-4 {
+ right: 33.33333333%;
}
-.glyphicon-off:before {
- content: "\e017";
+.col-xs-pull-3 {
+ right: 25%;
}
-.glyphicon-signal:before {
- content: "\e018";
+.col-xs-pull-2 {
+ right: 16.66666667%;
}
-.glyphicon-cog:before {
- content: "\e019";
+.col-xs-pull-1 {
+ right: 8.33333333%;
}
-.glyphicon-trash:before {
- content: "\e020";
+.col-xs-pull-0 {
+ right: auto;
}
-.glyphicon-home:before {
- content: "\e021";
+.col-xs-push-12 {
+ left: 100%;
}
-.glyphicon-file:before {
- content: "\e022";
+.col-xs-push-11 {
+ left: 91.66666667%;
}
-.glyphicon-time:before {
- content: "\e023";
+.col-xs-push-10 {
+ left: 83.33333333%;
}
-.glyphicon-road:before {
- content: "\e024";
+.col-xs-push-9 {
+ left: 75%;
}
-.glyphicon-download-alt:before {
- content: "\e025";
+.col-xs-push-8 {
+ left: 66.66666667%;
}
-.glyphicon-download:before {
- content: "\e026";
+.col-xs-push-7 {
+ left: 58.33333333%;
}
-.glyphicon-upload:before {
- content: "\e027";
+.col-xs-push-6 {
+ left: 50%;
}
-.glyphicon-inbox:before {
- content: "\e028";
+.col-xs-push-5 {
+ left: 41.66666667%;
}
-.glyphicon-play-circle:before {
- content: "\e029";
+.col-xs-push-4 {
+ left: 33.33333333%;
}
-.glyphicon-repeat:before {
- content: "\e030";
+.col-xs-push-3 {
+ left: 25%;
}
-.glyphicon-refresh:before {
- content: "\e031";
+.col-xs-push-2 {
+ left: 16.66666667%;
}
-.glyphicon-list-alt:before {
- content: "\e032";
+.col-xs-push-1 {
+ left: 8.33333333%;
}
-.glyphicon-lock:before {
- content: "\e033";
+.col-xs-push-0 {
+ left: auto;
}
-.glyphicon-flag:before {
- content: "\e034";
+.col-xs-offset-12 {
+ margin-left: 100%;
}
-.glyphicon-headphones:before {
- content: "\e035";
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
}
-.glyphicon-volume-off:before {
- content: "\e036";
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
}
-.glyphicon-volume-down:before {
- content: "\e037";
+.col-xs-offset-9 {
+ margin-left: 75%;
}
-.glyphicon-volume-up:before {
- content: "\e038";
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
}
-.glyphicon-qrcode:before {
- content: "\e039";
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
}
-.glyphicon-barcode:before {
- content: "\e040";
+.col-xs-offset-6 {
+ margin-left: 50%;
}
-.glyphicon-tag:before {
- content: "\e041";
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
}
-.glyphicon-tags:before {
- content: "\e042";
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
}
-.glyphicon-book:before {
- content: "\e043";
+.col-xs-offset-3 {
+ margin-left: 25%;
}
-.glyphicon-bookmark:before {
- content: "\e044";
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
}
-.glyphicon-print:before {
- content: "\e045";
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
}
-.glyphicon-camera:before {
- content: "\e046";
+.col-xs-offset-0 {
+ margin-left: 0;
}
-.glyphicon-font:before {
- content: "\e047";
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
}
-.glyphicon-bold:before {
- content: "\e048";
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
}
-.glyphicon-italic:before {
- content: "\e049";
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
}
-.glyphicon-text-height:before {
- content: "\e050";
+table {
+ max-width: 100%;
+ background-color: transparent;
}
-.glyphicon-text-width:before {
- content: "\e051";
+th {
+ text-align: left;
}
-.glyphicon-align-left:before {
- content: "\e052";
+.table {
+ width: 100%;
+ margin-bottom: 20px;
}
-.glyphicon-align-center:before {
- content: "\e053";
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
}
-.glyphicon-align-right:before {
- content: "\e054";
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
}
-.glyphicon-align-justify:before {
- content: "\e055";
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
}
-.glyphicon-list:before {
- content: "\e056";
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
}
-.glyphicon-indent-left:before {
- content: "\e057";
+.table .table {
+ background-color: #fff;
}
-.glyphicon-indent-right:before {
- content: "\e058";
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
}
-.glyphicon-facetime-video:before {
- content: "\e059";
+.table-bordered {
+ border: 1px solid #ddd;
}
-.glyphicon-picture:before {
- content: "\e060";
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
}
-.glyphicon-map-marker:before {
- content: "\e062";
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
}
-.glyphicon-adjust:before {
- content: "\e063";
+.table-striped > tbody > tr:nth-child(odd) > td,
+.table-striped > tbody > tr:nth-child(odd) > th {
+ background-color: #f9f9f9;
}
-.glyphicon-tint:before {
- content: "\e064";
+.table-hover > tbody > tr:hover > td,
+.table-hover > tbody > tr:hover > th {
+ background-color: #f5f5f5;
}
-.glyphicon-edit:before {
- content: "\e065";
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
}
-.glyphicon-share:before {
- content: "\e066";
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
}
-.glyphicon-check:before {
- content: "\e067";
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
}
-.glyphicon-move:before {
- content: "\e068";
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
}
-.glyphicon-step-backward:before {
- content: "\e069";
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
}
-.glyphicon-fast-backward:before {
- content: "\e070";
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
}
-.glyphicon-backward:before {
- content: "\e071";
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
}
-.glyphicon-play:before {
- content: "\e072";
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
}
-.glyphicon-pause:before {
- content: "\e073";
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
}
-.glyphicon-stop:before {
- content: "\e074";
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
}
-.glyphicon-forward:before {
- content: "\e075";
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
}
-.glyphicon-fast-forward:before {
- content: "\e076";
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
}
-.glyphicon-step-forward:before {
- content: "\e077";
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-x: scroll;
+ overflow-y: hidden;
+ -webkit-overflow-scrolling: touch;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
}
-.glyphicon-eject:before {
- content: "\e078";
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
}
-.glyphicon-chevron-left:before {
- content: "\e079";
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
}
-.glyphicon-chevron-right:before {
- content: "\e080";
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
}
-.glyphicon-plus-sign:before {
- content: "\e081";
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
-.glyphicon-minus-sign:before {
- content: "\e082";
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
}
-.glyphicon-remove-sign:before {
- content: "\e083";
+input[type="file"] {
+ display: block;
}
-.glyphicon-ok-sign:before {
- content: "\e084";
+input[type="range"] {
+ display: block;
+ width: 100%;
}
-.glyphicon-question-sign:before {
- content: "\e085";
+select[multiple],
+select[size] {
+ height: auto;
}
-.glyphicon-info-sign:before {
- content: "\e086";
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
}
-.glyphicon-screenshot:before {
- content: "\e087";
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
}
-.glyphicon-remove-circle:before {
- content: "\e088";
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
}
-.glyphicon-ok-circle:before {
- content: "\e089";
+.form-control:focus {
+ border-color: #000;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 0, 0, .6);
}
-.glyphicon-ban-circle:before {
- content: "\e090";
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
}
-.glyphicon-arrow-left:before {
- content: "\e091";
+.form-control:-ms-input-placeholder {
+ color: #999;
}
-.glyphicon-arrow-right:before {
- content: "\e092";
+.form-control::-webkit-input-placeholder {
+ color: #999;
}
-.glyphicon-arrow-up:before {
- content: "\e093";
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+ background-color: #eee;
+ opacity: 1;
}
-.glyphicon-arrow-down:before {
- content: "\e094";
+textarea.form-control {
+ height: auto;
}
-.glyphicon-share-alt:before {
- content: "\e095";
+input[type="search"] {
+ -webkit-appearance: none;
}
-.glyphicon-resize-full:before {
- content: "\e096";
+input[type="date"],
+input[type="time"],
+input[type="datetime-local"],
+input[type="month"] {
+ line-height: 34px;
+ line-height: 1.42857143 \0;
}
-.glyphicon-resize-small:before {
- content: "\e097";
+input[type="date"].input-sm,
+input[type="time"].input-sm,
+input[type="datetime-local"].input-sm,
+input[type="month"].input-sm {
+ line-height: 30px;
}
-.glyphicon-exclamation-sign:before {
- content: "\e101";
+input[type="date"].input-lg,
+input[type="time"].input-lg,
+input[type="datetime-local"].input-lg,
+input[type="month"].input-lg {
+ line-height: 46px;
}
-.glyphicon-gift:before {
- content: "\e102";
+.form-group {
+ margin-bottom: 15px;
}
-.glyphicon-leaf:before {
- content: "\e103";
+.radio,
+.checkbox {
+ display: block;
+ min-height: 20px;
+ margin-top: 10px;
+ margin-bottom: 10px;
}
-.glyphicon-fire:before {
- content: "\e104";
+.radio label,
+.checkbox label {
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
}
-.glyphicon-eye-open:before {
- content: "\e105";
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ float: left;
+ margin-left: -20px;
}
-.glyphicon-eye-close:before {
- content: "\e106";
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
}
-.glyphicon-warning-sign:before {
- content: "\e107";
+.radio-inline,
+.checkbox-inline {
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
}
-.glyphicon-plane:before {
- content: "\e108";
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
}
-.glyphicon-calendar:before {
- content: "\e109";
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+.radio[disabled],
+.radio-inline[disabled],
+.checkbox[disabled],
+.checkbox-inline[disabled],
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"],
+fieldset[disabled] .radio,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
}
-.glyphicon-random:before {
- content: "\e110";
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
}
-.glyphicon-comment:before {
- content: "\e111";
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
}
-.glyphicon-magnet:before {
- content: "\e112";
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
}
-.glyphicon-chevron-up:before {
- content: "\e113";
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.33;
+ border-radius: 6px;
}
-.glyphicon-chevron-down:before {
- content: "\e114";
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
}
-.glyphicon-retweet:before {
- content: "\e115";
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
}
-.glyphicon-shopping-cart:before {
- content: "\e116";
+.has-feedback {
+ position: relative;
}
-.glyphicon-folder-close:before {
- content: "\e117";
+.has-feedback .form-control {
+ padding-right: 42.5px;
}
-.glyphicon-folder-open:before {
- content: "\e118";
+.form-control-feedback {
+ position: absolute;
+ top: 25px;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
}
-.glyphicon-resize-vertical:before {
- content: "\e119";
+.input-lg + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
}
-.glyphicon-resize-horizontal:before {
- content: "\e120";
+.input-sm + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
}
-.glyphicon-hdd:before {
- content: "\e121";
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline {
+ color: #3c763d;
}
-.glyphicon-bullhorn:before {
- content: "\e122";
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
-.glyphicon-bell:before {
- content: "\e123";
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
}
-.glyphicon-certificate:before {
- content: "\e124";
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
}
-.glyphicon-thumbs-up:before {
- content: "\e125";
+.has-success .form-control-feedback {
+ color: #3c763d;
}
-.glyphicon-thumbs-down:before {
- content: "\e126";
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline {
+ color: #f39c12;
}
-.glyphicon-hand-right:before {
- content: "\e127";
+.has-warning .form-control {
+ border-color: #f39c12;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
-.glyphicon-hand-left:before {
- content: "\e128";
+.has-warning .form-control:focus {
+ border-color: #c87f0a;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #f8c573;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #f8c573;
}
-.glyphicon-hand-up:before {
- content: "\e129";
+.has-warning .input-group-addon {
+ color: #f39c12;
+ background-color: #fcf8e3;
+ border-color: #f39c12;
}
-.glyphicon-hand-down:before {
- content: "\e130";
+.has-warning .form-control-feedback {
+ color: #f39c12;
}
-.glyphicon-circle-arrow-right:before {
- content: "\e131";
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline {
+ color: #c0392b;
}
-.glyphicon-circle-arrow-left:before {
- content: "\e132";
+.has-error .form-control {
+ border-color: #c0392b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
-.glyphicon-circle-arrow-up:before {
- content: "\e133";
+.has-error .form-control:focus {
+ border-color: #962d22;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #df7c72;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #df7c72;
}
-.glyphicon-circle-arrow-down:before {
- content: "\e134";
+.has-error .input-group-addon {
+ color: #c0392b;
+ background-color: #f2dede;
+ border-color: #c0392b;
}
-.glyphicon-globe:before {
- content: "\e135";
+.has-error .form-control-feedback {
+ color: #c0392b;
}
-.glyphicon-wrench:before {
- content: "\e136";
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
}
-.glyphicon-tasks:before {
- content: "\e137";
+.form-control-static {
+ margin-bottom: 0;
}
-.glyphicon-filter:before {
- content: "\e138";
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
}
-.glyphicon-briefcase:before {
- content: "\e139";
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ padding-left: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ float: none;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
}
-.glyphicon-fullscreen:before {
- content: "\e140";
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
}
-.glyphicon-dashboard:before {
- content: "\e141";
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
}
-.glyphicon-paperclip:before {
- content: "\e142";
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
}
-.glyphicon-heart-empty:before {
- content: "\e143";
+.form-horizontal .form-control-static {
+ padding-top: 7px;
+ padding-bottom: 7px;
}
-.glyphicon-link:before {
- content: "\e144";
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
}
-.glyphicon-phone:before {
- content: "\e145";
+.form-horizontal .has-feedback .form-control-feedback {
+ top: 0;
+ right: 15px;
}
-.glyphicon-pushpin:before {
- content: "\e146";
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
}
-.glyphicon-usd:before {
- content: "\e148";
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
}
-.glyphicon-gbp:before {
- content: "\e149";
+.btn:hover,
+.btn:focus {
+ color: #333;
+ text-decoration: none;
}
-.glyphicon-sort:before {
- content: "\e150";
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
-.glyphicon-sort-by-alphabet:before {
- content: "\e151";
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ pointer-events: none;
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
}
-.glyphicon-sort-by-alphabet-alt:before {
- content: "\e152";
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
}
-.glyphicon-sort-by-order:before {
- content: "\e153";
+.btn-default:hover,
+.btn-default:focus,
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
}
-.glyphicon-sort-by-order-alt:before {
- content: "\e154";
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
}
-.glyphicon-sort-by-attributes:before {
- content: "\e155";
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+ background-color: #fff;
+ border-color: #ccc;
}
-.glyphicon-sort-by-attributes-alt:before {
- content: "\e156";
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
}
-.glyphicon-unchecked:before {
- content: "\e157";
+.btn-primary {
+ color: #fff;
+ background-color: #2980b9;
+ border-color: #2472a4;
}
-.glyphicon-expand:before {
- content: "\e158";
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #20638f;
+ border-color: #194f72;
}
-.glyphicon-collapse-down:before {
- content: "\e159";
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
}
-.glyphicon-collapse-up:before {
- content: "\e160";
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+ background-color: #2980b9;
+ border-color: #2472a4;
}
-.glyphicon-log-in:before {
- content: "\e161";
+.btn-primary .badge {
+ color: #2980b9;
+ background-color: #fff;
}
-.glyphicon-flash:before {
- content: "\e162";
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
}
-.glyphicon-log-out:before {
- content: "\e163";
+.btn-success:hover,
+.btn-success:focus,
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
}
-.glyphicon-new-window:before {
- content: "\e164";
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
}
-.glyphicon-record:before {
- content: "\e165";
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
}
-.glyphicon-save:before {
- content: "\e166";
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
}
-.glyphicon-open:before {
- content: "\e167";
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
}
-.glyphicon-saved:before {
- content: "\e168";
+.btn-info:hover,
+.btn-info:focus,
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
}
-.glyphicon-import:before {
- content: "\e169";
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
}
-.glyphicon-export:before {
- content: "\e170";
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+ background-color: #5bc0de;
+ border-color: #46b8da;
}
-.glyphicon-send:before {
- content: "\e171";
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
}
-.glyphicon-floppy-disk:before {
- content: "\e172";
+.btn-warning {
+ color: #fff;
+ background-color: #f39c12;
+ border-color: #e08e0b;
}
-.glyphicon-floppy-saved:before {
- content: "\e173";
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #c87f0a;
+ border-color: #a66908;
}
-.glyphicon-floppy-remove:before {
- content: "\e174";
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
}
-.glyphicon-floppy-save:before {
- content: "\e175";
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+ background-color: #f39c12;
+ border-color: #e08e0b;
}
-.glyphicon-floppy-open:before {
- content: "\e176";
+.btn-warning .badge {
+ color: #f39c12;
+ background-color: #fff;
}
-.glyphicon-credit-card:before {
- content: "\e177";
+.btn-danger {
+ color: #fff;
+ background-color: #c0392b;
+ border-color: #ab3326;
}
-.glyphicon-transfer:before {
- content: "\e178";
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #962d22;
+ border-color: #79241b;
}
-.glyphicon-cutlery:before {
- content: "\e179";
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
}
-.glyphicon-header:before {
- content: "\e180";
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+ background-color: #c0392b;
+ border-color: #ab3326;
}
-.glyphicon-compressed:before {
- content: "\e181";
+.btn-danger .badge {
+ color: #c0392b;
+ background-color: #fff;
}
-.glyphicon-earphone:before {
- content: "\e182";
+.btn-link {
+ font-weight: normal;
+ color: #000;
+ cursor: pointer;
+ border-radius: 0;
}
-.glyphicon-phone-alt:before {
- content: "\e183";
+.btn-link,
+.btn-link:active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
}
-.glyphicon-tower:before {
- content: "\e184";
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
}
-.glyphicon-stats:before {
- content: "\e185";
+.btn-link:hover,
+.btn-link:focus {
+ color: #000;
+ text-decoration: underline;
+ background-color: transparent;
}
-.glyphicon-sd-video:before {
- content: "\e186";
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #999;
+ text-decoration: none;
}
-.glyphicon-hd-video:before {
- content: "\e187";
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.33;
+ border-radius: 6px;
}
-.glyphicon-subtitles:before {
- content: "\e188";
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
}
-.glyphicon-sound-stereo:before {
- content: "\e189";
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
}
-.glyphicon-sound-dolby:before {
- content: "\e190";
+.btn-block {
+ display: block;
+ width: 100%;
+ padding-right: 0;
+ padding-left: 0;
}
-.glyphicon-sound-5-1:before {
- content: "\e191";
+.btn-block + .btn-block {
+ margin-top: 5px;
}
-.glyphicon-sound-6-1:before {
- content: "\e192";
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
}
-.glyphicon-sound-7-1:before {
- content: "\e193";
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
}
-.glyphicon-copyright-mark:before {
- content: "\e194";
+.fade.in {
+ opacity: 1;
}
-.glyphicon-registration-mark:before {
- content: "\e195";
+.collapse {
+ display: none;
}
-.glyphicon-cloud-download:before {
- content: "\e197";
+.collapse.in {
+ display: block;
}
-.glyphicon-cloud-upload:before {
- content: "\e198";
+tr.collapse.in {
+ display: table-row;
}
-.glyphicon-tree-conifer:before {
- content: "\e199";
+tbody.collapse.in {
+ display: table-row-group;
}
-.glyphicon-tree-deciduous:before {
- content: "\e200";
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition: height .35s ease;
+ -o-transition: height .35s ease;
+ transition: height .35s ease;
}
.caret {
display: inline-block;
@@ -2994,9 +3087,11 @@ input[type="button"].btn-block {
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
+ text-align: left;
list-style: none;
background-color: #fff;
- background-clip: padding-box;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
@@ -3127,7 +3222,7 @@ input[type="button"].btn-block {
}
.btn-group > .btn:focus,
.btn-group-vertical > .btn:focus {
- outline: none;
+ outline: 0;
}
.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
@@ -3181,24 +3276,6 @@ input[type="button"].btn-block {
.btn-group.open .dropdown-toggle {
outline: 0;
}
-.btn-group-xs > .btn {
- padding: 1px 5px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-.btn-group-sm > .btn {
- padding: 5px 10px;
- font-size: 12px;
- line-height: 1.5;
- border-radius: 3px;
-}
-.btn-group-lg > .btn {
- padding: 10px 16px;
- font-size: 18px;
- line-height: 1.33;
- border-radius: 6px;
-}
.btn-group > .btn + .dropdown-toggle {
padding-right: 8px;
padding-left: 8px;
@@ -3283,9 +3360,15 @@ input[type="button"].btn-block {
.btn-group-justified > .btn-group .btn {
width: 100%;
}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
- display: none;
+ position: absolute;
+ z-index: -1;
+ filter: alpha(opacity=0);
+ opacity: 0;
}
.input-group {
position: relative;
@@ -3298,6 +3381,8 @@ input[type="button"].btn-block {
padding-left: 0;
}
.input-group .form-control {
+ position: relative;
+ z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
@@ -3472,7 +3557,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.nav .open > a:hover,
.nav .open > a:focus {
background-color: #eee;
- border-color: #2980b9;
+ border-color: #000;
}
.nav .nav-divider {
height: 1px;
@@ -3648,13 +3733,13 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
}
.navbar-collapse {
- max-height: 340px;
padding-right: 15px;
padding-left: 15px;
overflow-x: visible;
-webkit-overflow-scrolling: touch;
border-top: 1px solid transparent;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.navbar-collapse.in {
overflow-y: auto;
@@ -3663,7 +3748,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-collapse {
width: auto;
border-top: 0;
- box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
}
.navbar-collapse.collapse {
display: block !important;
@@ -3681,6 +3767,16 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
padding-left: 0;
}
}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
@@ -3730,7 +3826,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
.navbar-brand {
float: left;
- height: 20px;
+ height: 36px;
padding: 8px 15px;
font-size: 18px;
line-height: 20px;
@@ -3758,7 +3854,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
border-radius: 4px;
}
.navbar-toggle:focus {
- outline: none;
+ outline: 0;
}
.navbar-toggle .icon-bar {
display: block;
@@ -3790,7 +3886,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
margin-top: 0;
background-color: transparent;
border: 0;
- box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
}
.navbar-nav .open .dropdown-menu > li > a,
.navbar-nav .open .dropdown-menu .dropdown-header {
@@ -3850,6 +3947,18 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
width: auto;
vertical-align: middle;
}
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
.navbar-form .control-label {
margin-bottom: 0;
vertical-align: middle;
@@ -4009,6 +4118,19 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-default .navbar-link:hover {
color: #333;
}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
.navbar-inverse {
background-color: rgba(0, 0, 0, .7);
border-color: rgba(0, 0, 0, .7);
@@ -4098,6 +4220,19 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.navbar-inverse .navbar-link:hover {
color: #fff;
}
+.navbar-inverse .btn-link {
+ color: #eee;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
.breadcrumb {
padding: 8px 15px;
margin-bottom: 20px;
@@ -4132,7 +4267,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
- color: #2980b9;
+ color: #000;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
@@ -4152,7 +4287,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
- color: #1b557a;
+ color: #000;
background-color: #eee;
border-color: #ddd;
}
@@ -4259,8 +4394,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
vertical-align: baseline;
border-radius: .25em;
}
-.label[href]:hover,
-.label[href]:focus {
+a.label:hover,
+a.label:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
@@ -4347,7 +4482,7 @@ a.badge:focus {
}
a.list-group-item.active > .badge,
.nav-pills > .active > a > .badge {
- color: #2980b9;
+ color: #000;
background-color: #fff;
}
.nav-pills > li > a > .badge {
@@ -4368,6 +4503,9 @@ a.list-group-item.active > .badge,
font-size: 21px;
font-weight: 200;
}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
.container .jumbotron {
border-radius: 6px;
}
@@ -4397,20 +4535,18 @@ a.list-group-item.active > .badge,
border: 1px solid #ddd;
border-radius: 4px;
-webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
.thumbnail > img,
.thumbnail a > img {
- display: block;
- max-width: 100%;
- height: auto;
margin-right: auto;
margin-left: auto;
}
a.thumbnail:hover,
a.thumbnail:focus,
a.thumbnail.active {
- border-color: #2980b9;
+ border-color: #000;
}
.thumbnail .caption {
padding: 9px;
@@ -4491,15 +4627,7 @@ a.thumbnail.active {
}
@-webkit-keyframes progress-bar-stripes {
from {
- background-position: 10px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-@-moz-keyframes progress-bar-stripes {
- from {
- background-position: 10px 0;
+ background-position: 40px 0;
}
to {
background-position: 0 0;
@@ -4507,22 +4635,22 @@ a.thumbnail.active {
}
@-o-keyframes progress-bar-stripes {
from {
- background-position: 0 0;
+ background-position: 40px 0;
}
to {
- background-position: 10px 0;
+ background-position: 0 0;
}
}
@keyframes progress-bar-stripes {
from {
- background-position: 10px 0;
+ background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
.progress {
- height: 10px;
+ height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
@@ -4535,29 +4663,46 @@ a.thumbnail.active {
width: 0;
height: 100%;
font-size: 12px;
- line-height: 10px;
+ line-height: 20px;
color: #fff;
text-align: center;
background-color: #2980b9;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
-webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
transition: width .6s ease;
}
.progress-striped .progress-bar {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-size: 10px 10px;
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
}
.progress.active .progress-bar {
-webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
+.progress-bar[aria-valuenow="1"],
+.progress-bar[aria-valuenow="2"] {
+ min-width: 30px;
+}
+.progress-bar[aria-valuenow="0"] {
+ min-width: 30px;
+ color: #999;
+ background-color: transparent;
+ background-image: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
.progress-bar-success {
background-color: #5cb85c;
}
.progress-striped .progress-bar-success {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-info {
@@ -4565,6 +4710,7 @@ a.thumbnail.active {
}
.progress-striped .progress-bar-info {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-warning {
@@ -4572,6 +4718,7 @@ a.thumbnail.active {
}
.progress-striped .progress-bar-warning {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.progress-bar-danger {
@@ -4579,6 +4726,7 @@ a.thumbnail.active {
}
.progress-striped .progress-bar-danger {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.media,
@@ -4644,25 +4792,42 @@ a.list-group-item .list-group-item-heading {
}
a.list-group-item:hover,
a.list-group-item:focus {
+ color: #555;
text-decoration: none;
background-color: #f5f5f5;
}
-a.list-group-item.active,
-a.list-group-item.active:hover,
-a.list-group-item.active:focus {
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #999;
+ background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #999;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
z-index: 2;
color: #fff;
background-color: #2980b9;
border-color: #2980b9;
}
-a.list-group-item.active .list-group-item-heading,
-a.list-group-item.active:hover .list-group-item-heading,
-a.list-group-item.active:focus .list-group-item-heading {
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading {
color: inherit;
}
-a.list-group-item.active .list-group-item-text,
-a.list-group-item.active:hover .list-group-item-text,
-a.list-group-item.active:focus .list-group-item-text {
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
color: #bedcf0;
}
.list-group-item-success {
@@ -4772,6 +4937,31 @@ a.list-group-item-danger.active:focus {
.panel-body {
padding: 15px;
}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
.panel > .list-group {
margin-bottom: 0;
}
@@ -4779,17 +4969,13 @@ a.list-group-item-danger.active:focus {
border-width: 1px 0;
border-radius: 0;
}
-.panel > .list-group .list-group-item:first-child {
- border-top: 0;
-}
-.panel > .list-group .list-group-item:last-child {
- border-bottom: 0;
-}
.panel > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.panel > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
}
@@ -4800,6 +4986,11 @@ a.list-group-item-danger.active:focus {
.panel > .table-responsive > .table {
margin-bottom: 0;
}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
@@ -4820,6 +5011,11 @@ a.list-group-item-danger.active:focus {
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
border-top-right-radius: 3px;
}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
@@ -4880,69 +5076,35 @@ a.list-group-item-danger.active:focus {
.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
border-right: 0;
}
-.panel > .table-bordered > thead > tr:first-child > th,
-.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
-.panel > .table-bordered > tbody > tr:first-child > th,
-.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th,
-.panel > .table-bordered > tfoot > tr:first-child > th,
-.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > th,
.panel > .table-bordered > thead > tr:first-child > td,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
.panel > .table-bordered > tbody > tr:first-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
-.panel > .table-bordered > tfoot > tr:first-child > td,
-.panel > .table-responsive > .table-bordered > tfoot > tr:first-child > td {
- border-top: 0;
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
}
-.panel > .table-bordered > thead > tr:last-child > th,
-.panel > .table-responsive > .table-bordered > thead > tr:last-child > th,
-.panel > .table-bordered > tbody > tr:last-child > th,
-.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
-.panel > .table-bordered > tfoot > tr:last-child > th,
-.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th,
-.panel > .table-bordered > thead > tr:last-child > td,
-.panel > .table-responsive > .table-bordered > thead > tr:last-child > td,
.panel > .table-bordered > tbody > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
.panel > .table-bordered > tfoot > tr:last-child > td,
-.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
border-bottom: 0;
}
.panel > .table-responsive {
margin-bottom: 0;
border: 0;
}
-.panel-heading {
- padding: 10px 15px;
- border-bottom: 1px solid transparent;
- border-top-left-radius: 3px;
- border-top-right-radius: 3px;
-}
-.panel-heading > .dropdown .dropdown-toggle {
- color: inherit;
-}
-.panel-title {
- margin-top: 0;
- margin-bottom: 0;
- font-size: 16px;
- color: inherit;
-}
-.panel-title > a {
- color: inherit;
-}
-.panel-footer {
- padding: 10px 15px;
- background-color: #f5f5f5;
- border-top: 1px solid #ddd;
- border-bottom-right-radius: 3px;
- border-bottom-left-radius: 3px;
-}
.panel-group {
margin-bottom: 20px;
}
.panel-group .panel {
margin-bottom: 0;
- overflow: hidden;
border-radius: 4px;
}
.panel-group .panel + .panel {
@@ -4968,10 +5130,10 @@ a.list-group-item-danger.active:focus {
background-color: #f5f5f5;
border-color: #ddd;
}
-.panel-default > .panel-heading + .panel-collapse .panel-body {
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #ddd;
}
-.panel-default > .panel-footer + .panel-collapse .panel-body {
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #ddd;
}
.panel-primary {
@@ -4982,10 +5144,10 @@ a.list-group-item-danger.active:focus {
background-color: #2980b9;
border-color: #2980b9;
}
-.panel-primary > .panel-heading + .panel-collapse .panel-body {
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #2980b9;
}
-.panel-primary > .panel-footer + .panel-collapse .panel-body {
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #2980b9;
}
.panel-success {
@@ -4996,10 +5158,10 @@ a.list-group-item-danger.active:focus {
background-color: #dff0d8;
border-color: #d6e9c6;
}
-.panel-success > .panel-heading + .panel-collapse .panel-body {
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #d6e9c6;
}
-.panel-success > .panel-footer + .panel-collapse .panel-body {
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #d6e9c6;
}
.panel-info {
@@ -5010,10 +5172,10 @@ a.list-group-item-danger.active:focus {
background-color: #d9edf7;
border-color: #bce8f1;
}
-.panel-info > .panel-heading + .panel-collapse .panel-body {
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #bce8f1;
}
-.panel-info > .panel-footer + .panel-collapse .panel-body {
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #bce8f1;
}
.panel-warning {
@@ -5024,10 +5186,10 @@ a.list-group-item-danger.active:focus {
background-color: #fcf8e3;
border-color: #faebcc;
}
-.panel-warning > .panel-heading + .panel-collapse .panel-body {
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #faebcc;
}
-.panel-warning > .panel-footer + .panel-collapse .panel-body {
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #faebcc;
}
.panel-danger {
@@ -5038,12 +5200,37 @@ a.list-group-item-danger.active:focus {
background-color: #f2dede;
border-color: #ebccd1;
}
-.panel-danger > .panel-heading + .panel-collapse .panel-body {
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
border-top-color: #ebccd1;
}
-.panel-danger > .panel-footer + .panel-collapse .panel-body {
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
border-bottom-color: #ebccd1;
}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
.well {
min-height: 20px;
padding: 19px;
@@ -5109,16 +5296,17 @@ button.close {
}
.modal.fade .modal-dialog {
-webkit-transition: -webkit-transform .3s ease-out;
- -moz-transition: -moz-transform .3s ease-out;
-o-transition: -o-transform .3s ease-out;
transition: transform .3s ease-out;
-webkit-transform: translate(0, -25%);
-ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
transform: translate(0, -25%);
}
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
transform: translate(0, 0);
}
.modal-dialog {
@@ -5129,11 +5317,12 @@ button.close {
.modal-content {
position: relative;
background-color: #fff;
- background-clip: padding-box;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
border: 1px solid #999;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
- outline: none;
+ outline: 0;
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
}
@@ -5168,11 +5357,10 @@ button.close {
}
.modal-body {
position: relative;
- padding: 20px;
+ padding: 15px;
}
.modal-footer {
- padding: 19px 20px 20px;
- margin-top: 15px;
+ padding: 15px;
text-align: right;
border-top: 1px solid #e5e5e5;
}
@@ -5186,6 +5374,13 @@ button.close {
.modal-footer .btn-block + .btn-block {
margin-left: 0;
}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
@media (min-width: 768px) {
.modal-dialog {
width: 600px;
@@ -5198,13 +5393,15 @@ button.close {
.modal-sm {
width: 300px;
}
+}
+@media (min-width: 992px) {
.modal-lg {
width: 900px;
}
}
.tooltip {
position: absolute;
- z-index: 1030;
+ z-index: 1070;
display: block;
font-size: 12px;
line-height: 1.4;
@@ -5304,14 +5501,15 @@ button.close {
position: absolute;
top: 0;
left: 0;
- z-index: 1010;
+ z-index: 1060;
display: none;
max-width: 276px;
padding: 1px;
text-align: left;
white-space: normal;
background-color: #fff;
- background-clip: padding-box;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
@@ -5343,8 +5541,8 @@ button.close {
.popover-content {
padding: 9px 14px;
}
-.popover .arrow,
-.popover .arrow:after {
+.popover > .arrow,
+.popover > .arrow:after {
position: absolute;
display: block;
width: 0;
@@ -5352,14 +5550,14 @@ button.close {
border-color: transparent;
border-style: solid;
}
-.popover .arrow {
+.popover > .arrow {
border-width: 11px;
}
-.popover .arrow:after {
+.popover > .arrow:after {
content: "";
border-width: 10px;
}
-.popover.top .arrow {
+.popover.top > .arrow {
bottom: -11px;
left: 50%;
margin-left: -11px;
@@ -5367,14 +5565,14 @@ button.close {
border-top-color: rgba(0, 0, 0, .25);
border-bottom-width: 0;
}
-.popover.top .arrow:after {
+.popover.top > .arrow:after {
bottom: 1px;
margin-left: -10px;
content: " ";
border-top-color: #fff;
border-bottom-width: 0;
}
-.popover.right .arrow {
+.popover.right > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
@@ -5382,14 +5580,14 @@ button.close {
border-right-color: rgba(0, 0, 0, .25);
border-left-width: 0;
}
-.popover.right .arrow:after {
+.popover.right > .arrow:after {
bottom: -10px;
left: 1px;
content: " ";
border-right-color: #fff;
border-left-width: 0;
}
-.popover.bottom .arrow {
+.popover.bottom > .arrow {
top: -11px;
left: 50%;
margin-left: -11px;
@@ -5397,14 +5595,14 @@ button.close {
border-bottom-color: #999;
border-bottom-color: rgba(0, 0, 0, .25);
}
-.popover.bottom .arrow:after {
+.popover.bottom > .arrow:after {
top: 1px;
margin-left: -10px;
content: " ";
border-top-width: 0;
border-bottom-color: #fff;
}
-.popover.left .arrow {
+.popover.left > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
@@ -5412,7 +5610,7 @@ button.close {
border-left-color: #999;
border-left-color: rgba(0, 0, 0, .25);
}
-.popover.left .arrow:after {
+.popover.left > .arrow:after {
right: 1px;
bottom: -10px;
content: " ";
@@ -5431,13 +5629,11 @@ button.close {
position: relative;
display: none;
-webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
transition: .6s ease-in-out left;
}
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
- display: block;
- max-width: 100%;
- height: auto;
line-height: 1;
}
.carousel-inner > .active,
@@ -5485,6 +5681,9 @@ button.close {
}
.carousel-control.left {
background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .5) 0%), color-stop(rgba(0, 0, 0, .0001) 100%));
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
background-repeat: repeat-x;
@@ -5493,6 +5692,9 @@ button.close {
right: 0;
left: auto;
background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .0001) 0%), color-stop(rgba(0, 0, 0, .5) 100%));
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
background-repeat: repeat-x;
@@ -5502,7 +5704,7 @@ button.close {
color: #fff;
text-decoration: none;
filter: alpha(opacity=90);
- outline: none;
+ outline: 0;
opacity: .9;
}
.carousel-control .icon-prev,
@@ -5517,17 +5719,18 @@ button.close {
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
left: 50%;
+ margin-left: -10px;
}
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-right {
right: 50%;
+ margin-right: -10px;
}
.carousel-control .icon-prev,
.carousel-control .icon-next {
width: 20px;
height: 20px;
margin-top: -10px;
- margin-left: -10px;
font-family: serif;
}
.carousel-control .icon-prev:before {
@@ -5581,16 +5784,23 @@ button.close {
text-shadow: none;
}
@media screen and (min-width: 768px) {
- .carousel-control .glyphicons-chevron-left,
- .carousel-control .glyphicons-chevron-right,
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
.carousel-control .icon-prev,
.carousel-control .icon-next {
width: 30px;
height: 30px;
margin-top: -15px;
- margin-left: -15px;
font-size: 30px;
}
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -15px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -15px;
+ }
.carousel-caption {
right: 20%;
left: 20%;
@@ -5602,6 +5812,8 @@ button.close {
}
.clearfix:before,
.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
.container:before,
.container:after,
.container-fluid:before,
@@ -5632,6 +5844,7 @@ button.close {
content: " ";
}
.clearfix:after,
+.dl-horizontal dd:after,
.container:after,
.container-fluid:after,
.row:after,
@@ -5685,9 +5898,23 @@ button.close {
width: device-width;
}
.visible-xs,
-tr.visible-xs,
-th.visible-xs,
-td.visible-xs {
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
display: none !important;
}
@media (max-width: 767px) {
@@ -5705,11 +5932,20 @@ td.visible-xs {
display: table-cell !important;
}
}
-.visible-sm,
-tr.visible-sm,
-th.visible-sm,
-td.visible-sm {
- display: none !important;
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
}
@media (min-width: 768px) and (max-width: 991px) {
.visible-sm {
@@ -5726,11 +5962,20 @@ td.visible-sm {
display: table-cell !important;
}
}
-.visible-md,
-tr.visible-md,
-th.visible-md,
-td.visible-md {
- display: none !important;
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
}
@media (min-width: 992px) and (max-width: 1199px) {
.visible-md {
@@ -5747,11 +5992,20 @@ td.visible-md {
display: table-cell !important;
}
}
-.visible-lg,
-tr.visible-lg,
-th.visible-lg,
-td.visible-lg {
- display: none !important;
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
}
@media (min-width: 1200px) {
.visible-lg {
@@ -5768,42 +6022,42 @@ td.visible-lg {
display: table-cell !important;
}
}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
@media (max-width: 767px) {
- .hidden-xs,
- tr.hidden-xs,
- th.hidden-xs,
- td.hidden-xs {
+ .hidden-xs {
display: none !important;
}
}
@media (min-width: 768px) and (max-width: 991px) {
- .hidden-sm,
- tr.hidden-sm,
- th.hidden-sm,
- td.hidden-sm {
+ .hidden-sm {
display: none !important;
}
}
@media (min-width: 992px) and (max-width: 1199px) {
- .hidden-md,
- tr.hidden-md,
- th.hidden-md,
- td.hidden-md {
+ .hidden-md {
display: none !important;
}
}
@media (min-width: 1200px) {
- .hidden-lg,
- tr.hidden-lg,
- th.hidden-lg,
- td.hidden-lg {
+ .hidden-lg {
display: none !important;
}
}
-.visible-print,
-tr.visible-print,
-th.visible-print,
-td.visible-print {
+.visible-print {
display: none !important;
}
@media print {
@@ -5821,11 +6075,32 @@ td.visible-print {
display: table-cell !important;
}
}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
@media print {
- .hidden-print,
- tr.hidden-print,
- th.hidden-print,
- td.hidden-print {
+ .hidden-print {
display: none !important;
}
}
@@ -5835,11 +6110,6 @@ td.visible-print {
.list-group-item {
padding: 8px 15px;
}
-.panel {
- border: 1px solid transparent;
- -webkit-box-shadow: none;
- box-shadow: none;
-}
h3,
h4 {
font-weight: bold;
@@ -5848,3 +6118,4 @@ ul.with-margin li,
ol.with-margin li {
margin: 7px auto;
}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css
index 4668115949..93265bb994 100644
--- a/frappe/public/css/desk.css
+++ b/frappe/public/css/desk.css
@@ -1,3 +1,5 @@
+@import url(http://fonts.googleapis.com/css?family=Noto+Sans:400,700);
+
html {
min-height: 100%;
position: relative;
@@ -13,12 +15,22 @@ a {
cursor: pointer;
}
+.navbar-inverse {
+ background-color: #444;
+ border-bottom: 0px;
+}
+
a.disabled, a.disabled:hover {
color: #888;
cursor: default;
text-decoration: none;
}
+a.form-link {
+ font-weight: bold;
+ font-size: 102%;
+}
+
.layout-main {
padding-bottom: 10px;
}
@@ -28,7 +40,6 @@ a.disabled, a.disabled:hover {
}
.text-ellipsis {
- display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -55,8 +66,20 @@ div#freeze {
text-align: center;
}
-/* listing */
+.app-page {
+ border: 1px solid #c7c7c7;
+ border-radius: 4px;
+ margin-top: 15px;
+ padding: 0px;
+ overflow: hidden;
+}
+
+.page-container .container {
+ max-width: 970px;
+}
+
+/* listing */
.show_filters {
padding-top: 15px;
padding-bottom: 15px;
@@ -64,8 +87,13 @@ div#freeze {
border-bottom: 1px solid #c7c7c7;
}
+.set-filters .btn-group {
+ margin-bottom: 10px;
+ margin-right: 10px;
+}
+
.list-row {
- padding: 5px 15px;
+ padding: 5px 15px 10px;
margin: 0px -15px;
border-bottom: 1px solid #c7c7c7;
}
@@ -91,21 +119,23 @@ div#freeze {
margin-top: 3px;
}
-.icon-in-circle {
- color: #b7b7b7;
- background-color: white;
- border-radius:50%;
- text-align: center;
- width: 20px;
- height: 20px;
- font-size: 20px;
- display: inline-block;
-}
-
.form-layout {
/*margin-top: -15px;*/
}
+.form-print-wrapper {
+ margin: 0px -15px -15px -15px;
+ background-color: #ddd;
+ padding: 0px 15px 30px 15px;
+}
+
+.form-page-header {
+ border-top: 1px solid #eee;
+ margin: 15px -15px -15px -15px;
+ padding: 10px 15px;
+ background-color: #f9f9f9;
+}
+
.form-control {
padding: 6px 8px;
}
@@ -136,22 +166,43 @@ div#freeze {
/* list */
+.progress {
+ height: 10px;
+}
+
.doclist-row {
position: relative;
padding-top: 5px;
- padding-bottom: 3px;
+ padding-bottom: 6px;
border-bottom: "1px solid #eee";
}
-.doclist-row .col {
- padding-left: 7px;
- padding-right: 7px;
+.doclist-row .progress {
+ margin-top: 12px;
+}
+
+.filterable {
+ cursor: pointer;
+}
+
+.doclist-row .label {
+ margin-right: 8px;
}
.list-timestamp {
position: absolute;
- right: 5px;
+ right: 15px;
+ bottom: 3px;
+ font-size: 70%;
+ color: #888;
+}
+
+.list-doc-name {
+ position: absolute;
bottom: 2px;
+}
+
+.list-doc-name a {
font-size: 70%;
color: #888;
}
@@ -199,7 +250,7 @@ div#freeze {
position: fixed;
bottom: 8px;
right: 8px;
- z-index: 10;
+ z-index: 1050;
}
#alert-container .alert {
@@ -225,6 +276,43 @@ div#freeze {
}
/* form */
+.comment-connector {
+ height: 30px;
+ margin-left: 70px;
+ border-left: 1px solid #d7d7d7;
+}
+
+.comment-body {
+ border-left: 1px solid #d7d7d7;
+ padding: 5px 15px 15px 30px;
+}
+
+.comment-body p {
+ margin-bottom: 5px;
+}
+
+.comment-icon {
+ margin-right: -14px !important;
+ margin-left: 15px;
+ z-index: 1;
+}
+
+.icon-timeline {
+ color: #fff;
+ height: 29px;
+ width: 29px;
+ padding: 8px 9px 7px 9px;
+ border-radius: 50%;
+ background-color: #d7d7d7;
+ text-align: center;
+ display: inline-block;
+ float: left;
+}
+
+.comment {
+ margin-top: 0px;
+}
+
.frappe-editor {
cursor: text;
}
@@ -257,33 +345,56 @@ ul.linked-with-list li {
}
.grid-heading-row {
- padding: 8px;
- border-bottom: 1px solid #dddddd;
+ padding: 8px 15px;
+ border-bottom: 1px solid #c7c7c7;
+ background-color: #f9f9f9;
+ font-weight: bold;
}
.rows .grid-row .divider {
padding-bottom: 5px;
margin-bottom: 5px;
- border-bottom: 1px solid #dddddd;
+ margin-top: 8px;
+ border-bottom: 1px solid #c7c7c7;
}
.rows .grid-row .data-row, .rows .grid-row .panel-heading {
cursor: pointer;
}
+.data-row {
+ margin-left: -20px;
+}
+
+.row-index {
+ text-align: right;
+}
+
.grid-row .panel {
background-color: #fffff8;
}
+.grid-row td {
+ vertical-align: top;
+}
+
+.grid-row p {
+ margin-bottom: 5px;
+}
+
/* form footer */
.form-footer {
- padding-top: 15px;
- padding-bottom: 15px;
- color: #888;
+ padding-bottom: 30px;
/*box-shadow: 0px -1px 6px rgba(0,0,0,0.3);*/
}
+.form-footer h5 {
+ margin: 15px 0px;
+ font-weight: bold;
+}
+
+
.like-disabled-input {
background-color: #f8f8f8;
padding: 6px;
@@ -352,6 +463,7 @@ ul.linked-with-list li {
margin-bottom: 7px;
}
+
/* hack */
.ui-datepicker { z-index: 9999999 !important; }
.ui-autocomplete {
@@ -364,9 +476,10 @@ ul.linked-with-list li {
}
.print-preview {
- padding: 50px 20px;
- margin: 0px -15px;
- box-shadow: 1px 1px 5px rgba(0,0,0,0.5);
+ padding: 0px;
+ max-width: 8.3in;
+ margin: auto;
+ min-height: 11.69in;
}
.module-view-layout {
diff --git a/frappe/public/css/hljs-github.css b/frappe/public/css/hljs-github.css
new file mode 100644
index 0000000000..71967a3739
--- /dev/null
+++ b/frappe/public/css/hljs-github.css
@@ -0,0 +1,125 @@
+/*
+
+github.com style (c) Vasily Polovnyov
+
+*/
+
+.hljs {
+ display: block; padding: 0.5em;
+ color: #333;
+ background: #f8f8f8
+}
+
+.hljs-comment,
+.hljs-template_comment,
+.diff .hljs-header,
+.hljs-javadoc {
+ color: #998;
+ font-style: italic
+}
+
+.hljs-keyword,
+.css .rule .hljs-keyword,
+.hljs-winutils,
+.javascript .hljs-title,
+.nginx .hljs-title,
+.hljs-subst,
+.hljs-request,
+.hljs-status {
+ color: #333;
+ font-weight: bold
+}
+
+.hljs-number,
+.hljs-hexcolor,
+.ruby .hljs-constant {
+ color: #099;
+}
+
+.hljs-string,
+.hljs-tag .hljs-value,
+.hljs-phpdoc,
+.tex .hljs-formula {
+ color: #d14
+}
+
+.hljs-title,
+.hljs-id,
+.coffeescript .hljs-params,
+.scss .hljs-preprocessor {
+ color: #900;
+ font-weight: bold
+}
+
+.javascript .hljs-title,
+.lisp .hljs-title,
+.clojure .hljs-title,
+.hljs-subst {
+ font-weight: normal
+}
+
+.hljs-class .hljs-title,
+.haskell .hljs-type,
+.vhdl .hljs-literal,
+.tex .hljs-command {
+ color: #458;
+ font-weight: bold
+}
+
+.hljs-tag,
+.hljs-tag .hljs-title,
+.hljs-rules .hljs-property,
+.django .hljs-tag .hljs-keyword {
+ color: #000080;
+ font-weight: normal
+}
+
+.hljs-attribute,
+.hljs-variable,
+.lisp .hljs-body {
+ color: #008080
+}
+
+.hljs-regexp {
+ color: #009926
+}
+
+.hljs-symbol,
+.ruby .hljs-symbol .hljs-string,
+.lisp .hljs-keyword,
+.tex .hljs-special,
+.hljs-prompt {
+ color: #990073
+}
+
+.hljs-built_in,
+.lisp .hljs-title,
+.clojure .hljs-built_in {
+ color: #0086b3
+}
+
+.hljs-preprocessor,
+.hljs-pragma,
+.hljs-pi,
+.hljs-doctype,
+.hljs-shebang,
+.hljs-cdata {
+ color: #999;
+ font-weight: bold
+}
+
+.hljs-deletion {
+ background: #fdd
+}
+
+.hljs-addition {
+ background: #dfd
+}
+
+.diff .hljs-change {
+ background: #0086b3
+}
+
+.hljs-chunk {
+ color: #aaa
+}
diff --git a/frappe/public/css/less/frappe.less b/frappe/public/css/less/frappe.less
index 6c218e541b..0f3578357b 100644
--- a/frappe/public/css/less/frappe.less
+++ b/frappe/public/css/less/frappe.less
@@ -12,6 +12,9 @@
@alert-padding: 10px;
@nav-link-padding: 8px 15px;
+@link-color: #000;
+@font-family-sans-serif: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+
.alert {
border: 1px solid transparent;
}
@@ -20,12 +23,6 @@
padding: 8px 15px;
}
-.panel {
- border: 1px solid transparent;
- -webkit-box-shadow: none;
- box-shadow: none;
-}
-
h3, h4 {
font-weight: bold;
}
@@ -33,4 +30,4 @@ h3, h4 {
ul.with-margin li,
ol.with-margin li {
margin: 7px auto;
-}
\ No newline at end of file
+}
diff --git a/frappe/public/css/octicons/LICENSE.txt b/frappe/public/css/octicons/LICENSE.txt
new file mode 100755
index 0000000000..259b43d14d
--- /dev/null
+++ b/frappe/public/css/octicons/LICENSE.txt
@@ -0,0 +1,9 @@
+(c) 2012-2014 GitHub
+
+When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos)
+
+Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL)
+Applies to all font files
+
+Code License: MIT (http://choosealicense.com/licenses/mit/)
+Applies to all other files
diff --git a/frappe/public/css/octicons/README.md b/frappe/public/css/octicons/README.md
new file mode 100755
index 0000000000..1007073350
--- /dev/null
+++ b/frappe/public/css/octicons/README.md
@@ -0,0 +1 @@
+If you intend to install Octicons locally, install `octicons-local.ttf`. It should appear as “github-octicons” in your font list. It is specially designed not to conflict with GitHub's web fonts.
diff --git a/frappe/public/css/octicons/octicons-local.ttf b/frappe/public/css/octicons/octicons-local.ttf
new file mode 100755
index 0000000000..62bcbb3ae0
Binary files /dev/null and b/frappe/public/css/octicons/octicons-local.ttf differ
diff --git a/frappe/public/css/octicons/octicons.css b/frappe/public/css/octicons/octicons.css
new file mode 100755
index 0000000000..dd05c96320
--- /dev/null
+++ b/frappe/public/css/octicons/octicons.css
@@ -0,0 +1,245 @@
+@font-face {
+ font-family: 'octicons';
+ src: url('/assets/frappe/css/octicons/octicons.eot?#iefix') format('embedded-opentype'),
+ url('/assets/frappe/css/octicons/octicons.woff') format('woff'),
+ url('/assets/frappe/css/octicons/octicons.ttf') format('truetype'),
+ url('/assets/frappe/css/octicons/octicons.svg#octicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+/*
+
+.octicon is optimized for 16px.
+.mega-octicon is optimized for 32px but can be used larger.
+
+*/
+.octicon {
+ font: normal normal 16px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon {
+ font: normal normal 32px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-alignment-align:before { content: '\f08a'} /* */
+.octicon-alignment-aligned-to:before { content: '\f08e'} /* */
+.octicon-alignment-unalign:before { content: '\f08b'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-beer:before { content: '\f069'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hourglass:before { content: '\f09e'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-jump-down:before { content: '\f072'} /* */
+.octicon-jump-left:before { content: '\f0a5'} /* */
+.octicon-jump-right:before { content: '\f0a6'} /* */
+.octicon-jump-up:before { content: '\f073'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-microscope:before { content: '\f089'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-move-down:before { content: '\f0a8'} /* */
+.octicon-move-left:before { content: '\f074'} /* */
+.octicon-move-right:before { content: '\f0a9'} /* */
+.octicon-move-up:before { content: '\f0a7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-playback-fast-forward:before { content: '\f0bd'} /* */
+.octicon-playback-pause:before { content: '\f0bb'} /* */
+.octicon-playback-play:before { content: '\f0bf'} /* */
+.octicon-playback-rewind:before { content: '\f0bc'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-podium:before { content: '\f0af'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-puzzle:before { content: '\f0c0'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-split:before { content: '\f0c6'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-steps:before { content: '\f0c7'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/frappe/public/css/octicons/octicons.eot b/frappe/public/css/octicons/octicons.eot
new file mode 100755
index 0000000000..a3aef43c6e
Binary files /dev/null and b/frappe/public/css/octicons/octicons.eot differ
diff --git a/frappe/public/css/octicons/octicons.less b/frappe/public/css/octicons/octicons.less
new file mode 100755
index 0000000000..78ef46ead8
--- /dev/null
+++ b/frappe/public/css/octicons/octicons.less
@@ -0,0 +1,244 @@
+@octicons-font-path: ".";
+@octicons-version: "897b19cdb9c4473f9166329e039ba8337c77d561";
+
+@font-face {
+ font-family: 'octicons';
+ src: ~"url('@{octicons-font-path}/octicons.eot?#iefix&v=@{octicons-version}') format('embedded-opentype')",
+ ~"url('@{octicons-font-path}/octicons.woff?v=@{octicons-version}') format('woff')",
+ ~"url('@{octicons-font-path}/octicons.ttf?v=@{octicons-version}') format('truetype')",
+ ~"url('@{octicons-font-path}/octicons.svg?v=@{octicons-version}#octicons') format('svg')";
+ font-weight: normal;
+ font-style: normal;
+}
+
+// .octicon is optimized for 16px.
+// .mega-octicon is optimized for 32px but can be used larger.
+.octicon {
+ font: normal normal 16px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon {
+ font: normal normal 32px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-alignment-align:before { content: '\f08a'} /* */
+.octicon-alignment-aligned-to:before { content: '\f08e'} /* */
+.octicon-alignment-unalign:before { content: '\f08b'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-beer:before { content: '\f069'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hourglass:before { content: '\f09e'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-jump-down:before { content: '\f072'} /* */
+.octicon-jump-left:before { content: '\f0a5'} /* */
+.octicon-jump-right:before { content: '\f0a6'} /* */
+.octicon-jump-up:before { content: '\f073'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-microscope:before { content: '\f089'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-move-down:before { content: '\f0a8'} /* */
+.octicon-move-left:before { content: '\f074'} /* */
+.octicon-move-right:before { content: '\f0a9'} /* */
+.octicon-move-up:before { content: '\f0a7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-playback-fast-forward:before { content: '\f0bd'} /* */
+.octicon-playback-pause:before { content: '\f0bb'} /* */
+.octicon-playback-play:before { content: '\f0bf'} /* */
+.octicon-playback-rewind:before { content: '\f0bc'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-podium:before { content: '\f0af'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-puzzle:before { content: '\f0c0'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-split:before { content: '\f0c6'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-steps:before { content: '\f0c7'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/frappe/public/css/octicons/octicons.svg b/frappe/public/css/octicons/octicons.svg
new file mode 100755
index 0000000000..ea3e0f1615
--- /dev/null
+++ b/frappe/public/css/octicons/octicons.svg
@@ -0,0 +1,198 @@
+
+
+
+
+(c) 2012-2014 GitHub
+
+When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos)
+
+Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL)
+Applies to all font files
+
+Code License: MIT (http://choosealicense.com/licenses/mit/)
+Applies to all other files
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frappe/public/css/octicons/octicons.ttf b/frappe/public/css/octicons/octicons.ttf
new file mode 100755
index 0000000000..7111762d8b
Binary files /dev/null and b/frappe/public/css/octicons/octicons.ttf differ
diff --git a/frappe/public/css/octicons/octicons.woff b/frappe/public/css/octicons/octicons.woff
new file mode 100755
index 0000000000..a3989c84a3
Binary files /dev/null and b/frappe/public/css/octicons/octicons.woff differ
diff --git a/frappe/public/css/octicons/sprockets-octicons.scss b/frappe/public/css/octicons/sprockets-octicons.scss
new file mode 100755
index 0000000000..f2c1664ede
--- /dev/null
+++ b/frappe/public/css/octicons/sprockets-octicons.scss
@@ -0,0 +1,241 @@
+@font-face {
+ font-family: 'octicons';
+ src: font-url('octicons.eot?#iefix') format('embedded-opentype'),
+ font-url('octicons.woff') format('woff'),
+ font-url('octicons.ttf') format('truetype'),
+ font-url('octicons.svg#octicons') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+// .octicon is optimized for 16px.
+// .mega-octicon is optimized for 32px but can be used larger.
+.octicon {
+ font: normal normal 16px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.mega-octicon {
+ font: normal normal 32px octicons;
+ line-height: 1;
+ display: inline-block;
+ text-decoration: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.octicon-alert:before { content: '\f02d'} /* */
+.octicon-alignment-align:before { content: '\f08a'} /* */
+.octicon-alignment-aligned-to:before { content: '\f08e'} /* */
+.octicon-alignment-unalign:before { content: '\f08b'} /* */
+.octicon-arrow-down:before { content: '\f03f'} /* */
+.octicon-arrow-left:before { content: '\f040'} /* */
+.octicon-arrow-right:before { content: '\f03e'} /* */
+.octicon-arrow-small-down:before { content: '\f0a0'} /* */
+.octicon-arrow-small-left:before { content: '\f0a1'} /* */
+.octicon-arrow-small-right:before { content: '\f071'} /* */
+.octicon-arrow-small-up:before { content: '\f09f'} /* */
+.octicon-arrow-up:before { content: '\f03d'} /* */
+.octicon-beer:before { content: '\f069'} /* */
+.octicon-book:before { content: '\f007'} /* */
+.octicon-bookmark:before { content: '\f07b'} /* */
+.octicon-briefcase:before { content: '\f0d3'} /* */
+.octicon-broadcast:before { content: '\f048'} /* */
+.octicon-browser:before { content: '\f0c5'} /* */
+.octicon-bug:before { content: '\f091'} /* */
+.octicon-calendar:before { content: '\f068'} /* */
+.octicon-check:before { content: '\f03a'} /* */
+.octicon-checklist:before { content: '\f076'} /* */
+.octicon-chevron-down:before { content: '\f0a3'} /* */
+.octicon-chevron-left:before { content: '\f0a4'} /* */
+.octicon-chevron-right:before { content: '\f078'} /* */
+.octicon-chevron-up:before { content: '\f0a2'} /* */
+.octicon-circle-slash:before { content: '\f084'} /* */
+.octicon-circuit-board:before { content: '\f0d6'} /* */
+.octicon-clippy:before { content: '\f035'} /* */
+.octicon-clock:before { content: '\f046'} /* */
+.octicon-cloud-download:before { content: '\f00b'} /* */
+.octicon-cloud-upload:before { content: '\f00c'} /* */
+.octicon-code:before { content: '\f05f'} /* */
+.octicon-color-mode:before { content: '\f065'} /* */
+.octicon-comment-add:before,
+.octicon-comment:before { content: '\f02b'} /* */
+.octicon-comment-discussion:before { content: '\f04f'} /* */
+.octicon-credit-card:before { content: '\f045'} /* */
+.octicon-dash:before { content: '\f0ca'} /* */
+.octicon-dashboard:before { content: '\f07d'} /* */
+.octicon-database:before { content: '\f096'} /* */
+.octicon-device-camera:before { content: '\f056'} /* */
+.octicon-device-camera-video:before { content: '\f057'} /* */
+.octicon-device-desktop:before { content: '\f27c'} /* */
+.octicon-device-mobile:before { content: '\f038'} /* */
+.octicon-diff:before { content: '\f04d'} /* */
+.octicon-diff-added:before { content: '\f06b'} /* */
+.octicon-diff-ignored:before { content: '\f099'} /* */
+.octicon-diff-modified:before { content: '\f06d'} /* */
+.octicon-diff-removed:before { content: '\f06c'} /* */
+.octicon-diff-renamed:before { content: '\f06e'} /* */
+.octicon-ellipsis:before { content: '\f09a'} /* */
+.octicon-eye-unwatch:before,
+.octicon-eye-watch:before,
+.octicon-eye:before { content: '\f04e'} /* */
+.octicon-file-binary:before { content: '\f094'} /* */
+.octicon-file-code:before { content: '\f010'} /* */
+.octicon-file-directory:before { content: '\f016'} /* */
+.octicon-file-media:before { content: '\f012'} /* */
+.octicon-file-pdf:before { content: '\f014'} /* */
+.octicon-file-submodule:before { content: '\f017'} /* */
+.octicon-file-symlink-directory:before { content: '\f0b1'} /* */
+.octicon-file-symlink-file:before { content: '\f0b0'} /* */
+.octicon-file-text:before { content: '\f011'} /* */
+.octicon-file-zip:before { content: '\f013'} /* */
+.octicon-flame:before { content: '\f0d2'} /* */
+.octicon-fold:before { content: '\f0cc'} /* */
+.octicon-gear:before { content: '\f02f'} /* */
+.octicon-gift:before { content: '\f042'} /* */
+.octicon-gist:before { content: '\f00e'} /* */
+.octicon-gist-secret:before { content: '\f08c'} /* */
+.octicon-git-branch-create:before,
+.octicon-git-branch-delete:before,
+.octicon-git-branch:before { content: '\f020'} /* */
+.octicon-git-commit:before { content: '\f01f'} /* */
+.octicon-git-compare:before { content: '\f0ac'} /* */
+.octicon-git-merge:before { content: '\f023'} /* */
+.octicon-git-pull-request-abandoned:before,
+.octicon-git-pull-request:before { content: '\f009'} /* */
+.octicon-globe:before { content: '\f0b6'} /* */
+.octicon-graph:before { content: '\f043'} /* */
+.octicon-heart:before { content: '\2665'} /* ♥ */
+.octicon-history:before { content: '\f07e'} /* */
+.octicon-home:before { content: '\f08d'} /* */
+.octicon-horizontal-rule:before { content: '\f070'} /* */
+.octicon-hourglass:before { content: '\f09e'} /* */
+.octicon-hubot:before { content: '\f09d'} /* */
+.octicon-inbox:before { content: '\f0cf'} /* */
+.octicon-info:before { content: '\f059'} /* */
+.octicon-issue-closed:before { content: '\f028'} /* */
+.octicon-issue-opened:before { content: '\f026'} /* */
+.octicon-issue-reopened:before { content: '\f027'} /* */
+.octicon-jersey:before { content: '\f019'} /* */
+.octicon-jump-down:before { content: '\f072'} /* */
+.octicon-jump-left:before { content: '\f0a5'} /* */
+.octicon-jump-right:before { content: '\f0a6'} /* */
+.octicon-jump-up:before { content: '\f073'} /* */
+.octicon-key:before { content: '\f049'} /* */
+.octicon-keyboard:before { content: '\f00d'} /* */
+.octicon-law:before { content: '\f0d8'} /* */
+.octicon-light-bulb:before { content: '\f000'} /* */
+.octicon-link:before { content: '\f05c'} /* */
+.octicon-link-external:before { content: '\f07f'} /* */
+.octicon-list-ordered:before { content: '\f062'} /* */
+.octicon-list-unordered:before { content: '\f061'} /* */
+.octicon-location:before { content: '\f060'} /* */
+.octicon-gist-private:before,
+.octicon-mirror-private:before,
+.octicon-git-fork-private:before,
+.octicon-lock:before { content: '\f06a'} /* */
+.octicon-logo-github:before { content: '\f092'} /* */
+.octicon-mail:before { content: '\f03b'} /* */
+.octicon-mail-read:before { content: '\f03c'} /* */
+.octicon-mail-reply:before { content: '\f051'} /* */
+.octicon-mark-github:before { content: '\f00a'} /* */
+.octicon-markdown:before { content: '\f0c9'} /* */
+.octicon-megaphone:before { content: '\f077'} /* */
+.octicon-mention:before { content: '\f0be'} /* */
+.octicon-microscope:before { content: '\f089'} /* */
+.octicon-milestone:before { content: '\f075'} /* */
+.octicon-mirror-public:before,
+.octicon-mirror:before { content: '\f024'} /* */
+.octicon-mortar-board:before { content: '\f0d7'} /* */
+.octicon-move-down:before { content: '\f0a8'} /* */
+.octicon-move-left:before { content: '\f074'} /* */
+.octicon-move-right:before { content: '\f0a9'} /* */
+.octicon-move-up:before { content: '\f0a7'} /* */
+.octicon-mute:before { content: '\f080'} /* */
+.octicon-no-newline:before { content: '\f09c'} /* */
+.octicon-octoface:before { content: '\f008'} /* */
+.octicon-organization:before { content: '\f037'} /* */
+.octicon-package:before { content: '\f0c4'} /* */
+.octicon-paintcan:before { content: '\f0d1'} /* */
+.octicon-pencil:before { content: '\f058'} /* */
+.octicon-person-add:before,
+.octicon-person-follow:before,
+.octicon-person:before { content: '\f018'} /* */
+.octicon-pin:before { content: '\f041'} /* */
+.octicon-playback-fast-forward:before { content: '\f0bd'} /* */
+.octicon-playback-pause:before { content: '\f0bb'} /* */
+.octicon-playback-play:before { content: '\f0bf'} /* */
+.octicon-playback-rewind:before { content: '\f0bc'} /* */
+.octicon-plug:before { content: '\f0d4'} /* */
+.octicon-repo-create:before,
+.octicon-gist-new:before,
+.octicon-file-directory-create:before,
+.octicon-file-add:before,
+.octicon-plus:before { content: '\f05d'} /* */
+.octicon-podium:before { content: '\f0af'} /* */
+.octicon-primitive-dot:before { content: '\f052'} /* */
+.octicon-primitive-square:before { content: '\f053'} /* */
+.octicon-pulse:before { content: '\f085'} /* */
+.octicon-puzzle:before { content: '\f0c0'} /* */
+.octicon-question:before { content: '\f02c'} /* */
+.octicon-quote:before { content: '\f063'} /* */
+.octicon-radio-tower:before { content: '\f030'} /* */
+.octicon-repo-delete:before,
+.octicon-repo:before { content: '\f001'} /* */
+.octicon-repo-clone:before { content: '\f04c'} /* */
+.octicon-repo-force-push:before { content: '\f04a'} /* */
+.octicon-gist-fork:before,
+.octicon-repo-forked:before { content: '\f002'} /* */
+.octicon-repo-pull:before { content: '\f006'} /* */
+.octicon-repo-push:before { content: '\f005'} /* */
+.octicon-rocket:before { content: '\f033'} /* */
+.octicon-rss:before { content: '\f034'} /* */
+.octicon-ruby:before { content: '\f047'} /* */
+.octicon-screen-full:before { content: '\f066'} /* */
+.octicon-screen-normal:before { content: '\f067'} /* */
+.octicon-search-save:before,
+.octicon-search:before { content: '\f02e'} /* */
+.octicon-server:before { content: '\f097'} /* */
+.octicon-settings:before { content: '\f07c'} /* */
+.octicon-log-in:before,
+.octicon-sign-in:before { content: '\f036'} /* */
+.octicon-log-out:before,
+.octicon-sign-out:before { content: '\f032'} /* */
+.octicon-split:before { content: '\f0c6'} /* */
+.octicon-squirrel:before { content: '\f0b2'} /* */
+.octicon-star-add:before,
+.octicon-star-delete:before,
+.octicon-star:before { content: '\f02a'} /* */
+.octicon-steps:before { content: '\f0c7'} /* */
+.octicon-stop:before { content: '\f08f'} /* */
+.octicon-repo-sync:before,
+.octicon-sync:before { content: '\f087'} /* */
+.octicon-tag-remove:before,
+.octicon-tag-add:before,
+.octicon-tag:before { content: '\f015'} /* */
+.octicon-telescope:before { content: '\f088'} /* */
+.octicon-terminal:before { content: '\f0c8'} /* */
+.octicon-three-bars:before { content: '\f05e'} /* */
+.octicon-tools:before { content: '\f031'} /* */
+.octicon-trashcan:before { content: '\f0d0'} /* */
+.octicon-triangle-down:before { content: '\f05b'} /* */
+.octicon-triangle-left:before { content: '\f044'} /* */
+.octicon-triangle-right:before { content: '\f05a'} /* */
+.octicon-triangle-up:before { content: '\f0aa'} /* */
+.octicon-unfold:before { content: '\f039'} /* */
+.octicon-unmute:before { content: '\f0ba'} /* */
+.octicon-versions:before { content: '\f064'} /* */
+.octicon-remove-close:before,
+.octicon-x:before { content: '\f081'} /* */
+.octicon-zap:before { content: '\26A1'} /* ⚡ */
diff --git a/frappe/public/css/tree_grid.css b/frappe/public/css/tree_grid.css
index c91e17584b..5ce94263cf 100644
--- a/frappe/public/css/tree_grid.css
+++ b/frappe/public/css/tree_grid.css
@@ -13,9 +13,9 @@
}
.toggle.expand {
- background: url("../lib/images/icons/expand.gif") no-repeat center center;
+ background: url("../frappe/js/lib/slickgrid/images/expand.gif") no-repeat center center;
}
.toggle.collapse {
- background: url("../lib/images/icons/collapse.gif") no-repeat center center;
-}
\ No newline at end of file
+ background: url("../frappe/js/lib/slickgrid/images/collapse.gif") no-repeat center center;
+}
diff --git a/frappe/public/html/list_info_template.html b/frappe/public/html/list_info_template.html
new file mode 100644
index 0000000000..61ffdcc143
--- /dev/null
+++ b/frappe/public/html/list_info_template.html
@@ -0,0 +1,17 @@
+{% if (tags.length) { %}
+
+ {%= tags.join(", ") %}
+{% } %}
+{% if (comments.length) { %}
+
+ {%= comments.length %}
+
+{% } %}
+{% if (assign.length) { %}
+ {% for (var i=0, l=assign.length; i
+ {%= frappe.avatar(assign[i], "avatar-xs") %}
+ {% }%}
+{% } %}
+{%= comment_when(data.modified) %}
diff --git a/frappe/public/html/print_template.html b/frappe/public/html/print_template.html
new file mode 100644
index 0000000000..740261397a
--- /dev/null
+++ b/frappe/public/html/print_template.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+ {%= title %}
+
+
+
+
+
+
+
diff --git a/frappe/public/images/help/print-style-classic.png b/frappe/public/images/help/print-style-classic.png
new file mode 100644
index 0000000000..e1817aad28
Binary files /dev/null and b/frappe/public/images/help/print-style-classic.png differ
diff --git a/frappe/public/images/help/print-style-modern.png b/frappe/public/images/help/print-style-modern.png
new file mode 100644
index 0000000000..57917de063
Binary files /dev/null and b/frappe/public/images/help/print-style-modern.png differ
diff --git a/frappe/public/images/help/print-style-monochrome.png b/frappe/public/images/help/print-style-monochrome.png
new file mode 100644
index 0000000000..ed0a301deb
Binary files /dev/null and b/frappe/public/images/help/print-style-monochrome.png differ
diff --git a/frappe/public/images/help/print-style-standard.png b/frappe/public/images/help/print-style-standard.png
new file mode 100644
index 0000000000..db1c37044e
Binary files /dev/null and b/frappe/public/images/help/print-style-standard.png differ
diff --git a/frappe/public/images/help/style-settings-help.png b/frappe/public/images/help/style-settings-help.png
new file mode 100644
index 0000000000..cc49373b59
Binary files /dev/null and b/frappe/public/images/help/style-settings-help.png differ
diff --git a/frappe/public/js/frappe/defaults.js b/frappe/public/js/frappe/defaults.js
index cdaeca429e..886b2c2bca 100644
--- a/frappe/public/js/frappe/defaults.js
+++ b/frappe/public/js/frappe/defaults.js
@@ -46,11 +46,11 @@ frappe.defaults = {
}
}
},
- get_restrictions: function() {
- return frappe.defaults.restrictions;
+ get_user_permissions: function() {
+ return frappe.defaults.user_permissions;
},
- set_restrictions: function(restrictions) {
- if(!restrictions) return;
- frappe.defaults.restrictions = $.extend(frappe.defaults.restrictions || {}, restrictions);
+ set_user_permissions: function(user_permissions) {
+ if(!user_permissions) return;
+ frappe.defaults.user_permissions = $.extend(frappe.defaults.user_permissions || {}, user_permissions);
}
}
\ No newline at end of file
diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js
index 7d2ed46f0e..21e7510964 100644
--- a/frappe/public/js/frappe/desk.js
+++ b/frappe/public/js/frappe/desk.js
@@ -1,14 +1,6 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
-if(!console) {
- var console = {
- log: function(txt) {
- // suppress
- }
- }
-}
-
$(document).ready(function() {
frappe.assets.check();
frappe.provide('frappe.app');
@@ -19,7 +11,7 @@ frappe.Application = Class.extend({
init: function() {
this.load_startup();
},
-
+
load_startup: function() {
var me = this;
if(window.app) {
@@ -37,56 +29,70 @@ frappe.Application = Class.extend({
});
} else {
this.startup();
- }
+ }
},
startup: function() {
// load boot info
this.load_bootinfo();
- // page container
- this.make_page_container();
-
+ if(user!="Guest") this.set_user_display_settings();
+
// navbar
this.make_nav_bar();
-
+
// favicon
this.set_favicon();
-
- if(user!="Guest") this.set_user_display_settings();
-
+
this.setup_keyboard_shortcuts();
-
+
// control panel startup code
this.run_startup_js();
+
if(frappe.boot) {
- // route to home page
- frappe.route();
+ if(localStorage.getItem("session_lost_route")) {
+ window.location.hash = localStorage.getItem("session_lost_route");
+ localStorage.removeItem("session_lost_route");
+ }
+
}
-
+
+ // page container
+ this.make_page_container();
+
+ // route to home page
+ frappe.route();
+
// trigger app startup
$(document).trigger('startup');
this.start_notification_updates();
-
+
$(document).trigger('app_ready');
},
-
+
set_user_display_settings: function() {
- frappe.ui.set_user_background(frappe.boot.user.background_image);
+ frappe.ui.set_user_background(frappe.boot.user.background_image, null,
+ frappe.boot.user.background_style);
},
-
+
load_bootinfo: function() {
if(frappe.boot) {
frappe.modules = frappe.boot.modules;
this.check_metadata_cache_status();
this.set_globals();
this.sync_pages();
+ if(frappe.boot.timezone_info) {
+ moment.tz.add(frappe.boot.timezone_info);
+ }
+ if(frappe.boot.print_css) {
+ frappe.dom.set_style(frappe.boot.print_css)
+ }
} else {
this.set_as_guest();
}
},
-
+
check_metadata_cache_status: function() {
if(frappe.boot.metadata_version != localStorage.metadata_version) {
localStorage.clear();
@@ -94,22 +100,22 @@ frappe.Application = Class.extend({
frappe.assets.init_local_storage();
}
},
-
+
start_notification_updates: function() {
var me = this;
setInterval(function() {
me.refresh_notifications();
}, 30000);
-
+
// first time loaded in boot
$(document).trigger("notification-update");
-
+
// refresh notifications if user is back after sometime
$(document).on("session_alive", function() {
me.refresh_notifications();
})
},
-
+
refresh_notifications: function() {
if(frappe.session_alive) {
return frappe.call({
@@ -124,7 +130,7 @@ frappe.Application = Class.extend({
});
}
},
-
+
set_globals: function() {
// for backward compatibility
user = frappe.boot.user.name;
@@ -132,15 +138,15 @@ frappe.Application = Class.extend({
user_defaults = frappe.boot.user.defaults;
user_roles = frappe.boot.user.roles;
user_email = frappe.boot.user.email;
- sys_defaults = frappe.boot.sysdefaults;
+ sys_defaults = frappe.boot.sysdefaults;
},
sync_pages: function() {
// clear cached pages if timestamp is not found
if(localStorage["page_info"]) {
frappe.boot.allowed_pages = [];
page_info = JSON.parse(localStorage["page_info"]);
- $.each(frappe.boot.page_info, function(name, modified) {
- if(page_info[name]!=modified) {
+ $.each(frappe.boot.page_info, function(name, p) {
+ if(!page_info[name] || (page_info[name].modified != p.modified)) {
delete localStorage["_page:" + name];
}
frappe.boot.allowed_pages.push(name);
@@ -171,7 +177,7 @@ frappe.Application = Class.extend({
make_nav_bar: function() {
// toolbar
if(frappe.boot) {
- frappe.container.frappe_toolbar = new frappe.ui.toolbar.Toolbar();
+ frappe.frappe_toolbar = new frappe.ui.toolbar.Toolbar();
}
},
logout: function() {
@@ -189,14 +195,14 @@ frappe.Application = Class.extend({
})
},
redirect_to_login: function() {
- window.location.href = 'index.html';
+ window.location.href = '/';
},
set_favicon: function() {
var link = $('link[type="image/x-icon"]').remove().attr("href");
$(' ').appendTo("head");
$(' ').appendTo("head");
},
-
+
setup_keyboard_shortcuts: function() {
$(document)
.keydown("meta+g ctrl+g", function(e) {
@@ -246,9 +252,9 @@ frappe.Application = Class.extend({
})
},
-
+
run_startup_js: function() {
if(frappe.boot.startup_js)
eval(frappe.boot.startup_js);
}
-})
\ No newline at end of file
+})
diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js
index 180fabf93e..cdaa62defc 100644
--- a/frappe/public/js/frappe/dom.js
+++ b/frappe/public/js/frappe/dom.js
@@ -116,6 +116,10 @@ frappe.get_modal = function(title, body_html) {
\
'+body_html+'\
\
+ \
\
\
').appendTo(document.body);
@@ -170,52 +174,6 @@ frappe.get_shade = function(color, factor) {
+ get_hex(get_int(color.substr(4,2)) + factor)
}
-frappe.get_gradient_css = function(col, diff) {
- if(!diff) diff = 10
- var col1 = frappe.get_shade(col, diff);
- var col2 = frappe.get_shade(col, -diff);
- return "\nbackground-color: " + col + " !important;"
- +"\nbackground: -moz-linear-gradient(top, #"+col1+" 0%, #"+col2+" 99%) !important;"
- +"\nbackground:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#"+col1+"), color-stop(99%,#"+col2+")) !important;"
- +"\nbackground:-webkit-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-ms-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%) !important;"
- +"\nbackground:linear-gradient(top, #"+col1+" 0%,#%"+col2+" 99%) !important;"
- +"\nfilter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#"+col1+"', endColorstr='#"+col1+"',GradientType=0 ) !important;"
-}
-
-$.fn.gradientify = function(col) {
- if(!col) col = this.css("background-color");
- var col1 = frappe.get_shade(col, 1.05);
- var col2 = frappe.get_shade(col, 0.95);
-
- this.css({
- "background": "-moz-linear-gradient(top, #"+col1+" 0%, #"+col2+" 99%)"
- });
- this.css({
- "background": "-webkit-gradient(linear, left top, left bottom, color-stop(0%,#"+col1+"), color-stop(99%,#"+col2+"))"
- });
- this.css({
- "background": "-webkit-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%)"
- });
- this.css({
- "background": "-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "-ms-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "-o-linear-gradient(top, #"+col1+" 0%,#"+col2+" 99%);"
- });
- this.css({
- "background": "linear-gradient(top, #"+col1+" 0%,#%"+col2+" 99%);"
- });
- this.css({
- "filter": "progid:DXImageTransform.Microsoft.gradient( startColorstr='#"+col1+"', endColorstr='#"+col1+"',GradientType=0 )"
- });
-}
-
frappe.get_cookie = function(c) {
var clist = (document.cookie+'').split(';');
var cookies = {};
@@ -239,30 +197,31 @@ frappe.dom.set_box_shadow = function(ele, spread) {
// create options
for(var i=0; i').html(label).attr('value', value).appendTo(this);
+ if (is_null(v)) {
+ var value = null;
+ var label = null;
+ } else {
+ var is_value_null = is_null(v.value);
+ var is_label_null = is_null(v.label);
+
+ if (is_value_null && is_label_null) {
+ var value = v;
+ var label = __(v);
+ } else {
+ var value = is_value_null ? "" : v.value;
+ var label = is_label_null ? __(value) : __(v.label);
+ }
+ }
+ $('').html(cstr(label)).attr('value', value).appendTo(this);
}
// select the first option
this.selectedIndex = 0;
return $(this);
}
$.fn.set_working = function() {
- var ele = this.get(0);
- $(ele).prop('disabled', true);
- if(ele.loading_img) {
- $(ele.loading_img).toggle(true);
- } else {
- ele.loading_img = $(' ')
- .insertAfter(ele);
- }
+ this.prop('disabled', true);
}
$.fn.done_working = function() {
- var ele = this.get(0);
- $(ele).prop('disabled', false);
- if(ele.loading_img) {
- $(ele.loading_img).toggle(false);
- };
+ this.prop('disabled', false);
}
})(jQuery);
diff --git a/frappe/public/js/frappe/form/assign_to.js b/frappe/public/js/frappe/form/assign_to.js
index 6bf24bdd76..7fb81f3cfb 100644
--- a/frappe/public/js/frappe/form/assign_to.js
+++ b/frappe/public/js/frappe/form/assign_to.js
@@ -35,41 +35,45 @@ frappe.ui.form.AssignTo = Class.extend({
var me = this;
this.frm.get_docinfo().assignments = d;
this.$list.empty();
+
+ if(me.primary_action) {
+ me.primary_action.remove();
+ me.primary_action = null;
+ }
+
if(this.dialog) {
this.dialog.hide();
}
if(d && d.length) {
for(var i=0; i\
- %(avatar)s %(fullname)s \
- × ', info))
+ var info = frappe.user_info(d[i].owner);
+ info.owner = d[i].owner;
+ info.image = frappe.user_info(d[i].owner).image;
+ info.description = d[i].description || "";
+
+ $(repl('', info))
.appendTo(this.$list);
- this.$list.find(".avatar").css("margin-top", "-7px")
- this.$list.find('.avatar img').centerImage();
+ if(d[i].owner===user) {
+ me.primary_action = this.frm.appframe.add_primary_action(__("Assignment Complete"), function() {
+ me.remove(user);
+ }, "icon-ok", "btn-success")
+ }
}
// set remove
this.$list.find('a.close').click(function() {
- frappe.call({
- method:'frappe.widgets.form.assign_to.remove',
- args: {
- doctype: me.frm.doctype,
- name: me.frm.docname,
- assign_to: $(this).attr('data-owner')
- },
- callback:function(r,rt) {
- me.render(r.message);
- me.frm.toolbar.show_infobar();
- me.frm.comments.refresh();
- }
- });
+ me.remove($(this).attr('data-owner'));
return false;
});
} else {
@@ -84,35 +88,22 @@ frappe.ui.form.AssignTo = Class.extend({
fields: [
{fieldtype:'Link', fieldname:'assign_to', options:'User',
label:__("Assign To"),
- description:__("Add to To Do List of"), reqd:true},
+ description:__("Add to To Do List Of"), reqd:true},
{fieldtype:'Data', fieldname:'description', label:__("Comment"), reqd:true},
{fieldtype:'Date', fieldname:'date', label: __("Complete By")},
{fieldtype:'Select', fieldname:'priority', label: __("Priority"),
options:'Low\nMedium\nHigh', 'default':'Medium'},
{fieldtype:'Check', fieldname:'notify',
- label:__("Notify By Email"), "default":1},
- {fieldtype:'Check', fieldname:'restrict',
- label:__("Add This To User's Restrictions")
- + ' '},
+ label:__("Notify by Email"), "default":1},
{fieldtype:'Button', label:__("Add"), fieldname:'add_btn'}
]
});
- me.dialog.fields_dict.restrict.$wrapper
- .find(".assign-user-properties")
- .on("click", function() {
- frappe.route_options = {
- property: me.frm.doctype,
- user: me.dialog.get_value("assign_to")
- };
- frappe.set_route("user-properties");
- });
-
me.dialog.fields_dict.add_btn.input.onclick = function() {
var assign_to = me.dialog.fields_dict.assign_to.get_value();
var args = me.dialog.get_values();
- if(assign_to) {
+ if(args && assign_to) {
return frappe.call({
method:'frappe.widgets.form.assign_to.add',
args: $.extend(args, {
@@ -135,22 +126,27 @@ frappe.ui.form.AssignTo = Class.extend({
}
me.dialog.clear();
- (function toggle_restrict() {
- var can_restrict = frappe.model.can_restrict(me.frm.doctype, me.frm);
- me.dialog.fields_dict.restrict.$wrapper.toggle(can_restrict);
- me.dialog.get_input("restrict").prop("checked", can_restrict);
- })();
-
if(me.frm.meta.title_field) {
me.dialog.set_value("description", me.frm.doc[me.frm.meta.title_field])
}
me.dialog.show();
-
- if(!frappe.perm.get_perm(me.frm.doctype)[0].restricted) {
- me.dialog.fields_dict.restrict.set_input(0);
- me.dialog.fields_dict.restrict.$wrapper.toggle(false);
- }
+ },
+ remove: function(owner) {
+ var me = this;
+ frappe.call({
+ method:'frappe.widgets.form.assign_to.remove',
+ args: {
+ doctype: me.frm.doctype,
+ name: me.frm.docname,
+ assign_to: owner
+ },
+ callback:function(r,rt) {
+ me.render(r.message);
+ me.frm.toolbar.show_infobar();
+ me.frm.comments.refresh();
+ }
+ });
}
});
diff --git a/frappe/public/js/frappe/form/attachments.js b/frappe/public/js/frappe/form/attachments.js
index a84c45b564..580d7c73e9 100644
--- a/frappe/public/js/frappe/form/attachments.js
+++ b/frappe/public/js/frappe/form/attachments.js
@@ -12,6 +12,8 @@ frappe.ui.form.Attachments = Class.extend({
var me = this;
this.wrapper = $('\
\
+
'
+ +__("You can also drag and drop attachments")+'
\
').appendTo(this.parent);
this.$list = this.wrapper.find(".attachment-list");
@@ -61,14 +63,14 @@ frappe.ui.form.Attachments = Class.extend({
},
add_attachment: function(attachment) {
var file_name = attachment.file_name;
- var file_url = attachment.file_url;
+ var file_url = this.get_file_url(attachment);
var fileid = attachment.name;
if (!file_name) {
file_name = file_url;
}
var me = this;
- var $attach = $(repl('\
+ var $attach = $(repl('
\
\
").appendTo(this.parent);
- this.input = $('\
-
')
- .appendTo(this.row)
- .find("textarea");
- this.button = $('\
- \
- \
-
')
- .appendTo(this.row)
- .find("button")
+ $('').appendTo(this.parent);
+ this.list = $('')
+ .appendTo(this.parent);
+
+ this.row = $(repl('', {image: frappe.user_info(user).image,
+ fullname: user_fullname})).appendTo(this.parent);
+
+ this.input = this.row.find(".form-control");
+ this.button = this.row.find(".btn-go")
.click(function() {
me.add_comment(this);
});
- this.list = $('')
- .appendTo(this.parent);
- },
- get_comments: function() {
- return this.frm.get_docinfo().comments;
},
refresh: function() {
var me = this;
@@ -37,27 +41,86 @@ frappe.ui.form.Comments = Class.extend({
}
this.wrapper.toggle(true);
this.list.empty();
- var comments = this.get_comments();
+
+ comments = [{"comment": "Created", "comment_type": "Created",
+ "comment_by": this.frm.doc.owner, "creation": this.frm.doc.creation}].concat(this.get_comments());
+
$.each(comments, function(i, c) {
- if(frappe.model.can_delete("Comment")) {
+ if((c.comment_type || "Comment") === "Comment" && frappe.model.can_delete("Comment")) {
c["delete"] = ' × ';
} else {
c["delete"] = "";
}
- c.image = frappe.user_info(c.comment_by).image;
- c.comment_on = dateutil.comment_when(c.creation);
+ c.image = frappe.user_info(c.comment_by).image || frappe.get_gravatar(c.comment_by);
+ c.comment_on = comment_when(c.creation);
c.fullname = frappe.user_info(c.comment_by).fullname;
- $(repl('
', doc))
+ %(content)s
\
+ ', doc))
.appendTo(this.body);
-
- if(!doc.name) {
- comm.find(".show-details").toggle(false);
- }
-
- comm.find(".comm-header")
- .css({"cursor":"pointer"})
- .click(function() {
- $(this).parent().find(".comm-content").toggle();
- });
-
this.comm_list.push(comm);
- comm.find(".comm-content .inner").html(doc.content);
}
});
+frappe.last_edited_communication = {};
+frappe.standard_replies = {};
+
frappe.views.CommunicationComposer = Class.extend({
init: function(opts) {
$.extend(this, opts)
this.make();
- this.dialog.show();
},
make: function() {
var me = this;
@@ -143,6 +130,8 @@ frappe.views.CommunicationComposer = Class.extend({
description:__("Email addresses, separted by commas")},
{label:__("Subject"), fieldtype:"Data", reqd: 1,
fieldname:"subject"},
+ {label:__("Standard Reply"), fieldtype:"Link", options:"Standard Reply",
+ fieldname:"standard_reply"},
{label:__("Message"), fieldtype:"Text Editor", reqd: 1,
fieldname:"content"},
{label:__("Send As Email"), fieldtype:"Check",
@@ -169,6 +158,7 @@ frappe.views.CommunicationComposer = Class.extend({
this.dialog.$wrapper.find("[data-edit='outdent']").remove();
this.dialog.get_input("send").addClass("btn-primary");
+
$(document).on("upload_complete", function(event, attachment) {
if(me.dialog.display) {
var wrapper = $(me.dialog.fields_dict.select_attachments.wrapper);
@@ -190,16 +180,75 @@ frappe.views.CommunicationComposer = Class.extend({
}
})
this.prepare();
+ this.dialog.show();
+
},
prepare: function() {
this.setup_print();
this.setup_attach();
this.setup_email();
this.setup_autosuggest();
+ this.setup_last_edited_communication();
+ this.setup_standard_reply();
$(this.dialog.fields_dict.recipients.input).val(this.recipients || "").change();
$(this.dialog.fields_dict.subject.input).val(this.subject || "").change();
this.setup_earlier_reply();
},
+
+ setup_standard_reply: function() {
+ var me = this;
+ this.dialog.get_input("standard_reply").on("change", function() {
+ var standard_reply = $(this).val();
+ var prepend_reply = function() {
+ var content_field = me.dialog.fields_dict.content;
+ var content = content_field.get_value() || "";
+ content_field.set_input(
+ frappe.standard_replies[standard_reply]
+ + " " + content);
+ }
+ if(frappe.standard_replies[standard_reply]) {
+ prepend_reply();
+ } else {
+ $.ajax({
+ url:"/api/resource/Standard Reply/" + standard_reply,
+ statusCode: {
+ 200: function(data) {
+ frappe.standard_replies[standard_reply] = data.data.response;
+ prepend_reply();
+ }
+ }
+ });
+ }
+ });
+ },
+
+ setup_last_edited_communication: function() {
+ var me = this;
+ this.dialog.onhide = function() {
+ if(cur_frm && cur_frm.docname) {
+ if (!frappe.last_edited_communication[cur_frm.doctype]) {
+ frappe.last_edited_communication[cur_frm.doctype] = {};
+ }
+ frappe.last_edited_communication[cur_frm.doctype][cur_frm.docname] = {
+ recipients: me.dialog.get_value("recipients"),
+ subject: me.dialog.get_value("subject"),
+ content: me.dialog.get_value("content"),
+ }
+ }
+ }
+
+ this.dialog.onshow = function() {
+ if (cur_frm && cur_frm.docname &&
+ (frappe.last_edited_communication[cur_frm.doctype] || {})[cur_frm.docname]) {
+
+ c = frappe.last_edited_communication[cur_frm.doctype][cur_frm.docname];
+ me.dialog.set_value("subject", c.subject || "");
+ me.dialog.set_value("recipients", c.recipients || "");
+ me.dialog.set_value("content", c.content || "");
+ }
+ }
+
+ },
setup_print: function() {
// print formats
var fields = this.dialog.fields_dict;
@@ -211,13 +260,20 @@ frappe.views.CommunicationComposer = Class.extend({
// select print format
$(fields.select_print_format.wrapper).toggle(false);
- $(fields.select_print_format.input)
- .empty()
- .add_options(cur_frm.print_formats)
- .val(cur_frm.print_formats[0]);
+
+ if (cur_frm) {
+ $(fields.select_print_format.input)
+ .empty()
+ .add_options(cur_frm.print_preview.print_formats)
+ .val(cur_frm.print_preview.print_formats[0]);
+ } else {
+ $(fields.attach_document_print.wrapper).toggle(false);
+ }
},
setup_attach: function() {
+ if (!cur_frm) return;
+
var fields = this.dialog.fields_dict;
var attach = $(fields.select_attachments.wrapper);
@@ -225,8 +281,11 @@ frappe.views.CommunicationComposer = Class.extend({
if(files.length) {
$(""+__("Add Attachments")+":
").appendTo(attach.empty());
$.each(files, function(i, f) {
- $(repl(" %(file)s
", {file:f})).appendTo(attach)
+ if (!f.file_name) return;
+
+ $(repl(" %(file_name)s
", f))
+ .appendTo(attach)
});
}
},
@@ -265,20 +324,29 @@ frappe.views.CommunicationComposer = Class.extend({
})
if(form_values.attach_document_print) {
- _p.build(form_values.select_print_format || "", function(print_format_html) {
- me.send_email(btn, form_values, selected_attachments, print_format_html);
- });
+ if (cur_frm.print_preview.is_old_style(form_values.select_print_format || "")) {
+ cur_frm.print_preview.with_old_style({
+ format: form_values.select_print_format,
+ callback: function(print_html) {
+ me.send_email(btn, form_values, selected_attachments, print_html);
+ }
+ });
+ } else {
+ me.send_email(btn, form_values, selected_attachments, null, form_values.select_print_format || "");
+ }
+
} else {
me.send_email(btn, form_values, selected_attachments);
}
});
},
- send_email: function(btn, form_values, selected_attachments, print_html) {
+ send_email: function(btn, form_values, selected_attachments, print_html, print_format) {
var me = this;
if(!form_values.attach_document_print) {
- print_html = "";
+ print_html = null;
+ print_format = null;
}
if(form_values.send_email) {
@@ -303,6 +371,7 @@ frappe.views.CommunicationComposer = Class.extend({
send_me_a_copy: form_values.send_me_a_copy,
send_email: form_values.send_email,
print_html: print_html,
+ print_format: print_format,
communication_medium: form_values.communication_medium,
sent_or_received: form_values.sent_or_received,
attachments: selected_attachments
@@ -313,7 +382,13 @@ frappe.views.CommunicationComposer = Class.extend({
if(form_values.send_email)
msgprint(__("Email sent to {0}", [form_values.recipients]));
me.dialog.hide();
- cur_frm.reload_doc();
+
+ if (cur_frm) {
+ if (cur_frm.docname && (frappe.last_edited_communication[cur_frm.doctype] || {})[cur_frm.docname]) {
+ delete frappe.last_edited_communication[cur_frm.doctype][cur_frm.docname];
+ }
+ cur_frm.reload_doc();
+ }
} else {
msgprint(__("There were errors while sending email. Please try again."));
}
@@ -323,7 +398,7 @@ frappe.views.CommunicationComposer = Class.extend({
setup_earlier_reply: function() {
var fields = this.dialog.fields_dict;
- var comm_list = cur_frm.communication_view
+ var comm_list = (cur_frm && cur_frm.communication_view)
? cur_frm.communication_view.list
: [];
var signature = frappe.boot.user.email_signature || "";
@@ -342,7 +417,8 @@ frappe.views.CommunicationComposer = Class.extend({
if(comm_list.length > 0) {
fields.content.set_input(reply
+ "
"
- +"-----"+__("In response to")+"-----
"
+ +"-----"+__("In response to")+"-----"
+ +""+__("Please reply above this line or remove it if you are replying below it")+"
"
+ comm_list[0].content);
} else {
fields.content.set_input(reply);
diff --git a/frappe/public/js/frappe/views/container.js b/frappe/public/js/frappe/views/container.js
index e0f6a0ed6c..b391097e6a 100644
--- a/frappe/public/js/frappe/views/container.js
+++ b/frappe/public/js/frappe/views/container.js
@@ -15,7 +15,7 @@ frappe.views.Container = Class.extend({
this.pagemargin = 50;
},
add_page: function(label, onshow, onhide) {
- var page = $('
')
+ var page = $('
')
.attr('id', "page-" + label)
.attr("data-page-route", label)
.toggle(false)
diff --git a/frappe/public/js/frappe/views/doclistview.js b/frappe/public/js/frappe/views/doclistview.js
index d4a4d4334f..6385aabab6 100644
--- a/frappe/public/js/frappe/views/doclistview.js
+++ b/frappe/public/js/frappe/views/doclistview.js
@@ -57,52 +57,57 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
'+__('Loading')+'...
')
.appendTo(this.$page.find(".layout-main-section"));
- $('')
- .appendTo(this.$page.find(".layout-side-section"));
-
this.$page.find(".layout-main-section")
.addClass("listview-main-section")
.parent().css({"margin-top":"-15px"});
this.appframe = this.page.appframe;
var module = locals.DocType[this.doctype].module;
- this.appframe.set_title(__(this.doctype) + " " + __("List"));
+ this.appframe.set_title(__("{0} List", [__(this.doctype)]));
this.appframe.add_module_icon(module, this.doctype, null, true);
- this.appframe.set_title_left(function() { frappe.set_route(frappe.get_module(module).link); });
+ this.appframe.set_title_left(function() {
+ frappe.set_route(frappe.listview_parent_route[me.doctype]
+ || frappe.get_module(module).link);
+ });
this.appframe.set_views_for(this.doctype, "list");
},
setup: function() {
+ var me = this;
this.can_delete = frappe.model.can_delete(this.doctype);
this.meta = locals.DocType[this.doctype];
this.$page.find('.frappe-list-area').empty(),
this.setup_listview();
- this.setup_docstatus_filter();
this.init_list(false);
this.init_stats();
this.init_minbar();
this.show_match_help();
+ this.init_listview();
+ this.make_help();
+ this.setup_filterable();
+ this.init_filters();
+ this.$page.find(".show_filters").css({"padding":"15px", "margin":"0px -15px"});
+ this.$w.on("render-complete", function() {
+ // if only one record, open the form, if not coming from the form itself
+ if(me.data.length===1
+ && frappe.get_prev_route()[2]!== me.data[0].name) {
+ frappe.set_route("Form", me.doctype, me.data[0].name);
+ }
+ });
+ },
+
+ init_listview: function() {
if(this.listview.settings.onload) {
this.listview.settings.onload(this);
}
+
if(this.listview.settings.set_title_left) {
this.appframe.set_title_left(this.listview.settings.set_title_left);
+ } else if(this.listview.settings.parent_route) {
+ this.appframe.set_title_left(function() {
+ frappe.set_route(me.listview.settings.parent_route);
+ });
}
- this.make_help();
- this.$page.find(".show_filters").css({"padding":"15px", "margin":"0px -15px"});
- var me = this;
- // this.$w.on("render-complete", function() {
- // me.set_sidebar_height();
- // });
},
set_sidebar_height: function() {
@@ -112,28 +117,73 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.$page.find(".layout-main-section").css({"min-height": h_side});
},
+ setup_filterable: function() {
+ var me = this;
+ this.$page.on("click", ".filterable", function(e) {
+ var filters = $(this).attr("data-filter").split("|");
+ var added = false;
+ $.each(filters, function(i, f) {
+ f = f.split(",");
+ if(f[2]==="Today") {
+ f[2] = frappe.datetime.get_today();
+ } else if(f[2]=="User") {
+ f[2] = user;
+ }
+ added = added || me.filter_list.add_filter(me.doctype,
+ f[0], f[1], f.slice(2).join(","));
+ });
+ added && me.run();
+ })
+ },
+
+ init_filters: function() {
+ var me = this;
+ if(this.listview.settings.filters) {
+ $.each(this.listview.settings.filters, function(i, f) {
+ if(f.length===3) {
+ f = [me.doctype, f[0], f[1], f[2]]
+ }
+ me.filter_list.add_filter(f[0], f[1], f[2], f[3]);
+ });
+ }
+ },
+
show_match_help: function() {
var me = this;
- var match_rules = frappe.perm.get_match_rules(this.doctype);
+ var match_rules_list = frappe.perm.get_match_rules(this.doctype);
var perm = frappe.perm.get_perm(this.doctype);
- if(keys(match_rules).length) {
- var match_text = []
- $.each(match_rules, function(key, values) {
- if(values.length==0) {
- match_text.push(__(key) + __(" is not set"));
- } else if(values.length) {
- match_text.push(__(key) + " = " + frappe.utils.comma_or(values));
+ if(match_rules_list.length) {
+ var or_match_text = [];
+
+ $.each(match_rules_list, function(i, match_rules) {
+ var match_text = []
+ $.each(match_rules, function(key, values) {
+ if(values.length==0) {
+ match_text.push(__(key) + __(" is not set"));
+ } else if(values.length) {
+ match_text.push(__(key) + " = " + frappe.utils.comma_or(values));
+ }
+ });
+
+ if (match_text.length) {
+ var txt = "" + $.map(match_text, function(txt) { return ""+txt+" " }).join("") + " ";
+ or_match_text.push(txt);
}
});
- if(perm[0].restricted) {
- match_text.push(__("Or Created By") + " = " + user);
+ if (or_match_text.length) {
+ frappe.utils.set_footnote(this, this.$page.find(".layout-main-section"),
+ ""
+ + __("Additional filters based on User Permissions, having:") + "
"
+ + or_match_text.join(""
+ + __("or") + "
")
+ + ""
+ + __("Note: fields having empty value for above criteria are not filtered out.")
+ + "
");
+ $(this.footnote_area).css({"margin-top":"0px", "margin-bottom":"20px"});
}
- frappe.utils.set_footnote(this, this.$page.find(".layout-main-section"),
- "" + __("Showing only for (if not empty)") + ":
"
- + $.map(match_text, function(txt) { return ""+txt+" " }).join("")) + " ";
- $(this.footnote_area).css({"margin-top":"0px", "margin-bottom":"20px"});
}
},
make_help: function() {
@@ -142,19 +192,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.appframe.add_help_button(this.meta.description);
}
},
- setup_docstatus_filter: function() {
- var me = this;
- this.can_submit = $.map(locals.DocPerm || [], function(d) {
- if(d.parent==me.meta.name && d.submit) return 1
- else return null;
- }).length;
- if(this.can_submit) {
- this.$page.find('.show-docstatus').removeClass('hide');
- this.$page.find('.show-docstatus input').click(function() {
- me.run();
- })
- }
- },
setup_listview: function() {
this.listview = frappe.views.get_listview(this.doctype, this);
this.wrapper = this.$page.find('.frappe-list-area');
@@ -207,7 +244,11 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
var me = this;
me.filter_list.clear_filters();
$.each(frappe.route_options, function(key, value) {
- me.filter_list.add_filter(me.doctype, key, "=", value);
+ if($.isArray(value)) {
+ me.filter_list.add_filter(me.doctype, key, value[0], value[1]);
+ } else {
+ me.filter_list.add_filter(me.doctype, key, "=", value);
+ }
});
frappe.route_options = null;
me.run();
@@ -229,14 +270,11 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
make_no_result: function() {
var new_button = frappe.boot.user.can_create.indexOf(this.doctype)!=-1
? (''+
- __('Make a new') + ' %(doctype_label)s
')
+ list_view_doc="' + this.doctype + '">'+
+ __('Make a new {0}', [__(this.doctype)]) + '')
: '';
- var no_result_message = repl('\
-
' + __("No") + ' %(doctype_label)s ' + __("found") + '
' + new_button + '
', {
- doctype_label: __(this.doctype),
- doctype: this.doctype,
- });
+ var no_result_message = '\
+
' + __("No {0} found", [__(this.doctype)]) + '
' + new_button + '
';
return no_result_message;
},
@@ -245,16 +283,10 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
this.listview.render(row, data, this);
},
get_args: function() {
- var docstatus_list = this.can_submit ? $.map(this.$page.find('.show-docstatus :checked'),
- function(inp) {
- return $(inp).attr('data-docstatus');
- }) : []
-
var args = {
doctype: this.doctype,
fields: this.listview.fields,
filters: this.filter_list.get_filters(),
- docstatus: docstatus_list,
order_by: this.listview.order_by || undefined,
group_by: this.listview.group_by || undefined,
}
@@ -269,13 +301,21 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
init_minbar: function() {
var me = this;
this.appframe.add_icon_btn("2", 'icon-tag', __('Show Tags'), function() { me.toggle_tags(); });
- this.wrapper.on("click", ".list-tag-preview", function() { me.toggle_tags(); });
+ this.$page.on("click", ".list-tag-preview", function() { me.toggle_tags(); });
+
+ this.appframe.add_icon_btn("2", 'icon-user', __('Assigned To Me'),
+ function() {
+ me.filter_list.add_filter(me.doctype, "_assign", 'like', '%' + user + '%');
+ me.run();
+ });
+
if(this.can_delete || this.listview.settings.selectable) {
- this.appframe.add_icon_btn("2", 'icon-remove', __('Delete'), function() { me.delete_items(); });
this.appframe.add_icon_btn("2", 'icon-ok', __('Select All'), function() {
me.$page.find('.list-delete').prop("checked",
me.$page.find('.list-delete:checked').length ? false : true);
});
+ this.appframe.add_icon_btn("2", 'icon-trash', __('Delete'),
+ function() { me.delete_items(); });
}
if(frappe.model.can_import(this.doctype)) {
this.appframe.add_icon_btn("2", "icon-upload", __("Import"), function() {
@@ -284,16 +324,23 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
})
});
}
- if(frappe.model.can_restrict(this.doctype)) {
+ if(frappe.model.can_set_user_permissions(this.doctype)) {
this.appframe.add_icon_btn("2", "icon-shield",
- __("User Permission Restrictions"), function() {
+ __("User Permissions Manager"), function() {
frappe.route_options = {
- property: me.doctype
+ doctype: me.doctype
};
- frappe.set_route("user-properties");
+ frappe.set_route("user-permissions");
});
}
if(in_list(user_roles, "System Manager")) {
+ this.appframe.add_icon_btn("2", "icon-lock",
+ __("Role Permissions Manager"), function() {
+ frappe.route_options = {
+ doctype: me.doctype
+ };
+ frappe.set_route("permission-manager");
+ });
this.appframe.add_icon_btn("2", "icon-glass", __("Customize"), function() {
frappe.set_route("Form", "Customize Form", {
doctype: me.doctype
@@ -314,9 +361,10 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
get_checked_items: function() {
return $.map(this.$page.find('.list-delete:checked'), function(e) {
- return $(e).data('data');
+ return $(e).parents(".list-row:first").data('data');
});
},
+
delete_items: function() {
var me = this;
var dl = this.get_checked_items();
diff --git a/frappe/public/js/frappe/views/ganttview.js b/frappe/public/js/frappe/views/ganttview.js
index 6c9d1bd80d..f6c102db3f 100644
--- a/frappe/public/js/frappe/views/ganttview.js
+++ b/frappe/public/js/frappe/views/ganttview.js
@@ -11,7 +11,7 @@ frappe.views.GanttFactory = frappe.views.Factory.extend({
$(page).on("show", function() {
me.set_filters_from_route_options();
});
-
+
var options = {
doctype: route[1],
page: page
@@ -29,7 +29,7 @@ frappe.views.Gantt = Class.extend({
frappe.require('assets/frappe/js/lib/jQuery.Gantt/css/style.css');
frappe.require('assets/frappe/js/lib/jQuery.Gantt/js/jquery.fn.gantt.js');
-
+
this.make_page();
frappe.route_options ?
this.set_filters_from_route_options() :
@@ -38,21 +38,21 @@ frappe.views.Gantt = Class.extend({
make_page: function() {
var module = locals.DocType[this.doctype].module,
me = this;
-
+
this.appframe = this.page.appframe;
this.appframe.set_title(__("Gantt Chart") + " - " + __(this.doctype));
this.appframe.add_module_icon(module)
this.appframe.set_views_for(this.doctype, "gantt");
- this.appframe.set_title_right("Refresh",
+ this.appframe.set_title_right("Refresh",
function() { me.refresh(); }, "icon-refresh")
- this.appframe.add_field({fieldtype:"Date", label:"From",
+ this.appframe.add_field({fieldtype:"Date", label:"From",
fieldname:"start", "default": frappe.datetime.month_start(), input_css: {"z-index": 3}});
- this.appframe.add_field({fieldtype:"Date", label:"To",
+ this.appframe.add_field({fieldtype:"Date", label:"To",
fieldname:"end", "default": frappe.datetime.month_end(), input_css: {"z-index": 3}});
-
+
if(this.filters) {
$.each(this.filters, function(i, df) {
me.appframe.add_field(df);
@@ -66,7 +66,7 @@ frappe.views.Gantt = Class.extend({
.empty()
.css('min-height', '300px')
.html('Loading...
');
-
+
var me = this;
return frappe.call({
method: this.get_events_method,
@@ -95,11 +95,11 @@ frappe.views.Gantt = Class.extend({
onAddClick: function(dt, rowId) {
newdoc(me.doctype);
}
- });
+ });
}
}
})
-
+
},
set_filter: function(doctype, value) {
var me = this;
@@ -116,7 +116,7 @@ frappe.views.Gantt = Class.extend({
me = this;
if(this.filters) {
$.each(this.filters, function(i, df) {
- filter_vals[df.fieldname || df.label] =
+ filter_vals[df.fieldname || df.label] =
me.appframe.fields_dict[df.fieldname || df.label].get_parsed_value();
});
}
@@ -132,7 +132,7 @@ frappe.views.Gantt = Class.extend({
$.each(me.field_map, function(target, source) {
v[target] = v[source];
});
-
+
if(v.start && !v.end) {
v.end = new Date(v.start)
v.end.setHours(v.end.getHours() + 1);
@@ -140,28 +140,28 @@ frappe.views.Gantt = Class.extend({
if(v.start && v.end) {
source.push({
- name: v.title,
+ name: v.title,
desc: v.status,
values: [{
name: v.title,
- desc: v.title + " " + v.status,
- from: '/Date("'+v.start+'")/',
- to: '/Date("'+v.end+'")/',
+ desc: v.title + " " + (v.status || ""),
+ from: '/Date('+moment(v.start).format("X")+'000)/',
+ to: '/Date('+moment(v.end).format("X")+'000)/',
customClass: {
'danger':'ganttRed',
'warning':'ganttOrange',
'info':'ganttBlue',
'success':'ganttGreen',
'':'ganttGray'
- }[me.style_map ?
+ }[me.style_map ?
me.style_map[v.status] :
frappe.utils.guess_style(v.status, "standard")],
dataObj: v
}]
- })
+ })
}
});
- return source
+ return source
},
set_filters_from_route_options: function() {
var me = this;
diff --git a/frappe/public/js/frappe/views/grid_report.js b/frappe/public/js/frappe/views/grid_report.js
index 3dc7314cd0..c97e2e55d1 100644
--- a/frappe/public/js/frappe/views/grid_report.js
+++ b/frappe/public/js/frappe/views/grid_report.js
@@ -104,6 +104,7 @@ frappe.views.GridReport = Class.extend({
$.extend(this, opts);
this.wrapper = $('').appendTo(this.parent);
+ this.appframe.parent.find(".appframe").css({"padding-top": "0px"});
if(this.filters) {
this.make_filters();
@@ -255,7 +256,7 @@ frappe.views.GridReport = Class.extend({
} else if(v.fieldtype==='Button' && v.label==="Refresh") {
input = me.appframe.set_title_right(v.label, null, v.icon);
} else if(v.fieldtype==='Button') {
- input = me.appframe.add_primary_action(v.label, null, v.icon);
+ input = me.appframe.add_button(v.label, null, v.icon);
} else if(v.fieldtype==='Date') {
input = me.appframe.add_date(v.label);
} else if(v.fieldtype==='Label') {
@@ -353,8 +354,7 @@ frappe.views.GridReport = Class.extend({
this.round_off_data();
this.prepare_data_view();
// plot might need prepared data
- this.wrapper.find(".processing").toggle(true);
- this.wrapper.find(".processing").delay(2000).fadeOut(300);
+ show_alert("Updated", 2);
this.render();
this.render_plot && this.render_plot();
},
@@ -367,18 +367,10 @@ frappe.views.GridReport = Class.extend({
var me = this;
// plot wrapper
- this.plot_area = $('
').appendTo(this.wrapper);
- // print / export
- $('
').appendTo(this.wrapper);
-
- this.wrapper.find(".grid-report-export").click(function() { return me.export(); });
+ this.appframe.add_button(__("Export"), function() { return me.export(); }, "icon-download");
// grid wrapper
this.grid_wrapper = $("
').appendTo($(row).css({"position":"relative"})),
+
+ if(this.template) {
+ this.render_template(row, data);
+ } else {
+ this.render_standard_columns(row, data);
+ }
+
+ this.render_timestamp_and_comments(row, data);
+ this.render_tags(row, data);
+
+ },
+
+ render_template: function (row, data) {
+ $(frappe.render(this.template, {
+ doc: frappe.get_format_helper(data),
+ list: this
+ })).appendTo($('
').appendTo(row));
+ },
+
+ render_standard_columns: function(row, data) {
+ var left_cols = 4 + this.shift_right,
+ right_cols = 8 - this.shift_right,
+ body = $('
').appendTo(row),
colspans = 0,
me = this;
-
- me.render_avatar_and_id(data, body.find(".list-row-id-area"))
-
+
+ $(me.get_avatar_and_id(data, true)).appendTo(body.find(".list-row-id-area"));
+
// make table
$.each(this.columns, function(i, v) {
var colspan = v.colspan || 3;
colspans = colspans + flt(colspan)
-
+
if(colspans <= 12) {
- var col = me.make_column(body.find(".list-row-content-area"), colspan);
+ var col = me.make_column(body.find(".list-row-content-area"),
+ colspan);
me.render_column(data, col, v);
}
});
-
- var comments = data._comments ? JSON.parse(data._comments) : [];
- var tags = $.map((data._user_tags || "").split(","), function(v) { return v ? v : null; });
-
- var timestamp_and_comment =
+
+ },
+
+ render_timestamp_and_comments: function(row, data) {
+ var comments = data._comments ? JSON.parse(data._comments) : [],
+ tags = $.map((data._user_tags || "").split(","),
+ function(v) { return v ? v : null; }),
+ assign = data._assign ? JSON.parse(data._assign) : [],
+ me = this;
+
+ if(me.title_field && data[me.title_field]!==data.name) {
+ $('
')
+ .appendTo(row)
+ .css({"left": me.title_offset_left})
+ .html('
#' + data.name + " ");
+ }
+
+ $(row).find(".list-timestamp").remove();
+
+ var timestamp_and_comment =
$('
')
.appendTo(row)
- .html(""
- + (tags.length ? (
- '
' + tags.join(", ") + ' '
- ): "")
- + (comments.length ?
- ('
'
- + comments.length + " " + (
- comments.length===1 ? __("comment") : __("comments")) + ' ')
- : "")
- + comment_when(data.modified));
-
- // row #2
+ .html(frappe.render(frappe.templates.list_info_template, {
+ "tags": tags,
+ "comments": comments,
+ "assign": assign,
+ "data": data,
+ "doctype": this.doctype
+ }));
+ },
+
+ render_tags: function(row, data) {
+ var me = this;
var row2 = $('
').appendTo(row);
-
- // modified
- body.find(".list-last-modified").html(__("Last updated by") + ": " + frappe.user_info(data.modified_by).fullname);
-
+
if(!me.doclistview.tags_shown) {
row2.addClass("hide");
}
-
+
// add tags
var tag_editor = new frappe.ui.TagEditor({
parent: row2.find(".list-tag"),
@@ -228,17 +267,23 @@ frappe.views.ListView = Class.extend({
doctype: this.doctype,
docname: data.name
},
- user_tags: data._user_tags
+ user_tags: data._user_tags,
+ on_change: function(user_tags) {
+ data._user_tags = user_tags;
+ me.render_timestamp_and_comments(row, data);
+ }
});
tag_editor.$w.on("click", ".tagit-label", function() {
- me.doclistview.set_filter("_user_tags",
+ me.doclistview.set_filter("_user_tags",
$(this).text());
});
},
+
make_column: function(body, colspan) {
var col = $("
")
.appendTo(body)
.addClass("col-sm-" + cint(colspan))
+ .addClass("col-xs-" + (cint(colspan) + 2))
.css({
"white-space": "nowrap",
"text-overflow": "ellipsis",
@@ -247,45 +292,72 @@ frappe.views.ListView = Class.extend({
})
return col;
},
- render_avatar_and_id: function(data, parent) {
+ get_avatar_and_id: function(data, without_workflow) {
+ this.title_offset_left = 15;
+
+ var html = "";
+
+ // checkbox
if((frappe.model.can_delete(this.doctype) || this.settings.selectable) && !this.no_delete) {
- $('
')
- .data('name', data.name)
- .data('data', data)
- .css({"margin-right": "5px"})
- .appendTo(parent)
+ html += '
';
+
+ this.title_offset_left += 13 + 5;
}
-
- var $avatar = $(frappe.avatar(data.modified_by, false, __("Modified by")+": "
- + frappe.user_info(data.modified_by).fullname))
- .appendTo(parent)
- .css({"max-width": "100%"})
+ // avatar
+ var user_for_avatar = data.user_for_avatar || data.modified_by;
+ html += frappe.avatar(user_for_avatar, false, __("Modified by")+": "
+ + frappe.user_info(user_for_avatar).fullname)
+ this.title_offset_left += 30 + 5;
+
+ // docstatus lock
if(frappe.model.is_submittable(this.doctype)) {
- $(parent).append(repl('
\
- ', data));
- }
-
- var title = data[this.title_field || "name"];
- $("
")
- .attr("href", "#Form/" + data.doctype + "/" + encodeURIComponent(data.name))
- .html(title)
- .appendTo(parent.css({"overflow":"hidden"}));
-
- parent.attr("title", title).tooltip();
-
+ html += repl(' \
+ ', data);
+
+ this.title_offset_left += 15 + 4;
+ }
+
+ // title
+ var full_title = data[this.title_field || "name"], title = full_title;
+ if(full_title.length > 40) {
+ title = full_title.slice(0, 40) + "...";
+ }
+ html += repl(' %(title)s ', {
+ doctype: data.doctype,
+ name: encodeURIComponent(data.name),
+ title: title,
+ full_title: full_title,
+ });
+
+ this.title_offset_left += 5;
+
+ if(!without_workflow && this.workflow_state_fieldname) {
+ html+= repl('
\
+ %(value)s ', {
+ fieldname: this.workflow_state_fieldname,
+ value: data[this.workflow_state_fieldname],
+ style: frappe.utils.guess_style(data[this.workflow_state_fieldname])
+ });
+ }
+
+ return html;
},
+
render_column: function(data, parent, opts) {
var me = this;
if(opts.type) opts.type= opts.type.toLowerCase();
-
+
// style
if(opts.css) {
$.each(opts.css, function(k, v) { $(parent).css(k, v)});
}
-
+
// multiple content
if(opts.content.indexOf && opts.content.indexOf('+')!=-1) {
$.map(opts.content.split('+'), function(v) {
@@ -293,7 +365,7 @@ frappe.views.ListView = Class.extend({
});
return;
}
-
+
// content
if(typeof opts.content=='function') {
opts.content(parent, data, me);
@@ -305,7 +377,7 @@ frappe.views.ListView = Class.extend({
}
else if(opts.template) {
$(parent).append(repl(opts.template, data));
- }
+ }
else if(opts.type=="date" && data[opts.content]) {
$("
")
.html(frappe.datetime.str_to_user(data[opts.content]))
@@ -324,22 +396,19 @@ frappe.views.ListView = Class.extend({
.appendTo(parent);
}
else if(opts.type=="select" && data[opts.content]) {
-
+
var label_class = "label-default";
var style = frappe.utils.guess_style(data[opts.content]);
if(style) label_class = "label-" + style;
-
- $(""
+
+ $(""
+ data[opts.content] + " ")
.css({"cursor":"pointer"})
.addClass("label")
+ .addClass("filterable")
.addClass(label_class)
- .attr("data-fieldname", opts.content)
- .click(function() {
- me.doclistview.set_filter($(this).attr("data-fieldname"),
- $(this).text());
- })
+ .attr("data-filter", opts.df.fieldname + ",=," + data[opts.content])
.appendTo(parent.css({"overflow":"hidden"}));
}
else if(opts.type=="link" && data[opts.content]) {
@@ -347,35 +416,35 @@ frappe.views.ListView = Class.extend({
.html(frappe.format(data[opts.content], opts.df, null, data))
.appendTo(parent.css({"overflow":"hidden"}))
.click(function() {
- me.doclistview.set_filter($(this).attr("data-fieldname"),
+ me.doclistview.set_filter($(this).attr("data-fieldname"),
$(this).attr("data-value"));
return false;
})
.attr("data-fieldname", opts.content)
.attr("data-value", data[opts.content])
- .find("a").attr("href", "#");
-
+ .find("a").removeAttr("href");
+
}
else if(data[opts.content]) {
$("")
.html(frappe.format(data[opts.content], opts.df, null, data))
.appendTo(parent.css({"overflow":"hidden"}))
}
-
+
// finally
if(!$(parent).html()) {
$("- ").css({color:"#ccc"}).appendTo(parent);
}
-
+
// title
if(!in_list(["avatar", "_user_tags", "check"], opts.content)) {
if($(parent).attr("title")==undefined) {
- $(parent).attr("title", (opts.title || opts.content) + ": "
- + (data[opts.content] || "Not Set"))
+ $(parent).attr("title", (opts.title || opts.content) + ": "
+ + (data[opts.content] || __("Not Set")))
}
$(parent).tooltip();
}
-
+
},
show_hide_check_column: function() {
if(!this.doclistview.can_delete) {
@@ -383,22 +452,22 @@ frappe.views.ListView = Class.extend({
}
},
prepare_data: function(data) {
-
+
if(data.modified)
this.prepare_when(data, data.modified);
-
+
// docstatus
if(data.docstatus==0 || data.docstatus==null) {
- data.docstatus_icon = 'icon-check-empty';
+ data.docstatus_icon = 'icon-edit text-danger';
data.docstatus_title = __('Editable');
} else if(data.docstatus==1) {
- data.docstatus_icon = 'icon-lock';
+ data.docstatus_icon = 'icon-lock';
data.docstatus_title = __('Submitted');
} else if(data.docstatus==2) {
- data.docstatus_icon = 'icon-remove';
+ data.docstatus_icon = 'icon-ban-circle';
data.docstatus_title = __('Cancelled');
}
-
+
// nulls as strings
for(key in data) {
if(data[key]==null) {
@@ -410,7 +479,7 @@ frappe.views.ListView = Class.extend({
if(this.settings.prepare_data)
this.settings.prepare_data(data);
},
-
+
prepare_when: function(data, date_str) {
if (!date_str) date_str = data.modified;
// when
@@ -426,11 +495,11 @@ frappe.views.ListView = Class.extend({
data.when = __('2 days ago')
}
},
-
+
render_bar_graph: function(parent, data, field, label) {
var args = {
percent: data[field],
- label: label
+ label: __(label)
}
$(parent).append(repl(' \
\
\
%(description)s
\
\
', item)).appendTo($list);
@@ -219,6 +223,7 @@ frappe.views.moduleview.ModuleView = Class.extend({
if(!route) {
if(item.type==="doctype") {
route = "List/" + encodeURIComponent(item.name);
+ frappe.listview_parent_route[item.name] = ["Module", me.module];
} else if(item.type==="page") {
route = item.route || item.link || item.name;
} else if(item.type==="report") {
diff --git a/frappe/public/js/frappe/views/query_report.js b/frappe/public/js/frappe/views/query_report.js
index 56141d8ee4..b994ef829b 100644
--- a/frappe/public/js/frappe/views/query_report.js
+++ b/frappe/public/js/frappe/views/query_report.js
@@ -60,7 +60,7 @@ frappe.views.QueryReport = Class.extend({
this.appframe.set_title_right(__('Refresh'), function() { me.refresh(); });
// Edit
- var edit_btn = this.appframe.add_primary_action(__('Edit'), function() {
+ var edit_btn = this.appframe.add_button(__('Edit'), function() {
if(!frappe.user.is_report_manager()) {
msgprint(__("You are not allowed to create / edit reports"));
return false;
@@ -68,16 +68,16 @@ frappe.views.QueryReport = Class.extend({
frappe.set_route("Form", "Report", me.report_name);
}, "icon-edit");
- this.appframe.add_primary_action(__('Export'), function() { me.export_report(); },
+ this.appframe.add_button(__('Export'), function() { me.export_report(); },
"icon-download");
- if(frappe.model.can_restrict("Report")) {
- this.appframe.add_primary_action(__("User Restrictions"), function() {
+ if(frappe.model.can_set_user_permissions("Report")) {
+ this.appframe.add_button(__("User Permissions"), function() {
frappe.route_options = {
- property: "Report",
- restriction: me.report_name
+ doctype: "Report",
+ name: me.report_name
};
- frappe.set_route("user-properties");
+ frappe.set_route("user-permissions");
}, "icon-shield");
}
},
@@ -91,13 +91,13 @@ frappe.views.QueryReport = Class.extend({
this.wrapper.find(".no-report-area").toggle(false);
me.appframe.set_title(__("Query Report")+": " + __(me.report_name));
- me.appframe.set_title_left(function() {
- frappe.set_route(frappe.get_module(me.report_doc.module).link); });
-
-
frappe.model.with_doc("Report", me.report_name, function() {
+
me.report_doc = frappe.get_doc("Report", me.report_name);
+ me.appframe.set_title_left(function() {
+ frappe.set_route(frappe.get_module(me.report_doc.module).link); });
+
frappe.model.with_doctype(me.report_doc.ref_doctype, function() {
if(!frappe.query_reports[me.report_name]) {
return frappe.call({
@@ -107,13 +107,19 @@ frappe.views.QueryReport = Class.extend({
},
callback: function(r) {
me.appframe.set_title(__("Query Report")+": " + __(me.report_name));
- frappe.dom.eval(r.message || "");
+ frappe.dom.eval(r.message.script || "");
me.setup_filters();
+ me.setup_html_format(r.message.html_format);
+ frappe.query_reports[me.report_name]["html_format"] = r.message.html_format;
me.refresh();
}
});
} else {
me.setup_filters();
+
+ // setup a fresh print action
+ me.setup_html_format(frappe.query_reports[me.report_name]["html_format"]);
+
me.refresh();
}
});
@@ -124,6 +130,45 @@ frappe.views.QueryReport = Class.extend({
this.wrapper.find(".no-report-area").html(msg).toggle(true);
}
},
+ setup_html_format: function(html_format) {
+ var me = this;
+
+ // don't add multiple Print buttons
+ if (this.$print_action) {
+ this.$print_action.remove();
+ }
+
+ if(html_format) {
+ this.$print_action = this.appframe.add_button(__('Print'), function() {
+ if(!me.data) {
+ msgprint(__("Run the report first"));
+ return;
+ }
+
+ var data = [];
+ // get filtered data
+ for (var i=0, l=me.dataView.getLength(); i
")
+ .css("padding-left", (cint(dataContext.indent) * 21) + "px")
+ .html(value);
+
+ var idx = me.dataView.getIdxById(dataContext.id);
+ var show_toggle = me.data[idx + 1] && (me.data[idx + 1].indent > me.data[idx].indent)
+
+ if (dataContext[me.name_field] && show_toggle) {
+ $(' ')
+ .addClass(dataContext._collapsed ? "expand" : "collapse")
+ .css("margin-right", "7px")
+ .prependTo($span);
+ }
+
+ return $span.wrap("
").parent().html();
+ },
compare_values: function(value, filter, columnDef) {
var invert = false;
@@ -431,9 +615,35 @@ frappe.views.QueryReport = Class.extend({
me.dataView.refresh();
});
},
+ setup_tree: function() {
+ // set these in frappe.query_reports[report_name]
+ // "tree": true,
+ // "name_field": "account",
+ // "parent_field": "parent_account",
+ // "initial_depth": 3
+
+ // also set "is_tree" true for ColumnDef
+
+ var me = this;
+ this.grid.onClick.subscribe(function (e, args) {
+ if ($(e.target).hasClass("toggle")) {
+ var item = me.dataView.getItem(args.row);
+ if (item) {
+ if (!item._collapsed) {
+ item._collapsed = true;
+ } else {
+ item._collapsed = false;
+ }
+
+ me.dataView.updateItem(item.id, item);
+ }
+ e.stopImmediatePropagation();
+ }
+ });
+ },
export_report: function() {
if(!frappe.model.can_export(this.report_doc.ref_doctype)) {
- msgprint(_("You are not allowed to export this report"));
+ msgprint(__("You are not allowed to export this report"));
return false;
}
diff --git a/frappe/public/js/frappe/views/reportview.js b/frappe/public/js/frappe/views/reportview.js
index 07960f6bc0..e261f9db22 100644
--- a/frappe/public/js/frappe/views/reportview.js
+++ b/frappe/public/js/frappe/views/reportview.js
@@ -53,7 +53,7 @@ frappe.views.ReportViewPage = Class.extend({
var module = locals.DocType[this.doctype].module;
this.page.appframe.set_title(__(this.doctype));
this.page.appframe.add_module_icon(module, this.doctype)
- this.page.appframe.set_title_left(function() { frappe.set_route(frappe.get_module(module).link); });
+ this.page.appframe.set_title_left(function() { frappe.set_route((frappe.get_module(module) || {}).link); });
this.page.appframe.set_views_for(this.doctype, "report");
this.page.reportview = new frappe.views.ReportView({
@@ -107,7 +107,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
this.make_export();
this.set_init_columns();
this.make_save();
- this.make_user_restrictions();
+ this.make_user_permissions();
this.set_tag_and_status_filter();
},
@@ -118,7 +118,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
var columns = [['name', this.doctype],];
$.each(frappe.meta.docfield_list[this.doctype], function(i, df) {
if((df.in_filter || df.in_list_view) && df.fieldname!='naming_series'
- && !in_list(frappe.model.no_value_type, df.fieldname)) {
+ && !in_list(frappe.model.no_value_type, df.fieldtype)) {
columns.push([df.fieldname, df.parent]);
}
});
@@ -171,7 +171,6 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
fields: $.map(this.columns, function(v) { return me.get_full_column_name(v) }),
order_by: this.get_order_by(),
filters: this.filter_list.get_filters(),
- docstatus: ['0','1','2'],
with_childnames: 1
}
},
@@ -221,8 +220,12 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
width: (docfield ? cint(docfield.width) : 120) || 120,
formatter: function(row, cell, value, columnDef, dataContext) {
var docfield = columnDef.docfield;
- if(docfield.fieldname==="_user_tags") docfield.fieldtype = "Tag";
- if(docfield.fieldname==="_comments") docfield.fieldtype = "Comment";
+ docfield.fieldtype = {
+ "_user_tags": "Tag",
+ "_comments": "Comment",
+ "_assign": "Assign"
+ }[docfield.fieldname] || docfield.fieldtype;
+
if(docfield.fieldtype==="Link" && docfield.fieldname!=="name") {
docfield.link_onclick =
repl('frappe.container.page.reportview.set_filter("%(fieldname)s", "%(value)s").page.reportview.run()',
@@ -327,14 +330,20 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
});
d.get_input(docfield.fieldname).val(row[docfield.fieldname]);
d.get_input("update").on("click", function() {
+ var args = {
+ doctype: docfield.parent,
+ name: row[docfield.parent===me.doctype ? "name" : docfield.parent+":name"],
+ fieldname: docfield.fieldname,
+ value: d.get_value(docfield.fieldname)
+ };
+
+ if (!args.name) {
+ frappe.throw(__("ID field is required to edit values using Report. Please select the ID field using the Column Picker"));
+ }
+
frappe.call({
method: "frappe.client.set_value",
- args: {
- doctype: docfield.parent,
- name: row[docfield.parent===me.doctype ? "name" : docfield.parent+":name"],
- fieldname: docfield.fieldname,
- value: d.get_value(docfield.fieldname)
- },
+ args: args,
callback: function(r) {
if(!r.exc) {
d.hide();
@@ -398,12 +407,14 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
this.$w.find('.result-list').on("click", ".label-info", function() {
if($(this).attr("data-label")) {
me.set_filter("_user_tags", $(this).attr("data-label"));
+ me.refresh();
}
});
this.$w.find('.result-list').on("click", "[data-workflow-state]", function() {
if($(this).attr("data-workflow-state")) {
me.set_filter(me.state_fieldname,
$(this).attr("data-workflow-state"));
+ me.refresh();
}
});
},
@@ -550,19 +561,19 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
});
}));
- }, 'icon-remove');
+ }, 'icon-trash');
}
},
- make_user_restrictions: function() {
+ make_user_permissions: function() {
var me = this;
- if(this.docname && frappe.model.can_restrict("Report")) {
- this.page.appframe.add_button(__("User Permission Restrictions"), function() {
+ if(this.docname && frappe.model.can_set_user_permissions("Report")) {
+ this.page.appframe.add_button(__("User Permissions Manager"), function() {
frappe.route_options = {
- property: "Report",
- restriction: me.docname
+ doctype: "Report",
+ name: me.docname
};
- frappe.set_route("user-properties");
+ frappe.set_route("user-permissions");
}, "icon-shield");
}
},
@@ -599,7 +610,15 @@ frappe.ui.ColumnPicker = Class.extend({
me.add_column(c);
});
- $(this.dialog.body).find('.column-list').sortable();
+ $(this.dialog.body).find('.column-list').sortable({
+ update: function(event, ui) {
+ me.columns = [];
+ $.each($(me.dialog.body).find('.column-list .column-list-item'),
+ function(i, ele) {
+ me.columns.push($(ele).data("fieldselect"))
+ });
+ }
+ });
// add column
$(this.dialog.body).find('.btn-add').click(function() {
@@ -624,7 +643,7 @@ frappe.ui.ColumnPicker = Class.extend({
add_column: function(c) {
if(!c) return;
var w = $('\
+ width: 90%; margin-bottom: 10px; border-radius: 3px; cursor: move;" class="column-list-item">\
\
× \
')
@@ -638,6 +657,8 @@ frappe.ui.ColumnPicker = Class.extend({
fieldselect.$select.css({width: '70%', 'margin-top':'5px'})
fieldselect.val((c[1] || this.doctype) + "." + c[0]);
+ w.data("fieldselect", fieldselect);
+
w.find('.close').data("fieldselect", fieldselect).click(function() {
console.log(me.columns.indexOf($(this).data('fieldselect')));
delete me.columns[me.columns.indexOf($(this).data('fieldselect'))];
diff --git a/frappe/public/js/frappe/views/sidebar_stats.js b/frappe/public/js/frappe/views/sidebar_stats.js
index eaf32ca54a..dd30a373d1 100644
--- a/frappe/public/js/frappe/views/sidebar_stats.js
+++ b/frappe/public/js/frappe/views/sidebar_stats.js
@@ -3,7 +3,7 @@
frappe.provide('frappe.views');
-// opts:
+// opts:
// stats = list of fields
// doctype
// parent
@@ -29,10 +29,10 @@ frappe.views.SidebarStats = Class.extend({
$.each(me.stats, function(i, v) {
me.render_stat(v, (r.message || {})[v]);
});
-
+
// reload button at the end
if(me.stats.length) {
- $(' '+__('Refresh')+' ')
+ $(' '+__('Refresh')+' ')
.css({"margin-top":"15px", "display":"inline-block"})
.click(function() {
me.reload_stats();
@@ -46,11 +46,14 @@ frappe.views.SidebarStats = Class.extend({
},
render_stat: function(field, stat) {
var me = this;
+ var show_tags = ''
+ +__("Show tags") +' ';
if(!stat || !stat.length) {
if(field==='_user_tags') {
$('\
-
'+__('Tags')+'\
+
\
+ '+__('Tags')+show_tags+'\
\
'+__('No records tagged.')+' '
+'
\
@@ -59,9 +62,9 @@ frappe.views.SidebarStats = Class.extend({
return;
}
- var label = frappe.meta.docfield_map[this.doctype][field] ?
+ var label = frappe.meta.docfield_map[this.doctype][field] ?
frappe.meta.docfield_map[this.doctype][field].label : field;
- if(label==='_user_tags') label = 'Tags';
+ if(label==='_user_tags') label = 'Tags' + show_tags;
// grid
var $w = $('
\
@@ -76,12 +79,12 @@ frappe.views.SidebarStats = Class.extend({
$.each(stat, function(i,v) { sum = sum + v[1]; })
// render items
- $.each(stat, function(i, v) {
+ $.each(stat, function(i, v) {
me.render_stat_item(i, v, sum, field).appendTo($w.find('.side-panel-body'));
});
$w.appendTo(this.wrapper);
- },
+ },
render_stat_item: function(i, v, max, field) {
var me = this;
var args = {}
@@ -91,8 +94,8 @@ frappe.views.SidebarStats = Class.extend({
args.count = v[1];
args.field = field;
args.bar_style = "";
-
- $item = $(repl('
\
+
+ $item = $(repl('
\
\
%(_label)s (%(count)s)\
', args));
-
+
this.setup_stat_item_click($item);
return $item;
},
@@ -116,5 +119,5 @@ frappe.views.SidebarStats = Class.extend({
me.set_filter(fieldname, label);
return false;
});
- },
-});
\ No newline at end of file
+ },
+});
diff --git a/frappe/public/js/legacy/clientscriptAPI.js b/frappe/public/js/legacy/clientscriptAPI.js
index 0c741993d0..91226ac0fb 100644
--- a/frappe/public/js/legacy/clientscriptAPI.js
+++ b/frappe/public/js/legacy/clientscriptAPI.js
@@ -169,7 +169,7 @@ _f.Frm.prototype.call_server = function(method, args, callback) {
_f.Frm.prototype.get_files = function() {
return cur_frm.attachments
- ? keys(cur_frm.attachments.get_attachments()).sort()
+ ? frappe.utils.sort(cur_frm.attachments.get_attachments(), "file_name", "string")
: [] ;
}
@@ -263,8 +263,14 @@ _f.Frm.prototype.new_doc = function(doctype, field) {
_f.Frm.prototype.set_read_only = function() {
var perm = [];
- $.each(frappe.perm.get_perm(cur_frm.doc.doctype, cur_frm.doc.name), function(i, permlevel) {
- if(permlevel!=null) perm[permlevel] = {read:1};
+ $.each(frappe.perm.get_perm(cur_frm.doc.doctype), function(i, p) {
+ perm[p.permlevel || 0] = {read:1};
});
cur_frm.perm = perm;
}
+
+_f.Frm.prototype.get_formatted = function(fieldname) {
+ return frappe.format(this.doc[fieldname],
+ frappe.meta.get_docfield(this.doctype, fieldname, this.docname),
+ {no_icon:true}, this.doc);
+}
diff --git a/frappe/public/js/legacy/datatype.js b/frappe/public/js/legacy/datatype.js
index 04aa68092a..ad3383a696 100644
--- a/frappe/public/js/legacy/datatype.js
+++ b/frappe/public/js/legacy/datatype.js
@@ -1,11 +1,13 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-// MIT License. See license.txt
+// MIT License. See license.txt
-frappe.utils.full_name = function(fn, ln) {
- return fn + (ln ? ' ' : '') + (ln ? ln : '')
+frappe.utils.full_name = function(fn, ln) {
+ return fn + (ln ? ' ' : '') + (ln ? ln : '')
}
function fmt_money(v, format){
+ // deprecated!
+ // for backward compatibility
return format_number(v, format);
}
@@ -14,19 +16,19 @@ function fmt_money(v, format){
function toTitle(str){
var word_in = str.split(" ");
var word_out = [];
-
+
for(w in word_in){
word_out[w] = word_in[w].charAt(0).toUpperCase() + word_in[w].slice(1);
}
-
+
return word_out.join(" ");
}
function is_null(v) {
- if(v===null || v===undefined || v==="") return true;
+ if(v===null || v===undefined || cstr(v).trim()==="") return true;
}
-function set_value_in(ele, v, ftype, fopt, doc) {
+function set_value_in(ele, v, ftype, fopt, doc) {
$(ele).html(frappe.format(v, {fieldtype:ftype, options:fopt}, null, doc));
return;
}
@@ -42,12 +44,12 @@ function replace_newlines(t) {
return t?t.replace(/\n/g, '
'):'';
}
-function validate_email(txt) {
+function validate_email(txt) {
return frappe.utils.validate_type(txt, "email");
}
-function validate_spl_chars(txt) {
+function validate_spl_chars(txt) {
return frappe.utils.validate_type(txt, "alphanum")
-}
+}
function cstr(s) {
if(s==null)return '';
return s+'';
@@ -61,15 +63,15 @@ function nth(number) {
return number+s;
}
-function esc_quotes(s) {
- if(s==null)s='';
+function esc_quotes(s) {
+ if(s==null)s='';
return s.replace(/'/, "\'");
}
var crop = function(s, len) {
if(s.length>len)
return s.substr(0, len-3) + '...';
- else
+ else
return s;
}
@@ -105,12 +107,12 @@ function replace_all(s, t1, t2) {
return s.split(t1).join(t2);
}
-function keys(obj) {
+function keys(obj) {
var mykeys=[];
for (var key in obj) mykeys[mykeys.length]=key;
return mykeys;
}
-function values(obj) {
+function values(obj) {
var myvalues=[];
for (var key in obj) myvalues[myvalues.length]=obj[key];
return myvalues;
diff --git a/frappe/public/js/legacy/datetime.js b/frappe/public/js/legacy/datetime.js
deleted file mode 100644
index ff56951989..0000000000
--- a/frappe/public/js/legacy/datetime.js
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-// MIT License. See license.txt
-
-// Date
-
-function same_day(d1, d2) {
- if(d1.getFullYear()==d2.getFullYear() && d1.getMonth()==d2.getMonth() && d1.getDate()==d2.getDate())return true; else return false;
-}
-var month_list = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
-var month_last = {1:31,2:28,3:31,4:30,5:31,6:30,7:31,8:31,9:30,10:31,11:30,12:31}
-var month_list_full = ['January','February','March','April','May','June','July','August','September','October','November','December'];
-
-var week_list = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
-var week_list_full = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
-
-function int_to_str(i, len) {
- i = ''+i;
- if(i.length
').find('input:last');
for(key in attributes)
$input.attr(key, attributes[key]);
-
+
var input = $input.get(0);
if(cs)
$y(input,cs);
return input;
}
-function $dh(d) {
- if(d && d.substr)d=$i(d);
- if(d && d.style.display.toLowerCase() != 'none') d.style.display = 'none';
+function $dh(d) {
+ if(d && d.substr)d=$i(d);
+ if(d && d.style.display.toLowerCase() != 'none') d.style.display = 'none';
}
-function $ds(d) {
- if(d && d.substr)d=$i(d);
+function $ds(d) {
+ if(d && d.substr)d=$i(d);
var t = 'block';
- if(d && in_list(['span','img','button'], d.tagName.toLowerCase()))
+ if(d && in_list(['span','img','button'], d.tagName.toLowerCase()))
t = 'inline'
- if(d && d.style.display.toLowerCase() != t)
- d.style.display = t;
+ if(d && d.style.display.toLowerCase() != t)
+ d.style.display = t;
}
function $di(d) { if(d && d.substr)d=$i(d); if(d)d.style.display = 'inline'; }
-function $i(id) {
- if(!id) return null;
+function $i(id) {
+ if(!id) return null;
if(id && id.appendChild)return id; // already an element
- return document.getElementById(id);
+ return document.getElementById(id);
}
function $w(e,w) { if(e && e.style && w)e.style.width = w; }
function $h(e,h) { if(e && e.style && h)e.style.height = h; }
function $bg(e,w) { if(e && e.style && w)e.style.backgroundColor = w; }
-function $y(ele, s) {
- if(ele && s) {
- for(var i in s) ele.style[i]=s[i];
- };
+function $y(ele, s) {
+ if(ele && s) {
+ for(var i in s) ele.style[i]=s[i];
+ };
return ele;
}
-function $yt(tab, r, c, s) { /// set style on tables with wildcards
- var rmin = r; var rmax = r;
- if(r=='*') { rmin = 0; rmax = tab.rows.length-1; }
- if(r.search && r.search('-')!= -1) {
- r = r.split('-');
- rmin = cint(r[0]); rmax = cint(r[1]);
- }
-
- var cmin = c; var cmax = c;
- if(c=='*') { cmin = 0; cmax = tab.rows[0].cells.length-1; }
- if(c.search && c.search('-')!= -1) {
- c = c.split('-');
- rmin = cint(c[0]); rmax = cint(c[1]);
- }
-
- for(var ri = rmin; ri<=rmax; ri++) {
- for(var ci = cmin; ci<=cmax; ci++)
- $y($td(tab,ri,ci),s);
- }
-}
-
// Make table
function make_table(parent, nr, nc, table_width, widths, cell_style, table_style) {
@@ -277,16 +142,16 @@ function append_row(t, at, style) {
return r
}
-function $td(t,r,c) {
+function $td(t,r,c) {
if(r<0)r=t.rows.length+r;
if(c<0)c=t.rows[0].cells.length+c;
- return t.rows[r].cells[c];
+ return t.rows[r].cells[c];
}
// URL utilities
frappe.urllib = {
-
+
// get argument from url
get_arg: function(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
@@ -296,9 +161,9 @@ frappe.urllib = {
if( results == null )
return "";
else
- return decodeURIComponent(results[1]);
+ return decodeURIComponent(results[1]);
},
-
+
// returns url dictionary
get_dict: function() {
var d = {}
@@ -313,15 +178,15 @@ frappe.urllib = {
var a = t[i].split('=');
d[decodeURIComponent(a[0])] = decodeURIComponent(a[1]);
}
- return d;
+ return d;
},
-
+
// returns the base url with http + domain + path (-index.cgi or # or ?)
get_base_url: function() {
var url= window.location.href.split('#')[0].split('?')[0].split('desk')[0];
if(url.substr(url.length-1, 1)=='/') url = url.substr(0, url.length-1)
return url
- }
+ }
}
get_url_arg = frappe.urllib.get_arg;
diff --git a/frappe/public/js/legacy/form.js b/frappe/public/js/legacy/form.js
index d11da18448..25a93ef924 100644
--- a/frappe/public/js/legacy/form.js
+++ b/frappe/public/js/legacy/form.js
@@ -115,58 +115,46 @@ _f.Frm.prototype.setup = function() {
parent: $(this.wrapper).find(".appframe-footer")
})
+ this.setup_drag_drop();
this.setup_done = true;
}
-_f.Frm.prototype.setup_print_layout = function() {
- this.print_wrapper = $('')
- .appendTo(this.layout_main)
- .toggle(false);
-
+_f.Frm.prototype.setup_drag_drop = function() {
var me = this;
- this.print_wrapper.find(".close").click(function() {
- me.hide_print();
- });
+ $(this.wrapper).on('dragenter dragover', false)
+ .on('drop', function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ if(me.doc.__islocal) {
+ msgprint(__("Please save before attaching."));
+ return false;
+ throw "attach error";
+ }
+ if(me.attachments.max_reached()) {
+ msgprint(__("Maximum Attachment Limit for this record reached."));
+ throw "attach error";
+ }
- this.print_formats = frappe.meta.get_print_formats(this.meta.name);
- this.print_letterhead = this.print_wrapper
- .find(".print-letterhead")
- .on("change", function() { me.print_sel.trigger("change"); });
- this.print_sel = this.print_wrapper
- .find(".print-preview-select")
- .on("change", function() {
- _p.build(me.print_sel.val(), function(html) {
- me.print_wrapper.find(".print-preview").html(html);
- }, !me.print_letterhead.is(":checked"), true, true);
- })
+ var dataTransfer = e.originalEvent.dataTransfer;
+ if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
+ frappe.upload.upload_file(dataTransfer.files[0], me.attachments.get_args(), {
+ callback: function(attachment, r) {
+ me.attachments.attachment_uploaded(attachment, r);
+ }
+ });
+ }
+ });
+}
- this.print_wrapper.find(".print-print").click(function() {
- _p.build(
- me.print_sel.val(), // fmtname
- _p.go, // onload
- !me.print_letterhead.is(":checked") // no_letterhead
- );
+_f.Frm.prototype.setup_print_layout = function() {
+ this.print_preview = new frappe.ui.form.PrintPreview({
+ frm: this
})
}
_f.Frm.prototype.print_doc = function() {
- if(this.print_wrapper.is(":visible")) {
+ if(this.print_preview.wrapper.is(":visible")) {
this.hide_print();
return;
}
@@ -179,17 +167,17 @@ _f.Frm.prototype.print_doc = function() {
msgprint(__("Cannot print cancelled documents"));
return;
}
- this.print_wrapper.toggle(true);
- this.print_sel
- .empty().add_options(this.print_formats)
+ this.print_preview.print_sel
+ .empty().add_options(this.print_preview.print_formats)
.trigger("change");
+ this.print_preview.wrapper.toggle(true);
this.form_wrapper.toggle(false);
}
_f.Frm.prototype.hide_print = function() {
if(this.setup_done) {
- this.print_wrapper.toggle(false);
+ this.print_preview.wrapper.toggle(false);
this.form_wrapper.toggle(true);
}
}
@@ -206,7 +194,7 @@ _f.Frm.prototype.watch_model_updates = function() {
me.fields_dict[fieldname]
&& me.fields_dict[fieldname].refresh(fieldname);
- me.refresh_dependency();
+ me.layout.refresh_dependency();
me.script_manager.trigger(fieldname, doc.doctype, doc.name);
}
})
@@ -335,8 +323,7 @@ _f.Frm.prototype.refresh_header = function() {
_f.Frm.prototype.check_doc_perm = function() {
// get perm
var dt = this.parent_doctype?this.parent_doctype : this.doctype;
- var dn = this.parent_docname?this.parent_docname : this.docname;
- this.perm = frappe.perm.get_perm(dt, dn);
+ this.perm = frappe.perm.get_perm(dt, this.doc);
if(!this.perm[0].read) {
return 0;
@@ -359,6 +346,9 @@ _f.Frm.prototype.refresh = function(docname) {
if(this.docname) { // document to show
+ // set the doc
+ this.doc = frappe.get_doc(this.doctype, this.docname);
+
// check permissions
if(!this.check_doc_perm()) {
frappe.show_not_permitted(__(this.doctype) + " " + __(this.docname));
@@ -368,9 +358,6 @@ _f.Frm.prototype.refresh = function(docname) {
// read only (workflow)
this.read_only = frappe.workflow.is_read_only(this.doctype, this.docname);
- // set the doc
- this.doc = frappe.get_doc(this.doctype, this.docname);
-
// check if doctype is already open
if (!this.opendocs[this.docname]) {
this.check_doctype_conflict(this.docname);
@@ -445,9 +432,6 @@ _f.Frm.prototype.refresh_fields = function() {
// cleanup activities after refresh
this.cleanup_refresh(this);
-
- // dependent fields
- this.refresh_dependency();
}
@@ -481,60 +465,6 @@ _f.Frm.prototype.cleanup_refresh = function() {
}
}
-// Resolve "depends_on" and show / hide accordingly
-
-_f.Frm.prototype.refresh_dependency = function() {
- var me = this;
- var doc = locals[this.doctype][this.docname];
-
- // build dependants' dictionary
- var has_dep = false;
-
- for(fkey in me.fields) {
- var f = me.fields[fkey];
- f.dependencies_clear = true;
- if(f.df.depends_on) {
- has_dep = true;
- }
- }
-
- if(!has_dep)return;
-
- // show / hide based on values
- for(var i=me.fields.length-1;i>=0;i--) {
- var f = me.fields[i];
- f.guardian_has_value = true;
- if(f.df.depends_on) {
- // evaluate guardian
- var v = doc[f.df.depends_on];
- if(f.df.depends_on.substr(0,5)=='eval:') {
- f.guardian_has_value = eval(f.df.depends_on.substr(5));
- } else if(f.df.depends_on.substr(0,3)=='fn:') {
- f.guardian_has_value = me.script_manager.trigger(f.df.depends_on.substr(3), me.doctype, me.docname);
- } else {
- if(!v) {
- f.guardian_has_value = false;
- }
- }
-
- // show / hide
- if(f.guardian_has_value) {
- if(f.df.hidden_due_to_dependency) {
- f.df.hidden_due_to_dependency = false;
- f.refresh();
- }
- } else {
- if(!f.df.hidden_due_to_dependency) {
- f.df.hidden_due_to_dependency = true;
- f.refresh();
- }
- }
- }
- }
-
- this.layout.refresh_section_count();
-}
-
_f.Frm.prototype.setnewdoc = function() {
// moved this call to refresh function
// this.check_doctype_conflict(docname);
@@ -564,6 +494,12 @@ _f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) {
// fields
me.refresh_fields();
+ // enable button
+ if(callingfield)
+ $(callingfield.input).done_working();
+ },
+ // error
+ function() {
// enable button
if(callingfield)
$(callingfield.input).done_working();
@@ -599,6 +535,7 @@ _f.Frm.prototype.reload_doc = function() {
var validated;
_f.Frm.prototype.save = function(save_action, callback, btn, on_error) {
+ btn && $(btn).prop("disabled", true);
$(document.activeElement).blur();
// let any pending js process finish
@@ -614,13 +551,16 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) {
if((!this.meta.in_dialog || this.in_form) && !this.meta.istable)
scroll(0, 0);
- // validate
- validated = true;
- this.script_manager.trigger("validate");
- if(!validated) {
- if(on_error)
- on_error();
- return;
+ if(save_action != "Update") {
+ // validate
+ validated = true;
+ this.script_manager.trigger("validate");
+
+ if(!validated) {
+ if(on_error)
+ on_error();
+ return;
+ }
}
var after_save = function(r) {
@@ -646,7 +586,7 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) {
}
-_f.Frm.prototype.savesubmit = function(btn, on_error) {
+_f.Frm.prototype.savesubmit = function(btn, callback, on_error) {
var me = this;
this.validate_form_action("Submit");
frappe.confirm(__("Permanently Submit {0}?", [this.docname]), function() {
@@ -660,13 +600,14 @@ _f.Frm.prototype.savesubmit = function(btn, on_error) {
me.save('Submit', function(r) {
if(!r.exc) {
+ callback && callback();
me.script_manager.trigger("on_submit");
}
}, btn, on_error);
});
};
-_f.Frm.prototype.savecancel = function(btn, on_error) {
+_f.Frm.prototype.savecancel = function(btn, callback, on_error) {
var me = this;
this.validate_form_action('Cancel');
frappe.confirm(__("Permanently Cancel {0}?", [this.docname]), function() {
@@ -681,6 +622,7 @@ _f.Frm.prototype.savecancel = function(btn, on_error) {
var after_cancel = function(r) {
if(!r.exc) {
me.refresh();
+ callback && callback();
me.script_manager.trigger("after_cancel");
} else {
on_error();
@@ -762,9 +704,10 @@ _f.Frm.prototype.set_footnote = function(txt) {
}
-_f.Frm.prototype.add_custom_button = function(label, fn, icon) {
- return this.appframe.add_primary_action(label, fn, icon || "icon-arrow-right");
+_f.Frm.prototype.add_custom_button = function(label, fn, icon, toolbar_or_class) {
+ return this.appframe.add_primary_action(label, fn, icon || "icon-arrow-play", toolbar_or_class);
}
+
_f.Frm.prototype.clear_custom_buttons = function() {
this.appframe.clear_primary_action()
}
diff --git a/frappe/public/js/legacy/printElement.js b/frappe/public/js/legacy/printElement.js
deleted file mode 100644
index f38b7547a2..0000000000
--- a/frappe/public/js/legacy/printElement.js
+++ /dev/null
@@ -1,133 +0,0 @@
-///
-/*
-* Print Element Plugin 1.2
-*
-* Copyright (c) 2010 Erik Zaadi
-*
-* Inspired by PrintArea (http://plugins.jquery.com/project/PrintArea) and
-* http://stackoverflow.com/questions/472951/how-do-i-print-an-iframe-from-javascript-in-safari-chrome
-*
-* Home Page : http://projects.erikzaadi/jQueryPlugins/jQuery.printElement
-* Issues (bug reporting) : http://github.com/erikzaadi/jQueryPlugins/issues/labels/printElement
-* jQuery plugin page : http://plugins.jquery.com/project/printElement
-*
-* Thanks to David B (http://github.com/ungenio) and icgJohn (http://www.blogger.com/profile/11881116857076484100)
-* For their great contributions!
-*
-* Dual licensed under the MIT and GPL licenses:
-* http://www.opensource.org/licenses/mit-license.php
-* http://www.gnu.org/licenses/gpl.html
-*
-* Note, Iframe Printing is not supported in Opera and Chrome 3.0, a popup window will be shown instead
-*/
-; (function (window, undefined) {
- var document = window["document"];
- var $ = window["jQuery"];
- $.fn["printElement"] = function (options) {
- var mainOptions = $.extend({}, $.fn["printElement"]["defaults"], options);
- //Remove previously printed iframe if exists
- $("[id^='printElement_']").remove();
-
- return this.each(function () {
- //Support Metadata Plug-in if available
- var opts = $.meta ? $.extend({}, mainOptions, $(this).data()) : mainOptions;
- _printElement($(this), opts);
- });
- };
- $.fn["printElement"]["defaults"] = {
- "printMode": 'iframe', //Usage : iframe / popup
- "pageTitle": '', //Print Page Title
- "overrideElementCSS": null,
- /* Can be one of the following 3 options:
-* 1 : boolean (pass true for stripping all css linked)
-* 2 : array of $.fn.printElement.cssElement (s)
-* 3 : array of strings with paths to alternate css files (optimized for print)
-*/
- "printBodyOptions": {
- "styleToAdd": 'padding:10px;margin:10px;', //style attributes to add to the body of print document
- "classNameToAdd": '' //css class to add to the body of print document
- },
- "leaveOpen": false, // in case of popup, leave the print page open or not
- "iframeElementOptions": {
- "styleToAdd": 'border:none;position:absolute;width:0px;height:0px;bottom:0px;left:0px;', //style attributes to add to the iframe element
- "classNameToAdd": '' //css class to add to the iframe element
- }
- };
- $.fn["printElement"]["cssElement"] = {
- "href": '',
- "media": ''
- };
- function _printElement(element, opts) {
- //Create markup to be printed
- var html = _getMarkup(element, opts);
-
- var popupOrIframe = null;
- var documentToWriteTo = null;
- if (opts["printMode"].toLowerCase() == 'popup') {
- popupOrIframe = window.open('about:blank', 'printElementWindow', 'width=650,height=440,scrollbars=yes');
- documentToWriteTo = popupOrIframe.document;
- }
- else {
- //The random ID is to overcome a safari bug http://www.cjboco.com.sharedcopy.com/post.cfm/442dc92cd1c0ca10a5c35210b8166882.html
- var printElementID = "printElement_" + (Math.round(Math.random() * 99999)).toString();
- //Native creation of the element is faster..
- var iframe = document.createElement('IFRAME');
- $(iframe).attr({
- style: opts["iframeElementOptions"]["styleToAdd"],
- id: printElementID,
- className: opts["iframeElementOptions"]["classNameToAdd"],
- frameBorder: 0,
- scrolling: 'no',
- src: 'about:blank'
- });
- document.body.appendChild(iframe);
- documentToWriteTo = (iframe.contentWindow || iframe.contentDocument);
- if (documentToWriteTo.document)
- documentToWriteTo = documentToWriteTo.document;
- iframe = document.frames ? document.frames[printElementID] : document.getElementById(printElementID);
- popupOrIframe = iframe.contentWindow || iframe;
- }
- focus();
- documentToWriteTo.open();
- documentToWriteTo.write(html);
- documentToWriteTo.close();
- _callPrint(popupOrIframe);
- };
-
- function _callPrint(element) {
- if (element && element["printPage"])
- element["printPage"]();
- else
- setTimeout(function () {
- _callPrint(element);
- }, 50);
- }
-
- function _getElementHTMLIncludingFormElements(element) {
- var $element = $(element);
- var elementHtml = $('
').append($element.clone()).html();
- return elementHtml;
- }
-
- function _getBaseHref() {
- var port = (window.location.port) ? ':' + window.location.port : '';
- return window.location.protocol + '//' + window.location.hostname + port + window.location.pathname;
- }
-
- function _getMarkup(element, opts) {
- var $element = $(element);
- var elementHtml = _getElementHTMLIncludingFormElements(element);
-
- var html = new Array();
- html.push('' + opts["pageTitle"] + ' ');
- //Ensure that relative links work
- html.push(' ');
- html.push('');
- html.push('' + elementHtml + '
');
- html.push('');
- html.push('');
-
- return html.join('');
- };
-})(window);
\ No newline at end of file
diff --git a/frappe/public/js/legacy/print_format.js b/frappe/public/js/legacy/print_format.js
index deb074aacc..59066536b6 100644
--- a/frappe/public/js/legacy/print_format.js
+++ b/frappe/public/js/legacy/print_format.js
@@ -7,7 +7,7 @@ _p.def_print_style_body = "html, body, div, span, td, p { \
font-size: inherit; \
}\
.page-settings {\
- font-family: Arial, Helvetica Neue, Sans;\
+ font-family: Helvetica, 'Open Sans', sans-serif;\
font-size: 9pt;\
}\
pre { margin:0; padding:0;}";
@@ -38,6 +38,7 @@ _p.preview = function(html) {
return;
}
w.document.write(html);
+ w.document.close();
return w
}
@@ -85,7 +86,7 @@ $.extend(_p, {
dialog.onshow = function() {
var $print = dialog.fields_dict.print_format.$input;
- $print.empty().add_options(cur_frm.print_formats);
+ $print.empty().add_options(cur_frm.print_preview.print_formats);
if(cur_frm.$print_view_select && cur_frm.$print_view_select.val())
$print.val(cur_frm.$print_view_select.val());
@@ -173,6 +174,7 @@ $.extend(_p, {
_p.show_letterhead(container, args);
_p.run_embedded_js(container, args.doc);
+
var style = _p.consolidate_css(container, args);
_p.render_header_on_break(container, args);
@@ -285,23 +287,34 @@ $.extend(_p, {
// This is used to calculate and substitude values in the HTML
run_embedded_js: function(container, doc) {
- script_list = $(container).find("script");
- for(var i=0; i]>", "]>", "
]>", "
]>", "
]>"];
+ var tags = ["")
@@ -102,12 +94,12 @@ frappe.print.Table = Class.extend({
.css(me.head_cell_style)
.css({"width": me.widths[ci]})
.appendTo(headrow)
-
+
if(df && in_list(['Float', 'Currency'], df.fieldtype)) {
td.css({"text-align": "right"});
}
});
-
+
$.each(data, function(ri, row) {
var allow = true;
if(me.condition) {
@@ -115,13 +107,13 @@ frappe.print.Table = Class.extend({
}
if(allow) {
var tr = $("").appendTo(table);
-
+
$.each(me.columns, function(ci, fieldname) {
if(fieldname.toLowerCase()==="sr")
var value = row.idx;
else
var value = row[fieldname];
-
+
var df = frappe.meta.docfield_map[me.tabletype][fieldname];
value = frappe.format(value, df, {for_print:true});
@@ -142,7 +134,7 @@ frappe.print.Table = Class.extend({
});
this.tables.push(wrapper)
},
-
+
set_widths: function() {
var me = this;
// if widths not passed (like in standard),
@@ -152,7 +144,7 @@ frappe.print.Table = Class.extend({
df = frappe.meta.docfield_map[me.tabletype][fieldname];
return df && df.print_width || (fieldname=="Sr" ? 30 : 80);
});
-
+
var sum = 0;
$.each(this.widths, function(i, w) {
sum += cint(w);
@@ -164,7 +156,7 @@ frappe.print.Table = Class.extend({
});
}
},
-
+
get_tables: function() {
if(this.tables.length > 1) {
return $.map(this.tables, function(t) {
@@ -174,14 +166,14 @@ frappe.print.Table = Class.extend({
return this.tables[0].get(0);
}
},
-
+
cell_style: {
border: '1px solid #999',
padding: '3px',
'vertical-align': 'top',
'word-wrap': 'break-word',
},
-
+
head_cell_style: {
border: '1px solid #999',
padding: '3px',
@@ -190,7 +182,7 @@ frappe.print.Table = Class.extend({
'font-weight': 'bold',
'word-wrap': 'break-word',
},
-
+
table_style: {
width: '100%',
'border-collapse': 'collapse',
@@ -201,7 +193,7 @@ frappe.print.Table = Class.extend({
})
function print_table(dt, dn, fieldname, tabletype, cols, head_labels, widths, condition, cssClass, modifier) {
- return new frappe.print.Table({
+ return new frappe.printTable({
doctype: dt,
docname: dn,
fieldname: fieldname,
diff --git a/frappe/public/js/lib/bootstrap.min.js b/frappe/public/js/lib/bootstrap.min.js
index 1d4a4ed370..6c8416253c 100755
--- a/frappe/public/js/lib/bootstrap.min.js
+++ b/frappe/public/js/lib/bootstrap.min.js
@@ -1,6 +1,6 @@
/*!
- * Bootstrap v3.1.0 (http://getbootstrap.com)
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
-if("undefined"==typeof jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('
').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown",h),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=" li:not(.divider):visible a",i=f.find("[role=menu]"+h+", [role=listbox]"+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j ').appendTo(document.body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());c.is("a")&&b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=this.$element.parent(),l=e,m=document.documentElement.scrollTop||document.body.scrollTop,n="body"==this.options.container?window.innerWidth:k.outerWidth(),o="body"==this.options.container?window.innerHeight:k.outerHeight(),p="body"==this.options.container?0:k.offset().left;e="bottom"==e&&h.top+h.height+j-m>o?"top":"top"==e&&h.top-m-j<0?"bottom":"right"==e&&h.right+i>n?"left":"left"==e&&h.left-i
'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery);
\ No newline at end of file
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.1.1",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.1.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};c.VERSION="3.1.1",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(".item"),this.$items.index(this.$active)},c.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")}));var l=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(l)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(l)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),(h=e.attr("data-slide-to"))&&f.data("bs.carousel").to(h),c.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.1.1",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(b){return b&&b.target!=this.$element[0]?void this.$element.one(a.support.transition.end,a.proxy(g,this)):(this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,void this.$element.off(a.support.transition.end+".bs.collapse").trigger("shown.bs.collapse"))};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.on(a.support.transition.end+".bs.collapse",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(b){return b&&b.target!=this.$element[0]?void this.$element.one(a.support.transition.end,a.proxy(d,this)):(this.transitioning=0,void this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse"))};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.1.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('
').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j ').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;e?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var f=function(){c.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,f).emulateTransitionEnd(150):f()}else b&&b()},c.prototype.checkScrollbar=function(){document.body.clientWidth>=window.innerWidth||(this.scrollbarWidth=this.scrollbarWidth||this.measureScrollbar())},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0);this.scrollbarWidth&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),b.call(f,g,this),f.one("hide.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.1.1",c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=e,l=this.$element.parent(),m=this.getPosition(l);e="bottom"==e&&h.top+h.height+j-m.scroll>m.height?"top":"top"==e&&h.top-m.scroll-j<0?"bottom":"right"==e&&h.right+i>m.width?"left":"left"==e&&h.left-ig.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.1.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").empty()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scrollspy",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.1.1",b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).filter(":visible").map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight),d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.1.1",c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.closest("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},c.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(c){c.preventDefault(),b.call(a(this),"show")})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.1.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=a(document).height(),d=this.$target.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=b-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){null!=this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:b-this.$element.height()-h}))}}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},d.offsetBottom&&(d.offset.bottom=d.offsetBottom),d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/frappe/public/js/lib/highlight.pack.js b/frappe/public/js/lib/highlight.pack.js
new file mode 100644
index 0000000000..e602d3a443
--- /dev/null
+++ b/frappe/public/js/lib/highlight.pack.js
@@ -0,0 +1,8 @@
+var hljs=new function(){function k(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function i(w,x){var v=w&&w.exec(x);return v&&v.index==0}function d(v){return Array.prototype.map.call(v.childNodes,function(w){if(w.nodeType==3){return b.useBR?w.nodeValue.replace(/\n/g,""):w.nodeValue}if(t(w)=="br"){return"\n"}return d(w)}).join("")}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^language-/,"")});return v.filter(function(x){return j(x)||x=="no-highlight"})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(t(A)=="br"){z+=1}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""+t(G)+">"}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=k(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+k(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};function E(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})}if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b=D.bK.split(" ").join("|")}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?\\b("+F.b+")\\b\\.?":F.b}).concat([D.tE]).concat([D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}};D.continuation={}}x(y)}function c(S,L,J,R){function v(U,V){for(var T=0;T";U+=Z+'">';return U+X+Y}function N(){var U=k(C);if(!I.k){return U}var T="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(U);while(V){T+=U.substr(X,V.index-X);var W=E(I,V);if(W){H+=W[1];T+=w(W[0],V[0])}else{T+=V[0]}X=I.lR.lastIndex;V=I.lR.exec(U)}return T+U.substr(X)}function F(){if(I.sL&&!f[I.sL]){return k(C)}var T=I.sL?c(I.sL,C,true,I.continuation.top):g(C);if(I.r>0){H+=T.r}if(I.subLanguageMode=="continuous"){I.continuation.top=T.top}return w(T.language,T.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(V,U){var T=V.cN?w(V.cN,"",true):"";if(V.rB){D+=T;C=""}else{if(V.eB){D+=k(U)+T;C=""}else{D+=T;C=U}}I=Object.create(V,{parent:{value:I}})}function G(T,X){C+=T;if(X===undefined){D+=Q();return 0}var V=v(X,I);if(V){D+=Q();P(V,X);return V.rB?0:X.length}var W=z(I,X);if(W){var U=I;if(!(U.rE||U.eE)){C+=X}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=W.parent);if(U.eE){D+=k(X)}C="";if(W.starts){P(W.starts,"")}return U.rE?0:X.length}if(A(X,I)){throw new Error('Illegal lexeme "'+X+'" for mode "'+(I.cN||"")+'"')}C+=X;return X.length||1}var M=j(S);if(!M){throw new Error('Unknown language: "'+S+'"')}m(M);var I=R||M;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,D,true)}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:S,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:k(L)}}else{throw O}}}function g(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:k(y)};var w=v;x.forEach(function(z){if(!j(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function h(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g," ")}return v}function p(z){var y=d(z);var A=r(z);if(A=="no-highlight"){return}var v=A?c(A,y,true):g(y);var w=u(z);if(w.length){var x=document.createElementNS("http://www.w3.org/1999/xhtml","pre");x.innerHTML=v.value;v.value=q(w,u(x),y)}v.value=h(v.value);z.innerHTML=v.value;z.className+=" hljs "+(!A&&v.language||"");z.result={language:v.language,re:v.r};if(v.second_best){z.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function e(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function j(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=g;this.fixMarkup=h;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=e;this.getLanguage=j;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/,e:/>;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}});hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/,r:0,c:[d,{cN:"attribute",b:c,r:0},{b:"=",r:0,c:[{cN:"value",v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html"],cI:true,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"",rE:true,sL:"css"}},{cN:"tag",b:"
+
-
-
+
+
{%- block head_include %}{% endblock -%}
{%- block head -%}
- {%- if metatags -%}
- {%- for name in metatags %}
-
- {%- endfor -%}
- {%- endif -%}
+ {% if meta_block is defined %}
+ {{ meta_block }}
+ {% endif %}
+
{%- for link in web_include_css %}
{%- endfor -%}
@@ -29,6 +32,10 @@ https://frappe.io/apps/frappe
{%- if style is defined -%}{{ style }}{%- endif -%}
{%- endblock -%}
+
+ {%- for link in web_include_js %}
+
+ {%- endfor -%}
{%- endblock -%}
@@ -45,15 +52,15 @@ https://frappe.io/apps/frappe
@@ -89,10 +96,6 @@ https://frappe.io/apps/frappe
{%- block footer -%}{% include "templates/includes/footer.html" %}{%- endblock -%}
- {%- for link in web_include_js %}
-
- {%- endfor -%}
-
{%- block script %}
+{% endblock %}
diff --git a/frappe/templates/generators/web_page.html b/frappe/templates/generators/web_page.html
index f78c46c662..2311ca6872 100644
--- a/frappe/templates/generators/web_page.html
+++ b/frappe/templates/generators/web_page.html
@@ -1,7 +1,7 @@
{% block title %}{{ title }}{% endblock %}
{% block header %}
-{% if "<" in header %}{{ header }}{% else %}
{{ header }} {% endif %}
+{{ header }}
{% endblock %}
{% block content %}
@@ -28,6 +28,6 @@ $(function() {
{% endblock %}
-{% block style %}{{ style }}{% endblock %}
+{% block style %}{{ style or "" }}{% endblock %}
-{% block script %}{{ script }}{% endblock %}
+{% block script %}{{ script or "" }}{% endblock %}
diff --git a/frappe/templates/generators/web_page.py b/frappe/templates/generators/web_page.py
deleted file mode 100644
index aed21a4ef5..0000000000
--- a/frappe/templates/generators/web_page.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow
-from frappe.website.utils import find_first_image
-
-doctype = "Web Page"
-condition_field = "published"
-
-def get_context(context):
- web_page = frappe._dict(context.doc.as_dict())
-
- if web_page.slideshow:
- web_page.update(get_slideshow(web_page))
-
- if web_page.enable_comments:
- web_page.comment_list = frappe.db.sql("""select
- comment, comment_by_fullname, creation
- from `tabComment` where comment_doctype="Web Page"
- and comment_docname=%s order by creation""", web_page.name, as_dict=1) or []
-
- web_page.update({
- "style": web_page.css or "",
- "script": web_page.javascript or ""
- })
- web_page.update(context)
-
- web_page.metatags = {
- "name": web_page.title,
- "description": web_page.description or web_page.main_section[:150]
- }
-
- image = find_first_image(web_page.main_section)
- if image:
- web_page.metatags["image"] = image
-
-
- if not web_page.header:
- web_page.header = web_page.title
-
- return web_page
diff --git a/frappe/templates/generators/website_group.py b/frappe/templates/generators/website_group.py
deleted file mode 100644
index 77ad3aeb3a..0000000000
--- a/frappe/templates/generators/website_group.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-from frappe.website.permissions import get_access
-from frappe.website.render import can_cache
-from frappe.templates.website_group.forum import get_post_list_html
-
-doctype = "Website Group"
-no_cache = 1
-
-def get_context(context):
- group, view = guess_group_view(context)
-
- try:
- if not has_access(context.access, view):
- raise frappe.PermissionError
-
- return get_group_context(group, view, context)
-
- except frappe.DoesNotExistError:
- return {
- "content": '
'
- 'The page you are looking for does not exist.
'
- }
- except frappe.PermissionError:
- return {
- "content": '
'
- 'You are not permitted to view this page.
'
- }
-
-def get_group_context(group, view, context):
- cache_key = "website_group_context:{}:{}".format(group, view)
-
- views = get_views(context.doc.group_type)
- view = frappe._dict(views.get(view))
-
- if can_cache(view.no_cache):
- group_context = frappe.cache().get_value(cache_key)
- if group_context:
- return group_context
-
- group_context = build_group_context(group, view, views, context)
-
- if can_cache(view.get("no_cache")):
- frappe.cache().set_value(cache_key, group_context)
-
- return group_context
-
-def build_group_context(group, view, views, context):
- title = "{} - {}".format(context.doc.group_title, view.get("label"))
-
- group_context = frappe._dict({
- "group": context.doc,
- "view": view,
- "views": [v[1] for v in sorted(views.iteritems(), key=lambda (k, v): v.get("idx"))],
- "title": title,
- "pathname": context.pathname
- })
- group_context.update(build_view_context(group_context))
-
- return group_context
-
-def build_view_context(context):
- from frappe.templates.website_group.post import get_post_context
-
- if context.view.name in ("popular", "feed", "open", "closed", "upcoming", "past"):
- context.post_list_html = get_post_list_html(context.group.name, context.view.name)
-
- elif context.view.name == "edit":
- context.post = frappe.get_doc("Post", frappe.form_dict.name).as_dict()
-
- if context.post.assigned_to:
- context.user = frappe.get_doc("User", context.post.assigned_to)
-
- elif context.view.name == "settings":
- context.users = frappe.db.sql("""select p.*, wsp.`read`, wsp.`write`, wsp.`admin`
- from `tabUser` p, `tabWebsite Route Permission` wsp
- where wsp.website_route=%s and wsp.user=p.name""", context.pathname, as_dict=True)
-
- elif context.view.name == "post":
- context.update(get_post_context(context))
-
- return context
-
-def guess_group_view(context):
- group = context.docname
- view = frappe.form_dict.view or get_default_view(context.doc.group_type)
- return group, view
-
-def get_default_view(group_type):
- for view, opts in get_views(group_type).iteritems():
- if opts.get("default"):
- return view
-
-def get_views(group_type=None):
- if group_type:
- group_views = frappe._dict(views[group_type])
- else:
- group_views = {}
- for group_type in views:
- group_views.update(views[group_type].copy())
-
- group_views.update(common_views)
-
- if group_type == "Forum":
- group_views["post"]["upvote"] = True
-
- return group_views
-
-def has_access(access, view):
- if view=="settings":
- return access.get("admin")
- elif view in ("add", "edit"):
- return access.get("write")
- else:
- return access.get("read")
-
-def clear_cache(path=None, website_group=None):
- from frappe.templates.website_group.post import clear_post_cache
- if path:
- website_groups = [frappe.db.get_value("Website Route", path, "docname")]
- elif website_group:
- website_groups = [website_group]
- else:
- clear_post_cache()
- website_groups = frappe.db.sql_list("""select name from `tabWebsite Group`""")
-
- cache = frappe.cache()
- all_views = get_views()
- for group in website_groups:
- for view in all_views:
- cache.delete_value("website_group_context:{}:{}".format(group, view))
-
-def clear_event_cache():
- for group in frappe.db.sql_list("""select name from `tabWebsite Group` where group_type='Event'"""):
- clear_unit_views(website_group=group)
-
-def clear_cache_on_doc_event(doc, method, *args, **kwargs):
- clear_cache(path=doc.website_route, website_group=doc.website_group)
-
-def get_pathname(group):
- return frappe.db.get_value("Website Route", {"ref_doctype": "Website Group",
- "docname": group})
-
-views = {
- "Forum": {
- "popular": {
- "name": "popular",
- "template_path": "templates/website_group/forum.html",
- "label": "Popular",
- "icon": "icon-heart",
- "default": True,
- "upvote": True,
- "idx": 1
- },
- "feed": {
- "name": "feed",
- "template_path": "templates/website_group/forum.html",
- "label": "Feed",
- "icon": "icon-rss",
- "upvote": True,
- "idx": 2
- }
- },
- "Tasks": {
- "open": {
- "name": "open",
- "template_path": "templates/website_group/forum.html",
- "label": "Open",
- "icon": "icon-inbox",
- "default": True,
- "upvote": True,
- "idx": 1
- },
- "closed": {
- "name": "closed",
- "template_path": "templates/website_group/forum.html",
- "label": "Closed",
- "icon": "icon-smile",
- "idx": 2
- }
- },
- "Events": {
- "upcoming": {
- "name": "upcoming",
- "template_path": "templates/website_group/forum.html",
- "label": "Upcoming",
- "icon": "icon-calendar",
- "default": True,
- "idx": 1
- },
- "past": {
- "name": "past",
- "template_path": "templates/website_group/forum.html",
- "label": "Past",
- "icon": "icon-time",
- "idx": 2
- }
- }
-}
-
-common_views = {
- "post": {
- "name": "post",
- "template_path": "templates/website_group/post.html",
- "label": "Post",
- "icon": "icon-comments",
- "hidden": True,
- "no_cache": True,
- "idx": 3
- },
- "edit": {
- "name": "edit",
- "template_path": "templates/website_group/edit_post.html",
- "label": "Edit Post",
- "icon": "icon-pencil",
- "hidden": True,
- "no_cache": True,
- "idx": 4
- },
- "add": {
- "name": "add",
- "template_path": "templates/website_group/edit_post.html",
- "label": "Add Post",
- "icon": "icon-plus",
- "hidden": True,
- "idx": 5
- },
- "settings": {
- "name": "settings",
- "template_path": "templates/website_group/settings.html",
- "label": "Settings",
- "icon": "icon-cog",
- "hidden": True,
- "idx": 6
- }
-}
diff --git a/frappe/templates/includes/blog.js b/frappe/templates/includes/blog.js
index de1eb250ec..00ef5f649d 100644
--- a/frappe/templates/includes/blog.js
+++ b/frappe/templates/includes/blog.js
@@ -8,9 +8,8 @@ var blog = {
get_list: function() {
$.ajax({
method: "GET",
- url: "/",
+ url: "/api/method/frappe.website.doctype.blog_post.blog_post.get_blog_list",
data: {
- cmd: "frappe.templates.generators.blog_post.get_blog_list",
start: blog.start,
by: get_url_arg("by"),
category: window.category || get_url_arg("category")
diff --git a/frappe/templates/includes/breadcrumbs.html b/frappe/templates/includes/breadcrumbs.html
index f33ab80905..fde3aaf482 100644
--- a/frappe/templates/includes/breadcrumbs.html
+++ b/frappe/templates/includes/breadcrumbs.html
@@ -1,3 +1,4 @@
+{% set parents = doc.get_parents() if (doc and doc.get_parents) else [] %}
{% if parents|length > 0 %}
{% for parent in parents %}
diff --git a/frappe/templates/includes/comments.html b/frappe/templates/includes/comments.html
index 06e789f086..ecb2c7f641 100644
--- a/frappe/templates/includes/comments.html
+++ b/frappe/templates/includes/comments.html
@@ -18,7 +18,7 @@
+ placeholder="Your Email Id" type="email"/>
@@ -62,6 +62,11 @@ $(document).ready(function() {
return false;
}
+ if (!valid_email(args.comment_by)) {
+ frappe.msgprint("Please enter a valid email address.");
+ return false;
+ }
+
frappe.call({
btn: this,
type: "POST",
diff --git a/frappe/templates/includes/comments.py b/frappe/templates/includes/comments.py
index 2ee7858cda..6fe8840b33 100644
--- a/frappe/templates/includes/comments.py
+++ b/frappe/templates/includes/comments.py
@@ -43,7 +43,7 @@ def add_comment(args=None):
ifnull(unsubscribed, 0)=0""", (comment.comment_doctype, comment.comment_docname))]
owner = frappe.db.get_value(comment.comment_doctype, comment.comment_docname, "owner")
- recipients = commentors if owner=="Administrator" else list(set(commentors + [owner]))
+ recipients = list(set(commentors if owner=="Administrator" else (commentors + [owner])))
from frappe.utils.email_lib.bulk import send
diff --git a/frappe/templates/includes/login.js b/frappe/templates/includes/login.js
index e79af5dfad..00d81f5460 100644
--- a/frappe/templates/includes/login.js
+++ b/frappe/templates/includes/login.js
@@ -100,10 +100,13 @@ login.login_handlers = (function() {
var login_handlers = {
200: function(data) {
if(data.message=="Logged In") {
- window.location.href = "desk";
+ window.location.href = get_url_arg("redirect-to") || "/desk";
} else if(data.message=="No App") {
if(localStorage) {
- var last_visited = localStorage.getItem("last_visited") || "/index";
+ var last_visited =
+ localStorage.getItem("last_visited")
+ || get_url_arg("redirect-to")
+ || "/index";
localStorage.removeItem("last_visited");
window.location.href = last_visited;
} else {
@@ -124,5 +127,6 @@ frappe.ready(function() {
window.location.hash = "#login";
login.bind_events();
login.login();
+ $(".form-signup, .form-forgot").removeClass("hide");
$(document).trigger('login_rendered');
});
diff --git a/frappe/templates/includes/meta_block.html b/frappe/templates/includes/meta_block.html
new file mode 100644
index 0000000000..e311040606
--- /dev/null
+++ b/frappe/templates/includes/meta_block.html
@@ -0,0 +1,5 @@
+{%- if metatags -%}
+{%- for name in metatags %}
+
+{%- endfor -%}
+{%- endif -%}
diff --git a/frappe/templates/includes/navbar.html b/frappe/templates/includes/navbar.html
index a49af7a409..b0eb249cae 100644
--- a/frappe/templates/includes/navbar.html
+++ b/frappe/templates/includes/navbar.html
@@ -39,15 +39,15 @@
- {% if not disable_signup %}
- Sign Up / Login
- {% endif %}
+
+ {%- if not disable_signup %}Sign Up / {% endif -%} Login
diff --git a/frappe/templates/includes/sidebar.html b/frappe/templates/includes/sidebar.html
index d88756094a..5cea826b02 100644
--- a/frappe/templates/includes/sidebar.html
+++ b/frappe/templates/includes/sidebar.html
@@ -1,17 +1,12 @@
{% if children -%}
+
{%- endif %}
diff --git a/frappe/templates/includes/static_index.html b/frappe/templates/includes/static_index.html
index 7b0bc34cd8..dff735a3f2 100644
--- a/frappe/templates/includes/static_index.html
+++ b/frappe/templates/includes/static_index.html
@@ -2,12 +2,12 @@
- {% for item in items[1:] %}
+ {% for item in items %}
diff --git a/frappe/templates/pages/404.py b/frappe/templates/pages/404.py
index a770759b5e..ddd7ca82c8 100644
--- a/frappe/templates/pages/404.py
+++ b/frappe/templates/pages/404.py
@@ -1,4 +1,4 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
-no_sitemap = 1
\ No newline at end of file
+no_sitemap = 1
diff --git a/frappe/templates/pages/blog.py b/frappe/templates/pages/blog.py
index 7181ff63b4..182ddb8575 100644
--- a/frappe/templates/pages/blog.py
+++ b/frappe/templates/pages/blog.py
@@ -4,5 +4,12 @@
from __future__ import unicode_literals
import frappe
+page_title = "Blog"
def get_context(context):
- return frappe.get_doc("Blog Settings", "Blog Settings").as_dict()
+ context.update(frappe.get_doc("Blog Settings", "Blog Settings").as_dict())
+ context.children = get_children()
+
+def get_children():
+ return frappe.db.sql("""select concat("blog/", page_name) as name,
+ title from `tabBlog Category`
+ where ifnull(published, 0) = 1 order by title asc""", as_dict=1)
diff --git a/frappe/templates/pages/contact.py b/frappe/templates/pages/contact.py
index 1e67cff6e1..29180a2d6c 100644
--- a/frappe/templates/pages/contact.py
+++ b/frappe/templates/pages/contact.py
@@ -25,7 +25,7 @@ def get_context(context):
return out
-max_communications_per_hour = 300
+max_communications_per_hour = 1000
@frappe.whitelist(allow_guest=True)
def send_message(subject="Website Query", message="", sender=""):
@@ -39,7 +39,8 @@ def send_message(subject="Website Query", message="", sender=""):
# guest method, cap max writes per hour
if frappe.db.sql("""select count(*) from `tabCommunication`
- where TIMEDIFF(%s, modified) < '01:00:00'""", now())[0][0] > max_communications_per_hour:
+ where `sent_or_received`="Received"
+ and TIMEDIFF(%s, modified) < '01:00:00'""", now())[0][0] > max_communications_per_hour:
frappe.response["message"] = "Sorry: we believe we have received an unreasonably high number of requests of this kind. Please try later"
return
diff --git a/frappe/templates/pages/desk.html b/frappe/templates/pages/desk.html
index ff5bf36c04..9cca6df178 100644
--- a/frappe/templates/pages/desk.html
+++ b/frappe/templates/pages/desk.html
@@ -4,9 +4,11 @@
Frappe Desk
-
-
-
+
+
+
{% for include in include_css -%}
{%- endfor -%}
diff --git a/frappe/templates/pages/error.py b/frappe/templates/pages/error.py
index ade4f98b04..3c14599752 100644
--- a/frappe/templates/pages/error.py
+++ b/frappe/templates/pages/error.py
@@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
+# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
@@ -8,4 +8,5 @@ no_cache = 1
no_sitemap = 1
def get_context(context):
- return {"error": frappe.get_traceback()}
+ print frappe.get_traceback()
+ return {"error": frappe.get_traceback() }
diff --git a/frappe/templates/pages/list.py b/frappe/templates/pages/list.py
index 0e05b2f288..a111a157ea 100644
--- a/frappe/templates/pages/list.py
+++ b/frappe/templates/pages/list.py
@@ -39,7 +39,7 @@ def get_items(type, txt, limit_start=0):
#template_path = os.path.relpath(template_path)
template = env.get_template(template_path)
else:
- template = Template("""
+ template = Template("""""")
out.items = [template.render(doc=i, doctype=type,
diff --git a/frappe/templates/pages/login.html b/frappe/templates/pages/login.html
index d57871f75d..c3f923d098 100644
--- a/frappe/templates/pages/login.html
+++ b/frappe/templates/pages/login.html
@@ -4,7 +4,7 @@
{% endblock %}
{% block script_lib %}{% include "templates/includes/login.js" %}{% endblock %}
-{% block sidebar %}{% endblock %}
\ No newline at end of file
+{% block sidebar %}{% endblock %}
diff --git a/frappe/templates/pages/login.py b/frappe/templates/pages/login.py
index a20383643c..2e7b536b43 100644
--- a/frappe/templates/pages/login.py
+++ b/frappe/templates/pages/login.py
@@ -7,11 +7,14 @@ import json
import frappe.utils
from frappe import _
+class SignupDisabledError(frappe.PermissionError): pass
+
no_cache = True
def get_context(context):
# get settings from site config
context["title"] = "Login"
+ context["disable_signup"] = frappe.utils.cint(frappe.db.get_value("Website Settings", "Website Settings", "disable_signup"))
for provider in ("google", "github", "facebook"):
if get_oauth_keys(provider):
@@ -67,7 +70,7 @@ oauth2_providers = {
"auth_url_data": {
"display": "page",
"response_type": "code",
- "scope": "email,user_birthday"
+ "scope": "email,public_profile"
},
# relative to base_url
@@ -159,54 +162,72 @@ def login_via_oauth2(provider, code, decoder=None):
def login_oauth_user(data, provider=None):
user = data["email"]
- if not frappe.db.exists("User", user):
- create_oauth_user(data, provider)
+ try:
+ update_oauth_user(user, data, provider)
+ except SignupDisabledError:
+ return frappe.respond_as_web_page("Signup is Disabled", "Sorry. Signup from Website is disabled.",
+ success=False, http_status_code=403)
frappe.local.login_manager.user = user
frappe.local.login_manager.post_login()
# redirect!
frappe.local.response["type"] = "redirect"
- frappe.local.response["location"] = "/app" if frappe.local.response.get('message') == 'Logged In' else "/"
+
+ # the #desktop is added to prevent a facebook redirect bug
+ frappe.local.response["location"] = "/desk#desktop" if frappe.local.response.get('message') == 'Logged In' else "/"
# because of a GET request!
frappe.db.commit()
-def create_oauth_user(data, provider):
- if data.get("birthday"):
- from frappe.utils.dateutils import parse_date
- data["birthday"] = parse_date(data["birthday"])
-
+def update_oauth_user(user, data, provider):
if isinstance(data.get("location"), dict):
data["location"] = data.get("location").get("name")
- user = frappe.get_doc({
- "doctype":"User",
- "first_name": data.get("first_name") or data.get("given_name") or data.get("name"),
- "last_name": data.get("last_name") or data.get("family_name"),
- "email": data["email"],
- "gender": data.get("gender"),
- "enabled": 1,
- "new_password": frappe.generate_hash(data["email"]),
- "location": data.get("location"),
- "birth_date": data.get("birthday"),
- "user_type": "Website User",
- "user_image": data.get("picture") or data.get("avatar_url")
- })
-
- if provider=="facebook":
+ save = False
+
+ if not frappe.db.exists("User", user):
+
+ # is signup disabled?
+ if frappe.utils.cint(frappe.db.get_single_value("Website Settings", "disable_signup")):
+ raise SignupDisabledError
+
+ save = True
+ user = frappe.new_doc("User")
+ user.update({
+ "doctype":"User",
+ "first_name": data.get("first_name") or data.get("given_name") or data.get("name"),
+ "last_name": data.get("last_name") or data.get("family_name"),
+ "email": data["email"],
+ "gender": (data.get("gender") or "").title(),
+ "enabled": 1,
+ "new_password": frappe.generate_hash(data["email"]),
+ "location": data.get("location"),
+ "user_type": "Website User",
+ "user_image": data.get("picture") or data.get("avatar_url")
+ })
+
+ else:
+ user = frappe.get_doc("User", user)
+
+ if provider=="facebook" and not user.get("fb_userid"):
+ save = True
user.update({
- "fb_username": data["username"],
+ "fb_username": data.get("username"),
"fb_userid": data["id"],
- "user_image": "https://graph.facebook.com/{username}/picture".format(username=data["username"])
+ "user_image": "https://graph.facebook.com/{id}/picture".format(id=data["id"])
})
- elif provider=="google":
+
+ elif provider=="google" and not user.get("google_userid"):
+ save = True
user.google_userid = data["id"]
- elif provider=="github":
+ elif provider=="github" and not user.get("github_userid"):
+ save = True
user.github_userid = data["id"]
user.github_username = data["login"]
- user.ignore_permissions = True
- user.no_welcome_mail = True
- user.insert()
+ if save:
+ user.ignore_permissions = True
+ user.no_welcome_mail = True
+ user.save()
diff --git a/frappe/templates/pages/message.html b/frappe/templates/pages/message.html
index 2c70bf8457..d57b765f72 100644
--- a/frappe/templates/pages/message.html
+++ b/frappe/templates/pages/message.html
@@ -1,7 +1,6 @@
{% block title %}{{ title }}{% endblock %}
-{% block header %}
- {{ title }} {% endblock %}
+{% block header %}{{ title }}{% endblock %}
{% block content %}
diff --git a/frappe/templates/pages/print.html b/frappe/templates/pages/print.html
index 4c118d6e1a..0e69a533f4 100644
--- a/frappe/templates/pages/print.html
+++ b/frappe/templates/pages/print.html
@@ -3,16 +3,21 @@
-
Print Format
+
{{ title }}
+
- {{ body }}
+
{%- if comment -%}
{%- endif -%}
-
\ No newline at end of file
+