summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/css/apps.css32
-rw-r--r--core/css/auth.css39
-rw-r--r--core/css/styles.css40
-rw-r--r--core/js/compatibility.js4
-rw-r--r--core/js/core.json3
-rw-r--r--core/js/jquery.avatar.js6
-rw-r--r--core/js/js.js138
-rw-r--r--core/js/oc-dialogs.js46
-rw-r--r--core/js/share.js6
-rw-r--r--core/js/tests/specs/coreSpec.js93
-rw-r--r--core/js/underscore.js1344
-rw-r--r--core/l10n/ast.php74
-rw-r--r--core/l10n/ca.php1
-rw-r--r--core/l10n/cs_CZ.php1
-rw-r--r--core/l10n/da.php1
-rw-r--r--core/l10n/de.php1
-rw-r--r--core/l10n/de_CH.php1
-rw-r--r--core/l10n/de_DE.php1
-rw-r--r--core/l10n/el.php8
-rw-r--r--core/l10n/en_GB.php2
-rw-r--r--core/l10n/eo.php1
-rw-r--r--core/l10n/es.php2
-rw-r--r--core/l10n/es_AR.php1
-rw-r--r--core/l10n/et_EE.php12
-rw-r--r--core/l10n/eu.php1
-rw-r--r--core/l10n/fa.php1
-rw-r--r--core/l10n/fi_FI.php4
-rw-r--r--core/l10n/fr.php4
-rw-r--r--core/l10n/gl.php2
-rw-r--r--core/l10n/he.php1
-rw-r--r--core/l10n/hu_HU.php1
-rw-r--r--core/l10n/it.php1
-rw-r--r--core/l10n/ja.php4
-rw-r--r--core/l10n/jv.php9
-rw-r--r--core/l10n/ka_GE.php1
-rw-r--r--core/l10n/lv.php1
-rw-r--r--core/l10n/nb_NO.php5
-rw-r--r--core/l10n/nl.php2
-rw-r--r--core/l10n/pl.php2
-rw-r--r--core/l10n/pl_PL.php6
-rw-r--r--core/l10n/pt_BR.php2
-rw-r--r--core/l10n/pt_PT.php1
-rw-r--r--core/l10n/ru.php1
-rw-r--r--core/l10n/sk_SK.php14
-rw-r--r--core/l10n/sl.php1
-rw-r--r--core/l10n/sv.php17
-rw-r--r--core/l10n/th_TH.php1
-rw-r--r--core/l10n/tr.php10
-rw-r--r--core/l10n/uk.php1
-rw-r--r--core/l10n/vi.php1
-rw-r--r--core/l10n/zh_CN.php1
-rw-r--r--core/l10n/zh_TW.php1
-rw-r--r--core/lostpassword/templates/resetpassword.php10
53 files changed, 1826 insertions, 137 deletions
diff --git a/core/css/apps.css b/core/css/apps.css
index 0e6a080c9cd..a8dfc5b7ed1 100644
--- a/core/css/apps.css
+++ b/core/css/apps.css
@@ -29,10 +29,14 @@
-moz-box-sizing: border-box; box-sizing: border-box;
}
#app-navigation .active,
-#app-navigation .active a,
-#app-navigation li:hover > a {
+#app-navigation .active a {
background-color: #ddd;
}
+#app-navigation li:hover > a,
+#app-navigation .selected,
+#app-navigation .selected a {
+ background-color: #ccc;
+}
/* special rules for first-level entries and folders */
#app-navigation > ul > li {
@@ -151,9 +155,6 @@
transition: padding-bottom 500ms ease 0s;
padding-bottom: 40px;
}
-#app-navigation .personalblock > legend { /* TODO @Raydiation: still needed? */
- padding: 10px 0; margin: 0;
-}
#app-navigation .error {
color: #dd1144;
}
@@ -242,3 +243,24 @@ button.loading {
padding-right: 30px;
}
+
+/* general styles for the content area */
+.section {
+ display: block;
+ padding: 30px;
+ color: #555;
+ border-top: 1px solid #ddd;
+}
+.section h2 {
+ font-size: 20px;
+ margin-bottom: 7px;
+}
+.section h3 {
+ font-size: 16px;
+}
+/* slight position correction of checkboxes and radio buttons */
+.section input[type="checkbox"],
+.section input[type="radio"] {
+ vertical-align: -2px;
+ margin-right: 4px;
+}
diff --git a/core/css/auth.css b/core/css/auth.css
deleted file mode 100644
index 70df9f0ae0f..00000000000
--- a/core/css/auth.css
+++ /dev/null
@@ -1,39 +0,0 @@
-h2 {
- font-size:32px;
- font-weight:700;
- margin-bottom:16px;
- white-space:nowrap;
-}
-
-ul.scopes {
- list-style:disc;
-}
-
-ul.scopes li {
- white-space:nowrap;
-}
-
-h2 img {
- width:50%;
-}
-
-#oauth {
- width:320px;
- margin:64px auto 32px;
-}
-
-#allow-auth {
- background-color:#5c3;
- box-shadow:0 1px 1px #fff, 0 1px 1px #5f3 inset;
- color:#fff;
- text-shadow:#5e3 0 1px 0;
-}
-
-#deny-auth {
- background:none;
- border:0;
- box-shadow:0 0 0 #fff, 0 0 0 #fff inset;
- font-size:19px;
- margin:11px;
- padding:0;
-}
diff --git a/core/css/styles.css b/core/css/styles.css
index 2c043ab724c..57e2c4479a1 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -101,11 +101,18 @@ input[type="time"],
textarea,
select,
button, .button,
+input[type="submit"],
+input[type="button"],
#quota,
.pager li a {
- width:10em; margin:.3em; padding:.6em .5em .4em;
- font-size:1em;
- background:#fff; color:#333; border:1px solid #ddd; outline:none;
+ width: 130px;
+ margin: 3px 3px 3px 0;
+ padding: 7px 6px 5px;
+ font-size: 13px;
+ background-color: #fff;
+ color: #333;
+ border: 1px solid #ddd;
+ outline: none;
border-radius: 3px;
}
input[type="hidden"] {
@@ -170,14 +177,12 @@ input[type="submit"], input[type="button"],
button, .button,
#quota, select, .pager li a {
width: auto;
- padding: .4em;
+ padding: 5px;
background-color: rgba(240,240,240,.9);
font-weight: bold;
color: #555;
border: 1px solid rgba(190,190,190,.9);
cursor: pointer;
- border-radius: 3px;
- outline: none;
}
input[type="submit"]:hover, input[type="submit"]:focus,
input[type="button"]:hover, input[type="button"]:focus,
@@ -278,6 +283,10 @@ input[type="submit"].enabled {
padding: 7px 10px
}
+#controls .button.hidden {
+ display: none;
+}
+
#content { position:relative; height:100%; width:100%; }
#content .hascontrols {
position: relative;
@@ -793,20 +802,12 @@ tr .action { width:16px; height:16px; }
tr:hover .action:hover, .selectedActions a:hover, .header-action:hover { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
tbody tr:hover, tr:active { background-color:#f8f8f8; }
-#body-settings h2 {
- font-size: 20px;
- font-weight: normal;
- margin-bottom: 7px;
-}
-#body-settings .personalblock, #body-settings .helpblock {
- padding: 30px;
- color: #555;
- border-top: 1px solid #ddd;
-}
-#body-settings .personalblock#quota { position:relative; padding:0; }
-#body-settings #controls+.helpblock { position:relative; margin-top:3em; }
code { font-family:"Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", monospace; }
+#quota {
+ position: relative;
+ padding: 0;
+}
#quota div {
padding: 0;
background-color: rgb(220,220,220);
@@ -925,6 +926,9 @@ div.crumb {
background: url('../img/breadcrumb.svg') no-repeat right center;
height: 44px;
}
+div.crumb.hidden {
+ display: none;
+}
div.crumb a,
div.crumb span {
position: relative;
diff --git a/core/js/compatibility.js b/core/js/compatibility.js
index 6548f95d42b..c07288857f2 100644
--- a/core/js/compatibility.js
+++ b/core/js/compatibility.js
@@ -148,3 +148,7 @@ function outerHTML(node){
return h;
})(node);
}
+
+// devicePixelRatio for IE10
+window.devicePixelRatio = window.devicePixelRatio ||
+ window.screen.deviceXDPI / window.screen.logicalXDPI || 1;
diff --git a/core/js/core.json b/core/js/core.json
index 665e2485a90..05c2a17a679 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -6,7 +6,8 @@
"jquery-showpassword.js",
"jquery.infieldlabel.js",
"jquery.placeholder.js",
- "jquery-tipsy.js"
+ "jquery-tipsy.js",
+ "underscore.js"
],
"modules": [
"compatibility.js",
diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js
index 381c42d9dbb..7c19cb321fe 100644
--- a/core/js/jquery.avatar.js
+++ b/core/js/jquery.avatar.js
@@ -77,7 +77,7 @@
var url = OC.generateUrl(
'/avatar/{user}/{size}?requesttoken={requesttoken}',
- {user: user, size: size, requesttoken: oc_requesttoken});
+ {user: user, size: size * window.devicePixelRatio, requesttoken: oc_requesttoken});
$.get(url, function(result) {
if (typeof(result) === 'object') {
@@ -93,9 +93,9 @@
} else {
$div.show();
if (ie8fix === true) {
- $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
+ $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'#'+Math.floor(Math.random()*1000)+'">');
} else {
- $div.html('<img src="'+url+'">');
+ $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'">');
}
}
if(typeof callback === 'function') {
diff --git a/core/js/js.js b/core/js/js.js
index 302b6b4d9fa..1cbb9636dbe 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -159,6 +159,7 @@ function escapeHTML(s) {
* @param file The filename
* @param dir The directory the file is in - e.g. $('#dir').val()
* @return string
+* @deprecated use Files.getDownloadURL() instead
*/
function fileDownloadPath(dir, file) {
return OC.filePath('files', 'ajax', 'download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir);
@@ -371,6 +372,7 @@ var OC={
*/
parseQueryString:function(queryString){
var parts,
+ pos,
components,
result = {},
key,
@@ -378,12 +380,25 @@ var OC={
if (!queryString){
return null;
}
- if (queryString[0] === '?'){
- queryString = queryString.substr(1);
+ pos = queryString.indexOf('?');
+ if (pos >= 0){
+ queryString = queryString.substr(pos + 1);
}
- parts = queryString.split('&');
+ parts = queryString.replace(/\+/g, '%20').split('&');
for (var i = 0; i < parts.length; i++){
- components = parts[i].split('=');
+ // split on first equal sign
+ var part = parts[i]
+ pos = part.indexOf('=');
+ if (pos >= 0) {
+ components = [
+ part.substr(0, pos),
+ part.substr(pos + 1)
+ ]
+ }
+ else {
+ // key only
+ components = [part];
+ }
if (!components.length){
continue;
}
@@ -391,8 +406,14 @@ var OC={
if (!key){
continue;
}
- value = components[1];
- result[key] = value && decodeURIComponent(value);
+ // if equal sign was there, return string
+ if (components.length > 1) {
+ result[key] = decodeURIComponent(components[1]);
+ }
+ // no equal sign => null value
+ else {
+ result[key] = null;
+ }
}
return result;
},
@@ -477,7 +498,7 @@ var OC={
});
}
if(!SVGSupport()) {
- replaceSVG();
+ OC.Util.replaceSVG();
}
}).show();
}, 'html');
@@ -764,7 +785,7 @@ SVGSupport.checkMimeType=function(){
}
});
if(headers["content-type"]!=='image/svg+xml'){
- replaceSVG();
+ OC.Util.replaceSVG();
SVGSupport.checkMimeType.correct=false;
}
}
@@ -772,35 +793,10 @@ SVGSupport.checkMimeType=function(){
};
SVGSupport.checkMimeType.correct=true;
-//replace all svg images with png for browser compatibility
-function replaceSVG(){
- $('img.svg').each(function(index,element){
- element=$(element);
- var src=element.attr('src');
- element.attr('src',src.substr(0,src.length-3)+'png');
- });
- $('.svg').each(function(index,element){
- element=$(element);
- var background=element.css('background-image');
- if(background){
- var i=background.lastIndexOf('.svg');
- if(i>=0){
- background=background.substr(0,i)+'.png'+background.substr(i+4);
- element.css('background-image',background);
- }
- }
- element.find('*').each(function(index,element) {
- element=$(element);
- var background=element.css('background-image');
- if(background){
- var i=background.lastIndexOf('.svg');
- if(i>=0){
- background=background.substr(0,i)+'.png'+background.substr(i+4);
- element.css('background-image',background);
- }
- }
- });
- });
+// replace all svg images with png for browser compatibility
+// @deprecated use OC.Util.replaceSVG instead
+function replaceSVG($el){
+ return OC.Util.replaceSVG($el);
}
/**
@@ -879,7 +875,7 @@ function initCore() {
}
if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg
- replaceSVG();
+ OC.Util.replaceSVG();
}else{
SVGSupport.checkMimeType();
}
@@ -1113,6 +1109,72 @@ function relative_modified_date(timestamp) {
else { return t('core','years ago'); }
}
+OC.Util = {
+ /**
+ * Returns whether the browser supports SVG
+ *
+ * @return true if the browser supports SVG, false otherwise
+ */
+ // TODO: replace with original function
+ hasSVGSupport: SVGSupport,
+ /**
+ * If SVG is not supported, replaces the given icon's extension
+ * from ".svg" to ".png".
+ * If SVG is supported, return the image path as is.
+ *
+ * @param file image path with svg extension
+ * @return fixed image path with png extension if SVG is not
+ * supported
+ */
+ replaceSVGIcon: function(file) {
+ if (!OC.Util.hasSVGSupport()) {
+ var i = file.lastIndexOf('.svg');
+ if (i >= 0) {
+ file = file.substr(0, i) + '.png' + file.substr(i+4);
+ }
+ }
+ return file;
+ },
+ /**
+ * Replace SVG images in all elements that have the "svg" class set
+ * with PNG images.
+ *
+ * @param $el root element from which to search, defaults to $('body')
+ */
+ replaceSVG: function($el) {
+ if (!$el) {
+ $el = $('body');
+ }
+ $el.find('img.svg').each(function(index,element){
+ element=$(element);
+ var src=element.attr('src');
+ element.attr('src',src.substr(0, src.length-3) + 'png');
+ });
+ $el.find('.svg').each(function(index,element){
+ element = $(element);
+ var background = element.css('background-image');
+ if (background){
+ var i = background.lastIndexOf('.svg');
+ if (i >= 0){
+ background = background.substr(0,i) + '.png' + background.substr(i + 4);
+ element.css('background-image', background);
+ }
+ }
+ element.find('*').each(function(index, element) {
+ element = $(element);
+ var background = element.css('background-image');
+ if (background) {
+ var i = background.lastIndexOf('.svg');
+ if(i >= 0){
+ background = background.substr(0,i) + '.png' + background.substr(i + 4);
+ element.css('background-image', background);
+ }
+ }
+ });
+ });
+ }
+};
+
/**
* get a variable by name
* @param string name
diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js
index d1bcb4659b8..2233b983ad4 100644
--- a/core/js/oc-dialogs.js
+++ b/core/js/oc-dialogs.js
@@ -19,6 +19,8 @@
*
*/
+/* global OC, t */
+
/**
* this class to ease the usage of jquery dialogs
*/
@@ -138,6 +140,9 @@ var OCdialogs = {
self.$filePicker = null;
}
});
+ if (!OC.Util.hasSVGSupport()) {
+ OC.Util.replaceSVG(self.$filePicker.parent());
+ }
})
.fail(function(status, error) {
// If the method is called while navigating away
@@ -294,7 +299,7 @@ var OCdialogs = {
conflict.find('.replacement .mtime').text(formatDate(replacement.lastModifiedDate));
}
var path = original.directory + '/' +original.name;
- Files.lazyLoadPreview(path, original.mime, function(previewpath){
+ Files.lazyLoadPreview(path, original.mimetype, function(previewpath){
conflict.find('.original .icon').css('background-image','url('+previewpath+')');
}, 96, 96, original.etag);
getCroppedPreview(replacement).then(
@@ -343,7 +348,7 @@ var OCdialogs = {
addConflict(conflicts, original, replacement);
var count = $(dialog_id+ ' .conflict').length;
- var title = n('files',
+ var title = n('core',
'{count} file conflict',
'{count} file conflicts',
count,
@@ -358,14 +363,17 @@ var OCdialogs = {
//create dialog
this._fileexistsshown = true;
$.when(this._getFileExistsTemplate()).then(function($tmpl) {
- var title = t('files','One file conflict');
+ var title = t('core','One file conflict');
var $dlg = $tmpl.octemplate({
dialog_name: dialog_name,
title: title,
type: 'fileexists',
- why: t('files','Which files do you want to keep?'),
- what: t('files','If you select both versions, the copied file will have a number added to its name.')
+ allnewfiles: t('core','New Files'),
+ allexistingfiles: t('core','Already existing files'),
+
+ why: t('core','Which files do you want to keep?'),
+ what: t('core','If you select both versions, the copied file will have a number added to its name.')
});
$('body').append($dlg);
@@ -430,10 +438,10 @@ var OCdialogs = {
var count = $(dialog_id).find('.conflict .replacement input[type="checkbox"]:checked').length;
if (count === $(dialog_id+ ' .conflict').length) {
$(dialog_id).find('.allnewfiles').prop('checked', true);
- $(dialog_id).find('.allnewfiles + .count').text(t('files','(all selected)'));
+ $(dialog_id).find('.allnewfiles + .count').text(t('core','(all selected)'));
} else if (count > 0) {
$(dialog_id).find('.allnewfiles').prop('checked', false);
- $(dialog_id).find('.allnewfiles + .count').text(t('files','({count} selected)',{count:count}));
+ $(dialog_id).find('.allnewfiles + .count').text(t('core','({count} selected)',{count:count}));
} else {
$(dialog_id).find('.allnewfiles').prop('checked', false);
$(dialog_id).find('.allnewfiles + .count').text('');
@@ -443,10 +451,10 @@ var OCdialogs = {
var count = $(dialog_id).find('.conflict .original input[type="checkbox"]:checked').length;
if (count === $(dialog_id+ ' .conflict').length) {
$(dialog_id).find('.allexistingfiles').prop('checked', true);
- $(dialog_id).find('.allexistingfiles + .count').text(t('files','(all selected)'));
+ $(dialog_id).find('.allexistingfiles + .count').text(t('core','(all selected)'));
} else if (count > 0) {
$(dialog_id).find('.allexistingfiles').prop('checked', false);
- $(dialog_id).find('.allexistingfiles + .count').text(t('files','({count} selected)',{count:count}));
+ $(dialog_id).find('.allexistingfiles + .count').text(t('core','({count} selected)',{count:count}));
} else {
$(dialog_id).find('.allexistingfiles').prop('checked', false);
$(dialog_id).find('.allexistingfiles + .count').text('');
@@ -514,7 +522,7 @@ var OCdialogs = {
}
return $.getJSON(
- OC.filePath('files', 'ajax', 'rawlist.php'),
+ OC.filePath('files', 'ajax', 'list.php'),
{
dir: dir,
mimetypes: JSON.stringify(mimeType)
@@ -539,7 +547,7 @@ var OCdialogs = {
this.$filelist.empty().addClass('loading');
this.$filePicker.data('path', dir);
$.when(this._getFileList(dir, this.$filePicker.data('mimetype'))).then(function(response) {
- $.each(response.data, function(index, file) {
+ $.each(response.data.files, function(index, file) {
if (file.type === 'dir') {
dirs.push(file);
} else {
@@ -555,13 +563,25 @@ var OCdialogs = {
type: entry.type,
dir: dir,
filename: entry.name,
- date: OC.mtime2date(entry.mtime)
+ date: OC.mtime2date(Math.floor(entry.mtime / 1000))
});
- $li.find('img').attr('src', entry.mimetype_icon);
+ if (entry.isPreviewAvailable) {
+ var urlSpec = {
+ file: dir + '/' + entry.name
+ };
+ var previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
+ $li.find('img').attr('src', previewUrl);
+ }
+ else {
+ $li.find('img').attr('src', OC.Util.replaceSVGIcon(entry.icon));
+ }
self.$filelist.append($li);
});
self.$filelist.removeClass('loading');
+ if (!OC.Util.hasSVGSupport()) {
+ OC.Util.replaceSVG(self.$filePicker.find('.dirtree'));
+ }
});
},
/**
diff --git a/core/js/share.js b/core/js/share.js
index e769edd0a21..ef71cc7999a 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -551,7 +551,7 @@ $(document).ready(function() {
var itemType = $('#dropdown').data('item-type');
var itemSource = $('#dropdown').data('item-source');
var shareType = $li.data('share-type');
- var shareWith = $li.data('share-with');
+ var shareWith = $li.attr('data-share-with');
OC.Share.unshare(itemType, itemSource, shareType, shareWith, function() {
$li.remove();
var index = OC.Share.itemShares[shareType].indexOf(shareWith);
@@ -597,7 +597,7 @@ $(document).ready(function() {
OC.Share.setPermissions($('#dropdown').data('item-type'),
$('#dropdown').data('item-source'),
li.data('share-type'),
- li.data('share-with'),
+ li.attr('data-share-with'),
permissions);
});
@@ -782,7 +782,7 @@ $(document).ready(function() {
}
var shareType = $li.data('share-type');
- var shareWith = $li.data('share-with');
+ var shareWith = $li.attr('data-share-with');
$.post(OC.filePath('core', 'ajax', 'share.php'), {action: action, recipient: shareWith, shareType: shareType, itemSource: itemSource, itemType: itemType}, function(result) {
if (result.status !== 'success') {
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 57ea5be8be0..89056807788 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -268,7 +268,72 @@ describe('Core base tests', function() {
// still nothing
expect(counter).toEqual(0);
});
-
+ });
+ describe('Parse query string', function() {
+ it('Parses query string from full URL', function() {
+ var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x');
+ expect(query).toEqual({q: 'a', b: 'x'});
+ });
+ it('Parses query string from query part alone', function() {
+ var query = OC.parseQueryString('q=a&b=x');
+ expect(query).toEqual({q: 'a', b: 'x'});
+ });
+ it('Returns null hash when empty query', function() {
+ var query = OC.parseQueryString('');
+ expect(query).toEqual(null);
+ });
+ it('Returns empty hash when empty query with question mark', function() {
+ var query = OC.parseQueryString('?');
+ expect(query).toEqual({});
+ });
+ it('Decodes regular query strings', function() {
+ var query = OC.parseQueryString('a=abc&b=def');
+ expect(query).toEqual({
+ a: 'abc',
+ b: 'def'
+ });
+ });
+ it('Ignores empty parts', function() {
+ var query = OC.parseQueryString('&q=a&&b=x&');
+ expect(query).toEqual({q: 'a', b: 'x'});
+ });
+ it('Ignores lone equal signs', function() {
+ var query = OC.parseQueryString('&q=a&=&b=x&');
+ expect(query).toEqual({q: 'a', b: 'x'});
+ });
+ it('Includes extra equal signs in value', function() {
+ var query = OC.parseQueryString('u=a=x&q=a=b');
+ expect(query).toEqual({u: 'a=x', q: 'a=b'});
+ });
+ it('Decodes plus as space', function() {
+ var query = OC.parseQueryString('space+key=space+value');
+ expect(query).toEqual({'space key': 'space value'});
+ });
+ it('Decodes special characters', function() {
+ var query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97');
+ expect(query).toEqual({unicode: '汉字'});
+ query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand');
+ expect(query).toEqual({
+ b: 'spaace value',
+ 'space key': 'normalvalue',
+ 'slash/this': 'amp&ersand'
+ });
+ });
+ it('Decodes empty values', function() {
+ var query = OC.parseQueryString('keywithemptystring=&keywithnostring');
+ expect(query).toEqual({
+ 'keywithemptystring': '',
+ 'keywithnostring': null
+ });
+ });
+ it('Does not interpret data types', function() {
+ var query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123');
+ expect(query).toEqual({
+ 'booleanfalse': 'false',
+ 'booleantrue': 'true',
+ 'number': '123'
+ });
+ });
});
describe('Generate Url', function() {
it('returns absolute urls', function() {
@@ -383,5 +448,31 @@ describe('Core base tests', function() {
expect($navigation.is(':visible')).toEqual(true);
});
});
+ describe('SVG extension replacement', function() {
+ var svgSupportStub;
+
+ beforeEach(function() {
+ svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport');
+ });
+ afterEach(function() {
+ svgSupportStub.restore();
+ });
+ it('does not replace svg extension with png when SVG is supported', function() {
+ svgSupportStub.returns(true);
+ expect(
+ OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1')
+ ).toEqual(
+ '/path/to/myicon.svg?someargs=1'
+ );
+ });
+ it('replaces svg extension with png when SVG not supported', function() {
+ svgSupportStub.returns(false);
+ expect(
+ OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1')
+ ).toEqual(
+ '/path/to/myicon.png?someargs=1'
+ );
+ });
+ });
});
diff --git a/core/js/underscore.js b/core/js/underscore.js
new file mode 100644
index 00000000000..ca61fdc3a4b
--- /dev/null
+++ b/core/js/underscore.js
@@ -0,0 +1,1344 @@
+// Underscore.js 1.6.0
+// http://underscorejs.org
+// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.6.0';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return obj;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, length = obj.length; i < length; i++) {
+ if (iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
+ }
+ }
+ return obj;
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = _.collect = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results.push(iterator.call(context, value, index, list));
+ });
+ return results;
+ };
+
+ var reduceError = 'Reduce of empty array with no initial value';
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError(reduceError);
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var length = obj.length;
+ if (length !== +length) {
+ var keys = _.keys(obj);
+ length = keys.length;
+ }
+ each(obj, function(value, index, list) {
+ index = keys ? keys[--length] : --length;
+ if (!initial) {
+ memo = obj[index];
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, obj[index], index, list);
+ }
+ });
+ if (!initial) throw new TypeError(reduceError);
+ return memo;
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, predicate, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (predicate.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, predicate, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
+ each(obj, function(value, index, list) {
+ if (predicate.call(context, value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, predicate, context) {
+ return _.filter(obj, function(value, index, list) {
+ return !predicate.call(context, value, index, list);
+ }, context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && predicate.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
+ each(obj, function(value, index, list) {
+ if (result || (result = predicate.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if the array or object contains a given value (using `===`).
+ // Aliased as `include`.
+ _.contains = _.include = function(obj, target) {
+ if (obj == null) return false;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ return any(obj, function(value) {
+ return value === target;
+ });
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ return (isFunc ? method : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, _.property(key));
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matches(attrs));
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.find(obj, _.matches(attrs));
+ };
+
+ // Return the maximum element or (element-based computation).
+ // Can't optimize arrays of integers longer than 65,535 elements.
+ // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.max.apply(Math, obj);
+ }
+ var result = -Infinity, lastComputed = -Infinity;
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ if (computed > lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ return result;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.min.apply(Math, obj);
+ }
+ var result = Infinity, lastComputed = Infinity;
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ if (computed < lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ return result;
+ };
+
+ // Shuffle an array, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+ _.shuffle = function(obj) {
+ var rand;
+ var index = 0;
+ var shuffled = [];
+ each(obj, function(value) {
+ rand = _.random(index++);
+ shuffled[index - 1] = shuffled[rand];
+ shuffled[rand] = value;
+ });
+ return shuffled;
+ };
+
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
+ // An internal function to generate lookup iterators.
+ var lookupIterator = function(value) {
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return value;
+ return _.property(value);
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, iterator, context) {
+ iterator = lookupIterator(iterator);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value: value,
+ index: index,
+ criteria: iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index - right.index;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(behavior) {
+ return function(obj, iterator, context) {
+ var result = {};
+ iterator = lookupIterator(iterator);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = group(function(result, key, value) {
+ _.has(result, key) ? result[key].push(value) : result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, key, value) {
+ result[key] = value;
+ });
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = group(function(result, key) {
+ _.has(result, key) ? result[key]++ : result[key] = 1;
+ });
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator, context) {
+ iterator = lookupIterator(iterator);
+ var value = iterator.call(context, obj);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >>> 1;
+ iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (obj.length === +obj.length) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ if ((n == null) || guard) return array[0];
+ if (n < 0) return [];
+ return slice.call(array, 0, n);
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if ((n == null) || guard) return array[array.length - 1];
+ return slice.call(array, Math.max(array.length - n, 0));
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, (n == null) || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
+ each(input, function(value) {
+ if (_.isArray(value) || _.isArguments(value)) {
+ shallow ? push.apply(output, value) : flatten(value, shallow, output);
+ } else {
+ output.push(value);
+ }
+ });
+ return output;
+ };
+
+ // Flatten out an array, either recursively (by default), or just one level.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Split an array into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(array, predicate, context) {
+ predicate = lookupIterator(predicate);
+ var pass = [], fail = [];
+ each(array, function(elem) {
+ (predicate.call(context, elem) ? pass : fail).push(elem);
+ });
+ return [pass, fail];
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iterator, context) {
+ if (_.isFunction(isSorted)) {
+ context = iterator;
+ iterator = isSorted;
+ isSorted = false;
+ }
+ var initial = iterator ? _.map(array, iterator, context) : array;
+ var results = [];
+ var seen = [];
+ each(initial, function(value, index) {
+ if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
+ seen.push(value);
+ results.push(array[index]);
+ }
+ });
+ return results;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.contains(other, item);
+ });
+ });
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.contains(rest, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var length = _.max(_.pluck(arguments, 'length').concat(0));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) {
+ results[i] = _.pluck(arguments, '' + i);
+ }
+ return results;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ if (list == null) return {};
+ var result = {};
+ for (var i = 0, length = list.length; i < length; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i = 0, length = array.length;
+ if (isSorted) {
+ if (typeof isSorted == 'number') {
+ i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
+ } else {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
+ for (; i < length; i++) if (array[i] === item) return i;
+ return -1;
+ };
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item, from) {
+ if (array == null) return -1;
+ var hasIndex = from != null;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
+ return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
+ }
+ var i = (hasIndex ? from : array.length);
+ while (i--) if (array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(length);
+
+ while(idx < length) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
+ };
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
+ _.partial = function(func) {
+ var boundArgs = slice.call(arguments, 1);
+ return function() {
+ var position = 0;
+ var args = boundArgs.slice();
+ for (var i = 0, length = args.length; i < length; i++) {
+ if (args[i] === _) args[i] = arguments[position++];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return func.apply(this, args);
+ };
+ };
+
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length === 0) throw new Error('bindAll must be passed function names');
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(null, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ options || (options = {});
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+ if (last < wait) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) {
+ timeout = setTimeout(later, wait);
+ }
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
+ return result;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ memo = func.apply(this, arguments);
+ func = null;
+ return memo;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return _.partial(wrapper, func);
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = arguments;
+ return function() {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = new Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
+ return values;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = new Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ }
+ });
+ return obj;
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ each(keys, function(key) {
+ if (key in obj) copy[key] = obj[key];
+ });
+ return copy;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ for (var key in obj) {
+ if (!_.contains(keys, key)) copy[key] = obj[key];
+ }
+ return copy;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ if (source) {
+ for (var prop in source) {
+ if (obj[prop] === void 0) obj[prop] = source[prop];
+ }
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] == a) return bStack[length] == b;
+ }
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))
+ && ('constructor' in a && 'constructor' in b)) {
+ return false;
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack))) break;
+ }
+ }
+ } else {
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return result;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, [], []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) == '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
+ each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) == '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Optimize `isFunction` if appropriate.
+ if (typeof (/./) !== 'function') {
+ _.isFunction = function(obj) {
+ return typeof obj === 'function';
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj != +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ _.constant = function(value) {
+ return function () {
+ return value;
+ };
+ };
+
+ _.property = function(key) {
+ return function(obj) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+ _.matches = function(attrs) {
+ return function(obj) {
+ if (obj === attrs) return true; //avoid comparing an object to itself.
+ for (var key in attrs) {
+ if (attrs[key] !== obj[key])
+ return false;
+ }
+ return true;
+ }
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iterator, context) {
+ var accum = Array(Math.max(0, n));
+ for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() { return new Date().getTime(); };
+
+ // List of HTML entities for escaping.
+ var entityMap = {
+ escape: {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;'
+ }
+ };
+ entityMap.unescape = _.invert(entityMap.escape);
+
+ // Regexes containing the keys and values listed immediately above.
+ var entityRegexes = {
+ escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
+ unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
+ };
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ _.each(['escape', 'unescape'], function(method) {
+ _[method] = function(string) {
+ if (string == null) return '';
+ return ('' + string).replace(entityRegexes[method], function(match) {
+ return entityMap[method][match];
+ });
+ };
+ });
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property) {
+ if (object == null) return void 0;
+ var value = object[property];
+ return _.isFunction(value) ? value.call(object) : value;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name) {
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result.call(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\t': 't',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(text, data, settings) {
+ var render;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = new RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset)
+ .replace(escaper, function(match) { return '\\' + escapes[match]; });
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ }
+ if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ }
+ if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+ index = offset + match.length;
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + "return __p;\n";
+
+ try {
+ render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ if (data) return render(data, _);
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled function source as a convenience for precompilation.
+ template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
+ return result.call(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ _.extend(_.prototype, {
+
+ // Start chaining a wrapped Underscore object.
+ chain: function() {
+ this._chain = true;
+ return this;
+ },
+
+ // Extracts the result from a wrapped and chained object.
+ value: function() {
+ return this._wrapped;
+ }
+
+ });
+
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
+}).call(this);
diff --git a/core/l10n/ast.php b/core/l10n/ast.php
new file mode 100644
index 00000000000..9ae1685347c
--- /dev/null
+++ b/core/l10n/ast.php
@@ -0,0 +1,74 @@
+<?php
+$TRANSLATIONS = array(
+"Updated database" => "Base de datos anovada",
+"Sunday" => "Domingu",
+"Monday" => "Llunes",
+"Tuesday" => "Martes",
+"Wednesday" => "Miércoles",
+"Thursday" => "Xueves",
+"Friday" => "Vienres",
+"Saturday" => "Sábadu",
+"January" => "Xineru",
+"February" => "Febreru",
+"March" => "Marzu",
+"April" => "Abril",
+"May" => "Mayu",
+"June" => "Xunu",
+"July" => "Xunetu",
+"August" => "Agostu",
+"September" => "Setiembre",
+"October" => "Ochobre",
+"November" => "Payares",
+"December" => "Avientu",
+"Settings" => "Axustes",
+"seconds ago" => "fai segundos",
+"_%n minute ago_::_%n minutes ago_" => array("fai %n minutu","fai %n minutos"),
+"_%n hour ago_::_%n hours ago_" => array("fai %n hora","fai %n hores"),
+"today" => "güei",
+"yesterday" => "ayeri",
+"_%n day ago_::_%n days ago_" => array("fai %n día","fai %n díes"),
+"last month" => "mes caberu",
+"_%n month ago_::_%n months ago_" => array("fai %n mes","fai %n meses"),
+"months ago" => "fai meses",
+"last year" => "añu caberu",
+"years ago" => "fai años",
+"Choose" => "Esbillar",
+"Yes" => "Sí",
+"No" => "Non",
+"_{count} file conflict_::_{count} file conflicts_" => array("",""),
+"Which files do you want to keep?" => "¿Qué ficheros quies caltener?",
+"Cancel" => "Encaboxar",
+"Continue" => "Continuar",
+"Shared" => "Compartíu",
+"Share" => "Compartir",
+"Share link" => "Compartir enllaz",
+"Password" => "Contraseña",
+"Send" => "Unviar",
+"group" => "grupu",
+"Unshare" => "Dexar de compartir",
+"notify by email" => "notificar per corréu",
+"can edit" => "pue editar",
+"access control" => "control d'accesu",
+"create" => "crear",
+"update" => "xubir",
+"delete" => "desaniciar",
+"share" => "compartir",
+"Password protected" => "Contraseña protexida",
+"Email sent" => "Corréu unviáu",
+"Delete" => "Desaniciar",
+"Add" => "Amestar",
+"Edit tags" => "Editar etiquetes",
+"Username" => "Nome d'usuariu",
+"Reset" => "Reaniciar",
+"For the best results, please consider using a GNU/Linux server instead." => "Pa los meyores resultaos, por favor considera l'usu d'un sirvidor GNU/Linux nel so llugar.",
+"Personal" => "Personal",
+"Cheers!" => "¡Salú!",
+"will be used" => "usaráse",
+"Finishing …" => "Finando ...",
+"Log out" => "Zarrar sesión",
+"Lost your password?" => "¿Escaeciesti la to contraseña?",
+"Log in" => "Aniciar sesión",
+"Alternative Logins" => "Anicios de sesión alternativos",
+"Thank you for your patience." => "Gracies pola to paciencia."
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/core/l10n/ca.php b/core/l10n/ca.php
index 0a658d515d9..214b2eac0e9 100644
--- a/core/l10n/ca.php
+++ b/core/l10n/ca.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Error en carregar la plantilla de missatge: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicte de fitxer","{count} conflictes de fitxer"),
"One file conflict" => "Un fitxer en conflicte",
+"New Files" => "Fitxers nous",
"Which files do you want to keep?" => "Quin fitxer voleu conservar?",
"If you select both versions, the copied file will have a number added to its name." => "Si seleccioneu les dues versions, el fitxer copiat tindrà un número afegit al seu nom.",
"Cancel" => "Cancel·la",
diff --git a/core/l10n/cs_CZ.php b/core/l10n/cs_CZ.php
index ffe34f78280..c21d904b233 100644
--- a/core/l10n/cs_CZ.php
+++ b/core/l10n/cs_CZ.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Chyba při nahrávání šablony zprávy: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} souborový konflikt","{count} souborové konflikty","{count} souborových konfliktů"),
"One file conflict" => "Jeden konflikt souboru",
+"New Files" => "Nové soubory",
"Which files do you want to keep?" => "Které soubory chcete ponechat?",
"If you select both versions, the copied file will have a number added to its name." => "Pokud zvolíte obě verze, zkopírovaný soubor bude mít název doplněný o číslo.",
"Cancel" => "Zrušit",
diff --git a/core/l10n/da.php b/core/l10n/da.php
index d3384dac432..c7bda6fd365 100644
--- a/core/l10n/da.php
+++ b/core/l10n/da.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Fejl ved indlæsning af besked skabelon: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} filkonflikt","{count} filkonflikter"),
"One file conflict" => "En filkonflikt",
+"New Files" => "Nye filer",
"Which files do you want to keep?" => "Hvilke filer ønsker du at beholde?",
"If you select both versions, the copied file will have a number added to its name." => "Hvis du vælger begge versioner, vil den kopierede fil få tilføjet et nummer til sit navn.",
"Cancel" => "Annuller",
diff --git a/core/l10n/de.php b/core/l10n/de.php
index 79edfb725d7..4d8c583e164 100644
--- a/core/l10n/de.php
+++ b/core/l10n/de.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Fehler beim Laden der Nachrichtenvorlage: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} Dateikonflikt","{count} Dateikonflikte"),
"One file conflict" => "Ein Dateikonflikt",
+"New Files" => "Neue Dateien",
"Which files do you want to keep?" => "Welche Dateien möchtest Du behalten?",
"If you select both versions, the copied file will have a number added to its name." => "Wenn Du beide Versionen auswählst, erhält die kopierte Datei eine Zahl am Ende des Dateinamens.",
"Cancel" => "Abbrechen",
diff --git a/core/l10n/de_CH.php b/core/l10n/de_CH.php
index 42b8eb3bcea..eb2cfd233d3 100644
--- a/core/l10n/de_CH.php
+++ b/core/l10n/de_CH.php
@@ -40,6 +40,7 @@ $TRANSLATIONS = array(
"No" => "Nein",
"Ok" => "OK",
"_{count} file conflict_::_{count} file conflicts_" => array("",""),
+"New Files" => "Neue Dateien",
"Cancel" => "Abbrechen",
"Shared" => "Geteilt",
"Share" => "Teilen",
diff --git a/core/l10n/de_DE.php b/core/l10n/de_DE.php
index a0877e792e2..900d3c03172 100644
--- a/core/l10n/de_DE.php
+++ b/core/l10n/de_DE.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Fehler beim Laden der Nachrichtenvorlage: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} Dateikonflikt","{count} Dateikonflikte"),
"One file conflict" => "Ein Dateikonflikt",
+"New Files" => "Neue Dateien",
"Which files do you want to keep?" => "Welche Dateien möchten Sie behalten?",
"If you select both versions, the copied file will have a number added to its name." => "Wenn Sie beide Versionen auswählen, erhält die kopierte Datei eine Zahl am Ende des Dateinamens.",
"Cancel" => "Abbrechen",
diff --git a/core/l10n/el.php b/core/l10n/el.php
index ed7792b7261..c899427ae30 100644
--- a/core/l10n/el.php
+++ b/core/l10n/el.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => "Η ημερομηνία λήξης είναι στο παρελθόν.",
"Couldn't send mail to following users: %s " => "Αδυναμία αποστολής μηνύματος στους ακόλουθους χρήστες: %s",
"Turned on maintenance mode" => "Η κατάσταση συντήρησης ενεργοποιήθηκε",
"Turned off maintenance mode" => "Η κατάσταση συντήρησης απενεργοποιήθηκε",
@@ -49,14 +50,17 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Σφάλμα φόρτωσης προτύπου μηνυμάτων: {σφάλμα}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} αρχείο διαφέρει","{count} αρχεία διαφέρουν"),
"One file conflict" => "Ένα αρχείο διαφέρει",
+"New Files" => "Νέα Αρχεία",
"Which files do you want to keep?" => "Ποια αρχεία θέλετε να κρατήσετε;",
"If you select both versions, the copied file will have a number added to its name." => "Εάν επιλέξετε και τις δυο εκδοχές, ένας αριθμός θα προστεθεί στο αντιγραφόμενο αρχείο.",
"Cancel" => "Άκυρο",
"Continue" => "Συνέχεια",
"(all selected)" => "(όλα τα επιλεγμένα)",
"({count} selected)" => "({count} επιλέχθησαν)",
+"Error loading file exists template" => "Σφάλμα κατά την φόρτωση του προτύπου ύπαρξης αρχείου",
"Very weak password" => "Πολύ αδύναμο συνθηματικό",
"Weak password" => "Αδύναμο συνθηματικό",
+"So-so password" => "Μέτριο συνθηματικό",
"Good password" => "Καλό συνθηματικό",
"Strong password" => "Δυνατό συνθηματικό",
"Shared" => "Κοινόχρηστα",
@@ -119,6 +123,8 @@ $TRANSLATIONS = array(
"To login page" => "Σελίδα εισόδου",
"New password" => "Νέο συνθηματικό",
"Reset password" => "Επαναφορά συνθηματικού",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Το Mac OS X δεν υποστηρίζεται και το %s δεν θα λειτουργήσει σωστά σε αυτή την πλατφόρμα. Χρησιμοποιείτε με δική σας ευθύνη!",
+"For the best results, please consider using a GNU/Linux server instead." => "Για καλύτερα αποτελέσματα, παρακαλούμε εξετάστε την μετατροπή σε έναν διακομιστή GNU/Linux.",
"Personal" => "Προσωπικά",
"Users" => "Χρήστες",
"Apps" => "Εφαρμογές",
@@ -144,6 +150,7 @@ $TRANSLATIONS = array(
"Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Ο κατάλογος δεδομένων και τα αρχεία σας είναι πιθανό προσβάσιμα από το internet γιατί δεν δουλεύει το αρχείο .htaccess.",
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Για πληροφορίες πως να ρυθμίσετε ορθά τον διακομιστή σας, παρακαλώ δείτε την <a href=\"%s\" target=\"_blank\">τεκμηρίωση</a>.",
"Create an <strong>admin account</strong>" => "Δημιουργήστε έναν <strong>λογαριασμό διαχειριστή</strong>",
+"Storage & database" => "Αποθήκευση & βάση δεδομένων",
"Data folder" => "Φάκελος δεδομένων",
"Configure the database" => "Ρύθμιση της βάσης δεδομένων",
"will be used" => "θα χρησιμοποιηθούν",
@@ -166,6 +173,7 @@ $TRANSLATIONS = array(
"remember" => "απομνημόνευση",
"Log in" => "Είσοδος",
"Alternative Logins" => "Εναλλακτικές Συνδέσεις",
+"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Γειά χαρά,<br><br>απλά σας ενημερώνω πως ο %s μοιράστηκε το<strong>%s</strong> με εσάς.<br><a href=\"%s\">Δείτε το!</a><br><br>",
"This ownCloud instance is currently in single user mode." => "Αυτή η εγκατάσταση ownCloud είναι τώρα σε κατάσταση ενός χρήστη.",
"This means only administrators can use the instance." => "Αυτό σημαίνει ότι μόνο διαχειριστές μπορούν να χρησιμοποιήσουν την εγκατάσταση.",
"Contact your system administrator if this message persists or appeared unexpectedly." => "Επικοινωνήστε με το διαχειριστή του συστήματος αν αυτό το μήνυμα συνεχίζει να εμφανίζεται ή εμφανίστηκε απρόσμενα.",
diff --git a/core/l10n/en_GB.php b/core/l10n/en_GB.php
index bc36f5a4446..215bae92d1c 100644
--- a/core/l10n/en_GB.php
+++ b/core/l10n/en_GB.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Error loading message template: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} file conflict","{count} file conflicts"),
"One file conflict" => "One file conflict",
+"New Files" => "New Files",
+"Already existing files" => "Already existing files",
"Which files do you want to keep?" => "Which files do you wish to keep?",
"If you select both versions, the copied file will have a number added to its name." => "If you select both versions, the copied file will have a number added to its name.",
"Cancel" => "Cancel",
diff --git a/core/l10n/eo.php b/core/l10n/eo.php
index f264b7ed7a7..05d28efb66b 100644
--- a/core/l10n/eo.php
+++ b/core/l10n/eo.php
@@ -41,6 +41,7 @@ $TRANSLATIONS = array(
"Ok" => "Akcepti",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} dosierkonflikto","{count} dosierkonfliktoj"),
"One file conflict" => "Unu dosierkonflikto",
+"New Files" => "Novaj dosieroj",
"Which files do you want to keep?" => "Kiujn dosierojn vi volas konservi?",
"If you select both versions, the copied file will have a number added to its name." => "Se vi elektos ambaŭ eldonojn, la kopiota dosiero havos numeron aldonitan al sia nomo.",
"Cancel" => "Nuligi",
diff --git a/core/l10n/es.php b/core/l10n/es.php
index 52f1a15089a..cb2d09d60fe 100644
--- a/core/l10n/es.php
+++ b/core/l10n/es.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Error cargando plantilla del mensaje: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicto de archivo","{count} conflictos de archivo"),
"One file conflict" => "On conflicto de archivo",
+"New Files" => "Nuevos Archivos",
+"Already existing files" => "Archivos ya existentes",
"Which files do you want to keep?" => "¿Que archivos deseas mantener?",
"If you select both versions, the copied file will have a number added to its name." => "Si seleccionas ambas versiones, el archivo copiado tendrá añadido un número en su nombre.",
"Cancel" => "Cancelar",
diff --git a/core/l10n/es_AR.php b/core/l10n/es_AR.php
index b5b37d4825b..c9d270edefa 100644
--- a/core/l10n/es_AR.php
+++ b/core/l10n/es_AR.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Error cargando la plantilla del mensaje: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("un archivo en conflicto","{count} archivos en conflicto"),
"One file conflict" => "Un archivo en conflicto",
+"New Files" => "Nuevos archivos",
"Which files do you want to keep?" => "¿Qué archivos deseas retener?",
"If you select both versions, the copied file will have a number added to its name." => "Si tu seleccionas ambas versiones, el archivo copiado tendrá un número agregado a su nombre.",
"Cancel" => "Cancelar",
diff --git a/core/l10n/et_EE.php b/core/l10n/et_EE.php
index 5a2e34ff3a0..422caac9c15 100644
--- a/core/l10n/et_EE.php
+++ b/core/l10n/et_EE.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => "Aegumise kuupäev on minevikus.",
"Couldn't send mail to following users: %s " => "Kirja saatmine järgnevatele kasutajatele ebaõnnestus: %s ",
"Turned on maintenance mode" => "Haldusrežiimis sisse lülitatud",
"Turned off maintenance mode" => "Haldusrežiimis välja lülitatud",
@@ -49,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Viga sõnumi malli laadimisel: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} failikonflikt","{count} failikonflikti"),
"One file conflict" => "Üks failikonflikt",
+"New Files" => "Uued failid",
"Which files do you want to keep?" => "Milliseid faile sa soovid alles hoida?",
"If you select both versions, the copied file will have a number added to its name." => "Kui valid mõlemad versioonid, siis lisatakse kopeeritud faili nimele number.",
"Cancel" => "Loobu",
@@ -56,6 +58,11 @@ $TRANSLATIONS = array(
"(all selected)" => "(kõik valitud)",
"({count} selected)" => "({count} valitud)",
"Error loading file exists template" => "Viga faili olemasolu malli laadimisel",
+"Very weak password" => "Väga nõrk parool",
+"Weak password" => "Nõrk parool",
+"So-so password" => "Enam-vähem sobiv parool",
+"Good password" => "Hea parool",
+"Strong password" => "Väga hea parool",
"Shared" => "Jagatud",
"Share" => "Jaga",
"Error" => "Viga",
@@ -103,6 +110,7 @@ $TRANSLATIONS = array(
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Uuendus ebaõnnestus. Palun teavita probleemidest <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud kogukonda</a>.",
"The update was successful. Redirecting you to ownCloud now." => "Uuendus oli edukas. Kohe suunatakse Sind ownCloudi.",
"%s password reset" => "%s parooli lähtestus",
+"A problem has occurred whilst sending the email, please contact your administrator." => "Tekkis tõrge e-posti saatmisel, palun kontakteeru administraatoriga.",
"Use the following link to reset your password: {link}" => "Kasuta järgnevat linki oma parooli taastamiseks: {link}",
"The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Link parooli vahetuseks on saadetud Sinu e-posti aadressile.<br>Kui kiri pole saabunud mõistliku aja jooksul, siis kontrolli oma spam-/rämpskirjade katalooge.<br>Kui kirja pole ka seal, siis küsi abi süsteemihaldurilt.",
"Request failed!<br>Did you make sure your email/username was right?" => "Päring ebaõnnestus!<br>Oled sa veendunud, et e-post/kasutajanimi on õiged?",
@@ -115,6 +123,8 @@ $TRANSLATIONS = array(
"To login page" => "Sisselogimise lehele",
"New password" => "Uus parool",
"Reset password" => "Nulli parool",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X ei ole toetatud ja %s ei pruugi korralikult toimida sellel platvormil. Kasuta seda omal vastutusel!",
+"For the best results, please consider using a GNU/Linux server instead." => "Parema tulemuse saavitamiseks palun kaalu serveris GNU/Linux kasutamist.",
"Personal" => "Isiklik",
"Users" => "Kasutajad",
"Apps" => "Rakendused",
@@ -140,6 +150,7 @@ $TRANSLATIONS = array(
"Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Su andmete kataloog ja failid on tõenäoliselt internetist vabalt saadaval kuna .htaccess fail ei toimi.",
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Serveri korrektseks seadistuseks palun tutvu <a href=\"%s\" target=\"_blank\">dokumentatsiooniga</a>.",
"Create an <strong>admin account</strong>" => "Loo <strong>admini konto</strong>",
+"Storage & database" => "Andmehoidla ja andmebaas",
"Data folder" => "Andmete kaust",
"Configure the database" => "Seadista andmebaasi",
"will be used" => "kasutatakse",
@@ -162,6 +173,7 @@ $TRANSLATIONS = array(
"remember" => "pea meeles",
"Log in" => "Logi sisse",
"Alternative Logins" => "Alternatiivsed sisselogimisviisid",
+"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Hei,<br><br>annan teada, et %s jagas sinuga <strong>%s</strong>. <a href=\"%s\">Vaata seda!</a><br><br>",
"This ownCloud instance is currently in single user mode." => "See ownCloud on momendil seadistatud ühe kasutaja jaoks.",
"This means only administrators can use the instance." => "See tähendab, et seda saavad kasutada ainult administraatorid.",
"Contact your system administrator if this message persists or appeared unexpectedly." => "Kontakteeru oma süsteemihalduriga, kui see teade püsib või on tekkinud ootamatult.",
diff --git a/core/l10n/eu.php b/core/l10n/eu.php
index 33c98fb9b90..8fd554485db 100644
--- a/core/l10n/eu.php
+++ b/core/l10n/eu.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Errorea mezu txantiloia kargatzean: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("fitxategi {count}ek konfliktua sortu du","{count} fitxategik konfliktua sortu dute"),
"One file conflict" => "Fitxategi batek konfliktua sortu du",
+"New Files" => "Fitxategi Berriak",
"Which files do you want to keep?" => "Ze fitxategi mantendu nahi duzu?",
"If you select both versions, the copied file will have a number added to its name." => "Bi bertsioak hautatzen badituzu, kopiatutako fitxategiaren izenean zenbaki bat atxikituko zaio.",
"Cancel" => "Ezeztatu",
diff --git a/core/l10n/fa.php b/core/l10n/fa.php
index 3e7e246e827..a349d3b7704 100644
--- a/core/l10n/fa.php
+++ b/core/l10n/fa.php
@@ -37,6 +37,7 @@ $TRANSLATIONS = array(
"No" => "نه",
"Ok" => "قبول",
"_{count} file conflict_::_{count} file conflicts_" => array(""),
+"New Files" => "فایل های جدید",
"Cancel" => "منصرف شدن",
"Shared" => "اشتراک گذاشته شده",
"Share" => "اشتراک‌گذاری",
diff --git a/core/l10n/fi_FI.php b/core/l10n/fi_FI.php
index 0af7503ee9d..7797d17c872 100644
--- a/core/l10n/fi_FI.php
+++ b/core/l10n/fi_FI.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Virhe ladatessa viestipohjaa: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} tiedoston ristiriita","{count} tiedoston ristiriita"),
"One file conflict" => "Yhden tiedoston ristiriita",
+"New Files" => "Uudet tiedostot",
+"Already existing files" => "Jo olemassa olevat tiedostot",
"Which files do you want to keep?" => "Mitkä tiedostot haluat säilyttää?",
"If you select both versions, the copied file will have a number added to its name." => "Jos valitset kummatkin versiot, kopioidun tiedoston nimeen lisätään numero.",
"Cancel" => "Peru",
@@ -122,6 +124,8 @@ $TRANSLATIONS = array(
"To login page" => "Kirjautumissivulle",
"New password" => "Uusi salasana",
"Reset password" => "Palauta salasana",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X ei ole tuettu, joten %s ei toimi kunnolla tällä alustalla. Käytä omalla vastuulla!",
+"For the best results, please consider using a GNU/Linux server instead." => "Käytä parhaan lopputuloksen saamiseksi GNU/Linux-palvelinta.",
"Personal" => "Henkilökohtainen",
"Users" => "Käyttäjät",
"Apps" => "Sovellukset",
diff --git a/core/l10n/fr.php b/core/l10n/fr.php
index 3754e8c9e07..2475eddee8a 100644
--- a/core/l10n/fr.php
+++ b/core/l10n/fr.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => "La date d'expiration est dans le passé.",
"Couldn't send mail to following users: %s " => "Impossible d'envoyer un mail aux utilisateurs suivant : %s",
"Turned on maintenance mode" => "Basculé en mode maintenance",
"Turned off maintenance mode" => "Basculé en mode production (non maintenance)",
@@ -49,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Erreur de chargement du modèle de message : {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} fichier en conflit","{count} fichiers en conflit"),
"One file conflict" => "Un conflit de fichier",
+"New Files" => "Nouveaux fichiers",
"Which files do you want to keep?" => "Quels fichiers désirez-vous garder ?",
"If you select both versions, the copied file will have a number added to its name." => "Si vous sélectionnez les deux versions, un nombre sera ajouté au nom du fichier copié.",
"Cancel" => "Annuler",
@@ -121,6 +123,8 @@ $TRANSLATIONS = array(
"To login page" => "Retour à la page d'authentification",
"New password" => "Nouveau mot de passe",
"Reset password" => "Réinitialiser le mot de passe",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X n'est pas supporté et %s ne fonctionnera pas correctement sur cette plateforme. Son utilisation est à vos risques et périls !",
+"For the best results, please consider using a GNU/Linux server instead." => "Pour des résultats meilleurs encore, pensez à utiliser un serveur GNU/Linux à la place.",
"Personal" => "Personnel",
"Users" => "Utilisateurs",
"Apps" => "Applications",
diff --git a/core/l10n/gl.php b/core/l10n/gl.php
index c1c678e7e3f..eb9f1af5657 100644
--- a/core/l10n/gl.php
+++ b/core/l10n/gl.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Produciuse un erro ao cargar o modelo da mensaxe: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} conflito de ficheiro","{count} conflitos de ficheiros"),
"One file conflict" => "Un conflito de ficheiro",
+"New Files" => "Ficheiros novos",
+"Already existing files" => "Ficheiros xa existentes",
"Which files do you want to keep?" => "Que ficheiros quere conservar?",
"If you select both versions, the copied file will have a number added to its name." => "Se selecciona ambas versións, o ficheiro copiado terá un número engadido ao nome.",
"Cancel" => "Cancelar",
diff --git a/core/l10n/he.php b/core/l10n/he.php
index 4579626f12d..8fb7373a143 100644
--- a/core/l10n/he.php
+++ b/core/l10n/he.php
@@ -37,6 +37,7 @@ $TRANSLATIONS = array(
"No" => "לא",
"Ok" => "בסדר",
"_{count} file conflict_::_{count} file conflicts_" => array("",""),
+"New Files" => "קבצים חדשים",
"Cancel" => "ביטול",
"Shared" => "שותף",
"Share" => "שתף",
diff --git a/core/l10n/hu_HU.php b/core/l10n/hu_HU.php
index e81991ec7ad..096b28e2d9b 100644
--- a/core/l10n/hu_HU.php
+++ b/core/l10n/hu_HU.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Nem sikerült betölteni az üzenet sablont: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} fájl ütközik","{count} fájl ütközik"),
"One file conflict" => "Egy file ütközik",
+"New Files" => "Új fájlok",
"Which files do you want to keep?" => "Melyik file-okat akarod megtartani?",
"If you select both versions, the copied file will have a number added to its name." => "Ha kiválasztod mindazokaz a verziókat, a másolt fileok neve sorszámozva lesz.",
"Cancel" => "Mégsem",
diff --git a/core/l10n/it.php b/core/l10n/it.php
index 2f0017263fa..43e9752f5e0 100644
--- a/core/l10n/it.php
+++ b/core/l10n/it.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Errore durante il caricamento del modello di messaggio: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} file in conflitto","{count} file in conflitto"),
"One file conflict" => "Un file in conflitto",
+"New Files" => "File nuovi",
"Which files do you want to keep?" => "Quali file vuoi mantenere?",
"If you select both versions, the copied file will have a number added to its name." => "Se selezioni entrambe le versioni, sarà aggiunto un numero al nome del file copiato.",
"Cancel" => "Annulla",
diff --git a/core/l10n/ja.php b/core/l10n/ja.php
index eb3e6882578..3a99f0e598b 100644
--- a/core/l10n/ja.php
+++ b/core/l10n/ja.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => "有効期限が切れています。",
"Couldn't send mail to following users: %s " => "次のユーザーにメールを送信できませんでした: %s",
"Turned on maintenance mode" => "メンテナンスモードがオンになりました",
"Turned off maintenance mode" => "メンテナンスモードがオフになりました",
@@ -49,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "メッセージテンプレートの読み込みエラー: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} ファイルが競合"),
"One file conflict" => "1ファイルが競合",
+"New Files" => "新しいファイル",
"Which files do you want to keep?" => "どちらのファイルを保持したいですか?",
"If you select both versions, the copied file will have a number added to its name." => "両方のバージョンを選択した場合は、ファイル名の後ろに数字を追加したファイルのコピーを作成します。",
"Cancel" => "キャンセル",
@@ -121,6 +123,8 @@ $TRANSLATIONS = array(
"To login page" => "ログインページへ戻る",
"New password" => "新しいパスワードを入力",
"Reset password" => "パスワードをリセット",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X では、サポートされていません。このOSでは、%sは正常に動作しないかもしれません。ご自身の責任においてご利用ください。",
+"For the best results, please consider using a GNU/Linux server instead." => "最も良い方法としては、代わりにGNU/Linuxサーバーを利用することをご検討ください。",
"Personal" => "個人",
"Users" => "ユーザー",
"Apps" => "アプリ",
diff --git a/core/l10n/jv.php b/core/l10n/jv.php
new file mode 100644
index 00000000000..ffcdde48d47
--- /dev/null
+++ b/core/l10n/jv.php
@@ -0,0 +1,9 @@
+<?php
+$TRANSLATIONS = array(
+"_%n minute ago_::_%n minutes ago_" => array("",""),
+"_%n hour ago_::_%n hours ago_" => array("",""),
+"_%n day ago_::_%n days ago_" => array("",""),
+"_%n month ago_::_%n months ago_" => array("",""),
+"_{count} file conflict_::_{count} file conflicts_" => array("","")
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/core/l10n/ka_GE.php b/core/l10n/ka_GE.php
index 0070fd7994e..a76a8866541 100644
--- a/core/l10n/ka_GE.php
+++ b/core/l10n/ka_GE.php
@@ -37,6 +37,7 @@ $TRANSLATIONS = array(
"No" => "არა",
"Ok" => "დიახ",
"_{count} file conflict_::_{count} file conflicts_" => array(""),
+"New Files" => "ახალი ფაილები",
"Cancel" => "უარყოფა",
"Shared" => "გაზიარებული",
"Share" => "გაზიარება",
diff --git a/core/l10n/lv.php b/core/l10n/lv.php
index 505bf46b4c9..683ff2c129a 100644
--- a/core/l10n/lv.php
+++ b/core/l10n/lv.php
@@ -37,6 +37,7 @@ $TRANSLATIONS = array(
"No" => "Nē",
"Ok" => "Labi",
"_{count} file conflict_::_{count} file conflicts_" => array("","",""),
+"New Files" => "Jaunās datnes",
"Cancel" => "Atcelt",
"Shared" => "Kopīgs",
"Share" => "Dalīties",
diff --git a/core/l10n/nb_NO.php b/core/l10n/nb_NO.php
index 43141bc431f..c47599f5a17 100644
--- a/core/l10n/nb_NO.php
+++ b/core/l10n/nb_NO.php
@@ -56,6 +56,10 @@ $TRANSLATIONS = array(
"(all selected)" => "(alle valgt)",
"({count} selected)" => "({count} valgt)",
"Error loading file exists template" => "Feil ved lasting av \"filen eksisterer\"-mal",
+"Very weak password" => "Veldig svakt passord",
+"Weak password" => "Svakt passord",
+"Good password" => "Bra passord",
+"Strong password" => "Sterkt passord",
"Shared" => "Delt",
"Share" => "Del",
"Error" => "Feil",
@@ -140,6 +144,7 @@ $TRANSLATIONS = array(
"Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Datamappen og filene dine er sannsynligvis tilgjengelig fra Internett fordi .htaccess-filen ikke fungerer.",
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "For informasjon om hvordan du setter opp serveren din riktig, se <a href=\"%s\" target=\"_blank\">dokumentasjonen</a>.",
"Create an <strong>admin account</strong>" => "opprett en <strong>administrator-konto</strong>",
+"Storage & database" => "Lagring og database",
"Data folder" => "Datamappe",
"Configure the database" => "Konfigurer databasen",
"will be used" => "vil bli brukt",
diff --git a/core/l10n/nl.php b/core/l10n/nl.php
index 05cef6afd5a..b09509e6290 100644
--- a/core/l10n/nl.php
+++ b/core/l10n/nl.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Fout bij laden berichtensjabloon: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} bestandsconflict","{count} bestandsconflicten"),
"One file conflict" => "Een bestandsconflict",
+"New Files" => "Nieuwe bestanden",
+"Already existing files" => "Al aanwezige bestanden",
"Which files do you want to keep?" => "Welke bestanden wilt u bewaren?",
"If you select both versions, the copied file will have a number added to its name." => "Als u beide versies selecteerde, zal het gekopieerde bestand een nummer aan de naam toegevoegd krijgen.",
"Cancel" => "Annuleer",
diff --git a/core/l10n/pl.php b/core/l10n/pl.php
index 17fde36c7cd..fe0cf145832 100644
--- a/core/l10n/pl.php
+++ b/core/l10n/pl.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Błąd podczas ładowania szablonu wiadomości: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} konfliktów plików","{count} konfliktów plików","{count} konfliktów plików"),
"One file conflict" => "Konflikt pliku",
+"New Files" => "Nowe pliki",
+"Already existing files" => "Już istniejące pliki",
"Which files do you want to keep?" => "Które pliki chcesz zachować?",
"If you select both versions, the copied file will have a number added to its name." => "Jeśli wybierzesz obie wersje, skopiowany plik będzie miał dodany numerek w nazwie",
"Cancel" => "Anuluj",
diff --git a/core/l10n/pl_PL.php b/core/l10n/pl_PL.php
deleted file mode 100644
index 15c376eb954..00000000000
--- a/core/l10n/pl_PL.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-$TRANSLATIONS = array(
-"Settings" => "Ustawienia",
-"Username" => "Nazwa użytkownika"
-);
-$PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/core/l10n/pt_BR.php b/core/l10n/pt_BR.php
index b31925cdf79..3545426b670 100644
--- a/core/l10n/pt_BR.php
+++ b/core/l10n/pt_BR.php
@@ -50,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Erro no carregamento de modelo de mensagem: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} conflito de arquivo","{count} conflitos de arquivos"),
"One file conflict" => "Conflito em um arquivo",
+"New Files" => "Novos Arquivos",
+"Already existing files" => "Arquivos já existentes",
"Which files do you want to keep?" => "Qual arquivo você quer manter?",
"If you select both versions, the copied file will have a number added to its name." => "Se você selecionar ambas as versões, o arquivo copiado terá um número adicionado ao seu nome.",
"Cancel" => "Cancelar",
diff --git a/core/l10n/pt_PT.php b/core/l10n/pt_PT.php
index a4d6785cd5e..bb1b6011a6b 100644
--- a/core/l10n/pt_PT.php
+++ b/core/l10n/pt_PT.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Erro ao carregar o template: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicto de ficheiro","{count} conflitos de ficheiro"),
"One file conflict" => "Um conflito no ficheiro",
+"New Files" => "Ficheiros Novos",
"Which files do you want to keep?" => "Quais os ficheiros que pretende manter?",
"If you select both versions, the copied file will have a number added to its name." => "Se escolher ambas as versões, o ficheiro copiado irá ter um número adicionado ao seu nome.",
"Cancel" => "Cancelar",
diff --git a/core/l10n/ru.php b/core/l10n/ru.php
index e2fdc36be0b..aa784088f7a 100644
--- a/core/l10n/ru.php
+++ b/core/l10n/ru.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Ошибка загрузки шаблона сообщений: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} конфликт в файлах","{count} конфликта в файлах","{count} конфликтов в файлах"),
"One file conflict" => "Один конфликт в файлах",
+"New Files" => "Новые файлы",
"Which files do you want to keep?" => "Какие файлы вы хотите сохранить?",
"If you select both versions, the copied file will have a number added to its name." => "При выборе обоих версий, к названию копируемого файла будет добавлена цифра",
"Cancel" => "Отменить",
diff --git a/core/l10n/sk_SK.php b/core/l10n/sk_SK.php
index bb3c9863ce2..1b717bc412e 100644
--- a/core/l10n/sk_SK.php
+++ b/core/l10n/sk_SK.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => " \t\nDátum expirácie spadá do minulosti.",
"Couldn't send mail to following users: %s " => "Nebolo možné odoslať email týmto používateľom: %s ",
"Turned on maintenance mode" => "Mód údržby je zapnutý",
"Turned off maintenance mode" => "Mód údržby e vypnutý",
@@ -49,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Chyba pri nahrávaní šablóny správy: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} konflikt súboru","{count} konflikty súboru","{count} konfliktov súboru"),
"One file conflict" => "Jeden konflikt súboru",
+"New Files" => "Nové súbory",
"Which files do you want to keep?" => "Ktoré súbory chcete ponechať?",
"If you select both versions, the copied file will have a number added to its name." => "Ak zvolíte obe verzie, názov nakopírovaného súboru bude doplnený o číslo.",
"Cancel" => "Zrušiť",
@@ -56,6 +58,11 @@ $TRANSLATIONS = array(
"(all selected)" => "(všetko vybrané)",
"({count} selected)" => "({count} vybraných)",
"Error loading file exists template" => "Chyba pri nahrávaní šablóny existencie súboru",
+"Very weak password" => "Veľmi slabé heslo",
+"Weak password" => "Slabé heslo",
+"So-so password" => "Priemerné heslo",
+"Good password" => "Dobré heslo",
+"Strong password" => "Silné heslo",
"Shared" => "Zdieľané",
"Share" => "Zdieľať",
"Error" => "Chyba",
@@ -103,6 +110,7 @@ $TRANSLATIONS = array(
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Aktualizácia nebola úspešná. Problém nahláste <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud comunite</a>.",
"The update was successful. Redirecting you to ownCloud now." => "Aktualizácia bola úspešná. Presmerovávam vás na prihlasovaciu stránku.",
"%s password reset" => "reset hesla %s",
+"A problem has occurred whilst sending the email, please contact your administrator." => "Vyskytol sa problém pri odosielaní emailu, prosím obráťte sa na správcu.",
"Use the following link to reset your password: {link}" => "Použite nasledujúci odkaz pre obnovenie vášho hesla: {link}",
"The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Odkaz na obnovenie hesla bol odoslaný na vašu emailovú adresu.<br>Ak ho v krátkej dobe neobdržíte, skontrolujte si váš kôš a priečinok spam.<br>Ak ho ani tam nenájdete, kontaktujte svojho administrátora.",
"Request failed!<br>Did you make sure your email/username was right?" => "Požiadavka zlyhala.<br>Uistili ste sa, že vaše používateľské meno a email sú správne?",
@@ -115,6 +123,8 @@ $TRANSLATIONS = array(
"To login page" => "Na prihlasovaciu stránku",
"New password" => "Nové heslo",
"Reset password" => "Obnovenie hesla",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X nie je podporovaný a %s nebude správne fungovať na tejto platforme. Použite ho na vlastné riziko!",
+"For the best results, please consider using a GNU/Linux server instead." => "Pre dosiahnutie najlepších výsledkov, prosím zvážte použitie GNU/Linux servera.",
"Personal" => "Osobné",
"Users" => "Používatelia",
"Apps" => "Aplikácie",
@@ -129,7 +139,7 @@ $TRANSLATIONS = array(
"Error unfavoriting" => "Chyba pri odobratí z obľúbených",
"Access forbidden" => "Prístup odmietnutý",
"Cloud not found" => "Nenájdené",
-"Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" => "Ahoj,\n\nchcem ti dať navedomie, že %s s tebou zdieľa %s.\nTu je odkaz: %s\n\n",
+"Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" => "Dobrý deň,\n\nPoužívateľ %s zdieľa s vami súbor, alebo priečinok s názvom %s.\nPre zobrazenie kliknite na túto linku: %s\n",
"The share will expire on %s." => "Zdieľanie expiruje %s.",
"Cheers!" => "Pekný deň!",
"Security Warning" => "Bezpečnostné varovanie",
@@ -140,6 +150,7 @@ $TRANSLATIONS = array(
"Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Váš priečinok s dátami a súbormi je dostupný z internetu, lebo súbor .htaccess nefunguje.",
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Pre informácie, ako správne nastaviť váš server, sa pozrite do <a href=\"%s\" target=\"_blank\">dokumentácie</a>.",
"Create an <strong>admin account</strong>" => "Vytvoriť <strong>administrátorský účet</strong>",
+"Storage & database" => "Úložislo & databáza",
"Data folder" => "Priečinok dát",
"Configure the database" => "Nastaviť databázu",
"will be used" => "bude použité",
@@ -162,6 +173,7 @@ $TRANSLATIONS = array(
"remember" => "zapamätať",
"Log in" => "Prihlásiť sa",
"Alternative Logins" => "Alternatívne prihlásenie",
+"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Dobrý deň,<br><br>Používateľ %s zdieľa s vami súbor, alebo priečinok s názvom »%s«.<br><a href=\"%s\">Pre zobrazenie kliknite na túto linku!</a><br><br>",
"This ownCloud instance is currently in single user mode." => "Táto inštancia ownCloudu je teraz v jednopoužívateľskom móde.",
"This means only administrators can use the instance." => "Len správca systému môže používať túto inštanciu.",
"Contact your system administrator if this message persists or appeared unexpectedly." => "Kontaktujte prosím správcu systému, ak sa táto správa objavuje opakovane alebo neočakávane.",
diff --git a/core/l10n/sl.php b/core/l10n/sl.php
index 49eb4f9aa69..7476d9f9c7c 100644
--- a/core/l10n/sl.php
+++ b/core/l10n/sl.php
@@ -50,6 +50,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Napaka nalaganja predloge sporočil: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} spor datotek","{count} spora datotek","{count} spori datotek","{count} sporov datotek"),
"One file conflict" => "En spor datotek",
+"New Files" => "Nove datoteke",
"Which files do you want to keep?" => "Katare datoteke želite ohraniti?",
"If you select both versions, the copied file will have a number added to its name." => "Če izberete obe različici, bo kopirani datoteki k imenu dodana številka.",
"Cancel" => "Prekliči",
diff --git a/core/l10n/sv.php b/core/l10n/sv.php
index c4e92e62171..d46c204d7c3 100644
--- a/core/l10n/sv.php
+++ b/core/l10n/sv.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Expiration date is in the past." => "Utgångsdatumet är i det förflutna.",
"Couldn't send mail to following users: %s " => "Gick inte att skicka e-post till följande användare: %s",
"Turned on maintenance mode" => "Aktiverade underhållsläge",
"Turned off maintenance mode" => "Deaktiverade underhållsläge",
@@ -49,6 +50,8 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Fel uppstod under inläsningen av meddelandemallen: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} filkonflikt","{count} filkonflikter"),
"One file conflict" => "En filkonflikt",
+"New Files" => "Nya filer",
+"Already existing files" => "Filer som redan existerar",
"Which files do you want to keep?" => "Vilken fil vill du behålla?",
"If you select both versions, the copied file will have a number added to its name." => "Om du väljer båda versionerna kommer de kopierade filerna ha nummer tillagda i filnamnet.",
"Cancel" => "Avbryt",
@@ -56,6 +59,11 @@ $TRANSLATIONS = array(
"(all selected)" => "(Alla valda)",
"({count} selected)" => "({count} valda)",
"Error loading file exists template" => "Fel uppstod filmall existerar",
+"Very weak password" => "Väldigt svagt lösenord",
+"Weak password" => "Svagt lösenord",
+"So-so password" => "Okej lösenord",
+"Good password" => "Bra lösenord",
+"Strong password" => "Starkt lösenord",
"Shared" => "Delad",
"Share" => "Dela",
"Error" => "Fel",
@@ -99,9 +107,11 @@ $TRANSLATIONS = array(
"Edit tags" => "Editera taggar",
"Error loading dialog template: {error}" => "Fel under laddning utav dialog mall: {fel}",
"No tags selected for deletion." => "Inga taggar valda för borttagning.",
+"Please reload the page." => "Vänligen ladda om sidan.",
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Uppdateringen misslyckades. Rapportera detta problem till <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud Community</a>.",
"The update was successful. Redirecting you to ownCloud now." => "Uppdateringen lyckades. Du omdirigeras nu till OwnCloud.",
"%s password reset" => "%s återställ lösenord",
+"A problem has occurred whilst sending the email, please contact your administrator." => "Ett problem har uppstått under tiden e-post sändes, vänligen kontakta din administratör.",
"Use the following link to reset your password: {link}" => "Använd följande länk för att återställa lösenordet: {link}",
"The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Länken för att återställa ditt lösenorden har skickats till din e-postadress<br>Om du inte har erhållit meddelandet inom kort, vänligen kontrollera din skräppost-mapp<br>Om den inte finns där, vänligen kontakta din administratör.",
"Request failed!<br>Did you make sure your email/username was right?" => "Begäran misslyckades!<br>Är du helt säker på att din e-postadress/användarnamn är korrekt?",
@@ -114,6 +124,8 @@ $TRANSLATIONS = array(
"To login page" => "Till logginsidan",
"New password" => "Nytt lösenord",
"Reset password" => "Återställ lösenordet",
+"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X stöds inte och %s kommer inte att fungera korrekt på denna plattform. Använd på egen risk!",
+"For the best results, please consider using a GNU/Linux server instead." => "För bästa resultat, överväg att använda en GNU/Linux server istället.",
"Personal" => "Personligt",
"Users" => "Användare",
"Apps" => "Program",
@@ -139,6 +151,7 @@ $TRANSLATIONS = array(
"Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Din datakatalog och filer är förmodligen tillgängliga från Internet, eftersom .htaccess-filen inte fungerar.",
"For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "För information hur du korrekt konfigurerar din servern, se ownCloud <a href=\"%s\" target=\"_blank\">dokumentationen</a>.",
"Create an <strong>admin account</strong>" => "Skapa ett <strong>administratörskonto</strong>",
+"Storage & database" => "Lagring & databas",
"Data folder" => "Datamapp",
"Configure the database" => "Konfigurera databasen",
"will be used" => "kommer att användas",
@@ -149,6 +162,7 @@ $TRANSLATIONS = array(
"Database host" => "Databasserver",
"Finish setup" => "Avsluta installation",
"Finishing …" => "Avslutar ...",
+"This application requires JavaScript to be enabled for correct operation. Please <a href=\"http://enable-javascript.com/\" target=\"_blank\">enable JavaScript</a> and re-load this interface." => "Denna applikation kräver JavaScript aktiverat för att fungera korrekt. Vänligen <a href=\"http://enable-javascript.com/\" target=\"_blank\">aktivera JavaScript</a> och ladda om gränssnittet.",
"%s is available. Get more information on how to update." => "%s är tillgänglig. Få mer information om hur du går tillväga för att uppdatera.",
"Log out" => "Logga ut",
"Automatic logon rejected!" => "Automatisk inloggning inte tillåten!",
@@ -160,6 +174,9 @@ $TRANSLATIONS = array(
"remember" => "kom ihåg",
"Log in" => "Logga in",
"Alternative Logins" => "Alternativa inloggningar",
+"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Hej där,<br><br>ville bara informera dig om att %s delade <strong>%s</strong> med dig.<br><a href=\"%s\">Visa den!</a><br><br>",
+"This ownCloud instance is currently in single user mode." => "Denna ownCloud instans är för närvarande i enanvändarläge",
+"This means only administrators can use the instance." => "Detta betyder att endast administartörer kan använda instansen.",
"Contact your system administrator if this message persists or appeared unexpectedly." => "Hör av dig till din system administratör ifall detta meddelande fortsätter eller visas oväntat.",
"Thank you for your patience." => "Tack för ditt tålamod.",
"Updating ownCloud to version %s, this may take a while." => "Uppdaterar ownCloud till version %s, detta kan ta en stund.",
diff --git a/core/l10n/th_TH.php b/core/l10n/th_TH.php
index 85a9b4ab238..9ee3c60f947 100644
--- a/core/l10n/th_TH.php
+++ b/core/l10n/th_TH.php
@@ -37,6 +37,7 @@ $TRANSLATIONS = array(
"No" => "ไม่ตกลง",
"Ok" => "ตกลง",
"_{count} file conflict_::_{count} file conflicts_" => array(""),
+"New Files" => "ไฟล์ใหม่",
"Cancel" => "ยกเลิก",
"Shared" => "แชร์แล้ว",
"Share" => "แชร์",
diff --git a/core/l10n/tr.php b/core/l10n/tr.php
index affa1b063d0..7e75cdf4b01 100644
--- a/core/l10n/tr.php
+++ b/core/l10n/tr.php
@@ -31,7 +31,7 @@ $TRANSLATIONS = array(
"December" => "Aralık",
"Settings" => "Ayarlar",
"Saving..." => "Kaydediliyor...",
-"seconds ago" => "saniye önce",
+"seconds ago" => "saniyeler önce",
"_%n minute ago_::_%n minutes ago_" => array("%n dakika önce","%n dakika önce"),
"_%n hour ago_::_%n hours ago_" => array("%n saat önce","%n saat önce"),
"today" => "bugün",
@@ -50,8 +50,10 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "İleti şablonu yüklenirken hata: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} dosya çakışması","{count} dosya çakışması"),
"One file conflict" => "Bir dosya çakışması",
+"New Files" => "Yeni Dosyalar",
+"Already existing files" => "Zaten mevcut olan dosyalar",
"Which files do you want to keep?" => "Hangi dosyaları saklamak istiyorsunuz?",
-"If you select both versions, the copied file will have a number added to its name." => "Eğer iki sürümü de seçerseniz, kopyalanan dosya ismine eklenmiş bir sayı içerecektir.",
+"If you select both versions, the copied file will have a number added to its name." => "İki sürümü de seçerseniz, kopyalanan dosyanın ismine bir sayı ilave edilecektir.",
"Cancel" => "İptal",
"Continue" => "Devam et",
"(all selected)" => "(tümü seçildi)",
@@ -65,7 +67,7 @@ $TRANSLATIONS = array(
"Shared" => "Paylaşılan",
"Share" => "Paylaş",
"Error" => "Hata",
-"Error while sharing" => "Paylaşım sırasında hata ",
+"Error while sharing" => "Paylaşım sırasında hata",
"Error while unsharing" => "Paylaşım iptal edilirken hata",
"Error while changing permissions" => "İzinleri değiştirirken hata oluştu",
"Shared with you and the group {group} by {owner}" => "{owner} tarafından sizinle ve {group} ile paylaştırılmış",
@@ -159,7 +161,7 @@ $TRANSLATIONS = array(
"Database tablespace" => "Veritabanı tablo alanı",
"Database host" => "Veritabanı sunucusu",
"Finish setup" => "Kurulumu tamamla",
-"Finishing …" => "Tamamlanıyor ..",
+"Finishing …" => "Tamamlanıyor ...",
"This application requires JavaScript to be enabled for correct operation. Please <a href=\"http://enable-javascript.com/\" target=\"_blank\">enable JavaScript</a> and re-load this interface." => "Uygulama, doğru çalışabilmesi için JavaScript'in etkinleştirilmesini gerektiriyor. Lütfen <a href=\"http://enable-javascript.com/\" target=\"_blank\">JavaScript'i etkinleştirin</a> ve bu arayüzü yeniden yükleyin.",
"%s is available. Get more information on how to update." => "%s mevcut. Güncelleştirme hakkında daha fazla bilgi alın.",
"Log out" => "Çıkış yap",
diff --git a/core/l10n/uk.php b/core/l10n/uk.php
index ade29981b49..f6bcfdcdc8d 100644
--- a/core/l10n/uk.php
+++ b/core/l10n/uk.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Помилка при завантаженні шаблону повідомлення: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} файловий конфлікт","{count} файлових конфліктів","{count} файлових конфліктів"),
"One file conflict" => "Один файловий конфлікт",
+"New Files" => "Нових Файлів",
"Which files do you want to keep?" => "Які файли ви хочете залишити?",
"If you select both versions, the copied file will have a number added to its name." => "Якщо ви оберете обидві версії, скопійований файл буде мати номер, доданий у його ім'я.",
"Cancel" => "Відмінити",
diff --git a/core/l10n/vi.php b/core/l10n/vi.php
index be99580d942..319f68b6355 100644
--- a/core/l10n/vi.php
+++ b/core/l10n/vi.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "Lỗi khi tải mẫu thông điệp: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} tập tin xung đột"),
"One file conflict" => "Một tập tin xung đột",
+"New Files" => "File mới",
"Which files do you want to keep?" => "Bạn muốn tiếp tục với những tập tin nào?",
"If you select both versions, the copied file will have a number added to its name." => "Nếu bạn chọn cả hai phiên bản, tập tin được sao chép sẽ được đánh thêm số vào tên của nó.",
"Cancel" => "Hủy",
diff --git a/core/l10n/zh_CN.php b/core/l10n/zh_CN.php
index e5a6a254e54..68f50baf98f 100644
--- a/core/l10n/zh_CN.php
+++ b/core/l10n/zh_CN.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "加载消息模板出错: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} 个文件冲突"),
"One file conflict" => "1个文件冲突",
+"New Files" => "新文件",
"Which files do you want to keep?" => "想要保留哪一个文件呢?",
"If you select both versions, the copied file will have a number added to its name." => "如果同时选择了连个版本,复制的文件名将会添加上一个数字。",
"Cancel" => "取消",
diff --git a/core/l10n/zh_TW.php b/core/l10n/zh_TW.php
index dae143cef40..0799344697a 100644
--- a/core/l10n/zh_TW.php
+++ b/core/l10n/zh_TW.php
@@ -49,6 +49,7 @@ $TRANSLATIONS = array(
"Error loading message template: {error}" => "載入訊息樣板出錯: {error}",
"_{count} file conflict_::_{count} file conflicts_" => array("{count} 個檔案衝突"),
"One file conflict" => "一個檔案衝突",
+"New Files" => "新檔案",
"Which files do you want to keep?" => "您要保留哪一個檔案?",
"If you select both versions, the copied file will have a number added to its name." => "如果您同時選擇兩個版本,被複製的那個檔案名稱後面會加上編號",
"Cancel" => "取消",
diff --git a/core/lostpassword/templates/resetpassword.php b/core/lostpassword/templates/resetpassword.php
index 0ab32acca60..881455f5a9d 100644
--- a/core/lostpassword/templates/resetpassword.php
+++ b/core/lostpassword/templates/resetpassword.php
@@ -1,14 +1,14 @@
-<form action="<?php echo OC_Helper::linkToRoute('core_lostpassword_reset', $_['args']) ?>" method="post">
+<form action="<?php print_unescaped(OC_Helper::linkToRoute('core_lostpassword_reset', $_['args'])) ?>" method="post">
<fieldset>
<?php if($_['success']): ?>
- <h1><?php echo $l->t('Your password was reset'); ?></h1>
- <p><a href="<?php echo OC_Helper::linkTo('', 'index.php') ?>/"><?php echo $l->t('To login page'); ?></a></p>
+ <h1><?php p($l->t('Your password was reset')); ?></h1>
+ <p><a href="<?php print_unescaped(OC_Helper::linkTo('', 'index.php')) ?>/"><?php p($l->t('To login page')); ?></a></p>
<?php else: ?>
<p class="infield">
- <label for="password" class="infield"><?php echo $l->t( 'New password' ); ?></label>
+ <label for="password" class="infield"><?php p($l->t('New password')); ?></label>
<input type="password" name="password" id="password" value="" required />
</p>
- <input type="submit" id="submit" value="<?php echo $l->t('Reset password'); ?>" />
+ <input type="submit" id="submit" value="<?php p($l->t('Reset password')); ?>" />
<?php endif; ?>
</fieldset>
</form>