Browse Source

Uploading file to the cloud via curl

Andrea Fazzi 5 năm trước cách đây
mục cha
commit
bac047f165
100 tập tin đã thay đổi với 0 bổ sung23633 xóa
  1. 0 14
      compose/karmen/config/.htaccess
  2. 0 0
      compose/karmen/config/CAN_INSTALL
  3. 0 4
      compose/karmen/config/apache-pretty-urls.config.php
  4. 0 4
      compose/karmen/config/apcu.config.php
  5. 0 15
      compose/karmen/config/apps.config.php
  6. 0 31
      compose/karmen/config/autoconfig.php
  7. 0 34
      compose/karmen/config/config.php
  8. 0 1719
      compose/karmen/config/config.sample.php
  9. 0 13
      compose/karmen/config/redis.config.php
  10. 0 15
      compose/karmen/config/smtp.config.php
  11. 0 20
      compose/karmen/data/.htaccess
  12. 0 0
      compose/karmen/data/.ocdata
  13. BIN
      compose/karmen/data/admin/files/Documents/About.odt
  14. 0 10
      compose/karmen/data/admin/files/Documents/About.txt
  15. BIN
      compose/karmen/data/admin/files/Documents/Nextcloud Flyer.pdf
  16. BIN
      compose/karmen/data/admin/files/Documents/elenco_docenti.pdf
  17. 0 16
      compose/karmen/data/admin/files/Karmen/list/list.tpl.md
  18. BIN
      compose/karmen/data/admin/files/Karmen/list/reference.odt
  19. BIN
      compose/karmen/data/admin/files/Nextcloud Manual.pdf
  20. BIN
      compose/karmen/data/admin/files/Nextcloud intro.mp4
  21. BIN
      compose/karmen/data/admin/files/Nextcloud.mp4
  22. BIN
      compose/karmen/data/admin/files/Nextcloud.png
  23. BIN
      compose/karmen/data/admin/files/Photos/Coast.jpg
  24. BIN
      compose/karmen/data/admin/files/Photos/Hummingbird.jpg
  25. BIN
      compose/karmen/data/admin/files/Photos/Nextcloud Community.jpg
  26. BIN
      compose/karmen/data/admin/files/Photos/Nut.jpg
  27. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570114545
  28. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115314
  29. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115397
  30. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115459
  31. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116511
  32. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116637
  33. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116770
  34. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570117586
  35. BIN
      compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570117743
  36. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570114087
  37. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115384
  38. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115386
  39. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115387
  40. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115432
  41. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115445
  42. 0 16
      compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115450
  43. 0 0
      compose/karmen/data/appdata_oc216qe0mln5/appstore/apps.json
  44. 0 0
      compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css
  45. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css.deps
  46. BIN
      compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css.gzip
  47. 0 0
      compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css
  48. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css.deps
  49. BIN
      compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css.gzip
  50. 0 0
      compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css
  51. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css.deps
  52. BIN
      compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css.gzip
  53. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css
  54. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css.deps
  55. BIN
      compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css.gzip
  56. 0 608
      compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js
  57. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js.deps
  58. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js.gzip
  59. 0 1073
      compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js
  60. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js.deps
  61. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js.gzip
  62. 0 10666
      compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js
  63. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js.deps
  64. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js.gzip
  65. 0 491
      compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js
  66. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js.deps
  67. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js.gzip
  68. 0 6789
      compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js
  69. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js.deps
  70. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js.gzip
  71. 0 508
      compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js
  72. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js.deps
  73. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js.gzip
  74. 0 0
      compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js
  75. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js.deps
  76. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js.gzip
  77. 0 734
      compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js
  78. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js.deps
  79. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js.gzip
  80. 0 735
      compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js
  81. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js.deps
  82. BIN
      compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js.gzip
  83. BIN
      compose/karmen/data/appdata_oc216qe0mln5/preview/101/2048-2048-max.png
  84. BIN
      compose/karmen/data/appdata_oc216qe0mln5/preview/101/32-32-crop.png
  85. BIN
      compose/karmen/data/appdata_oc216qe0mln5/preview/16/2048-2048-max.png
  86. BIN
      compose/karmen/data/appdata_oc216qe0mln5/preview/16/32-32-crop.png
  87. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_application-pdf.svg
  88. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_folder.svg
  89. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_text.svg
  90. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_video.svg
  91. 0 1
      compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_x-office-document.svg
  92. 0 0
      compose/karmen/data/appdata_oc6972tp5niy/appstore/apps.json
  93. 0 0
      compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css
  94. 0 1
      compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.deps
  95. BIN
      compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.gzip
  96. 0 0
      compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css
  97. 0 1
      compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css.deps
  98. BIN
      compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css.gzip
  99. 0 0
      compose/karmen/data/appdata_oc6972tp5niy/css/files_texteditor/f1898ace4fdd2faf5ef6f8c60e062537-merged.css
  100. 0 1
      compose/karmen/data/appdata_oc6972tp5niy/css/files_texteditor/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.deps

+ 0 - 14
compose/karmen/config/.htaccess

@@ -1,14 +0,0 @@
-# line below if for Apache 2.4
-<ifModule mod_authz_core.c>
-Require all denied
-</ifModule>
-
-# line below if for Apache 2.2
-<ifModule !mod_authz_core.c>
-deny from all
-</ifModule>
-
-# section for Apache 2.2 and 2.4
-<ifModule mod_autoindex.c>
-IndexIgnore *
-</ifModule>

+ 0 - 0
compose/karmen/config/CAN_INSTALL


+ 0 - 4
compose/karmen/config/apache-pretty-urls.config.php

@@ -1,4 +0,0 @@
-<?php
-$CONFIG = array (
-  'htaccess.RewriteBase' => '/',
-);

+ 0 - 4
compose/karmen/config/apcu.config.php

@@ -1,4 +0,0 @@
-<?php
-$CONFIG = array (
-  'memcache.local' => '\OC\Memcache\APCu',
-);

+ 0 - 15
compose/karmen/config/apps.config.php

@@ -1,15 +0,0 @@
-<?php
-$CONFIG = array (
-  "apps_paths" => array (
-      0 => array (
-              "path"     => OC::$SERVERROOT."/apps",
-              "url"      => "/apps",
-              "writable" => false,
-      ),
-      1 => array (
-              "path"     => OC::$SERVERROOT."/custom_apps",
-              "url"      => "/custom_apps",
-              "writable" => true,
-      ),
-  ),
-);

+ 0 - 31
compose/karmen/config/autoconfig.php

@@ -1,31 +0,0 @@
-<?php
-
-$autoconfig_enabled = false;
-
-if (getenv('SQLITE_DATABASE')) {
-    $AUTOCONFIG["dbtype"] = "sqlite";
-    $AUTOCONFIG["dbname"] = getenv('SQLITE_DATABASE');
-    $autoconfig_enabled = true;
-} elseif (getenv('MYSQL_DATABASE') && getenv('MYSQL_USER') && getenv('MYSQL_PASSWORD') && getenv('MYSQL_HOST')) {
-    $AUTOCONFIG["dbtype"] = "mysql";
-    $AUTOCONFIG["dbname"] = getenv('MYSQL_DATABASE');
-    $AUTOCONFIG["dbuser"] = getenv('MYSQL_USER');
-    $AUTOCONFIG["dbpass"] = getenv('MYSQL_PASSWORD');
-    $AUTOCONFIG["dbhost"] = getenv('MYSQL_HOST');
-    $autoconfig_enabled = true;
-} elseif (getenv('POSTGRES_DB') && getenv('POSTGRES_USER') && getenv('POSTGRES_PASSWORD') && getenv('POSTGRES_HOST')) {
-    $AUTOCONFIG["dbtype"] = "pgsql";
-    $AUTOCONFIG["dbname"] = getenv('POSTGRES_DB');
-    $AUTOCONFIG["dbuser"] = getenv('POSTGRES_USER');
-    $AUTOCONFIG["dbpass"] = getenv('POSTGRES_PASSWORD');
-    $AUTOCONFIG["dbhost"] = getenv('POSTGRES_HOST');
-    $autoconfig_enabled = true;
-}
-
-if ($autoconfig_enabled) {
-    if (getenv('NEXTCLOUD_TABLE_PREFIX')) {
-        $AUTOCONFIG["dbtableprefix"] = getenv('NEXTCLOUD_TABLE_PREFIX');
-    }
-
-    $AUTOCONFIG["directory"] = getenv('NEXTCLOUD_DATA_DIR') ?: "/var/www/html/data";
-}

+ 0 - 34
compose/karmen/config/config.php

@@ -1,34 +0,0 @@
-<?php
-$CONFIG = array (
-  'htaccess.RewriteBase' => '/',
-  'memcache.local' => '\\OC\\Memcache\\APCu',
-  'apps_paths' => 
-  array (
-    0 => 
-    array (
-      'path' => '/var/www/html/apps',
-      'url' => '/apps',
-      'writable' => false,
-    ),
-    1 => 
-    array (
-      'path' => '/var/www/html/custom_apps',
-      'url' => '/custom_apps',
-      'writable' => true,
-    ),
-  ),
-  'passwordsalt' => 'LUWBpbDfP6KE5ee4vsMi/LJk/ky1ty',
-  'secret' => '1M5SVPb8cSp7aVSKQss+ha52hGSlAkq3SoGhr4gKQG7I49zF',
-  'trusted_domains' => 
-  array (
-    0 => 'localhost',
-    1 => 'nextcloud_server',
-  ),
-  'datadirectory' => '/var/www/html/data',
-  'dbtype' => 'sqlite3',
-  'version' => '17.0.0.9',
-  'overwrite.cli.url' => 'http://localhost',
-  'dbname' => 'nextcloud',
-  'installed' => true,
-  'instanceid' => 'occakkp6o8zz',
-);

+ 0 - 1719
compose/karmen/config/config.sample.php

@@ -1,1719 +0,0 @@
-<?php
-
-/**
- * This configuration file is only provided to document the different
- * configuration options and their usage.
- *
- * DO NOT COMPLETELY BASE YOUR CONFIGURATION FILE ON THIS SAMPLE. THIS MAY BREAK
- * YOUR INSTANCE. Instead, manually copy configuration switches that you
- * consider important for your instance to your working ``config.php``, and
- * apply configuration options that are pertinent for your instance.
- *
- * This file is used to generate the configuration documentation.
- * Please consider following requirements of the current parser:
- *  * all comments need to start with `/**` and end with ` *\/` - each on their
- *    own line
- *  * add a `@see CONFIG_INDEX` to copy a previously described config option
- *    also to this line
- *  * everything between the ` *\/` and the next `/**` will be treated as the
- *    config option
- *  * use RST syntax
- */
-
-$CONFIG = array(
-
-
-/**
- * Default Parameters
- *
- * These parameters are configured by the Nextcloud installer, and are required
- * for your Nextcloud server to operate.
- */
-
-
-/**
- * This is a unique identifier for your Nextcloud installation, created
- * automatically by the installer. This example is for documentation only,
- * and you should never use it because it will not work. A valid ``instanceid``
- * is created when you install Nextcloud.
- *
- * 'instanceid' => 'd3c944a9a',
- */
-'instanceid' => '',
-
- /**
-  * The salt used to hash all passwords, auto-generated by the Nextcloud
-  * installer. (There are also per-user salts.) If you lose this salt you lose
-  * all your passwords. This example is for documentation only, and you should
-  * never use it.
-  *
-  * @deprecated This salt is deprecated and only used for legacy-compatibility,
-  * developers should *NOT* use this value for anything nowadays.
-  *
-  * 'passwordsalt' => 'd3c944a9af095aa08f',
- */
-'passwordsalt' => '',
-
-/**
- * Your list of trusted domains that users can log into. Specifying trusted
- * domains prevents host header poisoning. Do not remove this, as it performs
- * necessary security checks.
- * You can specify:
- *
- * - the exact hostname of your host or virtual host, e.g. demo.example.org.
- * - the exact hostname with permitted port, e.g. demo.example.org:443.
- *   This disallows all other ports on this host
- * - use * as a wildcard, e.g. ubos-raspberry-pi*.local will allow
- *   ubos-raspberry-pi.local and ubos-raspberry-pi-2.local
- */
-'trusted_domains' =>
-  array (
-    'demo.example.org',
-    'otherdomain.example.org',
-  ),
-
-
-/**
- * Where user files are stored. The SQLite database is also stored here, when
- * you use SQLite.
- *
- * Default to ``data/`` in the Nextcloud directory.
- */
-'datadirectory' => '/var/www/nextcloud/data',
-
-/**
- * The current version number of your Nextcloud installation. This is set up
- * during installation and update, so you shouldn't need to change it.
- */
-'version' => '',
-
-/**
- * Identifies the database used with this installation. See also config option
- * ``supportedDatabases``
- *
- * Available:
- * 	- sqlite3 (SQLite3)
- * 	- mysql (MySQL/MariaDB)
- * 	- pgsql (PostgreSQL)
- *
- * Defaults to ``sqlite3``
- */
-'dbtype' => 'sqlite3',
-
-/**
- * Your host server name, for example ``localhost``, ``hostname``,
- * ``hostname.example.com``, or the IP address. To specify a port use
- * ``hostname:####``; to specify a Unix socket use
- * ``localhost:/path/to/socket``.
- */
-'dbhost' => '',
-
-/**
- * The name of the Nextcloud database, which is set during installation. You
- * should not need to change this.
- */
-'dbname' => 'nextcloud',
-
-/**
- * The user that Nextcloud uses to write to the database. This must be unique
- * across Nextcloud instances using the same SQL database. This is set up during
- * installation, so you shouldn't need to change it.
- */
-'dbuser' => '',
-
-/**
- * The password for the database user. This is set up during installation, so
- * you shouldn't need to change it.
- */
-'dbpassword' => '',
-
-/**
- * Prefix for the Nextcloud tables in the database.
- *
- * Default to ``oc_``
- */
-'dbtableprefix' => '',
-
-
-/**
- * Indicates whether the Nextcloud instance was installed successfully; ``true``
- * indicates a successful installation, and ``false`` indicates an unsuccessful
- * installation.
- *
- * Defaults to ``false``
- */
-'installed' => false,
-
-
-/**
- * User Experience
- *
- * These optional parameters control some aspects of the user interface. Default
- * values, where present, are shown.
- */
-
-/**
- * This sets the default language on your Nextcloud server, using ISO_639-1
- * language codes such as ``en`` for English, ``de`` for German, and ``fr`` for
- * French. It overrides automatic language detection on public pages like login
- * or shared items. User's language preferences configured under "personal ->
- * language" override this setting after they have logged in. Nextcloud has two
- * distinguished language codes for German, 'de' and 'de_DE'. 'de' is used for
- * informal German and 'de_DE' for formal German. By setting this value to 'de_DE'
- * you can enforce the formal version of German unless the user has chosen
- * something different explicitly.
- *
- * Defaults to ``en``
- */
-'default_language' => 'en',
-
-/**
- * With this setting a language can be forced for all users. If a language is
- * forced, the users are also unable to change their language in the personal
- * settings. If users shall be unable to change their language, but users have
- * different languages, this value can be set to ``true`` instead of a language
- * code.
- *
- * Defaults to ``false``
- */
-'force_language' => 'en',
-
-/**
- * This sets the default locale on your Nextcloud server, using ISO_639
- * language codes such as ``en`` for English, ``de`` for German, and ``fr`` for
- * French, and ISO-3166 country codes such as ``GB``, ``US``, ``CA``, as defined
- * in RFC 5646. It overrides automatic locale detection on public pages like
- * login or shared items. User's locale preferences configured under "personal
- * -> locale" override this setting after they have logged in.
- *
- * Defaults to ``en``
- */
-'default_locale' => 'en_US',
-
-/**
- * With this setting a locale can be forced for all users. If a locale is
- * forced, the users are also unable to change their locale in the personal
- * settings. If users shall be unable to change their locale, but users have
- * different languages, this value can be set to ``true`` instead of a locale
- * code.
- *
- * Defaults to ``false``
- */
-'force_locale' => 'en_US',
-
-/**
- * Set the default app to open on login. Use the app names as they appear in the
- * URL after clicking them in the Apps menu, such as documents, calendar, and
- * gallery. You can use a comma-separated list of app names, so if the first
- * app is not enabled for a user then Nextcloud will try the second one, and so
- * on. If no enabled apps are found it defaults to the Files app.
- *
- * Defaults to ``files``
- */
-'defaultapp' => 'files',
-
-/**
- * ``true`` enables the Help menu item in the user menu (top right of the
- * Nextcloud Web interface). ``false`` removes the Help item.
- */
-'knowledgebaseenabled' => true,
-
-/**
- * ``true`` allows users to change their display names (on their Personal
- * pages), and ``false`` prevents them from changing their display names.
- */
-'allow_user_to_change_display_name' => true,
-
-/**
- * Lifetime of the remember login cookie. This should be larger than the
- * session_lifetime. If it is set to 0 remember me is disabled.
- *
- * Defaults to ``60*60*24*15`` seconds (15 days)
- */
-'remember_login_cookie_lifetime' => 60*60*24*15,
-
-/**
- * The lifetime of a session after inactivity.
- *
- * Defaults to ``60*60*24`` seconds (24 hours)
- */
-'session_lifetime' => 60 * 60 * 24,
-
-/**
- * Enable or disable session keep-alive when a user is logged in to the Web UI.
- * Enabling this sends a "heartbeat" to the server to keep it from timing out.
- *
- * Defaults to ``true``
- */
-'session_keepalive' => true,
-
-/**
- * Enforce token authentication for clients, which blocks requests using the user
- * password for enhanced security. Users need to generate tokens in personal settings
- * which can be used as passwords on their clients.
- *
- * Defaults to ``false``
- */
-'token_auth_enforced' => false,
-
-/**
- * Whether the bruteforce protection shipped with Nextcloud should be enabled or not.
- *
- * Disabling this is discouraged for security reasons.
- *
- * Defaults to ``true``
- */
-'auth.bruteforce.protection.enabled' => true,
-
-/**
- * The directory where the skeleton files are located. These files will be
- * copied to the data directory of new users. Leave empty to not copy any
- * skeleton files.
- * ``{lang}`` can be used as a placeholder for the language of the user.
- * If the directory does not exist, it falls back to non dialect (from ``de_DE``
- * to ``de``). If that does not exist either, it falls back to ``default``
- *
- * Defaults to ``core/skeleton`` in the Nextcloud directory.
- */
-'skeletondirectory' => '/path/to/nextcloud/core/skeleton',
-
-/**
- * If your user backend does not allow password resets (e.g. when it's a
- * read-only user backend like LDAP), you can specify a custom link, where the
- * user is redirected to, when clicking the "reset password" link after a failed
- * login-attempt.
- * In case you do not want to provide any link, replace the url with 'disabled'
- */
-'lost_password_link' => 'https://example.org/link/to/password/reset',
-
-/**
- * Mail Parameters
- *
- * These configure the email settings for Nextcloud notifications and password
- * resets.
- */
-
-/**
- * The return address that you want to appear on emails sent by the Nextcloud
- * server, for example ``nc-admin@example.com``, substituting your own domain,
- * of course.
- */
-'mail_domain' => 'example.com',
-
-/**
- * FROM address that overrides the built-in ``sharing-noreply`` and
- * ``lostpassword-noreply`` FROM addresses.
- *
- * Defaults to different from addresses depending on the feature.
- */
-'mail_from_address' => 'nextcloud',
-
-/**
- * Enable SMTP class debugging.
- *
- * Defaults to ``false``
- */
-'mail_smtpdebug' => false,
-
-/**
- * Which mode to use for sending mail: ``sendmail``, ``smtp`` or ``qmail``.
- *
- * If you are using local or remote SMTP, set this to ``smtp``.
- *
- * For the ``sendmail`` option you need an installed and working email system on
- * the server, with ``/usr/sbin/sendmail`` installed on your Unix system.
- *
- * For ``qmail`` the binary is /var/qmail/bin/sendmail, and it must be installed
- * on your Unix system.
- *
- * Defaults to ``smtp``
- */
-'mail_smtpmode' => 'smtp',
-
-/**
- * This depends on ``mail_smtpmode``. Specify the IP address of your mail
- * server host. This may contain multiple hosts separated by a semi-colon. If
- * you need to specify the port number append it to the IP address separated by
- * a colon, like this: ``127.0.0.1:24``.
- *
- * Defaults to ``127.0.0.1``
- */
-'mail_smtphost' => '127.0.0.1',
-
-/**
- * This depends on ``mail_smtpmode``. Specify the port for sending mail.
- *
- * Defaults to ``25``
- */
-'mail_smtpport' => 25,
-
-/**
- * This depends on ``mail_smtpmode``. This sets the SMTP server timeout, in
- * seconds. You may need to increase this if you are running an anti-malware or
- * spam scanner.
- *
- * Defaults to ``10`` seconds
- */
-'mail_smtptimeout' => 10,
-
-/**
- * This depends on ``mail_smtpmode``. Specify when you are using ``ssl`` or
- * ``tls``, or leave empty for no encryption.
- *
- * Defaults to ``''`` (empty string)
- */
-'mail_smtpsecure' => '',
-
-/**
- * This depends on ``mail_smtpmode``. Change this to ``true`` if your mail
- * server requires authentication.
- *
- * Defaults to ``false``
- */
-'mail_smtpauth' => false,
-
-/**
- * This depends on ``mail_smtpmode``. If SMTP authentication is required, choose
- * the authentication type as ``LOGIN`` or ``PLAIN``.
- *
- * Defaults to ``LOGIN``
- */
-'mail_smtpauthtype' => 'LOGIN',
-
-/**
- * This depends on ``mail_smtpauth``. Specify the username for authenticating to
- * the SMTP server.
- *
- * Defaults to ``''`` (empty string)
- */
-'mail_smtpname' => '',
-
-/**
- * This depends on ``mail_smtpauth``. Specify the password for authenticating to
- * the SMTP server.
- *
- * Default to ``''`` (empty string)
- */
-'mail_smtppassword' => '',
-
-/**
- * Replaces the default mail template layout. This can be utilized if the
- * options to modify the mail texts with the theming app is not enough.
- * The class must extend  ``\OC\Mail\EMailTemplate``
- */
-'mail_template_class' => '\OC\Mail\EMailTemplate',
-
-/**
- * Email will be send by default with an HTML and a plain text body. This option
- * allows to only send plain text emails.
- */
-'mail_send_plaintext_only' => false,
-
-/**
- * This depends on ``mail_smtpmode``. Array of additional streams options that
- * will be passed to underlying Swift mailer implementation.
- * Defaults to an empty array.
- */
-'mail_smtpstreamoptions' => array(),
-
-/**
- * Which mode is used for sendmail/qmail: ``smtp`` or ``pipe``.
- *
- * For ``smtp`` the sendmail binary is started with the parameter ``-bs``:
- *   - Use the SMTP protocol on standard input and output.
- *
- * For ``pipe`` the binary is started with the parameters ``-t``:
- *   - Read message from STDIN and extract recipients.
- *
- * Defaults to ``smtp``
- */
-'mail_sendmailmode' => 'smtp',
-
-/**
- * Proxy Configurations
- */
-
-/**
- * The automatic hostname detection of Nextcloud can fail in certain reverse
- * proxy and CLI/cron situations. This option allows you to manually override
- * the automatic detection; for example ``www.example.com``, or specify the port
- * ``www.example.com:8080``.
- */
-'overwritehost' => '',
-
-/**
- * When generating URLs, Nextcloud attempts to detect whether the server is
- * accessed via ``https`` or ``http``. However, if Nextcloud is behind a proxy
- * and the proxy handles the ``https`` calls, Nextcloud would not know that
- * ``ssl`` is in use, which would result in incorrect URLs being generated.
- * Valid values are ``http`` and ``https``.
- */
-'overwriteprotocol' => '',
-
-/**
- * Nextcloud attempts to detect the webroot for generating URLs automatically.
- * For example, if ``www.example.com/nextcloud`` is the URL pointing to the
- * Nextcloud instance, the webroot is ``/nextcloud``. When proxies are in use,
- * it may be difficult for Nextcloud to detect this parameter, resulting in
- * invalid URLs.
- */
-'overwritewebroot' => '',
-
-/**
- * This option allows you to define a manual override condition as a regular
- * expression for the remote IP address. For example, defining a range of IP
- * addresses starting with ``10.0.0.`` and ending with 1 to 3:
- * ``^10\.0\.0\.[1-3]$``
- *
- * Defaults to ``''`` (empty string)
- */
-'overwritecondaddr' => '',
-
-/**
- * Use this configuration parameter to specify the base URL for any URLs which
- * are generated within Nextcloud using any kind of command line tools (cron or
- * occ). The value should contain the full base URL:
- * ``https://www.example.com/nextcloud``
- *
- * Defaults to ``''`` (empty string)
- */
-'overwrite.cli.url' => '',
-
-/**
- * To have clean URLs without `/index.php` this parameter needs to be configured.
- *
- * This parameter will be written as "RewriteBase" on update and installation of
- * Nextcloud to your `.htaccess` file. While this value is often simply the URL
- * path of the Nextcloud installation it cannot be set automatically properly in
- * every scenario and needs thus some manual configuration.
- *
- * In a standard Apache setup this usually equals the folder that Nextcloud is
- * accessible at. So if Nextcloud is accessible via "https://mycloud.org/nextcloud"
- * the correct value would most likely be "/nextcloud". If Nextcloud is running
- * under "https://mycloud.org/" then it would be "/".
- *
- * Note that the above rule is not valid in every case, as there are some rare setup
- * cases where this may not apply. However, to avoid any update problems this
- * configuration value is explicitly opt-in.
- *
- * After setting this value run `occ maintenance:update:htaccess`. Now, when the
- * following conditions are met Nextcloud URLs won't contain `index.php`:
- *
- * - `mod_rewrite` is installed
- * - `mod_env` is installed
- *
- * Defaults to ``''`` (empty string)
- */
-'htaccess.RewriteBase' => '/',
-
-/**
- * For server setups, that don't have `mod_env` enabled or restricted (e.g. suEXEC)
- * this parameter has to be set to true and will assume mod_rewrite.
- *
- * Please check, if `mod_rewrite` is active and functional before setting this
- * parameter and you updated your .htaccess with `occ maintenance:update:htaccess`.
- * Otherwise your nextcloud installation might not be reachable anymore.
- * For example, try accessing resources by leaving out `index.php` in the URL.
- */
-'htaccess.IgnoreFrontController' => false,
-
-/**
- * The URL of your proxy server, for example ``proxy.example.com:8081``.
- *
- * Defaults to ``''`` (empty string)
- */
-'proxy' => '',
-
-/**
- * The optional authentication for the proxy to use to connect to the internet.
- * The format is: ``username:password``.
- *
- * Defaults to ``''`` (empty string)
- */
-'proxyuserpwd' => '',
-
-
-/**
- * Deleted Items (trash bin)
- *
- * These parameters control the Deleted files app.
- */
-
-/**
- * If the trash bin app is enabled (default), this setting defines the policy
- * for when files and folders in the trash bin will be permanently deleted.
- * The app allows for two settings, a minimum time for trash bin retention,
- * and a maximum time for trash bin retention.
- * Minimum time is the number of days a file will be kept, after which it
- * may be deleted. Maximum time is the number of days at which it is guaranteed
- * to be deleted.
- * Both minimum and maximum times can be set together to explicitly define
- * file and folder deletion. For migration purposes, this setting is installed
- * initially set to "auto", which is equivalent to the default setting in
- * Nextcloud.
- *
- * Available values:
- *
- * * ``auto``
- *     default setting. keeps files and folders in the trash bin for 30 days
- *     and automatically deletes anytime after that if space is needed (note:
- *     files may not be deleted if space is not needed).
- * * ``D, auto``
- *     keeps files and folders in the trash bin for D+ days, delete anytime if
- *     space needed (note: files may not be deleted if space is not needed)
- * * ``auto, D``
- *     delete all files in the trash bin that are older than D days
- *     automatically, delete other files anytime if space needed
- * * ``D1, D2``
- *     keep files and folders in the trash bin for at least D1 days and
- *     delete when exceeds D2 days
- * * ``disabled``
- *     trash bin auto clean disabled, files and folders will be kept forever
- *
- * Defaults to ``auto``
- */
-'trashbin_retention_obligation' => 'auto',
-
-
-/**
- * File versions
- *
- * These parameters control the Versions app.
- */
-
-/**
- * If the versions app is enabled (default), this setting defines the policy
- * for when versions will be permanently deleted.
- * The app allows for two settings, a minimum time for version retention,
- * and a maximum time for version retention.
- * Minimum time is the number of days a version will be kept, after which it
- * may be deleted. Maximum time is the number of days at which it is guaranteed
- * to be deleted.
- * Both minimum and maximum times can be set together to explicitly define
- * version deletion. For migration purposes, this setting is installed
- * initially set to "auto", which is equivalent to the default setting in
- * Nextcloud.
- *
- * Available values:
- *
- * * ``auto``
- *     default setting. Automatically expire versions according to expire
- *     rules. Please refer to :doc:`../configuration_files/file_versioning` for
- *     more information.
- * * ``D, auto``
- *     keep versions at least for D days, apply expire rules to all versions
- *     that are older than D days
- * * ``auto, D``
- *     delete all versions that are older than D days automatically, delete
- *     other versions according to expire rules
- * * ``D1, D2``
- *     keep versions for at least D1 days and delete when exceeds D2 days
- * * ``disabled``
- *     versions auto clean disabled, versions will be kept forever
- *
- * Defaults to ``auto``
- */
-'versions_retention_obligation' => 'auto',
-
-/**
- * Nextcloud Verifications
- *
- * Nextcloud performs several verification checks. There are two options,
- * ``true`` and ``false``.
- */
-
-/**
- * Checks an app before install whether it uses private APIs instead of the
- * proper public APIs. If this is set to true it will only allow to install or
- * enable apps that pass this check.
- *
- * Defaults to ``false``
- */
-'appcodechecker' => true,
-
-/**
- * Check if Nextcloud is up-to-date and shows a notification if a new version is
- * available.
- *
- * Defaults to ``true``
- */
-'updatechecker' => true,
-
-/**
- * URL that Nextcloud should use to look for updates
- *
- * Defaults to ``https://updates.nextcloud.com/updater_server/``
- */
-'updater.server.url' => 'https://updates.nextcloud.com/updater_server/',
-
-/**
- * The channel that Nextcloud should use to look for updates
- *
- * Supported values:
- *   - ``daily``
- *   - ``beta``
- *   - ``stable``
- */
-'updater.release.channel' => 'stable',
-
-/**
- * Is Nextcloud connected to the Internet or running in a closed network?
- *
- * Defaults to ``true``
- */
-'has_internet_connection' => true,
-
-/**
- * Which domains to request to determine the availability of an Internet
- * connection. If none of these hosts are reachable, the administration panel
- * will show a warning. Set to an empty list to not do any such checks (warning
- * will still be shown).
- *
- * Defaults to the following domains:
- *
- *  - www.nextcloud.com
- *  - www.startpage.com
- *  - www.eff.org
- *  - www.edri.org
- */
-'connectivity_check_domains' => array(
-	'www.nextcloud.com',
-	'www.startpage.com',
-	'www.eff.org',
-	'www.edri.org'
-),
-
-/**
- * Allows Nextcloud to verify a working .well-known URL redirects. This is done
- * by attempting to make a request from JS to
- * https://your-domain.com/.well-known/caldav/
- *
- * Defaults to ``true``
- */
-'check_for_working_wellknown_setup' => true,
-
-/**
- * This is a crucial security check on Apache servers that should always be set
- * to ``true``. This verifies that the ``.htaccess`` file is writable and works.
- * If it is not, then any options controlled by ``.htaccess``, such as large
- * file uploads, will not work. It also runs checks on the ``data/`` directory,
- * which verifies that it can't be accessed directly through the Web server.
- *
- * Defaults to ``true``
- */
-'check_for_working_htaccess' => true,
-
-/**
- * In rare setups (e.g. on Openshift or docker on windows) the permissions check
- * might block the installation while the underlying system offers no means to
- * "correct" the permissions. In this case, set the value to false.
- *
- * In regular cases, if issues with permissions are encountered they should be
- * adjusted accordingly. Changing the flag is discouraged.
- *
- * Defaults to ``true``
- */
-'check_data_directory_permissions' => true,
-
-/**
- * In certain environments it is desired to have a read-only configuration file.
- * When this switch is set to ``true`` Nextcloud will not verify whether the
- * configuration is writable. However, it will not be possible to configure
- * all options via the Web interface. Furthermore, when updating Nextcloud
- * it is required to make the configuration file writable again for the update
- * process.
- *
- * Defaults to ``false``
- */
-'config_is_read_only' => false,
-
-/**
- * Logging
- */
-
-/**
- * This parameter determines where the Nextcloud logs are sent.
- * ``file``: the logs are written to file ``nextcloud.log`` in the default
- * Nextcloud data directory. The log file can be changed with parameter
- * ``logfile``.
- * ``syslog``: the logs are sent to the system log. This requires a syslog daemon
- * to be active.
- * ``errorlog``: the logs are sent to the PHP ``error_log`` function.
- * ``systemd``: the logs are sent to the Systemd journal. This requires a system
- * that runs Systemd and the Systemd journal. The PHP extension ``systemd``
- * must be installed and active.
- *
- * Defaults to ``file``
- */
-'log_type' => 'file',
-
-/**
- * Name of the file to which the Nextcloud logs are written if parameter
- * ``log_type`` is set to ``file``.
- *
- * Defaults to ``[datadirectory]/nextcloud.log``
- */
-'logfile' => '/var/log/nextcloud.log',
-
-/**
- * Log file mode for the Nextcloud loggin type in octal notation.
- *
- * Defaults to 0640 (writeable by user, readable by group).
- */
-'logfilemode' => 0640,
-
-/**
- * Loglevel to start logging at. Valid values are: 0 = Debug, 1 = Info, 2 =
- * Warning, 3 = Error, and 4 = Fatal. The default value is Warning.
- *
- * Defaults to ``2``
- */
-'loglevel' => 2,
-
-/**
- * If you maintain different instances and aggregate the logs, you may want
- * to distinguish between them. ``syslog_tag`` can be set per instance
- * with a unique id. Only available if ``log_type`` is set to ``syslog`` or
- * ``systemd``.
- *
- * The default value is ``Nextcloud``.
- */
-'syslog_tag' => 'Nextcloud',
-
-/**
- * Log condition for log level increase based on conditions. Once one of these
- * conditions is met, the required log level is set to debug. This allows to
- * debug specific requests, users or apps
- *
- * Supported conditions:
- *  - ``shared_secret``: if a request parameter with the name `log_secret` is set to
- *                this value the condition is met
- *  - ``users``:  if the current request is done by one of the specified users,
- *                this condition is met
- *  - ``apps``:   if the log message is invoked by one of the specified apps,
- *                this condition is met
- *
- * Defaults to an empty array.
- */
-'log.condition' => [
-	'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
-	'users' => ['sample-user'],
-	'apps' => ['files'],
-],
-
-/**
- * This uses PHP.date formatting; see http://php.net/manual/en/function.date.php
- *
- * Defaults to ISO 8601 ``2005-08-15T15:52:01+00:00`` - see \DateTime::ATOM
- * (https://secure.php.net/manual/en/class.datetime.php#datetime.constants.atom)
- */
-'logdateformat' => 'F d, Y H:i:s',
-
-/**
- * The timezone for logfiles. You may change this; see
- * http://php.net/manual/en/timezones.php
- *
- * Defaults to ``UTC``
- */
-'logtimezone' => 'Europe/Berlin',
-
-/**
- * Append all database queries and parameters to the log file. Use this only for
- * debugging, as your logfile will become huge.
- */
-'log_query' => false,
-
-/**
- * Enables log rotation and limits the total size of logfiles. The default is 0,
- * or no rotation. Specify a size in bytes, for example 104857600 (100 megabytes
- * = 100 * 1024 * 1024 bytes). A new logfile is created with a new name when the
- * old logfile reaches your limit. If a rotated log file is already present, it
- * will be overwritten.
- *
- * Defaults to 100 MB
- */
-'log_rotate_size' => 100 * 1024 * 1024,
-
-
-/**
- * Alternate Code Locations
- *
- * Some of the Nextcloud code may be stored in alternate locations.
- */
-
-/**
- * This section is for configuring the download links for Nextcloud clients, as
- * seen in the first-run wizard and on Personal pages.
- *
- * Defaults to:
- *  - Desktop client: ``https://nextcloud.com/install/#install-clients``
- *  - Android client: ``https://play.google.com/store/apps/details?id=com.nextcloud.client``
- *  - iOS client: ``https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8``
- *  - iOS client app id: ``1125420102``
- */
-'customclient_desktop' =>
-	'https://nextcloud.com/install/#install-clients',
-'customclient_android' =>
-	'https://play.google.com/store/apps/details?id=com.nextcloud.client',
-'customclient_ios' =>
-	'https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8',
-'customclient_ios_appid' =>
-		'1125420102',
-/**
- * Apps
- *
- * Options for the Apps folder, Apps store, and App code checker.
- */
-
-/**
- * When enabled, admins may install apps from the Nextcloud app store.
- *
- * Defaults to ``true``
- */
-'appstoreenabled' => true,
-
-/**
- * Use the ``apps_paths`` parameter to set the location of the Apps directory,
- * which should be scanned for available apps, and where user-specific apps
- * should be installed from the Apps store. The ``path`` defines the absolute
- * file system path to the app folder. The key ``url`` defines the HTTP Web path
- * to that folder, starting from the Nextcloud webroot. The key ``writable``
- * indicates if a Web server can write files to that folder.
- */
-'apps_paths' => array(
-	array(
-		'path'=> '/var/www/nextcloud/apps',
-		'url' => '/apps',
-		'writable' => true,
-	),
-),
-
-/**
- * @see appcodechecker
- */
-
-/**
- * Previews
- *
- * Nextcloud supports previews of image files, the covers of MP3 files, and text
- * files. These options control enabling and disabling previews, and thumbnail
- * size.
- */
-
-/**
- * By default, Nextcloud can generate previews for the following filetypes:
- *
- * - Image files
- * - Covers of MP3 files
- * - Text documents
- *
- * Valid values are ``true``, to enable previews, or
- * ``false``, to disable previews
- *
- * Defaults to ``true``
- */
-'enable_previews' => true,
-/**
- * The maximum width, in pixels, of a preview. A value of ``null`` means there
- * is no limit.
- *
- * Defaults to ``4096``
- */
-'preview_max_x' => 4096,
-/**
- * The maximum height, in pixels, of a preview. A value of ``null`` means there
- * is no limit.
- *
- * Defaults to ``4096``
- */
-'preview_max_y' => 4096,
-
-/**
- * max file size for generating image previews with imagegd (default behavior)
- * If the image is bigger, it'll try other preview generators, but will most
- * likely show the default mimetype icon. Set to -1 for no limit.
- *
- * Defaults to ``50`` megabytes
- */
-'preview_max_filesize_image' => 50,
-
-/**
- * custom path for LibreOffice/OpenOffice binary
- *
- *
- * Defaults to ``''`` (empty string)
- */
-'preview_libreoffice_path' => '/usr/bin/libreoffice',
-/**
- * Use this if LibreOffice/OpenOffice requires additional arguments.
- *
- * Defaults to ``''`` (empty string)
- */
-'preview_office_cl_parameters' =>
-	' --headless --nologo --nofirststartwizard --invisible --norestore '.
-	'--convert-to png --outdir ',
-
-/**
- * Only register providers that have been explicitly enabled
- *
- * The following providers are disabled by default due to performance or privacy
- * concerns:
- *
- *  - OC\Preview\Illustrator
- *  - OC\Preview\Movie
- *  - OC\Preview\MSOffice2003
- *  - OC\Preview\MSOffice2007
- *  - OC\Preview\MSOfficeDoc
- *  - OC\Preview\OpenDocument
- *  - OC\Preview\PDF
- *  - OC\Preview\Photoshop
- *  - OC\Preview\Postscript
- *  - OC\Preview\StarOffice
- *  - OC\Preview\SVG
- *  - OC\Preview\TIFF
- *  - OC\Preview\Font
- *
- * The following providers are not available in Microsoft Windows:
- *
- *  - OC\Preview\Movie
- *  - OC\Preview\MSOfficeDoc
- *  - OC\Preview\MSOffice2003
- *  - OC\Preview\MSOffice2007
- *  - OC\Preview\OpenDocument
- *  - OC\Preview\StarOffice
- *
- * Defaults to the following providers:
- *
- *  - OC\Preview\BMP
- *  - OC\Preview\GIF
- *  - OC\Preview\HEIC
- *  - OC\Preview\JPEG
- *  - OC\Preview\MarkDown
- *  - OC\Preview\MP3
- *  - OC\Preview\PNG
- *  - OC\Preview\TXT
- *  - OC\Preview\XBitmap
- */
-'enabledPreviewProviders' => array(
-	'OC\Preview\PNG',
-	'OC\Preview\JPEG',
-	'OC\Preview\GIF',
-	'OC\Preview\HEIC',
-	'OC\Preview\BMP',
-	'OC\Preview\XBitmap',
-	'OC\Preview\MP3',
-	'OC\Preview\TXT',
-	'OC\Preview\MarkDown'
-),
-
-/**
- * LDAP
- *
- * Global settings used by LDAP User and Group Backend
- */
-
-/**
- * defines the interval in minutes for the background job that checks user
- * existence and marks them as ready to be cleaned up. The number is always
- * minutes. Setting it to 0 disables the feature.
- * See command line (occ) methods ``ldap:show-remnants`` and ``user:delete``
- *
- * Defaults to ``51`` minutes
- */
-'ldapUserCleanupInterval' => 51,
-
-/**
- * Sort groups in the user settings by name instead of the user count
- *
- * By enabling this the user count beside the group name is disabled as well.
- */
-'sort_groups_by_name' => false,
-
-/**
- * Comments
- *
- * Global settings for the Comments infrastructure
- */
-
-/**
- * Replaces the default Comments Manager Factory. This can be utilized if an
- * own or 3rdParty CommentsManager should be used that – for instance – uses the
- * filesystem instead of the database to keep the comments.
- *
- * Defaults to ``\OC\Comments\ManagerFactory``
- */
-'comments.managerFactory' => '\OC\Comments\ManagerFactory',
-
-/**
- * Replaces the default System Tags Manager Factory. This can be utilized if an
- * own or 3rdParty SystemTagsManager should be used that – for instance – uses the
- * filesystem instead of the database to keep the tags.
- *
- * Defaults to ``\OC\SystemTag\ManagerFactory``
- */
-'systemtags.managerFactory' => '\OC\SystemTag\ManagerFactory',
-
-/**
- * Maintenance
- *
- * These options are for halting user activity when you are performing server
- * maintenance.
- */
-
-/**
- * Enable maintenance mode to disable Nextcloud
- *
- * If you want to prevent users from logging in to Nextcloud before you start
- * doing some maintenance work, you need to set the value of the maintenance
- * parameter to true. Please keep in mind that users who are already logged-in
- * are kicked out of Nextcloud instantly.
- *
- * Defaults to ``false``
- */
-'maintenance' => false,
-
-
-/**
- * SSL
- */
-
-/**
- * Extra SSL options to be used for configuration.
-  *
- * Defaults to an empty array.
- */
-'openssl' => array(
-	'config' => '/absolute/location/of/openssl.cnf',
-),
-
-/**
- * Memory caching backend configuration
- *
- * Available cache backends:
- *
- * * ``\OC\Memcache\APCu``       APC user backend
- * * ``\OC\Memcache\ArrayCache`` In-memory array-based backend (not recommended)
- * * ``\OC\Memcache\Memcached``  Memcached backend
- * * ``\OC\Memcache\Redis``      Redis backend
- *
- * Advice on choosing between the various backends:
- *
- * * APCu should be easiest to install. Almost all distributions have packages.
- *   Use this for single user environment for all caches.
- * * Use Redis or Memcached for distributed environments.
- *   For the local cache (you can configure two) take APCu.
- */
-
-/**
- * Memory caching backend for locally stored data
- *
- * * Used for host-specific data, e.g. file paths
- *
- * Defaults to ``none``
- */
-'memcache.local' => '\OC\Memcache\APCu',
-
-/**
- * Memory caching backend for distributed data
- *
- * * Used for installation-specific data, e.g. database caching
- * * If unset, defaults to the value of memcache.local
- *
- * Defaults to ``none``
- */
-'memcache.distributed' => '\OC\Memcache\Memcached',
-
-/**
- * Connection details for redis to use for memory caching in a single server configuration.
- *
- * For enhanced security it is recommended to configure Redis
- * to require a password. See http://redis.io/topics/security
- * for more information.
- */
-'redis' => [
-	'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock'
-	'port' => 6379,
-	'timeout' => 0.0,
-	'password' => '', // Optional, if not defined no password will be used.
-	'dbindex' => 0, // Optional, if undefined SELECT will not run and will use Redis Server's default DB Index.
-],
-
-/**
- * Connection details for a Redis Cluster
- *
- * Only for use with Redis Clustering, for Sentinel-based setups use the single
- * server configuration above, and perform HA on the hostname.
- *
- * Redis Cluster support requires the php module phpredis in version 3.0.0 or
- * higher.
- *
- * Available failover modes:
- *  - \RedisCluster::FAILOVER_NONE - only send commands to master nodes (default)
- *  - \RedisCluster::FAILOVER_ERROR - failover to slaves for read commands if master is unavailable (recommended)
- *  - \RedisCluster::FAILOVER_DISTRIBUTE - randomly distribute read commands across master and slaves
- *
- * WARNING: FAILOVER_DISTRIBUTE is a not recommended setting and we strongly
- * suggest to not use it if you use Redis for file locking. Due to the way Redis
- * is synchronized it could happen, that the read for an existing lock is
- * scheduled to a slave that is not fully synchronized with the connected master
- * which then causes a FileLocked exception.
- *
- * See https://redis.io/topics/cluster-spec for details about the Redis cluster
- *
- * Authentication works with phpredis version 4.2.1+. See
- * https://github.com/phpredis/phpredis/commit/c5994f2a42b8a348af92d3acb4edff1328ad8ce1
- */
-'redis.cluster' => [
-	'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
-		'localhost:7000',
-		'localhost:7001',
-	],
-	'timeout' => 0.0,
-	'read_timeout' => 0.0,
-	'failover_mode' => \RedisCluster::FAILOVER_ERROR,
-	'password' => '', // Optional, if not defined no password will be used.
-],
-
-
-/**
- * Server details for one or more memcached servers to use for memory caching.
- */
-'memcached_servers' => array(
-	// hostname, port and optional weight. Also see:
-	// http://www.php.net/manual/en/memcached.addservers.php
-	// http://www.php.net/manual/en/memcached.addserver.php
-	array('localhost', 11211),
-	//array('other.host.local', 11211),
-),
-
-/**
- * Connection options for memcached, see http://apprize.info/php/scaling/15.html
- */
-'memcached_options' => array(
-	// Set timeouts to 50ms
-	\Memcached::OPT_CONNECT_TIMEOUT => 50,
-	\Memcached::OPT_RETRY_TIMEOUT =>   50,
-	\Memcached::OPT_SEND_TIMEOUT =>    50,
-	\Memcached::OPT_RECV_TIMEOUT =>    50,
-	\Memcached::OPT_POLL_TIMEOUT =>    50,
-
-	// Enable compression
-	\Memcached::OPT_COMPRESSION =>          true,
-
-	// Turn on consistent hashing
-	\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
-
-	// Enable Binary Protocol
-	\Memcached::OPT_BINARY_PROTOCOL =>      true,
-
-	// Binary serializer vill be enabled if the igbinary PECL module is available
-	//\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_IGBINARY,
-),
-
-
-/**
- * Location of the cache folder, defaults to ``data/$user/cache`` where
- * ``$user`` is the current user. When specified, the format will change to
- * ``$cache_path/$user`` where ``$cache_path`` is the configured cache directory
- * and ``$user`` is the user.
- *
- * Defaults to ``''`` (empty string)
- */
-'cache_path' => '',
-
-/**
- * TTL of chunks located in the cache folder before they're removed by
- * garbage collection (in seconds). Increase this value if users have
- * issues uploading very large files via the Nextcloud Client as upload isn't
- * completed within one day.
- *
- * Defaults to ``60*60*24`` (1 day)
- */
-'cache_chunk_gc_ttl' => 60*60*24,
-
-/**
- * Using Object Store with Nextcloud
- */
-
-/**
- * This example shows how to configure Nextcloud to store all files in a
- * swift object storage.
- *
- * It is important to note that Nextcloud in object store mode will expect
- * exclusive access to the object store container because it only stores the
- * binary data for each file. The metadata is currently kept in the local
- * database for performance reasons.
- *
- * WARNING: The current implementation is incompatible with any app that uses
- * direct file IO and circumvents our virtual filesystem. That includes
- * Encryption and Gallery. Gallery will store thumbnails directly in the
- * filesystem and encryption will cause severe overhead because key files need
- * to be fetched in addition to any requested file.
- *
- * One way to test is applying for a trystack account at http://trystack.org/
- */
-'objectstore' => [
-	'class' => 'OC\\Files\\ObjectStore\\Swift',
-	'arguments' => [
-		// trystack will use your facebook id as the user name
-		'username' => 'facebook100000123456789',
-		// in the trystack dashboard go to user -> settings -> API Password to
-		// generate a password
-		'password' => 'Secr3tPaSSWoRdt7',
-		// must already exist in the objectstore, name can be different
-		'container' => 'nextcloud',
-		// prefix to prepend to the fileid, default is 'oid:urn:'
-		'objectPrefix' => 'oid:urn:',
-		// create the container if it does not exist. default is false
-		'autocreate' => true,
-		// required, dev-/trystack defaults to 'RegionOne'
-		'region' => 'RegionOne',
-		// The Identity / Keystone endpoint
-		'url' => 'http://8.21.28.222:5000/v2.0',
-		// required on dev-/trystack
-		'tenantName' => 'facebook100000123456789',
-		// dev-/trystack uses swift by default, the lib defaults to 'cloudFiles'
-		// if omitted
-		'serviceName' => 'swift',
-		// The Interface / url Type, optional
-		'urlType' => 'internal'
-	],
-],
-
-/**
- * To use swift V3
- */
-'objectstore' => [
-	'class' => 'OC\\Files\\ObjectStore\\Swift',
-	'arguments' => [
-		'autocreate' => true,
-		'user' => [
-			'name' => 'swift',
-			'password' => 'swift',
-			'domain' => [
-				'name' => 'default',
-			],
-		],
-		'scope' => [
-			'project' => [
-				'name' => 'service',
-				'domain' => [
-					'name' => 'default',
-				],
-			],
-		],
-		'tenantName' => 'service',
-		'serviceName' => 'swift',
-		'region' => 'regionOne',
-		'url' => 'http://yourswifthost:5000/v3',
-		'bucket' => 'nextcloud',
-	],
-],
-
-
-/**
- * Sharing
- *
- * Global settings for Sharing
- */
-
-/**
- * Replaces the default Share Provider Factory. This can be utilized if
- * own or 3rdParty Share Providers are used that – for instance – use the
- * filesystem instead of the database to keep the share information.
- *
- * Defaults to ``\OC\Share20\ProviderFactory``
- */
-'sharing.managerFactory' => '\OC\Share20\ProviderFactory',
-
-/**
- * Define max number of results returned by the user search for auto-completion
- * Default is unlimited (value set to 0).
- */
-'sharing.maxAutocompleteResults' => 0,
-
-/**
- * Define the minimum length of the search string before we start auto-completion
- * Default is no limit (value set to 0)
- */
-'sharing.minSearchStringLength' => 0,
-
-/**
- * All other configuration options
- */
-
-/**
- * Additional driver options for the database connection, eg. to enable SSL
- * encryption in MySQL or specify a custom wait timeout on a cheap hoster.
- */
-'dbdriveroptions' => array(
-	PDO::MYSQL_ATTR_SSL_CA => '/file/path/to/ca_cert.pem',
-	PDO::MYSQL_ATTR_INIT_COMMAND => 'SET wait_timeout = 28800'
-),
-
-/**
- * sqlite3 journal mode can be specified using this configuration parameter -
- * can be 'WAL' or 'DELETE' see for more details https://www.sqlite.org/wal.html
- */
-'sqlite.journal_mode' => 'DELETE',
-
-/**
- * During setup, if requirements are met (see below), this setting is set to true
- * and MySQL can handle 4 byte characters instead of 3 byte characters.
- *
- * If you want to convert an existing 3-byte setup into a 4-byte setup please
- * set the parameters in MySQL as mentioned below and run the migration command:
- * ./occ db:convert-mysql-charset
- * The config setting will be set automatically after a successful run.
- *
- * Consult the documentation for more details.
- *
- * MySQL requires a special setup for longer indexes (> 767 bytes) which are
- * needed:
- *
- * [mysqld]
- * innodb_large_prefix=ON
- * innodb_file_format=Barracuda
- * innodb_file_per_table=ON
- *
- * Tables will be created with
- *  * character set: utf8mb4
- *  * collation:     utf8mb4_bin
- *  * row_format:    compressed
- *
- * See:
- * https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb4.html
- * https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix
- * https://mariadb.com/kb/en/mariadb/xtradbinnodb-server-system-variables/#innodb_large_prefix
- * http://www.tocker.ca/2013/10/31/benchmarking-innodb-page-compression-performance.html
- * http://mechanics.flite.com/blog/2014/07/29/using-innodb-large-prefix-to-avoid-error-1071/
- */
-'mysql.utf8mb4' => false,
-
-/**
- * Database types that are supported for installation.
- *
- * Available:
- * 	- sqlite (SQLite3)
- * 	- mysql (MySQL)
- * 	- pgsql (PostgreSQL)
- * 	- oci (Oracle)
- *
- * Defaults to the following databases:
- *  - sqlite (SQLite3)
- *  - mysql (MySQL)
- *  - pgsql (PostgreSQL)
- */
-'supportedDatabases' => array(
-	'sqlite',
-	'mysql',
-	'pgsql',
-	'oci',
-),
-
-/**
- * Override where Nextcloud stores temporary files. Useful in situations where
- * the system temporary directory is on a limited space ramdisk or is otherwise
- * restricted, or if external storages which do not support streaming are in
- * use.
- *
- * The Web server user must have write access to this directory.
- */
-'tempdirectory' => '/tmp/nextcloudtemp',
-
-/**
- * The hashing cost used by hashes generated by Nextcloud
- * Using a higher value requires more time and CPU power to calculate the hashes
- */
-'hashingCost' => 10,
-
-/**
- * Blacklist a specific file or files and disallow the upload of files
- * with this name. ``.htaccess`` is blocked by default.
- * WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING.
- *
- * Defaults to ``array('.htaccess')``
- */
-'blacklisted_files' => array('.htaccess'),
-
-/**
- * Define a default folder for shared files and folders other than root.
- * Changes to this value will only have effect on new shares.
- *
- * Defaults to ``/``
- */
-'share_folder' => '/',
-
-/**
- * If you are applying a theme to Nextcloud, enter the name of the theme here.
- * The default location for themes is ``nextcloud/themes/``.
- *
- * Defaults to the theming app which is shipped since Nextcloud 9
- */
-'theme' => '',
-
-/**
- * The default cipher for encrypting files. Currently AES-128-CFB and
- * AES-256-CFB are supported.
- */
-'cipher' => 'AES-256-CFB',
-
-/**
- * The minimum Nextcloud desktop client version that will be allowed to sync with
- * this server instance. All connections made from earlier clients will be denied
- * by the server. Defaults to the minimum officially supported Nextcloud desktop
- * clientversion at the time of release of this server version.
- *
- * When changing this, note that older unsupported versions of the Nextcloud desktop
- * client may not function as expected, and could lead to permanent data loss for
- * clients or other unexpected results.
- *
- * Defaults to ``2.0.0``
- */
-'minimum.supported.desktop.version' => '2.0.0',
-
-/**
- * EXPERIMENTAL: option whether to include external storage in quota
- * calculation, defaults to false.
- *
- * Defaults to ``false``
- */
-'quota_include_external_storage' => false,
-
-/**
- * When an external storage is unavailable for some reasons, it will be flagged
- * as such for 10 minutes. When the trigger is a failed authentication attempt
- * the delay is higher and can be controlled with this option. The motivation
- * is to make account lock outs at Active Directories (and compatible) more
- * unlikely.
- *
- * Defaults to ``1800`` (seconds)
- */
-'external_storage.auth_availability_delay' => 1800,
-
-/**
- * Specifies how often the local filesystem (the Nextcloud data/ directory, and
- * NFS mounts in data/) is checked for changes made outside Nextcloud. This
- * does not apply to external storages.
- *
- * 0 -> Never check the filesystem for outside changes, provides a performance
- * increase when it's certain that no changes are made directly to the
- * filesystem
- *
- * 1 -> Check each file or folder at most once per request, recommended for
- * general use if outside changes might happen.
- *
- * Defaults to ``0``
- */
-'filesystem_check_changes' => 0,
-
-/**
- * By default Nextcloud will store the part files created during upload in the
- * same storage as the upload target. Setting this to false will store the part
- * files in the root of the users folder which might be required to work with certain
- * external storage setups that have limited rename capabilities.
- *
- * Defaults to ``true``
- */
-'part_file_in_storage' => true,
-
-/**
- * Where ``mount.json`` file should be stored, defaults to ``data/mount.json``
- * in the Nextcloud directory.
- *
- * Defaults to ``data/mount.json`` in the Nextcloud directory.
- */
-'mount_file' => '/var/www/nextcloud/data/mount.json',
-
-/**
- * When ``true``, prevent Nextcloud from changing the cache due to changes in
- * the filesystem for all storage.
- *
- * Defaults to ``false``
- */
-'filesystem_cache_readonly' => false,
-
-/**
- * Secret used by Nextcloud for various purposes, e.g. to encrypt data. If you
- * lose this string there will be data corruption.
- */
-'secret' => '',
-
-/**
- * List of trusted proxy servers
- *
- * You may set this to an array containing a combination of
- * - IPv4 addresses, e.g. `192.168.2.123`
- * - IPv4 ranges in CIDR notation, e.g. `192.168.2.0/24`
- * - IPv6 addresses, e.g. `fd9e:21a7:a92c:2323::1`
- *
- * _(CIDR notation for IPv6 is currently work in progress and thus not
- * available as of yet)_
- *
- * When an incoming request's `REMOTE_ADDR` matches any of the IP addresses
- * specified here, it is assumed to be a proxy instead of a client. Thus, the
- * client IP will be read from the HTTP header specified in
- * `forwarded_for_headers` instead of from `REMOTE_ADDR`.
- *
- * So if you configure `trusted_proxies`, also consider setting
- * `forwarded_for_headers` which otherwise defaults to `HTTP_X_FORWARDED_FOR`
- * (the `X-Forwarded-For` header).
- *
- * Defaults to an empty array.
- */
-'trusted_proxies' => array('203.0.113.45', '198.51.100.128', '192.168.2.0/24'),
-
-/**
- * Headers that should be trusted as client IP address in combination with
- * `trusted_proxies`. If the HTTP header looks like 'X-Forwarded-For', then use
- * 'HTTP_X_FORWARDED_FOR' here.
- *
- * If set incorrectly, a client can spoof their IP address as visible to
- * Nextcloud, bypassing access controls and making logs useless!
- *
- * Defaults to ``'HTTP_X_FORWARDED_FOR'``
- */
-'forwarded_for_headers' => array('HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR'),
-
-/**
- * max file size for animating gifs on public-sharing-site.
- * If the gif is bigger, it'll show a static preview
- *
- * Value represents the maximum filesize in megabytes. Set to ``-1`` for
- * no limit.
- *
- * Defaults to ``10`` megabytes
- */
-'max_filesize_animated_gifs_public_sharing' => 10,
-
-
-/**
- * Enables transactional file locking.
- * This is enabled by default.
- *
- * Prevents concurrent processes from accessing the same files
- * at the same time. Can help prevent side effects that would
- * be caused by concurrent operations. Mainly relevant for
- * very large installations with many users working with
- * shared files.
- *
- * Defaults to ``true``
- */
-'filelocking.enabled' => true,
-
-/**
- * Set the lock's time-to-live in seconds.
- *
- * Any lock older than this will be automatically cleaned up.
- *
- * Defaults to ``60*60`` seconds (1 hour) or the php
- *             max_execution_time, whichever is higher.
- */
-'filelocking.ttl' => 60*60,
-
-/**
- * Memory caching backend for file locking
- *
- * Because most memcache backends can clean values without warning using redis
- * is highly recommended to *avoid data loss*.
- *
- * Defaults to ``none``
- */
-'memcache.locking' => '\\OC\\Memcache\\Redis',
-
-/**
- * Enable locking debug logging
- *
- * Note that this can lead to a very large volume of log items being written which can lead
- * to performance degradation and large log files on busy instance.
- *
- * Thus enabling this in production for longer periods of time is not recommended
- * or should be used together with the ``log.condition`` setting.
- */
-'filelocking.debug' => false,
-
-/**
- * Disable the web based updater
- */
-'upgrade.disable-web' => false,
-
-/**
- * Set this Nextcloud instance to debugging mode
- *
- * Only enable this for local development and not in production environments
- * This will disable the minifier and outputs some additional debug information
- *
- * Defaults to ``false``
- */
-'debug' => false,
-
-/**
- * Sets the data-fingerprint of the current data served
- *
- * This is a property used by the clients to find out if a backup has been
- * restored on the server. Once a backup is restored run
- * ./occ maintenance:data-fingerprint
- * To set this to a new value.
- *
- * Updating/Deleting this value can make connected clients stall until
- * the user has resolved conflicts.
- *
- * Defaults to ``''`` (empty string)
- */
-'data-fingerprint' => '',
-
-/**
- * This entry is just here to show a warning in case somebody copied the sample
- * configuration. DO NOT ADD THIS SWITCH TO YOUR CONFIGURATION!
- *
- * If you, brave person, have read until here be aware that you should not
- * modify *ANY* settings in this file without reading the documentation.
- */
-'copied_sample_config' => true,
-
-/**
- * use a custom lookup server to publish user data
- */
-'lookup_server' => 'https://lookup.nextcloud.com',
-
-/**
- * set to true if the server is used in a setup based on Nextcloud's Global Scale architecture
- */
-'gs.enabled' => false,
-
-/**
- * by default federation is only used internally in a Global Scale setup
- * If you want to allow federation outside of your environment set it to 'global'
- */
-'gs.federation' => 'internal',
-
-/**
- * List of incompatible user agents opted out from Same Site Cookie Protection.
- * Some user agents are notorious and don't really properly follow HTTP
- * specifications. For those, have an opt-out.
- *
- * WARNING: only use this if you know what you are doing
- */
-'csrf.optout' => array(
-	'/^WebDAVFS/', // OS X Finder
-	'/^Microsoft-WebDAV-MiniRedir/', // Windows webdav drive
-),
-
-/**
- * By default there is on public pages a link shown that allows users to
- * learn about the "simple sign up" - see https://nextcloud.com/signup/
- *
- * If this is set to "false" it will not show the link.
- */
-'simpleSignUpLink.shown' => true,
-
-/**
- * By default autocompletion is enabled for the login form on Nextcloud's login page.
- * While this is enabled, browsers are allowed to "remember" login names and such.
- * Some companies require it to be disabled to comply with their security policy.
- *
- * Simply set this property to "false", if you want to turn this feature off.
- */
-
-'login_form_autocomplete' => true,
-);

+ 0 - 13
compose/karmen/config/redis.config.php

@@ -1,13 +0,0 @@
-<?php
-if (getenv('REDIS_HOST')) {
-  $CONFIG = array (
-    'memcache.distributed' => '\OC\Memcache\Redis',
-    'memcache.locking' => '\OC\Memcache\Redis',
-    'redis' => array(
-      'host' => getenv('REDIS_HOST'),
-      'port' => getenv('REDIS_HOST_PORT') ?: 6379,
-      'password' => getenv('REDIS_HOST_PASSWORD'),
-    ),
-  );
-}
-

+ 0 - 15
compose/karmen/config/smtp.config.php

@@ -1,15 +0,0 @@
-<?php
-if (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {
-  $CONFIG = array (
-    'mail_smtpmode' => 'smtp',
-    'mail_smtphost' => getenv('SMTP_HOST'),
-    'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25),
-    'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '',
-    'mail_smtpauth' => getenv('SMTP_NAME') && getenv('SMTP_PASSWORD'),
-    'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN',
-    'mail_smtpname' => getenv('SMTP_NAME') ?: '',
-    'mail_smtppassword' => getenv('SMTP_PASSWORD') ?: '',
-    'mail_from_address' => getenv('MAIL_FROM_ADDRESS'),
-    'mail_domain' => getenv('MAIL_DOMAIN'),
-  );
-}

+ 0 - 20
compose/karmen/data/.htaccess

@@ -1,20 +0,0 @@
-<<<<<<< HEAD
-# Generated by Nextcloud on 2019-10-04 06:18:10
-=======
-# Generated by Nextcloud on 2019-10-04 08:27:18
->>>>>>> 13c5b9ffd8316b3dbdad43702c234af8cbea8936
-# line below if for Apache 2.4
-<ifModule mod_authz_core.c>
-Require all denied
-</ifModule>
-
-# line below if for Apache 2.2
-<ifModule !mod_authz_core.c>
-deny from all
-Satisfy All
-</ifModule>
-
-# section for Apache 2.2 and 2.4
-<ifModule mod_autoindex.c>
-IndexIgnore *
-</ifModule>

+ 0 - 0
compose/karmen/data/.ocdata


BIN
compose/karmen/data/admin/files/Documents/About.odt


+ 0 - 10
compose/karmen/data/admin/files/Documents/About.txt

@@ -1,10 +0,0 @@
-About Nextcloud
-
-Welcome to Nextcloud, your self-hosted file sync and share solution.
-Nextcloud is the open source file sync and share software for everyone from individuals to large enterprises and service providers. Nextcloud provides a safe, secure and compliant file sync and share solution on servers you control.
-With Nextcloud you can share one or more folders on your PC, and sync them with your Nextcloud server. Place files in your local shared directories, and those files are immediately synced to the server, and then to other PCs via the desktop client. Not near a desktop client? No problem, simply log in with the web client and manage your files there. The Android and iOS mobile apps allow you to browse, download and upload photos and videos.
-Whether using a mobile device, a workstation, or a web client, Nextcloud provides the ability to put the right files in the right hands at the right time on any device in one simple-to-use, secure, private and controlled solution.
-
-
-All example pictures & music are licensed under Creative Commons Attribution.
-

BIN
compose/karmen/data/admin/files/Documents/Nextcloud Flyer.pdf


BIN
compose/karmen/data/admin/files/Documents/elenco_docenti.pdf


+ 0 - 16
compose/karmen/data/admin/files/Karmen/list/list.tpl.md

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2020/2021
-
-## Elenco docenti con classi
-
-Docente|Classe/i
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

BIN
compose/karmen/data/admin/files/Karmen/list/reference.odt


BIN
compose/karmen/data/admin/files/Nextcloud Manual.pdf


BIN
compose/karmen/data/admin/files/Nextcloud intro.mp4


BIN
compose/karmen/data/admin/files/Nextcloud.mp4


BIN
compose/karmen/data/admin/files/Nextcloud.png


BIN
compose/karmen/data/admin/files/Photos/Coast.jpg


BIN
compose/karmen/data/admin/files/Photos/Hummingbird.jpg


BIN
compose/karmen/data/admin/files/Photos/Nextcloud Community.jpg


BIN
compose/karmen/data/admin/files/Photos/Nut.jpg


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570114545


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115314


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115397


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570115459


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116511


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116637


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570116770


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570117586


BIN
compose/karmen/data/admin/files_versions/Documents/elenco_docenti.pdf.v1570117743


+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570114087

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi a.s. 2019/2020
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115384

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi a.s. 2020/20
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115386

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi a.s. 2020/2021
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115387

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi a.s. 2020/202
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115432

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi a.s. 2020/2021
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115445

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2019/2020
-
-## Elenco docenti con classi
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

+ 0 - 16
compose/karmen/data/admin/files_versions/Karmen/list/list.tpl.md.v1570115450

@@ -1,16 +0,0 @@
-# I.S.I.S. “GIOSUE’ CARDUCCI – DANTE ALIGHIERI”
-# Liceo Classico; Liceo Linguistico; Liceo Musicale
-# Liceo delle Scienze Umane; delle Scienze Umane opzione Economico Sociale;
-# 34133 TRIESTE - Via Giustiniano, 3
-# A.S.  2020/2021
-
-## Elenco docenti con classi
-
-Docente|Classi
--------|-----------------------------
-{{range $teacher := . -}}
-{{if not $teacher.Exclude -}}
-{{$teacher.CompleteName|abbrev}}|{{$teacher.Classes|groupClasses}}
-{{end}}
-{{- end}}
-

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc216qe0mln5/appstore/apps.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570113919,"\/var\/www\/html\/apps\/files\/css\/merged.scss":1570113918,"\/var\/www\/html\/apps\/files\/css\/files.scss":1570113918,"\/var\/www\/html\/apps\/files\/css\/upload.scss":1570113918,"\/var\/www\/html\/apps\/files\/css\/mobile.scss":1570113918,"\/var\/www\/html\/apps\/files\/css\/detailsView.scss":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/css/files/37d007a56d816107ce5b52c10342db37-merged.css.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570113919,"\/var\/www\/html\/apps\/files_sharing\/css\/mergedAdditionalStyles.scss":1570113918,"\/var\/www\/html\/apps\/files_sharing\/css\/sharetabview.scss":1570113918,"\/var\/www\/html\/apps\/files_sharing\/css\/sharebreadcrumb.scss":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/css/files_sharing/37d007a56d816107ce5b52c10342db37-mergedAdditionalStyles.css.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570113919,"\/var\/www\/html\/apps\/files_texteditor\/css\/merged.scss":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/css\/DroidSansMono\/stylesheet.scss":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/css\/style.scss":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/css\/mobile.scss":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/css/files_texteditor/37d007a56d816107ce5b52c10342db37-merged.css.gzip


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css

@@ -1 +0,0 @@
-.nc-theming-main-background{background-color:#0082c9}.nc-theming-main-text{color:#fff}.nc-theming-contrast{color:#fff}.icon-file,.icon-filetype-text{background-image:url(./img/core/filetypes/text.svg?v=0)}.icon-folder,.icon-filetype-folder{background-image:url(./img/core/filetypes/folder.svg?v=0)}.icon-filetype-folder-drag-accept{background-image:url(./img/core/filetypes/folder-drag-accept.svg?v=0) !important}#header .logo,#header .logo-icon{background-image:url(http://localhost:8080/core/img/logo.svg?v=0)}#body-login,#firstrunwizard .firstrunwizard-header,#theming-preview{background-image:url(http://localhost:8080/core/img/background.jpg?v=0);background-color:#0082c9}input.primary{background-color:#0082c9;border:1px solid #0082c9;color:#fff}

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570113919,"\/var\/www\/html\/apps\/theming\/css\/theming.scss":1570113919}

BIN
compose/karmen/data/appdata_oc216qe0mln5/css/theming/37d007a56d816107ce5b52c10342db37-theming.css.gzip


+ 0 - 608
compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js

@@ -1,608 +0,0 @@
-/**
- * @copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- */
-
-(function() {
-	OCA.Activity = OCA.Activity || {};
-
-	OCA.Activity.RichObjectStringParser = {
-		avatarsEnabled: true,
-
-		_fileTemplate: '<a class="filename has-tooltip" href="{{link}}" title="{{title}}">{{name}}</a>',
-		_fileNoPathTemplate: '<a class="filename" href="{{link}}">{{name}}</a>',
-
-		_systemTagTemplate: '<strong class="systemtag">{{name}}</strong>',
-
-		_emailTemplate: '<a class="email" href="mailto:{{id}}">{{name}}</a>',
-
-		_userLocalTemplate: '<span class="avatar-name-wrapper" data-user="{{id}}"><div class="avatar" data-user="{{id}}" data-user-display-name="{{name}}"></div><strong>{{name}}</strong></span>',
-		_userRemoteTemplate: '<strong>{{name}}</strong>',
-
-		_openGraphTemplate: '{{#if link}}<a href="{{link}}">{{/if}}<div id="opengraph-{{id}}" class="opengraph">' +
-		'{{#if thumb}}<div class="opengraph-thumb" style="background-image: url(\'{{thumb}}\')"></div>{{/if}}' +
-		'<div class="opengraph-name {{#if thumb}}opengraph-with-thumb{{/if}}">{{name}}</div>' +
-		'<div class="opengraph-description {{#if thumb}}opengraph-with-thumb{{/if}}">{{description}}</div>' +
-		'<span class="opengraph-website">{{website}}</span></div>{{#if link}}</a>{{/if}}',
-
-		_unknownTemplate: '<strong>{{name}}</strong>',
-		_unknownLinkTemplate: '<a href="{{link}}">{{name}}</a>',
-
-		/**
-		 * @param {string} subject
-		 * @param {Object} parameters
-		 * @returns {string}
-		 */
-		parseMessage: function(subject, parameters) {
-			var self = this,
-				regex = /\{([a-z0-9]+)\}/gi,
-				matches = subject.match(regex);
-
-			_.each(matches, function(parameter) {
-				parameter = parameter.substring(1, parameter.length - 1);
-				var parsed = self.parseParameter(parameters[parameter]);
-
-				subject = subject.replace('{' + parameter + '}', parsed);
-			});
-
-			return subject;
-		},
-
-		/**
-		 * @param {Object} parameter
-		 * @param {string} parameter.type
-		 * @param {string} parameter.id
-		 * @param {string} parameter.name
-		 * @param {string} parameter.link
-		 */
-		parseParameter: function(parameter) {
-			switch (parameter.type) {
-				case 'file':
-					return this.parseFileParameter(parameter);
-
-				case 'systemtag':
-					if (!this.systemTagTemplate) {
-						this.systemTagTemplate = Handlebars.compile(this._systemTagTemplate);
-					}
-
-					var name = parameter.name;
-					if (parameter.visibility !== '1') {
-						name = t('activity', '{name} (invisible)', parameter);
-					} else if (parameter.assignable !== '1') {
-						name = t('activity', '{name} (restricted)', parameter);
-					}
-
-					return this.systemTagTemplate({
-						name: name
-					});
-
-				case 'email':
-					if (!this.emailTemplate) {
-						this.emailTemplate = Handlebars.compile(this._emailTemplate);
-					}
-
-					return this.emailTemplate(parameter);
-
-				case 'open-graph':
-					if (!this.openGraphTemplate) {
-						this.openGraphTemplate = Handlebars.compile(this._openGraphTemplate);
-					}
-
-					return this.openGraphTemplate(parameter);
-
-				case 'user':
-					if (_.isUndefined(parameter.server)) {
-						if (!this.userLocalTemplate) {
-							this.userLocalTemplate = Handlebars.compile(this._userLocalTemplate);
-						}
-						return this.userLocalTemplate(parameter);
-					}
-
-					if (!this.userRemoteTemplate) {
-						this.userRemoteTemplate = Handlebars.compile(this._userRemoteTemplate);
-					}
-
-					return this.userRemoteTemplate(parameter);
-
-				default:
-					if (!_.isUndefined(parameter.link)) {
-						if (!this.unknownLinkTemplate) {
-							this.unknownLinkTemplate = Handlebars.compile(this._unknownLinkTemplate);
-						}
-						return this.unknownLinkTemplate(parameter);
-					}
-
-					if (!this.unknownTemplate) {
-						this.unknownTemplate = Handlebars.compile(this._unknownTemplate);
-					}
-					return this.unknownTemplate(parameter);
-			}
-		},
-
-		/**
-		 * @param {Object} parameter
-		 * @param {string} parameter.type
-		 * @param {string} parameter.id
-		 * @param {string} parameter.name
-		 * @param {string} parameter.path
-		 * @param {string} parameter.link
-		 */
-		parseFileParameter: function(parameter) {
-			if (!this.fileTemplate) {
-				this.fileTemplate = Handlebars.compile(this._fileTemplate);
-				this.fileNoPathTemplate = Handlebars.compile(this._fileNoPathTemplate);
-			}
-			var lastSlashPosition = parameter.path.lastIndexOf('/'),
-				firstSlashPosition = parameter.path.indexOf('/');
-			parameter.path = parameter.path.substring(firstSlashPosition === 0 ? 1 : 0, lastSlashPosition);
-
-			if (!parameter.link) {
-				parameter.link = OC.generateUrl('/f/{fileId}', {fileId: parameter.id})
-			}
-
-			if (parameter.path === '' || parameter.path === '/') {
-				return this.fileNoPathTemplate(parameter);
-			}
-			return this.fileTemplate(_.extend(parameter, {
-				title: parameter.path.length === 0 ? '' : t('activity', 'in {path}', parameter)
-			}));
-		}
-	};
-
-})();
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	/**
-	 * @class OCA.Activity.ActivityModel
-	 * @classdesc
-	 *
-	 * Displays activity information for a given file
-	 *
-	 */
-	var ActivityModel = OC.Backbone.Model.extend(/** @lends OCA.Activity.ActivityModel.prototype */{
-		/**
-		 *
-		 * @returns int UNIX milliseconds timestamp
-		 */
-		getUnixMilliseconds: function() {
-			if (_.isUndefined(this.unixMilliseconds)) {
-				this.unixMilliseconds = moment(this.get('datetime')).valueOf();
-			}
-			return this.unixMilliseconds;
-		},
-
-		/**
-		 * @returns string E.g. "seconds ago"
-		 */
-		getRelativeDate: function () {
-			return OC.Util.relativeModifiedDate(this.getUnixMilliseconds());
-		},
-
-		/**
-		 * @returns string E.g. "April 26, 2016 10:53 AM"
-		 */
-		getFullDate: function () {
-			return OC.Util.formatDate(this.getUnixMilliseconds());
-		}
-	});
-
-	OCA.Activity = OCA.Activity || {};
-	OCA.Activity.ActivityModel = ActivityModel;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	OCA.Activity = OCA.Activity || {};
-
-	/**
-	 * @class OCA.Activity.ActivityCollection
-	 * @classdesc
-	 *
-	 * Displays activity information for a given file
-	 *
-	 */
-	var ActivityCollection = OC.Backbone.Collection.extend(
-		/** @lends OCA.Activity.ActivityCollection.prototype */ {
-
-		firstKnownId: 0,
-		lastGivenId: 0,
-		hasMore: false,
-
-		/**
-		 * Id of the file for which to filter activities by
-		 *
-		 * @var int
-		 */
-		_objectId: null,
-
-		/**
-		 * Type of the object to filter by
-		 *
-		 * @var string
-		 */
-		_objectType: null,
-
-		model: OCA.Activity.ActivityModel,
-
-		/**
-		 * Sets the object id to filter by or null for all.
-		 * 
-		 * @param {int} objectId file id or null
-		 */
-		setObjectId: function(objectId) {
-			this._objectId = objectId;
-			this.firstKnownId = 0;
-			this.lastGivenId = 0;
-			this.hasMore = false;
-		},
-
-		/**
-		 * Sets the object type to filter by or null for all.
-		 * 
-		 * @param {string} objectType string
-		 */
-		setObjectType: function(objectType) {
-			this._objectType = objectType;
-			this.firstKnownId = 0;
-			this.lastGivenId = 0;
-			this.hasMore = false;
-		},
-
-		/**
-		 *
-		 * @param ocsResponse
-		 * @param response
-		 * @returns {Array}
-		 */
-		parse: function(ocsResponse, response) {
-			this._saveHeaders(response.xhr.getAllResponseHeaders());
-
-			if (response.xhr.status === 304) {
-				// No activities found
-				return [];
-			}
-
-			return ocsResponse.ocs.data;
-		},
-
-		/**
-		 * Read the X-Activity-First-Known and X-Activity-Last-Given headers
-		 * @param headers
-		 */
-		_saveHeaders: function(headers) {
-			var self = this;
-			this.hasMore = false;
-
-			headers = headers.split("\n");
-			_.each(headers, function (header) {
-				var parts = header.split(':');
-				if (parts[0].toLowerCase() === 'x-activity-first-known') {
-					self.firstKnownId = parseInt(parts[1].trim(), 10);
-				} else if (parts[0].toLowerCase() === 'x-activity-last-given') {
-					self.lastGivenId = parseInt(parts[1].trim(), 10);
-				} else if (parts[0].toLowerCase() === 'link') {
-					self.hasMore = true;
-				}
-			});
-		},
-
-		url: function() {
-			var query = {
-				format: 'json'
-			};
-			var url = OC.linkToOCS('apps/activity/api/v2/activity', 2) + 'filter';
-			if (this.lastGivenId) {
-				query.since = this.lastGivenId;
-			}
-			if (this._objectId && this._objectType) {
-				query.object_type = this._objectType;
-				query.object_id = this._objectId;
-			}
-			url += '?' + OC.buildQueryString(query);
-			return url;
-		}
-	});
-
-	OCA.Activity.ActivityCollection = ActivityCollection;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	var TEMPLATE =
-		'<div class="activity-section">' +
-		'<div class="loading hidden" style="height: 50px"></div>' +
-		'<div class="emptycontent">' +
-		'    <div class="icon-activity"></div>' +
-		'    <p>{{emptyMessage}}</p>' +
-		'</div>' +
-		'<ul class="activities hidden">' +
-		'</ul>' +
-		'<input type="button" class="showMore" value="{{moreLabel}}"' +
-		'</div>';
-	var ACTIVITY_TEMPLATE =
-		'    <li class="activity box">' +
-		'        <div class="activity-icon">' +
-		'        {{#if icon}}' +
-		'          <img src="{{icon}}">' +
-		'        {{/if}}' +
-		'        </div>' +
-		'        <div class="activitysubject">{{{subject}}}</div>' +
-		'        <span class="activitytime has-tooltip live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{formattedDateTooltip}}">{{formattedDate}}</span>' +
-		'        <div class="activitymessage">{{{message}}}</div>' +
-		'    </li>';
-
-	/**
-	 * @class OCA.Activity.ActivityTabView
-	 * @classdesc
-	 *
-	 * Displays activity information for a given file
-	 *
-	 */
-	var ActivityTabView = OCA.Files.DetailTabView.extend(/** @lends OCA.Activity.ActivityTabView.prototype */ {
-		id: 'activityTabView',
-		className: 'activityTabView tab',
-
-		events: {
-			'click .showMore': '_onClickShowMore'
-		},
-
-		_loading: false,
-		_plugins: [],
-
-		initialize: function() {
-			this.collection = new OCA.Activity.ActivityCollection();
-			this.collection.setObjectType('files');
-			this.collection.on('request', this._onRequest, this);
-			this.collection.on('sync', this._onEndRequest, this);
-			this.collection.on('error', this._onError, this);
-			this.collection.on('add', this._onAddModel, this);
-
-			this._plugins = OC.Plugins.getPlugins('OCA.Activity.RenderingPlugins');
-			_.each(this._plugins, function(plugin) {
-				if (_.isFunction(plugin.initialize)) {
-					plugin.initialize();
-				}
-			});
-		},
-
-		template: function(data) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			return this._template(data);
-		},
-
-		get$: function() {
-			return this.$el;
-		},
-
-		getLabel: function() {
-			return t('activity', 'Activities');
-		},
-
-		setFileInfo: function(fileInfo) {
-			this._fileInfo = fileInfo;
-			if (this._fileInfo) {
-				this.collection.setObjectId(this._fileInfo.get('id'));
-				this.collection.reset();
-				this.collection.fetch();
-
-				_.each(this._plugins, function(plugin) {
-					if (_.isFunction(plugin.setFileInfo)) {
-						plugin.setFileInfo('files', fileInfo.get('id'));
-					}
-				});
-			} else {
-				this.collection.reset();
-
-				_.each(this._plugins, function(plugin) {
-					if (_.isFunction(plugin.resetFileInfo)) {
-						plugin.resetFileInfo();
-					}
-				});
-			}
-		},
-
-		_onError: function() {
-			var $emptyContent = this.$el.find('.emptycontent');
-			$emptyContent.removeClass('hidden');
-			$emptyContent.find('p').text(t('activity', 'An error occurred while loading activities'));
-		},
-
-		_onRequest: function() {
-			if (this.collection.lastGivenId === 0) {
-				this.render();
-			}
-			this.$el.find('.showMore').addClass('hidden');
-		},
-
-		_onEndRequest: function() {
-			this.$container.removeClass('hidden');
-			this.$el.find('.loading').addClass('hidden');
-			if (this.collection.length) {
-				this.$el.find('.emptycontent').addClass('hidden');
-			}
-			if (this.collection.hasMore) {
-				this.$el.find('.showMore').removeClass('hidden');
-			}
-		},
-
-		_onClickShowMore: function() {
-			this.collection.fetch({
-				reset: false
-			});
-		},
-
-		/**
-		 * Format an activity model for display
-		 *
-		 * @param {OCA.Activity.ActivityModel} activity
-		 * @return {Object}
-		 */
-		_formatItem: function(activity) {
-
-			var subject = activity.get('subject'),
-				subject_rich = activity.get('subject_rich');
-			if (subject_rich[0].length > 1) {
-				subject = OCA.Activity.RichObjectStringParser.parseMessage(subject_rich[0], subject_rich[1]);
-			}
-			var message = activity.get('message'),
-				message_rich = activity.get('message_rich');
-			if (message_rich[0].length > 1) {
-				message = OCA.Activity.RichObjectStringParser.parseMessage(message_rich[0], message_rich[1]);
-			}
-
-			var output = {
-				subject: subject,
-				formattedDate: activity.getRelativeDate(),
-				formattedDateTooltip: activity.getFullDate(),
-				timestamp: moment(activity.get('datetime')).valueOf(),
-				message: message,
-				icon: activity.get('icon')
-			};
-
-			/**
-			 * Disable previews in the rightside bar,
-			 * it's always the same image anyway.
-			 if (activity.has('previews')) {
-					output.previews = _.map(activity.get('previews'), function(data) {
-						return {
-							previewClass: data.isMimeTypeIcon ? 'preview-mimetype-icon': '',
-							source: data.source
-						};
-					});
-				}
-			 */
-			return output;
-		},
-
-		activityTemplate: function(params) {
-			if (!this._activityTemplate) {
-				this._activityTemplate = Handlebars.compile(ACTIVITY_TEMPLATE);
-			}
-
-			return this._activityTemplate(params);
-		},
-
-		_onAddModel: function(model, collection, options) {
-			var $el = $(this.activityTemplate(this._formatItem(model)));
-
-			_.each(this._plugins, function(plugin) {
-				if (_.isFunction(plugin.prepareModelForDisplay)) {
-					plugin.prepareModelForDisplay(model, $el, 'ActivityTabView');
-				}
-			});
-
-			if (!_.isUndefined(options.at) && collection.length > 1) {
-				this.$container.find('li').eq(options.at).before($el);
-			} else {
-				this.$container.append($el);
-			}
-
-			this._postRenderItem($el);
-		},
-
-		_postRenderItem: function($el) {
-			$el.find('.avatar').each(function() {
-				var element = $(this);
-				if (element.data('user-display-name')) {
-					element.avatar(element.data('user'), 21, undefined, false, undefined, element.data('user-display-name'));
-				} else {
-					element.avatar(element.data('user'), 21);
-				}
-			});
-			$el.find('.avatar-name-wrapper').each(function() {
-				var element = $(this);
-				var avatar = element.find('.avatar');
-				var label = element.find('strong');
-
-				$.merge(avatar, label).contactsMenu(element.data('user'), 0, element);
-			});
-			$el.find('.has-tooltip').tooltip({
-				placement: 'bottom'
-			});
-		},
-
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			if (this._fileInfo) {
-				this.$el.html(this.template({
-					emptyMessage: t('activity', 'No activity yet'),
-					moreLabel: t('activity', 'Load more activities')
-				}));
-				this.$container = this.$el.find('ul.activities');
-			}
-		}
-	});
-
-	OCA.Activity = OCA.Activity || {};
-	OCA.Activity.ActivityTabView = ActivityTabView;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OCA) {
-
-var FilesPlugin = {
-	attach: function(fileList) {
-		fileList.registerTabView(new OCA.Activity.ActivityTabView({order: -50}));
-	}
-};
-
-OC.Plugins.register('OCA.Files.FileList', FilesPlugin);
-
-})(OCA);
-
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/activity\/js\/activity-sidebar.json":1570113918,"\/var\/www\/html\/apps\/activity\/js\/richObjectStringParser.js":1570113918,"\/var\/www\/html\/apps\/activity\/js\/activitymodel.js":1570113918,"\/var\/www\/html\/apps\/activity\/js\/activitycollection.js":1570113918,"\/var\/www\/html\/apps\/activity\/js\/activitytabview.js":1570113918,"\/var\/www\/html\/apps\/activity\/js\/filesplugin.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/activity/activity-sidebar.js.gzip


+ 0 - 1073
compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js

@@ -1,1073 +0,0 @@
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	if (!OCA.Comments) {
-		/**
-		 * @namespace
-		 */
-		OCA.Comments = {};
-	}
-
-})();
-
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
-
-	_.extend(OC.Files.Client, {
-		PROPERTY_FILEID:	'{' + OC.Files.Client.NS_OWNCLOUD + '}id',
-		PROPERTY_MESSAGE: 	'{' + OC.Files.Client.NS_OWNCLOUD + '}message',
-		PROPERTY_ACTORTYPE:	'{' + OC.Files.Client.NS_OWNCLOUD + '}actorType',
-		PROPERTY_ACTORID:	'{' + OC.Files.Client.NS_OWNCLOUD + '}actorId',
-		PROPERTY_ISUNREAD:	'{' + OC.Files.Client.NS_OWNCLOUD + '}isUnread',
-		PROPERTY_OBJECTID:	'{' + OC.Files.Client.NS_OWNCLOUD + '}objectId',
-		PROPERTY_OBJECTTYPE:	'{' + OC.Files.Client.NS_OWNCLOUD + '}objectType',
-		PROPERTY_ACTORDISPLAYNAME:	'{' + OC.Files.Client.NS_OWNCLOUD + '}actorDisplayName',
-		PROPERTY_CREATIONDATETIME:	'{' + OC.Files.Client.NS_OWNCLOUD + '}creationDateTime',
-		PROPERTY_MENTIONS: '{' + OC.Files.Client.NS_OWNCLOUD + '}mentions'
-	});
-
-	/**
-	 * @class OCA.Comments.CommentModel
-	 * @classdesc
-	 *
-	 * Comment
-	 *
-	 */
-	var CommentModel = OC.Backbone.Model.extend(
-		/** @lends OCA.Comments.CommentModel.prototype */ {
-		sync: OC.Backbone.davSync,
-
-		defaults: {
-			actorType: 'users',
-			objectType: 'files'
-		},
-
-		davProperties: {
-			'id':	OC.Files.Client.PROPERTY_FILEID,
-			'message':	OC.Files.Client.PROPERTY_MESSAGE,
-			'actorType':	OC.Files.Client.PROPERTY_ACTORTYPE,
-			'actorId':	OC.Files.Client.PROPERTY_ACTORID,
-			'actorDisplayName':	OC.Files.Client.PROPERTY_ACTORDISPLAYNAME,
-			'creationDateTime':	OC.Files.Client.PROPERTY_CREATIONDATETIME,
-			'objectType':	OC.Files.Client.PROPERTY_OBJECTTYPE,
-			'objectId':	OC.Files.Client.PROPERTY_OBJECTID,
-			'isUnread':	OC.Files.Client.PROPERTY_ISUNREAD,
-			'mentions': OC.Files.Client.PROPERTY_MENTIONS
-		},
-
-		parse: function(data) {
-			return {
-				id: data.id,
-				message: data.message,
-				actorType: data.actorType,
-				actorId: data.actorId,
-				actorDisplayName: data.actorDisplayName,
-				creationDateTime: data.creationDateTime,
-				objectType: data.objectType,
-				objectId: data.objectId,
-				isUnread: (data.isUnread === 'true'),
-				mentions: this._parseMentions(data.mentions)
-			};
-		},
-
-		_parseMentions: function(mentions) {
-			if(_.isUndefined(mentions)) {
-				return {};
-			}
-			var result = {};
-			for(var i in mentions) {
-				var mention = mentions[i];
-				if(_.isUndefined(mention.localName) || mention.localName !== 'mention') {
-					continue;
-				}
-				result[i] = {};
-				for (var child = mention.firstChild; child; child = child.nextSibling) {
-					if(_.isUndefined(child.localName) || !child.localName.startsWith('mention')) {
-						continue;
-					}
-					result[i][child.localName] = child.textContent;
-				}
-			}
-			return result;
-		}
-	});
-
-	OCA.Comments.CommentModel = CommentModel;
-})(OC, OCA);
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
-
-	/**
-	 * @class OCA.Comments.CommentCollection
-	 * @classdesc
-	 *
-	 * Collection of comments assigned to a file
-	 *
-	 */
-	var CommentCollection = OC.Backbone.Collection.extend(
-		/** @lends OCA.Comments.CommentCollection.prototype */ {
-
-		sync: OC.Backbone.davSync,
-
-		model: OCA.Comments.CommentModel,
-
-		/**
-		 * Object type
-		 *
-		 * @type string
-		 */
-		_objectType: 'files',
-
-		/**
-		 * Object id
-		 *
-		 * @type string
-		 */
-		_objectId: null,
-
-		/**
-		 * True if there are no more page results left to fetch
-		 *
-		 * @type bool
-		 */
-		_endReached: false,
-
-		/**
-		 * Number of comments to fetch per page
-		 *
-		 * @type int
-		 */
-		_limit : 20,
-
-		/**
-		 * Initializes the collection
-		 *
-		 * @param {string} [options.objectType] object type
-		 * @param {string} [options.objectId] object id
-		 */
-		initialize: function(models, options) {
-			options = options || {};
-			if (options.objectType) {
-				this._objectType = options.objectType;
-			}
-			if (options.objectId) {
-				this._objectId = options.objectId;
-			}
-		},
-
-		url: function() {
-			return OC.linkToRemote('dav') + '/comments/' +
-				encodeURIComponent(this._objectType) + '/' +
-				encodeURIComponent(this._objectId) + '/';
-		},
-
-		setObjectId: function(objectId) {
-			this._objectId = objectId;
-		},
-
-		hasMoreResults: function() {
-			return !this._endReached;
-		},
-
-		reset: function() {
-			this._endReached = false;
-			this._summaryModel = null;
-			return OC.Backbone.Collection.prototype.reset.apply(this, arguments);
-		},
-
-		/**
-		 * Fetch the next set of results
-		 */
-		fetchNext: function(options) {
-			var self = this;
-			if (!this.hasMoreResults()) {
-				return null;
-			}
-
-			var body = '<?xml version="1.0" encoding="utf-8" ?>\n' +
-				'<oc:filter-comments xmlns:D="DAV:" xmlns:oc="http://owncloud.org/ns">\n' +
-				// load one more so we know there is more
-				'    <oc:limit>' + (this._limit + 1) + '</oc:limit>\n' +
-				'    <oc:offset>' + this.length + '</oc:offset>\n' +
-				'</oc:filter-comments>\n';
-
-			options = options || {};
-			var success = options.success;
-			options = _.extend({
-				remove: false,
-				parse: true,
-				data: body,
-				davProperties: CommentCollection.prototype.model.prototype.davProperties,
-				success: function(resp) {
-					if (resp.length <= self._limit) {
-						// no new entries, end reached
-						self._endReached = true;
-					} else {
-						// remove last entry, for next page load
-						resp = _.initial(resp);
-					}
-					if (!self.set(resp, options)) {
-						return false;
-					}
-					if (success) {
-						success.apply(null, arguments);
-					}
-					self.trigger('sync', 'REPORT', self, options);
-				}
-			}, options);
-
-			return this.sync('REPORT', this, options);
-		},
-
-		/**
-		 * Returns the matching summary model
-		 *
-		 * @return {OCA.Comments.CommentSummaryModel} summary model
-		 */
-		getSummaryModel: function() {
-			if (!this._summaryModel) {
-				this._summaryModel = new OCA.Comments.CommentSummaryModel({
-					id: this._objectId,
-					objectType: this._objectType
-				});
-			}
-			return this._summaryModel;
-		},
-
-		/**
-		 * Updates the read marker for this comment thread
-		 *
-		 * @param {Date} [date] optional date, defaults to now
-		 * @param {Object} [options] backbone options
-		 */
-		updateReadMarker: function(date, options) {
-			options = options || {};
-
-			return this.getSummaryModel().save({
-				readMarker: (date || new Date()).toUTCString()
-			}, options);
-		}
-	});
-
-	OCA.Comments.CommentCollection = CommentCollection;
-})(OC, OCA);
-
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
-
-	_.extend(OC.Files.Client, {
-		PROPERTY_READMARKER:	'{' + OC.Files.Client.NS_OWNCLOUD + '}readMarker'
-	});
-
-	/**
-	 * @class OCA.Comments.CommentSummaryModel
-	 * @classdesc
-	 *
-	 * Model containing summary information related to comments
-	 * like the read marker.
-	 *
-	 */
-	var CommentSummaryModel = OC.Backbone.Model.extend(
-		/** @lends OCA.Comments.CommentSummaryModel.prototype */ {
-		sync: OC.Backbone.davSync,
-
-		/**
-		 * Object type
-		 *
-		 * @type string
-		 */
-		_objectType: 'files',
-
-		/**
-		 * Object id
-		 *
-		 * @type string
-		 */
-		_objectId: null,
-
-		davProperties: {
-			'readMarker': OC.Files.Client.PROPERTY_READMARKER
-		},
-
-		/**
-		 * Initializes the summary model
-		 *
-		 * @param {string} [options.objectType] object type
-		 * @param {string} [options.objectId] object id
-		 */
-		initialize: function(attrs, options) {
-			options = options || {};
-			if (options.objectType) {
-				this._objectType = options.objectType;
-			}
-		},
-
-		url: function() {
-			return OC.linkToRemote('dav') + '/comments/' +
-				encodeURIComponent(this._objectType) + '/' +
-				encodeURIComponent(this.id) + '/';
-		}
-	});
-
-	OCA.Comments.CommentSummaryModel = CommentSummaryModel;
-})(OC, OCA);
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Handlebars, escapeHTML */
-
-(function(OC, OCA) {
-	var TEMPLATE =
-		'<ul class="comments">' +
-		'</ul>' +
-		'<div class="emptycontent hidden"><div class="icon-comment"></div>' +
-		'<p>{{emptyResultLabel}}</p></div>' +
-		'<input type="button" class="showMore hidden" value="{{moreLabel}}"' +
-		' name="show-more" id="show-more" />' +
-		'<div class="loading hidden" style="height: 50px"></div>';
-
-	var EDIT_COMMENT_TEMPLATE =
-		'<div class="newCommentRow comment" data-id="{{id}}">' +
-		'    <div class="authorRow">' +
-		'        <div class="avatar" data-username="{{actorId}}"></div>' +
-		'        <div class="author">{{actorDisplayName}}</div>' +
-		'{{#if isEditMode}}' +
-		'        <a href="#" class="action delete icon icon-delete has-tooltip" title="{{deleteTooltip}}"></a>' +
-		'{{/if}}' +
-		'    </div>' +
-		'    <form class="newCommentForm">' +
-		'        <textarea rows="1" class="message" placeholder="{{newMessagePlaceholder}}">{{message}}</textarea>' +
-		'        <input class="submit icon-confirm" type="submit" value="" />' +
-		'{{#if isEditMode}}' +
-		'        <input class="cancel pull-right" type="button" value="{{cancelText}}" />' +
-		'{{/if}}' +
-		'        <div class="submitLoading icon-loading-small hidden"></div>'+
-		'    </form>' +
-		'</div>';
-
-	var COMMENT_TEMPLATE =
-		'<li class="comment{{#if isUnread}} unread{{/if}}{{#if isLong}} collapsed{{/if}}" data-id="{{id}}">' +
-		'    <div class="authorRow">' +
-		'        <div class="avatar" {{#if actorId}}data-username="{{actorId}}"{{/if}}> </div>' +
-		'        <div class="author">{{actorDisplayName}}</div>' +
-		'{{#if isUserAuthor}}' +
-		'        <a href="#" class="action edit icon icon-rename has-tooltip" title="{{editTooltip}}"></a>' +
-		'{{/if}}' +
-		'        <div class="date has-tooltip live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</div>' +
-		'    </div>' +
-		'    <div class="message">{{{formattedMessage}}}</div>' +
-		'{{#if isLong}}' +
-		'    <div class="message-overlay"></div>' +
-		'{{/if}}' +
-		'</li>';
-
-	/**
-	 * @memberof OCA.Comments
-	 */
-	var CommentsTabView = OCA.Files.DetailTabView.extend(
-		/** @lends OCA.Comments.CommentsTabView.prototype */ {
-		id: 'commentsTabView',
-		className: 'tab commentsTabView',
-
-		events: {
-			'submit .newCommentForm': '_onSubmitComment',
-			'click .showMore': '_onClickShowMore',
-			'click .action.edit': '_onClickEditComment',
-			'click .action.delete': '_onClickDeleteComment',
-			'click .cancel': '_onClickCloseComment',
-			'click .comment': '_onClickComment'
-		},
-
-		_commentMaxLength: 1000,
-
-		initialize: function() {
-			OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
-			this.collection = new OCA.Comments.CommentCollection();
-			this.collection.on('request', this._onRequest, this);
-			this.collection.on('sync', this._onEndRequest, this);
-			this.collection.on('add', this._onAddModel, this);
-
-			this._commentMaxThreshold = this._commentMaxLength * 0.9;
-
-			// TODO: error handling
-			_.bindAll(this, '_onTypeComment');
-		},
-
-		template: function(params) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			var currentUser = OC.getCurrentUser();
-			return this._template(_.extend({
-				actorId: currentUser.uid,
-				actorDisplayName: currentUser.displayName
-			}, params));
-		},
-
-		editCommentTemplate: function(params) {
-			if (!this._editCommentTemplate) {
-				this._editCommentTemplate = Handlebars.compile(EDIT_COMMENT_TEMPLATE);
-			}
-			var currentUser = OC.getCurrentUser();
-			return this._editCommentTemplate(_.extend({
-				actorId: currentUser.uid,
-				actorDisplayName: currentUser.displayName,
-				newMessagePlaceholder: t('comments', 'New comment …'),
-				deleteTooltip: t('comments', 'Delete comment'),
-				submitText: t('comments', 'Post'),
-				cancelText: t('comments', 'Cancel')
-			}, params));
-		},
-
-		commentTemplate: function(params) {
-			if (!this._commentTemplate) {
-				this._commentTemplate = Handlebars.compile(COMMENT_TEMPLATE);
-			}
-
-			params = _.extend({
-				editTooltip: t('comments', 'Edit comment'),
-				isUserAuthor: OC.getCurrentUser().uid === params.actorId,
-				isLong: this._isLong(params.message)
-			}, params);
-
-			if (params.actorType === 'deleted_users') {
-				// makes the avatar a X
-				params.actorId = null;
-				params.actorDisplayName = t('comments', '[Deleted user]');
-			}
-
-			return this._commentTemplate(params);
-		},
-
-		getLabel: function() {
-			return t('comments', 'Comments');
-		},
-
-		setFileInfo: function(fileInfo) {
-			if (fileInfo) {
-				this.model = fileInfo;
-				this.render();
-				this.collection.setObjectId(fileInfo.id);
-				// reset to first page
-				this.collection.reset([], {silent: true});
-				this.nextPage();
-			} else {
-				this.model = null;
-				this.render();
-				this.collection.reset();
-			}
-		},
-
-		render: function() {
-			this.$el.html(this.template({
-				emptyResultLabel: t('comments', 'No comments yet, start the conversation!'),
-				moreLabel: t('comments', 'More comments …')
-			}));
-			this.$el.find('.comments').before(this.editCommentTemplate({}));
-			this.$el.find('.has-tooltip').tooltip();
-			this.$container = this.$el.find('ul.comments');
-			this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 32);
-			this.delegateEvents();
-			this.$el.find('.message').on('keydown input change', this._onTypeComment);
-
-			autosize(this.$el.find('.newCommentRow textarea'))
-		},
-
-		_formatItem: function(commentModel) {
-			var timestamp = new Date(commentModel.get('creationDateTime')).getTime();
-			var data = _.extend({
-				timestamp: timestamp,
-				date: OC.Util.relativeModifiedDate(timestamp),
-				altDate: OC.Util.formatDate(timestamp),
-				formattedMessage: this._formatMessage(commentModel.get('message'), commentModel.get('mentions'))
-			}, commentModel.attributes);
-			return data;
-		},
-
-		_toggleLoading: function(state) {
-			this._loading = state;
-			this.$el.find('.loading').toggleClass('hidden', !state);
-		},
-
-		_onRequest: function(type) {
-			if (type === 'REPORT') {
-				this._toggleLoading(true);
-				this.$el.find('.showMore').addClass('hidden');
-			}
-		},
-
-		_onEndRequest: function(type) {
-			var fileInfoModel = this.model;
-			this._toggleLoading(false);
-			this.$el.find('.emptycontent').toggleClass('hidden', !!this.collection.length);
-			this.$el.find('.showMore').toggleClass('hidden', !this.collection.hasMoreResults());
-
-			if (type !== 'REPORT') {
-				return;
-			}
-
-			// find first unread comment
-			var firstUnreadComment = this.collection.findWhere({isUnread: true});
-			if (firstUnreadComment) {
-				// update read marker
-				this.collection.updateReadMarker(
-					null,
-					{
-						success: function() {
-							fileInfoModel.set('commentsUnread', 0);
-						}
-					}
-				);
-			}
-		},
-
-		_onAddModel: function(model, collection, options) {
-			var $el = $(this.commentTemplate(this._formatItem(model)));
-			if (!_.isUndefined(options.at) && collection.length > 1) {
-				this.$container.find('li').eq(options.at).before($el);
-			} else {
-				this.$container.append($el);
-			}
-
-			this._postRenderItem($el);
-		},
-
-		_postRenderItem: function($el) {
-			$el.find('.has-tooltip').tooltip();
-			$el.find('.avatar').each(function() {
-				var $this = $(this);
-				$this.avatar($this.attr('data-username'), 32);
-			});
-
-			var username = $el.find('.avatar').data('username');
-			if (username !== oc_current_user) {
-				$el.find('.authorRow .avatar, .authorRow .author').contactsMenu(
-					username, 0, $el.find('.authorRow'));
-			}
-
-			var $message = $el.find('.message');
-			this._postRenderMessage($message);
-		},
-
-		_postRenderMessage: function($el) {
-			$el.find('.avatar').each(function() {
-				var avatar = $(this);
-				var strong = $(this).next();
-				var appendTo = $(this).parent();
-
-				$.merge(avatar, strong).contactsMenu(avatar.data('user'), 0, appendTo);
-			});
-		},
-
-		/**
-		 * Convert a message to be displayed in HTML,
-		 * converts newlines to <br> tags.
-		 */
-		_formatMessage: function(message, mentions) {
-			message = escapeHTML(message).replace(/\n/g, '<br/>');
-
-			for(var i in mentions) {
-				var mention = '@' + mentions[i].mentionId;
-
-				var avatar = '<div class="avatar" '
-					+ 'data-user="' + _.escape(mentions[i].mentionId) + '"'
-					+' data-user-display-name="'
-					+ _.escape(mentions[i].mentionDisplayName) + '"></div>';
-
-				// escape possible regex characters in the name
-				mention = mention.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-				var displayName = ''
-					+ '<span class="avatar-name-wrapper">'
-					+ avatar + ' <strong>'+ _.escape(mentions[i].mentionDisplayName)+'</strong>'
-					+ '</span>';
-
-				// replace every mention either at the start of the input or after a whitespace
-				// followed by a non-word character.
-				message = message.replace(new RegExp("(^|\\s)(" + mention + ")\\b", 'g'),
-					function(match, p1) {
-						// to  get number of whitespaces (0 vs 1) right
-						return p1+displayName;
-					}
-				);
-			}
-
-			return message;
-		},
-
-		nextPage: function() {
-			if (this._loading || !this.collection.hasMoreResults()) {
-				return;
-			}
-
-			this.collection.fetchNext();
-		},
-
-		_onClickEditComment: function(ev) {
-			ev.preventDefault();
-			var $comment = $(ev.target).closest('.comment');
-			var commentId = $comment.data('id');
-			var commentToEdit = this.collection.get(commentId);
-			var $formRow = $(this.editCommentTemplate(_.extend({
-				isEditMode: true,
-				submitText: t('comments', 'Save')
-			}, commentToEdit.attributes)));
-
-			$comment.addClass('hidden').removeClass('collapsed');
-			// spawn form
-			$comment.after($formRow);
-			$formRow.data('commentEl', $comment);
-			$formRow.find('textarea').on('keydown input change', this._onTypeComment);
-
-			// copy avatar element from original to avoid flickering
-			$formRow.find('.avatar:first').replaceWith($comment.find('.avatar:first').clone());
-			$formRow.find('.has-tooltip').tooltip();
-
-			// Enable autosize
-			autosize($formRow.find('textarea'));
-
-			return false;
-		},
-
-		_onTypeComment: function(ev) {
-			var $field = $(ev.target);
-			var len = $field.val().length;
-			var $submitButton = $field.data('submitButtonEl');
-			if (!$submitButton) {
-				$submitButton = $field.closest('form').find('.submit');
-				$field.data('submitButtonEl', $submitButton);
-			}
-			$field.tooltip('hide');
-			if (len > this._commentMaxThreshold) {
-				$field.attr('data-original-title', t('comments', 'Allowed characters {count} of {max}', {count: len, max: this._commentMaxLength}));
-				$field.tooltip({trigger: 'manual'});
-				$field.tooltip('show');
-				$field.addClass('error');
-			}
-
-			var limitExceeded = (len > this._commentMaxLength);
-			$field.toggleClass('error', limitExceeded);
-			$submitButton.prop('disabled', limitExceeded);
-
-			//submits form on ctrl+Enter or cmd+Enter
-			if (ev.keyCode === 13 && (ev.ctrlKey || ev.metaKey)) {
-				$submitButton.click();
-			}
-		},
-
-		_onClickComment: function(ev) {
-			var $row = $(ev.target);
-			if (!$row.is('.comment')) {
-				$row = $row.closest('.comment');
-			}
-			$row.removeClass('collapsed');
-		},
-
-		_onClickCloseComment: function(ev) {
-			ev.preventDefault();
-			var $row = $(ev.target).closest('.comment');
-			$row.data('commentEl').removeClass('hidden');
-			$row.remove();
-			return false;
-		},
-
-		_onClickDeleteComment: function(ev) {
-			ev.preventDefault();
-			var $comment = $(ev.target).closest('.comment');
-			var commentId = $comment.data('id');
-			var $loading = $comment.find('.submitLoading');
-
-			$comment.addClass('disabled');
-			$loading.removeClass('hidden');
-			this.collection.get(commentId).destroy({
-				success: function() {
-					$comment.data('commentEl').remove();
-					$comment.remove();
-				},
-				error: function() {
-					$loading.addClass('hidden');
-					$comment.removeClass('disabled');
-					OC.Notification.showTemporary(t('comments', 'Error occurred while retrieving comment with id {id}', {id: commentId}));
-				}
-			});
-
-			return false;
-		},
-
-		_onClickShowMore: function(ev) {
-			ev.preventDefault();
-			this.nextPage();
-		},
-
-		/**
-		 * takes care of updating comment elements after submit (either new
-		 * comment or edit).
-		 *
-		 * @param {OC.Backbone.Model} model
-		 * @param {jQuery} $form
-		 * @param {string|undefined} commentId
-		 * @private
-		 */
-		_onSubmitSuccess: function(model, $form, commentId) {
-			var self = this;
-			var $submit = $form.find('.submit');
-			var $loading = $form.find('.submitLoading');
-			var $textArea = $form.find('.message');
-
-			model.fetch({
-				success: function(model) {
-					$submit.removeClass('hidden');
-					$loading.addClass('hidden');
-					var $target;
-
-					if(!_.isUndefined(commentId)) {
-						var $row = $form.closest('.comment');
-						$target = $row.data('commentEl');
-						$target.removeClass('hidden');
-						$row.remove();
-					} else {
-						$target = $('.commentsTabView .comments').find('li:first');
-						$textArea.val('').prop('disabled', false);
-					}
-
-					var $message = $target.find('.message');
-					$message
-						.html(self._formatMessage(model.get('message'), model.get('mentions')))
-						.find('.avatar')
-						.each(function () { $(this).avatar(); });
-
-					self._postRenderMessage($message);
-				},
-				error: function () {
-					self._onSubmitError($form, commentId);
-				}
-			});
-		},
-
-		_onSubmitComment: function(e) {
-			var self = this;
-			var $form = $(e.target);
-			var commentId = $form.closest('.comment').data('id');
-			var currentUser = OC.getCurrentUser();
-			var $submit = $form.find('.submit');
-			var $loading = $form.find('.submitLoading');
-			var $textArea = $form.find('.message');
-			var message = $textArea.val().trim();
-			e.preventDefault();
-
-			if (!message.length || message.length > this._commentMaxLength) {
-				return;
-			}
-
-			$textArea.prop('disabled', true);
-			$submit.addClass('hidden');
-			$loading.removeClass('hidden');
-
-			if (commentId) {
-				// edit mode
-				var comment = this.collection.get(commentId);
-				comment.save({
-					message: $textArea.val()
-				}, {
-					success: function(model) {
-						self._onSubmitSuccess(model, $form, commentId);
-					},
-					error: function() {
-						self._onSubmitError($form, commentId);
-					}
-				});
-			} else {
-				this.collection.create({
-					actorId: currentUser.uid,
-					actorDisplayName: currentUser.displayName,
-					actorType: 'users',
-					verb: 'comment',
-					message: $textArea.val(),
-					creationDateTime: (new Date()).toUTCString()
-				}, {
-					at: 0,
-					// wait for real creation before adding
-					wait: true,
-					success: function(model) {
-						self._onSubmitSuccess(model, $form);
-					},
-					error: function() {
-						self._onSubmitError($form);
-					}
-				});
-			}
-
-			return false;
-		},
-
-		/**
-		 * takes care of updating the UI after an error on submit (either new
-		 * comment or edit).
-		 *
-		 * @param {jQuery} $form
-		 * @param {string|undefined} commentId
-		 * @private
-		 */
-		_onSubmitError: function($form, commentId) {
-			$form.find('.submit').removeClass('hidden');
-			$form.find('.submitLoading').addClass('hidden');
-			$form.find('.message').prop('disabled', false);
-
-			if(!_.isUndefined(commentId)) {
-				OC.Notification.show(t('comments', 'Error occurred while updating comment with id {id}', {id: commentId}), {type: 'error'});
-			} else {
-				OC.Notification.show(t('comments', 'Error occurred while posting comment'), {type: 'error'});
-			}
-		},
-
-		/**
-		 * Returns whether the given message is long and needs
-		 * collapsing
-		 */
-		_isLong: function(message) {
-			return message.length > 250 || (message.match(/\n/g) || []).length > 1;
-		}
-	});
-
-	OCA.Comments.CommentsTabView = CommentsTabView;
-})(OC, OCA);
-
-
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Handlebars */
-
-(function() {
-
-	_.extend(OC.Files.Client, {
-		PROPERTY_COMMENTS_UNREAD:	'{' + OC.Files.Client.NS_OWNCLOUD + '}comments-unread'
-	});
-
-	var TEMPLATE_COMMENTS_UNREAD =
-		'<a class="action action-comment permanent" title="{{countMessage}}" href="#">' +
-		'<img class="svg" src="{{iconUrl}}"/>' +
-		'</a>';
-
-	OCA.Comments = _.extend({}, OCA.Comments);
-	if (!OCA.Comments) {
-		/**
-		 * @namespace
-		 */
-		OCA.Comments = {};
-	}
-
-	/**
-	 * @namespace
-	 */
-	OCA.Comments.FilesPlugin = {
-		ignoreLists: [
-			'files_trashbin',
-			'files.public'
-		],
-
-		_formatCommentCount: function(count) {
-			if (!this._commentsUnreadTemplate) {
-				this._commentsUnreadTemplate = Handlebars.compile(TEMPLATE_COMMENTS_UNREAD);
-			}
-			return this._commentsUnreadTemplate({
-				count: count,
-				countMessage: n('comments', '%n unread comment', '%n unread comments', count),
-				iconUrl: OC.imagePath('core', 'actions/comment')
-			});
-		},
-
-		attach: function(fileList) {
-			var self = this;
-			if (this.ignoreLists.indexOf(fileList.id) >= 0) {
-				return;
-			}
-
-			fileList.registerTabView(new OCA.Comments.CommentsTabView('commentsTabView'));
-
-			var oldGetWebdavProperties = fileList._getWebdavProperties;
-			fileList._getWebdavProperties = function() {
-				var props = oldGetWebdavProperties.apply(this, arguments);
-				props.push(OC.Files.Client.PROPERTY_COMMENTS_UNREAD);
-				return props;
-			};
-
-			fileList.filesClient.addFileInfoParser(function(response) {
-				var data = {};
-				var props = response.propStat[0].properties;
-				var commentsUnread = props[OC.Files.Client.PROPERTY_COMMENTS_UNREAD];
-				if (!_.isUndefined(commentsUnread) && commentsUnread !== '') {
-					data.commentsUnread = parseInt(commentsUnread, 10);
-				}
-				return data;
-			});
-
-			fileList.$el.addClass('has-comments');
-			var oldCreateRow = fileList._createRow;
-			fileList._createRow = function(fileData) {
-				var $tr = oldCreateRow.apply(this, arguments);
-				if (fileData.commentsUnread) {
-					$tr.attr('data-comments-unread', fileData.commentsUnread);
-				}
-				return $tr;
-			};
-
-			// register "comment" action for reading comments
-			fileList.fileActions.registerAction({
-				name: 'Comment',
-				displayName: t('comments', 'Comment'),
-				mime: 'all',
-				permissions: OC.PERMISSION_READ,
-				type: OCA.Files.FileActions.TYPE_INLINE,
-				render: function(actionSpec, isDefault, context) {
-					var $file = context.$file;
-					var unreadComments = $file.data('comments-unread');
-					if (unreadComments) {
-						var $actionLink = $(self._formatCommentCount(unreadComments));
-						context.$file.find('a.name>span.fileactions').append($actionLink);
-						return $actionLink;
-					}
-					return '';
-				},
-				actionHandler: function(fileName, context) {
-					context.$file.find('.action-comment').tooltip('hide');
-					// open sidebar in comments section
-					context.fileList.showDetailsView(fileName, 'commentsTabView');
-				}
-			});
-
-			// add attribute to "elementToFile"
-			var oldElementToFile = fileList.elementToFile;
-			fileList.elementToFile = function($el) {
-				var fileInfo = oldElementToFile.apply(this, arguments);
-				var commentsUnread = $el.data('comments-unread');
-				if (commentsUnread) {
-					fileInfo.commentsUnread = commentsUnread;
-				}
-				return fileInfo;
-			};
-		}
-	};
-
-})();
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Comments.FilesPlugin);
-
-
-/*
- * @author Joas Schilling <coding@schilljs.com>
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- */
-
-(function() {
-	OCA.Comments.ActivityTabViewPlugin = {
-
-		/**
-		 * Prepare activity for display
-		 *
-		 * @param {OCA.Activity.ActivityModel} model for this activity
-		 * @param {jQuery} $el jQuery handle for this activity
-		 * @param {string} view The view that displayes this activity
-		 */
-		prepareModelForDisplay: function (model, $el, view) {
-			if (model.get('app') !== 'comments' || model.get('type') !== 'comments') {
-				return;
-			}
-
-			if (view === 'ActivityTabView') {
-				$el.addClass('comment');
-				if (model.get('message') && this._isLong(model.get('message'))) {
-					$el.addClass('collapsed');
-					var $overlay = $('<div>').addClass('message-overlay');
-					$el.find('.activitymessage').after($overlay);
-					$el.on('click', this._onClickCollapsedComment);
-				}
-			}
-		},
-
-		/*
-		 * Copy of CommentsTabView._onClickComment()
-		 */
-		_onClickCollapsedComment: function(ev) {
-			var $row = $(ev.target);
-			if (!$row.is('.comment')) {
-				$row = $row.closest('.comment');
-			}
-			$row.removeClass('collapsed');
-		},
-
-		/*
-		 * Copy of CommentsTabView._isLong()
-		 */
-		_isLong: function(message) {
-			return message.length > 250 || (message.match(/\n/g) || []).length > 1;
-		}
-	};
-
-
-})();
-
-OC.Plugins.register('OCA.Activity.RenderingPlugins', OCA.Comments.ActivityTabViewPlugin);
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/comments\/js\/merged.json":1570113918,"\/var\/www\/html\/apps\/comments\/js\/app.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/commentmodel.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/commentcollection.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/commentsummarymodel.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/commentstabview.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/filesplugin.js":1570113918,"\/var\/www\/html\/apps\/comments\/js\/activitytabviewplugin.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/comments/merged.js.gzip


+ 0 - 10666
compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js

@@ -1,10666 +0,0 @@
-/*
- * Copyright (c) 2014
- *
- * @author Vincent Petry
- * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global dragOptions, folderDropOptions, OC */
-(function() {
-
-	if (!OCA.Files) {
-		/**
-		 * Namespace for the files app
-		 * @namespace OCA.Files
-		 */
-		OCA.Files = {};
-	}
-
-	/**
-	 * @namespace OCA.Files.App
-	 */
-	OCA.Files.App = {
-		/**
-		 * Navigation control
-		 *
-		 * @member {OCA.Files.Navigation}
-		 */
-		navigation: null,
-
-		/**
-		 * File list for the "All files" section.
-		 *
-		 * @member {OCA.Files.FileList}
-		 */
-		fileList: null,
-
-		/**
-		 * Backbone model for storing files preferences
-		 */
-		_filesConfig: null,
-
-		/**
-		 * Initializes the files app
-		 */
-		initialize: function() {
-			this.navigation = new OCA.Files.Navigation($('#app-navigation'));
-			this.$showHiddenFiles = $('input#showhiddenfilesToggle');
-			var showHidden = $('#showHiddenFiles').val() === "1";
-			this.$showHiddenFiles.prop('checked', showHidden);
-			if ($('#fileNotFound').val() === "1") {
-				OC.Notification.show(t('files', 'File could not be found'), {type: 'error'});
-			}
-
-			this._filesConfig = new OC.Backbone.Model({
-				showhidden: showHidden
-			});
-
-			var urlParams = OC.Util.History.parseUrlQuery();
-			var fileActions = new OCA.Files.FileActions();
-			// default actions
-			fileActions.registerDefaultActions();
-			// legacy actions
-			fileActions.merge(window.FileActions);
-			// regular actions
-			fileActions.merge(OCA.Files.fileActions);
-
-			this._onActionsUpdated = _.bind(this._onActionsUpdated, this);
-			OCA.Files.fileActions.on('setDefault.app-files', this._onActionsUpdated);
-			OCA.Files.fileActions.on('registerAction.app-files', this._onActionsUpdated);
-			window.FileActions.on('setDefault.app-files', this._onActionsUpdated);
-			window.FileActions.on('registerAction.app-files', this._onActionsUpdated);
-
-			this.files = OCA.Files.Files;
-
-			// TODO: ideally these should be in a separate class / app (the embedded "all files" app)
-			this.fileList = new OCA.Files.FileList(
-				$('#app-content-files'), {
-					scrollContainer: $('#app-content'),
-					dragOptions: dragOptions,
-					folderDropOptions: folderDropOptions,
-					fileActions: fileActions,
-					allowLegacyActions: true,
-					scrollTo: urlParams.scrollto,
-					filesClient: OC.Files.getClient(),
-					sorting: {
-						mode: $('#defaultFileSorting').val(),
-						direction: $('#defaultFileSortingDirection').val()
-					},
-					config: this._filesConfig,
-					enableUpload: true
-				}
-			);
-			this.files.initialize();
-
-			// for backward compatibility, the global FileList will
-			// refer to the one of the "files" view
-			window.FileList = this.fileList;
-
-			OC.Plugins.attach('OCA.Files.App', this);
-
-			this._setupEvents();
-			// trigger URL change event handlers
-			this._onPopState(urlParams);
-
-			$('#quota.has-tooltip').tooltip({
-				placement: 'top'
-			});
-
-			this._debouncedPersistShowHiddenFilesState = _.debounce(this._persistShowHiddenFilesState, 1200);
-		},
-
-		/**
-		 * Destroy the app
-		 */
-		destroy: function() {
-			this.navigation = null;
-			this.fileList.destroy();
-			this.fileList = null;
-			this.files = null;
-			OCA.Files.fileActions.off('setDefault.app-files', this._onActionsUpdated);
-			OCA.Files.fileActions.off('registerAction.app-files', this._onActionsUpdated);
-			window.FileActions.off('setDefault.app-files', this._onActionsUpdated);
-			window.FileActions.off('registerAction.app-files', this._onActionsUpdated);
-		},
-
-		_onActionsUpdated: function(ev, newAction) {
-			// forward new action to the file list
-			if (ev.action) {
-				this.fileList.fileActions.registerAction(ev.action);
-			} else if (ev.defaultAction) {
-				this.fileList.fileActions.setDefault(
-					ev.defaultAction.mime,
-					ev.defaultAction.name
-				);
-			}
-		},
-
-		/**
-		 * Returns the container of the currently visible app.
-		 *
-		 * @return app container
-		 */
-		getCurrentAppContainer: function() {
-			return this.navigation.getActiveContainer();
-		},
-
-		/**
-		 * Sets the currently active view
-		 * @param viewId view id
-		 */
-		setActiveView: function(viewId, options) {
-			this.navigation.setActiveItem(viewId, options);
-		},
-
-		/**
-		 * Returns the view id of the currently active view
-		 * @return view id
-		 */
-		getActiveView: function() {
-			return this.navigation.getActiveItem();
-		},
-
-		/**
-		 *
-		 * @returns {Backbone.Model}
-		 */
-		getFilesConfig: function() {
-			return this._filesConfig;
-		},
-
-		/**
-		 * Setup events based on URL changes
-		 */
-		_setupEvents: function() {
-			OC.Util.History.addOnPopStateHandler(_.bind(this._onPopState, this));
-
-			// detect when app changed their current directory
-			$('#app-content').delegate('>div', 'changeDirectory', _.bind(this._onDirectoryChanged, this));
-			$('#app-content').delegate('>div', 'afterChangeDirectory', _.bind(this._onAfterDirectoryChanged, this));
-			$('#app-content').delegate('>div', 'changeViewerMode', _.bind(this._onChangeViewerMode, this));
-
-			$('#app-navigation').on('itemChanged', _.bind(this._onNavigationChanged, this));
-			this.$showHiddenFiles.on('change', _.bind(this._onShowHiddenFilesChange, this));
-		},
-
-		/**
-		 * Toggle showing hidden files according to the settings checkbox
-		 *
-		 * @returns {undefined}
-		 */
-		_onShowHiddenFilesChange: function() {
-			var show = this.$showHiddenFiles.is(':checked');
-			this._filesConfig.set('showhidden', show);
-			this._debouncedPersistShowHiddenFilesState();
-		},
-
-		/**
-		 * Persist show hidden preference on ther server
-		 *
-		 * @returns {undefined}
-		 */
-		_persistShowHiddenFilesState: function() {
-			var show = this._filesConfig.get('showhidden');
-			$.post(OC.generateUrl('/apps/files/api/v1/showhidden'), {
-				show: show
-			});
-		},
-
-		/**
-		 * Event handler for when the current navigation item has changed
-		 */
-		_onNavigationChanged: function(e) {
-			var params;
-			if (e && e.itemId) {
-				params = {
-					view: e.itemId,
-					dir: '/'
-				};
-				this._changeUrl(params.view, params.dir);
-				OC.Apps.hideAppSidebar($('.detailsView'));
-				this.navigation.getActiveContainer().trigger(new $.Event('urlChanged', params));
-			}
-		},
-
-		/**
-		 * Event handler for when an app notified that its directory changed
-		 */
-		_onDirectoryChanged: function(e) {
-			if (e.dir) {
-				this._changeUrl(this.navigation.getActiveItem(), e.dir, e.fileId);
-			}
-		},
-
-		/**
-		 * Event handler for when an app notified that its directory changed
-		 */
-		_onAfterDirectoryChanged: function(e) {
-			if (e.dir && e.fileId) {
-				this._changeUrl(this.navigation.getActiveItem(), e.dir, e.fileId);
-			}
-		},
-
-		/**
-		 * Event handler for when an app notifies that it needs space
-		 * for viewer mode.
-		 */
-		_onChangeViewerMode: function(e) {
-			var state = !!e.viewerModeEnabled;
-			if (e.viewerModeEnabled) {
-				OC.Apps.hideAppSidebar($('.detailsView'));
-			}
-			$('#app-navigation').toggleClass('hidden', state);
-			$('.app-files').toggleClass('viewer-mode no-sidebar', state);
-		},
-
-		/**
-		 * Event handler for when the URL changed
-		 */
-		_onPopState: function(params) {
-			params = _.extend({
-				dir: '/',
-				view: 'files'
-			}, params);
-			var lastId = this.navigation.getActiveItem();
-			if (!this.navigation.itemExists(params.view)) {
-				params.view = 'files';
-			}
-			this.navigation.setActiveItem(params.view, {silent: true});
-			if (lastId !== this.navigation.getActiveItem()) {
-				this.navigation.getActiveContainer().trigger(new $.Event('show'));
-			}
-			this.navigation.getActiveContainer().trigger(new $.Event('urlChanged', params));
-		},
-
-		/**
-		 * Encode URL params into a string, except for the "dir" attribute
-		 * that gets encoded as path where "/" is not encoded
-		 *
-		 * @param {Object.<string>} params
-		 * @return {string} encoded params
-		 */
-		_makeUrlParams: function(params) {
-			var dir = params.dir;
-			delete params.dir;
-			return 'dir=' + OC.encodePath(dir) + '&' + OC.buildQueryString(params);
-		},
-
-		/**
-		 * Change the URL to point to the given dir and view
-		 */
-		_changeUrl: function(view, dir, fileId) {
-			var params = {dir: dir};
-			if (view !== 'files') {
-				params.view = view;
-			} else if (fileId) {
-				params.fileid = fileId;
-			}
-			var currentParams = OC.Util.History.parseUrlQuery();
-			if (currentParams.dir === params.dir && currentParams.view === params.view && currentParams.fileid !== params.fileid) {
-				// if only fileid changed or was added, replace instead of push
-				OC.Util.History.replaceState(this._makeUrlParams(params));
-			} else {
-				OC.Util.History.pushState(this._makeUrlParams(params));
-			}
-		}
-	};
-})();
-
-$(document).ready(function() {
-	// wait for other apps/extensions to register their event handlers and file actions
-	// in the "ready" clause
-	_.defer(function() {
-		OCA.Files.App.initialize();
-	});
-});
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/**
- * The file upload code uses several hooks to interact with blueimps jQuery file upload library:
- * 1. the core upload handling hooks are added when initializing the plugin,
- * 2. if the browser supports progress events they are added in a separate set after the initialization
- * 3. every app can add it's own triggers for fileupload
- *    - files adds d'n'd handlers and also reacts to done events to add new rows to the filelist
- *    - TODO pictures upload button
- *    - TODO music upload button
- */
-
-/* global jQuery, humanFileSize, md5 */
-
-/**
- * File upload object
- *
- * @class OC.FileUpload
- * @classdesc
- *
- * Represents a file upload
- *
- * @param {OC.Uploader} uploader uploader
- * @param {Object} data blueimp data
- */
-OC.FileUpload = function(uploader, data) {
-	this.uploader = uploader;
-	this.data = data;
-	var path = '';
-	if (this.uploader.fileList) {
-		path = OC.joinPaths(this.uploader.fileList.getCurrentDirectory(), this.getFile().name);
-	} else {
-		path = this.getFile().name;
-	}
-	this.id = 'web-file-upload-' + md5(path) + '-' + (new Date()).getTime();
-};
-OC.FileUpload.CONFLICT_MODE_DETECT = 0;
-OC.FileUpload.CONFLICT_MODE_OVERWRITE = 1;
-OC.FileUpload.CONFLICT_MODE_AUTORENAME = 2;
-OC.FileUpload.prototype = {
-
-	/**
-	 * Unique upload id
-	 *
-	 * @type string
-	 */
-	id: null,
-
-	/**
-	 * Upload element
-	 *
-	 * @type Object
-	 */
-	$uploadEl: null,
-
-	/**
-	 * Target folder
-	 *
-	 * @type string
-	 */
-	_targetFolder: '',
-
-	/**
-	 * @type int
-	 */
-	_conflictMode: OC.FileUpload.CONFLICT_MODE_DETECT,
-
-	/**
-	 * New name from server after autorename
-	 *
-	 * @type String
-	 */
-	_newName: null,
-
-	/**
-	 * Returns the unique upload id
-	 *
-	 * @return string
-	 */
-	getId: function() {
-		return this.id;
-	},
-
-	/**
-	 * Returns the file to be uploaded
-	 *
-	 * @return {File} file
-	 */
-	getFile: function() {
-		return this.data.files[0];
-	},
-
-	/**
-	 * Return the final filename.
-	 *
-	 * @return {String} file name
-	 */
-	getFileName: function() {
-		// autorenamed name
-		if (this._newName) {
-			return this._newName;
-		}
-		return this.getFile().name;
-	},
-
-	setTargetFolder: function(targetFolder) {
-		this._targetFolder = targetFolder;
-	},
-
-	getTargetFolder: function() {
-		return this._targetFolder;
-	},
-
-	/**
-	 * Get full path for the target file, including relative path,
-	 * without the file name.
-	 *
-	 * @return {String} full path
-	 */
-	getFullPath: function() {
-		return OC.joinPaths(this._targetFolder, this.getFile().relativePath || '');
-	},
-
-	/**
-	 * Get full path for the target file, 
-	 * including relative path and file name.
-	 *
-	 * @return {String} full path
-	 */
-	getFullFilePath: function() {
-		return OC.joinPaths(this.getFullPath(), this.getFile().name);
-	},
-
-	/**
-	 * Returns conflict resolution mode.
-	 *
-	 * @return {int} conflict mode
-	 */
-	getConflictMode: function() {
-		return this._conflictMode || OC.FileUpload.CONFLICT_MODE_DETECT;
-	},
-
-	/**
-	 * Set conflict resolution mode.
-	 * See CONFLICT_MODE_* constants.
-	 *
-	 * @param {int} mode conflict mode
-	 */
-	setConflictMode: function(mode) {
-		this._conflictMode = mode;
-	},
-
-	deleteUpload: function() {
-		delete this.data.jqXHR;
-	},
-
-	/**
-	 * Trigger autorename and append "(2)".
-	 * Multiple calls will increment the appended number.
-	 */
-	autoRename: function() {
-		var name = this.getFile().name;
-		if (!this._renameAttempt) {
-			this._renameAttempt = 1;
-		}
-
-		var dotPos = name.lastIndexOf('.');
-		var extPart = '';
-		if (dotPos > 0) {
-			this._newName = name.substr(0, dotPos);
-			extPart = name.substr(dotPos);
-		} else {
-			this._newName = name;
-		}
-
-		// generate new name
-		this._renameAttempt++;
-		this._newName = this._newName + ' (' + this._renameAttempt + ')' + extPart;
-	},
-
-	/**
-	 * Submit the upload
-	 */
-	submit: function() {
-		var self = this;
-		var data = this.data;
-		var file = this.getFile();
-
-		// it was a folder upload, so make sure the parent directory exists alrady
-		var folderPromise;
-		if (file.relativePath) {
-			folderPromise = this.uploader.ensureFolderExists(this.getFullPath());
-		} else {
-			folderPromise = $.Deferred().resolve().promise();
-		}
-
-		if (this.uploader.fileList) {
-			this.data.url = this.uploader.fileList.getUploadUrl(this.getFileName(), this.getFullPath());
-		}
-
-		if (!this.data.headers) {
-			this.data.headers = {};
-		}
-
-		// webdav without multipart
-		this.data.multipart = false;
-		this.data.type = 'PUT';
-
-		delete this.data.headers['If-None-Match'];
-		if (this._conflictMode === OC.FileUpload.CONFLICT_MODE_DETECT
-			|| this._conflictMode === OC.FileUpload.CONFLICT_MODE_AUTORENAME) {
-			this.data.headers['If-None-Match'] = '*';
-		}
-
-		var userName = this.uploader.filesClient.getUserName();
-		var password = this.uploader.filesClient.getPassword();
-		if (userName) {
-			// copy username/password from DAV client
-			this.data.headers['Authorization'] =
-				'Basic ' + btoa(userName + ':' + (password || ''));
-		}
-
-		var chunkFolderPromise;
-		if ($.support.blobSlice
-			&& this.uploader.fileUploadParam.maxChunkSize
-			&& this.getFile().size > this.uploader.fileUploadParam.maxChunkSize
-		) {
-			data.isChunked = true;
-			chunkFolderPromise = this.uploader.filesClient.createDirectory(
-				'uploads/' + encodeURIComponent(OC.getCurrentUser().uid) + '/' + encodeURIComponent(this.getId())
-			);
-			// TODO: if fails, it means same id already existed, need to retry
-		} else {
-			chunkFolderPromise = $.Deferred().resolve().promise();
-		}
-
-		// wait for creation of the required directory before uploading
-		$.when(folderPromise, chunkFolderPromise).then(function() {
-			data.submit();
-		}, function() {
-			self.abort();
-		});
-
-	},
-
-	/**
-	 * Process end of transfer
-	 */
-	done: function() {
-		if (!this.data.isChunked) {
-			return $.Deferred().resolve().promise();
-		}
-
-		var uid = OC.getCurrentUser().uid;
-		return this.uploader.filesClient.move(
-			'uploads/' + encodeURIComponent(uid) + '/' + encodeURIComponent(this.getId()) + '/.file',
-			'files/' + encodeURIComponent(uid) + '/' + OC.joinPaths(this.getFullPath(), this.getFileName())
-		);
-	},
-
-	/**
-	 * Abort the upload
-	 */
-	abort: function() {
-		if (this.data.isChunked) {
-			// delete transfer directory for this upload
-			this.uploader.filesClient.remove(
-				'uploads/' + encodeURIComponent(OC.getCurrentUser().uid) + '/' + encodeURIComponent(this.getId())
-			);
-		}
-		this.data.abort();
-	},
-
-	/**
-	 * Returns the server response
-	 *
-	 * @return {Object} response
-	 */
-	getResponse: function() {
-		var response = this.data.response();
-		if (typeof response.result !== 'string') {
-			//fetch response from iframe
-			response = $.parseJSON(response.result[0].body.innerText);
-			if (!response) {
-				// likely due to internal server error
-				response = {status: 500};
-			}
-		} else {
-			response = response.result;
-		}
-		return response;
-	},
-
-	/**
-	 * Returns the status code from the response
-	 *
-	 * @return {int} status code
-	 */
-	getResponseStatus: function() {
-		if (this.uploader.isXHRUpload()) {
-			var xhr = this.data.response().jqXHR;
-			if (xhr) {
-				return xhr.status;
-			}
-			return null;
-		}
-		return this.getResponse().status;
-	},
-
-	/**
-	 * Returns the response header by name
-	 *
-	 * @param {String} headerName header name
-	 * @return {Array|String} response header value(s)
-	 */
-	getResponseHeader: function(headerName) {
-		headerName = headerName.toLowerCase();
-		if (this.uploader.isXHRUpload()) {
-			return this.data.response().jqXHR.getResponseHeader(headerName);
-		}
-
-		var headers = this.getResponse().headers;
-		if (!headers) {
-			return null;
-		}
-
-		var value =  _.find(headers, function(value, key) {
-			return key.toLowerCase() === headerName;
-		});
-		if (_.isArray(value) && value.length === 1) {
-			return value[0];
-		}
-		return value;
-	}
-};
-
-/**
- * keeps track of uploads in progress and implements callbacks for the conflicts dialog
- * @namespace
- */
-
-OC.Uploader = function() {
-	this.init.apply(this, arguments);
-};
-
-OC.Uploader.prototype = _.extend({
-	/**
-	 * @type Array<OC.FileUpload>
-	 */
-	_uploads: {},
-
-	/**
-	 * List of directories known to exist.
-	 *
-	 * Key is the fullpath and value is boolean, true meaning that the directory
-	 * was already created so no need to create it again.
-	 */
-	_knownDirs: {},
-
-	/**
-	 * @type OCA.Files.FileList
-	 */
-	fileList: null,
-
-	/**
-	 * @type OC.Files.Client
-	 */
-	filesClient: null,
-
-	/**
-	 * Function that will allow us to know if Ajax uploads are supported
-	 * @link https://github.com/New-Bamboo/example-ajax-upload/blob/master/public/index.html
-	 * also see article @link http://blog.new-bamboo.co.uk/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata
-	 */
-	_supportAjaxUploadWithProgress: function() {
-		if (window.TESTING) {
-			return true;
-		}
-		return supportFileAPI() && supportAjaxUploadProgressEvents() && supportFormData();
-
-		// Is the File API supported?
-		function supportFileAPI() {
-			var fi = document.createElement('INPUT');
-			fi.type = 'file';
-			return 'files' in fi;
-		}
-
-		// Are progress events supported?
-		function supportAjaxUploadProgressEvents() {
-			var xhr = new XMLHttpRequest();
-			return !! (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
-		}
-
-		// Is FormData supported?
-		function supportFormData() {
-			return !! window.FormData;
-		}
-	},
-
-	/**
-	 * Returns whether an XHR upload will be used
-	 *
-	 * @return {bool} true if XHR upload will be used,
-	 * false for iframe upload
-	 */
-	isXHRUpload: function () {
-		return !this.fileUploadParam.forceIframeTransport &&
-			((!this.fileUploadParam.multipart && $.support.xhrFileUpload) ||
-			$.support.xhrFormDataFileUpload);
-	},
-
-	/**
-	 * Makes sure that the upload folder and its parents exists
-	 *
-	 * @param {String} fullPath full path
-	 * @return {Promise} promise that resolves when all parent folders
-	 * were created
-	 */
-	ensureFolderExists: function(fullPath) {
-		if (!fullPath || fullPath === '/') {
-			return $.Deferred().resolve().promise();
-		}
-
-		// remove trailing slash
-		if (fullPath.charAt(fullPath.length - 1) === '/') {
-			fullPath = fullPath.substr(0, fullPath.length - 1);
-		}
-
-		var self = this;
-		var promise = this._knownDirs[fullPath];
-
-		if (this.fileList) {
-			// assume the current folder exists
-			this._knownDirs[this.fileList.getCurrentDirectory()] = $.Deferred().resolve().promise();
-		}
-
-		if (!promise) {
-			var deferred = new $.Deferred();
-			promise = deferred.promise();
-			this._knownDirs[fullPath] = promise;
-
-			// make sure all parents already exist
-			var parentPath = OC.dirname(fullPath);
-			var parentPromise = this._knownDirs[parentPath];
-			if (!parentPromise) {
-				parentPromise = this.ensureFolderExists(parentPath);
-			}
-
-			parentPromise.then(function() {
-				self.filesClient.createDirectory(fullPath).always(function(status) {
-					// 405 is expected if the folder already exists
-					if ((status >= 200 && status < 300) || status === 405) {
-						self.trigger('createdfolder', fullPath);
-						deferred.resolve();
-						return;
-					}
-					OC.Notification.show(t('files', 'Could not create folder "{dir}"', {dir: fullPath}), {type: 'error'});
-					deferred.reject();
-				});
-			}, function() {
-				deferred.reject();
-			});
-		}
-
-		return promise;
-	},
-
-	/**
-	 * Submit the given uploads
-	 *
-	 * @param {Array} array of uploads to start
-	 */
-	submitUploads: function(uploads) {
-		var self = this;
-		_.each(uploads, function(upload) {
-			self._uploads[upload.data.uploadId] = upload;
-			upload.submit();
-		});
-	},
-
-	/**
-	 * Show conflict for the given file object
-	 *
-	 * @param {OC.FileUpload} file upload object
-	 */
-	showConflict: function(fileUpload) {
-		//show "file already exists" dialog
-		var self = this;
-		var file = fileUpload.getFile();
-		// already attempted autorename but the server said the file exists ? (concurrently added)
-		if (fileUpload.getConflictMode() === OC.FileUpload.CONFLICT_MODE_AUTORENAME) {
-			// attempt another autorename, defer to let the current callback finish
-			_.defer(function() {
-				self.onAutorename(fileUpload);
-			});
-			return;
-		}
-		// retrieve more info about this file
-		this.filesClient.getFileInfo(fileUpload.getFullFilePath()).then(function(status, fileInfo) {
-			var original = fileInfo;
-			var replacement = file;
-			original.directory = original.path;
-			OC.dialogs.fileexists(fileUpload, original, replacement, self);
-		});
-	},
-	/**
-	 * cancels all uploads
-	 */
-	cancelUploads:function() {
-		this.log('canceling uploads');
-		jQuery.each(this._uploads, function(i, upload) {
-			upload.abort();
-		});
-		this.clear();
-	},
-	/**
-	 * Clear uploads
-	 */
-	clear: function() {
-		this._uploads = {};
-		this._knownDirs = {};
-	},
-	/**
-	 * Returns an upload by id
-	 *
-	 * @param {int} data uploadId
-	 * @return {OC.FileUpload} file upload
-	 */
-	getUpload: function(data) {
-		if (_.isString(data)) {
-			return this._uploads[data];
-		} else if (data.uploadId && this._uploads[data.uploadId]) {
-			this._uploads[data.uploadId].data = data;
-			return this._uploads[data.uploadId];
-		}
-		return null;
-	},
-
-	showUploadCancelMessage: _.debounce(function() {
-		OC.Notification.show(t('files', 'Upload cancelled.'), {timeout : 7, type: 'error'});
-	}, 500),
-	/**
-	 * callback for the conflicts dialog
-	 */
-	onCancel:function() {
-		this.cancelUploads();
-	},
-	/**
-	 * callback for the conflicts dialog
-	 * calls onSkip, onReplace or onAutorename for each conflict
-	 * @param {object} conflicts - list of conflict elements
-	 */
-	onContinue:function(conflicts) {
-		var self = this;
-		//iterate over all conflicts
-		jQuery.each(conflicts, function (i, conflict) {
-			conflict = $(conflict);
-			var keepOriginal = conflict.find('.original input[type="checkbox"]:checked').length === 1;
-			var keepReplacement = conflict.find('.replacement input[type="checkbox"]:checked').length === 1;
-			if (keepOriginal && keepReplacement) {
-				// when both selected -> autorename
-				self.onAutorename(conflict.data('data'));
-			} else if (keepReplacement) {
-				// when only replacement selected -> overwrite
-				self.onReplace(conflict.data('data'));
-			} else {
-				// when only original seleted -> skip
-				// when none selected -> skip
-				self.onSkip(conflict.data('data'));
-			}
-		});
-	},
-	/**
-	 * handle skipping an upload
-	 * @param {OC.FileUpload} upload
-	 */
-	onSkip:function(upload) {
-		this.log('skip', null, upload);
-		upload.deleteUpload();
-	},
-	/**
-	 * handle replacing a file on the server with an uploaded file
-	 * @param {FileUpload} data
-	 */
-	onReplace:function(upload) {
-		this.log('replace', null, upload);
-		upload.setConflictMode(OC.FileUpload.CONFLICT_MODE_OVERWRITE);
-		this.submitUploads([upload]);
-	},
-	/**
-	 * handle uploading a file and letting the server decide a new name
-	 * @param {object} upload
-	 */
-	onAutorename:function(upload) {
-		this.log('autorename', null, upload);
-		upload.setConflictMode(OC.FileUpload.CONFLICT_MODE_AUTORENAME);
-
-		do {
-			upload.autoRename();
-			// if file known to exist on the client side, retry
-		} while (this.fileList && this.fileList.inList(upload.getFileName()));
-
-		// resubmit upload
-		this.submitUploads([upload]);
-	},
-	_trace:false, //TODO implement log handler for JS per class?
-	log:function(caption, e, data) {
-		if (this._trace) {
-			console.log(caption);
-			console.log(data);
-		}
-	},
-	/**
-	 * checks the list of existing files prior to uploading and shows a simple dialog to choose
-	 * skip all, replace all or choose which files to keep
-	 *
-	 * @param {array} selection of files to upload
-	 * @param {object} callbacks - object with several callback methods
-	 * @param {function} callbacks.onNoConflicts
-	 * @param {function} callbacks.onSkipConflicts
-	 * @param {function} callbacks.onReplaceConflicts
-	 * @param {function} callbacks.onChooseConflicts
-	 * @param {function} callbacks.onCancel
-	 */
-	checkExistingFiles: function (selection, callbacks) {
-		var fileList = this.fileList;
-		var conflicts = [];
-		// only keep non-conflicting uploads
-		selection.uploads = _.filter(selection.uploads, function(upload) {
-			var file = upload.getFile();
-			if (file.relativePath) {
-				// can't check in subfolder contents
-				return true;
-			}
-			if (!fileList) {
-				// no list to check against
-				return true;
-			}
-			var fileInfo = fileList.findFile(file.name);
-			if (fileInfo) {
-				conflicts.push([
-					// original
-					_.extend(fileInfo, {
-						directory: fileInfo.directory || fileInfo.path || fileList.getCurrentDirectory()
-					}),
-					// replacement (File object)
-					upload
-				]);
-				return false;
-			}
-			return true;
-		});
-		if (conflicts.length) {
-			// wait for template loading
-			OC.dialogs.fileexists(null, null, null, this).done(function() {
-				_.each(conflicts, function(conflictData) {
-					OC.dialogs.fileexists(conflictData[1], conflictData[0], conflictData[1].getFile(), this);
-				});
-			});
-		}
-
-		// upload non-conflicting files
-		// note: when reaching the server they might still meet conflicts
-		// if the folder was concurrently modified, these will get added
-		// to the already visible dialog, if applicable
-		callbacks.onNoConflicts(selection);
-	},
-
-	_hideProgressBar: function() {
-		var self = this;
-		$('#uploadprogresswrapper .stop').fadeOut();
-		$('#uploadprogressbar').fadeOut(function() {
-			self.$uploadEl.trigger(new $.Event('resized'));
-		});
-	},
-
-	_showProgressBar: function() {
-		$('#uploadprogressbar').fadeIn();
-		this.$uploadEl.trigger(new $.Event('resized'));
-	},
-
-	/**
-	 * Returns whether the given file is known to be a received shared file
-	 *
-	 * @param {Object} file file
-	 * @return {bool} true if the file is a shared file
-	 */
-	_isReceivedSharedFile: function(file) {
-		if (!window.FileList) {
-			return false;
-		}
-		var $tr = window.FileList.findFileEl(file.name);
-		if (!$tr.length) {
-			return false;
-		}
-
-		return ($tr.attr('data-mounttype') === 'shared-root' && $tr.attr('data-mime') !== 'httpd/unix-directory');
-	},
-
-	/**
-	 * Initialize the upload object
-	 *
-	 * @param {Object} $uploadEl upload element
-	 * @param {Object} options
-	 * @param {OCA.Files.FileList} [options.fileList] file list object
-	 * @param {OC.Files.Client} [options.filesClient] files client object
-	 * @param {Object} [options.dropZone] drop zone for drag and drop upload
-	 */
-	init: function($uploadEl, options) {
-		var self = this;
-
-		options = options || {};
-
-		this.fileList = options.fileList;
-		this.filesClient = options.filesClient || OC.Files.getClient();
-
-		$uploadEl = $($uploadEl);
-		this.$uploadEl = $uploadEl;
-
-		if ($uploadEl.exists()) {
-			$('#uploadprogresswrapper .stop').on('click', function() {
-				self.cancelUploads();
-			});
-
-			this.fileUploadParam = {
-				type: 'PUT',
-				dropZone: options.dropZone, // restrict dropZone to content div
-				autoUpload: false,
-				sequentialUploads: true,
-				//singleFileUploads is on by default, so the data.files array will always have length 1
-				/**
-				 * on first add of every selection
-				 * - check all files of originalFiles array with files in dir
-				 * - on conflict show dialog
-				 *   - skip all -> remember as single skip action for all conflicting files
-				 *   - replace all -> remember as single replace action for all conflicting files
-				 *   - choose -> show choose dialog
-				 *     - mark files to keep
-				 *       - when only existing -> remember as single skip action
-				 *       - when only new -> remember as single replace action
-				 *       - when both -> remember as single autorename action
-				 * - start uploading selection
-				 * @param {object} e
-				 * @param {object} data
-				 * @returns {boolean}
-				 */
-				add: function(e, data) {
-					self.log('add', e, data);
-					var that = $(this), freeSpace;
-
-					var upload = new OC.FileUpload(self, data);
-					// can't link directly due to jQuery not liking cyclic deps on its ajax object
-					data.uploadId = upload.getId();
-
-					// we need to collect all data upload objects before
-					// starting the upload so we can check their existence
-					// and set individual conflict actions. Unfortunately,
-					// there is only one variable that we can use to identify
-					// the selection a data upload is part of, so we have to
-					// collect them in data.originalFiles turning
-					// singleFileUploads off is not an option because we want
-					// to gracefully handle server errors like 'already exists'
-
-					// create a container where we can store the data objects
-					if ( ! data.originalFiles.selection ) {
-						// initialize selection and remember number of files to upload
-						data.originalFiles.selection = {
-							uploads: [],
-							filesToUpload: data.originalFiles.length,
-							totalBytes: 0
-						};
-					}
-					// TODO: move originalFiles to a separate container, maybe inside OC.Upload
-					var selection = data.originalFiles.selection;
-
-					// add uploads
-					if ( selection.uploads.length < selection.filesToUpload ) {
-						// remember upload
-						selection.uploads.push(upload);
-					}
-
-					//examine file
-					var file = upload.getFile();
-					try {
-						// FIXME: not so elegant... need to refactor that method to return a value
-						Files.isFileNameValid(file.name);
-					}
-					catch (errorMessage) {
-						data.textStatus = 'invalidcharacters';
-						data.errorThrown = errorMessage;
-					}
-
-					if (data.targetDir) {
-						upload.setTargetFolder(data.targetDir);
-						delete data.targetDir;
-					}
-
-					// in case folder drag and drop is not supported file will point to a directory
-					// http://stackoverflow.com/a/20448357
-					if ( ! file.type && file.size % 4096 === 0 && file.size <= 102400) {
-						var dirUploadFailure = false;
-						try {
-							var reader = new FileReader();
-							reader.readAsBinaryString(file);
-						} catch (NS_ERROR_FILE_ACCESS_DENIED) {
-							//file is a directory
-							dirUploadFailure = true;
-						}
-
-						if (dirUploadFailure) {
-							data.textStatus = 'dirorzero';
-							data.errorThrown = t('files',
-								'Unable to upload {filename} as it is a directory or has 0 bytes',
-								{filename: file.name}
-							);
-						}
-					}
-
-					// only count if we're not overwriting an existing shared file
-					if (self._isReceivedSharedFile(file)) {
-						file.isReceivedShare = true;
-					} else {
-						// add size
-						selection.totalBytes += file.size;
-					}
-
-					// check free space
-					freeSpace = $('#free_space').val();
-					if (freeSpace >= 0 && selection.totalBytes > freeSpace) {
-						data.textStatus = 'notenoughspace';
-						data.errorThrown = t('files',
-							'Not enough free space, you are uploading {size1} but only {size2} is left', {
-							'size1': humanFileSize(selection.totalBytes),
-							'size2': humanFileSize($('#free_space').val())
-						});
-					}
-
-					// end upload for whole selection on error
-					if (data.errorThrown) {
-						// trigger fileupload fail handler
-						var fu = that.data('blueimp-fileupload') || that.data('fileupload');
-						fu._trigger('fail', e, data);
-						return false; //don't upload anything
-					}
-
-					// check existing files when all is collected
-					if ( selection.uploads.length >= selection.filesToUpload ) {
-
-						//remove our selection hack:
-						delete data.originalFiles.selection;
-
-						var callbacks = {
-
-							onNoConflicts: function (selection) {
-								self.submitUploads(selection.uploads);
-							},
-							onSkipConflicts: function (selection) {
-								//TODO mark conflicting files as toskip
-							},
-							onReplaceConflicts: function (selection) {
-								//TODO mark conflicting files as toreplace
-							},
-							onChooseConflicts: function (selection) {
-								//TODO mark conflicting files as chosen
-							},
-							onCancel: function (selection) {
-								$.each(selection.uploads, function(i, upload) {
-									upload.abort();
-								});
-							}
-						};
-
-						self.checkExistingFiles(selection, callbacks);
-
-					}
-
-					return true; // continue adding files
-				},
-				/**
-				 * called after the first add, does NOT have the data param
-				 * @param {object} e
-				 */
-				start: function(e) {
-					self.log('start', e, null);
-					//hide the tooltip otherwise it covers the progress bar
-					$('#upload').tooltip('hide');
-				},
-				fail: function(e, data) {
-					var upload = self.getUpload(data);
-					var status = null;
-					if (upload) {
-						status = upload.getResponseStatus();
-					}
-					self.log('fail', e, upload);
-
-					if (data.textStatus === 'abort') {
-						self.showUploadCancelMessage();
-					} else if (status === 412) {
-						// file already exists
-						self.showConflict(upload);
-					} else if (status === 404) {
-						// target folder does not exist any more
-						OC.Notification.show(t('files', 'Target folder "{dir}" does not exist any more', {dir: upload.getFullPath()} ), {type: 'error'});
-						self.cancelUploads();
-					} else if (status === 507) {
-						// not enough space
-						OC.Notification.show(t('files', 'Not enough free space'), {type: 'error'});
-						self.cancelUploads();
-					} else {
-						// HTTP connection problem or other error
-						OC.Notification.show(data.errorThrown, {type: 'error'});
-					}
-
-					if (upload) {
-						upload.deleteUpload();
-					}
-				},
-				/**
-				 * called for every successful upload
-				 * @param {object} e
-				 * @param {object} data
-				 */
-				done:function(e, data) {
-					var upload = self.getUpload(data);
-					var that = $(this);
-					self.log('done', e, upload);
-
-					var status = upload.getResponseStatus();
-					if (status < 200 || status >= 300) {
-						// trigger fail handler
-						var fu = that.data('blueimp-fileupload') || that.data('fileupload');
-						fu._trigger('fail', e, data);
-						return;
-					}
-				},
-				/**
-				 * called after last upload
-				 * @param {object} e
-				 * @param {object} data
-				 */
-				stop: function(e, data) {
-					self.log('stop', e, data);
-				}
-			};
-
-			// initialize jquery fileupload (blueimp)
-			var fileupload = this.$uploadEl.fileupload(this.fileUploadParam);
-
-			if (this._supportAjaxUploadWithProgress()) {
-				//remaining time
-				var lastUpdate, lastSize, bufferSize, buffer, bufferIndex, bufferIndex2, bufferTotal;
-
-				// add progress handlers
-				fileupload.on('fileuploadadd', function(e, data) {
-					self.log('progress handle fileuploadadd', e, data);
-					self.trigger('add', e, data);
-				});
-				// add progress handlers
-				fileupload.on('fileuploadstart', function(e, data) {
-					self.log('progress handle fileuploadstart', e, data);
-					$('#uploadprogresswrapper .stop').show();
-					$('#uploadprogresswrapper .label').show();
-					$('#uploadprogressbar').progressbar({value: 0});
-					$('#uploadprogressbar .ui-progressbar-value').
-						html('<em class="label inner"><span class="desktop">'
-							+ t('files', 'Uploading...')
-							+ '</span><span class="mobile">'
-							+ t('files', '...')
-							+ '</span></em>');
-					$('#uploadprogressbar').tooltip({placement: 'bottom'});
-					self._showProgressBar();
-					// initial remaining time variables
-					lastUpdate   = new Date().getTime();
-					lastSize     = 0;
-					bufferSize   = 20;
-					buffer       = [];
-					bufferIndex  = 0;
-					bufferIndex2 = 0;
-					bufferTotal  = 0;
-					for(var i = 0; i < bufferSize; i++){
-						buffer[i]  = 0;
-					}
-					self.trigger('start', e, data);
-				});
-				fileupload.on('fileuploadprogress', function(e, data) {
-					self.log('progress handle fileuploadprogress', e, data);
-					//TODO progressbar in row
-					self.trigger('progress', e, data);
-				});
-				fileupload.on('fileuploadprogressall', function(e, data) {
-					self.log('progress handle fileuploadprogressall', e, data);
-					var progress = (data.loaded / data.total) * 100;
-					var thisUpdate = new Date().getTime();
-					var diffUpdate = (thisUpdate - lastUpdate)/1000; // eg. 2s
-					lastUpdate = thisUpdate;
-					var diffSize = data.loaded - lastSize;
-					lastSize = data.loaded;
-					diffSize = diffSize / diffUpdate; // apply timing factor, eg. 1MiB/2s = 0.5MiB/s, unit is byte per second
-					var remainingSeconds = ((data.total - data.loaded) / diffSize);
-					if(remainingSeconds >= 0) {
-						bufferTotal = bufferTotal - (buffer[bufferIndex]) + remainingSeconds;
-						buffer[bufferIndex] = remainingSeconds; //buffer to make it smoother
-						bufferIndex = (bufferIndex + 1) % bufferSize;
-						bufferIndex2++;
-					}
-					var smoothRemainingSeconds;
-					if (bufferIndex2 > 0 && bufferIndex2 < 20) {
-						smoothRemainingSeconds = bufferTotal / bufferIndex2;
-					} else if (bufferSize > 0) {
-						smoothRemainingSeconds = bufferTotal / bufferSize;
-					} else {
-						smoothRemainingSeconds = 1;
-					}
-
-					var h = moment.duration(smoothRemainingSeconds, "seconds").humanize();
-					if (!(smoothRemainingSeconds >= 0 && smoothRemainingSeconds < 14400)) {
-						// show "Uploading ..." for durations longer than 4 hours
-						h = t('files', 'Uploading...');
-					}
-					$('#uploadprogressbar .label .mobile').text(h);
-					$('#uploadprogressbar .label .desktop').text(h);
-					$('#uploadprogressbar').attr('original-title',
-						t('files', '{loadedSize} of {totalSize} ({bitrate})' , {
-							loadedSize: humanFileSize(data.loaded),
-							totalSize: humanFileSize(data.total),
-							bitrate: humanFileSize(data.bitrate / 8) + '/s'
-						})
-					);
-					$('#uploadprogressbar').progressbar('value', progress);
-					self.trigger('progressall', e, data);
-				});
-				fileupload.on('fileuploadstop', function(e, data) {
-					self.log('progress handle fileuploadstop', e, data);
-
-					self.clear();
-					self._hideProgressBar();
-					self.trigger('stop', e, data);
-				});
-				fileupload.on('fileuploadfail', function(e, data) {
-					self.log('progress handle fileuploadfail', e, data);
-					//if user pressed cancel hide upload progress bar and cancel button
-					if (data.errorThrown === 'abort') {
-						self._hideProgressBar();
-					}
-					self.trigger('fail', e, data);
-				});
-				var disableDropState = function() {
-					$('#app-content').removeClass('file-drag');
-					$('.dropping-to-dir').removeClass('dropping-to-dir');
-					$('.dir-drop').removeClass('dir-drop');
-					$('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept');
-				};
-				var disableClassOnFirefox = _.debounce(function() {
-					disableDropState();
-				}, 100);
-				fileupload.on('fileuploaddragover', function(e){
-					$('#app-content').addClass('file-drag');
-					// dropping a folder in firefox doesn't cause a drop event
-					// this is simulated by simply invoke disabling all classes
-					// once no dragover event isn't noticed anymore
-					if (/Firefox/i.test(navigator.userAgent)) {
-						disableClassOnFirefox();
-					}
-					$('#emptycontent .icon-folder').addClass('icon-filetype-folder-drag-accept');
-
-					var filerow = $(e.delegatedEvent.target).closest('tr');
-
-					if(!filerow.hasClass('dropping-to-dir')){
-						$('.dropping-to-dir .icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept');
-						$('.dropping-to-dir').removeClass('dropping-to-dir');
-						$('.dir-drop').removeClass('dir-drop');
-					}
-
-					if(filerow.attr('data-type') === 'dir'){
-						$('#app-content').addClass('dir-drop');
-						filerow.addClass('dropping-to-dir');
-						filerow.find('.thumbnail').addClass('icon-filetype-folder-drag-accept');
-					}
-				});
-				fileupload.on('fileuploaddragleave fileuploaddrop', function (){
-					$('#app-content').removeClass('file-drag');
-					$('.dropping-to-dir').removeClass('dropping-to-dir');
-					$('.dir-drop').removeClass('dir-drop');
-					$('.icon-filetype-folder-drag-accept').removeClass('icon-filetype-folder-drag-accept');
-				});
-
-				fileupload.on('fileuploadchunksend', function(e, data) {
-					// modify the request to adjust it to our own chunking
-					var upload = self.getUpload(data);
-					var range = data.contentRange.split(' ')[1];
-					var chunkId = range.split('/')[0];
-					data.url = OC.getRootPath() +
-						'/remote.php/dav/uploads' +
-						'/' + encodeURIComponent(OC.getCurrentUser().uid) +
-						'/' + encodeURIComponent(upload.getId()) +
-						'/' + encodeURIComponent(chunkId);
-					delete data.contentRange;
-					delete data.headers['Content-Range'];
-				});
-				fileupload.on('fileuploaddone', function(e, data) {
-					var upload = self.getUpload(data);
-					upload.done().then(function() {
-						self.trigger('done', e, upload);
-					});
-				});
-				fileupload.on('fileuploaddrop', function(e, data) {
-					self.trigger('drop', e, data);
-					if (e.isPropagationStopped()) {
-						return false;
-					}
-				});
-
-			}
-		}
-
-		//add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
-		if (navigator.userAgent.search(/konqueror/i) === -1) {
-			this.$uploadEl.attr('multiple', 'multiple');
-		}
-
-		return this.fileUploadParam;
-	}
-}, OC.Backbone.Events);
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Files */
-
-(function() {
-
-	var TEMPLATE_MENU =
-		'<ul>' +
-		'<li>' +
-		'<label for="file_upload_start" class="menuitem" data-action="upload" title="{{uploadMaxHumanFilesize}}"><span class="svg icon icon-upload"></span><span class="displayname">{{uploadLabel}}</span></label>' +
-		'</li>' +
-		'{{#each items}}' +
-		'<li>' +
-		'<a href="#" class="menuitem" data-templatename="{{templateName}}" data-filetype="{{fileType}}" data-action="{{id}}"><span class="icon {{iconClass}} svg"></span><span class="displayname">{{displayName}}</span></a>' +
-		'</li>' +
-		'{{/each}}' +
-		'</ul>';
-
-	var TEMPLATE_FILENAME_FORM =
-		'<form class="filenameform">' +
-		'<label class="hidden-visually" for="{{cid}}-input-{{fileType}}">{{fileName}}</label>' +
-		'<input id="{{cid}}-input-{{fileType}}" type="text" value="{{fileName}}" autocomplete="off" autocapitalize="off">' +
-		'</form>';
-
-	/**
-	 * Construct a new NewFileMenu instance
-	 * @constructs NewFileMenu
-	 *
-	 * @memberof OCA.Files
-	 */
-	var NewFileMenu = OC.Backbone.View.extend({
-		tagName: 'div',
-		// Menu is opened by default because it's rendered on "add-button" click
-		className: 'newFileMenu popovermenu bubble menu open menu-left',
-
-		events: {
-			'click .menuitem': '_onClickAction'
-		},
-
-		/**
-		 * @type OCA.Files.FileList
-		 */
-		fileList: null,
-
-		initialize: function(options) {
-			var self = this;
-			var $uploadEl = $('#file_upload_start');
-			if ($uploadEl.length) {
-				$uploadEl.on('fileuploadstart', function() {
-					self.trigger('actionPerformed', 'upload');
-				});
-			} else {
-				console.warn('Missing upload element "file_upload_start"');
-			}
-
-			this.fileList = options && options.fileList;
-
-			this._menuItems = [{
-				id: 'folder',
-				displayName: t('files', 'New folder'),
-				templateName: t('files', 'New folder'),
-				iconClass: 'icon-folder',
-				fileType: 'folder',
-				actionHandler: function(name) {
-					self.fileList.createDirectory(name);
-				}
-		        }];
-
-			OC.Plugins.attach('OCA.Files.NewFileMenu', this);
-		},
-
-		template: function(data) {
-			if (!OCA.Files.NewFileMenu._TEMPLATE) {
-				OCA.Files.NewFileMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
-			}
-			return OCA.Files.NewFileMenu._TEMPLATE(data);
-		},
-
-		/**
-		 * Event handler whenever an action has been clicked within the menu
-		 *
-		 * @param {Object} event event object
-		 */
-		_onClickAction: function(event) {
-			var $target = $(event.target);
-			if (!$target.hasClass('menuitem')) {
-				$target = $target.closest('.menuitem');
-			}
-			var action = $target.attr('data-action');
-			// note: clicking the upload label will automatically
-			// set the focus on the "file_upload_start" hidden field
-			// which itself triggers the upload dialog.
-			// Currently the upload logic is still in file-upload.js and filelist.js
-			if (action === 'upload') {
-				OC.hideMenus();
-			} else {
-				event.preventDefault();
-				this.$el.find('.menuitem.active').removeClass('active');
-				$target.addClass('active');
-				this._promptFileName($target);
-			}
-		},
-
-		_promptFileName: function($target) {
-			var self = this;
-			if (!OCA.Files.NewFileMenu._TEMPLATE_FORM) {
-				OCA.Files.NewFileMenu._TEMPLATE_FORM = Handlebars.compile(TEMPLATE_FILENAME_FORM);
-			}
-
-			if ($target.find('form').length) {
-				$target.find('input').focus();
-				return;
-			}
-
-			// discard other forms
-			this.$el.find('form').remove();
-			this.$el.find('.displayname').removeClass('hidden');
-
-			$target.find('.displayname').addClass('hidden');
-
-			var newName = $target.attr('data-templatename');
-			var fileType = $target.attr('data-filetype');
-			var $form = $(OCA.Files.NewFileMenu._TEMPLATE_FORM({
-				fileName: newName,
-				cid: this.cid,
-				fileType: fileType
-			}));
-
-			//this.trigger('actionPerformed', action);
-			$target.append($form);
-
-			// here comes the OLD code
-			var $input = $form.find('input');
-
-			var lastPos;
-			var checkInput = function () {
-				var filename = $input.val();
-				try {
-					if (!Files.isFileNameValid(filename)) {
-						// Files.isFileNameValid(filename) throws an exception itself
-					} else if (self.fileList.inList(filename)) {
-						throw t('files', '{newName} already exists', {newName: filename}, undefined, {
-							escape: false
-						});
-					} else {
-						return true;
-					}
-				} catch (error) {
-					$input.attr('title', error);
-					$input.tooltip({placement: 'right', trigger: 'manual'});
-					$input.tooltip('fixTitle');
-					$input.tooltip('show');
-					$input.addClass('error');
-				}
-				return false;
-			};
-
-			// verify filename on typing
-			$input.keyup(function() {
-				if (checkInput()) {
-					$input.tooltip('hide');
-					$input.removeClass('error');
-				}
-			});
-
-			$input.focus();
-			// pre select name up to the extension
-			lastPos = newName.lastIndexOf('.');
-			if (lastPos === -1) {
-				lastPos = newName.length;
-			}
-			$input.selectRange(0, lastPos);
-
-			$form.submit(function(event) {
-				event.stopPropagation();
-				event.preventDefault();
-
-				if (checkInput()) {
-					var newname = $input.val();
-
-					/* Find the right actionHandler that should be called.
-					 * Actions is retrieved by using `actionSpec.id` */
-					action = _.filter(self._menuItems, function(item) {
-						return item.id == $target.attr('data-action');
-					}).pop();
-					action.actionHandler(newname);
-
-					$form.remove();
-					$target.find('.displayname').removeClass('hidden');
-					OC.hideMenus();
-				}
-			});
-		},
-
-		/**
-		* Add a new item menu entry in the “New” file menu (in
-		* last position). By clicking on the item, the
-		* `actionHandler` function is called.
-		*
-		* @param {Object} actionSpec item’s properties
-		*/
-		addMenuEntry: function(actionSpec) {
-			this._menuItems.push({
-				id: actionSpec.id,
-				displayName: actionSpec.displayName,
-				templateName: actionSpec.templateName,
-				iconClass: actionSpec.iconClass,
-				fileType: actionSpec.fileType,
-				actionHandler: actionSpec.actionHandler,
-		        });
-		},
-
-		/**
-		 * Renders the menu with the currently set items
-		 */
-		render: function() {
-			this.$el.html(this.template({
-				uploadMaxHumanFileSize: 'TODO',
-				uploadLabel: t('files', 'Upload file'),
-				items: this._menuItems
-			}));
-			OC.Util.scaleFixForIE8(this.$('.svg'));
-		},
-
-		/**
-		 * Displays the menu under the given element
-		 *
-		 * @param {Object} $target target element
-		 */
-		showAt: function($target) {
-			this.render();
-			OC.showMenu(null, this.$el);
-		}
-	});
-
-	OCA.Files.NewFileMenu = NewFileMenu;
-
-})();
-
-
-/*
- * jQuery File Upload Plugin 9.12.5
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window, document, location, Blob, FormData */
-
-;(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define([
-            'jquery',
-            'jquery.ui.widget'
-        ], factory);
-    } else if (typeof exports === 'object') {
-        // Node/CommonJS:
-        factory(
-            require('jquery'),
-            require('./vendor/jquery.ui.widget')
-        );
-    } else {
-        // Browser globals:
-        factory(window.jQuery);
-    }
-}(function ($) {
-    'use strict';
-
-    // Detect file input support, based on
-    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
-    $.support.fileInput = !(new RegExp(
-        // Handle devices which give false positives for the feature detection:
-        '(Android (1\\.[0156]|2\\.[01]))' +
-            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
-            '|(w(eb)?OSBrowser)|(webOS)' +
-            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
-    ).test(window.navigator.userAgent) ||
-        // Feature detection for all other devices:
-        $('<input type="file">').prop('disabled'));
-
-    // The FileReader API is not actually used, but works as feature detection,
-    // as some Safari versions (5?) support XHR file uploads via the FormData API,
-    // but not non-multipart XHR file uploads.
-    // window.XMLHttpRequestUpload is not available on IE10, so we check for
-    // window.ProgressEvent instead to detect XHR2 file upload capability:
-    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
-    $.support.xhrFormDataFileUpload = !!window.FormData;
-
-    // Detect support for Blob slicing (required for chunked uploads):
-    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
-        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
-
-    // Helper function to create drag handlers for dragover/dragenter/dragleave:
-    function getDragHandler(type) {
-        var isDragOver = type === 'dragover';
-        return function (e) {
-            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
-            var dataTransfer = e.dataTransfer;
-            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
-                    this._trigger(
-                        type,
-                        $.Event(type, {delegatedEvent: e})
-                    ) !== false) {
-                e.preventDefault();
-                if (isDragOver) {
-                    dataTransfer.dropEffect = 'copy';
-                }
-            }
-        };
-    }
-
-    // The fileupload widget listens for change events on file input fields defined
-    // via fileInput setting and paste or drop events of the given dropZone.
-    // In addition to the default jQuery Widget methods, the fileupload widget
-    // exposes the "add" and "send" methods, to add or directly send files using
-    // the fileupload API.
-    // By default, files added via file input selection, paste, drag & drop or
-    // "add" method are uploaded immediately, but it is possible to override
-    // the "add" callback option to queue file uploads.
-    $.widget('blueimp.fileupload', {
-
-        options: {
-            // The drop target element(s), by the default the complete document.
-            // Set to null to disable drag & drop support:
-            dropZone: $(document),
-            // The paste target element(s), by the default undefined.
-            // Set to a DOM node or jQuery object to enable file pasting:
-            pasteZone: undefined,
-            // The file input field(s), that are listened to for change events.
-            // If undefined, it is set to the file input fields inside
-            // of the widget element on plugin initialization.
-            // Set to null to disable the change listener.
-            fileInput: undefined,
-            // By default, the file input field is replaced with a clone after
-            // each input field change event. This is required for iframe transport
-            // queues and allows change events to be fired for the same file
-            // selection, but can be disabled by setting the following option to false:
-            replaceFileInput: true,
-            // The parameter name for the file form data (the request argument name).
-            // If undefined or empty, the name property of the file input field is
-            // used, or "files[]" if the file input name property is also empty,
-            // can be a string or an array of strings:
-            paramName: undefined,
-            // By default, each file of a selection is uploaded using an individual
-            // request for XHR type uploads. Set to false to upload file
-            // selections in one request each:
-            singleFileUploads: true,
-            // To limit the number of files uploaded with one XHR request,
-            // set the following option to an integer greater than 0:
-            limitMultiFileUploads: undefined,
-            // The following option limits the number of files uploaded with one
-            // XHR request to keep the request size under or equal to the defined
-            // limit in bytes:
-            limitMultiFileUploadSize: undefined,
-            // Multipart file uploads add a number of bytes to each uploaded file,
-            // therefore the following option adds an overhead for each file used
-            // in the limitMultiFileUploadSize configuration:
-            limitMultiFileUploadSizeOverhead: 512,
-            // Set the following option to true to issue all file upload requests
-            // in a sequential order:
-            sequentialUploads: false,
-            // To limit the number of concurrent uploads,
-            // set the following option to an integer greater than 0:
-            limitConcurrentUploads: undefined,
-            // Set the following option to true to force iframe transport uploads:
-            forceIframeTransport: false,
-            // Set the following option to the location of a redirect url on the
-            // origin server, for cross-domain iframe transport uploads:
-            redirect: undefined,
-            // The parameter name for the redirect url, sent as part of the form
-            // data and set to 'redirect' if this option is empty:
-            redirectParamName: undefined,
-            // Set the following option to the location of a postMessage window,
-            // to enable postMessage transport uploads:
-            postMessage: undefined,
-            // By default, XHR file uploads are sent as multipart/form-data.
-            // The iframe transport is always using multipart/form-data.
-            // Set to false to enable non-multipart XHR uploads:
-            multipart: true,
-            // To upload large files in smaller chunks, set the following option
-            // to a preferred maximum chunk size. If set to 0, null or undefined,
-            // or the browser does not support the required Blob API, files will
-            // be uploaded as a whole.
-            maxChunkSize: undefined,
-            // When a non-multipart upload or a chunked multipart upload has been
-            // aborted, this option can be used to resume the upload by setting
-            // it to the size of the already uploaded bytes. This option is most
-            // useful when modifying the options object inside of the "add" or
-            // "send" callbacks, as the options are cloned for each file upload.
-            uploadedBytes: undefined,
-            // By default, failed (abort or error) file uploads are removed from the
-            // global progress calculation. Set the following option to false to
-            // prevent recalculating the global progress data:
-            recalculateProgress: true,
-            // Interval in milliseconds to calculate and trigger progress events:
-            progressInterval: 100,
-            // Interval in milliseconds to calculate progress bitrate:
-            bitrateInterval: 500,
-            // By default, uploads are started automatically when adding files:
-            autoUpload: true,
-
-            // Error and info messages:
-            messages: {
-                uploadedBytes: 'Uploaded bytes exceed file size'
-            },
-
-            // Translation function, gets the message key to be translated
-            // and an object with context specific data as arguments:
-            i18n: function (message, context) {
-                message = this.messages[message] || message.toString();
-                if (context) {
-                    $.each(context, function (key, value) {
-                        message = message.replace('{' + key + '}', value);
-                    });
-                }
-                return message;
-            },
-
-            // Additional form data to be sent along with the file uploads can be set
-            // using this option, which accepts an array of objects with name and
-            // value properties, a function returning such an array, a FormData
-            // object (for XHR file uploads), or a simple object.
-            // The form of the first fileInput is given as parameter to the function:
-            formData: function (form) {
-                return form.serializeArray();
-            },
-
-            // The add callback is invoked as soon as files are added to the fileupload
-            // widget (via file input selection, drag & drop, paste or add API call).
-            // If the singleFileUploads option is enabled, this callback will be
-            // called once for each file in the selection for XHR file uploads, else
-            // once for each file selection.
-            //
-            // The upload starts when the submit method is invoked on the data parameter.
-            // The data object contains a files property holding the added files
-            // and allows you to override plugin options as well as define ajax settings.
-            //
-            // Listeners for this callback can also be bound the following way:
-            // .bind('fileuploadadd', func);
-            //
-            // data.submit() returns a Promise object and allows to attach additional
-            // handlers using jQuery's Deferred callbacks:
-            // data.submit().done(func).fail(func).always(func);
-            add: function (e, data) {
-                if (e.isDefaultPrevented()) {
-                    return false;
-                }
-                if (data.autoUpload || (data.autoUpload !== false &&
-                        $(this).fileupload('option', 'autoUpload'))) {
-                    data.process().done(function () {
-                        data.submit();
-                    });
-                }
-            },
-
-            // Other callbacks:
-
-            // Callback for the submit event of each file upload:
-            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
-
-            // Callback for the start of each file upload request:
-            // send: function (e, data) {}, // .bind('fileuploadsend', func);
-
-            // Callback for successful uploads:
-            // done: function (e, data) {}, // .bind('fileuploaddone', func);
-
-            // Callback for failed (abort or error) uploads:
-            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
-
-            // Callback for completed (success, abort or error) requests:
-            // always: function (e, data) {}, // .bind('fileuploadalways', func);
-
-            // Callback for upload progress events:
-            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
-
-            // Callback for global upload progress events:
-            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
-
-            // Callback for uploads start, equivalent to the global ajaxStart event:
-            // start: function (e) {}, // .bind('fileuploadstart', func);
-
-            // Callback for uploads stop, equivalent to the global ajaxStop event:
-            // stop: function (e) {}, // .bind('fileuploadstop', func);
-
-            // Callback for change events of the fileInput(s):
-            // change: function (e, data) {}, // .bind('fileuploadchange', func);
-
-            // Callback for paste events to the pasteZone(s):
-            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
-
-            // Callback for drop events of the dropZone(s):
-            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
-
-            // Callback for dragover events of the dropZone(s):
-            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
-
-            // Callback for the start of each chunk upload request:
-            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
-
-            // Callback for successful chunk uploads:
-            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
-
-            // Callback for failed (abort or error) chunk uploads:
-            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
-
-            // Callback for completed (success, abort or error) chunk upload requests:
-            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
-
-            // The plugin options are used as settings object for the ajax calls.
-            // The following are jQuery ajax settings required for the file uploads:
-            processData: false,
-            contentType: false,
-            cache: false,
-            timeout: 0
-        },
-
-        // A list of options that require reinitializing event listeners and/or
-        // special initialization code:
-        _specialOptions: [
-            'fileInput',
-            'dropZone',
-            'pasteZone',
-            'multipart',
-            'forceIframeTransport'
-        ],
-
-        _blobSlice: $.support.blobSlice && function () {
-            var slice = this.slice || this.webkitSlice || this.mozSlice;
-            return slice.apply(this, arguments);
-        },
-
-        _BitrateTimer: function () {
-            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
-            this.loaded = 0;
-            this.bitrate = 0;
-            this.getBitrate = function (now, loaded, interval) {
-                var timeDiff = now - this.timestamp;
-                if (!this.bitrate || !interval || timeDiff > interval) {
-                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
-                    this.loaded = loaded;
-                    this.timestamp = now;
-                }
-                return this.bitrate;
-            };
-        },
-
-        _isXHRUpload: function (options) {
-            return !options.forceIframeTransport &&
-                ((!options.multipart && $.support.xhrFileUpload) ||
-                $.support.xhrFormDataFileUpload);
-        },
-
-        _getFormData: function (options) {
-            var formData;
-            if ($.type(options.formData) === 'function') {
-                return options.formData(options.form);
-            }
-            if ($.isArray(options.formData)) {
-                return options.formData;
-            }
-            if ($.type(options.formData) === 'object') {
-                formData = [];
-                $.each(options.formData, function (name, value) {
-                    formData.push({name: name, value: value});
-                });
-                return formData;
-            }
-            return [];
-        },
-
-        _getTotal: function (files) {
-            var total = 0;
-            $.each(files, function (index, file) {
-                total += file.size || 1;
-            });
-            return total;
-        },
-
-        _initProgressObject: function (obj) {
-            var progress = {
-                loaded: 0,
-                total: 0,
-                bitrate: 0
-            };
-            if (obj._progress) {
-                $.extend(obj._progress, progress);
-            } else {
-                obj._progress = progress;
-            }
-        },
-
-        _initResponseObject: function (obj) {
-            var prop;
-            if (obj._response) {
-                for (prop in obj._response) {
-                    if (obj._response.hasOwnProperty(prop)) {
-                        delete obj._response[prop];
-                    }
-                }
-            } else {
-                obj._response = {};
-            }
-        },
-
-        _onProgress: function (e, data) {
-            if (e.lengthComputable) {
-                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
-                    loaded;
-                if (data._time && data.progressInterval &&
-                        (now - data._time < data.progressInterval) &&
-                        e.loaded !== e.total) {
-                    return;
-                }
-                data._time = now;
-                loaded = Math.floor(
-                    e.loaded / e.total * (data.chunkSize || data._progress.total)
-                ) + (data.uploadedBytes || 0);
-                // Add the difference from the previously loaded state
-                // to the global loaded counter:
-                this._progress.loaded += (loaded - data._progress.loaded);
-                this._progress.bitrate = this._bitrateTimer.getBitrate(
-                    now,
-                    this._progress.loaded,
-                    data.bitrateInterval
-                );
-                data._progress.loaded = data.loaded = loaded;
-                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
-                    now,
-                    loaded,
-                    data.bitrateInterval
-                );
-                // Trigger a custom progress event with a total data property set
-                // to the file size(s) of the current upload and a loaded data
-                // property calculated accordingly:
-                this._trigger(
-                    'progress',
-                    $.Event('progress', {delegatedEvent: e}),
-                    data
-                );
-                // Trigger a global progress event for all current file uploads,
-                // including ajax calls queued for sequential file uploads:
-                this._trigger(
-                    'progressall',
-                    $.Event('progressall', {delegatedEvent: e}),
-                    this._progress
-                );
-            }
-        },
-
-        _initProgressListener: function (options) {
-            var that = this,
-                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
-            // Accesss to the native XHR object is required to add event listeners
-            // for the upload progress event:
-            if (xhr.upload) {
-                $(xhr.upload).bind('progress', function (e) {
-                    var oe = e.originalEvent;
-                    // Make sure the progress event properties get copied over:
-                    e.lengthComputable = oe.lengthComputable;
-                    e.loaded = oe.loaded;
-                    e.total = oe.total;
-                    that._onProgress(e, options);
-                });
-                options.xhr = function () {
-                    return xhr;
-                };
-            }
-        },
-
-        _isInstanceOf: function (type, obj) {
-            // Cross-frame instanceof check
-            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
-        },
-
-        _initXHRData: function (options) {
-            var that = this,
-                formData,
-                file = options.files[0],
-                // Ignore non-multipart setting if not supported:
-                multipart = options.multipart || !$.support.xhrFileUpload,
-                paramName = $.type(options.paramName) === 'array' ?
-                    options.paramName[0] : options.paramName;
-            options.headers = $.extend({}, options.headers);
-            if (options.contentRange) {
-                options.headers['Content-Range'] = options.contentRange;
-            }
-            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
-                options.headers['Content-Disposition'] = 'attachment; filename="' +
-                    encodeURI(file.name) + '"';
-            }
-            if (!multipart) {
-                options.contentType = file.type || 'application/octet-stream';
-                options.data = options.blob || file;
-            } else if ($.support.xhrFormDataFileUpload) {
-                if (options.postMessage) {
-                    // window.postMessage does not allow sending FormData
-                    // objects, so we just add the File/Blob objects to
-                    // the formData array and let the postMessage window
-                    // create the FormData object out of this array:
-                    formData = this._getFormData(options);
-                    if (options.blob) {
-                        formData.push({
-                            name: paramName,
-                            value: options.blob
-                        });
-                    } else {
-                        $.each(options.files, function (index, file) {
-                            formData.push({
-                                name: ($.type(options.paramName) === 'array' &&
-                                    options.paramName[index]) || paramName,
-                                value: file
-                            });
-                        });
-                    }
-                } else {
-                    if (that._isInstanceOf('FormData', options.formData)) {
-                        formData = options.formData;
-                    } else {
-                        formData = new FormData();
-                        $.each(this._getFormData(options), function (index, field) {
-                            formData.append(field.name, field.value);
-                        });
-                    }
-                    if (options.blob) {
-                        formData.append(paramName, options.blob, file.name);
-                    } else {
-                        $.each(options.files, function (index, file) {
-                            // This check allows the tests to run with
-                            // dummy objects:
-                            if (that._isInstanceOf('File', file) ||
-                                    that._isInstanceOf('Blob', file)) {
-                                formData.append(
-                                    ($.type(options.paramName) === 'array' &&
-                                        options.paramName[index]) || paramName,
-                                    file,
-                                    file.uploadName || file.name
-                                );
-                            }
-                        });
-                    }
-                }
-                options.data = formData;
-            }
-            // Blob reference is not needed anymore, free memory:
-            options.blob = null;
-        },
-
-        _initIframeSettings: function (options) {
-            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
-            // Setting the dataType to iframe enables the iframe transport:
-            options.dataType = 'iframe ' + (options.dataType || '');
-            // The iframe transport accepts a serialized array as form data:
-            options.formData = this._getFormData(options);
-            // Add redirect url to form data on cross-domain uploads:
-            if (options.redirect && targetHost && targetHost !== location.host) {
-                options.formData.push({
-                    name: options.redirectParamName || 'redirect',
-                    value: options.redirect
-                });
-            }
-        },
-
-        _initDataSettings: function (options) {
-            if (this._isXHRUpload(options)) {
-                if (!this._chunkedUpload(options, true)) {
-                    if (!options.data) {
-                        this._initXHRData(options);
-                    }
-                    this._initProgressListener(options);
-                }
-                if (options.postMessage) {
-                    // Setting the dataType to postmessage enables the
-                    // postMessage transport:
-                    options.dataType = 'postmessage ' + (options.dataType || '');
-                }
-            } else {
-                this._initIframeSettings(options);
-            }
-        },
-
-        _getParamName: function (options) {
-            var fileInput = $(options.fileInput),
-                paramName = options.paramName;
-            if (!paramName) {
-                paramName = [];
-                fileInput.each(function () {
-                    var input = $(this),
-                        name = input.prop('name') || 'files[]',
-                        i = (input.prop('files') || [1]).length;
-                    while (i) {
-                        paramName.push(name);
-                        i -= 1;
-                    }
-                });
-                if (!paramName.length) {
-                    paramName = [fileInput.prop('name') || 'files[]'];
-                }
-            } else if (!$.isArray(paramName)) {
-                paramName = [paramName];
-            }
-            return paramName;
-        },
-
-        _initFormSettings: function (options) {
-            // Retrieve missing options from the input field and the
-            // associated form, if available:
-            if (!options.form || !options.form.length) {
-                options.form = $(options.fileInput.prop('form'));
-                // If the given file input doesn't have an associated form,
-                // use the default widget file input's form:
-                if (!options.form.length) {
-                    options.form = $(this.options.fileInput.prop('form'));
-                }
-            }
-            options.paramName = this._getParamName(options);
-            if (!options.url) {
-                options.url = options.form.prop('action') || location.href;
-            }
-            // The HTTP request method must be "POST" or "PUT":
-            options.type = (options.type ||
-                ($.type(options.form.prop('method')) === 'string' &&
-                    options.form.prop('method')) || ''
-                ).toUpperCase();
-            if (options.type !== 'POST' && options.type !== 'PUT' &&
-                    options.type !== 'PATCH') {
-                options.type = 'POST';
-            }
-            if (!options.formAcceptCharset) {
-                options.formAcceptCharset = options.form.attr('accept-charset');
-            }
-        },
-
-        _getAJAXSettings: function (data) {
-            var options = $.extend({}, this.options, data);
-            this._initFormSettings(options);
-            this._initDataSettings(options);
-            return options;
-        },
-
-        // jQuery 1.6 doesn't provide .state(),
-        // while jQuery 1.8+ removed .isRejected() and .isResolved():
-        _getDeferredState: function (deferred) {
-            if (deferred.state) {
-                return deferred.state();
-            }
-            if (deferred.isResolved()) {
-                return 'resolved';
-            }
-            if (deferred.isRejected()) {
-                return 'rejected';
-            }
-            return 'pending';
-        },
-
-        // Maps jqXHR callbacks to the equivalent
-        // methods of the given Promise object:
-        _enhancePromise: function (promise) {
-            promise.success = promise.done;
-            promise.error = promise.fail;
-            promise.complete = promise.always;
-            return promise;
-        },
-
-        // Creates and returns a Promise object enhanced with
-        // the jqXHR methods abort, success, error and complete:
-        _getXHRPromise: function (resolveOrReject, context, args) {
-            var dfd = $.Deferred(),
-                promise = dfd.promise();
-            context = context || this.options.context || promise;
-            if (resolveOrReject === true) {
-                dfd.resolveWith(context, args);
-            } else if (resolveOrReject === false) {
-                dfd.rejectWith(context, args);
-            }
-            promise.abort = dfd.promise;
-            return this._enhancePromise(promise);
-        },
-
-        // Adds convenience methods to the data callback argument:
-        _addConvenienceMethods: function (e, data) {
-            var that = this,
-                getPromise = function (args) {
-                    return $.Deferred().resolveWith(that, args).promise();
-                };
-            data.process = function (resolveFunc, rejectFunc) {
-                if (resolveFunc || rejectFunc) {
-                    data._processQueue = this._processQueue =
-                        (this._processQueue || getPromise([this])).then(
-                            function () {
-                                if (data.errorThrown) {
-                                    return $.Deferred()
-                                        .rejectWith(that, [data]).promise();
-                                }
-                                return getPromise(arguments);
-                            }
-                        ).then(resolveFunc, rejectFunc);
-                }
-                return this._processQueue || getPromise([this]);
-            };
-            data.submit = function () {
-                if (this.state() !== 'pending') {
-                    data.jqXHR = this.jqXHR =
-                        (that._trigger(
-                            'submit',
-                            $.Event('submit', {delegatedEvent: e}),
-                            this
-                        ) !== false) && that._onSend(e, this);
-                }
-                return this.jqXHR || that._getXHRPromise();
-            };
-            data.abort = function () {
-                if (this.jqXHR) {
-                    return this.jqXHR.abort();
-                }
-                this.errorThrown = 'abort';
-                that._trigger('fail', null, this);
-                return that._getXHRPromise(false);
-            };
-            data.state = function () {
-                if (this.jqXHR) {
-                    return that._getDeferredState(this.jqXHR);
-                }
-                if (this._processQueue) {
-                    return that._getDeferredState(this._processQueue);
-                }
-            };
-            data.processing = function () {
-                return !this.jqXHR && this._processQueue && that
-                    ._getDeferredState(this._processQueue) === 'pending';
-            };
-            data.progress = function () {
-                return this._progress;
-            };
-            data.response = function () {
-                return this._response;
-            };
-        },
-
-        // Parses the Range header from the server response
-        // and returns the uploaded bytes:
-        _getUploadedBytes: function (jqXHR) {
-            var range = jqXHR.getResponseHeader('Range'),
-                parts = range && range.split('-'),
-                upperBytesPos = parts && parts.length > 1 &&
-                    parseInt(parts[1], 10);
-            return upperBytesPos && upperBytesPos + 1;
-        },
-
-        // Uploads a file in multiple, sequential requests
-        // by splitting the file up in multiple blob chunks.
-        // If the second parameter is true, only tests if the file
-        // should be uploaded in chunks, but does not invoke any
-        // upload requests:
-        _chunkedUpload: function (options, testOnly) {
-            options.uploadedBytes = options.uploadedBytes || 0;
-            var that = this,
-                file = options.files[0],
-                fs = file.size,
-                ub = options.uploadedBytes,
-                mcs = options.maxChunkSize || fs,
-                slice = this._blobSlice,
-                dfd = $.Deferred(),
-                promise = dfd.promise(),
-                jqXHR,
-                upload;
-            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
-                    options.data) {
-                return false;
-            }
-            if (testOnly) {
-                return true;
-            }
-            if (ub >= fs) {
-                file.error = options.i18n('uploadedBytes');
-                return this._getXHRPromise(
-                    false,
-                    options.context,
-                    [null, 'error', file.error]
-                );
-            }
-            // The chunk upload method:
-            upload = function () {
-                // Clone the options object for each chunk upload:
-                var o = $.extend({}, options),
-                    currentLoaded = o._progress.loaded;
-                o.blob = slice.call(
-                    file,
-                    ub,
-                    ub + mcs,
-                    file.type
-                );
-                // Store the current chunk size, as the blob itself
-                // will be dereferenced after data processing:
-                o.chunkSize = o.blob.size;
-                // Expose the chunk bytes position range:
-                o.contentRange = 'bytes ' + ub + '-' +
-                    (ub + o.chunkSize - 1) + '/' + fs;
-                // Process the upload data (the blob and potential form data):
-                that._initXHRData(o);
-                // Add progress listeners for this chunk upload:
-                that._initProgressListener(o);
-                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
-                        that._getXHRPromise(false, o.context))
-                    .done(function (result, textStatus, jqXHR) {
-                        ub = that._getUploadedBytes(jqXHR) ||
-                            (ub + o.chunkSize);
-                        // Create a progress event if no final progress event
-                        // with loaded equaling total has been triggered
-                        // for this chunk:
-                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
-                            that._onProgress($.Event('progress', {
-                                lengthComputable: true,
-                                loaded: ub - o.uploadedBytes,
-                                total: ub - o.uploadedBytes
-                            }), o);
-                        }
-                        options.uploadedBytes = o.uploadedBytes = ub;
-                        o.result = result;
-                        o.textStatus = textStatus;
-                        o.jqXHR = jqXHR;
-                        that._trigger('chunkdone', null, o);
-                        that._trigger('chunkalways', null, o);
-                        if (ub < fs) {
-                            // File upload not yet complete,
-                            // continue with the next chunk:
-                            upload();
-                        } else {
-                            dfd.resolveWith(
-                                o.context,
-                                [result, textStatus, jqXHR]
-                            );
-                        }
-                    })
-                    .fail(function (jqXHR, textStatus, errorThrown) {
-                        o.jqXHR = jqXHR;
-                        o.textStatus = textStatus;
-                        o.errorThrown = errorThrown;
-                        that._trigger('chunkfail', null, o);
-                        that._trigger('chunkalways', null, o);
-                        dfd.rejectWith(
-                            o.context,
-                            [jqXHR, textStatus, errorThrown]
-                        );
-                    });
-            };
-            this._enhancePromise(promise);
-            promise.abort = function () {
-                return jqXHR.abort();
-            };
-            upload();
-            return promise;
-        },
-
-        _beforeSend: function (e, data) {
-            if (this._active === 0) {
-                // the start callback is triggered when an upload starts
-                // and no other uploads are currently running,
-                // equivalent to the global ajaxStart event:
-                this._trigger('start');
-                // Set timer for global bitrate progress calculation:
-                this._bitrateTimer = new this._BitrateTimer();
-                // Reset the global progress values:
-                this._progress.loaded = this._progress.total = 0;
-                this._progress.bitrate = 0;
-            }
-            // Make sure the container objects for the .response() and
-            // .progress() methods on the data object are available
-            // and reset to their initial state:
-            this._initResponseObject(data);
-            this._initProgressObject(data);
-            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
-            data._progress.total = data.total = this._getTotal(data.files) || 1;
-            data._progress.bitrate = data.bitrate = 0;
-            this._active += 1;
-            // Initialize the global progress values:
-            this._progress.loaded += data.loaded;
-            this._progress.total += data.total;
-        },
-
-        _onDone: function (result, textStatus, jqXHR, options) {
-            var total = options._progress.total,
-                response = options._response;
-            if (options._progress.loaded < total) {
-                // Create a progress event if no final progress event
-                // with loaded equaling total has been triggered:
-                this._onProgress($.Event('progress', {
-                    lengthComputable: true,
-                    loaded: total,
-                    total: total
-                }), options);
-            }
-            response.result = options.result = result;
-            response.textStatus = options.textStatus = textStatus;
-            response.jqXHR = options.jqXHR = jqXHR;
-            this._trigger('done', null, options);
-        },
-
-        _onFail: function (jqXHR, textStatus, errorThrown, options) {
-            var response = options._response;
-            if (options.recalculateProgress) {
-                // Remove the failed (error or abort) file upload from
-                // the global progress calculation:
-                this._progress.loaded -= options._progress.loaded;
-                this._progress.total -= options._progress.total;
-            }
-            response.jqXHR = options.jqXHR = jqXHR;
-            response.textStatus = options.textStatus = textStatus;
-            response.errorThrown = options.errorThrown = errorThrown;
-            this._trigger('fail', null, options);
-        },
-
-        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
-            // jqXHRorResult, textStatus and jqXHRorError are added to the
-            // options object via done and fail callbacks
-            this._trigger('always', null, options);
-        },
-
-        _onSend: function (e, data) {
-            if (!data.submit) {
-                this._addConvenienceMethods(e, data);
-            }
-            var that = this,
-                jqXHR,
-                aborted,
-                slot,
-                pipe,
-                options = that._getAJAXSettings(data),
-                send = function () {
-                    that._sending += 1;
-                    // Set timer for bitrate progress calculation:
-                    options._bitrateTimer = new that._BitrateTimer();
-                    jqXHR = jqXHR || (
-                        ((aborted || that._trigger(
-                            'send',
-                            $.Event('send', {delegatedEvent: e}),
-                            options
-                        ) === false) &&
-                        that._getXHRPromise(false, options.context, aborted)) ||
-                        that._chunkedUpload(options) || $.ajax(options)
-                    ).done(function (result, textStatus, jqXHR) {
-                        that._onDone(result, textStatus, jqXHR, options);
-                    }).fail(function (jqXHR, textStatus, errorThrown) {
-                        that._onFail(jqXHR, textStatus, errorThrown, options);
-                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
-                        that._onAlways(
-                            jqXHRorResult,
-                            textStatus,
-                            jqXHRorError,
-                            options
-                        );
-                        that._sending -= 1;
-                        that._active -= 1;
-                        if (options.limitConcurrentUploads &&
-                                options.limitConcurrentUploads > that._sending) {
-                            // Start the next queued upload,
-                            // that has not been aborted:
-                            var nextSlot = that._slots.shift();
-                            while (nextSlot) {
-                                if (that._getDeferredState(nextSlot) === 'pending') {
-                                    nextSlot.resolve();
-                                    break;
-                                }
-                                nextSlot = that._slots.shift();
-                            }
-                        }
-                        if (that._active === 0) {
-                            // The stop callback is triggered when all uploads have
-                            // been completed, equivalent to the global ajaxStop event:
-                            that._trigger('stop');
-                        }
-                    });
-                    return jqXHR;
-                };
-            this._beforeSend(e, options);
-            if (this.options.sequentialUploads ||
-                    (this.options.limitConcurrentUploads &&
-                    this.options.limitConcurrentUploads <= this._sending)) {
-                if (this.options.limitConcurrentUploads > 1) {
-                    slot = $.Deferred();
-                    this._slots.push(slot);
-                    pipe = slot.then(send);
-                } else {
-                    this._sequence = this._sequence.then(send, send);
-                    pipe = this._sequence;
-                }
-                // Return the piped Promise object, enhanced with an abort method,
-                // which is delegated to the jqXHR object of the current upload,
-                // and jqXHR callbacks mapped to the equivalent Promise methods:
-                pipe.abort = function () {
-                    aborted = [undefined, 'abort', 'abort'];
-                    if (!jqXHR) {
-                        if (slot) {
-                            slot.rejectWith(options.context, aborted);
-                        }
-                        return send();
-                    }
-                    return jqXHR.abort();
-                };
-                return this._enhancePromise(pipe);
-            }
-            return send();
-        },
-
-        _onAdd: function (e, data) {
-            var that = this,
-                result = true,
-                options = $.extend({}, this.options, data),
-                files = data.files,
-                filesLength = files.length,
-                limit = options.limitMultiFileUploads,
-                limitSize = options.limitMultiFileUploadSize,
-                overhead = options.limitMultiFileUploadSizeOverhead,
-                batchSize = 0,
-                paramName = this._getParamName(options),
-                paramNameSet,
-                paramNameSlice,
-                fileSet,
-                i,
-                j = 0;
-            if (!filesLength) {
-                return false;
-            }
-            if (limitSize && files[0].size === undefined) {
-                limitSize = undefined;
-            }
-            if (!(options.singleFileUploads || limit || limitSize) ||
-                    !this._isXHRUpload(options)) {
-                fileSet = [files];
-                paramNameSet = [paramName];
-            } else if (!(options.singleFileUploads || limitSize) && limit) {
-                fileSet = [];
-                paramNameSet = [];
-                for (i = 0; i < filesLength; i += limit) {
-                    fileSet.push(files.slice(i, i + limit));
-                    paramNameSlice = paramName.slice(i, i + limit);
-                    if (!paramNameSlice.length) {
-                        paramNameSlice = paramName;
-                    }
-                    paramNameSet.push(paramNameSlice);
-                }
-            } else if (!options.singleFileUploads && limitSize) {
-                fileSet = [];
-                paramNameSet = [];
-                for (i = 0; i < filesLength; i = i + 1) {
-                    batchSize += files[i].size + overhead;
-                    if (i + 1 === filesLength ||
-                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
-                            (limit && i + 1 - j >= limit)) {
-                        fileSet.push(files.slice(j, i + 1));
-                        paramNameSlice = paramName.slice(j, i + 1);
-                        if (!paramNameSlice.length) {
-                            paramNameSlice = paramName;
-                        }
-                        paramNameSet.push(paramNameSlice);
-                        j = i + 1;
-                        batchSize = 0;
-                    }
-                }
-            } else {
-                paramNameSet = paramName;
-            }
-            data.originalFiles = files;
-            $.each(fileSet || files, function (index, element) {
-                var newData = $.extend({}, data);
-                newData.files = fileSet ? element : [element];
-                newData.paramName = paramNameSet[index];
-                that._initResponseObject(newData);
-                that._initProgressObject(newData);
-                that._addConvenienceMethods(e, newData);
-                result = that._trigger(
-                    'add',
-                    $.Event('add', {delegatedEvent: e}),
-                    newData
-                );
-                return result;
-            });
-            return result;
-        },
-
-        _replaceFileInput: function (data) {
-            var input = data.fileInput,
-                inputClone = input.clone(true),
-                restoreFocus = input.is(document.activeElement);
-            // Add a reference for the new cloned file input to the data argument:
-            data.fileInputClone = inputClone;
-            $('<form></form>').append(inputClone)[0].reset();
-            // Detaching allows to insert the fileInput on another form
-            // without loosing the file input value:
-            input.after(inputClone).detach();
-            // If the fileInput had focus before it was detached,
-            // restore focus to the inputClone.
-            if (restoreFocus) {
-                inputClone.focus();
-            }
-            // Avoid memory leaks with the detached file input:
-            $.cleanData(input.unbind('remove'));
-            // Replace the original file input element in the fileInput
-            // elements set with the clone, which has been copied including
-            // event handlers:
-            this.options.fileInput = this.options.fileInput.map(function (i, el) {
-                if (el === input[0]) {
-                    return inputClone[0];
-                }
-                return el;
-            });
-            // If the widget has been initialized on the file input itself,
-            // override this.element with the file input clone:
-            if (input[0] === this.element[0]) {
-                this.element = inputClone;
-            }
-        },
-
-        _handleFileTreeEntry: function (entry, path) {
-            var that = this,
-                dfd = $.Deferred(),
-                errorHandler = function (e) {
-                    if (e && !e.entry) {
-                        e.entry = entry;
-                    }
-                    // Since $.when returns immediately if one
-                    // Deferred is rejected, we use resolve instead.
-                    // This allows valid files and invalid items
-                    // to be returned together in one set:
-                    dfd.resolve([e]);
-                },
-                successHandler = function (entries) {
-                    that._handleFileTreeEntries(
-                        entries,
-                        path + entry.name + '/'
-                    ).done(function (files) {
-                        dfd.resolve(files);
-                    }).fail(errorHandler);
-                },
-                readEntries = function () {
-                    dirReader.readEntries(function (results) {
-                        if (!results.length) {
-                            successHandler(entries);
-                        } else {
-                            entries = entries.concat(results);
-                            readEntries();
-                        }
-                    }, errorHandler);
-                },
-                dirReader, entries = [];
-            path = path || '';
-            if (entry.isFile) {
-                if (entry._file) {
-                    // Workaround for Chrome bug #149735
-                    entry._file.relativePath = path;
-                    dfd.resolve(entry._file);
-                } else {
-                    entry.file(function (file) {
-                        file.relativePath = path;
-                        dfd.resolve(file);
-                    }, errorHandler);
-                }
-            } else if (entry.isDirectory) {
-                dirReader = entry.createReader();
-                readEntries();
-            } else {
-                // Return an empy list for file system items
-                // other than files or directories:
-                dfd.resolve([]);
-            }
-            return dfd.promise();
-        },
-
-        _handleFileTreeEntries: function (entries, path) {
-            var that = this;
-            return $.when.apply(
-                $,
-                $.map(entries, function (entry) {
-                    return that._handleFileTreeEntry(entry, path);
-                })
-            ).then(function () {
-                return Array.prototype.concat.apply(
-                    [],
-                    arguments
-                );
-            });
-        },
-
-        _getDroppedFiles: function (dataTransfer) {
-            dataTransfer = dataTransfer || {};
-            var items = dataTransfer.items;
-            if (items && items.length && (items[0].webkitGetAsEntry ||
-                    items[0].getAsEntry)) {
-                return this._handleFileTreeEntries(
-                    $.map(items, function (item) {
-                        var entry;
-                        if (item.webkitGetAsEntry) {
-                            entry = item.webkitGetAsEntry();
-                            if (entry) {
-                                // Workaround for Chrome bug #149735:
-                                entry._file = item.getAsFile();
-                            }
-                            return entry;
-                        }
-                        return item.getAsEntry();
-                    })
-                );
-            }
-            return $.Deferred().resolve(
-                $.makeArray(dataTransfer.files)
-            ).promise();
-        },
-
-        _getSingleFileInputFiles: function (fileInput) {
-            fileInput = $(fileInput);
-            var entries = fileInput.prop('webkitEntries') ||
-                    fileInput.prop('entries'),
-                files,
-                value;
-            if (entries && entries.length) {
-                return this._handleFileTreeEntries(entries);
-            }
-            files = $.makeArray(fileInput.prop('files'));
-            if (!files.length) {
-                value = fileInput.prop('value');
-                if (!value) {
-                    return $.Deferred().resolve([]).promise();
-                }
-                // If the files property is not available, the browser does not
-                // support the File API and we add a pseudo File object with
-                // the input value as name with path information removed:
-                files = [{name: value.replace(/^.*\\/, '')}];
-            } else if (files[0].name === undefined && files[0].fileName) {
-                // File normalization for Safari 4 and Firefox 3:
-                $.each(files, function (index, file) {
-                    file.name = file.fileName;
-                    file.size = file.fileSize;
-                });
-            }
-            return $.Deferred().resolve(files).promise();
-        },
-
-        _getFileInputFiles: function (fileInput) {
-            if (!(fileInput instanceof $) || fileInput.length === 1) {
-                return this._getSingleFileInputFiles(fileInput);
-            }
-            return $.when.apply(
-                $,
-                $.map(fileInput, this._getSingleFileInputFiles)
-            ).then(function () {
-                return Array.prototype.concat.apply(
-                    [],
-                    arguments
-                );
-            });
-        },
-
-        _onChange: function (e) {
-            var that = this,
-                data = {
-                    fileInput: $(e.target),
-                    form: $(e.target.form)
-                };
-            this._getFileInputFiles(data.fileInput).always(function (files) {
-                data.files = files;
-                if (that.options.replaceFileInput) {
-                    that._replaceFileInput(data);
-                }
-                if (that._trigger(
-                        'change',
-                        $.Event('change', {delegatedEvent: e}),
-                        data
-                    ) !== false) {
-                    that._onAdd(e, data);
-                }
-            });
-        },
-
-        _onPaste: function (e) {
-            var items = e.originalEvent && e.originalEvent.clipboardData &&
-                    e.originalEvent.clipboardData.items,
-                data = {files: []};
-            if (items && items.length) {
-                $.each(items, function (index, item) {
-                    var file = item.getAsFile && item.getAsFile();
-                    if (file) {
-                        data.files.push(file);
-                    }
-                });
-                if (this._trigger(
-                        'paste',
-                        $.Event('paste', {delegatedEvent: e}),
-                        data
-                    ) !== false) {
-                    this._onAdd(e, data);
-                }
-            }
-        },
-
-        _onDrop: function (e) {
-            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
-            var that = this,
-                dataTransfer = e.dataTransfer,
-                data = {};
-            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
-                e.preventDefault();
-                this._getDroppedFiles(dataTransfer).always(function (files) {
-                    data.files = files;
-                    if (that._trigger(
-                            'drop',
-                            $.Event('drop', {delegatedEvent: e}),
-                            data
-                        ) !== false) {
-                        that._onAdd(e, data);
-                    }
-                });
-            }
-        },
-
-        _onDragOver: getDragHandler('dragover'),
-
-        _onDragEnter: getDragHandler('dragenter'),
-
-        _onDragLeave: getDragHandler('dragleave'),
-
-        _initEventHandlers: function () {
-            if (this._isXHRUpload(this.options)) {
-                this._on(this.options.dropZone, {
-                    dragover: this._onDragOver,
-                    drop: this._onDrop,
-                    // event.preventDefault() on dragenter is required for IE10+:
-                    dragenter: this._onDragEnter,
-                    // dragleave is not required, but added for completeness:
-                    dragleave: this._onDragLeave
-                });
-                this._on(this.options.pasteZone, {
-                    paste: this._onPaste
-                });
-            }
-            if ($.support.fileInput) {
-                this._on(this.options.fileInput, {
-                    change: this._onChange
-                });
-            }
-        },
-
-        _destroyEventHandlers: function () {
-            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
-            this._off(this.options.pasteZone, 'paste');
-            this._off(this.options.fileInput, 'change');
-        },
-
-        _setOption: function (key, value) {
-            var reinit = $.inArray(key, this._specialOptions) !== -1;
-            if (reinit) {
-                this._destroyEventHandlers();
-            }
-            this._super(key, value);
-            if (reinit) {
-                this._initSpecialOptions();
-                this._initEventHandlers();
-            }
-        },
-
-        _initSpecialOptions: function () {
-            var options = this.options;
-            if (options.fileInput === undefined) {
-                options.fileInput = this.element.is('input[type="file"]') ?
-                        this.element : this.element.find('input[type="file"]');
-            } else if (!(options.fileInput instanceof $)) {
-                options.fileInput = $(options.fileInput);
-            }
-            if (!(options.dropZone instanceof $)) {
-                options.dropZone = $(options.dropZone);
-            }
-            if (!(options.pasteZone instanceof $)) {
-                options.pasteZone = $(options.pasteZone);
-            }
-        },
-
-        _getRegExp: function (str) {
-            var parts = str.split('/'),
-                modifiers = parts.pop();
-            parts.shift();
-            return new RegExp(parts.join('/'), modifiers);
-        },
-
-        _isRegExpOption: function (key, value) {
-            return key !== 'url' && $.type(value) === 'string' &&
-                /^\/.*\/[igm]{0,3}$/.test(value);
-        },
-
-        _initDataAttributes: function () {
-            var that = this,
-                options = this.options,
-                data = this.element.data();
-            // Initialize options set via HTML5 data-attributes:
-            $.each(
-                this.element[0].attributes,
-                function (index, attr) {
-                    var key = attr.name.toLowerCase(),
-                        value;
-                    if (/^data-/.test(key)) {
-                        // Convert hyphen-ated key to camelCase:
-                        key = key.slice(5).replace(/-[a-z]/g, function (str) {
-                            return str.charAt(1).toUpperCase();
-                        });
-                        value = data[key];
-                        if (that._isRegExpOption(key, value)) {
-                            value = that._getRegExp(value);
-                        }
-                        options[key] = value;
-                    }
-                }
-            );
-        },
-
-        _create: function () {
-            this._initDataAttributes();
-            this._initSpecialOptions();
-            this._slots = [];
-            this._sequence = this._getXHRPromise(true);
-            this._sending = this._active = 0;
-            this._initProgressObject(this);
-            this._initEventHandlers();
-        },
-
-        // This method is exposed to the widget API and allows to query
-        // the number of active uploads:
-        active: function () {
-            return this._active;
-        },
-
-        // This method is exposed to the widget API and allows to query
-        // the widget upload progress.
-        // It returns an object with loaded, total and bitrate properties
-        // for the running uploads:
-        progress: function () {
-            return this._progress;
-        },
-
-        // This method is exposed to the widget API and allows adding files
-        // using the fileupload API. The data parameter accepts an object which
-        // must have a files property and can contain additional options:
-        // .fileupload('add', {files: filesList});
-        add: function (data) {
-            var that = this;
-            if (!data || this.options.disabled) {
-                return;
-            }
-            if (data.fileInput && !data.files) {
-                this._getFileInputFiles(data.fileInput).always(function (files) {
-                    data.files = files;
-                    that._onAdd(null, data);
-                });
-            } else {
-                data.files = $.makeArray(data.files);
-                this._onAdd(null, data);
-            }
-        },
-
-        // This method is exposed to the widget API and allows sending files
-        // using the fileupload API. The data parameter accepts an object which
-        // must have a files or fileInput property and can contain additional options:
-        // .fileupload('send', {files: filesList});
-        // The method returns a Promise object for the file upload call.
-        send: function (data) {
-            if (data && !this.options.disabled) {
-                if (data.fileInput && !data.files) {
-                    var that = this,
-                        dfd = $.Deferred(),
-                        promise = dfd.promise(),
-                        jqXHR,
-                        aborted;
-                    promise.abort = function () {
-                        aborted = true;
-                        if (jqXHR) {
-                            return jqXHR.abort();
-                        }
-                        dfd.reject(null, 'abort', 'abort');
-                        return promise;
-                    };
-                    this._getFileInputFiles(data.fileInput).always(
-                        function (files) {
-                            if (aborted) {
-                                return;
-                            }
-                            if (!files.length) {
-                                dfd.reject();
-                                return;
-                            }
-                            data.files = files;
-                            jqXHR = that._onSend(null, data);
-                            jqXHR.then(
-                                function (result, textStatus, jqXHR) {
-                                    dfd.resolve(result, textStatus, jqXHR);
-                                },
-                                function (jqXHR, textStatus, errorThrown) {
-                                    dfd.reject(jqXHR, textStatus, errorThrown);
-                                }
-                            );
-                        }
-                    );
-                    return this._enhancePromise(promise);
-                }
-                data.files = $.makeArray(data.files);
-                if (data.files.length) {
-                    return this._onSend(null, data);
-                }
-            }
-            return this._getXHRPromise(false, data && data.context);
-        }
-
-    });
-
-}));
-
-/*!
- * jquery-visibility v1.0.11
- * Page visibility shim for jQuery.
- *
- * Project Website: http://mths.be/visibility
- *
- * @version 1.0.11
- * @license MIT.
- * @author Mathias Bynens - @mathias
- * @author Jan Paepke - @janpaepke
- */
-;(function (root, factory) {
-	if (typeof define === 'function' && define.amd) {
-		// AMD. Register as an anonymous module.
-		define(['jquery'], function ($) {
-			return factory(root, $);
-		});
-	} else if (typeof exports === 'object') {
-		// Node/CommonJS
-		module.exports = factory(root, require('jquery'));
-	} else {
-		// Browser globals
-		factory(root, jQuery);
-	}
-}(this, function(window, $, undefined) {
-	"use strict";
-
-	var
-		document = window.document,
-		property, // property name of document, that stores page visibility
-		vendorPrefixes = ['webkit', 'o', 'ms', 'moz', ''],
-		$support = $.support || {},
-	// In Opera, `'onfocusin' in document == true`, hence the extra `hasFocus` check to detect IE-like behavior
-		eventName = 'onfocusin' in document && 'hasFocus' in document ?
-			'focusin focusout' :
-			'focus blur';
-
-	var prefix;
-	while ((prefix = vendorPrefixes.pop()) !== undefined) {
-		property = (prefix ? prefix + 'H': 'h') + 'idden';
-		$support.pageVisibility = document[property] !== undefined;
-		if ($support.pageVisibility) {
-			eventName = prefix + 'visibilitychange';
-			break;
-		}
-	}
-
-	// normalize to and update document hidden property
-	function updateState() {
-		if (property !== 'hidden') {
-			document.hidden = $support.pageVisibility ? document[property] : undefined;
-		}
-	}
-	updateState();
-
-	$(/blur$/.test(eventName) ? window : document).on(eventName, function(event) {
-		var type = event.type;
-		var originalEvent = event.originalEvent;
-
-		// Avoid errors from triggered native events for which `originalEvent` is
-		// not available.
-		if (!originalEvent) {
-			return;
-		}
-
-		var toElement = originalEvent.toElement;
-
-		// If it’s a `{focusin,focusout}` event (IE), `fromElement` and `toElement`
-		// should both be `null` or `undefined`; else, the page visibility hasn’t
-		// changed, but the user just clicked somewhere in the doc. In IE9, we need
-		// to check the `relatedTarget` property instead.
-		if (
-			!/^focus./.test(type) || (
-				toElement === undefined &&
-				originalEvent.fromElement === undefined &&
-				originalEvent.relatedTarget === undefined
-			)
-		) {
-			$(document).triggerHandler(
-				property && document[property] || /^(?:blur|focusout)$/.test(type) ?
-					'hide' :
-					'show'
-			);
-		}
-		// and update the current state
-		updateState();
-	});
-}));
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OC, OCA) {
-
-	/**
-	 * @class OC.Files.FileInfo
-	 * @classdesc File information
-	 *
-	 * @param {Object} attributes file data
-	 * @param {int} attributes.id file id
-	 * @param {string} attributes.name file name
-	 * @param {string} attributes.path path leading to the file,
-	 * without the file name and with a leading slash
-	 * @param {int} attributes.size size
-	 * @param {string} attributes.mimetype mime type
-	 * @param {string} attributes.icon icon URL
-	 * @param {int} attributes.permissions permissions
-	 * @param {Date} attributes.mtime modification time
-	 * @param {string} attributes.etag etag
-	 * @param {string} mountType mount type
-	 *
-	 * @since 8.2
-	 */
-	var FileInfoModel = OC.Backbone.Model.extend({
-
-		defaults: {
-			mimetype: 'application/octet-stream',
-			path: ''
-		},
-
-		_filesClient: null,
-
-		initialize: function(data, options) {
-			if (!_.isUndefined(data.id)) {
-				data.id = parseInt(data.id, 10);
-			}
-
-			if( options ){
-				if (options.filesClient) {
-					this._filesClient = options.filesClient;
-				}
-			}
-		},
-
-		/**
-		 * Returns whether this file is a directory
-		 *
-		 * @return {boolean} true if this is a directory, false otherwise
-		 */
-		isDirectory: function() {
-			return this.get('mimetype') === 'httpd/unix-directory';
-		},
-
-		/**
-		 * Returns whether this file is an image
-		 *
-		 * @return {boolean} true if this is an image, false otherwise
-		 */
-		isImage: function() {
-			if (!this.has('mimetype')) {
-				return false;
-			}
-			return this.get('mimetype').substr(0, 6) === 'image/'
-				|| this.get('mimetype') === 'application/postscript'
-				|| this.get('mimetype') === 'application/illustrator'
-				|| this.get('mimetype') === 'application/x-photoshop';
-		},
-
-		/**
-		 * Returns the full path to this file
-		 *
-		 * @return {string} full path
-		 */
-		getFullPath: function() {
-			return OC.joinPaths(this.get('path'), this.get('name'));
-		},
-
-		/**
-		 * Reloads missing properties from server and set them in the model.
-		 * @param properties array of properties to be reloaded
-		 * @return ajax call object
-		 */
-		reloadProperties: function(properties) {
-			if( !this._filesClient ){
-				return;
-			}
-
-			var self = this;
-			var deferred = $.Deferred();
-
-			var targetPath = OC.joinPaths(this.get('path') + '/', this.get('name'));
-
-			this._filesClient.getFileInfo(targetPath, {
-					properties: properties
-				})
-				.then(function(status, data) {
-					// the following lines should be extracted to a mapper
-
-					if( properties.indexOf(OC.Files.Client.PROPERTY_GETCONTENTLENGTH) !== -1
-					||  properties.indexOf(OC.Files.Client.PROPERTY_SIZE) !== -1 ) {
-						self.set('size', data.size);
-					}
-
-					deferred.resolve(status, data);
-				})
-				.fail(function(status) {
-					OC.Notification.show(t('files', 'Could not load info for file "{file}"', {file: self.get('name')}), {type: 'error'});
-					deferred.reject(status);
-				});
-
-			return deferred.promise();
-		}
-	});
-
-	if (!OCA.Files) {
-		OCA.Files = {};
-	}
-	OCA.Files.FileInfoModel = FileInfoModel;
-
-})(OC, OCA);
-
-
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-(function() {
-	var INFO_TEMPLATE =
-		'<span class="info">' +
-			'<span class="dirinfo"></span>' +
-			'<span class="connector">{{connectorLabel}}</span>' +
-			'<span class="fileinfo"></span>' +
-			'<span class="hiddeninfo"></span>' +
-			'<span class="filter"></span>' +
-		'</span>';
-
-	/**
-	 * The FileSummary class encapsulates the file summary values and
-	 * the logic to render it in the given container
-	 *
-	 * @constructs FileSummary
-	 * @memberof OCA.Files
-	 *
-	 * @param $tr table row element
-	 * @param {OC.Backbone.Model} [options.filesConfig] files app configuration
-	 */
-	var FileSummary = function($tr, options) {
-		options = options || {};
-		var self = this;
-		this.$el = $tr;
-		var filesConfig = options.config;
-		if (filesConfig) {
-			this._showHidden = !!filesConfig.get('showhidden');
-			filesConfig.on('change:showhidden', function() {
-				self._showHidden = !!this.get('showhidden');
-				self.update();
-			});
-		}
-		this.clear();
-		this.render();
-	};
-
-	FileSummary.prototype = {
-		_showHidden: null,
-
-		summary: {
-			totalFiles: 0,
-			totalDirs: 0,
-			totalHidden: 0,
-			totalSize: 0,
-			filter:'',
-			sumIsPending:false
-		},
-
-		/**
-		 * Returns whether the given file info must be hidden
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo file info
-		 * 
-		 * @return {boolean} true if the file is a hidden file, false otherwise
-		 */
-		_isHiddenFile: function(file) {
-			return file.name && file.name.charAt(0) === '.';
-		},
-
-		/**
-		 * Adds file
-		 * @param {OC.Files.FileInfo} file file to add
-		 * @param {boolean} update whether to update the display
-		 */
-		add: function(file, update) {
-			if (file.name && file.name.toLowerCase().indexOf(this.summary.filter) === -1) {
-				return;
-			}
-			if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
-				this.summary.totalDirs++;
-			}
-			else {
-				this.summary.totalFiles++;
-			}
-			if (this._isHiddenFile(file)) {
-				this.summary.totalHidden++;
-			}
-
-			var size = parseInt(file.size, 10) || 0;
-			if (size >=0) {
-				this.summary.totalSize += size;
-			} else {
-				this.summary.sumIsPending = true;
-			}
-			if (!!update) {
-				this.update();
-			}
-		},
-		/**
-		 * Removes file
-		 * @param {OC.Files.FileInfo} file file to remove
-		 * @param {boolean} update whether to update the display
-		 */
-		remove: function(file, update) {
-			if (file.name && file.name.toLowerCase().indexOf(this.summary.filter) === -1) {
-				return;
-			}
-			if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
-				this.summary.totalDirs--;
-			}
-			else {
-				this.summary.totalFiles--;
-			}
-			if (this._isHiddenFile(file)) {
-				this.summary.totalHidden--;
-			}
-			var size = parseInt(file.size, 10) || 0;
-			if (size >=0) {
-				this.summary.totalSize -= size;
-			}
-			if (!!update) {
-				this.update();
-			}
-		},
-		setFilter: function(filter, files){
-			this.summary.filter = filter.toLowerCase();
-			this.calculate(files);
-		},
-		/**
-		 * Returns the total of files and directories
-		 */
-		getTotal: function() {
-			return this.summary.totalDirs + this.summary.totalFiles;
-		},
-		/**
-		 * Recalculates the summary based on the given files array
-		 * @param files array of files
-		 */
-		calculate: function(files) {
-			var file;
-			var summary = {
-				totalDirs: 0,
-				totalFiles: 0,
-				totalHidden: 0,
-				totalSize: 0,
-				filter: this.summary.filter,
-				sumIsPending: false
-			};
-
-			for (var i = 0; i < files.length; i++) {
-				file = files[i];
-				if (file.name && file.name.toLowerCase().indexOf(this.summary.filter) === -1) {
-					continue;
-				}
-				if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
-					summary.totalDirs++;
-				}
-				else {
-					summary.totalFiles++;
-				}
-				if (this._isHiddenFile(file)) {
-					summary.totalHidden++;
-				}
-				var size = parseInt(file.size, 10) || 0;
-				if (size >=0) {
-					summary.totalSize += size;
-				} else {
-					summary.sumIsPending = true;
-				}
-			}
-			this.setSummary(summary);
-		},
-		/**
-		 * Clears the summary
-		 */
-		clear: function() {
-			this.calculate([]);
-		},
-		/**
-		 * Sets the current summary values
-		 * @param summary map
-		 */
-		setSummary: function(summary) {
-			this.summary = summary;
-			if (typeof this.summary.filter === 'undefined') {
-				this.summary.filter = '';
-			}
-			this.update();
-		},
-
-		_infoTemplate: function(data) {
-			if (!this._infoTemplateCompiled) {
-				this._infoTemplateCompiled = Handlebars.compile(INFO_TEMPLATE);
-			}
-			return this._infoTemplateCompiled(_.extend({
-				connectorLabel: t('files', '{dirs} and {files}', {dirs: '', files: ''})
-			}, data));
-		},
-
-		/**
-		 * Renders the file summary element
-		 */
-		update: function() {
-			if (!this.$el) {
-				return;
-			}
-			if (!this.summary.totalFiles && !this.summary.totalDirs) {
-				this.$el.addClass('hidden');
-				return;
-			}
-			// There's a summary and data -> Update the summary
-			this.$el.removeClass('hidden');
-			var $dirInfo = this.$el.find('.dirinfo');
-			var $fileInfo = this.$el.find('.fileinfo');
-			var $connector = this.$el.find('.connector');
-			var $filterInfo = this.$el.find('.filter');
-			var $hiddenInfo = this.$el.find('.hiddeninfo');
-
-			// Substitute old content with new translations
-			$dirInfo.html(n('files', '%n folder', '%n folders', this.summary.totalDirs));
-			$fileInfo.html(n('files', '%n file', '%n files', this.summary.totalFiles));
-			$hiddenInfo.html(' (' + n('files', 'including %n hidden', 'including %n hidden', this.summary.totalHidden) + ')');
-			var fileSize = this.summary.sumIsPending ? t('files', 'Pending') : OC.Util.humanFileSize(this.summary.totalSize);
-			this.$el.find('.filesize').html(fileSize);
-
-			// Show only what's necessary (may be hidden)
-			if (this.summary.totalDirs === 0) {
-				$dirInfo.addClass('hidden');
-				$connector.addClass('hidden');
-			} else {
-				$dirInfo.removeClass('hidden');
-			}
-			if (this.summary.totalFiles === 0) {
-				$fileInfo.addClass('hidden');
-				$connector.addClass('hidden');
-			} else {
-				$fileInfo.removeClass('hidden');
-			}
-			if (this.summary.totalDirs > 0 && this.summary.totalFiles > 0) {
-				$connector.removeClass('hidden');
-			}
-			$hiddenInfo.toggleClass('hidden', this.summary.totalHidden === 0 || this._showHidden)
-			if (this.summary.filter === '') {
-				$filterInfo.html('');
-				$filterInfo.addClass('hidden');
-			} else {
-				$filterInfo.html(' ' + n('files', 'matches \'{filter}\'', 'match \'{filter}\'', this.summary.totalDirs + this.summary.totalFiles, {filter: this.summary.filter}));
-				$filterInfo.removeClass('hidden');
-			}
-		},
-		render: function() {
-			if (!this.$el) {
-				return;
-			}
-			var summary = this.summary;
-
-			// don't show the filesize column, if filesize is NaN (e.g. in trashbin)
-			var fileSize = '';
-			if (!isNaN(summary.totalSize)) {
-				fileSize = summary.sumIsPending ? t('files', 'Pending') : OC.Util.humanFileSize(summary.totalSize);
-				fileSize = '<td class="filesize">' + fileSize + '</td>';
-			}
-
-			var $summary = $(
-				'<td>' + this._infoTemplate() + '</td>' +
-				fileSize +
-				'<td class="date"></td>'
-			);
-			this.$el.addClass('hidden');
-			this.$el.append($summary);
-			this.update();
-		}
-	};
-	OCA.Files.FileSummary = FileSummary;
-})();
-
-
-
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-(function() {
-	/**
-	 * @class BreadCrumb
-	 * @memberof OCA.Files
-	 * @classdesc Breadcrumbs that represent the current path.
-	 *
-	 * @param {Object} [options] options
-	 * @param {Function} [options.onClick] click event handler
-	 * @param {Function} [options.onDrop] drop event handler
-	 * @param {Function} [options.getCrumbUrl] callback that returns
-	 * the URL of a given breadcrumb
-	 */
-	var BreadCrumb = function(options){
-		this.$el = $('<div class="breadcrumb"></div>');
-		options = options || {};
-		if (options.onClick) {
-			this.onClick = options.onClick;
-		}
-		if (options.onDrop) {
-			this.onDrop = options.onDrop;
-			this.onOver = options.onOver;
-			this.onOut = options.onOut;
-		}
-		if (options.getCrumbUrl) {
-			this.getCrumbUrl = options.getCrumbUrl;
-		}
-		this._detailViews = [];
-	};
-	/**
-	 * @memberof OCA.Files
-	 */
-	BreadCrumb.prototype = {
-		$el: null,
-		dir: null,
-		dirInfo: null,
-
-		/**
-		 * Total width of all breadcrumbs
-		 * @type int
-		 * @private
-		 */
-		totalWidth: 0,
-		breadcrumbs: [],
-		onClick: null,
-		onDrop: null,
-		onOver: null,
-		onOut: null,
-
-		/**
-		 * Sets the directory to be displayed as breadcrumb.
-		 * This will re-render the breadcrumb.
-		 * @param dir path to be displayed as breadcrumb
-		 */
-		setDirectory: function(dir) {
-			dir = dir.replace(/\\/g, '/');
-			dir = dir || '/';
-			if (dir !== this.dir) {
-				this.dir = dir;
-				this.render();
-			}
-		},
-
-		setDirectoryInfo: function(dirInfo) {
-			if (dirInfo !== this.dirInfo) {
-				this.dirInfo = dirInfo;
-				this.render();
-			}
-		},
-
-		/**
-		 * @param {Backbone.View} detailView
-		 */
-		addDetailView: function(detailView) {
-			this._detailViews.push(detailView);
-		},
-
-		/**
-		 * Returns the full URL to the given directory
-		 *
-		 * @param {Object.<String, String>} part crumb data as map
-		 * @param {int} index crumb index
-		 * @return full URL
-		 */
-		getCrumbUrl: function(part, index) {
-			return '#';
-		},
-
-		/**
-		 * Renders the breadcrumb elements
-		 */
-		render: function() {
-			var parts = this._makeCrumbs(this.dir || '/');
-			var $crumb;
-			this.$el.empty();
-			this.breadcrumbs = [];
-
-			for (var i = 0; i < parts.length; i++) {
-				var part = parts[i];
-				var $image;
-				var $link = $('<a></a>').attr('href', this.getCrumbUrl(part, i));
-				$link.text(part.name);
-				$crumb = $('<div class="crumb svg"></div>');
-				$crumb.append($link);
-				$crumb.attr('data-dir', part.dir);
-
-				if (part.img) {
-					$image = $('<img class="svg"></img>');
-					$image.attr('src', part.img);
-					$image.attr('alt', part.alt);
-					$link.append($image);
-				}
-				this.breadcrumbs.push($crumb);
-				this.$el.append($crumb);
-				if (this.onClick) {
-					$crumb.on('click', this.onClick);
-				}
-			}
-			$crumb.addClass('last');
-
-			_.each(this._detailViews, function(view) {
-				view.render({
-					dirInfo: this.dirInfo
-				});
-				$crumb.append(view.$el);
-			}, this);
-
-			// in case svg is not supported by the browser we need to execute the fallback mechanism
-			if (!OC.Util.hasSVGSupport()) {
-				OC.Util.replaceSVG(this.$el);
-			}
-
-			// setup drag and drop
-			if (this.onDrop) {
-				this.$el.find('.crumb:not(.last)').droppable({
-					drop: this.onDrop,
-					over: this.onOver,
-					out: this.onOut,
-					tolerance: 'pointer',
-					hoverClass: 'canDrop'
-				});
-			}
-
-			this._updateTotalWidth();
-		},
-
-		/**
-		 * Makes a breadcrumb structure based on the given path
-		 *
-		 * @param {String} dir path to split into a breadcrumb structure
-		 * @return {Object.<String, String>} map of {dir: path, name: displayName}
-		 */
-		_makeCrumbs: function(dir) {
-			var crumbs = [];
-			var pathToHere = '';
-			// trim leading and trailing slashes
-			dir = dir.replace(/^\/+|\/+$/g, '');
-			var parts = dir.split('/');
-			if (dir === '') {
-				parts = [];
-			}
-			// root part
-			crumbs.push({
-				dir: '/',
-				name: '',
-				alt: t('files', 'Home'),
-				img: OC.imagePath('core', 'places/home.svg')
-			});
-			for (var i = 0; i < parts.length; i++) {
-				var part = parts[i];
-				pathToHere = pathToHere + '/' + part;
-				crumbs.push({
-					dir: pathToHere,
-					name: part
-				});
-			}
-			return crumbs;
-		},
-
-		/**
-		 * Calculate the total breadcrumb width when
-		 * all crumbs are expanded
-		 */
-		_updateTotalWidth: function () {
-			this.totalWidth = 0;
-			for (var i = 0; i < this.breadcrumbs.length; i++ ) {
-				var $crumb = $(this.breadcrumbs[i]);
-				$crumb.data('real-width', $crumb.width());
-				this.totalWidth += $crumb.width();
-			}
-			this._resize();
-		},
-
-		/**
-		 * Show/hide breadcrumbs to fit the given width
-		 * 
-		 * @param {int} availableWidth available width
-		 */
-		setMaxWidth: function (availableWidth) {
-			if (this.availableWidth !== availableWidth) {
-				this.availableWidth = availableWidth;
-				this._resize();
-			}
-		},
-
-		_resize: function() {
-			var i, $crumb, $ellipsisCrumb;
-
-			if (!this.availableWidth) {
-				this.availableWidth = this.$el.width();
-			}
-
-			if (this.breadcrumbs.length <= 1) {
-				return;
-			}
-
-			// reset crumbs
-			this.$el.find('.crumb.ellipsized').remove();
-
-			// unhide all
-			this.$el.find('.crumb.hidden').removeClass('hidden');
-
-			if (this.totalWidth <= this.availableWidth) {
-				// no need to compute breadcrumbs, there is enough space
-				return;
-			}
-
-			// running width, considering the hidden crumbs
-			var currentTotalWidth = $(this.breadcrumbs[0]).data('real-width');
-			var firstHidden = true;
-
-			// insert ellipsis after root part (root part is always visible)
-			$ellipsisCrumb = $('<div class="crumb ellipsized svg"><span class="ellipsis">...</span></div>');
-			$(this.breadcrumbs[0]).after($ellipsisCrumb);
-			currentTotalWidth += $ellipsisCrumb.width();
-
-			i = this.breadcrumbs.length - 1;
-
-			// find the first section that would cause the overflow
-			// then hide everything in front of that
-			//
-			// this ensures that the last crumb section stays visible
-			// for most of the cases and is always the last one to be
-			// hidden when the screen becomes very narrow
-			while (i > 0) {
-				$crumb = $(this.breadcrumbs[i]);
-				// if the current breadcrumb would cause overflow
-				if (!firstHidden || currentTotalWidth + $crumb.data('real-width') > this.availableWidth) {
-					// hide it
-					$crumb.addClass('hidden');
-					if (firstHidden) {
-						// set the path of this one as title for the ellipsis
-						this.$el.find('.crumb.ellipsized')
-							.attr('title', $crumb.attr('data-dir'))
-							.tooltip();
-						this.$el.find('.ellipsis')
-							.wrap('<a class="ellipsislink" href="' + encodeURI(OC.generateUrl('apps/files/?dir=' + $crumb.attr('data-dir'))) + '"></a>');
-					}
-					// and all the previous ones (going backwards)
-					firstHidden = false;
-				} else {
-					// add to total width
-					currentTotalWidth += $crumb.data('real-width');
-				}
-				i--;
-			}
-
-			if (!OC.Util.hasSVGSupport()) {
-				OC.Util.replaceSVG(this.$el);
-			}
-		}
-	};
-
-	OCA.Files.BreadCrumb = BreadCrumb;
-})();
-
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	var TEMPLATE_ADDBUTTON = '<a href="#" class="button new">' +
-		'<span class="icon {{iconClass}}"></span>' +
-		'<span class="hidden-visually">{{addText}}</span>' +
-		'</a>';
-
-	/**
-	 * @class OCA.Files.FileList
-	 * @classdesc
-	 *
-	 * The FileList class manages a file list view.
-	 * A file list view consists of a controls bar and
-	 * a file list table.
-	 *
-	 * @param $el container element with existing markup for the #controls
-	 * and a table
-	 * @param {Object} [options] map of options, see other parameters
-	 * @param {Object} [options.scrollContainer] scrollable container, defaults to $(window)
-	 * @param {Object} [options.dragOptions] drag options, disabled by default
-	 * @param {Object} [options.folderDropOptions] folder drop options, disabled by default
-	 * @param {boolean} [options.detailsViewEnabled=true] whether to enable details view
-	 * @param {boolean} [options.enableUpload=false] whether to enable uploader
-	 * @param {OC.Files.Client} [options.filesClient] files client to use
-	 */
-	var FileList = function($el, options) {
-		this.initialize($el, options);
-	};
-	/**
-	 * @memberof OCA.Files
-	 */
-	FileList.prototype = {
-		SORT_INDICATOR_ASC_CLASS: 'icon-triangle-n',
-		SORT_INDICATOR_DESC_CLASS: 'icon-triangle-s',
-
-		id: 'files',
-		appName: t('files', 'Files'),
-		isEmpty: true,
-		useUndo:true,
-
-		/**
-		 * Top-level container with controls and file list
-		 */
-		$el: null,
-
-		/**
-		 * Files table
-		 */
-		$table: null,
-
-		/**
-		 * List of rows (table tbody)
-		 */
-		$fileList: null,
-
-		/**
-		 * @type OCA.Files.BreadCrumb
-		 */
-		breadcrumb: null,
-
-		/**
-		 * @type OCA.Files.FileSummary
-		 */
-		fileSummary: null,
-
-		/**
-		 * @type OCA.Files.DetailsView
-		 */
-		_detailsView: null,
-
-		/**
-		 * Files client instance
-		 *
-		 * @type OC.Files.Client
-		 */
-		filesClient: null,
-
-		/**
-		 * Whether the file list was initialized already.
-		 * @type boolean
-		 */
-		initialized: false,
-
-		/**
-		 * Wheater the file list was already shown once
-		 * @type boolean
-		 */
-		shown: false,
-
-		/**
-		 * Number of files per page
-		 *
-		 * @return {int} page size
-		 */
-		pageSize: function() {
-			return Math.ceil(this.$container.height() / 50);
-		},
-
-		/**
-		 * Array of files in the current folder.
-		 * The entries are of file data.
-		 *
-		 * @type Array.<OC.Files.FileInfo>
-		 */
-		files: [],
-
-		/**
-		 * Current directory entry
-		 *
-		 * @type OC.Files.FileInfo
-		 */
-		dirInfo: null,
-
-		/**
-		 * File actions handler, defaults to OCA.Files.FileActions
-		 * @type OCA.Files.FileActions
-		 */
-		fileActions: null,
-
-		/**
-		 * Whether selection is allowed, checkboxes and selection overlay will
-		 * be rendered
-		 */
-		_allowSelection: true,
-
-		/**
-		 * Map of file id to file data
-		 * @type Object.<int, Object>
-		 */
-		_selectedFiles: {},
-
-		/**
-		 * Summary of selected files.
-		 * @type OCA.Files.FileSummary
-		 */
-		_selectionSummary: null,
-
-		/**
-		 * If not empty, only files containing this string will be shown
-		 * @type String
-		 */
-		_filter: '',
-
-		/**
-		 * @type Backbone.Model
-		 */
-		_filesConfig: undefined,
-
-		/**
-		 * Sort attribute
-		 * @type String
-		 */
-		_sort: 'name',
-
-		/**
-		 * Sort direction: 'asc' or 'desc'
-		 * @type String
-		 */
-		_sortDirection: 'asc',
-
-		/**
-		 * Sort comparator function for the current sort
-		 * @type Function
-		 */
-		_sortComparator: null,
-
-		/**
-		 * Whether to do a client side sort.
-		 * When false, clicking on a table header will call reload().
-		 * When true, clicking on a table header will simply resort the list.
-		 */
-		_clientSideSort: true,
-
-		/**
-		 * Whether or not users can change the sort attribute or direction
-		 */
-		_allowSorting: true,
-
-		/**
-		 * Current directory
-		 * @type String
-		 */
-		_currentDirectory: null,
-
-		_dragOptions: null,
-		_folderDropOptions: null,
-
-		/**
-		 * @type OC.Uploader
-		 */
-		_uploader: null,
-
-		/**
-		 * Initialize the file list and its components
-		 *
-		 * @param $el container element with existing markup for the #controls
-		 * and a table
-		 * @param options map of options, see other parameters
-		 * @param options.scrollContainer scrollable container, defaults to $(window)
-		 * @param options.dragOptions drag options, disabled by default
-		 * @param options.folderDropOptions folder drop options, disabled by default
-		 * @param options.scrollTo name of file to scroll to after the first load
-		 * @param {OC.Files.Client} [options.filesClient] files API client
-		 * @param {OC.Backbone.Model} [options.filesConfig] files app configuration
-		 * @private
-		 */
-		initialize: function($el, options) {
-			var self = this;
-			options = options || {};
-			if (this.initialized) {
-				return;
-			}
-
-			if (options.config) {
-				this._filesConfig = options.config;
-			} else if (!_.isUndefined(OCA.Files) && !_.isUndefined(OCA.Files.App)) {
-				this._filesConfig = OCA.Files.App.getFilesConfig();
-			} else {
-				this._filesConfig = new OC.Backbone.Model({
-					'showhidden': false
-				});
-			}
-
-			if (options.dragOptions) {
-				this._dragOptions = options.dragOptions;
-			}
-			if (options.folderDropOptions) {
-				this._folderDropOptions = options.folderDropOptions;
-			}
-			if (options.filesClient) {
-				this.filesClient = options.filesClient;
-			} else {
-				// default client if not specified
-				this.filesClient = OC.Files.getClient();
-			}
-
-			this.$el = $el;
-			if (options.id) {
-				this.id = options.id;
-			}
-			this.$container = options.scrollContainer || $(window);
-			this.$table = $el.find('table:first');
-			this.$fileList = $el.find('#fileList');
-
-			if (!_.isUndefined(this._filesConfig)) {
-				this._filesConfig.on('change:showhidden', function() {
-					var showHidden = this.get('showhidden');
-					self.$el.toggleClass('hide-hidden-files', !showHidden);
-					self.updateSelectionSummary();
-
-					if (!showHidden) {
-						// hiding files could make the page too small, need to try rendering next page
-						self._onScroll();
-					}
-				});
-
-				this.$el.toggleClass('hide-hidden-files', !this._filesConfig.get('showhidden'));
-			}
-
-
-			if (_.isUndefined(options.detailsViewEnabled) || options.detailsViewEnabled) {
-				this._detailsView = new OCA.Files.DetailsView();
-				this._detailsView.$el.insertBefore(this.$el);
-				this._detailsView.$el.addClass('disappear');
-			}
-
-			this._initFileActions(options.fileActions);
-
-			if (this._detailsView) {
-				this._detailsView.addDetailView(new OCA.Files.MainFileInfoDetailView({fileList: this, fileActions: this.fileActions}));
-			}
-
-			this.files = [];
-			this._selectedFiles = {};
-			this._selectionSummary = new OCA.Files.FileSummary(undefined, {config: this._filesConfig});
-			// dummy root dir info
-			this.dirInfo = new OC.Files.FileInfo({});
-
-			this.fileSummary = this._createSummary();
-
-			if (options.sorting) {
-				this.setSort(options.sorting.mode, options.sorting.direction, false, false);
-			} else {
-				this.setSort('name', 'asc', false, false);
-			}
-
-			var breadcrumbOptions = {
-				onClick: _.bind(this._onClickBreadCrumb, this),
-				getCrumbUrl: function(part) {
-					return self.linkTo(part.dir);
-				}
-			};
-			// if dropping on folders is allowed, then also allow on breadcrumbs
-			if (this._folderDropOptions) {
-				breadcrumbOptions.onDrop = _.bind(this._onDropOnBreadCrumb, this);
-				breadcrumbOptions.onOver = function() {
-					self.$el.find('td.filename.ui-droppable').droppable('disable');
-				}
-				breadcrumbOptions.onOut = function() {
-					self.$el.find('td.filename.ui-droppable').droppable('enable');
-				}
-			}
-			this.breadcrumb = new OCA.Files.BreadCrumb(breadcrumbOptions);
-
-			var $controls = this.$el.find('#controls');
-			if ($controls.length > 0) {
-				$controls.prepend(this.breadcrumb.$el);
-				this.$table.addClass('has-controls');
-			}
-
-			this._renderNewButton();
-
-			this.$el.find('thead th .columntitle').click(_.bind(this._onClickHeader, this));
-
-			this._onResize = _.debounce(_.bind(this._onResize, this), 100);
-			$('#app-content').on('appresized', this._onResize);
-			$(window).resize(this._onResize);
-
-			this.$el.on('show', this._onResize);
-
-			this.updateSearch();
-
-			this.$fileList.on('click','td.filename>a.name, td.filesize, td.date', _.bind(this._onClickFile, this));
-
-			this.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(this._onClickFileCheckbox, this));
-			this.$el.on('show', _.bind(this._onShow, this));
-			this.$el.on('urlChanged', _.bind(this._onUrlChanged, this));
-			this.$el.find('.select-all').click(_.bind(this._onClickSelectAll, this));
-			this.$el.find('.download').click(_.bind(this._onClickDownloadSelected, this));
-			this.$el.find('.delete-selected').click(_.bind(this._onClickDeleteSelected, this));
-
-			this.$el.find('.selectedActions a').tooltip({placement:'top'});
-
-			this.$container.on('scroll', _.bind(this._onScroll, this));
-
-			if (options.scrollTo) {
-				this.$fileList.one('updated', function() {
-					self.scrollTo(options.scrollTo);
-				});
-			}
-
-			if (options.enableUpload) {
-				// TODO: auto-create this element
-				var $uploadEl = this.$el.find('#file_upload_start');
-				if ($uploadEl.exists()) {
-					this._uploader = new OC.Uploader($uploadEl, {
-						fileList: this,
-						filesClient: this.filesClient,
-						dropZone: $('#content')
-					});
-
-					this.setupUploadEvents(this._uploader);
-				}
-			}
-
-			OC.Plugins.attach('OCA.Files.FileList', this);
-		},
-
-		/**
-		 * Destroy / uninitialize this instance.
-		 */
-		destroy: function() {
-			if (this._newFileMenu) {
-				this._newFileMenu.remove();
-			}
-			if (this._newButton) {
-				this._newButton.remove();
-			}
-			if (this._detailsView) {
-				this._detailsView.remove();
-			}
-			// TODO: also unregister other event handlers
-			this.fileActions.off('registerAction', this._onFileActionsUpdated);
-			this.fileActions.off('setDefault', this._onFileActionsUpdated);
-			OC.Plugins.detach('OCA.Files.FileList', this);
-			$('#app-content').off('appresized', this._onResize);
-		},
-
-		/**
-		 * Initializes the file actions, set up listeners.
-		 *
-		 * @param {OCA.Files.FileActions} fileActions file actions
-		 */
-		_initFileActions: function(fileActions) {
-			var self = this;
-			this.fileActions = fileActions;
-			if (!this.fileActions) {
-				this.fileActions = new OCA.Files.FileActions();
-				this.fileActions.registerDefaultActions();
-			}
-
-			if (this._detailsView) {
-				this.fileActions.registerAction({
-					name: 'Details',
-					displayName: t('files', 'Details'),
-					mime: 'all',
-					order: -50,
-					iconClass: 'icon-details',
-					permissions: OC.PERMISSION_READ,
-					actionHandler: function(fileName, context) {
-						self._updateDetailsView(fileName);
-					}
-				});
-			}
-
-			this._onFileActionsUpdated = _.debounce(_.bind(this._onFileActionsUpdated, this), 100);
-			this.fileActions.on('registerAction', this._onFileActionsUpdated);
-			this.fileActions.on('setDefault', this._onFileActionsUpdated);
-		},
-
-		/**
-		 * Returns a unique model for the given file name.
-		 *
-		 * @param {string|object} fileName file name or jquery row
-		 * @return {OCA.Files.FileInfoModel} file info model
-		 */
-		getModelForFile: function(fileName) {
-			var self = this;
-			var $tr;
-			// jQuery object ?
-			if (fileName.is) {
-				$tr = fileName;
-				fileName = $tr.attr('data-file');
-			} else {
-				$tr = this.findFileEl(fileName);
-			}
-
-			if (!$tr || !$tr.length) {
-				return null;
-			}
-
-			// if requesting the selected model, return it
-			if (this._currentFileModel && this._currentFileModel.get('name') === fileName) {
-				return this._currentFileModel;
-			}
-
-			// TODO: note, this is a temporary model required for synchronising
-			// state between different views.
-			// In the future the FileList should work with Backbone.Collection
-			// and contain existing models that can be used.
-			// This method would in the future simply retrieve the matching model from the collection.
-			var model = new OCA.Files.FileInfoModel(this.elementToFile($tr), {
-				filesClient: this.filesClient
-			});
-			if (!model.get('path')) {
-				model.set('path', this.getCurrentDirectory(), {silent: true});
-			}
-
-			model.on('change', function(model) {
-				// re-render row
-				var highlightState = $tr.hasClass('highlighted');
-				$tr = self.updateRow(
-					$tr,
-					model.toJSON(),
-					{updateSummary: true, silent: false, animate: true}
-				);
-
-				// restore selection state
-				var selected = !!self._selectedFiles[$tr.data('id')];
-				self._selectFileEl($tr, selected);
-
-				$tr.toggleClass('highlighted', highlightState);
-			});
-			model.on('busy', function(model, state) {
-				self.showFileBusyState($tr, state);
-			});
-
-			return model;
-		},
-
-		/**
-		 * Displays the details view for the given file and
-		 * selects the given tab
-		 *
-		 * @param {string|OCA.Files.FileInfoModel} fileName file name or FileInfoModel for which to show details
-		 * @param {string} [tabId] optional tab id to select
-		 */
-		showDetailsView: function(fileName, tabId) {
-			this._updateDetailsView(fileName);
-			if (tabId) {
-				this._detailsView.selectTab(tabId);
-			}
-			OC.Apps.showAppSidebar(this._detailsView.$el);
-		},
-
-		/**
-		 * Update the details view to display the given file
-		 *
-		 * @param {string|OCA.Files.FileInfoModel} fileName file name from the current list or a FileInfoModel object
-		 * @param {boolean} [show=true] whether to open the sidebar if it was closed
-		 */
-		_updateDetailsView: function(fileName, show) {
-			if (!this._detailsView) {
-				return;
-			}
-
-			// show defaults to true
-			show = _.isUndefined(show) || !!show;
-			var oldFileInfo = this._detailsView.getFileInfo();
-			if (oldFileInfo) {
-				// TODO: use more efficient way, maybe track the highlight
-				this.$fileList.children().filterAttr('data-id', '' + oldFileInfo.get('id')).removeClass('highlighted');
-				oldFileInfo.off('change', this._onSelectedModelChanged, this);
-			}
-
-			if (!fileName) {
-				this._detailsView.setFileInfo(null);
-				if (this._currentFileModel) {
-					this._currentFileModel.off();
-				}
-				this._currentFileModel = null;
-				OC.Apps.hideAppSidebar(this._detailsView.$el);
-				return;
-			}
-
-			if (show && this._detailsView.$el.hasClass('disappear')) {
-				OC.Apps.showAppSidebar(this._detailsView.$el);
-			}
-
-			if (fileName instanceof OCA.Files.FileInfoModel) {
-				var model = fileName;
-			} else {
-				var $tr = this.findFileEl(fileName);
-				var model = this.getModelForFile($tr);
-				$tr.addClass('highlighted');
-			}
-
-			this._currentFileModel = model;
-
-			this._detailsView.setFileInfo(model);
-			this._detailsView.$el.scrollTop(0);
-		},
-
-		/**
-		 * Event handler for when the window size changed
-		 */
-		_onResize: function() {
-			var containerWidth = this.$el.width();
-			var actionsWidth = 0;
-			$.each(this.$el.find('#controls .actions'), function(index, action) {
-				actionsWidth += $(action).outerWidth();
-			});
-
-			// subtract app navigation toggle when visible
-			containerWidth -= $('#app-navigation-toggle').width();
-
-			this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10);
-
-			this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth());
-		},
-
-		/**
-		 * Event handler when leaving previously hidden state
-		 */
-		_onShow: function(e) {
-			if (this.shown) {
-				this.reload();
-			}
-			this.shown = true;
-		},
-
-		/**
-		 * Event handler for when the URL changed
-		 */
-		_onUrlChanged: function(e) {
-			if (e && _.isString(e.dir)) {
-				var currentDir = this.getCurrentDirectory();
-				// this._currentDirectory is NULL when fileList is first initialised
-				if( (this._currentDirectory || this.$el.find('#dir').val()) && currentDir === e.dir) {
-					return;
-				}
-				this.changeDirectory(e.dir, false, true);
-			}
-		},
-
-		/**
-		 * Selected/deselects the given file element and updated
-		 * the internal selection cache.
-		 *
-		 * @param {Object} $tr single file row element
-		 * @param {bool} state true to select, false to deselect
-		 */
-		_selectFileEl: function($tr, state, showDetailsView) {
-			var $checkbox = $tr.find('td.filename>.selectCheckBox');
-			var oldData = !!this._selectedFiles[$tr.data('id')];
-			var data;
-			$checkbox.prop('checked', state);
-			$tr.toggleClass('selected', state);
-			// already selected ?
-			if (state === oldData) {
-				return;
-			}
-			data = this.elementToFile($tr);
-			if (state) {
-				this._selectedFiles[$tr.data('id')] = data;
-				this._selectionSummary.add(data);
-			}
-			else {
-				delete this._selectedFiles[$tr.data('id')];
-				this._selectionSummary.remove(data);
-			}
-			if (this._detailsView && !this._detailsView.$el.hasClass('disappear')) {
-				// hide sidebar
-				this._updateDetailsView(null);
-			}
-			this.$el.find('.select-all').prop('checked', this._selectionSummary.getTotal() === this.files.length);
-		},
-
-		/**
-		 * Event handler for when clicking on files to select them
-		 */
-		_onClickFile: function(event) {
-			var $tr = $(event.target).closest('tr');
-			if ($tr.hasClass('dragging')) {
-				return;
-			}
-			if (this._allowSelection && (event.ctrlKey || event.shiftKey)) {
-				event.preventDefault();
-				if (event.shiftKey) {
-					var $lastTr = $(this._lastChecked);
-					var lastIndex = $lastTr.index();
-					var currentIndex = $tr.index();
-					var $rows = this.$fileList.children('tr');
-
-					// last clicked checkbox below current one ?
-					if (lastIndex > currentIndex) {
-						var aux = lastIndex;
-						lastIndex = currentIndex;
-						currentIndex = aux;
-					}
-
-					// auto-select everything in-between
-					for (var i = lastIndex + 1; i < currentIndex; i++) {
-						this._selectFileEl($rows.eq(i), true);
-					}
-				}
-				else {
-					this._lastChecked = $tr;
-				}
-				var $checkbox = $tr.find('td.filename>.selectCheckBox');
-				this._selectFileEl($tr, !$checkbox.prop('checked'));
-				this.updateSelectionSummary();
-			} else {
-				// clicked directly on the name
-				if (!this._detailsView || $(event.target).is('.nametext') || $(event.target).closest('.nametext').length) {
-					var filename = $tr.attr('data-file');
-					var renaming = $tr.data('renaming');
-					if (!renaming) {
-						this.fileActions.currentFile = $tr.find('td');
-						var mime = this.fileActions.getCurrentMimeType();
-						var type = this.fileActions.getCurrentType();
-						var permissions = this.fileActions.getCurrentPermissions();
-						var action = this.fileActions.getDefault(mime,type, permissions);
-						if (action) {
-							event.preventDefault();
-							// also set on global object for legacy apps
-							window.FileActions.currentFile = this.fileActions.currentFile;
-							action(filename, {
-								$file: $tr,
-								fileList: this,
-								fileActions: this.fileActions,
-								dir: $tr.attr('data-path') || this.getCurrentDirectory()
-							});
-						}
-						// deselect row
-						$(event.target).closest('a').blur();
-					}
-				} else {
-					this._updateDetailsView($tr.attr('data-file'));
-					event.preventDefault();
-				}
-			}
-		},
-
-		/**
-		 * Event handler for when clicking on a file's checkbox
-		 */
-		_onClickFileCheckbox: function(e) {
-			var $tr = $(e.target).closest('tr');
-			var state = !$tr.hasClass('selected');
-			this._selectFileEl($tr, state);
-			this._lastChecked = $tr;
-			this.updateSelectionSummary();
-			if (this._detailsView && !this._detailsView.$el.hasClass('disappear')) {
-				// hide sidebar
-				this._updateDetailsView(null);
-			}
-		},
-
-		/**
-		 * Event handler for when selecting/deselecting all files
-		 */
-		_onClickSelectAll: function(e) {
-			var checked = $(e.target).prop('checked');
-			this.$fileList.find('td.filename>.selectCheckBox').prop('checked', checked)
-				.closest('tr').toggleClass('selected', checked);
-			this._selectedFiles = {};
-			this._selectionSummary.clear();
-			if (checked) {
-				for (var i = 0; i < this.files.length; i++) {
-					var fileData = this.files[i];
-					this._selectedFiles[fileData.id] = fileData;
-					this._selectionSummary.add(fileData);
-				}
-			}
-			this.updateSelectionSummary();
-			if (this._detailsView && !this._detailsView.$el.hasClass('disappear')) {
-				// hide sidebar
-				this._updateDetailsView(null);
-			}
-		},
-
-		/**
-		 * Event handler for when clicking on "Download" for the selected files
-		 */
-		_onClickDownloadSelected: function(event) {
-			var files;
-			var dir = this.getCurrentDirectory();
-			if (this.isAllSelected() && this.getSelectedFiles().length > 1) {
-				files = OC.basename(dir);
-				dir = OC.dirname(dir) || '/';
-			}
-			else {
-				files = _.pluck(this.getSelectedFiles(), 'name');
-			}
-
-			var downloadFileaction = $('#selectedActionsList').find('.download');
-
-			// don't allow a second click on the download action
-			if(downloadFileaction.hasClass('disabled')) {
-				event.preventDefault();
-				return;
-			}
-
-			var disableLoadingState = function(){
-				OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, false);
-			};
-
-			OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, true);
-			if(this.getSelectedFiles().length > 1) {
-				OCA.Files.Files.handleDownload(this.getDownloadUrl(files, dir, true), disableLoadingState);
-			}
-			else {
-				first = this.getSelectedFiles()[0];
-				OCA.Files.Files.handleDownload(this.getDownloadUrl(first.name, dir, true), disableLoadingState);
-			}
-			return false;
-		},
-
-		/**
-		 * Event handler for when clicking on "Delete" for the selected files
-		 */
-		_onClickDeleteSelected: function(event) {
-			var files = null;
-			if (!this.isAllSelected()) {
-				files = _.pluck(this.getSelectedFiles(), 'name');
-			}
-			this.do_delete(files);
-			event.preventDefault();
-			return false;
-		},
-
-		/**
-		 * Event handler when clicking on a table header
-		 */
-		_onClickHeader: function(e) {
-			if (this.$table.hasClass('multiselect')) {
-				return;
-			}
-			var $target = $(e.target);
-			var sort;
-			if (!$target.is('a')) {
-				$target = $target.closest('a');
-			}
-			sort = $target.attr('data-sort');
-			if (sort && this._allowSorting) {
-				if (this._sort === sort) {
-					this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true, true);
-				}
-				else {
-					if ( sort === 'name' ) {	//default sorting of name is opposite to size and mtime
-						this.setSort(sort, 'asc', true, true);
-					}
-					else {
-						this.setSort(sort, 'desc', true, true);
-					}
-				}
-			}
-		},
-
-		/**
-		 * Event handler when clicking on a bread crumb
-		 */
-		_onClickBreadCrumb: function(e) {
-			var $el = $(e.target).closest('.crumb'),
-				$targetDir = $el.data('dir');
-
-			if ($targetDir !== undefined && e.which === 1) {
-				e.preventDefault();
-				this.changeDirectory($targetDir);
-				this.updateSearch();
-			}
-		},
-
-		/**
-		 * Event handler for when scrolling the list container.
-		 * This appends/renders the next page of entries when reaching the bottom.
-		 */
-		_onScroll: function(e) {
-			if (this.$container.scrollTop() + this.$container.height() > this.$el.height() - 300) {
-				this._nextPage(true);
-			}
-		},
-
-		/**
-		 * Event handler when dropping on a breadcrumb
-		 */
-		_onDropOnBreadCrumb: function( event, ui ) {
-			var self = this;
-			var $target = $(event.target);
-			if (!$target.is('.crumb')) {
-				$target = $target.closest('.crumb');
-			}
-			var targetPath = $(event.target).data('dir');
-			var dir = this.getCurrentDirectory();
-			while (dir.substr(0,1) === '/') {//remove extra leading /'s
-				dir = dir.substr(1);
-			}
-			dir = '/' + dir;
-			if (dir.substr(-1,1) !== '/') {
-				dir = dir + '/';
-			}
-			// do nothing if dragged on current dir
-			if (targetPath === dir || targetPath + '/' === dir) {
-				return;
-			}
-
-			var files = this.getSelectedFiles();
-			if (files.length === 0) {
-				// single one selected without checkbox?
-				files = _.map(ui.helper.find('tr'), function(el) {
-					return self.elementToFile($(el));
-				});
-			}
-
-			this.move(_.pluck(files, 'name'), targetPath);
-
-			// re-enable td elements to be droppable
-			// sometimes the filename drop handler is still called after re-enable,
-			// it seems that waiting for a short time before re-enabling solves the problem
-			setTimeout(function() {
-				self.$el.find('td.filename.ui-droppable').droppable('enable');
-			}, 10);
-		},
-
-		/**
-		 * Sets a new page title
-		 */
-		setPageTitle: function(title){
-			if (title) {
-				title += ' - ';
-			} else {
-				title = '';
-			}
-			title += this.appName;
-			// Sets the page title with the " - Nextcloud" suffix as in templates
-			window.document.title = title + ' - ' + oc_defaults.title;
-
-			return true;
-		},
-		/**
-		 * Returns the file info for the given file name from the internal collection.
-		 *
-		 * @param {string} fileName file name
-		 * @return {OCA.Files.FileInfo} file info or null if it was not found
-		 *
-		 * @since 8.2
-		 */
-		findFile: function(fileName) {
-			return _.find(this.files, function(aFile) {
-				return (aFile.name === fileName);
-			}) || null;
-		},
-		/**
-		 * Returns the tr element for a given file name, but only if it was already rendered.
-		 *
-		 * @param {string} fileName file name
-		 * @return {Object} jQuery object of the matching row
-		 */
-		findFileEl: function(fileName){
-			// use filterAttr to avoid escaping issues
-			return this.$fileList.find('tr').filterAttr('data-file', fileName);
-		},
-
-		/**
-		 * Returns the file data from a given file element.
-		 * @param $el file tr element
-		 * @return file data
-		 */
-		elementToFile: function($el){
-			$el = $($el);
-			var data = {
-				id: parseInt($el.attr('data-id'), 10),
-				name: $el.attr('data-file'),
-				mimetype: $el.attr('data-mime'),
-				mtime: parseInt($el.attr('data-mtime'), 10),
-				type: $el.attr('data-type'),
-				etag: $el.attr('data-etag'),
-				permissions: parseInt($el.attr('data-permissions'), 10),
-				hasPreview: $el.attr('data-has-preview') === 'true'
-			};
-			var size = $el.attr('data-size');
-			if (size) {
-				data.size = parseInt(size, 10);
-			}
-			var icon = $el.attr('data-icon');
-			if (icon) {
-				data.icon = icon;
-			}
-			var mountType = $el.attr('data-mounttype');
-			if (mountType) {
-				data.mountType = mountType;
-			}
-			var path = $el.attr('data-path');
-			if (path) {
-				data.path = path;
-			}
-			return data;
-		},
-
-		/**
-		 * Appends the next page of files into the table
-		 * @param animate true to animate the new elements
-		 * @return array of DOM elements of the newly added files
-		 */
-		_nextPage: function(animate) {
-			var index = this.$fileList.children().length,
-				count = this.pageSize(),
-				hidden,
-				tr,
-				fileData,
-				newTrs = [],
-				isAllSelected = this.isAllSelected(),
-				showHidden = this._filesConfig.get('showhidden');
-
-			if (index >= this.files.length) {
-				return false;
-			}
-
-			while (count > 0 && index < this.files.length) {
-				fileData = this.files[index];
-				if (this._filter) {
-					hidden = fileData.name.toLowerCase().indexOf(this._filter.toLowerCase()) === -1;
-				} else {
-					hidden = false;
-				}
-				tr = this._renderRow(fileData, {updateSummary: false, silent: true, hidden: hidden});
-				this.$fileList.append(tr);
-				if (isAllSelected || this._selectedFiles[fileData.id]) {
-					tr.addClass('selected');
-					tr.find('.selectCheckBox').prop('checked', true);
-				}
-				if (animate) {
-					tr.addClass('appear transparent');
-				}
-				newTrs.push(tr);
-				index++;
-				// only count visible rows
-				if (showHidden || !tr.hasClass('hidden-file')) {
-					count--;
-				}
-			}
-
-			// trigger event for newly added rows
-			if (newTrs.length > 0) {
-				this.$fileList.trigger($.Event('fileActionsReady', {fileList: this, $files: newTrs}));
-			}
-
-			if (animate) {
-				// defer, for animation
-				window.setTimeout(function() {
-					for (var i = 0; i < newTrs.length; i++ ) {
-						newTrs[i].removeClass('transparent');
-					}
-				}, 0);
-			}
-
-			return newTrs;
-		},
-
-		/**
-		 * Event handler for when file actions were updated.
-		 * This will refresh the file actions on the list.
-		 */
-		_onFileActionsUpdated: function() {
-			var self = this;
-			var $files = this.$fileList.find('tr');
-			if (!$files.length) {
-				return;
-			}
-
-			$files.each(function() {
-				self.fileActions.display($(this).find('td.filename'), false, self);
-			});
-			this.$fileList.trigger($.Event('fileActionsReady', {fileList: this, $files: $files}));
-
-		},
-
-		/**
-		 * Sets the files to be displayed in the list.
-		 * This operation will re-render the list and update the summary.
-		 * @param filesArray array of file data (map)
-		 */
-		setFiles: function(filesArray) {
-			var self = this;
-
-			// detach to make adding multiple rows faster
-			this.files = filesArray;
-
-			this.$fileList.empty();
-
-			// clear "Select all" checkbox
-			this.$el.find('.select-all').prop('checked', false);
-
-			// Save full files list while rendering
-
-			this.isEmpty = this.files.length === 0;
-			this._nextPage();
-
-			this.updateEmptyContent();
-
-			this.fileSummary.calculate(this.files);
-
-			this._selectedFiles = {};
-			this._selectionSummary.clear();
-			this.updateSelectionSummary();
-			$(window).scrollTop(0);
-
-			this.$fileList.trigger(jQuery.Event('updated'));
-			_.defer(function() {
-				self.$el.closest('#app-content').trigger(jQuery.Event('apprendered'));
-			});
-		},
-
-		/**
-		 * Returns whether the given file info must be hidden
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo file info
-		 *
-		 * @return {boolean} true if the file is a hidden file, false otherwise
-		 */
-		_isHiddenFile: function(file) {
-			return file.name && file.name.charAt(0) === '.';
-		},
-
-		/**
-		 * Returns the icon URL matching the given file info
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo file info
-		 *
-		 * @return {string} icon URL
-		 */
-		_getIconUrl: function(fileInfo) {
-			var mimeType = fileInfo.mimetype || 'application/octet-stream';
-			if (mimeType === 'httpd/unix-directory') {
-				// use default folder icon
-				if (fileInfo.mountType === 'shared' || fileInfo.mountType === 'shared-root') {
-					return OC.MimeType.getIconUrl('dir-shared');
-				} else if (fileInfo.mountType === 'external-root') {
-					return OC.MimeType.getIconUrl('dir-external');
-				} else if (fileInfo.mountType !== undefined && fileInfo.mountType !== '') {
-					return OC.MimeType.getIconUrl('dir-' + fileInfo.mountType);
-				}
-				return OC.MimeType.getIconUrl('dir');
-			}
-			return OC.MimeType.getIconUrl(mimeType);
-		},
-
-		/**
-		 * Creates a new table row element using the given file data.
-		 * @param {OC.Files.FileInfo} fileData file info attributes
-		 * @param options map of attributes
-		 * @return new tr element (not appended to the table)
-		 */
-		_createRow: function(fileData, options) {
-			var td, simpleSize, basename, extension, sizeColor,
-				icon = fileData.icon || this._getIconUrl(fileData),
-				name = fileData.name,
-				// TODO: get rid of type, only use mime type
-				type = fileData.type || 'file',
-				mtime = parseInt(fileData.mtime, 10),
-				mime = fileData.mimetype,
-				path = fileData.path,
-				dataIcon = null,
-				linkUrl;
-			options = options || {};
-
-			if (isNaN(mtime)) {
-				mtime = new Date().getTime();
-			}
-
-			if (type === 'dir') {
-				mime = mime || 'httpd/unix-directory';
-
-				if (fileData.mountType && fileData.mountType.indexOf('external') === 0) {
-					icon = OC.MimeType.getIconUrl('dir-external');
-					dataIcon = icon;
-				}
-			}
-
-			//containing tr
-			var tr = $('<tr></tr>').attr({
-				"data-id" : fileData.id,
-				"data-type": type,
-				"data-size": fileData.size,
-				"data-file": name,
-				"data-mime": mime,
-				"data-mtime": mtime,
-				"data-etag": fileData.etag,
-				"data-permissions": fileData.permissions || this.getDirectoryPermissions(),
-				"data-has-preview": fileData.hasPreview !== false
-			});
-
-			if (dataIcon) {
-				// icon override
-				tr.attr('data-icon', dataIcon);
-			}
-
-			if (fileData.mountType) {
-				// dirInfo (parent) only exist for the "real" file list
-				if (this.dirInfo.id) {
-					// FIXME: HACK: detect shared-root
-					if (fileData.mountType === 'shared' && this.dirInfo.mountType !== 'shared' && this.dirInfo.mountType !== 'shared-root') {
-						// if parent folder isn't share, assume the displayed folder is a share root
-						fileData.mountType = 'shared-root';
-					} else if (fileData.mountType === 'external' && this.dirInfo.mountType !== 'external' && this.dirInfo.mountType !== 'external-root') {
-						// if parent folder isn't external, assume the displayed folder is the external storage root
-						fileData.mountType = 'external-root';
-					}
-				}
-				tr.attr('data-mounttype', fileData.mountType);
-			}
-
-			if (!_.isUndefined(path)) {
-				tr.attr('data-path', path);
-			}
-			else {
-				path = this.getCurrentDirectory();
-			}
-
-			// filename td
-			td = $('<td class="filename"></td>');
-
-
-			// linkUrl
-			if (mime === 'httpd/unix-directory') {
-				linkUrl = this.linkTo(path + '/' + name);
-			}
-			else {
-				linkUrl = this.getDownloadUrl(name, path, type === 'dir');
-			}
-			if (this._allowSelection) {
-				td.append(
-					'<input id="select-' + this.id + '-' + fileData.id +
-					'" type="checkbox" class="selectCheckBox checkbox"/><label for="select-' + this.id + '-' + fileData.id + '">' +
-					'<div class="thumbnail" style="background-image:url(' + icon + '); background-size: 32px;"></div>' +
-					'<span class="hidden-visually">' + t('files', 'Select') + '</span>' +
-					'</label>'
-				);
-			} else {
-				td.append('<div class="thumbnail" style="background-image:url(' + icon + '); background-size: 32px;"></div>');
-			}
-			var linkElem = $('<a></a>').attr({
-				"class": "name",
-				"href": linkUrl
-			});
-
-			// from here work on the display name
-			name = fileData.displayName || name;
-
-			// show hidden files (starting with a dot) completely in gray
-			if(name.indexOf('.') === 0) {
-				basename = '';
-				extension = name;
-			// split extension from filename for non dirs
-			} else if (mime !== 'httpd/unix-directory' && name.indexOf('.') !== -1) {
-				basename = name.substr(0, name.lastIndexOf('.'));
-				extension = name.substr(name.lastIndexOf('.'));
-			} else {
-				basename = name;
-				extension = false;
-			}
-			var nameSpan=$('<span></span>').addClass('nametext');
-			var innernameSpan = $('<span></span>').addClass('innernametext').text(basename);
-
-			if (path && path !== '/') {
-				var conflictingItems = this.$fileList.find('tr[data-file="' + this._jqSelEscape(name) + '"]');
-				if (conflictingItems.length !== 0) {
-					if (conflictingItems.length === 1) {
-						// Update the path on the first conflicting item
-						var $firstConflict = $(conflictingItems[0]),
-							firstConflictPath = $firstConflict.attr('data-path') + '/';
-						if (firstConflictPath.charAt(0) === '/') {
-							firstConflictPath = firstConflictPath.substr(1);
-						}
-						$firstConflict.find('td.filename span.innernametext').prepend($('<span></span>').addClass('conflict-path').text(firstConflictPath));
-					}
-
-					var conflictPath = path + '/';
-					if (conflictPath.charAt(0) === '/') {
-						conflictPath = conflictPath.substr(1);
-					}
-					nameSpan.append($('<span></span>').addClass('conflict-path').text(conflictPath));
-				}
-			}
-
-			nameSpan.append(innernameSpan);
-			linkElem.append(nameSpan);
-			if (extension) {
-				nameSpan.append($('<span></span>').addClass('extension').text(extension));
-			}
-			if (fileData.extraData) {
-				if (fileData.extraData.charAt(0) === '/') {
-					fileData.extraData = fileData.extraData.substr(1);
-				}
-				nameSpan.addClass('extra-data').attr('title', fileData.extraData);
-				nameSpan.tooltip({placement: 'right'});
-			}
-			// dirs can show the number of uploaded files
-			if (mime === 'httpd/unix-directory') {
-				linkElem.append($('<span></span>').attr({
-					'class': 'uploadtext',
-					'currentUploads': 0
-				}));
-			}
-			td.append(linkElem);
-			tr.append(td);
-
-			// size column
-			if (typeof(fileData.size) !== 'undefined' && fileData.size >= 0) {
-				simpleSize = humanFileSize(parseInt(fileData.size, 10), true);
-				sizeColor = Math.round(160-Math.pow((fileData.size/(1024*1024)),2));
-			} else {
-				simpleSize = t('files', 'Pending');
-			}
-
-			td = $('<td></td>').attr({
-				"class": "filesize",
-				"style": 'color:rgb(' + sizeColor + ',' + sizeColor + ',' + sizeColor + ')'
-			}).text(simpleSize);
-			tr.append(td);
-
-			// date column (1000 milliseconds to seconds, 60 seconds, 60 minutes, 24 hours)
-			// difference in days multiplied by 5 - brightest shade for files older than 32 days (160/5)
-			var modifiedColor = Math.round(((new Date()).getTime() - mtime )/1000/60/60/24*5 );
-			// ensure that the brightest color is still readable
-			if (modifiedColor >= '160') {
-				modifiedColor = 160;
-			}
-			var formatted;
-			var text;
-			if (mtime > 0) {
-				formatted = OC.Util.formatDate(mtime);
-				text = OC.Util.relativeModifiedDate(mtime);
-			} else {
-				formatted = t('files', 'Unable to determine date');
-				text = '?';
-			}
-			td = $('<td></td>').attr({ "class": "date" });
-			td.append($('<span></span>').attr({
-				"class": "modified live-relative-timestamp",
-				"title": formatted,
-				"data-timestamp": mtime,
-				"style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')'
-			}).text(text)
-			  .tooltip({placement: 'top'})
-			);
-			tr.find('.filesize').text(simpleSize);
-			tr.append(td);
-			return tr;
-		},
-
-		/* escape a selector expression for jQuery */
-		_jqSelEscape: function (expression) {
-			if (expression) {
-				return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&');
-			}
-			return null;
-		},
-
-		/**
-		 * Adds an entry to the files array and also into the DOM
-		 * in a sorted manner.
-		 *
-		 * @param {OC.Files.FileInfo} fileData map of file attributes
-		 * @param {Object} [options] map of attributes
-		 * @param {boolean} [options.updateSummary] true to update the summary
-		 * after adding (default), false otherwise. Defaults to true.
-		 * @param {boolean} [options.silent] true to prevent firing events like "fileActionsReady",
-		 * defaults to false.
-		 * @param {boolean} [options.animate] true to animate the thumbnail image after load
-		 * defaults to true.
-		 * @return new tr element (not appended to the table)
-		 */
-		add: function(fileData, options) {
-			var index = -1;
-			var $tr;
-			var $rows;
-			var $insertionPoint;
-			options = _.extend({animate: true}, options || {});
-
-			// there are three situations to cover:
-			// 1) insertion point is visible on the current page
-			// 2) insertion point is on a not visible page (visible after scrolling)
-			// 3) insertion point is at the end of the list
-
-			$rows = this.$fileList.children();
-			index = this._findInsertionIndex(fileData);
-			if (index > this.files.length) {
-				index = this.files.length;
-			}
-			else {
-				$insertionPoint = $rows.eq(index);
-			}
-
-			// is the insertion point visible ?
-			if ($insertionPoint.length) {
-				// only render if it will really be inserted
-				$tr = this._renderRow(fileData, options);
-				$insertionPoint.before($tr);
-			}
-			else {
-				// if insertion point is after the last visible
-				// entry, append
-				if (index === $rows.length) {
-					$tr = this._renderRow(fileData, options);
-					this.$fileList.append($tr);
-				}
-			}
-
-			this.isEmpty = false;
-			this.files.splice(index, 0, fileData);
-
-			if ($tr && options.animate) {
-				$tr.addClass('appear transparent');
-				window.setTimeout(function() {
-					$tr.removeClass('transparent');
-				});
-			}
-
-			if (options.scrollTo) {
-				this.scrollTo(fileData.name);
-			}
-
-			// defaults to true if not defined
-			if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) {
-				this.fileSummary.add(fileData, true);
-				this.updateEmptyContent();
-			}
-
-			return $tr;
-		},
-
-		/**
-		 * Creates a new row element based on the given attributes
-		 * and returns it.
-		 *
-		 * @param {OC.Files.FileInfo} fileData map of file attributes
-		 * @param {Object} [options] map of attributes
-		 * @param {int} [options.index] index at which to insert the element
-		 * @param {boolean} [options.updateSummary] true to update the summary
-		 * after adding (default), false otherwise. Defaults to true.
-		 * @param {boolean} [options.animate] true to animate the thumbnail image after load
-		 * defaults to true.
-		 * @return new tr element (not appended to the table)
-		 */
-		_renderRow: function(fileData, options) {
-			options = options || {};
-			var type = fileData.type || 'file',
-				mime = fileData.mimetype,
-				path = fileData.path || this.getCurrentDirectory(),
-				permissions = parseInt(fileData.permissions, 10) || 0;
-
-			if (fileData.isShareMountPoint) {
-				permissions = permissions | OC.PERMISSION_UPDATE;
-			}
-
-			if (type === 'dir') {
-				mime = mime || 'httpd/unix-directory';
-			}
-			var tr = this._createRow(
-				fileData,
-				options
-			);
-			var filenameTd = tr.find('td.filename');
-
-			// TODO: move dragging to FileActions ?
-			// enable drag only for deletable files
-			if (this._dragOptions && permissions & OC.PERMISSION_DELETE) {
-				filenameTd.draggable(this._dragOptions);
-			}
-			// allow dropping on folders
-			if (this._folderDropOptions && mime === 'httpd/unix-directory') {
-				tr.droppable(this._folderDropOptions);
-			}
-
-			if (options.hidden) {
-				tr.addClass('hidden');
-			}
-
-			if (this._isHiddenFile(fileData)) {
-				tr.addClass('hidden-file');
-			}
-
-			// display actions
-			this.fileActions.display(filenameTd, !options.silent, this);
-
-			if (mime !== 'httpd/unix-directory' && fileData.hasPreview !== false) {
-				var iconDiv = filenameTd.find('.thumbnail');
-				// lazy load / newly inserted td ?
-				// the typeof check ensures that the default value of animate is true
-				if (typeof(options.animate) === 'undefined' || !!options.animate) {
-					this.lazyLoadPreview({
-						path: path + '/' + fileData.name,
-						mime: mime,
-						etag: fileData.etag,
-						callback: function(url) {
-							iconDiv.css('background-image', 'url("' + url + '")');
-						}
-					});
-				}
-				else {
-					// set the preview URL directly
-					var urlSpec = {
-							file: path + '/' + fileData.name,
-							c: fileData.etag
-						};
-					var previewUrl = this.generatePreviewUrl(urlSpec);
-					previewUrl = previewUrl.replace('(', '%28').replace(')', '%29');
-					iconDiv.css('background-image', 'url("' + previewUrl + '")');
-				}
-			}
-			return tr;
-		},
-		/**
-		 * Returns the current directory
-		 * @method getCurrentDirectory
-		 * @return current directory
-		 */
-		getCurrentDirectory: function(){
-			return this._currentDirectory || this.$el.find('#dir').val() || '/';
-		},
-		/**
-		 * Returns the directory permissions
-		 * @return permission value as integer
-		 */
-		getDirectoryPermissions: function() {
-			return parseInt(this.$el.find('#permissions').val(), 10);
-		},
-		/**
-		 * Changes the current directory and reload the file list.
-		 * @param {string} targetDir target directory (non URL encoded)
-		 * @param {boolean} [changeUrl=true] if the URL must not be changed (defaults to true)
-		 * @param {boolean} [force=false] set to true to force changing directory
-		 * @param {string} [fileId] optional file id, if known, to be appended in the URL
-		 */
-		changeDirectory: function(targetDir, changeUrl, force, fileId) {
-			var self = this;
-			var currentDir = this.getCurrentDirectory();
-			targetDir = targetDir || '/';
-			if (!force && currentDir === targetDir) {
-				return;
-			}
-			this._setCurrentDir(targetDir, changeUrl, fileId);
-
-			// discard finished uploads list, we'll get it through a regular reload
-			this._uploads = {};
-			this.reload().then(function(success){
-				if (!success) {
-					self.changeDirectory(currentDir, true);
-				}
-			});
-		},
-		linkTo: function(dir) {
-			return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
-		},
-
-		/**
-		 * @param {string} path
-		 * @returns {boolean}
-		 */
-		_isValidPath: function(path) {
-			var sections = path.split('/');
-			for (var i = 0; i < sections.length; i++) {
-				if (sections[i] === '..') {
-					return false;
-				}
-			}
-
-			return path.toLowerCase().indexOf(decodeURI('%0a')) === -1 &&
-				path.toLowerCase().indexOf(decodeURI('%00')) === -1;
-		},
-
-		/**
-		 * Sets the current directory name and updates the breadcrumb.
-		 * @param targetDir directory to display
-		 * @param changeUrl true to also update the URL, false otherwise (default)
-		 * @param {string} [fileId] file id
-		 */
-		_setCurrentDir: function(targetDir, changeUrl, fileId) {
-			targetDir = targetDir.replace(/\\/g, '/');
-			if (!this._isValidPath(targetDir)) {
-				targetDir = '/';
-				changeUrl = true;
-			}
-			var previousDir = this.getCurrentDirectory(),
-				baseDir = OC.basename(targetDir);
-
-			if (baseDir !== '') {
-				this.setPageTitle(baseDir);
-			}
-			else {
-				this.setPageTitle();
-			}
-
-			if (targetDir.length > 0 && targetDir[0] !== '/') {
-				targetDir = '/' + targetDir;
-			}
-			this._currentDirectory = targetDir;
-
-			// legacy stuff
-			this.$el.find('#dir').val(targetDir);
-
-			if (changeUrl !== false) {
-				var params = {
-					dir: targetDir,
-					previousDir: previousDir
-				};
-				if (fileId) {
-					params.fileId = fileId;
-				}
-				this.$el.trigger(jQuery.Event('changeDirectory', params));
-			}
-			this.breadcrumb.setDirectory(this.getCurrentDirectory());
-		},
-		/**
-		 * Sets the current sorting and refreshes the list
-		 *
-		 * @param sort sort attribute name
-		 * @param direction sort direction, one of "asc" or "desc"
-		 * @param update true to update the list, false otherwise (default)
-		 * @param persist true to save changes in the database (default)
-		 */
-		setSort: function(sort, direction, update, persist) {
-			var comparator = FileList.Comparators[sort] || FileList.Comparators.name;
-			this._sort = sort;
-			this._sortDirection = (direction === 'desc')?'desc':'asc';
-			this._sortComparator = function(fileInfo1, fileInfo2) {
-				if(fileInfo1.isFavorite && !fileInfo2.isFavorite) {
-					return -1;
-				} else if(!fileInfo1.isFavorite && fileInfo2.isFavorite) {
-					return 1;
-				}
-				return direction === 'asc' ? comparator(fileInfo1, fileInfo2) : -comparator(fileInfo1, fileInfo2);
-			};
-
-			this.$el.find('thead th .sort-indicator')
-				.removeClass(this.SORT_INDICATOR_ASC_CLASS)
-				.removeClass(this.SORT_INDICATOR_DESC_CLASS)
-				.toggleClass('hidden', true)
-				.addClass(this.SORT_INDICATOR_DESC_CLASS);
-
-			this.$el.find('thead th.column-' + sort + ' .sort-indicator')
-				.removeClass(this.SORT_INDICATOR_ASC_CLASS)
-				.removeClass(this.SORT_INDICATOR_DESC_CLASS)
-				.toggleClass('hidden', false)
-				.addClass(direction === 'desc' ? this.SORT_INDICATOR_DESC_CLASS : this.SORT_INDICATOR_ASC_CLASS);
-			if (update) {
-				if (this._clientSideSort) {
-					this.files.sort(this._sortComparator);
-					this.setFiles(this.files);
-				}
-				else {
-					this.reload();
-				}
-			}
-
-			if (persist) {
-				$.post(OC.generateUrl('/apps/files/api/v1/sorting'), {
-					mode: sort,
-					direction: direction
-				});
-			}
-		},
-
-		/**
-		 * Returns list of webdav properties to request
-		 */
-		_getWebdavProperties: function() {
-			return [].concat(this.filesClient.getPropfindProperties());
-		},
-
-		/**
-		 * Reloads the file list using ajax call
-		 *
-		 * @return ajax call object
-		 */
-		reload: function() {
-			this._selectedFiles = {};
-			this._selectionSummary.clear();
-			if (this._currentFileModel) {
-				this._currentFileModel.off();
-			}
-			this._currentFileModel = null;
-			this.$el.find('.select-all').prop('checked', false);
-			this.showMask();
-			this._reloadCall = this.filesClient.getFolderContents(
-				this.getCurrentDirectory(), {
-					includeParent: true,
-					properties: this._getWebdavProperties()
-				}
-			);
-			if (this._detailsView) {
-				// close sidebar
-				this._updateDetailsView(null);
-			}
-			var callBack = this.reloadCallback.bind(this);
-			return this._reloadCall.then(callBack, callBack);
-		},
-		reloadCallback: function(status, result) {
-			delete this._reloadCall;
-			this.hideMask();
-
-			if (status === 401) {
-				return false;
-			}
-
-			// Firewall Blocked request?
-			if (status === 403) {
-				// Go home
-				this.changeDirectory('/');
-				OC.Notification.show(t('files', 'This operation is forbidden'), {type: 'error'});
-				return false;
-			}
-
-			// Did share service die or something else fail?
-			if (status === 500) {
-				// Go home
-				this.changeDirectory('/');
-				OC.Notification.show(t('files', 'This directory is unavailable, please check the logs or contact the administrator'), 
-					{type: 'error'}
-				);
-				return false;
-			}
-
-			if (status === 503) {
-				// Go home
-				if (this.getCurrentDirectory() !== '/') {
-					this.changeDirectory('/');
-					// TODO: read error message from exception
-					OC.Notification.show(t('files', 'Storage is temporarily not available'), 
-						{type: 'error'}
-					);
-				}
-				return false;
-			}
-
-			if (status === 400 || status === 404 || status === 405) {
-				// go back home
-				this.changeDirectory('/');
-				return false;
-			}
-			// aborted ?
-			if (status === 0){
-				return true;
-			}
-
-			// TODO: parse remaining quota from PROPFIND response
-			this.updateStorageStatistics(true);
-
-			// first entry is the root
-			this.dirInfo = result.shift();
-			this.breadcrumb.setDirectoryInfo(this.dirInfo);
-
-			if (this.dirInfo.permissions) {
-				this.setDirectoryPermissions(this.dirInfo.permissions);
-			}
-
-			result.sort(this._sortComparator);
-			this.setFiles(result);
-
-			if (this.dirInfo) {
-				var newFileId = this.dirInfo.id;
-				// update fileid in URL
-				var params = {
-					dir: this.getCurrentDirectory()
-				};
-				if (newFileId) {
-					params.fileId = newFileId;
-				}
-				this.$el.trigger(jQuery.Event('afterChangeDirectory', params));
-			}
-			return true;
-		},
-
-		updateStorageStatistics: function(force) {
-			OCA.Files.Files.updateStorageStatistics(this.getCurrentDirectory(), force);
-		},
-
-		/**
-		 * @deprecated do not use nor override
-		 */
-		getAjaxUrl: function(action, params) {
-			return OCA.Files.Files.getAjaxUrl(action, params);
-		},
-
-		getDownloadUrl: function(files, dir, isDir) {
-			return OCA.Files.Files.getDownloadUrl(files, dir || this.getCurrentDirectory(), isDir);
-		},
-
-		getUploadUrl: function(fileName, dir) {
-			if (_.isUndefined(dir)) {
-				dir = this.getCurrentDirectory();
-			}
-
-			var pathSections = dir.split('/');
-			if (!_.isUndefined(fileName)) {
-				pathSections.push(fileName);
-			}
-			var encodedPath = '';
-			_.each(pathSections, function(section) {
-				if (section !== '') {
-					encodedPath += '/' + encodeURIComponent(section);
-				}
-			});
-			return OC.linkToRemoteBase('webdav') + encodedPath;
-		},
-
-		/**
-		 * Generates a preview URL based on the URL space.
-		 * @param urlSpec attributes for the URL
-		 * @param {int} urlSpec.x width
-		 * @param {int} urlSpec.y height
-		 * @param {String} urlSpec.file path to the file
-		 * @return preview URL
-		 */
-		generatePreviewUrl: function(urlSpec) {
-			urlSpec = urlSpec || {};
-			if (!urlSpec.x) {
-				urlSpec.x = this.$table.data('preview-x') || 32;
-			}
-			if (!urlSpec.y) {
-				urlSpec.y = this.$table.data('preview-y') || 32;
-			}
-			urlSpec.x *= window.devicePixelRatio;
-			urlSpec.y *= window.devicePixelRatio;
-			urlSpec.x = Math.ceil(urlSpec.x);
-			urlSpec.y = Math.ceil(urlSpec.y);
-			urlSpec.forceIcon = 0;
-			return OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
-		},
-
-		/**
-		 * Lazy load a file's preview.
-		 *
-		 * @param path path of the file
-		 * @param mime mime type
-		 * @param callback callback function to call when the image was loaded
-		 * @param etag file etag (for caching)
-		 */
-		lazyLoadPreview : function(options) {
-			var self = this;
-			var path = options.path;
-			var mime = options.mime;
-			var ready = options.callback;
-			var etag = options.etag;
-
-			// get mime icon url
-			var iconURL = OC.MimeType.getIconUrl(mime);
-			var previewURL,
-				urlSpec = {};
-			ready(iconURL); // set mimeicon URL
-
-			urlSpec.file = OCA.Files.Files.fixPath(path);
-			if (options.x) {
-				urlSpec.x = options.x;
-			}
-			if (options.y) {
-				urlSpec.y = options.y;
-			}
-			if (options.a) {
-				urlSpec.a = options.a;
-			}
-			if (options.mode) {
-				urlSpec.mode = options.mode;
-			}
-
-			if (etag){
-				// use etag as cache buster
-				urlSpec.c = etag;
-			}
-
-			previewURL = self.generatePreviewUrl(urlSpec);
-			previewURL = previewURL.replace('(', '%28');
-			previewURL = previewURL.replace(')', '%29');
-
-			// preload image to prevent delay
-			// this will make the browser cache the image
-			var img = new Image();
-			img.onload = function(){
-				// if loading the preview image failed (no preview for the mimetype) then img.width will < 5
-				if (img.width > 5) {
-					ready(previewURL, img);
-				} else if (options.error) {
-					options.error();
-				}
-			};
-			if (options.error) {
-				img.onerror = options.error;
-			}
-			img.src = previewURL;
-		},
-
-		/**
-		 * @deprecated
-		 */
-		setDirectoryPermissions: function(permissions) {
-			var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0;
-			this.$el.find('#permissions').val(permissions);
-			this.$el.find('.creatable').toggleClass('hidden', !isCreatable);
-			this.$el.find('.notCreatable').toggleClass('hidden', isCreatable);
-		},
-		/**
-		 * Shows/hides action buttons
-		 *
-		 * @param show true for enabling, false for disabling
-		 */
-		showActions: function(show){
-			this.$el.find('.actions,#file_action_panel').toggleClass('hidden', !show);
-			if (show){
-				// make sure to display according to permissions
-				var permissions = this.getDirectoryPermissions();
-				var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0;
-				this.$el.find('.creatable').toggleClass('hidden', !isCreatable);
-				this.$el.find('.notCreatable').toggleClass('hidden', isCreatable);
-				// remove old style breadcrumbs (some apps might create them)
-				this.$el.find('#controls .crumb').remove();
-				// refresh breadcrumbs in case it was replaced by an app
-				this.breadcrumb.render();
-			}
-			else{
-				this.$el.find('.creatable, .notCreatable').addClass('hidden');
-			}
-		},
-		/**
-		 * Enables/disables viewer mode.
-		 * In viewer mode, apps can embed themselves under the controls bar.
-		 * In viewer mode, the actions of the file list will be hidden.
-		 * @param show true for enabling, false for disabling
-		 */
-		setViewerMode: function(show){
-			this.showActions(!show);
-			this.$el.find('#filestable').toggleClass('hidden', show);
-			this.$el.trigger(new $.Event('changeViewerMode', {viewerModeEnabled: show}));
-		},
-		/**
-		 * Removes a file entry from the list
-		 * @param name name of the file to remove
-		 * @param {Object} [options] map of attributes
-		 * @param {boolean} [options.updateSummary] true to update the summary
-		 * after removing, false otherwise. Defaults to true.
-		 * @return deleted element
-		 */
-		remove: function(name, options){
-			options = options || {};
-			var fileEl = this.findFileEl(name);
-			var fileId = fileEl.data('id');
-			var index = fileEl.index();
-			if (!fileEl.length) {
-				return null;
-			}
-			if (this._selectedFiles[fileId]) {
-				// remove from selection first
-				this._selectFileEl(fileEl, false);
-				this.updateSelectionSummary();
-			}
-			if (this._dragOptions && (fileEl.data('permissions') & OC.PERMISSION_DELETE)) {
-				// file is only draggable when delete permissions are set
-				fileEl.find('td.filename').draggable('destroy');
-			}
-			this.files.splice(index, 1);
-			if (this._currentFileModel && this._currentFileModel.get('id') === fileId) {
-				// Note: in the future we should call destroy() directly on the model
-				// and the model will take care of the deletion.
-				// Here we only trigger the event to notify listeners that
-				// the file was removed.
-				this._currentFileModel.trigger('destroy');
-				this._updateDetailsView(null);
-			}
-			fileEl.remove();
-			// TODO: improve performance on batch update
-			this.isEmpty = !this.files.length;
-			if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) {
-				this.updateEmptyContent();
-				this.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')}, true);
-			}
-
-			var lastIndex = this.$fileList.children().length;
-			// if there are less elements visible than one page
-			// but there are still pending elements in the array,
-			// then directly append the next page
-			if (lastIndex < this.files.length && lastIndex < this.pageSize()) {
-				this._nextPage(true);
-			}
-
-			return fileEl;
-		},
-		/**
-		 * Finds the index of the row before which the given
-		 * fileData should be inserted, considering the current
-		 * sorting
-		 *
-		 * @param {OC.Files.FileInfo} fileData file info
-		 */
-		_findInsertionIndex: function(fileData) {
-			var index = 0;
-			while (index < this.files.length && this._sortComparator(fileData, this.files[index]) > 0) {
-				index++;
-			}
-			return index;
-		},
-		/**
-		 * Moves a file to a given target folder.
-		 *
-		 * @param fileNames array of file names to move
-		 * @param targetPath absolute target path
-		 */
-		move: function(fileNames, targetPath) {
-			var self = this;
-			var dir = this.getCurrentDirectory();
-			if (dir.charAt(dir.length - 1) !== '/') {
-				dir += '/';
-			}
-			var target = OC.basename(targetPath);
-			if (!_.isArray(fileNames)) {
-				fileNames = [fileNames];
-			}
-			_.each(fileNames, function(fileName) {
-				var $tr = self.findFileEl(fileName);
-				self.showFileBusyState($tr, true);
-				if (targetPath.charAt(targetPath.length - 1) !== '/') {
-					// make sure we move the files into the target dir,
-					// not overwrite it
-					targetPath = targetPath + '/';
-				}
-				self.filesClient.move(dir + fileName, targetPath + fileName)
-					.done(function() {
-						// if still viewing the same directory
-						if (OC.joinPaths(self.getCurrentDirectory(), '/') === dir) {
-							// recalculate folder size
-							var oldFile = self.findFileEl(target);
-							var newFile = self.findFileEl(fileName);
-							var oldSize = oldFile.data('size');
-							var newSize = oldSize + newFile.data('size');
-							oldFile.data('size', newSize);
-							oldFile.find('td.filesize').text(OC.Util.humanFileSize(newSize));
-
-							// TODO: also update entry in FileList.files
-							self.remove(fileName);
-						}
-					})
-					.fail(function(status) {
-						if (status === 412) {
-							// TODO: some day here we should invoke the conflict dialog
-							OC.Notification.show(t('files', 'Could not move "{file}", target exists', 
-								{file: fileName}), {type: 'error'}
-							);
-						} else {
-							OC.Notification.show(t('files', 'Could not move "{file}"', 
-								{file: fileName}), {type: 'error'}
-							);
-						}
-					})
-					.always(function() {
-						self.showFileBusyState($tr, false);
-					});
-			});
-
-		},
-
-		/**
-		 * Updates the given row with the given file info
-		 *
-		 * @param {Object} $tr row element
-		 * @param {OCA.Files.FileInfo} fileInfo file info
-		 * @param {Object} options options
-		 *
-		 * @return {Object} new row element
-		 */
-		updateRow: function($tr, fileInfo, options) {
-			this.files.splice($tr.index(), 1);
-			$tr.remove();
-			options = _.extend({silent: true}, options);
-			options = _.extend(options, {updateSummary: false});
-			$tr = this.add(fileInfo, options);
-			this.$fileList.trigger($.Event('fileActionsReady', {fileList: this, $files: $tr}));
-			return $tr;
-		},
-
-		/**
-		 * Triggers file rename input field for the given file name.
-		 * If the user enters a new name, the file will be renamed.
-		 *
-		 * @param oldName file name of the file to rename
-		 */
-		rename: function(oldName) {
-			var self = this;
-			var tr, td, input, form;
-			tr = this.findFileEl(oldName);
-			var oldFileInfo = this.files[tr.index()];
-			tr.data('renaming',true);
-			td = tr.children('td.filename');
-			input = $('<input type="text" class="filename"/>').val(oldName);
-			form = $('<form></form>');
-			form.append(input);
-			td.children('a.name').hide();
-			td.append(form);
-			input.focus();
-			//preselect input
-			var len = input.val().lastIndexOf('.');
-			if ( len === -1 ||
-				tr.data('type') === 'dir' ) {
-				len = input.val().length;
-			}
-			input.selectRange(0, len);
-			var checkInput = function () {
-				var filename = input.val();
-				if (filename !== oldName) {
-					// Files.isFileNameValid(filename) throws an exception itself
-					OCA.Files.Files.isFileNameValid(filename);
-					if (self.inList(filename)) {
-						throw t('files', '{newName} already exists', {newName: filename}, undefined, {
-							escape: false
-						});
-					}
-				}
-				return true;
-			};
-
-			function restore() {
-				input.tooltip('hide');
-				tr.data('renaming',false);
-				form.remove();
-				td.children('a.name').show();
-			}
-
-			function updateInList(fileInfo) {
-				self.updateRow(tr, fileInfo);
-				self._updateDetailsView(fileInfo, false);
-			}
-
-			// TODO: too many nested blocks, move parts into functions
-			form.submit(function(event) {
-				event.stopPropagation();
-				event.preventDefault();
-				if (input.hasClass('error')) {
-					return;
-				}
-
-				try {
-					var newName = input.val();
-					input.tooltip('hide');
-					form.remove();
-
-					if (newName !== oldName) {
-						checkInput();
-						// mark as loading (temp element)
-						self.showFileBusyState(tr, true);
-						tr.attr('data-file', newName);
-						var basename = newName;
-						if (newName.indexOf('.') > 0 && tr.data('type') !== 'dir') {
-							basename = newName.substr(0, newName.lastIndexOf('.'));
-						}
-						td.find('a.name span.nametext').text(basename);
-						td.children('a.name').show();
-
-						var path = tr.attr('data-path') || self.getCurrentDirectory();
-						self.filesClient.move(OC.joinPaths(path, oldName), OC.joinPaths(path, newName))
-							.done(function() {
-								oldFileInfo.name = newName;
-								updateInList(oldFileInfo);
-							})
-							.fail(function(status) {
-								// TODO: 409 means current folder does not exist, redirect ?
-								if (status === 404) {
-									// source not found, so remove it from the list
-									OC.Notification.show(t('files', 'Could not rename "{fileName}", it does not exist any more', 
-										{fileName: oldName}), {timeout: 7, type: 'error'}
-									);
-
-									self.remove(newName, {updateSummary: true});
-									return;
-								} else if (status === 412) {
-									// target exists
-									OC.Notification.show(
-										t('files', 'The name "{targetName}" is already used in the folder "{dir}". Please choose a different name.',
-										{
-											targetName: newName,
-											dir: self.getCurrentDirectory(),
-										}),
-										{
-											type: 'error'
-										}
-									);
-								} else {
-									// restore the item to its previous state
-									OC.Notification.show(t('files', 'Could not rename "{fileName}"', 
-										{fileName: oldName}), {type: 'error'}
-									);
-								}
-								updateInList(oldFileInfo);
-							});
-					} else {
-						// add back the old file info when cancelled
-						self.files.splice(tr.index(), 1);
-						tr.remove();
-						tr = self.add(oldFileInfo, {updateSummary: false, silent: true});
-						self.$fileList.trigger($.Event('fileActionsReady', {fileList: self, $files: $(tr)}));
-					}
-				} catch (error) {
-					input.attr('title', error);
-					input.tooltip({placement: 'right', trigger: 'manual'});
-					input.tooltip('fixTitle');
-					input.tooltip('show');
-					input.addClass('error');
-				}
-				return false;
-			});
-			input.keyup(function(event) {
-				// verify filename on typing
-				try {
-					checkInput();
-					input.tooltip('hide');
-					input.removeClass('error');
-				} catch (error) {
-					input.attr('title', error);
-					input.tooltip({placement: 'right', trigger: 'manual'});
-					input.tooltip('fixTitle');
-					input.tooltip('show');
-					input.addClass('error');
-				}
-				if (event.keyCode === 27) {
-					restore();
-				}
-			});
-			input.click(function(event) {
-				event.stopPropagation();
-				event.preventDefault();
-			});
-			input.blur(function() {
-				form.trigger('submit');
-			});
-		},
-
-		/**
-		 * Create an empty file inside the current directory.
-		 *
-		 * @param {string} name name of the file
-		 *
-		 * @return {Promise} promise that will be resolved after the
-		 * file was created
-		 *
-		 * @since 8.2
-		 */
-		createFile: function(name) {
-			var self = this;
-			var deferred = $.Deferred();
-			var promise = deferred.promise();
-
-			OCA.Files.Files.isFileNameValid(name);
-
-			if (this.lastAction) {
-				this.lastAction();
-			}
-
-			name = this.getUniqueName(name);
-			var targetPath = this.getCurrentDirectory() + '/' + name;
-
-			self.filesClient.putFileContents(
-					targetPath,
-					' ', // dont create empty files which fails on some storage backends
-					{
-						contentType: 'text/plain',
-						overwrite: true
-					}
-				)
-				.done(function() {
-					// TODO: error handling / conflicts
-					self.addAndFetchFileInfo(targetPath, '', {scrollTo: true}).then(function(status, data) {
-						deferred.resolve(status, data);
-					}, function() {
-						OC.Notification.show(t('files', 'Could not create file "{file}"', 
-							{file: name}), {type: 'error'}
-						);
-					});
-				})
-				.fail(function(status) {
-					if (status === 412) {
-						OC.Notification.show(t('files', 'Could not create file "{file}" because it already exists', 
-							{file: name}), {type: 'error'}
-						);
-					} else {
-						OC.Notification.show(t('files', 'Could not create file "{file}"', 
-							{file: name}), {type: 'error'}
-						);
-					}
-					deferred.reject(status);
-				});
-
-			return promise;
-		},
-
-		/**
-		 * Create a directory inside the current directory.
-		 *
-		 * @param {string} name name of the directory
-		 *
-		 * @return {Promise} promise that will be resolved after the
-		 * directory was created
-		 *
-		 * @since 8.2
-		 */
-		createDirectory: function(name) {
-			var self = this;
-			var deferred = $.Deferred();
-			var promise = deferred.promise();
-
-			OCA.Files.Files.isFileNameValid(name);
-
-			if (this.lastAction) {
-				this.lastAction();
-			}
-
-			name = this.getUniqueName(name);
-			var targetPath = this.getCurrentDirectory() + '/' + name;
-
-			this.filesClient.createDirectory(targetPath)
-				.done(function() {
-					self.addAndFetchFileInfo(targetPath, '', {scrollTo:true}).then(function(status, data) {
-						deferred.resolve(status, data);
-					}, function() {
-						OC.Notification.show(t('files', 'Could not create folder "{dir}"', 
-							{dir: name}), {type: 'error'}
-						);
-					});
-				})
-				.fail(function(createStatus) {
-					// method not allowed, folder might exist already
-					if (createStatus === 405) {
-						// add it to the list, for completeness
-						self.addAndFetchFileInfo(targetPath, '', {scrollTo:true})
-							.done(function(status, data) {
-								OC.Notification.show(t('files', 'Could not create folder "{dir}" because it already exists', 
-									{dir: name}), {type: 'error'}
-								);
-								// still consider a failure
-								deferred.reject(createStatus, data);
-							})
-							.fail(function() {
-								OC.Notification.show(t('files', 'Could not create folder "{dir}"', 
-									{dir: name}), {type: 'error'}
-								);
-								deferred.reject(status);
-							});
-					} else {
-						OC.Notification.show(t('files', 'Could not create folder "{dir}"', 
-							{dir: name}), {type: 'error'}
-						);
-						deferred.reject(createStatus);
-					}
-				});
-
-			return promise;
-		},
-
-		/**
-		 * Add file into the list by fetching its information from the server first.
-		 *
-		 * If the given directory does not match the current directory, nothing will
-		 * be fetched.
-		 *
-		 * @param {String} fileName file name
-		 * @param {String} [dir] optional directory, defaults to the current one
-		 * @param {Object} options same options as #add
-		 * @return {Promise} promise that resolves with the file info, or an
-		 * already resolved Promise if no info was fetched. The promise rejects
-		 * if the file was not found or an error occurred.
-		 *
-		 * @since 9.0
-		 */
-		addAndFetchFileInfo: function(fileName, dir, options) {
-			var self = this;
-			var deferred = $.Deferred();
-			if (_.isUndefined(dir)) {
-				dir = this.getCurrentDirectory();
-			} else {
-				dir = dir || '/';
-			}
-
-			var targetPath = OC.joinPaths(dir, fileName);
-
-			if ((OC.dirname(targetPath) || '/') !== this.getCurrentDirectory()) {
-				// no need to fetch information
-				deferred.resolve();
-				return deferred.promise();
-			}
-
-			var addOptions = _.extend({
-				animate: true,
-				scrollTo: false
-			}, options || {});
-
-			this.filesClient.getFileInfo(targetPath, {
-					properties: this._getWebdavProperties()
-				})
-				.then(function(status, data) {
-					// remove first to avoid duplicates
-					self.remove(data.name);
-					self.add(data, addOptions);
-					deferred.resolve(status, data);
-				})
-				.fail(function(status) {
-					OC.Notification.show(t('files', 'Could not create file "{file}"', 
-						{file: name}), {type: 'error'}
-					);
-					deferred.reject(status);
-				});
-
-			return deferred.promise();
-		},
-
-		/**
-		 * Returns whether the given file name exists in the list
-		 *
-		 * @param {string} file file name
-		 *
-		 * @return {bool} true if the file exists in the list, false otherwise
-		 */
-		inList:function(file) {
-			return this.findFile(file);
-		},
-
-		/**
-		 * Shows busy state on a given file row or multiple
-		 *
-		 * @param {string|Array.<string>} files file name or array of file names
-		 * @param {bool} [busy=true] busy state, true for busy, false to remove busy state
-		 *
-		 * @since 8.2
-		 */
-		showFileBusyState: function(files, state) {
-			var self = this;
-			if (!_.isArray(files) && !files.is) {
-				files = [files];
-			}
-
-			if (_.isUndefined(state)) {
-				state = true;
-			}
-
-			_.each(files, function(fileName) {
-				// jquery element already ?
-				var $tr;
-				if (_.isString(fileName)) {
-					$tr = self.findFileEl(fileName);
-				} else {
-					$tr = $(fileName);
-				}
-
-				var $thumbEl = $tr.find('.thumbnail');
-				$tr.toggleClass('busy', state);
-
-				if (state) {
-					$thumbEl.attr('data-oldimage', $thumbEl.css('background-image'));
-					$thumbEl.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
-				} else {
-					$thumbEl.css('background-image', $thumbEl.attr('data-oldimage'));
-					$thumbEl.removeAttr('data-oldimage');
-				}
-			});
-		},
-
-		/**
-		 * Delete the given files from the given dir
-		 * @param files file names list (without path)
-		 * @param dir directory in which to delete the files, defaults to the current
-		 * directory
-		 */
-		do_delete:function(files, dir) {
-			var self = this;
-			if (files && files.substr) {
-				files=[files];
-			}
-			if (!files) {
-				// delete all files in directory
-				files = _.pluck(this.files, 'name');
-			}
-			if (files) {
-				this.showFileBusyState(files, true);
-			}
-			// Finish any existing actions
-			if (this.lastAction) {
-				this.lastAction();
-			}
-
-			dir = dir || this.getCurrentDirectory();
-
-			function removeFromList(file) {
-				var fileEl = self.remove(file, {updateSummary: false});
-				// FIXME: not sure why we need this after the
-				// element isn't even in the DOM any more
-				fileEl.find('.selectCheckBox').prop('checked', false);
-				fileEl.removeClass('selected');
-				self.fileSummary.remove({type: fileEl.attr('data-type'), size: fileEl.attr('data-size')});
-				// TODO: this info should be returned by the ajax call!
-				self.updateEmptyContent();
-				self.fileSummary.update();
-				self.updateSelectionSummary();
-				// FIXME: don't repeat this, do it once all files are done
-				self.updateStorageStatistics();
-			}
-
-			_.each(files, function(file) {
-				self.filesClient.remove(dir + '/' + file)
-					.done(function() {
-						removeFromList(file);
-					})
-					.fail(function(status) {
-						if (status === 404) {
-							// the file already did not exist, remove it from the list
-							removeFromList(file);
-						} else {
-							// only reset the spinner for that one file
-							OC.Notification.show(t('files', 'Error deleting file "{fileName}".', 
-								{fileName: file}), {type: 'error'}
-							);
-							var deleteAction = self.findFileEl(file).find('.action.delete');
-							deleteAction.removeClass('icon-loading-small').addClass('icon-delete');
-							self.showFileBusyState(files, false);
-						}
-					});
-			});
-		},
-		/**
-		 * Creates the file summary section
-		 */
-		_createSummary: function() {
-			var $tr = $('<tr class="summary"></tr>');
-			this.$el.find('tfoot').append($tr);
-
-			return new OCA.Files.FileSummary($tr, {config: this._filesConfig});
-		},
-		updateEmptyContent: function() {
-			var permissions = this.getDirectoryPermissions();
-			var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0;
-			this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
-			this.$el.find('#emptycontent .uploadmessage').toggleClass('hidden', !isCreatable || !this.isEmpty);
-			this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
-		},
-		/**
-		 * Shows the loading mask.
-		 *
-		 * @see OCA.Files.FileList#hideMask
-		 */
-		showMask: function() {
-			// in case one was shown before
-			var $mask = this.$el.find('.mask');
-			if ($mask.exists()) {
-				return;
-			}
-
-			this.$table.addClass('hidden');
-			this.$el.find('#emptycontent').addClass('hidden');
-
-			$mask = $('<div class="mask transparent icon-loading"></div>');
-
-			this.$el.append($mask);
-
-			$mask.removeClass('transparent');
-		},
-		/**
-		 * Hide the loading mask.
-		 * @see OCA.Files.FileList#showMask
-		 */
-		hideMask: function() {
-			this.$el.find('.mask').remove();
-			this.$table.removeClass('hidden');
-		},
-		scrollTo:function(file) {
-			if (!_.isArray(file)) {
-				file = [file];
-			}
-			if (file.length === 1) {
-				_.defer(function() {
-					this.showDetailsView(file[0]);
-				}.bind(this));
-			}
-			this.highlightFiles(file, function($tr) {
-				$tr.addClass('searchresult');
-				$tr.one('hover', function() {
-					$tr.removeClass('searchresult');
-				});
-			});
-		},
-		/**
-		 * @deprecated use setFilter(filter)
-		 */
-		filter:function(query) {
-			this.setFilter('');
-		},
-		/**
-		 * @deprecated use setFilter('')
-		 */
-		unfilter:function() {
-			this.setFilter('');
-		},
-		/**
-		 * hide files matching the given filter
-		 * @param filter
-		 */
-		setFilter:function(filter) {
-			var total = 0;
-			if (this._filter === filter) {
-				return;
-			}
-			this._filter = filter;
-			this.fileSummary.setFilter(filter, this.files);
-			total = this.fileSummary.getTotal();
-			if (!this.$el.find('.mask').exists()) {
-				this.hideIrrelevantUIWhenNoFilesMatch();
-			}
-
-			var visibleCount = 0;
-			filter = filter.toLowerCase();
-
-			function filterRows(tr) {
-				var $e = $(tr);
-				if ($e.data('file').toString().toLowerCase().indexOf(filter) === -1) {
-					$e.addClass('hidden');
-				} else {
-					visibleCount++;
-					$e.removeClass('hidden');
-				}
-			}
-
-			var $trs = this.$fileList.find('tr');
-			do {
-				_.each($trs, filterRows);
-				if (visibleCount < total) {
-					$trs = this._nextPage(false);
-				}
-			} while (visibleCount < total && $trs.length > 0);
-
-			this.$container.trigger('scroll');
-		},
-		hideIrrelevantUIWhenNoFilesMatch:function() {
-			if (this._filter && this.fileSummary.summary.totalDirs + this.fileSummary.summary.totalFiles === 0) {
-				this.$el.find('#filestable thead th').addClass('hidden');
-				this.$el.find('#emptycontent').addClass('hidden');
-				$('#searchresults').addClass('filter-empty');
-				$('#searchresults .emptycontent').addClass('emptycontent-search');
-				if ( $('#searchresults').length === 0 || $('#searchresults').hasClass('hidden') ) {
-					var error = t('files', 'No search results in other folders for {tag}{filter}{endtag}', {filter:this._filter});
-					this.$el.find('.nofilterresults').removeClass('hidden').
-						find('p').html(error.replace('{tag}', '<strong>').replace('{endtag}', '</strong>'));
-				}
-			} else {
-				$('#searchresults').removeClass('filter-empty');
-				$('#searchresults .emptycontent').removeClass('emptycontent-search');
-				this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
-				if (!this.$el.find('.mask').exists()) {
-					this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
-				}
-				this.$el.find('.nofilterresults').addClass('hidden');
-			}
-		},
-		/**
-		 * get the current filter
-		 * @param filter
-		 */
-		getFilter:function(filter) {
-			return this._filter;
-		},
-		/**
-		 * update the search object to use this filelist when filtering
-		 */
-		updateSearch:function() {
-			if (OCA.Search.files) {
-				OCA.Search.files.setFileList(this);
-			}
-			if (OC.Search) {
-				OC.Search.clear();
-			}
-		},
-		/**
-		 * Update UI based on the current selection
-		 */
-		updateSelectionSummary: function() {
-			var summary = this._selectionSummary.summary;
-			var selection;
-
-			var showHidden = !!this._filesConfig.get('showhidden');
-			if (summary.totalFiles === 0 && summary.totalDirs === 0) {
-				this.$el.find('#headerName a.name>span:first').text(t('files','Name'));
-				this.$el.find('#headerSize a>span:first').text(t('files','Size'));
-				this.$el.find('#modified a>span:first').text(t('files','Modified'));
-				this.$el.find('table').removeClass('multiselect');
-				this.$el.find('.selectedActions').addClass('hidden');
-			}
-			else {
-				this.$el.find('.selectedActions').removeClass('hidden');
-				this.$el.find('#headerSize a>span:first').text(OC.Util.humanFileSize(summary.totalSize));
-
-				var directoryInfo = n('files', '%n folder', '%n folders', summary.totalDirs);
-				var fileInfo = n('files', '%n file', '%n files', summary.totalFiles);
-
-				if (summary.totalDirs > 0 && summary.totalFiles > 0) {
-					var selectionVars = {
-						dirs: directoryInfo,
-						files: fileInfo
-					};
-					selection = t('files', '{dirs} and {files}', selectionVars);
-				} else if (summary.totalDirs > 0) {
-					selection = directoryInfo;
-				} else {
-					selection = fileInfo;
-				}
-
-				if (!showHidden && summary.totalHidden > 0) {
-					var hiddenInfo = n('files', 'including %n hidden', 'including %n hidden', summary.totalHidden);
-					selection += ' (' + hiddenInfo + ')';
-				}
-
-				this.$el.find('#headerName a.name>span:first').text(selection);
-				this.$el.find('#modified a>span:first').text('');
-				this.$el.find('table').addClass('multiselect');
-				this.$el.find('.delete-selected').toggleClass('hidden', !this.isSelectedDeletable());
-			}
-		},
-
-		/**
-		 * Check whether all selected files are deletable
-		 */
-		isSelectedDeletable: function() {
-			return _.reduce(this.getSelectedFiles(), function(deletable, file) {
-				return deletable && (file.permissions & OC.PERMISSION_DELETE);
-			}, true);
-		},
-
-		/**
-		 * Returns whether all files are selected
-		 * @return true if all files are selected, false otherwise
-		 */
-		isAllSelected: function() {
-			return this.$el.find('.select-all').prop('checked');
-		},
-
-		/**
-		 * Returns the file info of the selected files
-		 *
-		 * @return array of file names
-		 */
-		getSelectedFiles: function() {
-			return _.values(this._selectedFiles);
-		},
-
-		getUniqueName: function(name) {
-			if (this.findFileEl(name).exists()) {
-				var numMatch;
-				var parts=name.split('.');
-				var extension = "";
-				if (parts.length > 1) {
-					extension=parts.pop();
-				}
-				var base=parts.join('.');
-				numMatch=base.match(/\((\d+)\)/);
-				var num=2;
-				if (numMatch && numMatch.length>0) {
-					num=parseInt(numMatch[numMatch.length-1], 10)+1;
-					base=base.split('(');
-					base.pop();
-					base=$.trim(base.join('('));
-				}
-				name=base+' ('+num+')';
-				if (extension) {
-					name = name+'.'+extension;
-				}
-				// FIXME: ugly recursion
-				return this.getUniqueName(name);
-			}
-			return name;
-		},
-
-		/**
-		 * Shows a "permission denied" notification
-		 */
-		_showPermissionDeniedNotification: function() {
-			var message = t('files', 'You don’t have permission to upload or create files here');
-			OC.Notification.show(message, {type: 'error'});
-		},
-
-		/**
-		 * Setup file upload events related to the file-upload plugin
-		 *
-		 * @param {OC.Uploader} uploader
-		 */
-		setupUploadEvents: function(uploader) {
-			var self = this;
-
-			self._uploads = {};
-
-			// detect the progress bar resize
-			uploader.on('resized', this._onResize);
-
-			uploader.on('drop', function(e, data) {
-				self._uploader.log('filelist handle fileuploaddrop', e, data);
-
-				if (self.$el.hasClass('hidden')) {
-					// do not upload to invisible lists
-					e.preventDefault();
-					return false;
-				}
-
-				var dropTarget = $(e.delegatedEvent.target);
-
-				// check if dropped inside this container and not another one
-				if (dropTarget.length
-					&& !self.$el.is(dropTarget) // dropped on list directly
-					&& !self.$el.has(dropTarget).length // dropped inside list
-					&& !dropTarget.is(self.$container) // dropped on main container
-					) {
-					e.preventDefault();
-					return false;
-				}
-
-				// find the closest tr or crumb to use as target
-				dropTarget = dropTarget.closest('tr, .crumb');
-
-				// if dropping on tr or crumb, drag&drop upload to folder
-				if (dropTarget && (dropTarget.data('type') === 'dir' ||
-					dropTarget.hasClass('crumb'))) {
-
-					// remember as context
-					data.context = dropTarget;
-
-					// if permissions are specified, only allow if create permission is there
-					var permissions = dropTarget.data('permissions');
-					if (!_.isUndefined(permissions) && (permissions & OC.PERMISSION_CREATE) === 0) {
-						self._showPermissionDeniedNotification();
-						return false;
-					}
-					var dir = dropTarget.data('file');
-					// if from file list, need to prepend parent dir
-					if (dir) {
-						var parentDir = self.getCurrentDirectory();
-						if (parentDir[parentDir.length - 1] !== '/') {
-							parentDir += '/';
-						}
-						dir = parentDir + dir;
-					}
-					else{
-						// read full path from crumb
-						dir = dropTarget.data('dir') || '/';
-					}
-
-					// add target dir
-					data.targetDir = dir;
-				} else {
-					// cancel uploads to current dir if no permission
-					var isCreatable = (self.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0;
-					if (!isCreatable) {
-						self._showPermissionDeniedNotification();
-						e.stopPropagation();
-						return false;
-					}
-
-					// we are dropping somewhere inside the file list, which will
-					// upload the file to the current directory
-					data.targetDir = self.getCurrentDirectory();
-				}
-			});
-			uploader.on('add', function(e, data) {
-				self._uploader.log('filelist handle fileuploadadd', e, data);
-
-				// add ui visualization to existing folder
-				if (data.context && data.context.data('type') === 'dir') {
-					// add to existing folder
-
-					// update upload counter ui
-					var uploadText = data.context.find('.uploadtext');
-					var currentUploads = parseInt(uploadText.attr('currentUploads'), 10);
-					currentUploads += 1;
-					uploadText.attr('currentUploads', currentUploads);
-
-					var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads);
-					if (currentUploads === 1) {
-						self.showFileBusyState(uploadText.closest('tr'), true);
-						uploadText.text(translatedText);
-						uploadText.show();
-					} else {
-						uploadText.text(translatedText);
-					}
-				}
-
-				if (!data.targetDir) {
-					data.targetDir = self.getCurrentDirectory();
-				}
-
-			});
-			/*
-			 * when file upload done successfully add row to filelist
-			 * update counter when uploading to sub folder
-			 */
-			uploader.on('done', function(e, upload) {
-				self._uploader.log('filelist handle fileuploaddone', e, data);
-
-				var data = upload.data;
-				var status = data.jqXHR.status;
-				if (status < 200 || status >= 300) {
-					// error was handled in OC.Uploads already
-					return;
-				}
-
-				var fileName = upload.getFileName();
-				var fetchInfoPromise = self.addAndFetchFileInfo(fileName, upload.getFullPath());
-				if (!self._uploads) {
-					self._uploads = {};
-				}
-				if (OC.isSamePath(OC.dirname(upload.getFullPath() + '/'), self.getCurrentDirectory())) {
-					self._uploads[fileName] = fetchInfoPromise;
-				}
-
-				var uploadText = self.$fileList.find('tr .uploadtext');
-				self.showFileBusyState(uploadText.closest('tr'), false);
-				uploadText.fadeOut();
-				uploadText.attr('currentUploads', 0);
-			});
-			uploader.on('createdfolder', function(fullPath) {
-				self.addAndFetchFileInfo(OC.basename(fullPath), OC.dirname(fullPath));
-			});
-			uploader.on('stop', function() {
-				self._uploader.log('filelist handle fileuploadstop');
-
-				// prepare list of uploaded file names in the current directory
-				// and discard the other ones
-				var promises = _.values(self._uploads);
-				var fileNames = _.keys(self._uploads);
-				self._uploads = [];
-
-				// as soon as all info is fetched
-				$.when.apply($, promises).then(function() {
-					// highlight uploaded files
-					self.highlightFiles(fileNames);
-					self.updateStorageStatistics();
-				});
-
-				var uploadText = self.$fileList.find('tr .uploadtext');
-				self.showFileBusyState(uploadText.closest('tr'), false);
-				uploadText.fadeOut();
-				uploadText.attr('currentUploads', 0);
-			});
-			uploader.on('fail', function(e, data) {
-				self._uploader.log('filelist handle fileuploadfail', e, data);
-				self._uploads = [];
-
-				//if user pressed cancel hide upload chrome
-				//cleanup uploading to a dir
-				var uploadText = self.$fileList.find('tr .uploadtext');
-				self.showFileBusyState(uploadText.closest('tr'), false);
-				uploadText.fadeOut();
-				uploadText.attr('currentUploads', 0);
-				self.updateStorageStatistics();
-			});
-
-		},
-
-		/**
-		 * Scroll to the last file of the given list
-		 * Highlight the list of files
-		 * @param files array of filenames,
-		 * @param {Function} [highlightFunction] optional function
-		 * to be called after the scrolling is finished
-		 */
-		highlightFiles: function(files, highlightFunction) {
-			// Detection of the uploaded element
-			var filename = files[files.length - 1];
-			var $fileRow = this.findFileEl(filename);
-
-			while(!$fileRow.exists() && this._nextPage(false) !== false) { // Checking element existence
-				$fileRow = this.findFileEl(filename);
-			}
-
-			if (!$fileRow.exists()) { // Element not present in the file list
-				return;
-			}
-
-			var currentOffset = this.$container.scrollTop();
-			var additionalOffset = this.$el.find("#controls").height()+this.$el.find("#controls").offset().top;
-
-			// Animation
-			var _this = this;
-			var $scrollContainer = this.$container;
-			if ($scrollContainer[0] === window) {
-				// need to use "body" to animate scrolling
-				// when the scroll container is the window
-				$scrollContainer = $('body');
-			}
-			$scrollContainer.animate({
-				// Scrolling to the top of the new element
-				scrollTop: currentOffset + $fileRow.offset().top - $fileRow.height() * 2 - additionalOffset
-			}, {
-				duration: 500,
-				complete: function() {
-					// Highlighting function
-					var highlightRow = highlightFunction;
-
-					if (!highlightRow) {
-						highlightRow = function($fileRow) {
-							$fileRow.addClass("highlightUploaded");
-							setTimeout(function() {
-								$fileRow.removeClass("highlightUploaded");
-							}, 2500);
-						};
-					}
-
-					// Loop over uploaded files
-					for(var i=0; i<files.length; i++) {
-						var $fileRow = _this.findFileEl(files[i]);
-
-						if($fileRow.length !== 0) { // Checking element existence
-							highlightRow($fileRow);
-						}
-					}
-
-				}
-			});
-		},
-
-		_renderNewButton: function() {
-			// if an upload button (legacy) already exists or no actions container exist, skip
-			var $actionsContainer = this.$el.find('#controls .actions');
-			if (!$actionsContainer.length || this.$el.find('.button.upload').length) {
-				return;
-			}
-			if (!this._addButtonTemplate) {
-				this._addButtonTemplate = Handlebars.compile(TEMPLATE_ADDBUTTON);
-			}
-			var $newButton = $(this._addButtonTemplate({
-				addText: t('files', 'New'),
-				iconClass: 'icon-add'
-			}));
-
-			$actionsContainer.prepend($newButton);
-			$newButton.tooltip({'placement': 'bottom'});
-
-			$newButton.click(_.bind(this._onClickNewButton, this));
-			this._newButton = $newButton;
-		},
-
-		_onClickNewButton: function(event) {
-			var $target = $(event.target);
-			if (!$target.hasClass('.button')) {
-				$target = $target.closest('.button');
-			}
-			this._newButton.tooltip('hide');
-			event.preventDefault();
-			if ($target.hasClass('disabled')) {
-				return false;
-			}
-			if (!this._newFileMenu) {
-				this._newFileMenu = new OCA.Files.NewFileMenu({
-					fileList: this
-				});
-				$('.actions').append(this._newFileMenu.$el);
-			}
-			this._newFileMenu.showAt($target);
-
-			return false;
-		},
-
-		/**
-		 * Register a tab view to be added to all views
-		 */
-		registerTabView: function(tabView) {
-			if (this._detailsView) {
-				this._detailsView.addTabView(tabView);
-			}
-		},
-
-		/**
-		 * Register a detail view to be added to all views
-		 */
-		registerDetailView: function(detailView) {
-			if (this._detailsView) {
-				this._detailsView.addDetailView(detailView);
-			}
-		},
-
-		/**
-		 * Register a view to be added to the breadcrumb view
-		 */
-		registerBreadCrumbDetailView: function(detailView) {
-			if (this.breadcrumb) {
-				this.breadcrumb.addDetailView(detailView);
-			}
-		},
-
-		/**
-		 * Returns the registered detail views.
-		 *
-		 * @return null|Array<OCA.Files.DetailFileInfoView> an array with the
-		 *         registered DetailFileInfoViews, or null if the details view
-		 *         is not enabled.
-		 */
-		getRegisteredDetailViews: function() {
-			if (this._detailsView) {
-				return this._detailsView.getDetailViews();
-			}
-
-			return null;
-		}
-	};
-
-	/**
-	 * Sort comparators.
-	 * @namespace OCA.Files.FileList.Comparators
-	 * @private
-	 */
-	FileList.Comparators = {
-		/**
-		 * Compares two file infos by name, making directories appear
-		 * first.
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo1 file info
-		 * @param {OC.Files.FileInfo} fileInfo2 file info
-		 * @return {int} -1 if the first file must appear before the second one,
-		 * 0 if they are identify, 1 otherwise.
-		 */
-		name: function(fileInfo1, fileInfo2) {
-			if (fileInfo1.type === 'dir' && fileInfo2.type !== 'dir') {
-				return -1;
-			}
-			if (fileInfo1.type !== 'dir' && fileInfo2.type === 'dir') {
-				return 1;
-			}
-			return OC.Util.naturalSortCompare(fileInfo1.name, fileInfo2.name);
-		},
-		/**
-		 * Compares two file infos by size.
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo1 file info
-		 * @param {OC.Files.FileInfo} fileInfo2 file info
-		 * @return {int} -1 if the first file must appear before the second one,
-		 * 0 if they are identify, 1 otherwise.
-		 */
-		size: function(fileInfo1, fileInfo2) {
-			return fileInfo1.size - fileInfo2.size;
-		},
-		/**
-		 * Compares two file infos by timestamp.
-		 *
-		 * @param {OC.Files.FileInfo} fileInfo1 file info
-		 * @param {OC.Files.FileInfo} fileInfo2 file info
-		 * @return {int} -1 if the first file must appear before the second one,
-		 * 0 if they are identify, 1 otherwise.
-		 */
-		mtime: function(fileInfo1, fileInfo2) {
-			return fileInfo1.mtime - fileInfo2.mtime;
-		}
-	};
-
-	/**
-	 * File info attributes.
-	 *
-	 * @typedef {Object} OC.Files.FileInfo
-	 *
-	 * @lends OC.Files.FileInfo
-	 *
-	 * @deprecated use OC.Files.FileInfo instead
-	 *
-	 */
-	OCA.Files.FileInfo = OC.Files.FileInfo;
-
-	OCA.Files.FileList = FileList;
-})();
-
-$(document).ready(function() {
-	// FIXME: unused ?
-	OCA.Files.FileList.useUndo = (window.onbeforeunload)?true:false;
-	$(window).bind('beforeunload', function () {
-		if (OCA.Files.FileList.lastAction) {
-			OCA.Files.FileList.lastAction();
-		}
-	});
-	$(window).on('unload', function () {
-		$(window).trigger('beforeunload');
-	});
-
-});
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-(function() {
-
-	/**
-	 * Construct a new FileActions instance
-	 * @constructs Files
-	 */
-	var Files = function() {
-		this.initialize();
-	};
-	/**
-	 * @memberof OCA.Search
-	 */
-	Files.prototype = {
-
-		fileList: null,
-
-		/**
-		 * Initialize the file search
-		 */
-		initialize: function() {
-
-			var self = this;
-
-			this.fileAppLoaded = function() {
-				return !!OCA.Files && !!OCA.Files.App;
-			};
-			function inFileList($row, result) {
-				if (! self.fileAppLoaded()) {
-					return false;
-				}
-				var dir = self.fileList.getCurrentDirectory().replace(/\/+$/,'');
-				var resultDir = OC.dirname(result.path);
-				return dir === resultDir && self.fileList.inList(result.name);
-			}
-			function updateLegacyMimetype(result) {
-				// backward compatibility:
-				if (!result.mime && result.mime_type) {
-					result.mime = result.mime_type;
-				}
-			}
-			function hideNoFilterResults() {
-				var $nofilterresults = $('.nofilterresults');
-				if ( ! $nofilterresults.hasClass('hidden') ) {
-					$nofilterresults.addClass('hidden');
-				}
-			}
-
-			this.renderFolderResult = function($row, result) {
-				if (inFileList($row, result)) {
-					return null;
-				}
-				hideNoFilterResults();
-				/*render folder icon, show path beneath filename,
-				 show size and last modified date on the right */
-				this.updateLegacyMimetype(result);
-
-				var $pathDiv = $('<div class="path"></div>').text(result.path.substr(1, result.path.lastIndexOf("/")));
-				$row.find('td.info div.name').after($pathDiv).text(result.name);
-
-				$row.find('td.result a').attr('href', result.link);
-				$row.find('td.icon').css('background-image', 'url(' +  OC.MimeType.getIconUrl(result.mime) + ')');
-				return $row;
-			};
-
-			this.renderFileResult = function($row, result) {
-				if (inFileList($row, result)) {
-					return null;
-				}
-				hideNoFilterResults();
-				/*render preview icon, show path beneath filename,
-				 show size and last modified date on the right */
-				this.updateLegacyMimetype(result);
-
-				var $pathDiv = $('<div class="path"></div>').text(result.path.substr(1, result.path.lastIndexOf("/")));
-				$row.find('td.info div.name').after($pathDiv).text(result.name);
-
-				$row.find('td.result a').attr('href', result.link);
-
-				if (self.fileAppLoaded()) {
-					self.fileList.lazyLoadPreview({
-						path: result.path,
-						mime: result.mime,
-						callback: function (url) {
-							$row.find('td.icon').css('background-image', 'url(' + url + ')');
-						}
-					});
-				} else {
-					// FIXME how to get mime icon if not in files app
-					var mimeicon = result.mime.replace('/', '-');
-					$row.find('td.icon').css('background-image', 'url(' + OC.MimeType.getIconUrl(result.mime) + ')');
-					var dir = OC.dirname(result.path);
-					if (dir === '') {
-						dir = '/';
-					}
-					$row.find('td.info a').attr('href',
-						OC.generateUrl('/apps/files/?dir={dir}&scrollto={scrollto}', {dir: dir, scrollto: result.name})
-					);
-				}
-				return $row;
-			};
-
-
-			this.handleFolderClick = function($row, result, event) {
-				// open folder
-				if (self.fileAppLoaded() && self.fileList.id === 'files') {
-					self.fileList.changeDirectory(result.path);
-					return false;
-				} else {
-					return true;
-				}
-			};
-
-			this.handleFileClick = function($row, result, event) {
-				if (self.fileAppLoaded() && self.fileList.id === 'files') {
-					self.fileList.changeDirectory(OC.dirname(result.path));
-					self.fileList.scrollTo(result.name);
-					return false;
-				} else {
-					return true;
-				}
-			};
-
-			this.updateLegacyMimetype = function (result) {
-				// backward compatibility:
-				if (!result.mime && result.mime_type) {
-					result.mime = result.mime_type;
-				}
-			};
-			this.setFileList = function (fileList) {
-				this.fileList = fileList;
-			};
-
-			OC.Plugins.register('OCA.Search', this);
-		},
-		attach: function(search) {
-			var self = this;
-			search.setFilter('files', function (query) {
-				if (self.fileAppLoaded()) {
-					self.fileList.setFilter(query);
-					if (query.length > 2) {
-						//search is not started until 500msec have passed
-						window.setTimeout(function() {
-							$('.nofilterresults').addClass('hidden');
-						}, 500);
-					}
-				}
-			});
-
-			search.setRenderer('folder', this.renderFolderResult.bind(this));
-			search.setRenderer('file',   this.renderFileResult.bind(this));
-			search.setRenderer('image',   this.renderFileResult.bind(this));
-			search.setRenderer('audio',   this.renderFileResult.bind(this));
-
-			search.setHandler('folder',  this.handleFolderClick.bind(this));
-			search.setHandler(['file', 'audio', 'image'], this.handleFileClick.bind(this));
-
-			if (self.fileAppLoaded()) {
-				// hide results when switching directory outside of search results
-				$('#app-content').delegate('>div', 'changeDirectory', function() {
-					search.clear();
-				});
-			}
-		}
-	};
-	OCA.Search.Files = Files;
-	OCA.Search.files = new Files();
-})();
-
-
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-// HACK: this piece needs to be loaded AFTER the files app (for unit tests)
-$(document).ready(function() {
-	(function(OCA) {
-		/**
-		 * @class OCA.Files.FavoritesFileList
-		 * @augments OCA.Files.FavoritesFileList
-		 *
-		 * @classdesc Favorites file list.
-		 * Displays the list of files marked as favorites
-		 *
-		 * @param $el container element with existing markup for the #controls
-		 * and a table
-		 * @param [options] map of options, see other parameters
-		 */
-		var FavoritesFileList = function($el, options) {
-			this.initialize($el, options);
-		};
-		FavoritesFileList.prototype = _.extend({}, OCA.Files.FileList.prototype,
-			/** @lends OCA.Files.FavoritesFileList.prototype */ {
-			id: 'favorites',
-			appName: t('files','Favorites'),
-
-			_clientSideSort: true,
-			_allowSelection: false,
-
-			/**
-			 * @private
-			 */
-			initialize: function($el, options) {
-				OCA.Files.FileList.prototype.initialize.apply(this, arguments);
-				if (this.initialized) {
-					return;
-				}
-				OC.Plugins.attach('OCA.Files.FavoritesFileList', this);
-			},
-
-			updateEmptyContent: function() {
-				var dir = this.getCurrentDirectory();
-				if (dir === '/') {
-					// root has special permissions
-					this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
-					this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
-				}
-				else {
-					OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments);
-				}
-			},
-
-			getDirectoryPermissions: function() {
-				return OC.PERMISSION_READ | OC.PERMISSION_DELETE;
-			},
-
-			updateStorageStatistics: function() {
-				// no op because it doesn't have
-				// storage info like free space / used space
-			},
-
-			reload: function() {
-				var tagName = OC.TAG_FAVORITE;
-				this.showMask();
-				if (this._reloadCall) {
-					this._reloadCall.abort();
-				}
-
-				// there is only root
-				this._setCurrentDir('/', false);
-
-				this._reloadCall = this.filesClient.getFilteredFiles(
-					{
-						favorite: true
-					},
-					{
-						properties: this._getWebdavProperties()
-					}
-				);
-				var callBack = this.reloadCallback.bind(this);
-				return this._reloadCall.then(callBack, callBack);
-			},
-
-			reloadCallback: function(status, result) {
-				if (result) {
-					// prepend empty dir info because original handler
-					result.unshift({});
-				}
-
-				return OCA.Files.FileList.prototype.reloadCallback.call(this, status, result);
-			},
-
-			_onUrlChanged: function (e) {
-				if (e && _.isString(e.dir)) {
-					this.changeDirectory(e.dir, false, true);
-				}
-			}
-		});
-
-		OCA.Files.FavoritesFileList = FavoritesFileList;
-	})(OCA);
-});
-
-
-
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-// HACK: this piece needs to be loaded AFTER the files app (for unit tests)
-$(document).ready(function () {
-	(function (OCA) {
-		/**
-		 * @class OCA.Files.RecentFileList
-		 * @augments OCA.Files.RecentFileList
-		 *
-		 * @classdesc Recent file list.
-		 * Displays the list of recently modified files
-		 *
-		 * @param $el container element with existing markup for the #controls
-		 * and a table
-		 * @param [options] map of options, see other parameters
-		 */
-		var RecentFileList = function ($el, options) {
-			options.sorting = {
-				mode: 'mtime',
-				direction: 'desc'
-			};
-			this.initialize($el, options);
-			this._allowSorting = false;
-		};
-		RecentFileList.prototype = _.extend({}, OCA.Files.FileList.prototype,
-			/** @lends OCA.Files.RecentFileList.prototype */ {
-				id: 'recent',
-				appName: t('files', 'Recent'),
-
-				_clientSideSort: true,
-				_allowSelection: false,
-
-				/**
-				 * @private
-				 */
-				initialize: function () {
-					OCA.Files.FileList.prototype.initialize.apply(this, arguments);
-					if (this.initialized) {
-						return;
-					}
-					OC.Plugins.attach('OCA.Files.RecentFileList', this);
-				},
-
-				updateEmptyContent: function () {
-					var dir = this.getCurrentDirectory();
-					if (dir === '/') {
-						// root has special permissions
-						this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
-						this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
-					}
-					else {
-						OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments);
-					}
-				},
-
-				getDirectoryPermissions: function () {
-					return OC.PERMISSION_READ | OC.PERMISSION_DELETE;
-				},
-
-				updateStorageStatistics: function () {
-					// no op because it doesn't have
-					// storage info like free space / used space
-				},
-
-				reload: function () {
-					this.showMask();
-					if (this._reloadCall) {
-						this._reloadCall.abort();
-					}
-
-					// there is only root
-					this._setCurrentDir('/', false);
-
-					this._reloadCall = $.ajax({
-						url: OC.generateUrl('/apps/files/api/v1/recent'),
-						type: 'GET',
-						dataType: 'json'
-					});
-					var callBack = this.reloadCallback.bind(this);
-					return this._reloadCall.then(callBack, callBack);
-				},
-
-				reloadCallback: function (result) {
-					delete this._reloadCall;
-					this.hideMask();
-
-					if (result.files) {
-						this.setFiles(result.files.sort(this._sortComparator));
-						return true;
-					}
-					return false;
-				}
-			});
-
-		OCA.Files.RecentFileList = RecentFileList;
-	})(OCA);
-});
-
-
-
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global Handlebars */
-
-(function(OCA) {
-
-	_.extend(OC.Files.Client, {
-		PROPERTY_TAGS:	'{' + OC.Files.Client.NS_OWNCLOUD + '}tags',
-		PROPERTY_FAVORITE:	'{' + OC.Files.Client.NS_OWNCLOUD + '}favorite'
-	});
-
-	var TEMPLATE_FAVORITE_ACTION =
-		'<a href="#" ' +
-		'class="action action-favorite {{#isFavorite}}permanent{{/isFavorite}}">' +
-		'<span class="icon {{iconClass}}" />' +
-		'<span class="hidden-visually">{{altText}}</span>' +
-		'</a>';
-
-	/**
-	 * Returns the icon class for the matching state
-	 *
-	 * @param {boolean} state true if starred, false otherwise
-	 * @return {string} icon class for star image
-	 */
-	function getStarIconClass(state) {
-		return state ? 'icon-starred' : 'icon-star';
-	}
-
-	/**
-	 * Render the star icon with the given state
-	 *
-	 * @param {boolean} state true if starred, false otherwise
-	 * @return {Object} jQuery object
-	 */
-	function renderStar(state) {
-		if (!this._template) {
-			this._template = Handlebars.compile(TEMPLATE_FAVORITE_ACTION);
-		}
-		return this._template({
-			isFavorite: state,
-			altText: state ? t('files', 'Favorited') : t('files', 'Favorite'),
-			iconClass: getStarIconClass(state)
-		});
-	}
-
-	/**
-	 * Toggle star icon on action element
-	 *
-	 * @param {Object} action element
-	 * @param {boolean} state true if starred, false otherwise
-	 */
-	function toggleStar($actionEl, state) {
-		$actionEl.removeClass('icon-star icon-starred').addClass(getStarIconClass(state));
-		$actionEl.toggleClass('permanent', state);
-	}
-
-	OCA.Files = OCA.Files || {};
-
-	/**
-	 * @namespace OCA.Files.TagsPlugin
-	 *
-	 * Extends the file actions and file list to include a favorite action icon
-	 * and addition "data-tags" and "data-favorite" attributes.
-	 */
-	OCA.Files.TagsPlugin = {
-		name: 'Tags',
-
-		allowedLists: [
-			'files',
-			'favorites',
-			'systemtags',
-			'shares.self',
-			'shares.others',
-			'shares.link'
-		],
-
-		_extendFileActions: function(fileActions) {
-			var self = this;
-			// register "star" action
-			fileActions.registerAction({
-				name: 'Favorite',
-				displayName: t('files', 'Favorite'),
-				mime: 'all',
-				permissions: OC.PERMISSION_READ,
-				type: OCA.Files.FileActions.TYPE_INLINE,
-				render: function(actionSpec, isDefault, context) {
-					var $file = context.$file;
-					var isFavorite = $file.data('favorite') === true;
-					var $icon = $(renderStar(isFavorite));
-					$file.find('td:first>.favorite').replaceWith($icon);
-					return $icon;
-				},
-				actionHandler: function(fileName, context) {
-					var $actionEl = context.$file.find('.action-favorite');
-					var $file = context.$file;
-					var fileInfo = context.fileList.files[$file.index()];
-					var dir = context.dir || context.fileList.getCurrentDirectory();
-					var tags = $file.attr('data-tags');
-					if (_.isUndefined(tags)) {
-						tags = '';
-					}
-					tags = tags.split('|');
-					tags = _.without(tags, '');
-					var isFavorite = tags.indexOf(OC.TAG_FAVORITE) >= 0;
-					if (isFavorite) {
-						// remove tag from list
-						tags = _.without(tags, OC.TAG_FAVORITE);
-					} else {
-						tags.push(OC.TAG_FAVORITE);
-					}
-
-					// pre-toggle the star
-					toggleStar($actionEl, !isFavorite);
-
-					context.fileInfoModel.trigger('busy', context.fileInfoModel, true);
-
-					self.applyFileTags(
-						dir + '/' + fileName,
-						tags,
-						$actionEl,
-						isFavorite
-					).then(function(result) {
-						context.fileInfoModel.trigger('busy', context.fileInfoModel, false);
-						// response from server should contain updated tags
-						var newTags = result.tags;
-						if (_.isUndefined(newTags)) {
-							newTags = tags;
-						}
-						context.fileInfoModel.set({
-							'tags': newTags,
-							'favorite': !isFavorite
-						});
-					});
-				}
-			});
-		},
-
-		_extendFileList: function(fileList) {
-			// extend row prototype
-			fileList.$el.addClass('has-favorites');
-			var oldCreateRow = fileList._createRow;
-			fileList._createRow = function(fileData) {
-				var $tr = oldCreateRow.apply(this, arguments);
-				if (fileData.tags) {
-					$tr.attr('data-tags', fileData.tags.join('|'));
-					if (fileData.tags.indexOf(OC.TAG_FAVORITE) >= 0) {
-						$tr.attr('data-favorite', true);
-					}
-				}
-				$tr.find('td:first').prepend('<div class="favorite"></div>');
-				return $tr;
-			};
-			var oldElementToFile = fileList.elementToFile;
-			fileList.elementToFile = function($el) {
-				var fileInfo = oldElementToFile.apply(this, arguments);
-				var tags = $el.attr('data-tags');
-				if (_.isUndefined(tags)) {
-					tags = '';
-				}
-				tags = tags.split('|');
-				tags = _.without(tags, '');
-				fileInfo.tags = tags;
-				return fileInfo;
-			};
-
-			var oldGetWebdavProperties = fileList._getWebdavProperties;
-			fileList._getWebdavProperties = function() {
-				var props = oldGetWebdavProperties.apply(this, arguments);
-				props.push(OC.Files.Client.PROPERTY_TAGS);
-				props.push(OC.Files.Client.PROPERTY_FAVORITE);
-				return props;
-			};
-
-			fileList.filesClient.addFileInfoParser(function(response) {
-				var data = {};
-				var props = response.propStat[0].properties;
-				var tags = props[OC.Files.Client.PROPERTY_TAGS];
-				var favorite = props[OC.Files.Client.PROPERTY_FAVORITE];
-				if (tags && tags.length) {
-					tags = _.chain(tags).filter(function(xmlvalue) {
-						return (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'tag');
-					}).map(function(xmlvalue) {
-						return xmlvalue.textContent || xmlvalue.text;
-					}).value();
-				}
-				if (tags) {
-					data.tags = tags;
-				}
-				if (favorite && parseInt(favorite, 10) !== 0) {
-					data.tags = data.tags || [];
-					data.tags.push(OC.TAG_FAVORITE);
-				}
-				return data;
-			});
-		},
-
-		attach: function(fileList) {
-			if (this.allowedLists.indexOf(fileList.id) < 0) {
-				return;
-			}
-			this._extendFileActions(fileList.fileActions);
-			this._extendFileList(fileList);
-		},
-
-		/**
-		 * Replaces the given files' tags with the specified ones.
-		 *
-		 * @param {String} fileName path to the file or folder to tag
-		 * @param {Array.<String>} tagNames array of tag names
-		 * @param {Object} $actionEl element
-		 * @param {boolean} isFavorite Was the item favorited before
-		 */
-		applyFileTags: function(fileName, tagNames, $actionEl, isFavorite) {
-			var encodedPath = OC.encodePath(fileName);
-			while (encodedPath[0] === '/') {
-				encodedPath = encodedPath.substr(1);
-			}
-			return $.ajax({
-				url: OC.generateUrl('/apps/files/api/v1/files/') + encodedPath,
-				contentType: 'application/json',
-				data: JSON.stringify({
-					tags: tagNames || []
-				}),
-				dataType: 'json',
-				type: 'POST'
-			}).fail(function(response) {
-				var message = '';
-				// show message if it is available
-				if(response.responseJSON && response.responseJSON.message) {
-					message = ': ' + response.responseJSON.message;
-				}
-				OC.Notification.show(t('files', 'An error occurred while trying to update the tags' + message), {type: 'error'});
-				toggleStar($actionEl, isFavorite);
-			});
-		}
-	};
-})(OCA);
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Files.TagsPlugin);
-
-
-/*
- * Copyright (c) 2016 Robin Appelman <robin@icewind.nl>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-
-(function (OCA) {
-
-	OCA.Files = OCA.Files || {};
-
-	/**
-	 * @namespace OCA.Files.GotoPlugin
-	 *
-	 */
-	OCA.Files.GotoPlugin = {
-		name: 'Goto',
-
-		disallowedLists: [
-			'files',
-			'trashbin'
-		],
-
-		attach: function (fileList) {
-			if (this.disallowedLists.indexOf(fileList.id) !== -1) {
-				return;
-			}
-			var fileActions = fileList.fileActions;
-
-			fileActions.registerAction({
-				name: 'Goto',
-				displayName: t('files', 'View in folder'),
-				mime: 'all',
-				permissions: OC.PERMISSION_ALL,
-				iconClass: 'icon-goto nav-icon-extstoragemounts',
-				type: OCA.Files.FileActions.TYPE_DROPDOWN,
-				actionHandler: function (fileName, context) {
-					var fileModel = context.fileInfoModel;
-					OC.Apps.hideAppSidebar($('.detailsView'));
-					OCA.Files.App.setActiveView('files', {silent: true});
-					OCA.Files.App.fileList.changeDirectory(fileModel.get('path'), true, true).then(function() {
-						OCA.Files.App.fileList.scrollTo(fileModel.get('name'));
-					});
-				},
-				render: function (actionSpec, isDefault, context) {
-					return fileActions._defaultRenderAction.call(fileActions, actionSpec, isDefault, context)
-						.removeClass('permanent');
-				}
-			});
-		}
-	};
-})(OCA);
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Files.GotoPlugin);
-
-
-
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OCA) {
-	/**
-	 * @namespace OCA.Files.FavoritesPlugin
-	 *
-	 * Registers the favorites file list from the files app sidebar.
-	 */
-	OCA.Files.FavoritesPlugin = {
-		name: 'Favorites',
-
-		/**
-		 * @type OCA.Files.FavoritesFileList
-		 */
-		favoritesFileList: null,
-
-		attach: function() {
-			var self = this;
-			$('#app-content-favorites').on('show.plugin-favorites', function(e) {
-				self.showFileList($(e.target));
-			});
-			$('#app-content-favorites').on('hide.plugin-favorites', function() {
-				self.hideFileList();
-			});
-		},
-
-		detach: function() {
-			if (this.favoritesFileList) {
-				this.favoritesFileList.destroy();
-				OCA.Files.fileActions.off('setDefault.plugin-favorites', this._onActionsUpdated);
-				OCA.Files.fileActions.off('registerAction.plugin-favorites', this._onActionsUpdated);
-				$('#app-content-favorites').off('.plugin-favorites');
-				this.favoritesFileList = null;
-			}
-		},
-
-		showFileList: function($el) {
-			if (!this.favoritesFileList) {
-				this.favoritesFileList = this._createFavoritesFileList($el);
-			}
-			return this.favoritesFileList;
-		},
-
-		hideFileList: function() {
-			if (this.favoritesFileList) {
-				this.favoritesFileList.$fileList.empty();
-			}
-		},
-
-		/**
-		 * Creates the favorites file list.
-		 *
-		 * @param $el container for the file list
-		 * @return {OCA.Files.FavoritesFileList} file list
-		 */
-		_createFavoritesFileList: function($el) {
-			var fileActions = this._createFileActions();
-			// register favorite list for sidebar section
-			return new OCA.Files.FavoritesFileList(
-				$el, {
-					fileActions: fileActions,
-					scrollContainer: $('#app-content')
-				}
-			);
-		},
-
-		_createFileActions: function() {
-			// inherit file actions from the files app
-			var fileActions = new OCA.Files.FileActions();
-			// note: not merging the legacy actions because legacy apps are not
-			// compatible with the sharing overview and need to be adapted first
-			fileActions.registerDefaultActions();
-			fileActions.merge(OCA.Files.fileActions);
-
-			if (!this._globalActionsInitialized) {
-				// in case actions are registered later
-				this._onActionsUpdated = _.bind(this._onActionsUpdated, this);
-				OCA.Files.fileActions.on('setDefault.plugin-favorites', this._onActionsUpdated);
-				OCA.Files.fileActions.on('registerAction.plugin-favorites', this._onActionsUpdated);
-				this._globalActionsInitialized = true;
-			}
-
-			// when the user clicks on a folder, redirect to the corresponding
-			// folder in the files app instead of opening it directly
-			fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
-				OCA.Files.App.setActiveView('files', {silent: true});
-				OCA.Files.App.fileList.changeDirectory(OC.joinPaths(context.$file.attr('data-path'), filename), true, true);
-			});
-			fileActions.setDefault('dir', 'Open');
-			return fileActions;
-		},
-
-		_onActionsUpdated: function(ev) {
-			if (ev.action) {
-				this.favoritesFileList.fileActions.registerAction(ev.action);
-			} else if (ev.defaultAction) {
-				this.favoritesFileList.fileActions.setDefault(
-					ev.defaultAction.mime,
-					ev.defaultAction.name
-				);
-			}
-		}
-	};
-
-})(OCA);
-
-OC.Plugins.register('OCA.Files.App', OCA.Files.FavoritesPlugin);
-
-
-
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function (OCA) {
-	/**
-	 * @namespace OCA.Files.RecentPlugin
-	 *
-	 * Registers the recent file list from the files app sidebar.
-	 */
-	OCA.Files.RecentPlugin = {
-		name: 'Recent',
-
-		/**
-		 * @type OCA.Files.RecentFileList
-		 */
-		recentFileList: null,
-
-		attach: function () {
-			var self = this;
-			$('#app-content-recent').on('show.plugin-recent', function (e) {
-				self.showFileList($(e.target));
-			});
-			$('#app-content-recent').on('hide.plugin-recent', function () {
-				self.hideFileList();
-			});
-		},
-
-		detach: function () {
-			if (this.recentFileList) {
-				this.recentFileList.destroy();
-				OCA.Files.fileActions.off('setDefault.plugin-recent', this._onActionsUpdated);
-				OCA.Files.fileActions.off('registerAction.plugin-recent', this._onActionsUpdated);
-				$('#app-content-recent').off('.plugin-recent');
-				this.recentFileList = null;
-			}
-		},
-
-		showFileList: function ($el) {
-			if (!this.recentFileList) {
-				this.recentFileList = this._createRecentFileList($el);
-			}
-			return this.recentFileList;
-		},
-
-		hideFileList: function () {
-			if (this.recentFileList) {
-				this.recentFileList.$fileList.empty();
-			}
-		},
-
-		/**
-		 * Creates the recent file list.
-		 *
-		 * @param $el container for the file list
-		 * @return {OCA.Files.RecentFileList} file list
-		 */
-		_createRecentFileList: function ($el) {
-			var fileActions = this._createFileActions();
-			// register recent list for sidebar section
-			return new OCA.Files.RecentFileList(
-				$el, {
-					fileActions: fileActions,
-					scrollContainer: $('#app-content')
-				}
-			);
-		},
-
-		_createFileActions: function () {
-			// inherit file actions from the files app
-			var fileActions = new OCA.Files.FileActions();
-			// note: not merging the legacy actions because legacy apps are not
-			// compatible with the sharing overview and need to be adapted first
-			fileActions.registerDefaultActions();
-			fileActions.merge(OCA.Files.fileActions);
-
-			if (!this._globalActionsInitialized) {
-				// in case actions are registered later
-				this._onActionsUpdated = _.bind(this._onActionsUpdated, this);
-				OCA.Files.fileActions.on('setDefault.plugin-recent', this._onActionsUpdated);
-				OCA.Files.fileActions.on('registerAction.plugin-recent', this._onActionsUpdated);
-				this._globalActionsInitialized = true;
-			}
-
-			// when the user clicks on a folder, redirect to the corresponding
-			// folder in the files app instead of opening it directly
-			fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
-				OCA.Files.App.setActiveView('files', {silent: true});
-				var path = OC.joinPaths(context.$file.attr('data-path'), filename);
-				OCA.Files.App.fileList.changeDirectory(path, true, true);
-			});
-			fileActions.setDefault('dir', 'Open');
-			return fileActions;
-		},
-
-		_onActionsUpdated: function (ev) {
-			if (ev.action) {
-				this.recentFileList.fileActions.registerAction(ev.action);
-			} else if (ev.defaultAction) {
-				this.recentFileList.fileActions.setDefault(
-					ev.defaultAction.mime,
-					ev.defaultAction.name
-				);
-			}
-		}
-	};
-
-})(OCA);
-
-OC.Plugins.register('OCA.Files.App', OCA.Files.RecentPlugin);
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	/**
-	 * @class OCA.Files.DetailFileInfoView
-	 * @classdesc
-	 *
-	 * Displays a block of details about the file info.
-	 *
-	 */
-	var DetailFileInfoView = OC.Backbone.View.extend({
-		tagName: 'div',
-		className: 'detailFileInfoView',
-
-		_template: null,
-
-		/**
-		 * returns the jQuery object for HTML output
-		 *
-		 * @returns {jQuery}
-		 */
-		get$: function() {
-			return this.$el;
-		},
-
-		/**
-		 * Sets the file info to be displayed in the view
-		 *
-		 * @param {OCA.Files.FileInfo} fileInfo file info to set
-		 */
-		setFileInfo: function(fileInfo) {
-			this.model = fileInfo;
-			this.render();
-		},
-
-		/**
-		 * Returns the file info.
-		 *
-		 * @return {OCA.Files.FileInfo} file info
-		 */
-		getFileInfo: function() {
-			return this.model;
-		}
-	});
-
-	OCA.Files.DetailFileInfoView = DetailFileInfoView;
-})();
-
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function () {
-	SidebarPreviewManager = function (fileList) {
-		this._fileList = fileList;
-		this._previewHandlers = {};
-		OC.Plugins.attach('OCA.Files.SidebarPreviewManager', this);
-	};
-
-	SidebarPreviewManager.prototype = {
-		addPreviewHandler: function (mime, handler) {
-			this._previewHandlers[mime] = handler;
-		},
-
-		getMimeTypePreviewHandler: function(mime) {
-			var mimePart = mime.split('/').shift();
-			if (this._previewHandlers[mime]) {
-				return this._previewHandlers[mime];
-			} else if (this._previewHandlers[mimePart]) {
-				return this._previewHandlers[mimePart];
-			} else {
-				return null;
-			}
-		},
-
-		getPreviewHandler: function (mime) {
-			var mimetypeHandler = this.getMimeTypePreviewHandler(mime);
-			if (mimetypeHandler) {
-				return mimetypeHandler;
-			} else {
-				return this.fallbackPreview.bind(this);
-			}
-		},
-
-		loadPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
-			if (model.get('hasPreview') === false && this.getMimeTypePreviewHandler(model.get('mimetype')) === null) {
-				var mimeIcon = OC.MimeType.getIconUrl(model.get('mimetype'));
-				$thumbnailDiv.removeClass('icon-loading icon-32');
-				$thumbnailContainer.removeClass('image'); //fall back to regular view
-				$thumbnailDiv.css({
-					'background-image': 'url("' + mimeIcon + '")'
-				});
-			} else {
-				var handler = this.getPreviewHandler(model.get('mimetype'));
-				var fallback = this.fallbackPreview.bind(this, model, $thumbnailDiv, $thumbnailContainer);
-				handler(model, $thumbnailDiv, $thumbnailContainer, fallback);
-			}
-		},
-
-		// previews for images and mimetype icons
-		fallbackPreview: function (model, $thumbnailDiv, $thumbnailContainer) {
-			var isImage = model.isImage();
-			var maxImageWidth = $thumbnailContainer.parent().width() + 50;  // 50px for negative margins
-			var maxImageHeight = maxImageWidth / (16 / 9);
-			var smallPreviewSize = 75;
-
-			var isLandscape = function (img) {
-				return img.width > (img.height * 1.2);
-			};
-
-			var isSmall = function (img) {
-				return (img.width * 1.1) < (maxImageWidth * window.devicePixelRatio);
-			};
-
-			var getTargetHeight = function (img) {
-				if (isImage) {
-					var targetHeight = img.height / window.devicePixelRatio;
-					if (targetHeight <= smallPreviewSize) {
-						targetHeight = smallPreviewSize;
-					}
-					return targetHeight;
-				} else {
-					return smallPreviewSize;
-				}
-			};
-
-			var getTargetRatio = function (img) {
-				var ratio = img.width / img.height;
-				if (ratio > 16 / 9) {
-					return ratio;
-				} else {
-					return 16 / 9;
-				}
-			};
-
-			this._fileList.lazyLoadPreview({
-				path: model.getFullPath(),
-				mime: model.get('mimetype'),
-				etag: model.get('etag'),
-				y: isImage ? maxImageHeight : smallPreviewSize,
-				x: isImage ? maxImageWidth : smallPreviewSize,
-				a: isImage ? 1 : null,
-				mode: isImage ? 'cover' : null,
-				callback: function (previewUrl, img) {
-					$thumbnailDiv.previewImg = previewUrl;
-
-					// as long as we only have the mimetype icon, we only save it in case there is no preview
-					if (!img) {
-						return;
-					}
-					$thumbnailDiv.removeClass('icon-loading icon-32');
-					var targetHeight = getTargetHeight(img);
-					if (isImage && targetHeight > smallPreviewSize) {
-						$thumbnailContainer.addClass((isLandscape(img) && !isSmall(img)) ? 'landscape' : 'portrait');
-						$thumbnailContainer.addClass('large');
-					}
-
-					// only set background when we have an actual preview
-					// when we don't have a preview we show the mime icon in the error handler
-					$thumbnailDiv.css({
-						'background-image': 'url("' + previewUrl + '")',
-						height: (targetHeight > smallPreviewSize) ? 'auto' : targetHeight,
-						'max-height': isSmall(img) ? targetHeight : null
-					});
-
-					var targetRatio = getTargetRatio(img);
-					$thumbnailDiv.find('.stretcher').css({
-						'padding-bottom': (100 / targetRatio) + '%'
-					});
-				},
-				error: function () {
-					$thumbnailDiv.removeClass('icon-loading icon-32');
-					$thumbnailContainer.removeClass('image'); //fall back to regular view
-					$thumbnailDiv.css({
-						'background-image': 'url("' + $thumbnailDiv.previewImg + '")'
-					});
-				}
-			});
-		}
-	};
-
-	OCA.Files.SidebarPreviewManager = SidebarPreviewManager;
-})();
-
-
-/*
- * Copyright (c) 2016
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function () {
-	var SidebarPreview = function () {
-	};
-
-	SidebarPreview.prototype = {
-		attach: function (manager) {
-			manager.addPreviewHandler('text', this.handlePreview.bind(this));
-		},
-
-		handlePreview: function (model, $thumbnailDiv, $thumbnailContainer, fallback) {
-			var previewWidth = $thumbnailContainer.parent().width() + 50;  // 50px for negative margins
-			var previewHeight = previewWidth / (16 / 9);
-
-			this.getFileContent(model.getFullPath()).then(function (content) {
-				$thumbnailDiv.removeClass('icon-loading icon-32');
-				$thumbnailContainer.addClass('large');
-				$thumbnailContainer.addClass('text');
-				var $textPreview = $('<pre/>').text(content);
-				$thumbnailDiv.children('.stretcher').remove();
-				$thumbnailDiv.append($textPreview);
-				$thumbnailContainer.css("max-height", previewHeight);
-			}, function () {
-				fallback();
-			});
-		},
-
-		getFileContent: function (path) {
-			return $.get(OC.linkToRemoteBase('files' + path));
-		}
-	};
-
-	OC.Plugins.register('OCA.Files.SidebarPreviewManager', new SidebarPreview());
-})();
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	/**
-	 * @class OCA.Files.DetailTabView
-	 * @classdesc
-	 *
-	 * Base class for tab views to display file information.
-	 *
-	 */
-	var DetailTabView = OC.Backbone.View.extend({
-		tag: 'div',
-
-		className: 'tab',
-
-		/**
-		 * Tab label
-		 */
-		_label: null,
-
-		_template: null,
-
-		initialize: function(options) {
-			options = options || {};
-			if (!this.id) {
-				this.id = 'detailTabView' + DetailTabView._TAB_COUNT;
-				DetailTabView._TAB_COUNT++;
-			}
-			if (options.order) {
-				this.order = options.order || 0;
-			}
-		},
-
-		/**
-		 * Returns the tab label
-		 *
-		 * @return {String} label
-		 */
-		getLabel: function() {
-			return 'Tab ' + this.id;
-		},
-
-		/**
-		 * returns the jQuery object for HTML output
-		 *
-		 * @returns {jQuery}
-		 */
-		get$: function() {
-			return this.$el;
-		},
-
-		/**
-		 * Renders this details view
-		 *
-		 * @abstract
-		 */
-		render: function() {
-			// to be implemented in subclass
-			// FIXME: code is only for testing
-			this.$el.html('<div>Hello ' + this.id + '</div>');
-		},
-
-		/**
-		 * Sets the file info to be displayed in the view
-		 *
-		 * @param {OCA.Files.FileInfoModel} fileInfo file info to set
-		 */
-		setFileInfo: function(fileInfo) {
-			if (this.model !== fileInfo) {
-				this.model = fileInfo;
-				this.render();
-			}
-		},
-
-		/**
-		 * Returns the file info.
-		 *
-		 * @return {OCA.Files.FileInfoModel} file info
-		 */
-		getFileInfo: function() {
-			return this.model;
-		},
-
-		/**
-		 * Load the next page of results
-		 */
-		nextPage: function() {
-			// load the next page, if applicable
-		},
-
-		/**
-		 * Returns whether the current tab is able to display
-		 * the given file info, for example based on mime type.
-		 *
-		 * @param {OCA.Files.FileInfoModel} fileInfo file info model
-		 * @return {bool} whether to display this tab
-		 */
-		canDisplay: function(fileInfo) {
-			return true;
-		}
-	});
-	DetailTabView._TAB_COUNT = 0;
-
-	OCA.Files = OCA.Files || {};
-
-	OCA.Files.DetailTabView = DetailTabView;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	var TEMPLATE =
-		'<div class="thumbnailContainer"><a href="#" class="thumbnail action-default"><div class="stretcher"/></a></div>' +
-		'<div class="file-details-container">' +
-		'<div class="fileName">' +
-			'<h3 title="{{name}}" class="ellipsis">{{name}}</h3>' +
-			'<a class="permalink" href="{{permalink}}" title="{{permalinkTitle}}">' +
-				'<span class="icon icon-clippy"></span>' +
-				'<span class="hidden-visually">{{permalinkTitle}}</span>' +
-			'</a>' +
-		'</div>' +
-		'	<div class="file-details ellipsis">' +
-		'		<a href="#" class="action action-favorite favorite permanent">' +
-		'			<span class="icon {{starClass}}" title="{{starAltText}}"></span>' +
-		'		</a>' +
-		'		{{#if hasSize}}<span class="size" title="{{altSize}}">{{size}}</span>, {{/if}}<span class="date live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</span>' +
-		'	</div>' +
-		'</div>' +
-		'<div class="hidden permalink-field">' +
-			'<input type="text" value="{{permalink}}" placeholder="{{permalinkTitle}}" readonly="readonly"/>' +
-		'</div>';
-
-	/**
-	 * @class OCA.Files.MainFileInfoDetailView
-	 * @classdesc
-	 *
-	 * Displays main details about a file
-	 *
-	 */
-	var MainFileInfoDetailView = OCA.Files.DetailFileInfoView.extend(
-		/** @lends OCA.Files.MainFileInfoDetailView.prototype */ {
-
-		className: 'mainFileInfoView',
-
-		/**
-		 * Associated file list instance, for file actions
-		 *
-		 * @type {OCA.Files.FileList}
-		 */
-		_fileList: null,
-
-		/**
-		 * File actions
-		 *
-		 * @type {OCA.Files.FileActions}
-		 */
-		_fileActions: null,
-
-		/**
-		 * @type {OCA.Files.SidebarPreviewManager}
-		 */
-		_previewManager: null,
-
-		events: {
-			'click a.action-favorite': '_onClickFavorite',
-			'click a.action-default': '_onClickDefaultAction',
-			'click a.permalink': '_onClickPermalink',
-			'focus .permalink-field>input': '_onFocusPermalink'
-		},
-
-		template: function(data) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			return this._template(data);
-		},
-
-		initialize: function(options) {
-			options = options || {};
-			this._fileList = options.fileList;
-			this._fileActions = options.fileActions;
-			if (!this._fileList) {
-				throw 'Missing required parameter "fileList"';
-			}
-			if (!this._fileActions) {
-				throw 'Missing required parameter "fileActions"';
-			}
-			this._previewManager = new OCA.Files.SidebarPreviewManager(this._fileList);
-		},
-
-		_onClickPermalink: function() {
-			var $row = this.$('.permalink-field');
-			$row.toggleClass('hidden');
-			if (!$row.hasClass('hidden')) {
-				$row.find('>input').focus();
-			}
-			// cancel click, user must right-click + copy or middle click
-			return false;
-		},
-
-		_onFocusPermalink: function() {
-			this.$('.permalink-field>input').select();
-		},
-
-		_onClickFavorite: function(event) {
-			event.preventDefault();
-			this._fileActions.triggerAction('Favorite', this.model, this._fileList);
-		},
-
-		_onClickDefaultAction: function(event) {
-			event.preventDefault();
-			this._fileActions.triggerAction(null, this.model, this._fileList);
-		},
-
-		_onModelChanged: function() {
-			// simply re-render
-			this.render();
-		},
-
-		_makePermalink: function(fileId) {
-			var baseUrl = OC.getProtocol() + '://' + OC.getHost();
-			return baseUrl + OC.generateUrl('/f/{fileId}', {fileId: fileId});
-		},
-
-		setFileInfo: function(fileInfo) {
-			if (this.model) {
-				this.model.off('change', this._onModelChanged, this);
-			}
-			this.model = fileInfo;
-			if (this.model) {
-				this.model.on('change', this._onModelChanged, this);
-			}
-
-			if (this.model) {
-				var properties = [];
-				if( !this.model.has('size') ) {
-					properties.push(OC.Files.Client.PROPERTY_SIZE);
-					properties.push(OC.Files.Client.PROPERTY_GETCONTENTLENGTH);
-				}
-
-				if( properties.length > 0){
-					this.model.reloadProperties(properties);
-				}
-			}
-
-			this.render();
-		},
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			this.trigger('pre-render');
-
-			if (this.model) {
-				var isFavorite = (this.model.get('tags') || []).indexOf(OC.TAG_FAVORITE) >= 0;
-				this.$el.html(this.template({
-					type: this.model.isImage()? 'image': '',
-					nameLabel: t('files', 'Name'),
-					name: this.model.get('displayName') || this.model.get('name'),
-					pathLabel: t('files', 'Path'),
-					path: this.model.get('path'),
-					hasSize: this.model.has('size'),
-					sizeLabel: t('files', 'Size'),
-					size: OC.Util.humanFileSize(this.model.get('size'), true),
-					altSize: n('files', '%n byte', '%n bytes', this.model.get('size')),
-					dateLabel: t('files', 'Modified'),
-					altDate: OC.Util.formatDate(this.model.get('mtime')),
-					timestamp: this.model.get('mtime'),
-					date: OC.Util.relativeModifiedDate(this.model.get('mtime')),
-					starAltText: isFavorite ? t('files', 'Favorited') : t('files', 'Favorite'),
-					starClass: isFavorite ? 'icon-starred' : 'icon-star',
-					permalink: this._makePermalink(this.model.get('id')),
-					permalinkTitle: t('files', 'Copy direct link (only works for users who have access to this file/folder)')
-				}));
-
-				// TODO: we really need OC.Previews
-				var $iconDiv = this.$el.find('.thumbnail');
-				var $container = this.$el.find('.thumbnailContainer');
-				if (!this.model.isDirectory()) {
-					$iconDiv.addClass('icon-loading icon-32');
-					this._previewManager.loadPreview(this.model, $iconDiv, $container);
-				} else {
-					var iconUrl = this.model.get('icon') || OC.MimeType.getIconUrl('dir');
-					$iconDiv.css('background-image', 'url("' + iconUrl + '")');
-					OC.Util.scaleFixForIE8($iconDiv);
-				}
-				this.$el.find('[title]').tooltip({placement: 'bottom'});
-			} else {
-				this.$el.empty();
-			}
-			this.delegateEvents();
-
-			this.trigger('post-render');
-		}
-	});
-
-	OCA.Files.MainFileInfoDetailView = MainFileInfoDetailView;
-})();
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	var TEMPLATE =
-		'	<div class="detailFileInfoContainer">' +
-		'	</div>' +
-		'	{{#if tabHeaders}}' +
-		'	<ul class="tabHeaders">' +
-		'		{{#each tabHeaders}}' +
-		'		<li class="tabHeader" data-tabid="{{tabId}}" data-tabindex="{{tabIndex}}">' +
-		'			<a href="#">{{label}}</a>' +
-		'		</li>' +
-		'		{{/each}}' +
-		'	</ul>' +
-		'	{{/if}}' +
-		'	<div class="tabsContainer">' +
-		'	</div>' +
-		'	<a class="close icon-close" href="#" alt="{{closeLabel}}"></a>';
-
-	/**
-	 * @class OCA.Files.DetailsView
-	 * @classdesc
-	 *
-	 * The details view show details about a selected file.
-	 *
-	 */
-	var DetailsView = OC.Backbone.View.extend({
-		id: 'app-sidebar',
-		tabName: 'div',
-		className: 'detailsView scroll-container',
-
-		_template: null,
-
-		/**
-		 * List of detail tab views
-		 *
-		 * @type Array<OCA.Files.DetailTabView>
-		 */
-		_tabViews: [],
-
-		/**
-		 * List of detail file info views
-		 *
-		 * @type Array<OCA.Files.DetailFileInfoView>
-		 */
-		_detailFileInfoViews: [],
-
-		/**
-		 * Id of the currently selected tab
-		 *
-		 * @type string
-		 */
-		_currentTabId: null,
-
-		/**
-		 * Dirty flag, whether the view needs to be rerendered
-		 */
-		_dirty: false,
-
-		events: {
-			'click a.close': '_onClose',
-			'click .tabHeaders .tabHeader': '_onClickTab'
-		},
-
-		/**
-		 * Initialize the details view
-		 */
-		initialize: function() {
-			this._tabViews = [];
-			this._detailFileInfoViews = [];
-
-			this._dirty = true;
-
-			// uncomment to add some dummy tabs for testing
-			//this._addTestTabs();
-		},
-
-		_onClose: function(event) {
-			OC.Apps.hideAppSidebar(this.$el);
-			event.preventDefault();
-		},
-
-		_onClickTab: function(e) {
-			var $target = $(e.target);
-			e.preventDefault();
-			if (!$target.hasClass('tabHeader')) {
-				$target = $target.closest('.tabHeader');
-			}
-			var tabId = $target.attr('data-tabid');
-			if (_.isUndefined(tabId)) {
-				return;
-			}
-
-			this.selectTab(tabId);
-		},
-
-		_addTestTabs: function() {
-			for (var j = 0; j < 2; j++) {
-				var testView = new OCA.Files.DetailTabView({id: 'testtab' + j});
-				testView.index = j;
-				testView.getLabel = function() { return 'Test tab ' + this.index; };
-				testView.render = function() {
-					this.$el.empty();
-					for (var i = 0; i < 100; i++) {
-						this.$el.append('<div>Test tab ' + this.index + ' row ' + i + '</div>');
-					}
-				};
-				this._tabViews.push(testView);
-			}
-		},
-
-		template: function(vars) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			return this._template(vars);
-		},
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			var templateVars = {
-				closeLabel: t('files', 'Close')
-			};
-
-			this._tabViews = this._tabViews.sort(function(tabA, tabB) {
-				var orderA = tabA.order || 0;
-				var orderB = tabB.order || 0;
-				if (orderA === orderB) {
-					return OC.Util.naturalSortCompare(tabA.getLabel(), tabB.getLabel());
-				}
-				return orderA - orderB;
-			});
-
-			templateVars.tabHeaders = _.map(this._tabViews, function(tabView, i) {
-				return {
-					tabId: tabView.id,
-					tabIndex: i,
-					label: tabView.getLabel()
-				};
-			});
-
-			this.$el.html(this.template(templateVars));
-
-			var $detailsContainer = this.$el.find('.detailFileInfoContainer');
-
-			// render details
-			_.each(this._detailFileInfoViews, function(detailView) {
-				$detailsContainer.append(detailView.get$());
-			});
-
-			if (!this._currentTabId && this._tabViews.length > 0) {
-				this._currentTabId = this._tabViews[0].id;
-			}
-
-			this.selectTab(this._currentTabId);
-
-			this._updateTabVisibilities();
-
-			this._dirty = false;
-		},
-
-		/**
-		 * Selects the given tab by id
-		 *
-		 * @param {string} tabId tab id
-		 */
-		selectTab: function(tabId) {
-			if (!tabId) {
-				return;
-			}
-
-			var tabView = _.find(this._tabViews, function(tab) {
-				return tab.id === tabId;
-			});
-
-			if (!tabView) {
-				console.warn('Details view tab with id "' + tabId + '" not found');
-				return;
-			}
-
-			this._currentTabId = tabId;
-
-			var $tabsContainer = this.$el.find('.tabsContainer');
-			var $tabEl = $tabsContainer.find('#' + tabId);
-
-			// hide other tabs
-			$tabsContainer.find('.tab').addClass('hidden');
-
-			// tab already rendered ?
-			if (!$tabEl.length) {
-				// render tab
-				$tabsContainer.append(tabView.$el);
-				$tabEl = tabView.$el;
-			}
-
-			// this should trigger tab rendering
-			tabView.setFileInfo(this.model);
-
-			$tabEl.removeClass('hidden');
-
-			// update tab headers
-			var $tabHeaders = this.$el.find('.tabHeaders li');
-			$tabHeaders.removeClass('selected');
-			$tabHeaders.filterAttr('data-tabid', tabView.id).addClass('selected');
-		},
-
-		/**
-		 * Sets the file info to be displayed in the view
-		 *
-		 * @param {OCA.Files.FileInfoModel} fileInfo file info to set
-		 */
-		setFileInfo: function(fileInfo) {
-			this.model = fileInfo;
-
-			if (this._dirty) {
-				this.render();
-			} else {
-				this._updateTabVisibilities();
-			}
-
-			if (this._currentTabId) {
-				// only update current tab, others will be updated on-demand
-				var tabId = this._currentTabId;
-				var tabView = _.find(this._tabViews, function(tab) {
-					return tab.id === tabId;
-				});
-				tabView.setFileInfo(fileInfo);
-			}
-
-			_.each(this._detailFileInfoViews, function(detailView) {
-				detailView.setFileInfo(fileInfo);
-			});
-		},
-
-		/**
-		 * Update tab headers based on the current model
-		 */
-		_updateTabVisibilities: function() {
-			// update tab header visibilities
-			var self = this;
-			var deselect = false;
-			var countVisible = 0;
-			var $tabHeaders = this.$el.find('.tabHeaders li');
-			_.each(this._tabViews, function(tabView) {
-				var isVisible = tabView.canDisplay(self.model);
-				if (isVisible) {
-					countVisible += 1;
-				}
-				if (!isVisible && self._currentTabId === tabView.id) {
-					deselect = true;
-				}
-				$tabHeaders.filterAttr('data-tabid', tabView.id).toggleClass('hidden', !isVisible);
-			});
-
-			// hide the whole container if there is only one tab
-			this.$el.find('.tabHeaders').toggleClass('hidden', countVisible <= 1);
-
-			if (deselect) {
-				// select the first visible tab instead
-				var visibleTabId = this.$el.find('.tabHeader:not(.hidden):first').attr('data-tabid');
-				this.selectTab(visibleTabId);
-			}
-
-		},
-
-		/**
-		 * Returns the file info.
-		 *
-		 * @return {OCA.Files.FileInfoModel} file info
-		 */
-		getFileInfo: function() {
-			return this.model;
-		},
-
-		/**
-		 * Adds a tab in the tab view
-		 *
-		 * @param {OCA.Files.DetailTabView} tab view
-		 */
-		addTabView: function(tabView) {
-			this._tabViews.push(tabView);
-			this._dirty = true;
-		},
-
-		/**
-		 * Adds a detail view for file info.
-		 *
-		 * @param {OCA.Files.DetailFileInfoView} detail view
-		 */
-		addDetailView: function(detailView) {
-			this._detailFileInfoViews.push(detailView);
-			this._dirty = true;
-		},
-
-		/**
-		 * Returns an array with the added DetailFileInfoViews.
-		 *
-		 * @return Array<OCA.Files.DetailFileInfoView> an array with the added
-		 *         DetailFileInfoViews.
-		 */
-		getDetailViews: function() {
-			return [].concat(this._detailFileInfoViews);
-		}
-	});
-
-	OCA.Files.DetailsView = DetailsView;
-})();
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	var TEMPLATE_FILE_ACTION_TRIGGER =
-		'<a class="action action-{{nameLowerCase}}" href="#" data-action="{{name}}">' +
-		'{{#if icon}}' +
-			'<img class="svg" alt="{{altText}}" src="{{icon}}" />' +
-		'{{else}}' +
-			'{{#if iconClass}}<span class="icon {{iconClass}}" />{{/if}}' +
-			'{{#unless hasDisplayName}}<span class="hidden-visually">{{altText}}</span>{{/unless}}' +
-		'{{/if}}' +
-		'{{#if displayName}}<span> {{displayName}}</span>{{/if}}' +
-		'</a>';
-
-	/**
-	 * Construct a new FileActions instance
-	 * @constructs FileActions
-	 * @memberof OCA.Files
-	 */
-	var FileActions = function() {
-		this.initialize();
-	};
-	FileActions.TYPE_DROPDOWN = 0;
-	FileActions.TYPE_INLINE = 1;
-	FileActions.prototype = {
-		/** @lends FileActions.prototype */
-		actions: {},
-		defaults: {},
-		icons: {},
-
-		/**
-		 * @deprecated
-		 */
-		currentFile: null,
-
-		/**
-		 * Dummy jquery element, for events
-		 */
-		$el: null,
-
-		/**
-		 * List of handlers to be notified whenever a register() or
-		 * setDefault() was called.
-		 *
-		 * @member {Function[]}
-		 */
-		_updateListeners: {},
-
-		_fileActionTriggerTemplate: null,
-
-		/**
-		 * @private
-		 */
-		initialize: function() {
-			this.clear();
-			// abusing jquery for events until we get a real event lib
-			this.$el = $('<div class="dummy-fileactions hidden"></div>');
-			$('body').append(this.$el);
-
-			this._showMenuClosure = _.bind(this._showMenu, this);
-		},
-
-		/**
-		 * Adds an event handler
-		 *
-		 * @param {String} eventName event name
-		 * @param {Function} callback
-		 */
-		on: function(eventName, callback) {
-			this.$el.on(eventName, callback);
-		},
-
-		/**
-		 * Removes an event handler
-		 *
-		 * @param {String} eventName event name
-		 * @param Function callback
-		 */
-		off: function(eventName, callback) {
-			this.$el.off(eventName, callback);
-		},
-
-		/**
-		 * Notifies the event handlers
-		 *
-		 * @param {String} eventName event name
-		 * @param {Object} data data
-		 */
-		_notifyUpdateListeners: function(eventName, data) {
-			this.$el.trigger(new $.Event(eventName, data));
-		},
-
-		/**
-		 * Merges the actions from the given fileActions into
-		 * this instance.
-		 *
-		 * @param {OCA.Files.FileActions} fileActions instance of OCA.Files.FileActions
-		 */
-		merge: function(fileActions) {
-			var self = this;
-			// merge first level to avoid unintended overwriting
-			_.each(fileActions.actions, function(sourceMimeData, mime) {
-				var targetMimeData = self.actions[mime];
-				if (!targetMimeData) {
-					targetMimeData = {};
-				}
-				self.actions[mime] = _.extend(targetMimeData, sourceMimeData);
-			});
-
-			this.defaults = _.extend(this.defaults, fileActions.defaults);
-			this.icons = _.extend(this.icons, fileActions.icons);
-		},
-		/**
-		 * @deprecated use #registerAction() instead
-		 */
-		register: function(mime, name, permissions, icon, action, displayName) {
-			return this.registerAction({
-				name: name,
-				mime: mime,
-				permissions: permissions,
-				icon: icon,
-				actionHandler: action,
-				displayName: displayName || name
-			});
-		},
-
-		/**
-		 * Register action
-		 *
-		 * @param {OCA.Files.FileAction} action object
-		 */
-		registerAction: function (action) {
-			var mime = action.mime;
-			var name = action.name;
-			var actionSpec = {
-				action: action.actionHandler,
-				name: name,
-				displayName: action.displayName,
-				mime: mime,
-				order: action.order || 0,
-				icon: action.icon,
-				iconClass: action.iconClass,
-				permissions: action.permissions,
-				type: action.type || FileActions.TYPE_DROPDOWN,
-				altText: action.altText || ''
-			};
-			if (_.isUndefined(action.displayName)) {
-				actionSpec.displayName = t('files', name);
-			}
-			if (_.isFunction(action.render)) {
-				actionSpec.render = action.render;
-			}
-			if (!this.actions[mime]) {
-				this.actions[mime] = {};
-			}
-			this.actions[mime][name] = actionSpec;
-			this.icons[name] = action.icon;
-			this._notifyUpdateListeners('registerAction', {action: action});
-		},
-		/**
-		 * Clears all registered file actions.
-		 */
-		clear: function() {
-			this.actions = {};
-			this.defaults = {};
-			this.icons = {};
-			this.currentFile = null;
-			this._updateListeners = [];
-		},
-		/**
-		 * Sets the default action for a given mime type.
-		 *
-		 * @param {String} mime mime type
-		 * @param {String} name action name
-		 */
-		setDefault: function (mime, name) {
-			this.defaults[mime] = name;
-			this._notifyUpdateListeners('setDefault', {defaultAction: {mime: mime, name: name}});
-		},
-
-		/**
-		 * Returns a map of file actions handlers matching the given conditions
-		 *
-		 * @param {string} mime mime type
-		 * @param {string} type "dir" or "file"
-		 * @param {int} permissions permissions
-		 *
-		 * @return {Object.<string,OCA.Files.FileActions~actionHandler>} map of action name to action spec
-		 */
-		get: function (mime, type, permissions) {
-			var actions = this.getActions(mime, type, permissions);
-			var filteredActions = {};
-			$.each(actions, function (name, action) {
-				filteredActions[name] = action.action;
-			});
-			return filteredActions;
-		},
-
-		/**
-		 * Returns an array of file actions matching the given conditions
-		 *
-		 * @param {string} mime mime type
-		 * @param {string} type "dir" or "file"
-		 * @param {int} permissions permissions
-		 *
-		 * @return {Array.<OCA.Files.FileAction>} array of action specs
-		 */
-		getActions: function (mime, type, permissions) {
-			var actions = {};
-			if (this.actions.all) {
-				actions = $.extend(actions, this.actions.all);
-			}
-			if (type) {//type is 'dir' or 'file'
-				if (this.actions[type]) {
-					actions = $.extend(actions, this.actions[type]);
-				}
-			}
-			if (mime) {
-				var mimePart = mime.substr(0, mime.indexOf('/'));
-				if (this.actions[mimePart]) {
-					actions = $.extend(actions, this.actions[mimePart]);
-				}
-				if (this.actions[mime]) {
-					actions = $.extend(actions, this.actions[mime]);
-				}
-			}
-			var filteredActions = {};
-			$.each(actions, function (name, action) {
-				if (action.permissions & permissions) {
-					filteredActions[name] = action;
-				}
-			});
-			return filteredActions;
-		},
-
-		/**
-		 * Returns the default file action handler for the given conditions
-		 *
-		 * @param {string} mime mime type
-		 * @param {string} type "dir" or "file"
-		 * @param {int} permissions permissions
-		 *
-		 * @return {OCA.Files.FileActions~actionHandler} action handler
-		 *
-		 * @deprecated use getDefaultFileAction instead
-		 */
-		getDefault: function (mime, type, permissions) {
-			var defaultActionSpec = this.getDefaultFileAction(mime, type, permissions);
-			if (defaultActionSpec) {
-				return defaultActionSpec.action;
-			}
-			return undefined;
-		},
-
-		/**
-		 * Returns the default file action handler for the given conditions
-		 *
-		 * @param {string} mime mime type
-		 * @param {string} type "dir" or "file"
-		 * @param {int} permissions permissions
-		 *
-		 * @return {OCA.Files.FileActions~actionHandler} action handler
-		 * @since 8.2
-		 */
-		getDefaultFileAction: function(mime, type, permissions) {
-			var mimePart;
-			if (mime) {
-				mimePart = mime.substr(0, mime.indexOf('/'));
-			}
-			var name = false;
-			if (mime && this.defaults[mime]) {
-				name = this.defaults[mime];
-			} else if (mime && this.defaults[mimePart]) {
-				name = this.defaults[mimePart];
-			} else if (type && this.defaults[type]) {
-				name = this.defaults[type];
-			} else {
-				name = this.defaults.all;
-			}
-			var actions = this.getActions(mime, type, permissions);
-			return actions[name];
-		},
-
-		/**
-		 * Default function to render actions
-		 *
-		 * @param {OCA.Files.FileAction} actionSpec file action spec
-		 * @param {boolean} isDefault true if the action is a default one,
-		 * false otherwise
-		 * @param {OCA.Files.FileActionContext} context action context
-		 */
-		_defaultRenderAction: function(actionSpec, isDefault, context) {
-			if (!isDefault) {
-				var params = {
-					name: actionSpec.name,
-					nameLowerCase: actionSpec.name.toLowerCase(),
-					displayName: actionSpec.displayName,
-					icon: actionSpec.icon,
-					iconClass: actionSpec.iconClass,
-					altText: actionSpec.altText,
-					hasDisplayName: !!actionSpec.displayName
-				};
-				if (_.isFunction(actionSpec.icon)) {
-					params.icon = actionSpec.icon(context.$file.attr('data-file'), context);
-				}
-				if (_.isFunction(actionSpec.iconClass)) {
-					params.iconClass = actionSpec.iconClass(context.$file.attr('data-file'), context);
-				}
-
-				var $actionLink = this._makeActionLink(params, context);
-				context.$file.find('a.name>span.fileactions').append($actionLink);
-				$actionLink.addClass('permanent');
-				return $actionLink;
-			}
-		},
-
-		/**
-		 * Renders the action link element
-		 *
-		 * @param {Object} params action params
-		 */
-		_makeActionLink: function(params) {
-			if (!this._fileActionTriggerTemplate) {
-				this._fileActionTriggerTemplate = Handlebars.compile(TEMPLATE_FILE_ACTION_TRIGGER);
-			}
-
-			return $(this._fileActionTriggerTemplate(params));
-		},
-
-		/**
-		 * Displays the file actions dropdown menu
-		 *
-		 * @param {string} fileName file name
-		 * @param {OCA.Files.FileActionContext} context rendering context
-		 */
-		_showMenu: function(fileName, context) {
-			var menu;
-			var $trigger = context.$file.closest('tr').find('.fileactions .action-menu');
-			$trigger.addClass('open');
-
-			menu = new OCA.Files.FileActionsMenu();
-
-			context.$file.find('td.filename').append(menu.$el);
-
-			menu.$el.on('afterHide', function() {
-				context.$file.removeClass('mouseOver');
-				$trigger.removeClass('open');
-				menu.remove();
-			});
-
-			context.$file.addClass('mouseOver');
-			menu.show(context);
-		},
-
-		/**
-		 * Renders the menu trigger on the given file list row
-		 *
-		 * @param {Object} $tr file list row element
-		 * @param {OCA.Files.FileActionContext} context rendering context
-		 */
-		_renderMenuTrigger: function($tr, context) {
-			// remove previous
-			$tr.find('.action-menu').remove();
-
-			var $el = this._renderInlineAction({
-				name: 'menu',
-				displayName: '',
-				iconClass: 'icon-more',
-				altText: t('files', 'Actions'),
-				action: this._showMenuClosure
-			}, false, context);
-
-			$el.addClass('permanent');
-		},
-
-		/**
-		 * Renders the action element by calling actionSpec.render() and
-		 * registers the click event to process the action.
-		 *
-		 * @param {OCA.Files.FileAction} actionSpec file action to render
-		 * @param {boolean} isDefault true if the action is a default action,
-		 * false otherwise
-		 * @param {OCA.Files.FileActionContext} context rendering context
-		 */
-		_renderInlineAction: function(actionSpec, isDefault, context) {
-			var renderFunc = actionSpec.render || _.bind(this._defaultRenderAction, this);
-			var $actionEl = renderFunc(actionSpec, isDefault, context);
-			if (!$actionEl || !$actionEl.length) {
-				return;
-			}
-			$actionEl.on(
-				'click', {
-					a: null
-				},
-				function(event) {
-					event.stopPropagation();
-					event.preventDefault();
-
-					if ($actionEl.hasClass('open')) {
-						return;
-					}
-
-					var $file = $(event.target).closest('tr');
-					if ($file.hasClass('busy')) {
-						return;
-					}
-					var currentFile = $file.find('td.filename');
-					var fileName = $file.attr('data-file');
-
-					context.fileActions.currentFile = currentFile;
-					// also set on global object for legacy apps
-					window.FileActions.currentFile = currentFile;
-
-					var callContext = _.extend({}, context);
-
-					if (!context.dir && context.fileList) {
-						callContext.dir = $file.attr('data-path') || context.fileList.getCurrentDirectory();
-					}
-
-					if (!context.fileInfoModel && context.fileList) {
-						callContext.fileInfoModel = context.fileList.getModelForFile(fileName);
-						if (!callContext.fileInfoModel) {
-							console.warn('No file info model found for file "' + fileName + '"');
-						}
-					}
-
-					actionSpec.action(
-						fileName,
-						callContext
-					);
-				}
-			);
-			$actionEl.tooltip({placement:'top'});
-			return $actionEl;
-		},
-
-		/**
-		 * Trigger the given action on the given file.
-		 *
-		 * @param {string} actionName action name
-		 * @param {OCA.Files.FileInfoModel} fileInfoModel file info model
-		 * @param {OCA.Files.FileList} [fileList] file list, for compatibility with older action handlers [DEPRECATED]
-		 *
-		 * @return {boolean} true if the action handler was called, false otherwise
-		 *
-		 * @since 8.2
-		 */
-		triggerAction: function(actionName, fileInfoModel, fileList) {
-			var actionFunc;
-			var actions = this.get(
-				fileInfoModel.get('mimetype'),
-				fileInfoModel.isDirectory() ? 'dir' : 'file',
-				fileInfoModel.get('permissions')
-			);
-
-			if (actionName) {
-				actionFunc = actions[actionName];
-			} else {
-				actionFunc = this.getDefault(
-					fileInfoModel.get('mimetype'),
-					fileInfoModel.isDirectory() ? 'dir' : 'file',
-					fileInfoModel.get('permissions')
-				);
-			}
-
-			if (!actionFunc) {
-				actionFunc = actions['Download'];
-			}
-
-			if (!actionFunc) {
-				return false;
-			}
-
-			var context = {
-				fileActions: this,
-				fileInfoModel: fileInfoModel,
-				dir: fileInfoModel.get('path')
-			};
-
-			var fileName = fileInfoModel.get('name');
-			this.currentFile = fileName;
-			// also set on global object for legacy apps
-			window.FileActions.currentFile = fileName;
-
-			if (fileList) {
-				// compatibility with action handlers that expect these
-				context.fileList = fileList;
-				context.$file = fileList.findFileEl(fileName);
-			}
-
-			actionFunc(fileName, context);
-		},
-
-		/**
-		 * Display file actions for the given element
-		 * @param parent "td" element of the file for which to display actions
-		 * @param triggerEvent if true, triggers the fileActionsReady on the file
-		 * list afterwards (false by default)
-		 * @param fileList OCA.Files.FileList instance on which the action is
-		 * done, defaults to OCA.Files.App.fileList
-		 */
-		display: function (parent, triggerEvent, fileList) {
-			if (!fileList) {
-				console.warn('FileActions.display() MUST be called with a OCA.Files.FileList instance');
-				return;
-			}
-			this.currentFile = parent;
-			var self = this;
-			var $tr = parent.closest('tr');
-			var actions = this.getActions(
-				this.getCurrentMimeType(),
-				this.getCurrentType(),
-				this.getCurrentPermissions()
-			);
-			var nameLinks;
-			if ($tr.data('renaming')) {
-				return;
-			}
-
-			// recreate fileactions container
-			nameLinks = parent.children('a.name');
-			nameLinks.find('.fileactions, .nametext .action').remove();
-			nameLinks.append('<span class="fileactions" />');
-			var defaultAction = this.getDefaultFileAction(
-				this.getCurrentMimeType(),
-				this.getCurrentType(),
-				this.getCurrentPermissions()
-			);
-
-			var context = {
-				$file: $tr,
-				fileActions: this,
-				fileList: fileList
-			};
-
-			$.each(actions, function (name, actionSpec) {
-				if (actionSpec.type === FileActions.TYPE_INLINE) {
-					self._renderInlineAction(
-						actionSpec,
-						defaultAction && actionSpec.name === defaultAction.name,
-						context
-					);
-				}
-			});
-
-			this._renderMenuTrigger($tr, context);
-
-			if (triggerEvent){
-				fileList.$fileList.trigger(jQuery.Event("fileActionsReady", {fileList: fileList, $files: $tr}));
-			}
-		},
-		getCurrentFile: function () {
-			return this.currentFile.parent().attr('data-file');
-		},
-		getCurrentMimeType: function () {
-			return this.currentFile.parent().attr('data-mime');
-		},
-		getCurrentType: function () {
-			return this.currentFile.parent().attr('data-type');
-		},
-		getCurrentPermissions: function () {
-			return this.currentFile.parent().data('permissions');
-		},
-
-		/**
-		 * Register the actions that are used by default for the files app.
-		 */
-		registerDefaultActions: function() {
-			this.registerAction({
-				name: 'Download',
-				displayName: t('files', 'Download'),
-				order: -20,
-				mime: 'all',
-				permissions: OC.PERMISSION_READ,
-				iconClass: 'icon-download',
-				actionHandler: function (filename, context) {
-					var dir = context.dir || context.fileList.getCurrentDirectory();
-					var isDir = context.$file.attr('data-type') === 'dir';
-					var url = context.fileList.getDownloadUrl(filename, dir, isDir);
-
-					var downloadFileaction = $(context.$file).find('.fileactions .action-download');
-
-					// don't allow a second click on the download action
-					if(downloadFileaction.hasClass('disabled')) {
-						return;
-					}
-
-					if (url) {
-						var disableLoadingState = function() {
-							context.fileList.showFileBusyState(filename, false);
-						};
-
-						context.fileList.showFileBusyState(filename, true);
-						OCA.Files.Files.handleDownload(url, disableLoadingState);
-					}
-				}
-			});
-
-			this.registerAction({
-				name: 'Rename',
-				displayName: t('files', 'Rename'),
-				mime: 'all',
-				order: -30,
-				permissions: OC.PERMISSION_UPDATE,
-				iconClass: 'icon-rename',
-				actionHandler: function (filename, context) {
-					context.fileList.rename(filename);
-				}
-			});
-
-			this.registerAction({
-				name: 'Move',
-				displayName: t('files', 'Move'),
-				mime: 'all',
-				order: -25,
-				permissions: OC.PERMISSION_UPDATE,
-				iconClass: 'icon-external',
-				actionHandler: function (filename, context) {
-					OC.dialogs.filepicker(t('files', 'Target folder'), function(targetPath) {
-						context.fileList.move(filename, targetPath);
-					}, false, "httpd/unix-directory", true);
-				}
-			});
-
-			this.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
-				var dir = context.$file.attr('data-path') || context.fileList.getCurrentDirectory();
-				context.fileList.changeDirectory(OC.joinPaths(dir, filename), true, false, parseInt(context.$file.attr('data-id'), 10));
-			});
-
-			this.registerAction({
-				name: 'Delete',
-				displayName: function(context) {
-					var mountType = context.$file.attr('data-mounttype');
-					var deleteTitle = t('files', 'Delete');
-					if (mountType === 'external-root') {
-						deleteTitle = t('files', 'Disconnect storage');
-					} else if (mountType === 'shared-root') {
-						deleteTitle = t('files', 'Unshare');
-					}
-					return deleteTitle;
-				},
-				mime: 'all',
-				order: 1000,
-				// permission is READ because we show a hint instead if there is no permission
-				permissions: OC.PERMISSION_DELETE,
-				iconClass: 'icon-delete',
-				actionHandler: function(fileName, context) {
-					// if there is no permission to delete do nothing
-					if((context.$file.data('permissions') & OC.PERMISSION_DELETE) === 0) {
-						return;
-					}
-					context.fileList.do_delete(fileName, context.dir);
-					$('.tipsy').remove();
-				}
-			});
-
-			this.setDefault('dir', 'Open');
-		}
-	};
-
-	OCA.Files.FileActions = FileActions;
-
-	/**
-	 * Replaces the download icon with a loading spinner and vice versa
-	 * - also adds the class disabled to the passed in element
-	 *
-	 * @param {jQuery} $downloadButtonElement download fileaction
-	 * @param {boolean} showIt whether to show the spinner(true) or to hide it(false)
-	 */
-	OCA.Files.FileActions.updateFileActionSpinner = function($downloadButtonElement, showIt) {
-		var $icon = $downloadButtonElement.find('.icon');
-		if (showIt) {
-			var $loadingIcon = $('<span class="icon icon-loading-small"></span>');
-			$icon.after($loadingIcon);
-			$icon.addClass('hidden');
-		} else {
-			$downloadButtonElement.find('.icon-loading-small').remove();
-			$downloadButtonElement.find('.icon').removeClass('hidden');
-		}
-	};
-
-	/**
-	 * File action attributes.
-	 *
-	 * @todo make this a real class in the future
-	 * @typedef {Object} OCA.Files.FileAction
-	 *
-	 * @property {String} name identifier of the action
-	 * @property {(String|OCA.Files.FileActions~displayNameFunction)} displayName
-	 * display name string for the action, or function that returns the display name.
-	 * Defaults to the name given in name property
-	 * @property {String} mime mime type
-	 * @property {int} permissions permissions
-	 * @property {(Function|String)} icon icon path to the icon or function that returns it (deprecated, use iconClass instead)
-	 * @property {(Function|String)} iconClass class name of the icon (recommended for theming)
-	 * @property {OCA.Files.FileActions~renderActionFunction} [render] optional rendering function
-	 * @property {OCA.Files.FileActions~actionHandler} actionHandler action handler function
-	 */
-
-	/**
-	 * File action context attributes.
-	 *
-	 * @typedef {Object} OCA.Files.FileActionContext
-	 *
-	 * @property {Object} $file jQuery file row element
-	 * @property {OCA.Files.FileActions} fileActions file actions object
-	 * @property {OCA.Files.FileList} fileList file list object
-	 */
-
-	/**
-	 * Render function for actions.
-	 * The function must render a link element somewhere in the DOM
-	 * and return it. The function should NOT register the event handler
-	 * as this will be done after the link was returned.
-	 *
-	 * @callback OCA.Files.FileActions~renderActionFunction
-	 * @param {OCA.Files.FileAction} actionSpec action definition
-	 * @param {Object} $row row container
-	 * @param {boolean} isDefault true if the action is the default one,
-	 * false otherwise
-	 * @return {Object} jQuery link object
-	 */
-
-	/**
-	 * Display name function for actions.
-	 * The function returns the display name of the action using
-	 * the given context information..
-	 *
-	 * @callback OCA.Files.FileActions~displayNameFunction
-	 * @param {OCA.Files.FileActionContext} context action context
-	 * @return {String} display name
-	 */
-
-	/**
-	 * Action handler function for file actions
-	 *
-	 * @callback OCA.Files.FileActions~actionHandler
-	 * @param {String} fileName name of the file on which the action must be performed
-	 * @param context context
-	 * @param {String} context.dir directory of the file
-	 * @param {OCA.Files.FileInfoModel} fileInfoModel file info model
-	 * @param {Object} [context.$file] jQuery element of the file [DEPRECATED]
-	 * @param {OCA.Files.FileList} [context.fileList] the FileList instance on which the action occurred [DEPRECATED]
-	 * @param {OCA.Files.FileActions} context.fileActions the FileActions instance on which the action occurred
-	 */
-
-	// global file actions to be used by all lists
-	OCA.Files.fileActions = new OCA.Files.FileActions();
-	OCA.Files.legacyFileActions = new OCA.Files.FileActions();
-
-	// for backward compatibility
-	//
-	// legacy apps are expecting a stateful global FileActions object to register
-	// their actions on. Since legacy apps are very likely to break with other
-	// FileList views than the main one ("All files"), actions registered
-	// through window.FileActions will be limited to the main file list.
-	// @deprecated use OCA.Files.FileActions instead
-	window.FileActions = OCA.Files.legacyFileActions;
-	window.FileActions.register = function (mime, name, permissions, icon, action, displayName) {
-		console.warn('FileActions.register() is deprecated, please use OCA.Files.fileActions.register() instead', arguments);
-		OCA.Files.FileActions.prototype.register.call(
-				window.FileActions, mime, name, permissions, icon, action, displayName
-		);
-	};
-	window.FileActions.display = function (parent, triggerEvent, fileList) {
-		fileList = fileList || OCA.Files.App.fileList;
-		console.warn('FileActions.display() is deprecated, please use OCA.Files.fileActions.register() which automatically redisplays actions', mime, name);
-		OCA.Files.FileActions.prototype.display.call(window.FileActions, parent, triggerEvent, fileList);
-	};
-})();
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	var TEMPLATE_MENU =
-		'<ul>' +
-		'{{#each items}}' +
-		'<li>' +
-		'<a href="#" class="menuitem action action-{{nameLowerCase}} permanent" data-action="{{name}}">' +
-			'{{#if icon}}<img class="icon" src="{{icon}}"/>' +
-			'{{else}}'+
-				'{{#if iconClass}}' +
-				'<span class="icon {{iconClass}}"></span>' +
-				'{{else}}' +
-				'<span class="no-icon"></span>' +
-				'{{/if}}' +
-			'{{/if}}' +
-			'<span>{{displayName}}</span></a>' +
-		'</li>' +
-		'{{/each}}' +
-		'</ul>';
-
-	/**
-	 * Construct a new FileActionsMenu instance
-	 * @constructs FileActionsMenu
-	 * @memberof OCA.Files
-	 */
-	var FileActionsMenu = OC.Backbone.View.extend({
-		tagName: 'div',
-		className: 'fileActionsMenu popovermenu bubble hidden open menu',
-
-		/**
-		 * Current context
-		 *
-		 * @type OCA.Files.FileActionContext
-		 */
-		_context: null,
-
-		events: {
-			'click a.action': '_onClickAction'
-		},
-
-		template: function(data) {
-			if (!OCA.Files.FileActionsMenu._TEMPLATE) {
-				OCA.Files.FileActionsMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
-			}
-			return OCA.Files.FileActionsMenu._TEMPLATE(data);
-		},
-
-		/**
-		 * Event handler whenever an action has been clicked within the menu
-		 *
-		 * @param {Object} event event object
-		 */
-		_onClickAction: function(event) {
-			var $target = $(event.target);
-			if (!$target.is('a')) {
-				$target = $target.closest('a');
-			}
-			var fileActions = this._context.fileActions;
-			var actionName = $target.attr('data-action');
-			var actions = fileActions.getActions(
-				fileActions.getCurrentMimeType(),
-				fileActions.getCurrentType(),
-				fileActions.getCurrentPermissions()
-			);
-			var actionSpec = actions[actionName];
-			var fileName = this._context.$file.attr('data-file');
-
-			event.stopPropagation();
-			event.preventDefault();
-
-			OC.hideMenus();
-
-			actionSpec.action(
-				fileName,
-				this._context
-			);
-		},
-
-		/**
-		 * Renders the menu with the currently set items
-		 */
-		render: function() {
-			var self = this;
-			var fileActions = this._context.fileActions;
-			var actions = fileActions.getActions(
-				fileActions.getCurrentMimeType(),
-				fileActions.getCurrentType(),
-				fileActions.getCurrentPermissions()
-			);
-
-			var defaultAction = fileActions.getDefaultFileAction(
-				fileActions.getCurrentMimeType(),
-				fileActions.getCurrentType(),
-				fileActions.getCurrentPermissions()
-			);
-
-			var items = _.filter(actions, function(actionSpec) {
-				return (
-					actionSpec.type === OCA.Files.FileActions.TYPE_DROPDOWN &&
-					(!defaultAction || actionSpec.name !== defaultAction.name)
-				);
-			});
-			items = _.map(items, function(item) {
-				if (_.isFunction(item.displayName)) {
-					item = _.extend({}, item);
-					item.displayName = item.displayName(self._context);
-				}
-				return item;
-			});
-			items = items.sort(function(actionA, actionB) {
-				var orderA = actionA.order || 0;
-				var orderB = actionB.order || 0;
-				if (orderB === orderA) {
-					return OC.Util.naturalSortCompare(actionA.displayName, actionB.displayName);
-				}
-				return orderA - orderB;
-			});
-			items = _.map(items, function(item) {
-				item.nameLowerCase = item.name.toLowerCase();
-				return item;
-			});
-
-			this.$el.html(this.template({
-				items: items
-			}));
-		},
-
-		/**
-		 * Displays the menu under the given element
-		 *
-		 * @param {OCA.Files.FileActionContext} context context
-		 * @param {Object} $trigger trigger element
-		 */
-		show: function(context) {
-			this._context = context;
-
-			this.render();
-			this.$el.removeClass('hidden');
-
-			OC.showMenu(null, this.$el);
-		}
-	});
-
-	OCA.Files.FileActionsMenu = FileActionsMenu;
-
-})();
-
-
-
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* global getURLParameter */
-/**
- * Utility class for file related operations
- */
-(function() {
-	var Files = {
-		// file space size sync
-		_updateStorageStatistics: function(currentDir) {
-			var state = Files.updateStorageStatistics;
-			if (state.dir){
-				if (state.dir === currentDir) {
-					return;
-				}
-				// cancel previous call, as it was for another dir
-				state.call.abort();
-			}
-			state.dir = currentDir;
-			state.call = $.getJSON(OC.filePath('files','ajax','getstoragestats.php') + '?dir=' + encodeURIComponent(currentDir),function(response) {
-				state.dir = null;
-				state.call = null;
-				Files.updateMaxUploadFilesize(response);
-			});
-		},
-		/**
-		 * Update storage statistics such as free space, max upload,
-		 * etc based on the given directory.
-		 *
-		 * Note this function is debounced to avoid making too
-		 * many ajax calls in a row.
-		 *
-		 * @param dir directory
-		 * @param force whether to force retrieving
-		 */
-		updateStorageStatistics: function(dir, force) {
-			if (!OC.currentUser) {
-				return;
-			}
-
-			if (force) {
-				Files._updateStorageStatistics(dir);
-			}
-			else {
-				Files._updateStorageStatisticsDebounced(dir);
-			}
-		},
-
-		updateMaxUploadFilesize:function(response) {
-			if (response === undefined) {
-				return;
-			}
-			if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) {
-				$('#free_space').val(response.data.freeSpace);
-				$('#upload.button').attr('data-original-title', response.data.maxHumanFilesize);
-				$('#usedSpacePercent').val(response.data.usedSpacePercent);
-				$('#owner').val(response.data.owner);
-				$('#ownerDisplayName').val(response.data.ownerDisplayName);
-				Files.displayStorageWarnings();
-			}
-			if (response[0] === undefined) {
-				return;
-			}
-			if (response[0].uploadMaxFilesize !== undefined) {
-				$('#upload.button').attr('data-original-title', response[0].maxHumanFilesize);
-				$('#usedSpacePercent').val(response[0].usedSpacePercent);
-				Files.displayStorageWarnings();
-			}
-
-		},
-
-		/**
-		 * Fix path name by removing double slash at the beginning, if any
-		 */
-		fixPath: function(fileName) {
-			if (fileName.substr(0, 2) == '//') {
-				return fileName.substr(1);
-			}
-			return fileName;
-		},
-
-		/**
-		 * Checks whether the given file name is valid.
-		 * @param name file name to check
-		 * @return true if the file name is valid.
-		 * Throws a string exception with an error message if
-		 * the file name is not valid
-		 */
-		isFileNameValid: function (name) {
-			var trimmedName = name.trim();
-			if (trimmedName === '.'	|| trimmedName === '..')
-			{
-				throw t('files', '"{name}" is an invalid file name.', {name: name});
-			} else if (trimmedName.length === 0) {
-				throw t('files', 'File name cannot be empty.');
-			} else if (OC.fileIsBlacklisted(trimmedName)) {
-				throw t('files', '"{name}" is not an allowed filetype', {name: name});
-			}
-
-			return true;
-		},
-		displayStorageWarnings: function() {
-			if (!OC.Notification.isHidden()) {
-				return;
-			}
-
-			var usedSpacePercent = $('#usedSpacePercent').val(),
-				owner = $('#owner').val(),
-				ownerDisplayName = $('#ownerDisplayName').val();
-			if (usedSpacePercent > 98) {
-				if (owner !== oc_current_user) {
-					OC.Notification.show(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!', 
-						{owner: ownerDisplayName}), {type: 'error'}
-					);
-					return;
-				}
-				OC.Notification.show(t('files', 
-					'Your storage is full, files can not be updated or synced anymore!'), 
-					{type : 'error'}
-				);
-				return;
-			}
-			if (usedSpacePercent > 90) {
-				if (owner !== oc_current_user) {
-					OC.Notification.show(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)', 
-						{
-							usedSpacePercent: usedSpacePercent,  
-							owner: ownerDisplayName
-						}),
-						{  
-							type: 'error'
-						}
-					);
-					return;
-				}
-				OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)',
-					{usedSpacePercent: usedSpacePercent}), 
-					{type : 'error'}
-				);
-			}
-		},
-
-		/**
-		 * Returns the download URL of the given file(s)
-		 * @param {string} filename string or array of file names to download
-		 * @param {string} [dir] optional directory in which the file name is, defaults to the current directory
-		 * @param {bool} [isDir=false] whether the given filename is a directory and might need a special URL
-		 */
-		getDownloadUrl: function(filename, dir, isDir) {
-			if (!_.isArray(filename) && !isDir) {
-				var pathSections = dir.split('/');
-				pathSections.push(filename);
-				var encodedPath = '';
-				_.each(pathSections, function(section) {
-					if (section !== '') {
-						encodedPath += '/' + encodeURIComponent(section);
-					}
-				});
-				return OC.linkToRemoteBase('webdav') + encodedPath;
-			}
-
-			if (_.isArray(filename)) {
-				filename = JSON.stringify(filename);
-			}
-
-			var params = {
-				dir: dir,
-				files: filename
-			};
-			return this.getAjaxUrl('download', params);
-		},
-
-		/**
-		 * Returns the ajax URL for a given action
-		 * @param action action string
-		 * @param params optional params map
-		 */
-		getAjaxUrl: function(action, params) {
-			var q = '';
-			if (params) {
-				q = '?' + OC.buildQueryString(params);
-			}
-			return OC.filePath('files', 'ajax', action + '.php') + q;
-		},
-
-		/**
-		 * Fetch the icon url for the mimetype
-		 * @param {string} mime The mimetype
-		 * @param {Files~mimeicon} ready Function to call when mimetype is retrieved
-		 * @deprecated use OC.MimeType.getIconUrl(mime)
-		 */
-		getMimeIcon: function(mime, ready) {
-			ready(OC.MimeType.getIconUrl(mime));
-		},
-
-		/**
-		 * Generates a preview URL based on the URL space.
-		 * @param urlSpec attributes for the URL
-		 * @param {int} urlSpec.x width
-		 * @param {int} urlSpec.y height
-		 * @param {String} urlSpec.file path to the file
-		 * @return preview URL
-		 * @deprecated used OCA.Files.FileList.generatePreviewUrl instead
-		 */
-		generatePreviewUrl: function(urlSpec) {
-			console.warn('DEPRECATED: please use generatePreviewUrl() from an OCA.Files.FileList instance');
-			return OCA.Files.App.fileList.generatePreviewUrl(urlSpec);
-		},
-
-		/**
-		 * Lazy load preview
-		 * @deprecated used OCA.Files.FileList.lazyLoadPreview instead
-		 */
-		lazyLoadPreview : function(path, mime, ready, width, height, etag) {
-			console.warn('DEPRECATED: please use lazyLoadPreview() from an OCA.Files.FileList instance');
-			return FileList.lazyLoadPreview({
-				path: path,
-				mime: mime,
-				callback: ready,
-				width: width,
-				height: height,
-				etag: etag
-			});
-		},
-
-		/**
-		 * Initialize the files view
-		 */
-		initialize: function() {
-			Files.bindKeyboardShortcuts(document, $);
-
-			// TODO: move file list related code (upload) to OCA.Files.FileList
-			$('#file_action_panel').attr('activeAction', false);
-
-			// drag&drop support using jquery.fileupload
-			// TODO use OC.dialogs
-			$(document).bind('drop dragover', function (e) {
-					e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
-				});
-
-			// display storage warnings
-			setTimeout(Files.displayStorageWarnings, 100);
-
-			// only possible at the moment if user is logged in or the files app is loaded
-			if (OC.currentUser && OCA.Files.App) {
-				// start on load - we ask the server every 5 minutes
-				var func = _.bind(OCA.Files.App.fileList.updateStorageStatistics, OCA.Files.App.fileList);
-				var updateStorageStatisticsInterval = 5*60*1000;
-				var updateStorageStatisticsIntervalId = setInterval(func, updateStorageStatisticsInterval);
-
-				// TODO: this should also stop when switching to another view
-				// Use jquery-visibility to de-/re-activate file stats sync
-				if ($.support.pageVisibility) {
-					$(document).on({
-						'show': function() {
-							if (!updateStorageStatisticsIntervalId) {
-								updateStorageStatisticsIntervalId = setInterval(func, updateStorageStatisticsInterval);
-							}
-						},
-						'hide': function() {
-							clearInterval(updateStorageStatisticsIntervalId);
-							updateStorageStatisticsIntervalId = 0;
-						}
-					});
-				}
-			}
-
-
-			$('#webdavurl').on('click touchstart', function () {
-				this.focus();
-				this.setSelectionRange(0, this.value.length);
-			});
-
-			$('#upload').tooltip({placement:'right'});
-
-			//FIXME scroll to and highlight preselected file
-			/*
-			if (getURLParameter('scrollto')) {
-				FileList.scrollTo(getURLParameter('scrollto'));
-			}
-			*/
-		},
-
-		/**
-		 * Handles the download and calls the callback function once the download has started
-		 * - browser sends download request and adds parameter with a token
-		 * - server notices this token and adds a set cookie to the download response
-		 * - browser now adds this cookie for the domain
-		 * - JS periodically checks for this cookie and then knows when the download has started to call the callback
-		 *
-		 * @param {string} url download URL
-		 * @param {function} callback function to call once the download has started
-		 */
-		handleDownload: function(url, callback) {
-			var randomToken = Math.random().toString(36).substring(2),
-				checkForDownloadCookie = function() {
-					if (!OC.Util.isCookieSetToValue('ocDownloadStarted', randomToken)){
-						return false;
-					} else {
-						callback();
-						return true;
-					}
-				};
-
-			if (url.indexOf('?') >= 0) {
-				url += '&';
-			} else {
-				url += '?';
-			}
-			OC.redirect(url + 'downloadStartSecret=' + randomToken);
-			OC.Util.waitFor(checkForDownloadCookie, 500);
-		}
-	};
-
-	Files._updateStorageStatisticsDebounced = _.debounce(Files._updateStorageStatistics, 250);
-	OCA.Files.Files = Files;
-})();
-
-// TODO: move to FileList
-var createDragShadow = function(event) {
-	// FIXME: inject file list instance somehow
-	/* global FileList, Files */
-
-	//select dragged file
-	var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked');
-	if (!isDragSelected) {
-		//select dragged file
-		FileList._selectFileEl($(event.target).parents('tr:first'), true, false);
-	}
-
-	// do not show drag shadow for too many files
-	var selectedFiles = _.first(FileList.getSelectedFiles(), FileList.pageSize());
-	selectedFiles = _.sortBy(selectedFiles, FileList._fileInfoCompare);
-
-	if (!isDragSelected && selectedFiles.length === 1) {
-		//revert the selection
-		FileList._selectFileEl($(event.target).parents('tr:first'), false, false);
-	}
-
-	// build dragshadow
-	var dragshadow = $('<table class="dragshadow"></table>');
-	var tbody = $('<tbody></tbody>');
-	dragshadow.append(tbody);
-
-	var dir = FileList.getCurrentDirectory();
-
-	$(selectedFiles).each(function(i,elem) {
-		// TODO: refactor this with the table row creation code
-		var newtr = $('<tr/>')
-			.attr('data-dir', dir)
-			.attr('data-file', elem.name)
-			.attr('data-origin', elem.origin);
-		newtr.append($('<td class="filename" />').text(elem.name).css('background-size', 32));
-		newtr.append($('<td class="size" />').text(OC.Util.humanFileSize(elem.size)));
-		tbody.append(newtr);
-		if (elem.type === 'dir') {
-			newtr.find('td.filename')
-				.css('background-image', 'url(' + OC.MimeType.getIconUrl('folder') + ')');
-		} else {
-			var path = dir + '/' + elem.name;
-			Files.lazyLoadPreview(path, elem.mimetype, function(previewpath) {
-				newtr.find('td.filename')
-					.css('background-image', 'url(' + previewpath + ')');
-			}, null, null, elem.etag);
-		}
-	});
-
-	return dragshadow;
-};
-
-//options for file drag/drop
-//start&stop handlers needs some cleaning up
-// TODO: move to FileList class
-var dragOptions={
-	revert: 'invalid',
-	revertDuration: 300,
-	opacity: 0.7,
-	zIndex: 100,
-	appendTo: 'body',
-	cursorAt: { left: 24, top: 18 },
-	helper: createDragShadow,
-	cursor: 'move',
-
-	start: function(event, ui){
-		var $selectedFiles = $('td.filename input:checkbox:checked');
-		if (!$selectedFiles.length) {
-			$selectedFiles = $(this);
-		}
-		$selectedFiles.closest('tr').addClass('animate-opacity dragging');
-		$selectedFiles.closest('tr').filter('.ui-droppable').droppable( 'disable' );
-
-	},
-	stop: function(event, ui) {
-		var $selectedFiles = $('td.filename input:checkbox:checked');
-		if (!$selectedFiles.length) {
-			$selectedFiles = $(this);
-		}
-
-		var $tr = $selectedFiles.closest('tr');
-		$tr.removeClass('dragging');
-		$tr.filter('.ui-droppable').droppable( 'enable' );
-
-		setTimeout(function() {
-			$tr.removeClass('animate-opacity');
-		}, 300);
-	},
-	drag: function(event, ui) {
-		var scrollingArea = FileList.$container;
-		var currentScrollTop = $(scrollingArea).scrollTop();
-		var scrollArea = Math.min(Math.floor($(window).innerHeight() / 2), 100);
-
-		var bottom = $(window).innerHeight() - scrollArea;
-		var top = $(window).scrollTop() + scrollArea;
-		if (event.pageY < top) {
-			$('html, body').animate({
-
-				scrollTop: $(scrollingArea).scrollTop(currentScrollTop - 10)
-			}, 400);
-
-		} else if (event.pageY > bottom) {
-			$('html, body').animate({
-				scrollTop: $(scrollingArea).scrollTop(currentScrollTop + 10)
-			}, 400);
-		}
-
-	}
-};
-// sane browsers support using the distance option
-if ( $('html.ie').length === 0) {
-	dragOptions['distance'] = 20;
-}
-
-// TODO: move to FileList class
-var folderDropOptions = {
-	hoverClass: "canDrop",
-	drop: function( event, ui ) {
-		// don't allow moving a file into a selected folder
-		/* global FileList */
-		if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) {
-			return false;
-		}
-
-		var $tr = $(this).closest('tr');
-		if (($tr.data('permissions') & OC.PERMISSION_CREATE) === 0) {
-			FileList._showPermissionDeniedNotification();
-			return false;
-		}
-		var targetPath = FileList.getCurrentDirectory() + '/' + $tr.data('file');
-
-		var files = FileList.getSelectedFiles();
-		if (files.length === 0) {
-			// single one selected without checkbox?
-			files = _.map(ui.helper.find('tr'), function(el) {
-				return FileList.elementToFile($(el));
-			});
-		}
-
-		FileList.move(_.pluck(files, 'name'), targetPath);
-	},
-	tolerance: 'pointer'
-};
-
-// override core's fileDownloadPath (legacy)
-function fileDownloadPath(dir, file) {
-	return OCA.Files.Files.getDownloadUrl(file, dir);
-}
-
-// for backward compatibility
-window.Files = OCA.Files.Files;
-
-
-/**
- * Copyright (c) 2012 Erik Sargent <esthepiking at gmail dot com>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- */
-/*****************************
- * Keyboard shortcuts for Files app
- * ctrl/cmd+n: new folder
- * ctrl/cmd+shift+n: new file
- * esc (while new file context menu is open): close menu
- * up/down: select file/folder
- * enter: open file/folder
- * delete/backspace: delete file/folder
- *****************************/
-(function(Files) {
-	var keys = [];
-	var keyCodes = {
-		shift: 16,
-		n: 78,
-		cmdFirefox: 224,
-		cmdOpera: 17,
-		leftCmdWebKit: 91,
-		rightCmdWebKit: 93,
-		ctrl: 17,
-		esc: 27,
-		downArrow: 40,
-		upArrow: 38,
-		enter: 13,
-		del: 46
-	};
-
-	function removeA(arr) {
-		var what, a = arguments,
-			L = a.length,
-			ax;
-		while (L > 1 && arr.length) {
-			what = a[--L];
-			while ((ax = arr.indexOf(what)) !== -1) {
-				arr.splice(ax, 1);
-			}
-		}
-		return arr;
-	}
-
-	function newFile() {
-		$("#new").addClass("active");
-		$(".popup.popupTop").toggle(true);
-		$('#new li[data-type="file"]').trigger('click');
-		removeA(keys, keyCodes.n);
-	}
-
-	function newFolder() {
-		$("#new").addClass("active");
-		$(".popup.popupTop").toggle(true);
-		$('#new li[data-type="folder"]').trigger('click');
-		removeA(keys, keyCodes.n);
-	}
-
-	function esc() {
-		$("#controls").trigger('click');
-	}
-
-	function down() {
-		var select = -1;
-		$("#fileList tr").each(function(index) {
-			if ($(this).hasClass("mouseOver")) {
-				select = index + 1;
-				$(this).removeClass("mouseOver");
-			}
-		});
-		if (select === -1) {
-			$("#fileList tr:first").addClass("mouseOver");
-		} else {
-			$("#fileList tr").each(function(index) {
-				if (index === select) {
-					$(this).addClass("mouseOver");
-				}
-			});
-		}
-	}
-
-	function up() {
-		var select = -1;
-		$("#fileList tr").each(function(index) {
-			if ($(this).hasClass("mouseOver")) {
-				select = index - 1;
-				$(this).removeClass("mouseOver");
-			}
-		});
-		if (select === -1) {
-			$("#fileList tr:last").addClass("mouseOver");
-		} else {
-			$("#fileList tr").each(function(index) {
-				if (index === select) {
-					$(this).addClass("mouseOver");
-				}
-			});
-		}
-	}
-
-	function enter() {
-		$("#fileList tr").each(function(index) {
-			if ($(this).hasClass("mouseOver")) {
-				$(this).removeClass("mouseOver");
-				$(this).find("span.nametext").trigger('click');
-			}
-		});
-	}
-
-	function del() {
-		$("#fileList tr").each(function(index) {
-			if ($(this).hasClass("mouseOver")) {
-				$(this).removeClass("mouseOver");
-				$(this).find("a.action.delete").trigger('click');
-			}
-		});
-	}
-
-	function rename() {
-		$("#fileList tr").each(function(index) {
-			if ($(this).hasClass("mouseOver")) {
-				$(this).removeClass("mouseOver");
-				$(this).find("a[data-action='Rename']").trigger('click');
-			}
-		});
-	}
-	Files.bindKeyboardShortcuts = function(document, $) {
-		$(document).keydown(function(event) { //check for modifier keys
-            if(!$(event.target).is('body')) {
-                return;
-            }
-			var preventDefault = false;
-			if ($.inArray(event.keyCode, keys) === -1) {
-				keys.push(event.keyCode);
-			}
-			if (
-			$.inArray(keyCodes.n, keys) !== -1 && ($.inArray(keyCodes.cmdFirefox, keys) !== -1 || $.inArray(keyCodes.cmdOpera, keys) !== -1 || $.inArray(keyCodes.leftCmdWebKit, keys) !== -1 || $.inArray(keyCodes.rightCmdWebKit, keys) !== -1 || $.inArray(keyCodes.ctrl, keys) !== -1 || event.ctrlKey)) {
-				preventDefault = true; //new file/folder prevent browser from responding
-			}
-			if (preventDefault) {
-				event.preventDefault(); //Prevent web browser from responding
-				event.stopPropagation();
-				return false;
-			}
-		});
-		$(document).keyup(function(event) {
-			// do your event.keyCode checks in here
-			if (
-			$.inArray(keyCodes.n, keys) !== -1 && ($.inArray(keyCodes.cmdFirefox, keys) !== -1 || $.inArray(keyCodes.cmdOpera, keys) !== -1 || $.inArray(keyCodes.leftCmdWebKit, keys) !== -1 || $.inArray(keyCodes.rightCmdWebKit, keys) !== -1 || $.inArray(keyCodes.ctrl, keys) !== -1 || event.ctrlKey)) {
-				if ($.inArray(keyCodes.shift, keys) !== -1) { //16=shift, New File
-					newFile();
-				} else { //New Folder
-					newFolder();
-				}
-			} else if ($("#new").hasClass("active") && $.inArray(keyCodes.esc, keys) !== -1) { //close new window
-				esc();
-			} else if ($.inArray(keyCodes.downArrow, keys) !== -1) { //select file
-				down();
-			} else if ($.inArray(keyCodes.upArrow, keys) !== -1) { //select file
-				up();
-			} else if (!$("#new").hasClass("active") && $.inArray(keyCodes.enter, keys) !== -1) { //open file
-				enter();
-			} else if (!$("#new").hasClass("active") && $.inArray(keyCodes.del, keys) !== -1) { //delete file
-				del();
-			}
-			removeA(keys, event.keyCode);
-		});
-	};
-})((OCA.Files && OCA.Files.Files) || {});
-
-
-/*
- * Copyright (c) 2014
- *
- * @author Vincent Petry
- * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	/**
-	 * @class OCA.Files.Navigation
-	 * @classdesc Navigation control for the files app sidebar.
-	 *
-	 * @param $el element containing the navigation
-	 */
-	var Navigation = function($el) {
-		this.initialize($el);
-	};
-
-	/**
-	 * @memberof OCA.Files
-	 */
-	Navigation.prototype = {
-
-		/**
-		 * Currently selected item in the list
-		 */
-		_activeItem: null,
-
-		/**
-		 * Currently selected container
-		 */
-		$currentContent: null,
-
-		/**
-		 * Initializes the navigation from the given container
-		 *
-		 * @private
-		 * @param $el element containing the navigation
-		 */
-		initialize: function($el) {
-			this.$el = $el;
-			this._activeItem = null;
-			this.$currentContent = null;
-			this._setupEvents();
-		},
-
-		/**
-		 * Setup UI events
-		 */
-		_setupEvents: function() {
-			this.$el.on('click', 'li a', _.bind(this._onClickItem, this));
-		},
-
-		/**
-		 * Returns the container of the currently active app.
-		 *
-		 * @return app container
-		 */
-		getActiveContainer: function() {
-			return this.$currentContent;
-		},
-
-		/**
-		 * Returns the currently active item
-		 * 
-		 * @return item ID
-		 */
-		getActiveItem: function() {
-			return this._activeItem;
-		},
-
-		/**
-		 * Switch the currently selected item, mark it as selected and
-		 * make the content container visible, if any.
-		 *
-		 * @param string itemId id of the navigation item to select
-		 * @param array options "silent" to not trigger event
-		 */
-		setActiveItem: function(itemId, options) {
-			var oldItemId = this._activeItem;
-			if (itemId === this._activeItem) {
-				if (!options || !options.silent) {
-					this.$el.trigger(
-						new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId})
-					);
-				}
-				return;
-			}
-			this.$el.find('li').removeClass('active');
-			if (this.$currentContent) {
-				this.$currentContent.addClass('hidden');
-				this.$currentContent.trigger(jQuery.Event('hide'));
-			}
-			this._activeItem = itemId;
-			this.$el.find('li[data-id=' + itemId + ']').addClass('active');
-			this.$currentContent = $('#app-content-' + itemId);
-			this.$currentContent.removeClass('hidden');
-			if (!options || !options.silent) {
-				this.$currentContent.trigger(jQuery.Event('show'));
-				this.$el.trigger(
-					new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId})
-				);
-			}
-		},
-
-		/**
-		 * Returns whether a given item exists
-		 */
-		itemExists: function(itemId) {
-			return this.$el.find('li[data-id=' + itemId + ']').length;
-		},
-
-		/**
-		 * Event handler for when clicking on an item.
-		 */
-		_onClickItem: function(ev) {
-			var $target = $(ev.target);
-			var itemId = $target.closest('li').attr('data-id');
-			if (!_.isUndefined(itemId)) {
-				this.setActiveItem(itemId);
-			}
-			ev.preventDefault();
-		}
-	};
-
-	OCA.Files.Navigation = Navigation;
-
-})();
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/files\/js\/merged-index.json":1570113918,"\/var\/www\/html\/apps\/files\/js\/app.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/file-upload.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/newfilemenu.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/jquery.fileupload.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/jquery-visibility.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/fileinfomodel.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/filesummary.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/breadcrumb.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/filelist.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/search.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/favoritesfilelist.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/recentfilelist.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/tagsplugin.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/gotoplugin.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/favoritesplugin.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/recentplugin.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/detailfileinfoview.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/sidebarpreviewmanager.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/sidebarpreviewtext.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/detailtabview.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/mainfileinfodetailview.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/detailsview.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/fileactions.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/fileactionsmenu.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/files.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/keyboardshortcuts.js":1570113918,"\/var\/www\/html\/apps\/files\/js\/navigation.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/files/merged-index.js.gzip


+ 0 - 491
compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js

@@ -1,491 +0,0 @@
-/*
- * Copyright (c) 2014
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-
-	_.extend(OC.Files.Client, {
-		PROPERTY_SHARE_TYPES:	'{' + OC.Files.Client.NS_OWNCLOUD + '}share-types',
-		PROPERTY_OWNER_DISPLAY_NAME:	'{' + OC.Files.Client.NS_OWNCLOUD + '}owner-display-name'
-	});
-
-	if (!OCA.Sharing) {
-		OCA.Sharing = {};
-	}
-	/**
-	 * @namespace
-	 */
-	OCA.Sharing.Util = {
-		/**
-		 * Initialize the sharing plugin.
-		 *
-		 * Registers the "Share" file action and adds additional
-		 * DOM attributes for the sharing file info.
-		 *
-		 * @param {OCA.Files.FileList} fileList file list to be extended
-		 */
-		attach: function(fileList) {
-			// core sharing is disabled/not loaded
-			if (!OC.Share) {
-				return;
-			}
-			if (fileList.id === 'trashbin' || fileList.id === 'files.public') {
-				return;
-			}
-			var fileActions = fileList.fileActions;
-			var oldCreateRow = fileList._createRow;
-			fileList._createRow = function(fileData) {
-				var tr = oldCreateRow.apply(this, arguments);
-				var sharePermissions = OCA.Sharing.Util.getSharePermissions(fileData);
-				tr.attr('data-share-permissions', sharePermissions);
-				if (fileData.shareOwner) {
-					tr.attr('data-share-owner', fileData.shareOwner);
-					// user should always be able to rename a mount point
-					if (fileData.mountType === 'shared-root') {
-						tr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE);
-					}
-				}
-				if (fileData.recipientsDisplayName) {
-					tr.attr('data-share-recipients', fileData.recipientsDisplayName);
-				}
-				if (fileData.shareTypes) {
-					tr.attr('data-share-types', fileData.shareTypes.join(','));
-				}
-				return tr;
-			};
-
-			var oldElementToFile = fileList.elementToFile;
-			fileList.elementToFile = function($el) {
-				var fileInfo = oldElementToFile.apply(this, arguments);
-				fileInfo.sharePermissions = $el.attr('data-share-permissions') || undefined;
-				fileInfo.shareOwner = $el.attr('data-share-owner') || undefined;
-
-				if( $el.attr('data-share-types')){
-					var shareTypes = $el.attr('data-share-types').split(',');
-					fileInfo.shareTypes = shareTypes;
-				}
-
-				if( $el.attr('data-expiration')){
-					var expirationTimestamp = parseInt($el.attr('data-expiration'));
-					fileInfo.shares = [];
-					fileInfo.shares.push({expiration: expirationTimestamp});
-				}
-
-				fileInfo.recipientsDisplayName = $el.attr('data-share-recipients') || undefined;
-
-				return fileInfo;
-			};
-
-			var oldGetWebdavProperties = fileList._getWebdavProperties;
-			fileList._getWebdavProperties = function() {
-				var props = oldGetWebdavProperties.apply(this, arguments);
-				props.push(OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME);
-				props.push(OC.Files.Client.PROPERTY_SHARE_TYPES);
-				return props;
-			};
-
-			fileList.filesClient.addFileInfoParser(function(response) {
-				var data = {};
-				var props = response.propStat[0].properties;
-				var permissionsProp = props[OC.Files.Client.PROPERTY_PERMISSIONS];
-
-				if (permissionsProp && permissionsProp.indexOf('S') >= 0) {
-					data.shareOwner = props[OC.Files.Client.PROPERTY_OWNER_DISPLAY_NAME];
-				}
-
-				var shareTypesProp = props[OC.Files.Client.PROPERTY_SHARE_TYPES];
-				if (shareTypesProp) {
-					data.shareTypes = _.chain(shareTypesProp).filter(function(xmlvalue) {
-						return (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'share-type');
-					}).map(function(xmlvalue) {
-						return parseInt(xmlvalue.textContent || xmlvalue.text, 10);
-					}).value();
-				}
-
-				return data;
-			});
-
-			// use delegate to catch the case with multiple file lists
-			fileList.$el.on('fileActionsReady', function(ev){
-				var $files = ev.$files;
-
-				_.each($files, function(file) {
-					var $tr = $(file);
-					var shareTypes = $tr.attr('data-share-types') || '';
-					var shareOwner = $tr.attr('data-share-owner');
-					if (shareTypes || shareOwner) {
-						var hasLink = false;
-						var hasShares = false;
-						_.each(shareTypes.split(',') || [], function(shareType) {
-							shareType = parseInt(shareType, 10);
-							if (shareType === OC.Share.SHARE_TYPE_LINK) {
-								hasLink = true;
-							} else if (shareType === OC.Share.SHARE_TYPE_EMAIL) {
-								hasLink = true;
-							} else if (shareType === OC.Share.SHARE_TYPE_USER) {
-								hasShares = true;
-							} else if (shareType === OC.Share.SHARE_TYPE_GROUP) {
-								hasShares = true;
-							} else if (shareType === OC.Share.SHARE_TYPE_REMOTE) {
-								hasShares = true;
-							} else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) {
-								hasShares = true;
-							}
-						});
-						OCA.Sharing.Util._updateFileActionIcon($tr, hasShares, hasLink);
-					}
-				});
-			});
-
-
-			fileList.$el.on('changeDirectory', function() {
-				OCA.Sharing.sharesLoaded = false;
-			});
-
-			fileActions.registerAction({
-				name: 'Share',
-				displayName: '',
-				altText: t('core', 'Share'),
-				mime: 'all',
-				permissions: OC.PERMISSION_ALL,
-				iconClass: 'icon-shared',
-				type: OCA.Files.FileActions.TYPE_INLINE,
-				actionHandler: function(fileName) {
-					fileList.showDetailsView(fileName, 'shareTabView');
-				},
-				render: function(actionSpec, isDefault, context) {
-					var permissions = parseInt(context.$file.attr('data-permissions'), 10);
-					// if no share permissions but share owner exists, still show the link
-					if ((permissions & OC.PERMISSION_SHARE) !== 0 || context.$file.attr('data-share-owner')) {
-						return fileActions._defaultRenderAction.call(fileActions, actionSpec, isDefault, context);
-					}
-					// don't render anything
-					return null;
-				}
-			});
-
-			var shareTab = new OCA.Sharing.ShareTabView('shareTabView', {order: -20});
-			// detect changes and change the matching list entry
-			shareTab.on('sharesChanged', function(shareModel) {
-				var fileInfoModel = shareModel.fileInfoModel;
-				var $tr = fileList.findFileEl(fileInfoModel.get('name'));
-
-				// We count email shares as link share
-				var hasLinkShare = shareModel.hasLinkShare();
-				shareModel.get('shares').forEach(function (share) {
-					if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) {
-						hasLinkShare = true;
-					}
-				});
-
-				OCA.Sharing.Util._updateFileListDataAttributes(fileList, $tr, shareModel);
-				if (!OCA.Sharing.Util._updateFileActionIcon($tr, shareModel.hasUserShares(), hasLinkShare)) {
-					// remove icon, if applicable
-					OC.Share.markFileAsShared($tr, false, false);
-				}
-
-				// FIXME: this is too convoluted. We need to get rid of the above updates
-				// and only ever update the model and let the events take care of rerendering
-				fileInfoModel.set({
-					shareTypes: shareModel.getShareTypes(),
-					// in case markFileAsShared decided to change the icon,
-					// we need to modify the model
-					// (FIXME: yes, this is hacky)
-					icon: $tr.attr('data-icon')
-				});
-			});
-			fileList.registerTabView(shareTab);
-
-			var breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView({shareTab: shareTab});
-			fileList.registerBreadCrumbDetailView(breadCrumbSharingDetailView);
-		},
-
-		/**
-		 * Update file list data attributes
-		 */
-		_updateFileListDataAttributes: function(fileList, $tr, shareModel) {
-			// files app current cannot show recipients on load, so we don't update the
-			// icon when changed for consistency
-			if (fileList.id === 'files') {
-				return;
-			}
-			var recipients = _.pluck(shareModel.get('shares'), 'share_with_displayname');
-			// note: we only update the data attribute because updateIcon()
-			if (recipients.length) {
-				$tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
-			}
-			else {
-				$tr.removeAttr('data-share-recipients');
-			}
-		},
-
-		/**
-		 * Update the file action share icon for the given file
-		 *
-		 * @param $tr file element of the file to update
-		 * @param {bool} hasUserShares true if a user share exists
-		 * @param {bool} hasLinkShare true if a link share exists
-		 *
-		 * @return {bool} true if the icon was set, false otherwise
-		 */
-		_updateFileActionIcon: function($tr, hasUserShares, hasLinkShare) {
-			// if the statuses are loaded already, use them for the icon
-			// (needed when scrolling to the next page)
-			if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
-				OC.Share.markFileAsShared($tr, true, hasLinkShare);
-				return true;
-			}
-			return false;
-		},
-
-		/**
-		 * Formats a recipients array to be displayed.
-		 * The first four recipients will be shown and the
-		 * other ones will be shown as "+x" where "x" is the number of
-		 * remaining recipients.
-		 *
-		 * @param {Array.<String>} recipients recipients array
-		 * @param {int} count optional total recipients count (in case the array was shortened)
-		 * @return {String} formatted recipients display text
-		 */
-		formatRecipients: function(recipients, count) {
-			var maxRecipients = 4;
-			var text;
-			if (!_.isNumber(count)) {
-				count = recipients.length;
-			}
-			// TODO: use natural sort
-			recipients = _.first(recipients, maxRecipients).sort();
-			text = recipients.join(', ');
-			if (count > maxRecipients) {
-				text += ', +' + (count - maxRecipients);
-			}
-			return text;
-		},
-
-		/**
-		 * @param {Array} fileData
-		 * @returns {String}
-		 */
-		getSharePermissions: function(fileData) {
-			var sharePermissions = fileData.permissions;
-			if (fileData.mountType && fileData.mountType === "external-root"){
-				// for external storages we can't use the permissions of the mountpoint
-				// instead we show all permissions and only use the share permissions from the mountpoint to handle resharing
-				sharePermissions = sharePermissions | (OC.PERMISSION_ALL & ~OC.PERMISSION_SHARE);
-			}
-			if (fileData.type === 'file') {
-				// files can't be shared with delete permissions
-				sharePermissions = sharePermissions & ~OC.PERMISSION_DELETE;
-
-				// create permissions don't mean anything for files
-				sharePermissions = sharePermissions & ~OC.PERMISSION_CREATE;
-			}
-			return sharePermissions;
-		}
-	};
-})();
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Sharing.Util);
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* @global Handlebars */
-
-(function() {
-	var TEMPLATE =
-		'<div>' +
-		'<div class="dialogContainer"></div>' +
-		'</div>';
-
-	/**
-	 * @memberof OCA.Sharing
-	 */
-	var ShareTabView = OCA.Files.DetailTabView.extend(
-		/** @lends OCA.Sharing.ShareTabView.prototype */ {
-		id: 'shareTabView',
-		className: 'tab shareTabView',
-
-		template: function(params) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			return this._template(params);
-		},
-
-		getLabel: function() {
-			return t('files_sharing', 'Sharing');
-		},
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			var self = this;
-			if (this._dialog) {
-				// remove/destroy older instance
-				this._dialog.model.off();
-				this._dialog.remove();
-				this._dialog = null;
-			}
-
-			if (this.model) {
-				this.$el.html(this.template());
-
-				if (_.isUndefined(this.model.get('sharePermissions'))) {
-					this.model.set('sharePermissions', OCA.Sharing.Util.getSharePermissions(this.model.attributes));
-				}
-
-				// TODO: the model should read these directly off the passed fileInfoModel
-				var attributes = {
-					itemType: this.model.isDirectory() ? 'folder' : 'file',
-				   	itemSource: this.model.get('id'),
-					possiblePermissions: this.model.get('sharePermissions')
-				};
-				var configModel = new OC.Share.ShareConfigModel();
-				var shareModel = new OC.Share.ShareItemModel(attributes, {
-					configModel: configModel,
-					fileInfoModel: this.model
-				});
-				this._dialog = new OC.Share.ShareDialogView({
-					configModel: configModel,
-					model: shareModel
-				});
-				this.$el.find('.dialogContainer').append(this._dialog.$el);
-				this._dialog.render();
-				this._dialog.model.fetch();
-				this._dialog.model.on('change', function() {
-					self.trigger('sharesChanged', shareModel);
-				});
-			} else {
-				this.$el.empty();
-				// TODO: render placeholder text?
-			}
-		}
-	});
-
-	OCA.Sharing.ShareTabView = ShareTabView;
-})();
-
-
-
-/* global Handlebars, OC */
-
-/**
- * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-(function() {
-	'use strict';
-
-	var BreadCrumbView = OC.Backbone.View.extend({
-		tagName: 'span',
-		events: {
-			click: '_onClick'
-		},
-		_dirInfo: undefined,
-
-		/** @type OCA.Sharing.ShareTabView */
-		_shareTab: undefined,
-
-		initialize: function(options) {
-			this._shareTab = options.shareTab;
-		},
-
-		render: function(data) {
-			this._dirInfo = data.dirInfo || null;
-
-			if (this._dirInfo !== null && (this._dirInfo.path !== '/' || this._dirInfo.name !== '')) {
-				var isShared = data.dirInfo && data.dirInfo.shareTypes && data.dirInfo.shareTypes.length > 0;
-				this.$el.removeClass('shared icon-public icon-shared');
-				if (isShared) {
-					this.$el.addClass('shared');
-					if (data.dirInfo.shareTypes.indexOf(OC.Share.SHARE_TYPE_LINK) !== -1) {
-						this.$el.addClass('icon-public');
-					} else {
-						this.$el.addClass('icon-shared');
-					}
-				} else {
-					this.$el.addClass('icon-shared');
-				}
-				this.$el.show();
-				this.delegateEvents();
-			} else {
-				this.$el.removeClass('shared icon-public icon-shared');
-				this.$el.hide();
-			}
-
-			return this;
-		},
-		_onClick: function(e) {
-			e.preventDefault();
-
-			var fileInfoModel = new OCA.Files.FileInfoModel(this._dirInfo);
-			var self = this;
-			fileInfoModel.on('change', function() {
-				self.render({
-					dirInfo: self._dirInfo
-				});
-			});
-			this._shareTab.on('sharesChanged', function(shareModel) {
-				var shareTypes = [];
-				var shares = shareModel.getSharesWithCurrentItem();
-
-				for(var i = 0; i < shares.length; i++) {
-					if (shareTypes.indexOf(shares[i].share_type) === -1) {
-						shareTypes.push(shares[i].share_type);
-					}
-				}
-
-				if (shareModel.hasLinkShare()) {
-					shareTypes.push(OC.Share.SHARE_TYPE_LINK);
-				}
-
-				// Since the dirInfo isn't updated we need to do this dark hackery
-				self._dirInfo.shareTypes = shareTypes;
-
-				self.render({
-					dirInfo: self._dirInfo
-				});
-			});
-			OCA.Files.App.fileList.showDetailsView(fileInfoModel, 'shareTabView');
-		}
-	});
-
-	OCA.Sharing.ShareBreadCrumbView = BreadCrumbView;
-})();
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/files_sharing\/js\/additionalScripts.json":1570113918,"\/var\/www\/html\/apps\/files_sharing\/js\/share.js":1570113918,"\/var\/www\/html\/apps\/files_sharing\/js\/sharetabview.js":1570113918,"\/var\/www\/html\/apps\/files_sharing\/js\/sharebreadcrumbview.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/files_sharing/additionalScripts.js.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 6789
compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/files_texteditor\/js\/merged.json":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/js\/editor.js":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/js\/sidebarpreview.js":1570113918,"\/var\/www\/html\/apps\/files_texteditor\/js\/core\/vendor\/ace-builds\/src-noconflict\/ace.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/files_texteditor/merged.js.gzip


+ 0 - 508
compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js

@@ -1,508 +0,0 @@
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	/**
-	 * @memberof OCA.Versions
-	 */
-	var VersionModel = OC.Backbone.Model.extend({
-
-		/**
-		 * Restores the original file to this revision
-		 */
-		revert: function(options) {
-			options = options ? _.clone(options) : {};
-			var model = this;
-			var file = this.getFullPath();
-			var revision = this.get('timestamp');
-
-			$.ajax({
-				type: 'GET',
-				url: OC.generateUrl('/apps/files_versions/ajax/rollbackVersion.php'),
-				dataType: 'json',
-				data: {
-					file: file,
-					revision: revision
-				},
-				success: function(response) {
-					if (response.status === 'error') {
-						if (options.error) {
-							options.error.call(options.context, model, response, options);
-						}
-						model.trigger('error', model, response, options);
-					} else {
-						if (options.success) {
-							options.success.call(options.context, model, response, options);
-						}
-						model.trigger('revert', model, response, options);
-					}
-				}
-			});
-		},
-
-		getFullPath: function() {
-			return this.get('fullPath');
-		},
-
-		getPreviewUrl: function() {
-			var url = OC.generateUrl('/apps/files_versions/preview');
-			var params = {
-				file: this.get('fullPath'),
-				version: this.get('timestamp')
-			};
-			return url + '?' + OC.buildQueryString(params);
-		},
-
-		getDownloadUrl: function() {
-			var url = OC.generateUrl('/apps/files_versions/download.php');
-			var params = {
-				file: this.get('fullPath'),
-				revision: this.get('timestamp')
-			};
-			return url + '?' + OC.buildQueryString(params);
-		}
-	});
-
-	OCA.Versions = OCA.Versions || {};
-
-	OCA.Versions.VersionModel = VersionModel;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	/**
-	 * @memberof OCA.Versions
-	 */
-	var VersionCollection = OC.Backbone.Collection.extend({
-		model: OCA.Versions.VersionModel,
-
-		/**
-		 * @var OCA.Files.FileInfoModel
-		 */
-		_fileInfo: null,
-
-		_endReached: false,
-		_currentIndex: 0,
-
-		url: function() {
-			var url = OC.generateUrl('/apps/files_versions/ajax/getVersions.php');
-			var query = {
-				source: this._fileInfo.getFullPath(),
-				start: this._currentIndex
-			};
-			return url + '?' + OC.buildQueryString(query);
-		},
-
-		setFileInfo: function(fileInfo) {
-			this._fileInfo = fileInfo;
-			// reset
-			this._endReached = false;
-			this._currentIndex = 0;
-		},
-
-		getFileInfo: function() {
-			return this._fileInfo;
-		},
-
-		hasMoreResults: function() {
-			return !this._endReached;
-		},
-
-		fetch: function(options) {
-			if (!options || options.remove) {
-				this._currentIndex = 0;
-			}
-			return OC.Backbone.Collection.prototype.fetch.apply(this, arguments);
-		},
-
-		/**
-		 * Fetch the next set of results
-		 */
-		fetchNext: function() {
-			if (!this.hasMoreResults()) {
-				return null;
-			}
-			if (this._currentIndex === 0) {
-				return this.fetch();
-			}
-			return this.fetch({remove: false});
-		},
-
-		reset: function() {
-			this._currentIndex = 0;
-			OC.Backbone.Collection.prototype.reset.apply(this, arguments);
-		},
-
-		parse: function(result) {
-			var fullPath = this._fileInfo.getFullPath();
-			var results = _.map(result.data.versions, function(version) {
-				var revision = parseInt(version.version, 10);
-				return {
-					id: revision,
-					name: version.name,
-					fullPath: fullPath,
-					timestamp: revision,
-					size: version.size,
-					mimetype: version.mimetype
-				};
-			});
-			this._endReached = result.data.endReached;
-			this._currentIndex += results.length;
-			return results;
-		}
-	});
-
-	OCA.Versions = OCA.Versions || {};
-
-	OCA.Versions.VersionCollection = VersionCollection;
-})();
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-/* @global Handlebars */
-
-(function() {
-	var TEMPLATE_ITEM =
-		'<li data-revision="{{timestamp}}">' +
-		'<div>' +
-		'<div class="preview-container">' +
-		'<img class="preview" src="{{previewUrl}}" width="44" height="44"/>' +
-		'</div>' +
-		'<div class="version-container">' +
-		'<div>' +
-		'<a href="{{downloadUrl}}" class="downloadVersion"><img src="{{downloadIconUrl}}" />' +
-		'<span class="versiondate has-tooltip live-relative-timestamp" data-timestamp="{{millisecondsTimestamp}}" title="{{formattedTimestamp}}">{{relativeTimestamp}}</span>' +
-		'</a>' +
-		'</div>' +
-		'{{#hasDetails}}' +
-		'<div class="version-details">' +
-		'<span class="size has-tooltip" title="{{altSize}}">{{humanReadableSize}}</span>' +
-		'</div>' +
-		'{{/hasDetails}}' +
-		'</div>' +
-		'{{#canRevert}}' +
-		'<a href="#" class="revertVersion" title="{{revertLabel}}"><img src="{{revertIconUrl}}" /></a>' +
-		'{{/canRevert}}' +
-		'</div>' +
-		'</li>';
-
-	var TEMPLATE =
-		'<ul class="versions"></ul>' +
-		'<div class="clear-float"></div>' +
-		'<div class="empty hidden">' +
-		'<div class="emptycontent">' +
-		'<div class="icon-history"></div>' +
-		'<p>{{emptyResultLabel}}</p>' +
-		'</div></div>' +
-		'<input type="button" class="showMoreVersions hidden" value="{{moreVersionsLabel}}"' +
-		' name="show-more-versions" id="show-more-versions" />' +
-		'<div class="loading hidden" style="height: 50px"></div>';
-
-	/**
-	 * @memberof OCA.Versions
-	 */
-	var VersionsTabView = OCA.Files.DetailTabView.extend(
-		/** @lends OCA.Versions.VersionsTabView.prototype */ {
-		id: 'versionsTabView',
-		className: 'tab versionsTabView',
-
-		_template: null,
-
-		$versionsContainer: null,
-
-		events: {
-			'click .revertVersion': '_onClickRevertVersion',
-			'click .showMoreVersions': '_onClickShowMoreVersions'
-		},
-
-		initialize: function() {
-			OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
-			this.collection = new OCA.Versions.VersionCollection();
-			this.collection.on('request', this._onRequest, this);
-			this.collection.on('sync', this._onEndRequest, this);
-			this.collection.on('update', this._onUpdate, this);
-			this.collection.on('error', this._onError, this);
-			this.collection.on('add', this._onAddModel, this);
-		},
-
-		getLabel: function() {
-			return t('files_versions', 'Versions');
-		},
-
-		nextPage: function() {
-			if (this._loading || !this.collection.hasMoreResults()) {
-				return;
-			}
-
-			if (this.collection.getFileInfo() && this.collection.getFileInfo().isDirectory()) {
-				return;
-			}
-			this.collection.fetchNext();
-		},
-
-		_onClickShowMoreVersions: function(ev) {
-			ev.preventDefault();
-			this.nextPage();
-		},
-
-		_onClickRevertVersion: function(ev) {
-			var self = this;
-			var $target = $(ev.target);
-			var fileInfoModel = this.collection.getFileInfo();
-			var revision;
-			if (!$target.is('li')) {
-				$target = $target.closest('li');
-			}
-
-			ev.preventDefault();
-			revision = $target.attr('data-revision');
-
-			this.$el.find('.versions, .showMoreVersions').addClass('hidden');
-
-			var versionModel = this.collection.get(revision);
-			versionModel.revert({
-				success: function() {
-					// reset and re-fetch the updated collection
-					self.$versionsContainer.empty();
-					self.collection.setFileInfo(fileInfoModel);
-					self.collection.reset([], {silent: true});
-					self.collection.fetchNext();
-
-					self.$el.find('.versions').removeClass('hidden');
-
-					// update original model
-					fileInfoModel.trigger('busy', fileInfoModel, false);
-					fileInfoModel.set({
-						size: versionModel.get('size'),
-						mtime: versionModel.get('timestamp') * 1000,
-						// temp dummy, until we can do a PROPFIND
-						etag: versionModel.get('id') + versionModel.get('timestamp')
-					});
-				},
-
-				error: function() {
-					fileInfoModel.trigger('busy', fileInfoModel, false);
-					self.$el.find('.versions').removeClass('hidden');
-					self._toggleLoading(false);
-					OC.Notification.show(t('files_version', 'Failed to revert {file} to revision {timestamp}.', 
-						{
-							file: versionModel.getFullPath(),
-							timestamp: OC.Util.formatDate(versionModel.get('timestamp') * 1000)
-						}),
-						{
-							type: 'error'
-						}
-					);
-				}
-			});
-
-			// spinner
-			this._toggleLoading(true);
-			fileInfoModel.trigger('busy', fileInfoModel, true);
-		},
-
-		_toggleLoading: function(state) {
-			this._loading = state;
-			this.$el.find('.loading').toggleClass('hidden', !state);
-		},
-
-		_onRequest: function() {
-			this._toggleLoading(true);
-			this.$el.find('.showMoreVersions').addClass('hidden');
-		},
-
-		_onEndRequest: function() {
-			this._toggleLoading(false);
-			this.$el.find('.empty').toggleClass('hidden', !!this.collection.length);
-			this.$el.find('.showMoreVersions').toggleClass('hidden', !this.collection.hasMoreResults());
-		},
-
-		_onAddModel: function(model) {
-			var $el = $(this.itemTemplate(this._formatItem(model)));
-			this.$versionsContainer.append($el);
-
-			var preview = $el.find('.preview')[0];
-			this._lazyLoadPreview({
-				url: model.getPreviewUrl(),
-				mime: model.get('mimetype'),
-				callback: function(url) {
-					preview.src = url;
-				}
-			});
-			$el.find('.has-tooltip').tooltip();
-		},
-
-		template: function(data) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-
-			return this._template(data);
-		},
-
-		itemTemplate: function(data) {
-			if (!this._itemTemplate) {
-				this._itemTemplate = Handlebars.compile(TEMPLATE_ITEM);
-			}
-
-			return this._itemTemplate(data);
-		},
-
-		setFileInfo: function(fileInfo) {
-			if (fileInfo) {
-				this.render();
-				this.collection.setFileInfo(fileInfo);
-				this.collection.reset([], {silent: true});
-				this.nextPage();
-			} else {
-				this.render();
-				this.collection.reset();
-			}
-		},
-
-		_formatItem: function(version) {
-			var timestamp = version.get('timestamp') * 1000;
-			var size = version.has('size') ? version.get('size') : 0;
-			return _.extend({
-				millisecondsTimestamp: timestamp,
-				formattedTimestamp: OC.Util.formatDate(timestamp),
-				relativeTimestamp: OC.Util.relativeModifiedDate(timestamp),
-				humanReadableSize: OC.Util.humanFileSize(size, true),
-				altSize: n('files', '%n byte', '%n bytes', size),
-				hasDetails: version.has('size'),
-				downloadUrl: version.getDownloadUrl(),
-				downloadIconUrl: OC.imagePath('core', 'actions/download'),
-				revertIconUrl: OC.imagePath('core', 'actions/history'),
-				revertLabel: t('files_versions', 'Restore'),
-				canRevert: (this.collection.getFileInfo().get('permissions') & OC.PERMISSION_UPDATE) !== 0
-			}, version.attributes);
-		},
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			this.$el.html(this.template({
-				emptyResultLabel: t('files_versions', 'No earlier versions available'),
-				moreVersionsLabel: t('files_versions', 'More versions …')
-			}));
-			this.$el.find('.has-tooltip').tooltip();
-			this.$versionsContainer = this.$el.find('ul.versions');
-			this.delegateEvents();
-		},
-
-		/**
-		 * Returns true for files, false for folders.
-		 *
-		 * @return {bool} true for files, false for folders
-		 */
-		canDisplay: function(fileInfo) {
-			if (!fileInfo) {
-				return false;
-			}
-			return !fileInfo.isDirectory();
-		},
-
-		/**
-		 * Lazy load a file's preview.
-		 *
-		 * @param path path of the file
-		 * @param mime mime type
-		 * @param callback callback function to call when the image was loaded
-		 * @param etag file etag (for caching)
-		 */
-		_lazyLoadPreview : function(options) {
-			var url = options.url;
-			var mime = options.mime;
-			var ready = options.callback;
-
-			// get mime icon url
-			var iconURL = OC.MimeType.getIconUrl(mime);
-			ready(iconURL); // set mimeicon URL
-
-			var img = new Image();
-			img.onload = function(){
-				// if loading the preview image failed (no preview for the mimetype) then img.width will < 5
-				if (img.width > 5) {
-					ready(url, img);
-				} else if (options.error) {
-					options.error();
-				}
-			};
-			if (options.error) {
-				img.onerror = options.error;
-			}
-			img.src = url;
-		}
-	});
-
-	OCA.Versions = OCA.Versions || {};
-
-	OCA.Versions.VersionsTabView = VersionsTabView;
-})();
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	OCA.Versions = OCA.Versions || {};
-
-	/**
-	 * @namespace
-	 */
-	OCA.Versions.Util = {
-		/**
-		 * Initialize the versions plugin.
-		 *
-		 * @param {OCA.Files.FileList} fileList file list to be extended
-		 */
-		attach: function(fileList) {
-			if (fileList.id === 'trashbin' || fileList.id === 'files.public') {
-				return;
-			}
-
-			fileList.registerTabView(new OCA.Versions.VersionsTabView('versionsTabView', {order: -10}));
-		}
-	};
-})();
-
-OC.Plugins.register('OCA.Files.FileList', OCA.Versions.Util);
-
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/files_versions\/js\/merged.json":1570113918,"\/var\/www\/html\/apps\/files_versions\/js\/versionmodel.js":1570113918,"\/var\/www\/html\/apps\/files_versions\/js\/versioncollection.js":1570113918,"\/var\/www\/html\/apps\/files_versions\/js\/versionstabview.js":1570113918,"\/var\/www\/html\/apps\/files_versions\/js\/filesplugin.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/files_versions/merged.js.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/gallery\/js\/scripts-for-file-app.json":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/vendor\/bigshot\/bigshot-compressed.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/vendor\/dompurify\/src\/purify.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/galleryutility.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/galleryfileaction.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/slideshow.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/slideshowcontrols.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/slideshowzoomablepreview.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/gallerybutton.js":1570113918,"\/var\/www\/html\/apps\/gallery\/js\/vendor\/nextcloud\/share.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/gallery/scripts-for-file-app.js.gzip


+ 0 - 734
compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js

@@ -1,734 +0,0 @@
-/**
- * @copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- * @copyright (c) 2015 Tom Needham <tom@owncloud.com>
- *
- * @author Tom Needham <tom@owncloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- */
-
-(function() {
-
-	if (!OCA.Notifications) {
-		OCA.Notifications = {};
-	}
-
-	OCA.Notifications = {
-		/** @type {number} */
-		pollInterval: 30000, // milliseconds
-		/** @type {number|null} */
-		interval: null,
-
-		/** @type {OCA.Notifications.Notification[]|{}} */
-		notifications: {},
-
-		/** @type {Object} */
-		$button: null,
-		/** @type {Object} */
-		$container: null,
-		/** @type {Object} */
-		$notifications: null,
-
-		/** @type {Function} */
-		notificationTemplate: null,
-
-		/** @type {string} */
-		_containerTemplate: '' +
-		'<div class="notifications hidden">' +
-		'  <div class="notifications-button menutoggle">' +
-		'    <img class="svg" alt="" title="' + t('notifications', 'Notifications') + '"' +
-		'      src="' + OC.imagePath('notifications', 'notifications') + '">' +
-		'  </div>' +
-		'  <div class="notification-container">' +
-		'    <div class="notification-wrapper"></div>' +
-		'    <div class="emptycontent">' +
-		'      <h2>' + t('notifications', 'No notifications') + '</h2>' +
-		'    </div>' +
-		'  </div>' +
-		'</div>',
-
-		/** @type {string} */
-		_notificationTemplate: '' +
-		'<div class="notification" data-id="{{notification_id}}" data-timestamp="{{timestamp}}">' +
-		'  <span class="notification-time has-tooltip live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{absoluteDate}}">{{relativeDate}}</span>' +
-		'  {{#if link}}' +
-		'    <div class="notification-subject">' +
-		'      <a href="{{link}}" class="full-subject-link">' +
-		'        {{#if icon}}<span class="image"><img src="{{icon}}" class="notification-icon"></span>{{/if}}' +
-		'        <span class="text">{{{subject}}}</span>' +
-		'      </a>' +
-		'    </div>' +
-		'  {{else}}' +
-		'    <div class="notification-subject">' +
-		'        {{#if icon}}<span class="image"><img src="{{icon}}" class="notification-icon"></span>{{/if}}' +
-		'        <span class="text">{{{subject}}}</span>' +
-		'    </div>' +
-		'  {{/if}}' +
-		'  <div class="notification-message">{{{message}}}</div>' +
-		'  <div class="notification-full-message hidden">{{{full_message}}}</div>' +
-		'  <div class="notification-actions">' +
-		'    {{#each actions}}' +
-		'      <button class="action-button pull-right{{#if this.primary}} primary{{/if}}" data-type="{{this.type}}" ' +
-		'data-href="{{this.link}}">{{this.label}}</button>' +
-		'    {{/each}}' +
-		'  </div>' +
-		'  <div style="display: none;" class="notification-delete">' +
-		'    <div class="icon icon-close svg" title="' + t('notifications', 'Dismiss') + '"></div>' +
-		'  </div>' +
-		'</div>',
-
-		/**
-		 * Initialise the app
-		 */
-		initialise: function() {
-			// Setup elements
-			var compiledTemplate = Handlebars.compile(this._containerTemplate);
-			this.notificationTemplate = Handlebars.compile(this._notificationTemplate);
-			this.$notifications = $(compiledTemplate());
-			this.$button = this.$notifications.find('.notifications-button');
-			this.$container = this.$notifications.find('.notification-container');
-
-			// Add to the UI
-			$('form.searchbox').after(this.$notifications);
-
-			// Initial call to the notification endpoint
-			this.initialFetch();
-
-			// Bind the button click event
-			OC.registerMenu(this.$button, this.$container);
-			this.$button.on('click', _.bind(this._onNotificationsButtonClick, this));
-
-			this.$container.on('click', '.action-button', _.bind(this._onClickAction, this));
-			this.$container.on('click', '.notification-delete', _.bind(this._onClickDismissNotification, this));
-
-			// Setup the background checker
-			this.interval = setInterval(_.bind(this.backgroundFetch, this), this.pollInterval);
-		},
-
-		/**
-		 * Handles the notification dismiss click event
-		 * @param {Event} event
-		 */
-		_onClickDismissNotification: function(event) {
-			event.preventDefault();
-			var self = this,
-				$target = $(event.target),
-				$notification = $target.closest('.notification'),
-				id = $notification.attr('data-id');
-
-			$notification.fadeOut(OC.menuSpeed);
-
-			$.ajax({
-				url: OC.linkToOCS('apps/notifications/api/v2', 2) + 'notifications/' + id,
-				type: 'DELETE',
-				beforeSend: function (request) {
-					request.setRequestHeader('Accept', 'application/json');
-				},
-				success: function() {
-					self._removeNotification(id);
-				},
-				error: function() {
-					$notification.fadeIn(OC.menuSpeed);
-					OC.Notification.showTemporary('Failed to perform action');
-				}
-			});
-		},
-
-		/**
-		 * Handles the notification action click event
-		 * @param {Event} event
-		 */
-		_onClickAction: function(event) {
-			event.preventDefault();
-			var self = this;
-			var $target = $(event.target);
-			var $notification = $target.closest('.notification');
-			var actionType = $target.attr('data-type') || 'GET';
-			var actionUrl = $target.attr('data-href');
-
-			$notification.fadeOut(OC.menuSpeed);
-
-			$.ajax({
-				url: actionUrl,
-				type: actionType,
-				success: function(data) {
-					$('body').trigger(new $.Event('OCA.Notification.Action', {
-						notification: self.notifications[$notification.attr('data-id')],
-						action: {
-							url: actionUrl,
-							type: actionType
-						}
-					}));
-					self._removeNotification($notification.attr('data-id'));
-				},
-				error: function() {
-					$notification.fadeIn(OC.menuSpeed);
-					OC.Notification.showTemporary('Failed to perform action');
-				}
-			});
-		},
-
-		/**
-		 * Remove a notification from the collection and the UI
-		 * @param {Number} id
-		 */
-		_removeNotification: function(id) {
-			var $notification = this.notifications[id].getElement();
-			delete this.notifications[id];
-
-			$notification.remove();
-			if (this.numNotifications() === 0) {
-				this._onHaveNoNotifications();
-			}
-		},
-
-		/**
-		 * Handles the notification button click event
-		 */
-		_onNotificationsButtonClick: function() {
-			// Show a popup
-			OC.showMenu(null, this.$container);
-		},
-
-		/**
-		 * Initial fetch handler
-		 */
-		initialFetch: function() {
-			var self = this;
-
-			this._fetch(
-				function(data) {
-					// Fill Array
-					_.each(data, function(notification) {
-						var n = new self.Notification(notification);
-						self.notifications[n.getId()] = n;
-						self._addToUI(n);
-					});
-
-					// Check if we have any, and notify the UI
-					if (self.numNotifications() !== 0) {
-						self._onHaveNotifications();
-					} else {
-						self._onHaveNoNotifications();
-					}
-				},
-				_.bind(self._onFetchError, self)
-			);
-		},
-
-		/**
-		 * Background fetch handler
-		 */
-		backgroundFetch: function() {
-			var self = this;
-
-			this._fetch(
-				function(data) {
-					var inJson = [],
-						oldNum = self.numNotifications();
-
-					_.each(data, function(notification) {
-						var n = new self.Notification(notification);
-						inJson.push(n.getId());
-						if (!self.getNotification(n.getId())) {
-							// New notification!
-							self._onNewNotification(n);
-						}
-					});
-
-					_.each(self.getNotifications(), function(n) {
-						if (inJson.indexOf(n.getId()) === -1) {
-							// Not in JSON, remove from UI
-							self._onRemoveNotification(n);
-						}
-					});
-
-					// Now check if we suddenly have notifs, or now none
-					if (oldNum === 0 && self.numNotifications() !== 0) {
-						// We now have some!
-						self._onHaveNotifications();
-					} else if (oldNum !== 0 && self.numNotifications() === 0) {
-						// Now we have none
-						self._onHaveNoNotifications();
-					}
-				},
-				_.bind(self._onFetchError, self)
-			);
-		},
-
-		/**
-		 * Handles errors when requesting the notifications
-		 * @param {XMLHttpRequest} xhr
-		 */
-		_onFetchError: function(xhr) {
-			if (xhr.status === 503) {
-				// 503 - Maintenance mode
-				console.debug('Shutting down notifications: instance is in maintenance mode.');
-			} else if (xhr.status === 404) {
-				// 404 - App disabled
-				console.debug('Shutting down notifications: app is disabled.');
-			} else {
-				console.error('Shutting down notifications: [' + xhr.status + '] ' + xhr.statusText);
-			}
-			this._shutDownNotifications();
-		},
-
-		/**
-		 * Handles removing the Notification from the UI when no longer in JSON
-		 * @param {OCA.Notifications.Notification} notification
-		 */
-		_onRemoveNotification: function(notification) {
-			notification.getElement().remove();
-			delete this.notifications[notification.getId()];
-		},
-
-		/**
-		 * Handle new notification received
-		 * @param {OCA.Notifications.Notification} notification
-		 */
-		_onNewNotification: function(notification) {
-			var self = this;
-			// Add it to the array
-			this.notifications[notification.getId()] = notification;
-			// Add to the UI
-			this._addToUI(notification);
-
-			// Trigger browsers web notification
-			// https://github.com/owncloud/notifications/issues/1
-			if ("Notification" in window) {
-				if (Notification.permission === "granted") {
-					// If it's okay let's create a notification
-					this._createWebNotification(notification);
-				}
-
-				// Otherwise, we need to ask the user for permission
-				else if (Notification.permission !== 'denied') {
-					Notification.requestPermission(function (permission) {
-						// If the user accepts, let's create a notification
-						if (permission === "granted") {
-							self._createWebNotification(notification);
-						}
-					});
-				}
-			}
-		},
-
-		/**
-		 * Create a browser notification
-		 *
-		 * @see https://developer.mozilla.org/en/docs/Web/API/notification
-		 * @param {OCA.Notifications.Notification} notification
-		 */
-		_createWebNotification: function (notification) {
-			var n = new Notification(notification.getPlainSubject(), {
-				title: notification.getPlainSubject(),
-				lang: OC.getLocale(),
-				body: notification.getMessage(),
-				icon: notification.getIcon(),
-				tag: notification.getId()
-			});
-
-			if (notification.getLink()) {
-				n.onclick = function(event) {
-					event.preventDefault();
-					window.location.href = notification.getLink();
-				}
-			}
-
-			setTimeout(n.close.bind(n), 5000);
-		},
-
-		/**
-		 * The app was disabled or has no notifiers, so we can stop polling
-		 * And hide the UI as well
-		 */
-		_shutDownNotifications: function() {
-			window.clearInterval(this.interval);
-			this.$notifications.addClass('hidden');
-		},
-
-		/**
-		 * Adds the notification to the UI
-		 * @param {OCA.Notifications.Notification} notification
-		 */
-		_addToUI: function(notification) {
-			var $element = $(notification.renderElement(this.notificationTemplate));
-
-			$element.find('.avatar').each(function() {
-				var element = $(this);
-				if (element.data('user-display-name')) {
-					element.avatar(element.data('user'), 21, undefined, false, undefined, element.data('user-display-name'));
-				} else {
-					element.avatar(element.data('user'), 21);
-				}
-			});
-
-			$element.find('.avatar-name-wrapper').each(function() {
-				var element = $(this);
-				var avatar = element.find('.avatar');
-				var label = element.find('strong');
-
-				$.merge(avatar, label).contactsMenu(element.data('user'), 0, element);
-			});
-
-			$element.find('.has-tooltip').tooltip({
-				placement: 'bottom'
-			});
-
-			$element.find('.notification-message').on('click', function() {
-				var $fullMessage = $(this).parent().find('.notification-full-message');
-				$(this).addClass('hidden');
-				$fullMessage.removeClass('hidden');
-
-			});
-
-			this.$container.find('.notification-wrapper').prepend($element);
-		},
-
-		/**
-		 * Handle event when we have notifications (and didnt before)
-		 */
-		_onHaveNotifications: function() {
-			// Add the button, title, etc
-			var icon;
-			if (OCA.Theming && OCA.Theming.inverted) {
-				icon = 'notifications-new-dark';
-			} else {
-				icon = 'notifications-new';
-			}
-			this.$button.addClass('hasNotifications');
-			this.$button.find('img').attr('src', OC.imagePath('notifications', icon))
-				.animate({opacity: 0.6}, 600)
-				.animate({opacity: 1}, 600)
-				.animate({opacity: 0.6}, 600)
-				.animate({opacity: 1}, 600);
-			this.$container.find('.emptycontent').addClass('hidden');
-
-			this.$notifications.removeClass('hidden');
-		},
-
-		/**
-		 * Handle when all dismissed
-		 */
-		_onHaveNoNotifications: function() {
-			// Remove the border
-			this.$button.removeClass('hasNotifications');
-			this.$container.find('.emptycontent').removeClass('hidden');
-			this.$button.find('img').attr('src', OC.imagePath('notifications', 'notifications'));
-
-			this.$notifications.addClass('hidden');
-		},
-
-		/**
-		 * Performs the AJAX request to retrieve the notifications
-		 * @param {Function} success
-		 * @param {Function} failure
-		 */
-		_fetch: function(success, failure) {
-			var self = this;
-			var request = $.ajax({
-				url: OC.linkToOCS('apps/notifications/api/v2', 2) + 'notifications',
-				type: 'GET',
-				beforeSend: function (request) {
-					request.setRequestHeader('Accept', 'application/json');
-				}
-			});
-
-			request.done(function(data, statusText, xhr) {
-				if (xhr.status === 204) {
-					// 204 No Content - Intercept when no notifiers are there.
-					self._shutDownNotifications();
-				} else if (!_.isUndefined(data) && !_.isUndefined(data.ocs) && !_.isUndefined(data.ocs.data) && _.isArray(data.ocs.data)) {
-					success(data.ocs.data, statusText, xhr);
-				} else {
-					console.debug("data.ocs.data is undefined or not an array");
-				}
-			});
-			request.fail(failure);
-		},
-
-		/**
-		 * Retrieves a notification object by id
-		 * @param {int} id
-		 * @return {OCA.Notifications.Notification|boolean}
-		 */
-		getNotification: function(id) {
-			if (!_.isUndefined(this.notifications[id])) {
-				return this.notifications[id];
-			} else {
-				return false;
-			}
-		},
-
-		/**
-		 * Returns all notification objects
-		 * @return {OCA.Notifications.Notification[]}
-		 */
-		getNotifications: function() {
-			return this.notifications;
-		},
-
-		/**
-		 * Returns how many notifications in the UI
-		 * @return {int}
-		 */
-		numNotifications: function() {
-			return _.keys(this.notifications).length;
-		}
-
-	};
-})();
-
-$(document).ready(function () {
-	OCA.Notifications.initialise();
-});
-
-
-/**
- * @copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- * @copyright (c) 2015 Tom Needham <tom@owncloud.com>
- *
- * @author Tom Needham <tom@owncloud.com>
- * @author Joas Schilling <coding@schilljs.com>
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- */
-
-(function() {
-
-	/**
-	 * Initialise the notification
-	 *
-	 * @param {Object} data
-	 * @param {int} data.notification_id
-	 * @param {string} data.app
-	 * @param {string} data.user
-	 * @param {string} data.datetime
-	 * @param {string} data.object_type
-	 * @param {string} data.object_id
-	 * @param {string} data.subject
-	 * @param {string} data.subjectRich
-	 * @param {Object[]} data.subjectRichParameters
-	 * @param {string} data.message
-	 * @param {string} data.link
-	 * @param {string} data.icon
-	 * @param {Object[]} data.actions
-	 */
-	OCA.Notifications.Notification = function(data) {
-		this.data = data;
-	};
-
-	OCA.Notifications.Notification.prototype = {
-		getId: function() {
-			return this.data.notification_id;
-		},
-
-		getApp: function() {
-			return this.data.app;
-		},
-
-		getUser: function() {
-			return this.data.user;
-		},
-
-		getTimestamp: function() {
-			if (_.isUndefined(this.data.timestamp)) {
-				this.data.timestamp = moment(this.data.datetime).format('X') * 1000;
-			}
-
-			return this.data.timestamp;
-		},
-
-		getObjectType: function() {
-			return this.data.object_type;
-		},
-
-		getObjectId: function() {
-			return this.data.object_id;
-		},
-
-		getSubject: function() {
-			if (this.data.subjectRich.length !== 0) {
-				return OCA.Notifications.RichObjectStringParser.parseMessage(
-					this.data.subjectRich,
-					this.data.subjectRichParameters
-				);
-			}
-
-			return this.getPlainSubject();
-		},
-
-		getPlainSubject: function() {
-			return this.data.subject;
-		},
-
-		getMessage: function() {
-			var message = this.data.message;
-
-			/**
-			 * Trim on word end after 180 chars or hard 200 chars
-			 */
-			if (message.length > 200) {
-				var spacePosition = message.indexOf(' ', 180);
-				if (spacePosition !== -1 && spacePosition <= 200) {
-					message = message.substring(0, spacePosition);
-				} else {
-					message = message.substring(0, 200);
-				}
-				message += '…';
-			}
-
-			return message.replace(new RegExp("\n", 'g'), ' ');
-		},
-
-		getLink: function() {
-			if (this.getSubject().indexOf('<a ') === -1) {
-				return this.data.link;
-			}
-			return '';
-		},
-
-		getIcon: function() {
-			return this.data.icon;
-		},
-
-		getActions: function() {
-			return this.data.actions;
-		},
-
-		getElement: function() {
-			return $('div.notification[data-id=' + parseInt(this.getId(), 10) + ']');
-		},
-
-		/**
-		 * Generates the HTML for the notification
-		 * @param {Function} template
-		 */
-		renderElement: function(template) {
-			var temp = _.extend({}, this.data);
-			return template(_.extend(temp, {
-				subject: this.getSubject(),
-				link: this.getLink(),
-				message: this.getMessage(),
-				full_message: this.data.message,
-				timestamp: this.getTimestamp(),
-				relativeDate: OC.Util.relativeModifiedDate(this.getTimestamp()),
-				absoluteDate: OC.Util.formatDate(this.getTimestamp())
-			}));
-		}
-	};
-
-})();
-
-
-/**
- * @copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- *
- * @author Joas Schilling <coding@schilljs.com>
- *
- * This file is licensed under the Affero General Public License version 3 or
- * later. See the COPYING file.
- */
-
-(function() {
-
-	OCA.Notifications.RichObjectStringParser = {
-		avatarsEnabled: true,
-
-		_fileTemplate: '<a class="filename has-tooltip" href="{{link}}" title="{{title}}">{{name}}</a>',
-
-		_userLocalTemplate: '<span class="avatar-name-wrapper" data-user="{{id}}"><div class="avatar" data-user="{{id}}" data-user-display-name="{{name}}"></div><strong>{{name}}</strong></span>',
-		_userRemoteTemplate: '<strong>{{name}}</strong>',
-
-		_unknownTemplate: '<strong>{{name}}</strong>',
-		_unknownLinkTemplate: '<a href="{{link}}">{{name}}</a>',
-
-		/**
-		 * @param {string} subject
-		 * @param {Object} parameters
-		 * @returns {string}
-		 */
-		parseMessage: function(subject, parameters) {
-			var self = this,
-				regex = /\{([a-z0-9]+)\}/gi,
-				matches = subject.match(regex);
-
-			_.each(matches, function(parameter) {
-				parameter = parameter.substring(1, parameter.length - 1);
-				var parsed = self.parseParameter(parameters[parameter]);
-
-				subject = subject.replace('{' + parameter + '}', parsed);
-			});
-
-			return subject;
-		},
-
-		/**
-		 * @param {Object} parameter
-		 * @param {string} parameter.type
-		 * @param {string} parameter.id
-		 * @param {string} parameter.name
-		 * @param {string} parameter.link
-		 */
-		parseParameter: function(parameter) {
-			switch (parameter.type) {
-				case 'file':
-					return this.parseFileParameter(parameter);
-
-				case 'user':
-					if (_.isUndefined(parameter.server)) {
-						if (!this.userLocalTemplate) {
-							this.userLocalTemplate = Handlebars.compile(this._userLocalTemplate);
-						}
-						return this.userLocalTemplate(parameter);
-					}
-
-					if (!this.userRemoteTemplate) {
-						this.userRemoteTemplate = Handlebars.compile(this._userRemoteTemplate);
-					}
-
-					return this.userRemoteTemplate(parameter);
-
-				default:
-					if (!_.isUndefined(parameter.link)) {
-						if (!this.unknownLinkTemplate) {
-							this.unknownLinkTemplate = Handlebars.compile(this._unknownLinkTemplate);
-						}
-						return this.unknownLinkTemplate(parameter);
-					}
-
-					if (!this.unknownTemplate) {
-						this.unknownTemplate = Handlebars.compile(this._unknownTemplate);
-					}
-					return this.unknownTemplate(parameter);
-			}
-		},
-
-		/**
-		 * @param {Object} parameter
-		 * @param {string} parameter.type
-		 * @param {string} parameter.id
-		 * @param {string} parameter.name
-		 * @param {string} parameter.path
-		 * @param {string} parameter.link
-		 */
-		parseFileParameter: function(parameter) {
-			if (!this.fileTemplate) {
-				this.fileTemplate = Handlebars.compile(this._fileTemplate);
-			}
-			var lastSlashPosition = parameter.path.lastIndexOf('/'),
-				firstSlashPosition = parameter.path.indexOf('/');
-			parameter.path = parameter.path.substring(firstSlashPosition === 0 ? 1 : 0, lastSlashPosition);
-
-			return this.fileTemplate(_.extend(parameter, {
-				title: parameter.path.length === 0 ? '' : t('notifications', 'in {path}', parameter)
-			}));
-		}
-	};
-
-})();
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/notifications\/js\/merged.json":1570113918,"\/var\/www\/html\/apps\/notifications\/js\/app.js":1570113918,"\/var\/www\/html\/apps\/notifications\/js\/notification.js":1570113918,"\/var\/www\/html\/apps\/notifications\/js\/richObjectStringParser.js":1570113918}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/notifications/merged.js.gzip


+ 0 - 735
compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js

@@ -1,735 +0,0 @@
-/*
- * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	if (!OCA.SystemTags) {
-		/**
-		 * @namespace
-		 */
-		OCA.SystemTags = {};
-	}
-
-	OCA.SystemTags.App = {
-
-		initFileList: function($el) {
-			if (this._fileList) {
-				return this._fileList;
-			}
-
-			this._fileList = new OCA.SystemTags.FileList(
-				$el,
-				{
-					id: 'systemtags',
-					scrollContainer: $('#app-content'),
-					fileActions: this._createFileActions(),
-					config: OCA.Files.App.getFilesConfig()
-				}
-			);
-
-			this._fileList.appName = t('systemtags', 'Tags');
-			return this._fileList;
-		},
-
-		removeFileList: function() {
-			if (this._fileList) {
-				this._fileList.$fileList.empty();
-			}
-		},
-
-		_createFileActions: function() {
-			// inherit file actions from the files app
-			var fileActions = new OCA.Files.FileActions();
-			// note: not merging the legacy actions because legacy apps are not
-			// compatible with the sharing overview and need to be adapted first
-			fileActions.registerDefaultActions();
-			fileActions.merge(OCA.Files.fileActions);
-
-			if (!this._globalActionsInitialized) {
-				// in case actions are registered later
-				this._onActionsUpdated = _.bind(this._onActionsUpdated, this);
-				OCA.Files.fileActions.on('setDefault.app-systemtags', this._onActionsUpdated);
-				OCA.Files.fileActions.on('registerAction.app-systemtags', this._onActionsUpdated);
-				this._globalActionsInitialized = true;
-			}
-
-			// when the user clicks on a folder, redirect to the corresponding
-			// folder in the files app instead of opening it directly
-			fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
-				OCA.Files.App.setActiveView('files', {silent: true});
-				OCA.Files.App.fileList.changeDirectory(OC.joinPaths(context.$file.attr('data-path'), filename), true, true);
-			});
-			fileActions.setDefault('dir', 'Open');
-			return fileActions;
-		},
-
-		_onActionsUpdated: function(ev) {
-			if (!this._fileList) {
-				return;
-			}
-
-			if (ev.action) {
-				this._fileList.fileActions.registerAction(ev.action);
-			} else if (ev.defaultAction) {
-				this._fileList.fileActions.setDefault(
-					ev.defaultAction.mime,
-					ev.defaultAction.name
-				);
-			}
-		},
-
-		/**
-		 * Destroy the app
-		 */
-		destroy: function() {
-			OCA.Files.fileActions.off('setDefault.app-systemtags', this._onActionsUpdated);
-			OCA.Files.fileActions.off('registerAction.app-systemtags', this._onActionsUpdated);
-			this.removeFileList();
-			this._fileList = null;
-			delete this._globalActionsInitialized;
-		}
-	};
-
-})();
-
-$(document).ready(function() {
-	$('#app-content-systemtagsfilter').on('show', function(e) {
-		OCA.SystemTags.App.initFileList($(e.target));
-	});
-	$('#app-content-systemtagsfilter').on('hide', function() {
-		OCA.SystemTags.App.removeFileList();
-	});
-});
-
-
-/*
- * Copyright (c) 2016 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-(function() {
-	/**
-	 * @class OCA.SystemTags.FileList
-	 * @augments OCA.Files.FileList
-	 *
-	 * @classdesc SystemTags file list.
-	 * Contains a list of files filtered by system tags.
-	 *
-	 * @param $el container element with existing markup for the #controls
-	 * and a table
-	 * @param [options] map of options, see other parameters
-	 * @param {Array.<string>} [options.systemTagIds] array of system tag ids to
-	 * filter by
-	 */
-	var FileList = function($el, options) {
-		this.initialize($el, options);
-	};
-	FileList.prototype = _.extend({}, OCA.Files.FileList.prototype,
-		/** @lends OCA.SystemTags.FileList.prototype */ {
-		id: 'systemtagsfilter',
-		appName: t('systemtags', 'Tagged files'),
-
-		/**
-		 * Array of system tag ids to filter by
-		 *
-		 * @type Array.<string>
-		 */
-		_systemTagIds: [],
-		_lastUsedTags: [],
-
-		_clientSideSort: true,
-		_allowSelection: false,
-
-		_filterField: null,
-
-		/**
-		 * @private
-		 */
-		initialize: function($el, options) {
-			OCA.Files.FileList.prototype.initialize.apply(this, arguments);
-			if (this.initialized) {
-				return;
-			}
-
-			if (options && options.systemTagIds) {
-				this._systemTagIds = options.systemTagIds;
-			}
-
-			OC.Plugins.attach('OCA.SystemTags.FileList', this);
-
-			var $controls = this.$el.find('#controls').empty();
-
-			_.defer(_.bind(this._getLastUsedTags, this));
-			this._initFilterField($controls);
-		},
-		
-		destroy: function() {
-			this.$filterField.remove();
-
-			OCA.Files.FileList.prototype.destroy.apply(this, arguments);
-		},
-
-		_getLastUsedTags: function() {
-			var self = this;
-			$.ajax({
-				type: 'GET',
-				url: OC.generateUrl('/apps/systemtags/lastused'),
-				success: function (response) {
-					self._lastUsedTags = response;
-				}
-			});
-		},
-
-		_initFilterField: function($container) {
-			var self = this;
-			this.$filterField = $('<input type="hidden" name="tags"/>');
-			$container.append(this.$filterField);
-			this.$filterField.select2({
-				placeholder: t('systemtags', 'Select tags to filter by'),
-				allowClear: false,
-				multiple: true,
-				toggleSelect: true,
-				separator: ',',
-				query: _.bind(this._queryTagsAutocomplete, this),
-
-				id: function(tag) {
-					return tag.id;
-				},
-
-				initSelection: function(element, callback) {
-					var val = $(element).val().trim();
-					if (val) {
-						var tagIds = val.split(','),
-							tags = [];
-
-						OC.SystemTags.collection.fetch({
-							success: function() {
-								_.each(tagIds, function(tagId) {
-									var tag = OC.SystemTags.collection.get(tagId);
-									if (!_.isUndefined(tag)) {
-										tags.push(tag.toJSON());
-									}
-								});
-
-								callback(tags);
-							}
-						});
-					} else {
-						callback([]);
-					}
-				},
-
-				formatResult: function (tag) {
-					return OC.SystemTags.getDescriptiveTag(tag);
-				},
-
-				formatSelection: function (tag) {
-					return OC.SystemTags.getDescriptiveTag(tag)[0].outerHTML;
-				},
-
-				sortResults: function(results) {
-					results.sort(function(a, b) {
-						var aLastUsed = self._lastUsedTags.indexOf(a.id);
-						var bLastUsed = self._lastUsedTags.indexOf(b.id);
-
-						if (aLastUsed !== bLastUsed) {
-							if (bLastUsed === -1) {
-								return -1;
-							}
-							if (aLastUsed === -1) {
-								return 1;
-							}
-							return aLastUsed < bLastUsed ? -1 : 1;
-						}
-
-						// Both not found
-						return OC.Util.naturalSortCompare(a.name, b.name);
-					});
-					return results;
-				},
-
-				escapeMarkup: function(m) {
-					// prevent double markup escape
-					return m;
-				},
-				formatNoMatches: function() {
-					return t('systemtags', 'No tags found');
-				}
-			});
-			this.$filterField.on('change', _.bind(this._onTagsChanged, this));
-			return this.$filterField;
-		},
-
-		/**
-		 * Autocomplete function for dropdown results
-		 *
-		 * @param {Object} query select2 query object
-		 */
-		_queryTagsAutocomplete: function(query) {
-			OC.SystemTags.collection.fetch({
-				success: function() {
-					var results = OC.SystemTags.collection.filterByName(query.term);
-
-					query.callback({
-						results: _.invoke(results, 'toJSON')
-					});
-				}
-			});
-		},
-
-		/**
-		 * Event handler for when the URL changed
-		 */
-		_onUrlChanged: function(e) {
-			if (e.dir) {
-				var tags = _.filter(e.dir.split('/'), function(val) { return val.trim() !== ''; });
-				this.$filterField.select2('val', tags || []);
-				this._systemTagIds = tags;
-				this.reload();
-			}
-		},
-
-		_onTagsChanged: function(ev) {
-			var val = $(ev.target).val().trim();
-			if (val !== '') {
-				this._systemTagIds = val.split(',');
-			} else {
-				this._systemTagIds = [];
-			}
-
-			this.$el.trigger(jQuery.Event('changeDirectory', {
-				dir: this._systemTagIds.join('/')
-			}));
-			this.reload();
-		},
-
-		updateEmptyContent: function() {
-			var dir = this.getCurrentDirectory();
-			if (dir === '/') {
-				// root has special permissions
-				if (!this._systemTagIds.length) {
-					// no tags selected
-					this.$el.find('#emptycontent').html('<div class="icon-systemtags"></div>' +
-						'<h2>' + t('systemtags', 'Please select tags to filter by') + '</h2>');
-				} else {
-					// tags selected but no results
-					this.$el.find('#emptycontent').html('<div class="icon-systemtags"></div>' +
-						'<h2>' + t('systemtags', 'No files found for the selected tags') + '</h2>');
-				}
-				this.$el.find('#emptycontent').toggleClass('hidden', !this.isEmpty);
-				this.$el.find('#filestable thead th').toggleClass('hidden', this.isEmpty);
-			}
-			else {
-				OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments);
-			}
-		},
-
-		getDirectoryPermissions: function() {
-			return OC.PERMISSION_READ | OC.PERMISSION_DELETE;
-		},
-
-		updateStorageStatistics: function() {
-			// no op because it doesn't have
-			// storage info like free space / used space
-		},
-
-		reload: function() {
-			if (!this._systemTagIds.length) {
-				// don't reload
-				this.updateEmptyContent();
-				this.setFiles([]);
-				return $.Deferred().resolve();
-			}
-
-			this._selectedFiles = {};
-			this._selectionSummary.clear();
-			if (this._currentFileModel) {
-				this._currentFileModel.off();
-			}
-			this._currentFileModel = null;
-			this.$el.find('.select-all').prop('checked', false);
-			this.showMask();
-			this._reloadCall = this.filesClient.getFilteredFiles(
-				{
-					systemTagIds: this._systemTagIds
-				},
-				{
-					properties: this._getWebdavProperties()
-				}
-			);
-			if (this._detailsView) {
-				// close sidebar
-				this._updateDetailsView(null);
-			}
-			var callBack = this.reloadCallback.bind(this);
-			return this._reloadCall.then(callBack, callBack);
-		},
-
-		reloadCallback: function(status, result) {
-			if (result) {
-				// prepend empty dir info because original handler
-				result.unshift({});
-			}
-
-			return OCA.Files.FileList.prototype.reloadCallback.call(this, status, result);
-		}
-	});
-
-	OCA.SystemTags.FileList = FileList;
-})();
-
-
-/*
- * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function() {
-	OCA.SystemTags = _.extend({}, OCA.SystemTags);
-	if (!OCA.SystemTags) {
-		/**
-		 * @namespace
-		 */
-		OCA.SystemTags = {};
-	}
-
-	/**
-	 * @namespace
-	 */
-	OCA.SystemTags.FilesPlugin = {
-		ignoreLists: [
-			'files_trashbin',
-			'files.public'
-		],
-
-		attach: function(fileList) {
-			if (this.ignoreLists.indexOf(fileList.id) >= 0) {
-				return;
-			}
-
-			var systemTagsInfoView = new OCA.SystemTags.SystemTagsInfoView();
-			fileList.registerDetailView(systemTagsInfoView);
-
-			_.each(fileList.getRegisteredDetailViews(), function(detailView) {
-				if (detailView instanceof OCA.Files.MainFileInfoDetailView) {
-					var systemTagsInfoViewToggleView =
-						new OCA.SystemTags.SystemTagsInfoViewToggleView({
-							systemTagsInfoView: systemTagsInfoView
-						});
-					systemTagsInfoViewToggleView.render();
-
-					// The toggle view element is detached before the
-					// MainFileInfoDetailView is rendered to prevent its event
-					// handlers from being removed.
-					systemTagsInfoViewToggleView.listenTo(detailView, 'pre-render', function() {
-						systemTagsInfoViewToggleView.$el.detach();
-					});
-					systemTagsInfoViewToggleView.listenTo(detailView, 'post-render', function() {
-						detailView.$el.find('.file-details').append(systemTagsInfoViewToggleView.$el);
-					});
-
-					return;
-				}
-			});
-		}
-	};
-
-})();
-
-OC.Plugins.register('OCA.Files.FileList', OCA.SystemTags.FilesPlugin);
-
-
-
-/*
- * Copyright (c) 2015
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-(function(OCA) {
-
-	function modelToSelection(model) {
-		var data = model.toJSON();
-		if (!OC.isUserAdmin() && !data.canAssign) {
-			data.locked = true;
-		}
-		return data;
-	}
-
-	/**
-	 * @class OCA.SystemTags.SystemTagsInfoView
-	 * @classdesc
-	 *
-	 * Displays a file's system tags
-	 *
-	 */
-	var SystemTagsInfoView = OCA.Files.DetailFileInfoView.extend(
-		/** @lends OCA.SystemTags.SystemTagsInfoView.prototype */ {
-
-		_rendered: false,
-
-		className: 'systemTagsInfoView hidden',
-
-		/**
-		 * @type OC.SystemTags.SystemTagsInputField
-		 */
-		_inputView: null,
-
-		initialize: function(options) {
-			var self = this;
-			options = options || {};
-
-			this._inputView = new OC.SystemTags.SystemTagsInputField({
-				multiple: true,
-				allowActions: true,
-				allowCreate: true,
-				isAdmin: OC.isUserAdmin(),
-				initSelection: function(element, callback) {
-					callback(self.selectedTagsCollection.map(modelToSelection));
-				}
-			});
-
-			this.selectedTagsCollection = new OC.SystemTags.SystemTagsMappingCollection([], {objectType: 'files'});
-
-			this._inputView.collection.on('change:name', this._onTagRenamedGlobally, this);
-			this._inputView.collection.on('remove', this._onTagDeletedGlobally, this);
-
-			this._inputView.on('select', this._onSelectTag, this);
-			this._inputView.on('deselect', this._onDeselectTag, this);
-		},
-
-		/**
-		 * Event handler whenever a tag was selected
-		 */
-		_onSelectTag: function(tag) {
-			// create a mapping entry for this tag
-			this.selectedTagsCollection.create(tag.toJSON());
-		},
-
-		/**
-		 * Event handler whenever a tag gets deselected.
-		 * Removes the selected tag from the mapping collection.
-		 *
-		 * @param {string} tagId tag id
-		 */
-		_onDeselectTag: function(tagId) {
-			this.selectedTagsCollection.get(tagId).destroy();
-		},
-
-		/**
-		 * Event handler whenever a tag was renamed globally.
-		 *
-		 * This will automatically adjust the tag mapping collection to
-		 * container the new name.
-		 *
-		 * @param {OC.Backbone.Model} changedTag tag model that has changed
-		 */
-		_onTagRenamedGlobally: function(changedTag) {
-			// also rename it in the selection, if applicable
-			var selectedTagMapping = this.selectedTagsCollection.get(changedTag.id);
-			if (selectedTagMapping) {
-				selectedTagMapping.set(changedTag.toJSON());
-			}
-		},
-
-		/**
-		 * Event handler whenever a tag was deleted globally.
-		 *
-		 * This will automatically adjust the tag mapping collection to
-		 * container the new name.
-		 *
-		 * @param {OC.Backbone.Model} tagId tag model that has changed
-		 */
-		_onTagDeletedGlobally: function(tagId) {
-			// also rename it in the selection, if applicable
-			this.selectedTagsCollection.remove(tagId);
-		},
-
-		setFileInfo: function(fileInfo) {
-			var self = this;
-			if (!this._rendered) {
-				this.render();
-			}
-
-			if (fileInfo) {
-				this.selectedTagsCollection.setObjectId(fileInfo.id);
-				this.selectedTagsCollection.fetch({
-					success: function(collection) {
-						collection.fetched = true;
-
-						var appliedTags = collection.map(modelToSelection);
-						self._inputView.setData(appliedTags);
-
-						if (appliedTags.length !== 0) {
-							self.show();
-						} else {
-							self.hide();
-						}
-					}
-				});
-			}
-
-			this.hide();
-		},
-
-		/**
-		 * Renders this details view
-		 */
-		render: function() {
-			var self = this;
-
-			this.$el.append(this._inputView.$el);
-			this._inputView.render();
-		},
-
-		isVisible: function() {
-			return !this.$el.hasClass('hidden');
-		},
-
-		show: function() {
-			this.$el.removeClass('hidden');
-		},
-
-		hide: function() {
-			this.$el.addClass('hidden');
-		},
-
-		openDropdown: function() {
-			this.$el.find('.systemTagsInputField').select2('open');
-		},
-
-		remove: function() {
-			this._inputView.remove();
-		}
-	});
-
-	OCA.SystemTags.SystemTagsInfoView = SystemTagsInfoView;
-
-})(OCA);
-
-
-
-/**
- *
- * @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-(function(OCA) {
-
-	var TEMPLATE =
-		'<span class="icon icon-tag"/>' + t('systemtags', 'Tags');
-
-	/**
-	 * @class OCA.SystemTags.SystemTagsInfoViewToggleView
-	 * @classdesc
-	 *
-	 * View to toggle the visibility of a SystemTagsInfoView.
-	 *
-	 * This toggle view must be explicitly rendered before it is used.
-	 */
-	var SystemTagsInfoViewToggleView = OC.Backbone.View.extend(
-		/** @lends OC.Backbone.View.prototype */ {
-
-		tagName: 'span',
-
-		className: 'tag-label',
-
-		events: {
-			'click': 'click'
-		},
-
-		/**
-		 * @type OCA.SystemTags.SystemTagsInfoView
-		 */
-		_systemTagsInfoView: null,
-
-		template: function(data) {
-			if (!this._template) {
-				this._template = Handlebars.compile(TEMPLATE);
-			}
-			return this._template(data);
-		},
-
-		/**
-		 * Initialize this toggle view.
-		 *
-		 * The options must provide a systemTagsInfoView parameter that
-		 * references the SystemTagsInfoView to associate to this toggle view.
-		 */
-		initialize: function(options) {
-			var self = this;
-			options = options || {};
-
-			this._systemTagsInfoView = options.systemTagsInfoView;
-			if (!this._systemTagsInfoView) {
-				throw 'Missing required parameter "systemTagsInfoView"';
-			}
-		},
-
-		/**
-		 * Toggles the visibility of the associated SystemTagsInfoView.
-		 *
-		 * When the systemTagsInfoView is shown its dropdown is also opened.
-		 */
-		click: function() {
-			if (this._systemTagsInfoView.isVisible()) {
-				this._systemTagsInfoView.hide();
-			} else {
-				this._systemTagsInfoView.show();
-				this._systemTagsInfoView.openDropdown();
-			}
-		},
-
-		/**
-		 * Renders this toggle view.
-		 *
-		 * @return OCA.SystemTags.SystemTagsInfoViewToggleView this object.
-		 */
-		render: function() {
-			this.$el.html(this.template());
-
-			return this;
-		},
-
-	});
-
-	OCA.SystemTags.SystemTagsInfoViewToggleView = SystemTagsInfoViewToggleView;
-
-})(OCA);
-
-

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/apps\/systemtags\/js\/merged.json":1570113919,"\/var\/www\/html\/apps\/systemtags\/js\/app.js":1570113919,"\/var\/www\/html\/apps\/systemtags\/js\/systemtagsfilelist.js":1570113919,"\/var\/www\/html\/apps\/systemtags\/js\/filesplugin.js":1570113919,"\/var\/www\/html\/apps\/systemtags\/js\/systemtagsinfoview.js":1570113919,"\/var\/www\/html\/apps\/systemtags\/js\/systemtagsinfoviewtoggleview.js":1570113919}

BIN
compose/karmen/data/appdata_oc216qe0mln5/js/systemtags/merged.js.gzip


BIN
compose/karmen/data/appdata_oc216qe0mln5/preview/101/2048-2048-max.png


BIN
compose/karmen/data/appdata_oc216qe0mln5/preview/101/32-32-crop.png


BIN
compose/karmen/data/appdata_oc216qe0mln5/preview/16/2048-2048-max.png


BIN
compose/karmen/data/appdata_oc216qe0mln5/preview/16/32-32-crop.png


+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_application-pdf.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path style="block-progression:tb;text-transform:none;text-indent:0" fill="#dc5047" d="M2.35 1v.002A.45.45 0 0 0 2 1.44V14.56a.45.45 0 0 0 .432.438H13.57a.452.452 0 0 0 .432-.437V4.418a.458.458 0 0 0-.055-.19l-3.312-3.2A.427.427 0 0 0 10.5 1H2.43a.432.432 0 0 0-.08 0zm5.005 2h.194a.69.69 0 0 1 .49.195c.533.533.285 1.83.02 2.903-.018.048-.027.09-.035.113.323.912.783 1.646 1.29 2.065.21.162.444.322.703.467a9.4 9.4 0 0 1 1.04-.057c1 0 1.605.178 1.838.557.08.13.12.282.096.443a.78.78 0 0 1-.224.534c-.138.152-.378.24-.733.24-.613 0-1.615-.187-2.422-.6-1.387.155-2.42.343-3.25.61-.04.015-.088.03-.144.053C5.22 12.233 4.476 13 3.823 13a.72.72 0 0 1-.355-.09l-.388-.248-.025-.04a.73.73 0 0 1-.04-.436c.087-.427.548-1.106 1.516-1.71.153-.114.394-.243.717-.396.242-.42.5-.91.775-1.45.412-.832.668-1.653.87-2.362v-.01c-.3-.976-.475-1.564-.176-2.637.07-.305.337-.62.635-.62zm.122.5c-.017.024-.04.065-.057.098-.137.338-.13.926.057 1.652l.04-.03c.057-.26.08-.486.13-.663l.023-.13c.08-.46.065-.692-.072-.886l-.12-.04zm.066 3.647a11.958 11.958 0 0 1-.816 1.933c-.162.306-.34.596-.405.838l.09-.03a15.23 15.23 0 0 1 2.695-.75c-.12-.082-.235-.17-.332-.26-.484-.41-.9-1.006-1.232-1.732zm3.36 2.216c-.055 0-.112 0-.184.08.587.258 1.16.412 1.53.412a.9.9 0 0 0 .154-.015h.034c.04-.016.064-.027.072-.108-.016-.024-.032-.055-.072-.088-.08-.08-.405-.28-1.534-.28zm-5.862 1.46c-.168.096-.305.185-.386.25-.572.523-.934 1.054-.974 1.36.363-.12.837-.65 1.36-1.61z" color="#000"/></svg>

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_folder.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path d="M1.457 1.997c-.25 0-.46.21-.46.46v11.08c0 .26.202.46.46.46h13.08c.258 0 .46-.2.46-.46V4.46c0-.25-.21-.463-.46-.463h-6.54l-2-2z" fill-rule="evenodd" fill="#0082c9"/></svg>

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_text.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path style="block-progression:tb;text-transform:none;text-indent:0" d="M2.35 1.002A.45.45 0 0 0 2 1.44V14.56c0 .232.206.44.432.44H13.57a.452.452 0 0 0 .432-.438V4.42a.458.458 0 0 0-.055-.192l-3.312-3.2a.427.427 0 0 0-.135-.026H2.43a.424.424 0 0 0-.08 0zM4 3h6v1H4V3zm0 3h5v1H4V6zm0 3h8v1H4V9zm0 3h4v1H4v-1z" fill="#969696" color="#000"/></svg>

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_video.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path style="block-progression:tb;text-transform:none;text-indent:0" d="M1.344 2A.445.445 0 0 0 1 2.438v11.124c0 .23.212.44.438.44h13.124a.457.457 0 0 0 .438-.44V2.61c0-.336-.265-.61-.516-.61zM2 3h12v10H2zm3 2v6l6-3z" fill="#969696" color="#000"/></svg>

+ 0 - 1
compose/karmen/data/appdata_oc216qe0mln5/theming/0/icon-core-filetypes_x-office-document.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path style="block-progression:tb;text-transform:none;text-indent:0" d="M2.35 1.002A.45.45 0 0 0 2 1.44V14.56c0 .232.206.44.432.44H13.57a.452.452 0 0 0 .432-.438V4.42a.458.458 0 0 0-.055-.192l-3.312-3.2a.427.427 0 0 0-.135-.026H2.43a.424.424 0 0 0-.08 0zM4 3h6v1H4V3zm0 3h5v1H4V6zm0 3h8v1H4V9zm0 3h4v1H4v-1z" fill="#49abea" color="#000"/></svg>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc6972tp5niy/appstore/apps.json


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css


+ 0 - 1
compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570116458,"\/var\/www\/html\/apps\/files\/css\/merged.scss":1570116457,"\/var\/www\/html\/apps\/files\/css\/files.scss":1570116457,"\/var\/www\/html\/apps\/files\/css\/upload.scss":1570116457,"\/var\/www\/html\/apps\/files\/css\/mobile.scss":1570116457,"\/var\/www\/html\/apps\/files\/css\/detailsView.scss":1570116457}

BIN
compose/karmen/data/appdata_oc6972tp5niy/css/files/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css


+ 0 - 1
compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570116458,"\/var\/www\/html\/apps\/files_sharing\/css\/mergedAdditionalStyles.scss":1570116457,"\/var\/www\/html\/apps\/files_sharing\/css\/sharetabview.scss":1570116457,"\/var\/www\/html\/apps\/files_sharing\/css\/sharebreadcrumb.scss":1570116457}

BIN
compose/karmen/data/appdata_oc6972tp5niy/css/files_sharing/f1898ace4fdd2faf5ef6f8c60e062537-mergedAdditionalStyles.css.gzip


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
compose/karmen/data/appdata_oc6972tp5niy/css/files_texteditor/f1898ace4fdd2faf5ef6f8c60e062537-merged.css


+ 0 - 1
compose/karmen/data/appdata_oc6972tp5niy/css/files_texteditor/f1898ace4fdd2faf5ef6f8c60e062537-merged.css.deps

@@ -1 +0,0 @@
-{"\/var\/www\/html\/core\/css\/variables.scss":1570116458,"\/var\/www\/html\/apps\/files_texteditor\/css\/merged.scss":1570116457,"\/var\/www\/html\/apps\/files_texteditor\/css\/DroidSansMono\/stylesheet.scss":1570116457,"\/var\/www\/html\/apps\/files_texteditor\/css\/style.scss":1570116457,"\/var\/www\/html\/apps\/files_texteditor\/css\/mobile.scss":1570116457}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác