aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzotlabs <mike@macgirvin.com>2019-04-15 20:53:44 -0700
committerzotlabs <mike@macgirvin.com>2019-04-15 20:53:44 -0700
commitdf5a1c59e6d2a0921de177aabacbee674d7385da (patch)
tree659c8b64743ac4cb894820eaa0f3ca47329b13d3
parent0615709a7ab7bba66b2a07d593e84a35ed083edb (diff)
parent71f17a233e29a45304f43ee2329bfff1865c6917 (diff)
downloadvolse-hubzilla-df5a1c59e6d2a0921de177aabacbee674d7385da.tar.gz
volse-hubzilla-df5a1c59e6d2a0921de177aabacbee674d7385da.tar.bz2
volse-hubzilla-df5a1c59e6d2a0921de177aabacbee674d7385da.zip
Merge branch 'dev' of https://framagit.org/hubzilla/core into dev
-rw-r--r--.gitlab-ci.yml95
-rw-r--r--CHANGELOG24
-rw-r--r--Zotlabs/Module/Cdav.php83
-rw-r--r--Zotlabs/Module/Cover_photo.php34
-rw-r--r--Zotlabs/Module/Getfile.php13
-rw-r--r--Zotlabs/Module/Profile_photo.php56
-rw-r--r--Zotlabs/Photo/PhotoDriver.php38
-rwxr-xr-xboot.php2
-rw-r--r--include/attach.php11
-rwxr-xr-xinclude/dba/dba_pdo.php2
-rw-r--r--include/import.php38
-rw-r--r--include/photos.php9
-rw-r--r--include/zot.php78
-rw-r--r--install/INSTALL.txt2
-rwxr-xr-xinstall/htconfig.sample.php2
-rw-r--r--library/fullcalendar.old/CHANGELOG.txt (renamed from library/fullcalendar/CHANGELOG.txt)0
-rw-r--r--library/fullcalendar.old/CONTRIBUTING.txt (renamed from library/fullcalendar/CONTRIBUTING.txt)0
-rw-r--r--library/fullcalendar.old/LICENSE.txt20
-rw-r--r--library/fullcalendar.old/fullcalendar.css (renamed from library/fullcalendar/fullcalendar.css)0
-rw-r--r--library/fullcalendar.old/fullcalendar.js (renamed from library/fullcalendar/fullcalendar.js)0
-rw-r--r--library/fullcalendar.old/fullcalendar.min.css (renamed from library/fullcalendar/fullcalendar.min.css)0
-rw-r--r--library/fullcalendar.old/fullcalendar.min.js (renamed from library/fullcalendar/fullcalendar.min.js)0
-rw-r--r--library/fullcalendar.old/fullcalendar.print.css (renamed from library/fullcalendar/fullcalendar.print.css)0
-rw-r--r--library/fullcalendar.old/fullcalendar.print.min.css (renamed from library/fullcalendar/fullcalendar.print.min.css)0
-rw-r--r--library/fullcalendar.old/gcal.js (renamed from library/fullcalendar/gcal.js)0
-rw-r--r--library/fullcalendar.old/gcal.min.js (renamed from library/fullcalendar/gcal.min.js)0
-rw-r--r--library/fullcalendar.old/locale-all.js (renamed from library/fullcalendar/locale-all.js)0
-rw-r--r--library/fullcalendar/CHANGELOG.md1377
-rw-r--r--library/fullcalendar/LICENSE.txt2
-rw-r--r--library/fullcalendar/demos/background-events.html109
-rw-r--r--library/fullcalendar/demos/daygrid-views.html109
-rw-r--r--library/fullcalendar/demos/default.html103
-rw-r--r--library/fullcalendar/demos/external-dragging-2cals.html75
-rw-r--r--library/fullcalendar/demos/external-dragging-builtin.html149
-rw-r--r--library/fullcalendar/demos/full-height.html129
-rw-r--r--library/fullcalendar/demos/google-calendar.html86
-rw-r--r--library/fullcalendar/demos/js/theme-chooser.js141
-rw-r--r--library/fullcalendar/demos/json.html93
-rw-r--r--library/fullcalendar/demos/json/events.json56
-rw-r--r--library/fullcalendar/demos/list-views.html118
-rw-r--r--library/fullcalendar/demos/locales.html152
-rw-r--r--library/fullcalendar/demos/php/get-events.php50
-rw-r--r--library/fullcalendar/demos/php/get-time-zones.php9
-rw-r--r--library/fullcalendar/demos/php/utils.php130
-rw-r--r--library/fullcalendar/demos/rrule.html73
-rw-r--r--library/fullcalendar/demos/selectable.html125
-rw-r--r--library/fullcalendar/demos/themes.html215
-rw-r--r--library/fullcalendar/demos/time-zones.html145
-rw-r--r--library/fullcalendar/demos/timegrid-views.html113
-rw-r--r--library/fullcalendar/demos/week-numbers.html118
-rw-r--r--library/fullcalendar/packages/bootstrap/main.css33
-rw-r--r--library/fullcalendar/packages/bootstrap/main.js90
-rw-r--r--library/fullcalendar/packages/bootstrap/main.min.css5
-rw-r--r--library/fullcalendar/packages/bootstrap/main.min.js20
-rw-r--r--library/fullcalendar/packages/core/locales-all.js1353
-rw-r--r--library/fullcalendar/packages/core/locales-all.min.js6
-rw-r--r--library/fullcalendar/packages/core/locales/af.js30
-rw-r--r--library/fullcalendar/packages/core/locales/ar-dz.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar-kw.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar-ly.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar-ma.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar-sa.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar-tn.js31
-rw-r--r--library/fullcalendar/packages/core/locales/ar.js31
-rw-r--r--library/fullcalendar/packages/core/locales/bg.js31
-rw-r--r--library/fullcalendar/packages/core/locales/bs.js32
-rw-r--r--library/fullcalendar/packages/core/locales/ca.js30
-rw-r--r--library/fullcalendar/packages/core/locales/cs.js32
-rw-r--r--library/fullcalendar/packages/core/locales/da.js30
-rw-r--r--library/fullcalendar/packages/core/locales/de.js33
-rw-r--r--library/fullcalendar/packages/core/locales/el.js30
-rw-r--r--library/fullcalendar/packages/core/locales/en-au.js17
-rw-r--r--library/fullcalendar/packages/core/locales/en-gb.js17
-rw-r--r--library/fullcalendar/packages/core/locales/en-nz.js17
-rw-r--r--library/fullcalendar/packages/core/locales/es-us.js30
-rw-r--r--library/fullcalendar/packages/core/locales/es.js30
-rw-r--r--library/fullcalendar/packages/core/locales/et.js32
-rw-r--r--library/fullcalendar/packages/core/locales/eu.js30
-rw-r--r--library/fullcalendar/packages/core/locales/fa.js33
-rw-r--r--library/fullcalendar/packages/core/locales/fi.js30
-rw-r--r--library/fullcalendar/packages/core/locales/fr-ca.js27
-rw-r--r--library/fullcalendar/packages/core/locales/fr-ch.js31
-rw-r--r--library/fullcalendar/packages/core/locales/fr.js31
-rw-r--r--library/fullcalendar/packages/core/locales/gl.js30
-rw-r--r--library/fullcalendar/packages/core/locales/he.js27
-rw-r--r--library/fullcalendar/packages/core/locales/hi.js32
-rw-r--r--library/fullcalendar/packages/core/locales/hr.js32
-rw-r--r--library/fullcalendar/packages/core/locales/hu.js30
-rw-r--r--library/fullcalendar/packages/core/locales/id.js30
-rw-r--r--library/fullcalendar/packages/core/locales/is.js30
-rw-r--r--library/fullcalendar/packages/core/locales/it.js32
-rw-r--r--library/fullcalendar/packages/core/locales/ja.js28
-rw-r--r--library/fullcalendar/packages/core/locales/ka.js32
-rw-r--r--library/fullcalendar/packages/core/locales/kk.js32
-rw-r--r--library/fullcalendar/packages/core/locales/ko.js26
-rw-r--r--library/fullcalendar/packages/core/locales/lb.js30
-rw-r--r--library/fullcalendar/packages/core/locales/lt.js30
-rw-r--r--library/fullcalendar/packages/core/locales/lv.js32
-rw-r--r--library/fullcalendar/packages/core/locales/mk.js28
-rw-r--r--library/fullcalendar/packages/core/locales/ms.js32
-rw-r--r--library/fullcalendar/packages/core/locales/nb.js30
-rw-r--r--library/fullcalendar/packages/core/locales/nl.js30
-rw-r--r--library/fullcalendar/packages/core/locales/nn.js30
-rw-r--r--library/fullcalendar/packages/core/locales/pl.js30
-rw-r--r--library/fullcalendar/packages/core/locales/pt-br.js28
-rw-r--r--library/fullcalendar/packages/core/locales/pt.js30
-rw-r--r--library/fullcalendar/packages/core/locales/ro.js32
-rw-r--r--library/fullcalendar/packages/core/locales/ru.js32
-rw-r--r--library/fullcalendar/packages/core/locales/sk.js32
-rw-r--r--library/fullcalendar/packages/core/locales/sl.js30
-rw-r--r--library/fullcalendar/packages/core/locales/sq.js32
-rw-r--r--library/fullcalendar/packages/core/locales/sr-cyrl.js32
-rw-r--r--library/fullcalendar/packages/core/locales/sr.js32
-rw-r--r--library/fullcalendar/packages/core/locales/sv.js30
-rw-r--r--library/fullcalendar/packages/core/locales/th.js25
-rw-r--r--library/fullcalendar/packages/core/locales/tr.js30
-rw-r--r--library/fullcalendar/packages/core/locales/uk.js32
-rw-r--r--library/fullcalendar/packages/core/locales/vi.js32
-rw-r--r--library/fullcalendar/packages/core/locales/zh-cn.js33
-rw-r--r--library/fullcalendar/packages/core/locales/zh-tw.js26
-rw-r--r--library/fullcalendar/packages/core/main.css900
-rw-r--r--library/fullcalendar/packages/core/main.js8791
-rw-r--r--library/fullcalendar/packages/core/main.min.css5
-rw-r--r--library/fullcalendar/packages/core/main.min.js9
-rw-r--r--library/fullcalendar/packages/daygrid/main.css69
-rw-r--r--library/fullcalendar/packages/daygrid/main.js1630
-rw-r--r--library/fullcalendar/packages/daygrid/main.min.css5
-rw-r--r--library/fullcalendar/packages/daygrid/main.min.js20
-rw-r--r--library/fullcalendar/packages/google-calendar/main.js169
-rw-r--r--library/fullcalendar/packages/google-calendar/main.min.js20
-rw-r--r--library/fullcalendar/packages/interaction/main.js2155
-rw-r--r--library/fullcalendar/packages/interaction/main.min.js21
-rw-r--r--library/fullcalendar/packages/list/main.css101
-rw-r--r--library/fullcalendar/packages/list/main.js341
-rw-r--r--library/fullcalendar/packages/list/main.min.css5
-rw-r--r--library/fullcalendar/packages/list/main.min.js20
-rw-r--r--library/fullcalendar/packages/luxon/main.js162
-rw-r--r--library/fullcalendar/packages/luxon/main.min.js20
-rw-r--r--library/fullcalendar/packages/moment-timezone/main.js64
-rw-r--r--library/fullcalendar/packages/moment-timezone/main.min.js20
-rw-r--r--library/fullcalendar/packages/moment/main.js103
-rw-r--r--library/fullcalendar/packages/moment/main.min.js6
-rw-r--r--library/fullcalendar/packages/rrule/main.js127
-rw-r--r--library/fullcalendar/packages/rrule/main.min.js20
-rw-r--r--library/fullcalendar/packages/timegrid/main.css266
-rw-r--r--library/fullcalendar/packages/timegrid/main.js1339
-rw-r--r--library/fullcalendar/packages/timegrid/main.min.css5
-rw-r--r--library/fullcalendar/packages/timegrid/main.min.js20
-rw-r--r--library/fullcalendar/vendor/rrule.js3617
-rw-r--r--util/po2php.php2
-rwxr-xr-xutil/storageconv137
-rw-r--r--view/css/cdav_calendar.css15
-rw-r--r--view/ru/hmessages.po22794
-rw-r--r--view/ru/hstrings.php5577
-rw-r--r--view/tpl/cdav_calendar.tpl285
-rwxr-xr-xview/tpl/event_head.tpl6
156 files changed, 42049 insertions, 14399 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 43c65f365..40e219551 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,6 @@
# Select image from https://hub.docker.com/_/php/
#image: php:7.2
-# Use a prepared Hubzilla image to optimise pipeline run
+# Use a prepared Hubzilla image to optimise pipeline duration
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.2
@@ -32,55 +32,28 @@ variables:
before_script:
+# pecl and composer do not work with PHP production restrictions (from Hubzilla Docker image)
+- if [ -f /usr/local/etc/php/conf.d/z_prod.ini ]; then mv /usr/local/etc/php/conf.d/z_prod.ini /usr/local/etc/php/conf.d/z_prod.ini.off; fi
# Install & enable Xdebug for code coverage reports
- pecl install xdebug
- docker-php-ext-enable xdebug
# Install composer
- curl -sS https://getcomposer.org/installer | php
# Install dev libraries from composer
-- php composer.phar install --no-progress
+- php ./composer.phar install --no-progress
-# test PHP7 with MySQL 5.7
-php7.2_mysql 1/2:
+# hidden job definition with template for MySQL/MariaDB
+.job_template_mysql: &job_definition_mysql
stage: test
- services:
- - mysql:5.7
- script:
- - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
-
-
-# test PHP7 with MySQL latest (8)
-php7.2_mysql 2/2:
- stage: test
- services:
- - name: mysql:latest
- command: ["--default-authentication-plugin=mysql_native_password"]
script:
- echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
-
-# test PHP7 with MariaDB latest (10.3)
-php7.2_mariadb:
- stage: test
- services:
- - name: mariadb:latest
- alias: mysql
- script:
- - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE"
- - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text
-
-
-# test PHP7 with PostgreSQL latest
-php7.2_postgres:
+# hidden job definition with template for PostgreSQL
+.job_template_postgres: &job_definition_postgres
stage: test
services:
- postgres:latest
@@ -95,7 +68,10 @@ php7.2_postgres:
#- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt;"
# Run the actual tests
- vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox
- artifacts:
+
+# hidden job definition with artifacts config template
+.artifacts_template:
+ artifacts: &artifacts_template
expire_in: 1 week
# Gitlab should show the results, but has problems parsing PHPUnit's junit file.
reports:
@@ -106,7 +82,52 @@ php7.2_postgres:
- tests/results/
-# Generate Doxygen API Documentation and deploy it at GitLab pages
+# PHP7.2 with MySQL 5.7
+php7.2_mysql5.7:
+ <<: *job_definition_mysql
+ services:
+ - mysql:5.7
+
+
+# PHP7.2 with MySQL 8 (latest)
+php7.2_mysql8:
+ <<: *job_definition_mysql
+ services:
+ - name: mysql:8
+ command: ["--default-authentication-plugin=mysql_native_password"]
+
+
+# PHP7.2 with MariaDB 10.2
+php7.2_mariadb10.2:
+ <<: *job_definition_mysql
+ services:
+ - name: mariadb:10.2
+ alias: mysql
+
+
+# PHP7.3 with MariaDB 10.3 (latest)
+php7.3_mariadb10.3:
+ <<: *job_definition_mysql
+ image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
+ services:
+ - name: mariadb:10.3
+ alias: mysql
+
+
+# PHP7.2 with PostgreSQL latest (11)
+php7.2_postgres11:
+ <<: *job_definition_postgres
+ artifacts: *artifacts_template
+
+
+# PHP7.3 with PostgreSQL latest (11)
+php7.3_postgres11:
+ <<: *job_definition_postgres
+ image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
+ artifacts: *artifacts_template
+
+
+# Generate Doxygen API Documentation and deploy it as GitLab pages
pages:
stage: deploy
cache: {}
diff --git a/CHANGELOG b/CHANGELOG
index eeba6c6d8..b90ae34c9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,27 @@
+Hubzilla 4.0.2 (2019-04-08)
+ - Port cdav calendar to fullcalendar version 4
+ - Fix perms_pending not evaluated correctly
+ - Fix return wrong profile photo modification date by plugin
+ - Fix suggestion widget using feature_enabled still
+ - Fix check service class limits when syncing files
+ - Remove xchan_instance_url from notifier query - it is not used anymore
+ - Implement remove cover photo functionality
+ - Fix z6_discover() and create a zot6 hubloc on import if applicable
+ - Add backend support for connections ordering
+ - Deduplicate items in item_store() by uuid if we got one otherwise by mid
+ - Add ITEM_TYPE_CUSTOM support to mod display
+ - Fix mod subthread on sys channel items
+ - Fix "recipient not found" dreport spaming with own xchan
+ - Fix wrong variables in dirsearch
+ - Fix 48 hours timeframe check in mod changeaddr
+ - Fix wrong variable in Libsync
+ - Pubcrawl: revert adding additional receivers to comments
+ - Diaspora: fix intro received when being banned
+ - Pubcrawl: add diaspora:guid from friendica AP posts for deduplication
+ - Diaspora: fix friendica plink
+ - Photocache: fix issue with spaces and quotes in original filenames
+
+
Hubzilla 4.0.1 (2019-03-21)
- Fix permissions not getting decrypted on follow
- Add option to add a poster to the video bbcode
diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php
index d644e48b1..5dd233d28 100644
--- a/Zotlabs/Module/Cdav.php
+++ b/Zotlabs/Module/Cdav.php
@@ -280,9 +280,12 @@ class Cdav extends Controller {
return;
$title = $_REQUEST['title'];
- $dtstart = new \DateTime($_REQUEST['dtstart']);
- if($_REQUEST['dtend'])
- $dtend = new \DateTime($_REQUEST['dtend']);
+ $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']);
+ $dtstart = new \DateTime($start);
+ if($_REQUEST['dtend']) {
+ $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']);
+ $dtend = new \DateTime($end);
+ }
$description = $_REQUEST['description'];
$location = $_REQUEST['location'];
@@ -306,13 +309,17 @@ class Cdav extends Controller {
'DTSTART' => $dtstart
]
]);
- if($dtend)
+ if($dtend) {
$vcalendar->VEVENT->add('DTEND', $dtend);
+ $vcalendar->VEVENT->DTEND['TZID'] = App::$timezone;
+ }
if($description)
$vcalendar->VEVENT->add('DESCRIPTION', $description);
if($location)
$vcalendar->VEVENT->add('LOCATION', $location);
+ $vcalendar->VEVENT->DTSTART['TZID'] = App::$timezone;
+
$calendarData = $vcalendar->serialize();
$caldavBackend->createCalendarObject($id, $objectUri, $calendarData);
@@ -351,8 +358,12 @@ class Cdav extends Controller {
$uri = $_REQUEST['uri'];
$title = $_REQUEST['title'];
- $dtstart = new \DateTime($_REQUEST['dtstart']);
- $dtend = $_REQUEST['dtend'] ? new \DateTime($_REQUEST['dtend']) : '';
+ $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']);
+ $dtstart = new \DateTime($start);
+ if($_REQUEST['dtend']) {
+ $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']);
+ $dtend = new \DateTime($end);
+ }
$description = $_REQUEST['description'];
$location = $_REQUEST['location'];
@@ -404,8 +415,12 @@ class Cdav extends Controller {
return;
$uri = $_REQUEST['uri'];
- $dtstart = new \DateTime($_REQUEST['dtstart']);
- $dtend = $_REQUEST['dtend'] ? new \DateTime($_REQUEST['dtend']) : '';
+ $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']);
+ $dtstart = new \DateTime($start);
+ if($_REQUEST['dtend']) {
+ $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']);
+ $dtend = new \DateTime($end);
+ }
$object = $caldavBackend->getCalendarObject($id, $uri);
@@ -877,12 +892,19 @@ class Cdav extends Controller {
//Display calendar(s) here
if(argc() == 2 && argv(1) === 'calendar') {
- head_add_css('/library/fullcalendar/fullcalendar.css');
+ head_add_css('/library/fullcalendar/packages/core/main.min.css');
+ head_add_css('/library/fullcalendar/packages/daygrid/main.min.css');
+ head_add_css('/library/fullcalendar/packages/timegrid/main.min.css');
+ head_add_css('/library/fullcalendar/packages/list/main.min.css');
head_add_css('cdav_calendar.css');
- head_add_js('/library/moment/moment.min.js', 1);
- head_add_js('/library/fullcalendar/fullcalendar.min.js', 1);
- head_add_js('/library/fullcalendar/locale-all.js', 1);
+ head_add_js('/library/fullcalendar/packages/core/main.min.js');
+ head_add_js('/library/fullcalendar/packages/interaction/main.min.js');
+ head_add_js('/library/fullcalendar/packages/daygrid/main.min.js');
+ head_add_js('/library/fullcalendar/packages/timegrid/main.min.js');
+ head_add_js('/library/fullcalendar/packages/list/main.min.js');
+
+ $sources = '';
foreach($calendars as $calendar) {
$editable = (($calendar['share-access'] == 2) ? 'false' : 'true'); // false/true must be string since we're passing it to javascript
@@ -891,6 +913,7 @@ class Cdav extends Controller {
$switch = get_pconfig(local_channel(), 'cdav_calendar', $calendar['id'][0]);
if($switch) {
$sources .= '{
+ id: ' . $calendar['id'][0] . ',
url: \'/cdav/calendar/json/' . $calendar['id'][0] . '/' . $calendar['id'][1] . '\',
color: \'' . $color . '\'
}, ';
@@ -911,8 +934,8 @@ class Cdav extends Controller {
$first_day = (($first_day) ? $first_day : 0);
$title = ['title', t('Event title')];
- $dtstart = ['dtstart', t('Start date and time'), '', t('Example: YYYY-MM-DD HH:mm')];
- $dtend = ['dtend', t('End date and time'), '', t('Example: YYYY-MM-DD HH:mm')];
+ $dtstart = ['dtstart', t('Start date and time')];
+ $dtend = ['dtend', t('End date and time')];
$description = ['description', t('Description')];
$location = ['location', t('Location')];
@@ -920,6 +943,7 @@ class Cdav extends Controller {
'$sources' => $sources,
'$color' => $color,
'$lang' => App::$language,
+ '$timezone' => App::$timezone,
'$first_day' => $first_day,
'$prev' => t('Previous'),
'$next' => t('Next'),
@@ -952,10 +976,12 @@ class Cdav extends Controller {
//Provide json data for calendar
if(argc() == 5 && argv(1) === 'calendar' && argv(2) === 'json' && intval(argv(3)) && intval(argv(4))) {
+ $events = [];
+
$id = [argv(3), argv(4)];
if(! cdav_perms($id[0],$calendars))
- killme();
+ json_return_and_die($events);
if (x($_GET,'start'))
$start = new \DateTime($_GET['start']);
@@ -969,16 +995,19 @@ class Cdav extends Controller {
$filters['comp-filters'][0]['time-range']['end'] = $end;
$uris = $caldavBackend->calendarQuery($id, $filters);
- if($uris) {
+ if($uris) {
$objects = $caldavBackend->getMultipleCalendarObjects($id, $uris);
-
foreach($objects as $object) {
$vcalendar = \Sabre\VObject\Reader::read($object['calendardata']);
- if(isset($vcalendar->VEVENT->RRULE))
+ if(isset($vcalendar->VEVENT->RRULE)) {
+ // expanding recurrent events seems to loose timezone info
+ // save it here so we can add it later
+ $recurrent_timezone = (string)$vcalendar->VEVENT->DTSTART['TZID'];
$vcalendar = $vcalendar->expand($start, $end);
+ }
foreach($vcalendar->VEVENT as $vevent) {
$title = (string)$vevent->SUMMARY;
@@ -986,14 +1015,15 @@ class Cdav extends Controller {
$dtend = (string)$vevent->DTEND;
$description = (string)$vevent->DESCRIPTION;
$location = (string)$vevent->LOCATION;
-
+ $timezone = (string)$vevent->DTSTART['TZID'];
$rw = ((cdav_perms($id[0],$calendars,true)) ? true : false);
- $recurrent = ((isset($vevent->{'RECURRENCE-ID'})) ? true : false);
-
$editable = $rw ? true : false;
+ $recurrent = ((isset($vevent->{'RECURRENCE-ID'})) ? true : false);
- if($recurrent)
+ if($recurrent) {
$editable = false;
+ $timezone = $recurrent_timezone;
+ }
$allDay = false;
@@ -1007,8 +1037,8 @@ class Cdav extends Controller {
'calendar_id' => $id,
'uri' => $object['uri'],
'title' => $title,
- 'start' => $dtstart,
- 'end' => $dtend,
+ 'start' => datetime_convert($timezone, $timezone, $dtstart, 'c'),
+ 'end' => (($dtend) ? datetime_convert($timezone, $timezone, $dtend, 'c') : ''),
'description' => $description,
'location' => $location,
'allDay' => $allDay,
@@ -1018,11 +1048,8 @@ class Cdav extends Controller {
];
}
}
- json_return_and_die($events);
- }
- else {
- killme();
}
+ json_return_and_die($events);
}
//enable/disable calendars
diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php
index b67c00cdc..7957d112c 100644
--- a/Zotlabs/Module/Cover_photo.php
+++ b/Zotlabs/Module/Cover_photo.php
@@ -129,7 +129,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
if(file_exists($tmp_name)) {
$base_image = $r[0];
$gis = getimagesize($tmp_name);
-logger('gis: ' . print_r($gis,true));
+ logger('gis: ' . print_r($gis,true), LOGGER_DEBUG);
$base_image['width'] = $gis[0];
$base_image['height'] = $gis[1];
$base_image['content'] = @file_get_contents($tmp_name);
@@ -190,25 +190,18 @@ logger('gis: ' . print_r($gis,true));
'filename' => $base_image['filename'],
'album' => t('Cover Photos'),
'os_path' => $base_image['os_path'],
- 'display_path' => $base_image['display_path']
+ 'display_path' => $base_image['display_path'],
+ 'photo_usage' => PHOTO_COVER
];
-
- $p['imgscale'] = 7;
- $p['photo_usage'] = PHOTO_COVER;
-
- $r1 = $im->save($p);
+
+ $r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
$im->doScaleImage(850,310);
- $p['imgscale'] = 8;
-
- $r2 = $im->save($p);
-
+ $r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850);
$im->doScaleImage(425,160);
- $p['imgscale'] = 9;
-
- $r3 = $im->save($p);
-
+ $r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425);
+
if($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
@@ -216,6 +209,17 @@ logger('gis: ' . print_r($gis,true));
dbesc($base_image['resource_id']),
local_channel()
);
+
+ $x = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1 AND imgscale >= 7",
+ dbesc($base_image['resource_id']),
+ local_channel()
+ );
+ if($x) {
+ foreach($x as $xx) {
+ @unlink(dbunescbin($xx['content']));
+ }
+ }
+
return;
}
diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php
index abc9f50d9..583cf38f0 100644
--- a/Zotlabs/Module/Getfile.php
+++ b/Zotlabs/Module/Getfile.php
@@ -35,7 +35,6 @@ class Getfile extends \Zotlabs\Web\Controller {
$sig = $_POST['signature'];
$resource = $_POST['resource'];
$revision = intval($_POST['revision']);
- $resolution = (-1);
if(! $hash)
killme();
@@ -81,9 +80,14 @@ class Getfile extends \Zotlabs\Web\Controller {
killme();
}
- if(substr($resource,-2,1) == '-') {
+ if(isset($_POST['resolution']))
+ $resolution = intval($_POST['resolution']);
+ elseif(substr($resource,-2,1) == '-') {
$resolution = intval(substr($resource,-1,1));
$resource = substr($resource,0,-2);
+ }
+ else {
+ $resolution = (-1);
}
$slop = intval(get_pconfig($channel['channel_id'],'system','getfile_time_slop'));
@@ -106,9 +110,10 @@ class Getfile extends \Zotlabs\Web\Controller {
}
if($resolution > 0) {
- $r = q("select * from photo where resource_id = '%s' and uid = %d limit 1",
+ $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($resource),
- intval($channel['channel_id'])
+ intval($channel['channel_id']),
+ $resolution
);
if($r) {
header('Content-type: ' . $r[0]['mimetype']);
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 751c4338f..9f1928e52 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -119,34 +119,45 @@ class Profile_photo extends \Zotlabs\Web\Controller {
'filename' => $base_image['filename'],
'album' => t('Profile Photos'),
'os_path' => $base_image['os_path'],
- 'display_path' => $base_image['display_path']
+ 'display_path' => $base_image['display_path'],
+ 'photo_usage' => PHOTO_PROFILE,
+ 'edited' => dbescdate($base_image['edited'])
];
- $p['imgscale'] = PHOTO_RES_PROFILE_300;
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
- $r1 = $im->save($p);
+ $r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
$im->scaleImage(80);
- $p['imgscale'] = PHOTO_RES_PROFILE_80;
-
- $r2 = $im->save($p);
+ $r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
$im->scaleImage(48);
- $p['imgscale'] = PHOTO_RES_PROFILE_48;
-
- $r3 = $im->save($p);
-
+ $r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48);
+
if($r1 === false || $r2 === false || $r3 === false) {
// if one failed, delete them all so we can start over.
notice( t('Image resize failed.') . EOL );
- $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
+ $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d )",
dbesc($base_image['resource_id']),
local_channel(),
intval(PHOTO_RES_PROFILE_300),
intval(PHOTO_RES_PROFILE_80),
intval(PHOTO_RES_PROFILE_48)
);
+
+ $x = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1 AND imgscale IN ( %d, %d, %d )",
+ dbesc($base_image['resource_id']),
+ local_channel(),
+ intval(PHOTO_RES_PROFILE_300),
+ intval(PHOTO_RES_PROFILE_80),
+ intval(PHOTO_RES_PROFILE_48)
+ );
+ if($x) {
+ foreach($x as $xx) {
+ @unlink(dbunescbin($xx['content']));
+ }
+ }
+
return;
}
@@ -198,7 +209,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
where xchan_hash = '%s'",
dbesc($im->getType()),
- dbesc(datetime_convert()),
+ dbescdate($base_image['edited']),
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
@@ -245,7 +256,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
else {
require_once('include/attach.php');
- $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash));
+ $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash, 'nosync' => true));
logger('attach_store: ' . print_r($res,true));
}
@@ -353,20 +364,23 @@ class Profile_photo extends \Zotlabs\Web\Controller {
if($havescale) {
// unset any existing profile photos
- $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
+ $x = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE),
- intval(local_channel()));
-
- $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'",
+ intval(local_channel())
+ );
+
+ $edited = datetime_convert();
+
+ $x = q("UPDATE photo SET photo_usage = %d, edited = '%s' WHERE uid = %d AND resource_id = '%s' AND imgscale > 0",
intval(PHOTO_PROFILE),
+ dbescdate($edited),
intval(local_channel()),
dbesc($resource_id)
- );
+ );
- $r = q("UPDATE xchan set xchan_photo_date = '%s'
- where xchan_hash = '%s'",
- dbesc(datetime_convert()),
+ $x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'",
+ dbescdate($edited),
dbesc($channel['xchan_hash'])
);
diff --git a/Zotlabs/Photo/PhotoDriver.php b/Zotlabs/Photo/PhotoDriver.php
index c47a7c3b2..c1993ac20 100644
--- a/Zotlabs/Photo/PhotoDriver.php
+++ b/Zotlabs/Photo/PhotoDriver.php
@@ -448,6 +448,7 @@ abstract class PhotoDriver {
$p['width'] = (($arr['width']) ? $arr['width'] : $this->getWidth());
$p['height'] = (($arr['height']) ? $arr['height'] : $this->getHeight());
$p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system', 'photo_cache_time', 86400)));
+ $p['profile'] = ((array_key_exists('profile', $arr)) ? intval($arr['profile']) : 0);
if(! intval($p['imgscale']))
logger('save: ' . print_r($arr, true), LOGGER_DATA);
@@ -481,18 +482,47 @@ abstract class PhotoDriver {
allow_gid = '%s',
deny_cid = '%s',
deny_gid = '%s',
- expires = '%s'
+ expires = '%s',
+ profile = %d
where id = %d",
- intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($x[0]['id']));
+ intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']), intval($x[0]['id']));
} else {
$p['created'] = (($arr['created']) ? $arr['created'] : $p['edited']);
$r = q("INSERT INTO photo
- ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']));
+ ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires, profile )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']));
}
logger('Photo save imgscale ' . $p['imgscale'] . ' returned ' . intval($r));
return $r;
}
+
+ /**
+ * @brief Stores thumbnail to database or filesystem.
+ *
+ * @param array $arr
+ * @param scale int
+ * @return boolean|array
+ */
+ public function storeThumbnail($arr, $scale = 0) {
+
+ $arr['imgscale'] = $scale;
+
+ if(boolval(get_config('system','filesystem_storage_thumbnails', 0)) && $scale > 0) {
+ $channel = \App::get_channel();
+ $arr['os_storage'] = 1;
+ $arr['os_syspath'] = 'store/' . $channel['channel_address'] . '/' . $arr['os_path'] . '-' . $scale;
+ if(! $this->saveImage($arr['os_syspath']))
+ return false;
+ }
+
+ if(! $this->save($arr)) {
+ if(array_key_exists('os_syspath', $arr))
+ @unlink($arr['os_syspath']);
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/boot.php b/boot.php
index 118443df9..6664e80cf 100755
--- a/boot.php
+++ b/boot.php
@@ -50,7 +50,7 @@ require_once('include/attach.php');
require_once('include/bbcode.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
-define ( 'STD_VERSION', '4.1.1' );
+define ( 'STD_VERSION', '4.1.2' );
define ( 'ZOT_REVISION', '6.0a' );
define ( 'DB_UPDATE_VERSION', 1231 );
diff --git a/include/attach.php b/include/attach.php
index f6594b154..f169e0669 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -1521,6 +1521,17 @@ function attach_drop_photo($channel_id,$resource) {
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
}
+
+ $r = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1",
+ dbesc($resource),
+ intval($channel_id)
+ );
+ if($r) {
+ foreach($r as $i) {
+ @unlink(dbunescbin($i['content']));
+ }
+ }
+
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)
diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php
index 5002f53e7..a70e4a1d7 100755
--- a/include/dba/dba_pdo.php
+++ b/include/dba/dba_pdo.php
@@ -19,7 +19,7 @@ class dba_pdo extends dba_driver {
$this->driver_dbtype = $scheme;
if(strpbrk($server,':;')) {
- $dsn = $server;
+ $dsn = $this->driver_dbtype . ':unix_socket=' . trim($server, ':;');
}
else {
$dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : '');
diff --git a/include/import.php b/include/import.php
index 7a1e9aa55..434a53f10 100644
--- a/include/import.php
+++ b/include/import.php
@@ -1345,6 +1345,7 @@ function sync_files($channel, $files) {
logger('attachment store failed',LOGGER_NORMAL,LOG_ERR);
}
if($f['photo']) {
+
foreach($f['photo'] as $p) {
unset($p['id']);
$p['aid'] = $channel['channel_account_id'];
@@ -1366,6 +1367,7 @@ function sync_files($channel, $files) {
dbesc($p['resource_id']),
intval($channel['channel_id'])
);
+ $update_xchan = $p['edited'];
}
// same for cover photos
@@ -1385,19 +1387,20 @@ function sync_files($channel, $files) {
else
$p['content'] = (($p['content'])? base64_decode($p['content']) : '');
- if(intval($p['imgscale']) && (! $p['content'])) {
+ if(intval($p['imgscale']) && (! empty($p['content']))) {
$time = datetime_convert();
- $parr = array('hash' => $channel['channel_hash'],
+ $parr = array(
+ 'hash' => $channel['channel_hash'],
'time' => $time,
- 'resource' => $att['hash'],
+ 'resource' => $p['resource_id'],
'revision' => 0,
'signature' => base64url_encode(rsa_sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey'])),
- 'resolution' => $p['imgscale']
+ 'resolution' => intval($p['imgscale'])
);
- $stored_image = $newfname . '-' . intval($p['imgscale']);
+ $stored_image = $newfname . '-' . $p['imgscale'];
$fp = fopen($stored_image,'w');
if(! $fp) {
@@ -1406,7 +1409,6 @@ function sync_files($channel, $files) {
}
$redirects = 0;
-
$headers = [];
$headers['Accept'] = 'application/x-zot+json' ;
$headers['Sigtoken'] = random_string();
@@ -1414,8 +1416,18 @@ function sync_files($channel, $files) {
$x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]);
fclose($fp);
- $p['content'] = file_get_contents($stored_image);
- unlink($stored_image);
+
+ // Override remote hub thumbnails storage settings
+ if(! boolval(get_config('system','filesystem_storage_thumbnails', 0))) {
+ $p['os_storage'] = 0;
+ $p['content'] = file_get_contents($stored_image);
+ @unlink($stored_image);
+ }
+ else {
+ $p['os_storage'] = 1;
+ $p['content'] = $stored_image;
+ $p['os_syspath'] = $stored_image;
+ }
}
if(!isset($p['display_path']))
@@ -1447,6 +1459,16 @@ function sync_files($channel, $files) {
create_table_from_array('photo',$p, [ 'content' ] );
}
}
+
+ }
+
+ // Set xchan photo date to prevent thumbnails fetch for clones on profile update packet recieve
+ if(isset($update_xchan)) {
+
+ $x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'",
+ dbescdate($update_xchan),
+ dbesc($channel['channel_hash'])
+ );
}
\Zotlabs\Daemon\Master::Summon([ 'Thumbnail' , $att['hash'] ]);
diff --git a/include/photos.php b/include/photos.php
index 44406e0b0..7ea2729ae 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -277,8 +277,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 1024 || $height > 1024) && (! $errors))
$ph->scaleImage(1024);
- $p['imgscale'] = 1;
- $r1 = $ph->save($p);
+ $r1 = $ph->storeThumbnail($p, PHOTO_RES_1024);
$link[1] = array(
'rel' => 'alternate',
'type' => 'text/html',
@@ -292,8 +291,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 640 || $height > 640) && (! $errors))
$ph->scaleImage(640);
- $p['imgscale'] = 2;
- $r2 = $ph->save($p);
+ $r2 = $ph->storeThumbnail($p, PHOTO_RES_640);
$link[2] = array(
'rel' => 'alternate',
'type' => 'text/html',
@@ -307,8 +305,7 @@ function photo_upload($channel, $observer, $args) {
if(($width > 320 || $height > 320) && (! $errors))
$ph->scaleImage(320);
- $p['imgscale'] = 3;
- $r3 = $ph->save($p);
+ $r3 = $ph->storeThumbnail($p, PHOTO_RES_320);
$link[3] = array(
'rel' => 'alternate',
'type' => 'text/html',
diff --git a/include/zot.php b/include/zot.php
index 227d82a13..9f2321bc4 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -925,46 +925,62 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
$local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1",
dbesc($xchan_hash)
);
+
if($local) {
+ // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied
+ // on most hubs in the network
+ // <---
$ph = z_fetch_url($arr['photo'], true);
+
if($ph['success']) {
+
+ // Do not fetch already received thumbnails
+ $x = q("SELECT resource_id FROM photo WHERE uid = %d AND imgscale = %d AND filesize = %d LIMIT 1",
+ intval($local[0]['channel_id']),
+ intval(PHOTO_RES_PROFILE_300),
+ strlen($ph['body'])
+ );
+
+ if($x)
+ $hash = $x[0]['resource_id'];
+ else
+ $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
+ }
+
+ if($hash) {
+ // unless proven otherwise
+ $is_default_profile = 1;
+
+ $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ if($profile) {
+ if(! intval($profile[0]['is_default']))
+ $is_default_profile = 0;
+ }
- $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
-
- if($hash) {
- // unless proven otherwise
- $is_default_profile = 1;
-
- $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ // If setting for the default profile, unset the profile photo flag from any other photos I own
+ if($is_default_profile) {
+ q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE),
+ dbesc($hash),
intval($local[0]['channel_account_id']),
intval($local[0]['channel_id'])
);
- if($profile) {
- if(! intval($profile[0]['is_default']))
- $is_default_profile = 0;
- }
-
- // If setting for the default profile, unset the profile photo flag from any other photos I own
- if($is_default_profile) {
- q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
- intval(PHOTO_NORMAL),
- intval(PHOTO_PROFILE),
- dbesc($hash),
- intval($local[0]['channel_account_id']),
- intval($local[0]['channel_id'])
- );
- }
}
-
- // reset the names in case they got messed up when we had a bug in this function
- $photos = array(
- z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
- z_root() . '/photo/profile/m/' . $local[0]['channel_id'],
- z_root() . '/photo/profile/s/' . $local[0]['channel_id'],
- $arr['photo_mimetype'],
- false
- );
}
+ // --->
+
+ // reset the names in case they got messed up when we had a bug in this function
+ $photos = array(
+ z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
+ z_root() . '/photo/profile/m/' . $local[0]['channel_id'],
+ z_root() . '/photo/profile/s/' . $local[0]['channel_id'],
+ $arr['photo_mimetype'],
+ false
+ );
}
else {
$photos = import_xchan_photo($arr['photo'], $xchan_hash);
diff --git a/install/INSTALL.txt b/install/INSTALL.txt
index fe2484d7a..0503ae2cc 100644
--- a/install/INSTALL.txt
+++ b/install/INSTALL.txt
@@ -175,7 +175,7 @@ encounter a database configuration which cannot be expressed on the setup form
(for instance using MySQL with an unusual socket location); you can supply
the PDO connection string as the database hostname. For instance
- mysql:unix_socket=/my/special/socket_path
+ :/path/to/socket.file
You should still fill in all other applicable form values as needed.
diff --git a/install/htconfig.sample.php b/install/htconfig.sample.php
index 07725e3f4..509942530 100755
--- a/install/htconfig.sample.php
+++ b/install/htconfig.sample.php
@@ -12,7 +12,7 @@
// Then set the following for your MySQL installation
-$db_host = 'your.mysqlhost.com'; // Use 'localhost' if you aren't using a remote server
+$db_host = 'your.mysqlhost.com'; // Use 'localhost' or ':/path/to/socket.file' if you aren't using a remote server
$db_port = 0; // leave 0 for default or set your port
$db_user = 'mysqlusername';
$db_pass = 'mysqlpassword';
diff --git a/library/fullcalendar/CHANGELOG.txt b/library/fullcalendar.old/CHANGELOG.txt
index 379f23691..379f23691 100644
--- a/library/fullcalendar/CHANGELOG.txt
+++ b/library/fullcalendar.old/CHANGELOG.txt
diff --git a/library/fullcalendar/CONTRIBUTING.txt b/library/fullcalendar.old/CONTRIBUTING.txt
index 74084517b..74084517b 100644
--- a/library/fullcalendar/CONTRIBUTING.txt
+++ b/library/fullcalendar.old/CONTRIBUTING.txt
diff --git a/library/fullcalendar.old/LICENSE.txt b/library/fullcalendar.old/LICENSE.txt
new file mode 100644
index 000000000..eafaf97ec
--- /dev/null
+++ b/library/fullcalendar.old/LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2015 Adam Shaw
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/library/fullcalendar/fullcalendar.css b/library/fullcalendar.old/fullcalendar.css
index a2f76c960..a2f76c960 100644
--- a/library/fullcalendar/fullcalendar.css
+++ b/library/fullcalendar.old/fullcalendar.css
diff --git a/library/fullcalendar/fullcalendar.js b/library/fullcalendar.old/fullcalendar.js
index 04399302b..04399302b 100644
--- a/library/fullcalendar/fullcalendar.js
+++ b/library/fullcalendar.old/fullcalendar.js
diff --git a/library/fullcalendar/fullcalendar.min.css b/library/fullcalendar.old/fullcalendar.min.css
index 255dbfffa..255dbfffa 100644
--- a/library/fullcalendar/fullcalendar.min.css
+++ b/library/fullcalendar.old/fullcalendar.min.css
diff --git a/library/fullcalendar/fullcalendar.min.js b/library/fullcalendar.old/fullcalendar.min.js
index c5eb8c751..c5eb8c751 100644
--- a/library/fullcalendar/fullcalendar.min.js
+++ b/library/fullcalendar.old/fullcalendar.min.js
diff --git a/library/fullcalendar/fullcalendar.print.css b/library/fullcalendar.old/fullcalendar.print.css
index c92bdd9df..c92bdd9df 100644
--- a/library/fullcalendar/fullcalendar.print.css
+++ b/library/fullcalendar.old/fullcalendar.print.css
diff --git a/library/fullcalendar/fullcalendar.print.min.css b/library/fullcalendar.old/fullcalendar.print.min.css
index c193968d7..c193968d7 100644
--- a/library/fullcalendar/fullcalendar.print.min.css
+++ b/library/fullcalendar.old/fullcalendar.print.min.css
diff --git a/library/fullcalendar/gcal.js b/library/fullcalendar.old/gcal.js
index 7e895337e..7e895337e 100644
--- a/library/fullcalendar/gcal.js
+++ b/library/fullcalendar.old/gcal.js
diff --git a/library/fullcalendar/gcal.min.js b/library/fullcalendar.old/gcal.min.js
index 02e7ea4d5..02e7ea4d5 100644
--- a/library/fullcalendar/gcal.min.js
+++ b/library/fullcalendar.old/gcal.min.js
diff --git a/library/fullcalendar/locale-all.js b/library/fullcalendar.old/locale-all.js
index 689a86e07..689a86e07 100644
--- a/library/fullcalendar/locale-all.js
+++ b/library/fullcalendar.old/locale-all.js
diff --git a/library/fullcalendar/CHANGELOG.md b/library/fullcalendar/CHANGELOG.md
new file mode 100644
index 000000000..2687cd8e7
--- /dev/null
+++ b/library/fullcalendar/CHANGELOG.md
@@ -0,0 +1,1377 @@
+
+v4.0.2 (2019-04-03)
+-------------------
+
+Bugfixes:
+- eventAllow and constraints not respected when dragging event between calendars
+- viewSkeletonRender now in typedefs (#4589)
+- invalid draggedEvent properties in eventAllow for external dnd (#4575)
+- forceEventDuration not working with external dnd (#4597)
+- rrule displaying time when allDay is true (#4576)
+- rrule events not displaying at interval start (#4596)
+- prev button not initially working when starting on 31st of a month (#4595)
+- clicking X in popover generating a dayClick (#4584)
+- locale file used as single script tag not affecting calendar locale (#4581)
+- header "today" button not translated for pt and pt-br (#4591)
+- fa locale typo (#4582)
+
+
+v4.0.1 (2019-03-18)
+-------------------
+
+Read about all the changes in v4:
+https://fullcalendar.io/docs/upgrading-from-v3
+
+Obscure breaking changes from v3->v4 not mentioned elsewhere:
+- `touchMouseIgnoreWait` moved to `(packageRoot).config.touchMouseIgnoreWait`
+- `dataAttrPrefix` moved to `(packageRoot).config.dataAttrPrefix`
+
+Advancements since latest prerelease:
+- New styling for buttons and icons in header. New styling for events.
+- Bugfixes: #4539, #4503, #4534, #4505, #4477, #4467, #4454, #4458, #4483,
+ #4517, #4506, #4435, #4498, #4497, #4446, #4432, #4530
+
+NOTE: version "4.0.0" was skipped because of an NPM publishing error
+
+
+v3.10.0 (2019-01-10)
+--------------------
+
+POTENTIALLY BREAKING CHANGE:
+The jquery and moment packages have been moved to peerDependencies. If you are using
+NPM to install fullcalendar, you'll need to explicitly add jquery and moment as
+dependencies of your project. NPM will not install them automatically. (#4136, #4233)
+
+New Features:
+- events from a Google Calendar event source will receive extended props (#4123)
+- export more classes and util functions (#4124)
+- new locales: zh-hk (#4266), be (#4274)
+
+Bugfixes:
+- not accepting dayClicks/selects because of overflow-x:hidden on html/body (#3615)
+- event end time not displayed when duration is one slot, in agenda view (#3049)
+- switching views before event fetch resolves, JS error (#3689)
+- single-day allDay event not showing when time is specified (#3854)
+- prev button doesn't work when previous days are hidden by hiddenDays and dayCount
+ is greater than dateIncrement (#4202)
+- calendar locale not used in all moments objects (#4174)
+- background event background color does not completely fill cells in Chrome (#4145)
+- provide a delta for eventResize when resizing from start (#4135)
+- IE11 memory leak from not removing handler correctly (#4311)
+- make touchstart handlers passive (#4087)
+- fixed typescript definition for: eventAllow (#4243), selectAllow (#4319)
+- fixed locales: de (#4197, #4371), hu (#4203), tr (#4312), ja (#4329)
+
+
+v3.9.0 (2018-03-04)
+-------------------
+
+- Bootstrap 4 support (#4032, #4065, thx @GeekJosh)
+- add OptionsInput to the fullcalendar.d.ts exports (#4040, #4006)
+- columnHeaderFormat/columnHeaderHtml/columnHeaderText in .d.ts file (#4061, #4085)
+- list-view auto-height not working (#3346, #4071, thx @WhatTheBuild)
+- bump momentjs minimum version to 2.20.1, for locale fixes (#4014)
+- swedish week header translation fix (#4082)
+- dutch year translation (#4069)
+
+
+v3.8.2 (2018-01-30)
+-------------------
+
+Bugfixes:
+- Fix TypeScript definitions file with strictNullChecks (#4035)
+
+
+v3.8.1 (2018-01-28)
+-------------------
+
+Bugfixes:
+- TypeScript definition file not compatible with noImplicitAny (#4017)
+- ES6 classes are not supported for grid class (#3437)
+- day numbers in month view should be localized (#3339)
+- select helper is resizable, causes js error (#3764)
+- selecting over existing select helper causes js error (#4031)
+- eventOrder doesn't work on custom fields (#3950)
+- aria label on button icons (#4023)
+- dynamic option changes to select/overlap/allow doesn't cause rerender
+
+Locales:
+- added Georgian (#3994)
+- added Bosnian (#4029)
+
+
+v3.8.0 (2017-12-18)
+-------------------
+
+- new settings for month/agenda/basic views (#3078):
+ - `columnHeaderFormat` (renamed from `columnFormat`)
+ - `columnHeaderText`
+ - `columnHeaderHtml`
+- TypeScript definition file (fullcalendar.d.ts) included in npm package (#3889)
+- codebase using SASS, though not taking advantage of it yet (#3463)
+- codebase fully ported to TypeScript / Webpack
+- Afrikaans locale fix (#3862)
+
+
+v3.7.0 (2017-11-13)
+-------------------
+
+Bugfixes:
+- `render` method does not re-adjust calendar dimension (#3893)
+- when custom view navigates completely into hidden weekends, JS error ([scheduler-375])
+
+Other:
+- in themes.html demo, fixed broken Bootswatch themes (#3917)
+- moved JavaScript codebase over to TypeScript
+ (same external API; embedded typedefs coming soon)
+
+[scheduler-375]: https://github.com/fullcalendar/fullcalendar-scheduler/issues/375
+
+
+v3.6.2 (2017-10-23)
+-------------------
+
+Bugfixes:
+- Google Calendar event sources not calling `loading` callback (#3884)
+- `eventDataTransform` w/ eventConstraint shouldn't be called during event resizing (#3859)
+- `navLinks` would go to the previously navigated date (#3869)
+- `nowIndicator` arrow would repeatedly render (#3872)
+- fc-content-skeleton DOM element would repeatedly render on navigation in agenda view
+
+
+v3.6.1 (2017-10-11)
+-------------------
+
+Bugfixes:
+- JSON feed event sources always requesting current page (#3865)
+- multi-day events appearing multiple times in more+ popover (#3856)
+
+
+v3.6.0 (2017-10-10)
+-------------------
+
+Features:
+- `agendaEventMinHeight` for guaranteeing height (#961, #3788) thx @Stafie
+- `columnHeader` can be set to `false` to hide headings (#3438, #3787) thx @caseyjhol
+- export all View classes (#2851, #3831)
+- `updateEvent`, update complex attributes (#2864)
+- Albanian locale (#3847) thx @alensaqe
+
+Bugfixes:
+- objects used as non-standard Event properties ignored by `updateEvent` (#3839)
+- listDay error if event goes over period (#3843)
+- `validDays` with `hiddenDays`, js error when no days active (#3846)
+- json feed Event Source object no longer has `url` property (#3845)
+- `updateEvent`, allDay to timed, when no end, wrong end date (#3144)
+- `removeEvents` by `_id` stopped working (#3828)
+- correct `this` context in FuncEventSource (#3848) thx @declspec
+- js event not received in unselect callback when selecting another cell (#3832)
+
+Incompatibilities:
+- The `viewRender` callback might now be fired AFTER events have been rendered
+ to the DOM. However, the eventRender/eventAfterRender/eventAfterAllRender callbacks
+ will always be fired after `viewRender`, just as before.
+- The internal `Grid` class (accessed via `$.fullCalendar.Grid`) has been removed.
+ For monkeypatching, use DayGrid/TimeGrid directly.
+
+
+v3.5.1 (2017-09-06)
+-------------------
+
+- fixed loading trigger not firing (#3810)
+- fixed overaggressively fetching events, on option changes (#3820)
+- fixed event object `date` property being discarded (tho still parsed) (#3819)
+- fixed event object `_id` property being discarded (#3811)
+
+
+v3.5.0 (2017-08-30)
+-------------------
+
+Features:
+- Bootstrap 3 theme support (#2334, #3566)
+ - via `themeSystem: 'bootstrap3'` (the `theme` option is deprecated)
+ - new `bootstrapGlyphicons` option
+ - jQuery UI "Cupertino" theme no longer included in zip archive
+ - improved theme switcher on demo page (#1436)
+ (big thanks to @joankaradimov)
+- 25% event rendering performance improvement across the board (#2524)
+- console message for unknown method/calendar (#3253)
+- Serbian cyrilic/latin (#3656)
+- available via Packagist (#2999, #3617)
+
+Bugfixes:
+- slot time label invisible when minTime starts out of alignment (#2786)
+- bug with inverse-background event rendering when out of range (#3652)
+- wrongly disabled prev/next when current date outside of validRange (#3686, #3651)
+- updateEvent, error when changing allDay from false to true (#3518)
+- updateEvent doesn't support ID changes (#2928)
+- Promise then method doesn't forward result (#3744)
+- Korean typo (#3693)
+- fixed switching from any view to listview, eventAfterRender isn't called (#3751)
+
+Incompatibilities:
+- Event Objects obtained from clientEvents or various callbacks are no longer
+ references to internally used objects. Rather, they are static object copies.
+- `clientEvents` method no longer returns events in same order as received.
+ Do not depend on order.
+
+
+v3.4.0 (2017-04-27)
+-------------------
+
+- composer.json for Composer (PHP package manager) (#3617)
+- fix toISOString for locales with non-trivial postformatting (#3619)
+- fix for nested inverse-background events (#3609)
+- Estonian locale (#3600)
+- fixed Latvian localization (#3525)
+- internal refactor of async systems
+
+
+v3.3.1 (2017-04-01)
+-------------------
+
+Bugfixes:
+- stale calendar title when navigate away from then back to the a view (#3604)
+- js error when gotoDate immediately after calendar initialization (#3598)
+- agenda view scrollbars causes misalignment in jquery 3.2.1 (#3612)
+- navigation bug when trying to navigate to a day of another week (#3610)
+- dateIncrement not working when duration and dateIncrement have different units
+
+
+v3.3.0 (2017-03-23)
+-------------------
+
+Features:
+- `visibleRange` - complete control over view's date range (#2847, #3105, #3245)
+- `validRange` - restrict date range (#429)
+- `changeView` - pass in a date or visibleRange as second param (#3366)
+- `dateIncrement` - customize prev/next jump (#2710)
+- `dateAlignment` - custom view alignment, like start-of-week (#3113)
+- `dayCount` - force a fixed number-of-days, even with hiddenDays (#2753)
+- `showNonCurrentDates` - option to hide day cells for prev/next months (#437)
+- can define a defaultView with a duration/visibleRange/dayCount with needing
+ to create a custom view in the `views` object. Known as a "Generic View".
+
+Behavior Changes:
+- when custom view is specified with duration `{days:7}`,
+ it will no longer align with the start of the week. (#2847)
+- when `gotoDate` is called on a custom view with a duration of multiple days,
+ the view will always shift to begin with the given date. (#3515)
+
+Bugfixes:
+- event rendering when excessive `minTime`/`maxTime` (#2530)
+- event dragging not shown when excessive `minTime`/`maxTime` (#3055)
+- excessive `minTime`/`maxTime` not reflected in event fetching (#3514)
+ - when minTime is negative, or maxTime beyond 24 hours, when event data is requested
+ via a function or a feed, the given data params will have time parts.
+- external event dragging via touchpunch broken (#3544)
+- can't make an immediate new selection after existing selection, with mouse.
+ introduced in v3.2.0 (#3558)
+
+
+v3.2.0 (2017-02-14)
+-------------------
+
+Features:
+- `selectMinDistance`, threshold before a mouse selection begins (#2428)
+
+Bugfixes:
+- iOS 10, unwanted scrolling while dragging events/selection (#3403)
+- dayClick triggered when swiping on touch devices (#3332)
+- dayClick not functioning on Firefix mobile (#3450)
+- title computed incorrectly for views with no weekends (#2884)
+- unwanted scrollbars in month-view when non-integer width (#3453, #3444)
+- incorrect date formatting for locales with non-standlone month/day names (#3478)
+- date formatting, incorrect omission of trailing period for certain locales (#2504, #3486)
+- formatRange should collapse same week numbers (#3467)
+- Taiwanese locale updated (#3426)
+- Finnish noEventsMessage updated (#3476)
+- Croatian (hr) buttonText is blank (#3270)
+- JSON feed PHP example, date range math bug (#3485)
+
+
+v3.1.0 (2016-12-05)
+-------------------
+
+- experimental support for implicitly batched ("debounced") event rendering (#2938)
+ - `eventRenderWait` (off by default)
+- new `footer` option, similar to header toolbar (#654, #3299)
+- event rendering batch methods (#3351):
+ - `renderEvents`
+ - `updateEvents`
+- more granular touch settings (#3377):
+ - `eventLongPressDelay`
+ - `selectLongPressDelay`
+- eventDestroy not called when removing the popover (#3416, #3419)
+- print stylesheet and gcal extension now offered as minified (#3415)
+- fc-today in agenda header cells (#3361, #3365)
+- height-related options in tandem with other options (#3327, #3384)
+- Kazakh locale (#3394)
+- Afrikaans locale (#3390)
+- internal refactor related to timing of rendering and firing handlers.
+ calls to rerender the current date-range and events from within handlers
+ might not execute immediately. instead, will execute after handler finishes.
+
+
+v3.0.1 (2016-09-26)
+-------------------
+
+Bugfixes:
+- list view rendering event times incorrectly (#3334)
+- list view rendering events/days out of order (#3347)
+- events with no title rendering as "undefined"
+- add .fc scope to table print styles (#3343)
+- "display no events" text fix for German (#3354)
+
+
+v3.0.0 (2016-09-04)
+-------------------
+
+Features:
+- List View (#560)
+ - new views: `listDay`, `listWeek`, `listMonth`, `listYear`, and simply `list`
+ - `listDayFormat`
+ - `listDayAltFormat`
+ - `noEventsMessage`
+- Clickable day/week numbers for easier navigation (#424)
+ - `navLinks`
+ - `navLinkDayClick`
+ - `navLinkWeekClick`
+- Programmatically allow/disallow user interactions:
+ - `eventAllow` (#2740)
+ - `selectAllow` (#2511)
+- Option to display week numbers in cells (#3024)
+ - `weekNumbersWithinDays` (set to `true` to activate)
+- When week calc is ISO, default first day-of-week to Monday (#3255)
+- Macedonian locale (#2739)
+- Malay locale
+
+Breaking Changes:
+- IE8 support dropped
+- jQuery: minimum support raised to v2.0.0
+- MomentJS: minimum support raised to v2.9.0
+- `lang` option renamed to `locale`
+- dist files have been renamed to be more consistent with MomentJS:
+ - `lang/` -> `locale/`
+ - `lang-all.js` -> `locale-all.js`
+- behavior of moment methods no longer affected by ambiguousness:
+ - `isSame`
+ - `isBefore`
+ - `isAfter`
+- View-Option-Hashes no longer supported (deprecated in 2.2.4)
+- removed `weekMode` setting
+- removed `axisFormat` setting
+- DOM structure of month/basic-view day cell numbers changed
+
+Bugfixes:
+- `$.fullCalendar.version` incorrect (#3292)
+
+Build System:
+- using gulp instead of grunt (faster)
+- using npm internally for dependencies instead of bower
+- changed repo directory structure
+
+
+v2.9.1 (2016-07-31)
+-------------------
+
+- multiple definitions for businessHours (#2686)
+- businessHours for single day doesn't display weekends (#2944)
+- height/contentHeight can accept a function or 'parent' for dynamic value (#3271)
+- fix +more popover clipped by overflow (#3232)
+- fix +more popover positioned incorrectly when scrolled (#3137)
+- Norwegian Nynorsk translation (#3246)
+- fix isAnimating JS error (#3285)
+
+
+v2.9.0 (2016-07-10)
+-------------------
+
+- Setters for (almost) all options (#564).
+ See [docs](http://fullcalendar.io/docs/utilities/dynamic_options/) for more info.
+- Travis CI improvements (#3266)
+
+
+v2.8.0 (2016-06-19)
+-------------------
+
+- getEventSources method (#3103, #2433)
+- getEventSourceById method (#3223)
+- refetchEventSources method (#3103, #1328, #254)
+- removeEventSources method (#3165, #948)
+- prevent flicker when refetchEvents is called (#3123, #2558)
+- fix for removing event sources that share same URL (#3209)
+- jQuery 3 support (#3197, #3124)
+- Travis CI integration (#3218)
+- EditorConfig for promoting consistent code style (#141)
+- use en dash when formatting ranges (#3077)
+- height:auto always shows scrollbars in month view on FF (#3202)
+- new languages:
+ - Basque (#2992)
+ - Galician (#194)
+ - Luxembourgish (#2979)
+
+
+v2.7.3 (2016-06-02)
+-------------------
+
+internal enhancements that plugins can benefit from:
+- EventEmitter not correctly working with stopListeningTo
+- normalizeEvent hook for manipulating event data
+
+
+v2.7.2 (2016-05-20)
+-------------------
+
+- fixed desktops/laptops with touch support not accepting mouse events for
+ dayClick/dragging/resizing (#3154, #3149)
+- fixed dayClick incorrectly triggered on touch scroll (#3152)
+- fixed touch event dragging wrongfully beginning upon scrolling document (#3160)
+- fixed minified JS still contained comments
+- UI change: mouse users must hover over an event to reveal its resizers
+
+
+v2.7.1 (2016-05-01)
+-------------------
+
+- dayClick not firing on touch devices (#3138)
+- icons for prev/next not working in MS Edge (#2852)
+- fix bad languages troubles with firewalls (#3133, #3132)
+- update all dev dependencies (#3145, #3010, #2901, #251)
+- git-ignore npm debug logs (#3011)
+- misc automated test updates (#3139, #3147)
+- Google Calendar htmlLink not always defined (#2844)
+
+
+v2.7.0 (2016-04-23)
+-------------------
+
+touch device support (#994):
+ - smoother scrolling
+ - interactions initiated via "long press":
+ - event drag-n-drop
+ - event resize
+ - time-range selecting
+ - `longPressDelay`
+
+
+v2.6.1 (2016-02-17)
+-------------------
+
+- make `nowIndicator` positioning refresh on window resize
+
+
+v2.6.0 (2016-01-07)
+-------------------
+
+- current time indicator (#414)
+- bundled with most recent version of moment (2.11.0)
+- UMD wrapper around lang files now handles commonjs (#2918)
+- fix bug where external event dragging would not respect eventOverlap
+- fix bug where external event dropping would not render the whole-day highlight
+
+
+v2.5.0 (2015-11-30)
+-------------------
+
+- internal timezone refactor. fixes #2396, #2900, #2945, #2711
+- internal "grid" system refactor. improved API for plugins.
+
+
+v2.4.0 (2015-08-16)
+-------------------
+
+- add new buttons to the header via `customButtons` ([225])
+- control stacking order of events via `eventOrder` ([364])
+- control frequency of slot text via `slotLabelInterval` ([946])
+- `displayEventTime` ([1904])
+- `on` and `off` methods ([1910])
+- renamed `axisFormat` to `slotLabelFormat`
+
+[225]: https://code.google.com/p/fullcalendar/issues/detail?id=225
+[364]: https://code.google.com/p/fullcalendar/issues/detail?id=364
+[946]: https://code.google.com/p/fullcalendar/issues/detail?id=946
+[1904]: https://code.google.com/p/fullcalendar/issues/detail?id=1904
+[1910]: https://code.google.com/p/fullcalendar/issues/detail?id=1910
+
+
+v2.3.2 (2015-06-14)
+-------------------
+
+- minor code adjustment in preparation for plugins
+
+
+v2.3.1 (2015-03-08)
+-------------------
+
+- Fix week view column title for en-gb ([PR220])
+- Publish to NPM ([2447])
+- Detangle bower from npm package ([PR179])
+
+[PR220]: https://github.com/arshaw/fullcalendar/pull/220
+[2447]: https://code.google.com/p/fullcalendar/issues/detail?id=2447
+[PR179]: https://github.com/arshaw/fullcalendar/pull/179
+
+
+v2.3.0 (2015-02-21)
+-------------------
+
+- internal refactoring in preparation for other views
+- businessHours now renders on whole-days in addition to timed areas
+- events in "more" popover not sorted by time ([2385])
+- avoid using moment's deprecated zone method ([2443])
+- destroying the calendar sometimes causes all window resize handlers to be unbound ([2432])
+- multiple calendars on one page, can't accept external elements after navigating ([2433])
+- accept external events from jqui sortable ([1698])
+- external jqui drop processed before reverting ([1661])
+- IE8 fix: month view renders incorrectly ([2428])
+- IE8 fix: eventLimit:true wouldn't activate "more" link ([2330])
+- IE8 fix: dragging an event with an href
+- IE8 fix: invisible element while dragging agenda view events
+- IE8 fix: erratic external element dragging
+
+[2385]: https://code.google.com/p/fullcalendar/issues/detail?id=2385
+[2443]: https://code.google.com/p/fullcalendar/issues/detail?id=2443
+[2432]: https://code.google.com/p/fullcalendar/issues/detail?id=2432
+[2433]: https://code.google.com/p/fullcalendar/issues/detail?id=2433
+[1698]: https://code.google.com/p/fullcalendar/issues/detail?id=1698
+[1661]: https://code.google.com/p/fullcalendar/issues/detail?id=1661
+[2428]: https://code.google.com/p/fullcalendar/issues/detail?id=2428
+[2330]: https://code.google.com/p/fullcalendar/issues/detail?id=2330
+
+
+v2.2.7 (2015-02-10)
+-------------------
+
+- view.title wasn't defined in viewRender callback ([2407])
+- FullCalendar versions >= 2.2.5 brokenness with Moment versions <= 2.8.3 ([2417])
+- Support Bokmal Norwegian language specifically ([2427])
+
+[2407]: https://code.google.com/p/fullcalendar/issues/detail?id=2407
+[2417]: https://code.google.com/p/fullcalendar/issues/detail?id=2417
+[2427]: https://code.google.com/p/fullcalendar/issues/detail?id=2427
+
+
+v2.2.6 (2015-01-11)
+-------------------
+
+- Compatibility with Moment v2.9. Was breaking GCal plugin ([2408])
+- View object's `title` property mistakenly omitted ([2407])
+- Single-day views with hiddens days could cause prev/next misbehavior ([2406])
+- Don't let the current date ever be a hidden day (solves [2395])
+- Hebrew locale ([2157])
+
+[2408]: https://code.google.com/p/fullcalendar/issues/detail?id=2408
+[2407]: https://code.google.com/p/fullcalendar/issues/detail?id=2407
+[2406]: https://code.google.com/p/fullcalendar/issues/detail?id=2406
+[2395]: https://code.google.com/p/fullcalendar/issues/detail?id=2395
+[2157]: https://code.google.com/p/fullcalendar/issues/detail?id=2157
+
+
+v2.2.5 (2014-12-30)
+-------------------
+
+- `buttonText` specified for custom views via the `views` option
+ - bugfix: wrong default value, couldn't override default
+ - feature: default value taken from locale
+
+
+v2.2.4 (2014-12-29)
+-------------------
+
+- Arbitrary durations for basic/agenda views with the `views` option ([692])
+- Specify view-specific options using the `views` option. fixes [2283]
+- Deprecate view-option-hashes
+- Formalize and expose View API ([1055])
+- updateEvent method, more intuitive behavior. fixes [2194]
+
+[692]: https://code.google.com/p/fullcalendar/issues/detail?id=692
+[2283]: https://code.google.com/p/fullcalendar/issues/detail?id=2283
+[1055]: https://code.google.com/p/fullcalendar/issues/detail?id=1055
+[2194]: https://code.google.com/p/fullcalendar/issues/detail?id=2194
+
+
+v2.2.3 (2014-11-26)
+-------------------
+
+- removeEventSource with Google Calendar object source, would not remove ([2368])
+- Events with invalid end dates are still accepted and rendered ([2350], [2237], [2296])
+- Bug when rendering business hours and navigating away from original view ([2365])
+- Links to Google Calendar events will use current timezone ([2122])
+- Google Calendar plugin works with timezone names that have spaces
+- Google Calendar plugin accepts person email addresses as calendar IDs
+- Internally use numeric sort instead of alphanumeric sort ([2370])
+
+[2368]: https://code.google.com/p/fullcalendar/issues/detail?id=2368
+[2350]: https://code.google.com/p/fullcalendar/issues/detail?id=2350
+[2237]: https://code.google.com/p/fullcalendar/issues/detail?id=2237
+[2296]: https://code.google.com/p/fullcalendar/issues/detail?id=2296
+[2365]: https://code.google.com/p/fullcalendar/issues/detail?id=2365
+[2122]: https://code.google.com/p/fullcalendar/issues/detail?id=2122
+[2370]: https://code.google.com/p/fullcalendar/issues/detail?id=2370
+
+
+v2.2.2 (2014-11-19)
+-------------------
+
+- Fixes to Google Calendar API V3 code
+ - wouldn't recognize a lone-string Google Calendar ID if periods before the @ symbol
+ - removeEventSource wouldn't work when given a Google Calendar ID
+
+
+v2.2.1 (2014-11-19)
+-------------------
+
+- Migrate Google Calendar plugin to use V3 of the API ([1526])
+
+[1526]: https://code.google.com/p/fullcalendar/issues/detail?id=1526
+
+
+v2.2.0 (2014-11-14)
+-------------------
+
+- Background events. Event object's `rendering` property ([144], [1286])
+- `businessHours` option ([144])
+- Controlling where events can be dragged/resized and selections can go ([396], [1286], [2253])
+ - `eventOverlap`, `selectOverlap`, and similar
+ - `eventConstraint`, `selectConstraint`, and similar
+- Improvements to dragging and dropping external events ([2004])
+ - Associating with real event data. used with `eventReceive`
+ - Associating a `duration`
+- Performance boost for moment creation
+ - Be aware, FullCalendar-specific methods now attached directly to global moment.fn
+ - Helps with [issue 2259][2259]
+- Reintroduced forgotten `dropAccept` option ([2312])
+
+[144]: https://code.google.com/p/fullcalendar/issues/detail?id=144
+[396]: https://code.google.com/p/fullcalendar/issues/detail?id=396
+[1286]: https://code.google.com/p/fullcalendar/issues/detail?id=1286
+[2004]: https://code.google.com/p/fullcalendar/issues/detail?id=2004
+[2253]: https://code.google.com/p/fullcalendar/issues/detail?id=2253
+[2259]: https://code.google.com/p/fullcalendar/issues/detail?id=2259
+[2312]: https://code.google.com/p/fullcalendar/issues/detail?id=2312
+
+
+v2.1.1 (2014-08-29)
+-------------------
+
+- removeEventSource not working with array ([2203])
+- mouseout not triggered after mouseover+updateEvent ([829])
+- agenda event's render with no <a> href, not clickable ([2263])
+
+[2203]: https://code.google.com/p/fullcalendar/issues/detail?id=2203
+[829]: https://code.google.com/p/fullcalendar/issues/detail?id=829
+[2263]: https://code.google.com/p/fullcalendar/issues/detail?id=2263
+
+
+v2.1.0 (2014-08-25)
+-------------------
+
+Large code refactor with better OOP, better code reuse, and more comments.
+**No more reliance on jQuery UI** for event dragging, resizing, or anything else.
+
+Significant changes to HTML/CSS skeleton:
+- Leverages tables for liquid rendering of days and events. No costly manual repositioning ([809])
+- **Backwards-incompatibilities**:
+ - **Many classNames have changed. Custom CSS will likely need to be adjusted.**
+ - IE7 definitely not supported anymore
+ - In `eventRender` callback, `element` will not be attached to DOM yet
+ - Events are styled to be one line by default ([1992]). Can be undone through custom CSS,
+ but not recommended (might get gaps [like this][111] in certain situations).
+
+A "more..." link when there are too many events on a day ([304]). Works with month and basic views
+as well as the all-day section of the agenda views. New options:
+- `eventLimit`. a number or `true`
+- `eventLimitClick`. the `"popover`" value will reveal all events in a raised panel (the default)
+- `eventLimitText`
+- `dayPopoverFormat`
+
+Changes related to height and scrollbars:
+- `aspectRatio`/`height`/`contentHeight` values will be honored *no matter what*
+ - If too many events causing too much vertical space, scrollbars will be used ([728]).
+ This is default behavior for month view (**backwards-incompatibility**)
+ - If too few slots in agenda view, view will stretch to be the correct height ([2196])
+- `'auto'` value for `height`/`contentHeight` options. If content is too tall, the view will
+ vertically stretch to accomodate and no scrollbars will be used ([521]).
+- Tall weeks in month view will borrow height from other weeks ([243])
+- Automatically scroll the view then dragging/resizing an event ([1025], [2078])
+- New `fixedWeekCount` option to determines the number of weeks in month view
+ - Supersedes `weekMode` (**deprecated**). Instead, use a combination of `fixedWeekCount` and
+ one of the height options, possibly with an `'auto'` value
+
+Much nicer, glitch-free rendering of calendar *for printers* ([35]). Things you might not expect:
+- Buttons will become hidden
+- Agenda views display a flat list of events where the time slots would be
+
+Other issues resolved along the way:
+- Space on right side of agenda events configurable through CSS ([204])
+- Problem with window resize ([259])
+- Events sorting stays consistent across weeks ([510])
+- Agenda's columns misaligned on wide screens ([511])
+- Run `selectHelper` through `eventRender` callbacks ([629])
+- Keyboard access, tabbing ([637])
+- Run resizing events through `eventRender` ([714])
+- Resize an event to a different day in agenda views ([736])
+- Allow selection across days in agenda views ([778])
+- Mouseenter delegated event not working on event elements ([936])
+- Agenda event dragging, snapping to different columns is erratic ([1101])
+- Android browser cuts off Day view at 8 PM with no scroll bar ([1203])
+- Don't fire `eventMouseover`/`eventMouseout` while dragging/resizing ([1297])
+- Customize the resize handle text ("=") ([1326])
+- If agenda event is too short, don't overwrite `.fc-event-time` ([1700])
+- Zooming calendar causes events to misalign ([1996])
+- Event destroy callback on event removal ([2017])
+- Agenda views, when RTL, should have axis on right ([2132])
+- Make header buttons more accessibile ([2151])
+- daySelectionMousedown should interpret OSX ctrl+click as a right mouse click ([2169])
+- Best way to display time text on multi-day events *with times* ([2172])
+- Eliminate table use for header layout ([2186])
+- Event delegation used for event-related callbacks (like `eventClick`). Speedier.
+
+[35]: https://code.google.com/p/fullcalendar/issues/detail?id=35
+[204]: https://code.google.com/p/fullcalendar/issues/detail?id=204
+[243]: https://code.google.com/p/fullcalendar/issues/detail?id=243
+[259]: https://code.google.com/p/fullcalendar/issues/detail?id=259
+[304]: https://code.google.com/p/fullcalendar/issues/detail?id=304
+[510]: https://code.google.com/p/fullcalendar/issues/detail?id=510
+[511]: https://code.google.com/p/fullcalendar/issues/detail?id=511
+[521]: https://code.google.com/p/fullcalendar/issues/detail?id=521
+[629]: https://code.google.com/p/fullcalendar/issues/detail?id=629
+[637]: https://code.google.com/p/fullcalendar/issues/detail?id=637
+[714]: https://code.google.com/p/fullcalendar/issues/detail?id=714
+[728]: https://code.google.com/p/fullcalendar/issues/detail?id=728
+[736]: https://code.google.com/p/fullcalendar/issues/detail?id=736
+[778]: https://code.google.com/p/fullcalendar/issues/detail?id=778
+[809]: https://code.google.com/p/fullcalendar/issues/detail?id=809
+[936]: https://code.google.com/p/fullcalendar/issues/detail?id=936
+[1025]: https://code.google.com/p/fullcalendar/issues/detail?id=1025
+[1101]: https://code.google.com/p/fullcalendar/issues/detail?id=1101
+[1203]: https://code.google.com/p/fullcalendar/issues/detail?id=1203
+[1297]: https://code.google.com/p/fullcalendar/issues/detail?id=1297
+[1326]: https://code.google.com/p/fullcalendar/issues/detail?id=1326
+[1700]: https://code.google.com/p/fullcalendar/issues/detail?id=1700
+[1992]: https://code.google.com/p/fullcalendar/issues/detail?id=1992
+[1996]: https://code.google.com/p/fullcalendar/issues/detail?id=1996
+[2017]: https://code.google.com/p/fullcalendar/issues/detail?id=2017
+[2078]: https://code.google.com/p/fullcalendar/issues/detail?id=2078
+[2132]: https://code.google.com/p/fullcalendar/issues/detail?id=2132
+[2151]: https://code.google.com/p/fullcalendar/issues/detail?id=2151
+[2169]: https://code.google.com/p/fullcalendar/issues/detail?id=2169
+[2172]: https://code.google.com/p/fullcalendar/issues/detail?id=2172
+[2186]: https://code.google.com/p/fullcalendar/issues/detail?id=2186
+[2196]: https://code.google.com/p/fullcalendar/issues/detail?id=2196
+[111]: https://code.google.com/p/fullcalendar/issues/detail?id=111
+
+
+v2.0.3 (2014-08-15)
+-------------------
+
+- moment-2.8.1 compatibility ([2221])
+- relative path in bower.json ([PR 117])
+- upgraded jquery-ui and misc dev dependencies
+
+[2221]: https://code.google.com/p/fullcalendar/issues/detail?id=2221
+[PR 117]: https://github.com/arshaw/fullcalendar/pull/177
+
+
+v2.0.2 (2014-06-24)
+-------------------
+
+- bug with persisting addEventSource calls ([2191])
+- bug with persisting removeEvents calls with an array source ([2187])
+- bug with removeEvents method when called with 0 removes all events ([2082])
+
+[2191]: https://code.google.com/p/fullcalendar/issues/detail?id=2191
+[2187]: https://code.google.com/p/fullcalendar/issues/detail?id=2187
+[2082]: https://code.google.com/p/fullcalendar/issues/detail?id=2082
+
+
+v2.0.1 (2014-06-15)
+-------------------
+
+- `delta` parameters reintroduced in `eventDrop` and `eventResize` handlers ([2156])
+ - **Note**: this changes the argument order for `revertFunc`
+- wrongfully triggering a windowResize when resizing an agenda view event ([1116])
+- `this` values in event drag-n-drop/resize handlers consistently the DOM node ([1177])
+- `displayEventEnd` - v2 workaround to force display of an end time ([2090])
+- don't modify passed-in eventSource items ([954])
+- destroy method now removes fc-ltr class ([2033])
+- weeks of last/next month still visible when weekends are hidden ([2095])
+- fixed memory leak when destroying calendar with selectable/droppable ([2137])
+- Icelandic language ([2180])
+- Bahasa Indonesia language ([PR 172])
+
+[1116]: https://code.google.com/p/fullcalendar/issues/detail?id=1116
+[1177]: https://code.google.com/p/fullcalendar/issues/detail?id=1177
+[2090]: https://code.google.com/p/fullcalendar/issues/detail?id=2090
+[954]: https://code.google.com/p/fullcalendar/issues/detail?id=954
+[2033]: https://code.google.com/p/fullcalendar/issues/detail?id=2033
+[2095]: https://code.google.com/p/fullcalendar/issues/detail?id=2095
+[2137]: https://code.google.com/p/fullcalendar/issues/detail?id=2137
+[2156]: https://code.google.com/p/fullcalendar/issues/detail?id=2156
+[2180]: https://code.google.com/p/fullcalendar/issues/detail?id=2180
+[PR 172]: https://github.com/arshaw/fullcalendar/pull/172
+
+
+v2.0.0 (2014-06-01)
+-------------------
+
+Internationalization support, timezone support, and [MomentJS] integration. Extensive changes, many
+of which are backwards incompatible.
+
+[Full list of changes][Upgrading-to-v2] | [Affected Issues][Date-Milestone]
+
+An automated testing framework has been set up ([Karma] + [Jasmine]) and tests have been written
+which cover about half of FullCalendar's functionality. Special thanks to @incre-d, @vidbina, and
+@sirrocco for the help.
+
+In addition, the main development repo has been repurposed to also include the built distributable
+JS/CSS for the project and will serve as the new [Bower] endpoint.
+
+[MomentJS]: http://momentjs.com/
+[Upgrading-to-v2]: http://arshaw.com/fullcalendar/wiki/Upgrading-to-v2/
+[Date-Milestone]: https://code.google.com/p/fullcalendar/issues/list?can=1&q=milestone%3Ddate
+[Karma]: http://karma-runner.github.io/
+[Jasmine]: http://jasmine.github.io/
+[Bower]: http://bower.io/
+
+
+v1.6.4 (2013-09-01)
+-------------------
+
+- better algorithm for positioning timed agenda events ([1115])
+- `slotEventOverlap` option to tweak timed agenda event overlapping ([218])
+- selection bug when slot height is customized ([1035])
+- supply view argument in `loading` callback ([1018])
+- fixed week number not displaying in agenda views ([1951])
+- fixed fullCalendar not initializing with no options ([1356])
+- NPM's `package.json`, no more warnings or errors ([1762])
+- building the bower component should output `bower.json` instead of `component.json` ([PR 125])
+- use bower internally for fetching new versions of jQuery and jQuery UI
+
+[1115]: https://code.google.com/p/fullcalendar/issues/detail?id=1115
+[218]: https://code.google.com/p/fullcalendar/issues/detail?id=218
+[1035]: https://code.google.com/p/fullcalendar/issues/detail?id=1035
+[1018]: https://code.google.com/p/fullcalendar/issues/detail?id=1018
+[1951]: https://code.google.com/p/fullcalendar/issues/detail?id=1951
+[1356]: https://code.google.com/p/fullcalendar/issues/detail?id=1356
+[1762]: https://code.google.com/p/fullcalendar/issues/detail?id=1762
+[PR 125]: https://github.com/arshaw/fullcalendar/pull/125
+
+
+v1.6.3 (2013-08-10)
+-------------------
+
+- `viewRender` callback ([PR 15])
+- `viewDestroy` callback ([PR 15])
+- `eventDestroy` callback ([PR 111])
+- `handleWindowResize` option ([PR 54])
+- `eventStartEditable`/`startEditable` options ([PR 49])
+- `eventDurationEditable`/`durationEditable` options ([PR 49])
+- specify function for `$.ajax` `data` parameter for JSON event sources ([PR 59])
+- fixed bug with agenda event dropping in wrong column ([PR 55])
+- easier event element z-index customization ([PR 58])
+- classNames on past/future days ([PR 88])
+- allow `null`/`undefined` event titles ([PR 84])
+- small optimize for agenda event rendering ([PR 56])
+- deprecated:
+ - `viewDisplay`
+ - `disableDragging`
+ - `disableResizing`
+- bundled with latest jQuery (1.10.2) and jQuery UI (1.10.3)
+
+[PR 15]: https://github.com/arshaw/fullcalendar/pull/15
+[PR 111]: https://github.com/arshaw/fullcalendar/pull/111
+[PR 54]: https://github.com/arshaw/fullcalendar/pull/54
+[PR 49]: https://github.com/arshaw/fullcalendar/pull/49
+[PR 59]: https://github.com/arshaw/fullcalendar/pull/59
+[PR 55]: https://github.com/arshaw/fullcalendar/pull/55
+[PR 58]: https://github.com/arshaw/fullcalendar/pull/58
+[PR 88]: https://github.com/arshaw/fullcalendar/pull/88
+[PR 84]: https://github.com/arshaw/fullcalendar/pull/84
+[PR 56]: https://github.com/arshaw/fullcalendar/pull/56
+
+
+v1.6.2 (2013-07-18)
+-------------------
+
+- `hiddenDays` option ([686])
+- bugfix: when `eventRender` returns `false`, incorrect stacking of events ([762])
+- bugfix: couldn't change `event.backgroundImage` when calling `updateEvent` (thx @stephenharris)
+
+[686]: https://code.google.com/p/fullcalendar/issues/detail?id=686
+[762]: https://code.google.com/p/fullcalendar/issues/detail?id=762
+
+
+v1.6.1 (2013-04-14)
+-------------------
+
+- fixed event inner content overflow bug ([1783])
+- fixed table header className bug [1772]
+- removed text-shadow on events (better for general use, thx @tkrotoff)
+
+[1783]: https://code.google.com/p/fullcalendar/issues/detail?id=1783
+[1772]: https://code.google.com/p/fullcalendar/issues/detail?id=1772
+
+
+v1.6.0 (2013-03-18)
+-------------------
+
+- visual facelift, with bootstrap-inspired buttons and colors
+- simplified HTML/CSS for events and buttons
+- `dayRender`, for modifying a day cell ([191], thx @althaus)
+- week numbers on side of calendar ([295])
+ - `weekNumber`
+ - `weekNumberCalculation`
+ - `weekNumberTitle`
+ - `W` formatting variable
+- finer snapping granularity for agenda view events ([495], thx @ms-doodle-com)
+- `eventAfterAllRender` ([753], thx @pdrakeweb)
+- `eventDataTransform` (thx @joeyspo)
+- `data-date` attributes on cells (thx @Jae)
+- expose `$.fullCalendar.dateFormatters`
+- when clicking fast on buttons, prevent text selection
+- bundled with latest jQuery (1.9.1) and jQuery UI (1.10.2)
+- Grunt/Lumbar build system for internal development
+- build for Bower package manager
+- build for jQuery plugin site
+
+[191]: https://code.google.com/p/fullcalendar/issues/detail?id=191
+[295]: https://code.google.com/p/fullcalendar/issues/detail?id=295
+[495]: https://code.google.com/p/fullcalendar/issues/detail?id=495
+[753]: https://code.google.com/p/fullcalendar/issues/detail?id=753
+
+
+v1.5.4 (2012-09-05)
+-------------------
+
+- made compatible with jQuery 1.8.* (thx @archaeron)
+- bundled with jQuery 1.8.1 and jQuery UI 1.8.23
+
+
+v1.5.3 (2012-02-06)
+-------------------
+
+- fixed dragging issue with jQuery UI 1.8.16 ([1168])
+- bundled with jQuery 1.7.1 and jQuery UI 1.8.17
+
+[1168]: https://code.google.com/p/fullcalendar/issues/detail?id=1168
+
+
+v1.5.2 (2011-08-21)
+-------------------
+
+- correctly process UTC "Z" ISO8601 date strings ([750])
+
+[750]: https://code.google.com/p/fullcalendar/issues/detail?id=750
+
+
+v1.5.1 (2011-04-09)
+-------------------
+
+- more flexible ISO8601 date parsing ([814])
+- more flexible parsing of UNIX timestamps ([826])
+- FullCalendar now buildable from source on a Mac ([795])
+- FullCalendar QA'd in FF4 ([883])
+- upgraded to jQuery 1.5.2 (which supports IE9) and jQuery UI 1.8.11
+
+[814]: https://code.google.com/p/fullcalendar/issues/detail?id=814
+[826]: https://code.google.com/p/fullcalendar/issues/detail?id=826
+[795]: https://code.google.com/p/fullcalendar/issues/detail?id=795
+[883]: https://code.google.com/p/fullcalendar/issues/detail?id=883
+
+
+v1.5 (2011-03-19)
+-----------------
+
+- slicker default styling for buttons
+- reworked a lot of the calendar's HTML and accompanying CSS (solves [327] and [395])
+- more printer-friendly (fullcalendar-print.css)
+- fullcalendar now inherits styles from jquery-ui themes differently.
+ styles for buttons are distinct from styles for calendar cells.
+ (solves [299])
+- can now color events through FullCalendar options and Event-Object properties ([117])
+ THIS IS NOW THE PREFERRED METHOD OF COLORING EVENTS (as opposed to using className and CSS)
+ - FullCalendar options:
+ - eventColor (changes both background and border)
+ - eventBackgroundColor
+ - eventBorderColor
+ - eventTextColor
+ - Event-Object options:
+ - color (changes both background and border)
+ - backgroundColor
+ - borderColor
+ - textColor
+- can now specify an event source as an *object* with a `url` property (json feed) or
+ an `events` property (function or array) with additional properties that will
+ be applied to the entire event source:
+ - color (changes both background and border)
+ - backgroudColor
+ - borderColor
+ - textColor
+ - className
+ - editable
+ - allDayDefault
+ - ignoreTimezone
+ - startParam (for a feed)
+ - endParam (for a feed)
+ - ANY OF THE JQUERY $.ajax OPTIONS
+ allows for easily changing from GET to POST and sending additional parameters ([386])
+ allows for easily attaching ajax handlers such as `error` ([754])
+ allows for turning caching on ([355])
+- Google Calendar feeds are now specified differently:
+ - specify a simple string of your feed's URL
+ - specify an *object* with a `url` property of your feed's URL.
+ you can include any of the new Event-Source options in this object.
+ - the old `$.fullCalendar.gcalFeed` method still works
+- no more IE7 SSL popup ([504])
+- remove `cacheParam` - use json event source `cache` option instead
+- latest jquery/jquery-ui
+
+[327]: https://code.google.com/p/fullcalendar/issues/detail?id=327
+[395]: https://code.google.com/p/fullcalendar/issues/detail?id=395
+[299]: https://code.google.com/p/fullcalendar/issues/detail?id=299
+[117]: https://code.google.com/p/fullcalendar/issues/detail?id=117
+[386]: https://code.google.com/p/fullcalendar/issues/detail?id=386
+[754]: https://code.google.com/p/fullcalendar/issues/detail?id=754
+[355]: https://code.google.com/p/fullcalendar/issues/detail?id=355
+[504]: https://code.google.com/p/fullcalendar/issues/detail?id=504
+
+
+v1.4.11 (2011-02-22)
+--------------------
+
+- fixed rerenderEvents bug ([790])
+- fixed bug with faulty dragging of events from all-day slot in agenda views
+- bundled with jquery 1.5 and jquery-ui 1.8.9
+
+[790]: https://code.google.com/p/fullcalendar/issues/detail?id=790
+
+
+v1.4.10 (2011-01-02)
+--------------------
+
+- fixed bug with resizing event to different week in 5-day month view ([740])
+- fixed bug with events not sticking after a removeEvents call ([757])
+- fixed bug with underlying parseTime method, and other uses of parseInt ([688])
+
+[740]: https://code.google.com/p/fullcalendar/issues/detail?id=740
+[757]: https://code.google.com/p/fullcalendar/issues/detail?id=757
+[688]: https://code.google.com/p/fullcalendar/issues/detail?id=688
+
+
+v1.4.9 (2010-11-16)
+-------------------
+
+- new algorithm for vertically stacking events ([111])
+- resizing an event to a different week ([306])
+- bug: some events not rendered with consecutive calls to addEventSource ([679])
+
+[111]: https://code.google.com/p/fullcalendar/issues/detail?id=111
+[306]: https://code.google.com/p/fullcalendar/issues/detail?id=306
+[679]: https://code.google.com/p/fullcalendar/issues/detail?id=679
+
+
+v1.4.8 (2010-10-16)
+-------------------
+
+- ignoreTimezone option (set to `false` to process UTC offsets in ISO8601 dates)
+- bugfixes
+ - event refetching not being called under certain conditions ([417], [554])
+ - event refetching being called multiple times under certain conditions ([586], [616])
+ - selection cannot be triggered by right mouse button ([558])
+ - agenda view left axis sized incorrectly ([465])
+ - IE js error when calendar is too narrow ([517])
+ - agenda view looks strange when no scrollbars ([235])
+ - improved parsing of ISO8601 dates with UTC offsets
+- $.fullCalendar.version
+- an internal refactor of the code, for easier future development and modularity
+
+[417]: https://code.google.com/p/fullcalendar/issues/detail?id=417
+[554]: https://code.google.com/p/fullcalendar/issues/detail?id=554
+[586]: https://code.google.com/p/fullcalendar/issues/detail?id=586
+[616]: https://code.google.com/p/fullcalendar/issues/detail?id=616
+[558]: https://code.google.com/p/fullcalendar/issues/detail?id=558
+[465]: https://code.google.com/p/fullcalendar/issues/detail?id=465
+[517]: https://code.google.com/p/fullcalendar/issues/detail?id=517
+[235]: https://code.google.com/p/fullcalendar/issues/detail?id=235
+
+
+v1.4.7 (2010-07-05)
+-------------------
+
+- "dropping" external objects onto the calendar
+ - droppable (boolean, to turn on/off)
+ - dropAccept (to filter which events the calendar will accept)
+ - drop (trigger)
+- selectable options can now be specified with a View Option Hash
+- bugfixes
+ - dragged & reverted events having wrong time text ([406])
+ - bug rendering events that have an endtime with seconds, but no hours/minutes ([477])
+ - gotoDate date overflow bug ([429])
+ - wrong date reported when clicking on edge of last column in agenda views [412]
+- support newlines in event titles
+- select/unselect callbacks now passes native js event
+
+[406]: https://code.google.com/p/fullcalendar/issues/detail?id=406
+[477]: https://code.google.com/p/fullcalendar/issues/detail?id=477
+[429]: https://code.google.com/p/fullcalendar/issues/detail?id=429
+[412]: https://code.google.com/p/fullcalendar/issues/detail?id=412
+
+
+v1.4.6 (2010-05-31)
+-------------------
+
+- "selecting" days or timeslots
+ - options: selectable, selectHelper, unselectAuto, unselectCancel
+ - callbacks: select, unselect
+ - methods: select, unselect
+- when dragging an event, the highlighting reflects the duration of the event
+- code compressing by Google Closure Compiler
+- bundled with jQuery 1.4.2 and jQuery UI 1.8.1
+
+
+v1.4.5 (2010-02-21)
+-------------------
+
+- lazyFetching option, which can force the calendar to fetch events on every view/date change
+- scroll state of agenda views are preserved when switching back to view
+- bugfixes
+ - calling methods on an uninitialized fullcalendar throws error
+ - IE6/7 bug where an entire view becomes invisible ([320])
+ - error when rendering a hidden calendar (in jquery ui tabs for example) in IE ([340])
+ - interconnected bugs related to calendar resizing and scrollbars
+ - when switching views or clicking prev/next, calendar would "blink" ([333])
+ - liquid-width calendar's events shifted (depending on initial height of browser) ([341])
+ - more robust underlying algorithm for calendar resizing
+
+[320]: https://code.google.com/p/fullcalendar/issues/detail?id=320
+[340]: https://code.google.com/p/fullcalendar/issues/detail?id=340
+[333]: https://code.google.com/p/fullcalendar/issues/detail?id=333
+[341]: https://code.google.com/p/fullcalendar/issues/detail?id=341
+
+
+v1.4.4 (2010-02-03)
+-------------------
+
+- optimized event rendering in all views (events render in 1/10 the time)
+- gotoDate() does not force the calendar to unnecessarily rerender
+- render() method now correctly readjusts height
+
+
+v1.4.3 (2009-12-22)
+-------------------
+
+- added destroy method
+- Google Calendar event pages respect currentTimezone
+- caching now handled by jQuery's ajax
+- protection from setting aspectRatio to zero
+- bugfixes
+ - parseISO8601 and DST caused certain events to display day before
+ - button positioning problem in IE6
+ - ajax event source removed after recently being added, events still displayed
+ - event not displayed when end is an empty string
+ - dynamically setting calendar height when no events have been fetched, throws error
+
+
+v1.4.2 (2009-12-02)
+-------------------
+
+- eventAfterRender trigger
+- getDate & getView methods
+- height & contentHeight options (explicitly sets the pixel height)
+- minTime & maxTime options (restricts shown hours in agenda view)
+- getters [for all options] and setters [for height, contentHeight, and aspectRatio ONLY! stay tuned..]
+- render method now readjusts calendar's size
+- bugfixes
+ - lightbox scripts that use iframes (like fancybox)
+ - day-of-week classNames were off when firstDay=1
+ - guaranteed space on right side of agenda events (even when stacked)
+ - accepts ISO8601 dates with a space (instead of 'T')
+
+
+v1.4.1 (2009-10-31)
+-------------------
+
+- can exclude weekends with new 'weekends' option
+- gcal feed 'currentTimezone' option
+- bugfixes
+ - year/month/date option sometimes wouldn't set correctly (depending on current date)
+ - daylight savings issue caused agenda views to start at 1am (for BST users)
+- cleanup of gcal.js code
+
+
+v1.4 (2009-10-19)
+-----------------
+
+- agendaWeek and agendaDay views
+- added some options for agenda views:
+ - allDaySlot
+ - allDayText
+ - firstHour
+ - slotMinutes
+ - defaultEventMinutes
+ - axisFormat
+- modified some existing options/triggers to work with agenda views:
+ - dragOpacity and timeFormat can now accept a "View Hash" (a new concept)
+ - dayClick now has an allDay parameter
+ - eventDrop now has an an allDay parameter
+ (this will affect those who use revertFunc, adjust parameter list)
+- added 'prevYear' and 'nextYear' for buttons in header
+- minor change for theme users, ui-state-hover not applied to active/inactive buttons
+- added event-color-changing example in docs
+- better defaults for right-to-left themed button icons
+
+
+v1.3.2 (2009-10-13)
+-------------------
+
+- Bugfixes (please upgrade from 1.3.1!)
+ - squashed potential infinite loop when addMonths and addDays
+ is called with an invalid date
+ - $.fullCalendar.parseDate() now correctly parses IETF format
+ - when switching views, the 'today' button sticks inactive, fixed
+- gotoDate now can accept a single Date argument
+- documentation for changes in 1.3.1 and 1.3.2 now on website
+
+
+v1.3.1 (2009-09-30)
+-------------------
+
+- Important Bugfixes (please upgrade from 1.3!)
+ - When current date was late in the month, for long months, and prev/next buttons
+ were clicked in month-view, some months would be skipped/repeated
+ - In certain time zones, daylight savings time would cause certain days
+ to be misnumbered in month-view
+- Subtle change in way week interval is chosen when switching from month to basicWeek/basicDay view
+- Added 'allDayDefault' option
+- Added 'changeView' and 'render' methods
+
+
+v1.3 (2009-09-21)
+-----------------
+
+- different 'views': month/basicWeek/basicDay
+- more flexible 'header' system for buttons
+- themable by jQuery UI themes
+- resizable events (require jQuery UI resizable plugin)
+- rescoped & rewritten CSS, enhanced default look
+- cleaner css & rendering techniques for right-to-left
+- reworked options & API to support multiple views / be consistent with jQuery UI
+- refactoring of entire codebase
+ - broken into different JS & CSS files, assembled w/ build scripts
+ - new test suite for new features, uses firebug-lite
+- refactored docs
+- Options
+ - + date
+ - + defaultView
+ - + aspectRatio
+ - + disableResizing
+ - + monthNames (use instead of $.fullCalendar.monthNames)
+ - + monthNamesShort (use instead of $.fullCalendar.monthAbbrevs)
+ - + dayNames (use instead of $.fullCalendar.dayNames)
+ - + dayNamesShort (use instead of $.fullCalendar.dayAbbrevs)
+ - + theme
+ - + buttonText
+ - + buttonIcons
+ - x draggable -> editable/disableDragging
+ - x fixedWeeks -> weekMode
+ - x abbrevDayHeadings -> columnFormat
+ - x buttons/title -> header
+ - x eventDragOpacity -> dragOpacity
+ - x eventRevertDuration -> dragRevertDuration
+ - x weekStart -> firstDay
+ - x rightToLeft -> isRTL
+ - x showTime (use 'allDay' CalEvent property instead)
+- Triggered Actions
+ - + eventResizeStart
+ - + eventResizeStop
+ - + eventResize
+ - x monthDisplay -> viewDisplay
+ - x resize -> windowResize
+ - 'eventDrop' params changed, can revert if ajax cuts out
+- CalEvent Properties
+ - x showTime -> allDay
+ - x draggable -> editable
+ - 'end' is now INCLUSIVE when allDay=true
+ - 'url' now produces a real <a> tag, more native clicking/tab behavior
+- Methods:
+ - + renderEvent
+ - x prevMonth -> prev
+ - x nextMonth -> next
+ - x prevYear/nextYear -> moveDate
+ - x refresh -> rerenderEvents/refetchEvents
+ - x removeEvent -> removeEvents
+ - x getEventsByID -> clientEvents
+- Utilities:
+ - 'formatDate' format string completely changed (inspired by jQuery UI datepicker + datejs)
+ - 'formatDates' added to support date-ranges
+- Google Calendar Options:
+ - x draggable -> editable
+- Bugfixes
+ - gcal extension fetched 25 results max, now fetches all
+
+
+v1.2.1 (2009-06-29)
+-------------------
+
+- bugfixes
+ - allows and corrects invalid end dates for events
+ - doesn't throw an error in IE while rendering when display:none
+ - fixed 'loading' callback when used w/ multiple addEventSource calls
+ - gcal className can now be an array
+
+
+v1.2 (2009-05-31)
+-----------------
+
+- expanded API
+ - 'className' CalEvent attribute
+ - 'source' CalEvent attribute
+ - dynamically get/add/remove/update events of current month
+ - locale improvements: change month/day name text
+ - better date formatting ($.fullCalendar.formatDate)
+ - multiple 'event sources' allowed
+ - dynamically add/remove event sources
+- options for prevYear and nextYear buttons
+- docs have been reworked (include addition of Google Calendar docs)
+- changed behavior of parseDate for number strings
+ (now interpets as unix timestamp, not MS times)
+- bugfixes
+ - rightToLeft month start bug
+ - off-by-one errors with month formatting commands
+ - events from previous months sticking when clicking prev/next quickly
+- Google Calendar API changed to work w/ multiple event sources
+ - can also provide 'className' and 'draggable' options
+- date utilties moved from $ to $.fullCalendar
+- more documentation in source code
+- minified version of fullcalendar.js
+- test suit (available from svn)
+- top buttons now use `<button>` w/ an inner `<span>` for better css cusomization
+ - thus CSS has changed. IF UPGRADING FROM PREVIOUS VERSIONS,
+ UPGRADE YOUR FULLCALENDAR.CSS FILE
+
+
+v1.1 (2009-05-10)
+-----------------
+
+- Added the following options:
+ - weekStart
+ - rightToLeft
+ - titleFormat
+ - timeFormat
+ - cacheParam
+ - resize
+- Fixed rendering bugs
+ - Opera 9.25 (events placement & window resizing)
+ - IE6 (window resizing)
+- Optimized window resizing for ALL browsers
+- Events on same day now sorted by start time (but first by timespan)
+- Correct z-index when dragging
+- Dragging contained in overflow DIV for IE6
+- Modified fullcalendar.css
+ - for right-to-left support
+ - for variable start-of-week
+ - for IE6 resizing bug
+ - for THEAD and TBODY (in 1.0, just used TBODY, restructured in 1.1)
+ - IF UPGRADING FROM FULLCALENDAR 1.0, YOU MUST UPGRADE FULLCALENDAR.CSS
diff --git a/library/fullcalendar/LICENSE.txt b/library/fullcalendar/LICENSE.txt
index eafaf97ec..2149cfbef 100644
--- a/library/fullcalendar/LICENSE.txt
+++ b/library/fullcalendar/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2015 Adam Shaw
+Copyright (c) 2019 Adam Shaw
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/library/fullcalendar/demos/background-events.html b/library/fullcalendar/demos/background-events.html
new file mode 100644
index 000000000..a36fede8d
--- /dev/null
+++ b/library/fullcalendar/demos/background-events.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ businessHours: true, // display business hours
+ editable: true,
+ events: [
+ {
+ title: 'Business Lunch',
+ start: '2019-04-03T13:00:00',
+ constraint: 'businessHours'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-13T11:00:00',
+ constraint: 'availableForMeeting', // defined below
+ color: '#257e4a'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-18',
+ end: '2019-04-20'
+ },
+ {
+ title: 'Party',
+ start: '2019-04-29T20:00:00'
+ },
+
+ // areas where "Meeting" must be dropped
+ {
+ groupId: 'availableForMeeting',
+ start: '2019-04-11T10:00:00',
+ end: '2019-04-11T16:00:00',
+ rendering: 'background'
+ },
+ {
+ groupId: 'availableForMeeting',
+ start: '2019-04-13T10:00:00',
+ end: '2019-04-13T16:00:00',
+ rendering: 'background'
+ },
+
+ // red areas where no events can be dropped
+ {
+ start: '2019-04-24',
+ end: '2019-04-28',
+ overlap: false,
+ rendering: 'background',
+ color: '#ff9f89'
+ },
+ {
+ start: '2019-04-06',
+ end: '2019-04-08',
+ overlap: false,
+ rendering: 'background',
+ color: '#ff9f89'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/daygrid-views.html b/library/fullcalendar/demos/daygrid-views.html
new file mode 100644
index 000000000..96220fb3e
--- /dev/null
+++ b/library/fullcalendar/demos/daygrid-views.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid' ],
+ header: {
+ left: 'prevYear,prev,next,nextYear today',
+ center: 'title',
+ right: 'dayGridMonth,dayGridWeek,dayGridDay'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/default.html b/library/fullcalendar/demos/default.html
new file mode 100644
index 000000000..a2b3849c8
--- /dev/null
+++ b/library/fullcalendar/demos/default.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid' ],
+ defaultDate: '2019-04-12',
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/external-dragging-2cals.html b/library/fullcalendar/demos/external-dragging-2cals.html
new file mode 100644
index 000000000..bf4f08470
--- /dev/null
+++ b/library/fullcalendar/demos/external-dragging-2cals.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var srcCalendarEl = document.getElementById('source-calendar');
+ var destCalendarEl = document.getElementById('destination-calendar');
+
+ var srcCalendar = new FullCalendar.Calendar(srcCalendarEl, {
+ plugins: [ 'interaction', 'dayGrid' ],
+ editable: true,
+ defaultDate: '2019-04-12',
+ events: [
+ {
+ title: 'event1',
+ start: '2019-04-11T10:00:00',
+ end: '2019-04-11T16:00:00'
+ },
+ {
+ title: 'event2',
+ start: '2019-04-13T10:00:00',
+ end: '2019-04-13T16:00:00'
+ }
+ ],
+ eventLeave: function(info) {
+ console.log('event left!', info.event);
+ }
+ });
+
+ var destCalendar = new FullCalendar.Calendar(destCalendarEl, {
+ plugins: [ 'interaction', 'dayGrid' ],
+ defaultDate: '2019-04-12',
+ editable: true,
+ droppable: true, // will let it receive events!
+ eventReceive: function(info) {
+ console.log('event received!', info.event);
+ }
+ });
+
+ srcCalendar.render();
+ destCalendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 20px 0 0 20px;
+ font-size: 14px;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ }
+
+ #source-calendar,
+ #destination-calendar {
+ float: left;
+ width: 600px;
+ margin: 0 20px 20px 0;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='source-calendar'></div>
+ <div id='destination-calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/external-dragging-builtin.html b/library/fullcalendar/demos/external-dragging-builtin.html
new file mode 100644
index 000000000..f9471b0ef
--- /dev/null
+++ b/library/fullcalendar/demos/external-dragging-builtin.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var Calendar = FullCalendar.Calendar;
+ var Draggable = FullCalendarInteraction.Draggable
+
+ /* initialize the external events
+ -----------------------------------------------------------------*/
+
+ var containerEl = document.getElementById('external-events-list');
+ new Draggable(containerEl, {
+ itemSelector: '.fc-event',
+ eventData: function(eventEl) {
+ return {
+ title: eventEl.innerText.trim()
+ }
+ }
+ });
+
+ //// the individual way to do it
+ // var containerEl = document.getElementById('external-events-list');
+ // var eventEls = Array.prototype.slice.call(
+ // containerEl.querySelectorAll('.fc-event')
+ // );
+ // eventEls.forEach(function(eventEl) {
+ // new Draggable(eventEl, {
+ // eventData: {
+ // title: eventEl.innerText.trim(),
+ // }
+ // });
+ // });
+
+ /* initialize the calendar
+ -----------------------------------------------------------------*/
+
+ var calendarEl = document.getElementById('calendar');
+ var calendar = new Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ editable: true,
+ droppable: true, // this allows things to be dropped onto the calendar
+ drop: function(arg) {
+ // is the "remove after drop" checkbox checked?
+ if (document.getElementById('drop-remove').checked) {
+ // if so, remove the element from the "Draggable Events" list
+ arg.draggedEl.parentNode.removeChild(arg.draggedEl);
+ }
+ }
+ });
+ calendar.render();
+
+ });
+
+</script>
+<style>
+
+ body {
+ margin-top: 40px;
+ font-size: 14px;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ }
+
+ #wrap {
+ width: 1100px;
+ margin: 0 auto;
+ }
+
+ #external-events {
+ float: left;
+ width: 150px;
+ padding: 0 10px;
+ border: 1px solid #ccc;
+ background: #eee;
+ text-align: left;
+ }
+
+ #external-events h4 {
+ font-size: 16px;
+ margin-top: 0;
+ padding-top: 1em;
+ }
+
+ #external-events .fc-event {
+ margin: 10px 0;
+ cursor: pointer;
+ }
+
+ #external-events p {
+ margin: 1.5em 0;
+ font-size: 11px;
+ color: #666;
+ }
+
+ #external-events p input {
+ margin: 0;
+ vertical-align: middle;
+ }
+
+ #calendar {
+ float: right;
+ width: 900px;
+ }
+
+</style>
+</head>
+<body>
+ <div id='wrap'>
+
+ <div id='external-events'>
+ <h4>Draggable Events</h4>
+
+ <div id='external-events-list'>
+ <div class='fc-event'>My Event 1</div>
+ <div class='fc-event'>My Event 2</div>
+ <div class='fc-event'>My Event 3</div>
+ <div class='fc-event'>My Event 4</div>
+ <div class='fc-event'>My Event 5</div>
+ </div>
+
+ <p>
+ <input type='checkbox' id='drop-remove' />
+ <label for='drop-remove'>remove after drop</label>
+ </p>
+ </div>
+
+ <div id='calendar'></div>
+
+ <div style='clear:both'></div>
+
+ </div>
+</body>
+</html>
diff --git a/library/fullcalendar/demos/full-height.html b/library/fullcalendar/demos/full-height.html
new file mode 100644
index 000000000..799622eab
--- /dev/null
+++ b/library/fullcalendar/demos/full-height.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ height: 'parent',
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ defaultView: 'dayGridMonth',
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01',
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ html, body {
+ overflow: hidden; /* don't do scrollbars */
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+
+ .fc-header-toolbar {
+ /*
+ the calendar will be butting up against the edges,
+ but let's scoot in the header's buttons
+ */
+ padding-top: 1em;
+ padding-left: 1em;
+ padding-right: 1em;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar-container'>
+ <div id='calendar'></div>
+ </div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/google-calendar.html b/library/fullcalendar/demos/google-calendar.html
new file mode 100644
index 000000000..96194ac62
--- /dev/null
+++ b/library/fullcalendar/demos/google-calendar.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script src='../packages/google-calendar/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+
+ plugins: [ 'interaction', 'dayGrid', 'list', 'googleCalendar' ],
+
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,listYear'
+ },
+
+ displayEventTime: false, // don't show the time column in list view
+
+ // THIS KEY WON'T WORK IN PRODUCTION!!!
+ // To make your own Google API key, follow the directions here:
+ // http://fullcalendar.io/docs/google_calendar/
+ googleCalendarApiKey: 'AIzaSyDcnW6WejpTOCffshGDDb4neIrXVUA1EAE',
+
+ // US Holidays
+ events: 'en.usa#holiday@group.v.calendar.google.com',
+
+ eventClick: function(arg) {
+ // opens events in a popup window
+ window.open(arg.event.url, 'google-calendar-event', 'width=700,height=600');
+
+ arg.jsEvent.preventDefault() // don't navigate in main tab
+ },
+
+ loading: function(bool) {
+ document.getElementById('loading').style.display =
+ bool ? 'block' : 'none';
+ }
+
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #loading {
+ display: none;
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='loading'>loading...</div>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/js/theme-chooser.js b/library/fullcalendar/demos/js/theme-chooser.js
new file mode 100644
index 000000000..92a7c4753
--- /dev/null
+++ b/library/fullcalendar/demos/js/theme-chooser.js
@@ -0,0 +1,141 @@
+
+function initThemeChooser(settings) {
+ var isInitialized = false;
+ var currentThemeSystem; // don't set this directly. use setThemeSystem
+ var currentStylesheetEl;
+ var loadingEl = document.getElementById('loading');
+ var systemSelectEl = document.querySelector('#theme-system-selector select');
+ var themeSelectWrapEls = Array.prototype.slice.call( // convert to real array
+ document.querySelectorAll('.selector[data-theme-system]')
+ );
+
+ systemSelectEl.addEventListener('change', function() {
+ setThemeSystem(this.value);
+ });
+
+ setThemeSystem(systemSelectEl.value);
+
+ themeSelectWrapEls.forEach(function(themeSelectWrapEl) {
+ var themeSelectEl = themeSelectWrapEl.querySelector('select');
+
+ themeSelectWrapEl.addEventListener('change', function() {
+ setTheme(
+ currentThemeSystem,
+ themeSelectEl.options[themeSelectEl.selectedIndex].value
+ );
+ });
+ });
+
+
+ function setThemeSystem(themeSystem) {
+ var selectedTheme;
+
+ currentThemeSystem = themeSystem;
+
+ themeSelectWrapEls.forEach(function(themeSelectWrapEl) {
+ var themeSelectEl = themeSelectWrapEl.querySelector('select');
+
+ if (themeSelectWrapEl.getAttribute('data-theme-system') === themeSystem) {
+ selectedTheme = themeSelectEl.options[themeSelectEl.selectedIndex].value;
+ themeSelectWrapEl.style.display = 'inline-block';
+ } else {
+ themeSelectWrapEl.style.display = 'none';
+ }
+ });
+
+ setTheme(themeSystem, selectedTheme);
+ }
+
+
+ function setTheme(themeSystem, themeName) {
+ var stylesheetUrl = generateStylesheetUrl(themeSystem, themeName);
+ var stylesheetEl;
+
+ function done() {
+ if (!isInitialized) {
+ isInitialized = true;
+ settings.init(themeSystem);
+ }
+ else {
+ settings.change(themeSystem);
+ }
+
+ showCredits(themeSystem, themeName);
+ }
+
+ if (stylesheetUrl) {
+ stylesheetEl = document.createElement('link');
+ stylesheetEl.setAttribute('rel', 'stylesheet');
+ stylesheetEl.setAttribute('href', stylesheetUrl);
+ document.querySelector('head').appendChild(stylesheetEl);
+
+ loadingEl.style.display = 'inline';
+
+ whenStylesheetLoaded(stylesheetEl, function() {
+ if (currentStylesheetEl) {
+ currentStylesheetEl.parentNode.removeChild(currentStylesheetEl);
+ }
+ currentStylesheetEl = stylesheetEl;
+ loadingEl.style.display = 'none';
+ done();
+ });
+ } else {
+ if (currentStylesheetEl) {
+ currentStylesheetEl.parentNode.removeChild(currentStylesheetEl);
+ currentStylesheetEl = null
+ }
+ done();
+ }
+ }
+
+
+ function generateStylesheetUrl(themeSystem, themeName) {
+ if (themeSystem === 'bootstrap') {
+ if (themeName) {
+ return 'https://bootswatch.com/4/' + themeName + '/bootstrap.min.css';
+ }
+ else { // the default bootstrap theme
+ return 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css';
+ }
+ }
+ }
+
+
+ function showCredits(themeSystem, themeName) {
+ var creditId;
+
+ if (themeSystem.match('bootstrap')) {
+ if (themeName) {
+ creditId = 'bootstrap-custom';
+ }
+ else {
+ creditId = 'bootstrap-standard';
+ }
+ }
+
+ Array.prototype.slice.call( // convert to real array
+ document.querySelectorAll('.credits')
+ ).forEach(function(creditEl) {
+ if (creditEl.getAttribute('data-credit-id') === creditId) {
+ creditEl.style.display = 'block';
+ } else {
+ creditEl.style.display = 'none';
+ }
+ })
+ }
+
+
+ function whenStylesheetLoaded(linkNode, callback) {
+ var isReady = false;
+
+ function ready() {
+ if (!isReady) { // avoid double-call
+ isReady = true;
+ callback();
+ }
+ }
+
+ linkNode.onload = ready; // does not work cross-browser
+ setTimeout(ready, 2000); // max wait. also handles browsers that don't support onload
+ }
+}
diff --git a/library/fullcalendar/demos/json.html b/library/fullcalendar/demos/json.html
new file mode 100644
index 000000000..a107361b0
--- /dev/null
+++ b/library/fullcalendar/demos/json.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ defaultDate: '2019-04-12',
+ editable: true,
+ navLinks: true, // can click day/week names to navigate views
+ eventLimit: true, // allow "more" link when too many events
+ events: {
+ url: 'php/get-events.php',
+ failure: function() {
+ document.getElementById('script-warning').style.display = 'block'
+ }
+ },
+ loading: function(bool) {
+ document.getElementById('loading').style.display =
+ bool ? 'block' : 'none';
+ }
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 0;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #script-warning {
+ display: none;
+ background: #eee;
+ border-bottom: 1px solid #ddd;
+ padding: 0 10px;
+ line-height: 40px;
+ text-align: center;
+ font-weight: bold;
+ font-size: 12px;
+ color: red;
+ }
+
+ #loading {
+ display: none;
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 40px auto;
+ padding: 0 10px;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='script-warning'>
+ <code>php/get-events.php</code> must be running.
+ </div>
+
+ <div id='loading'>loading...</div>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/json/events.json b/library/fullcalendar/demos/json/events.json
new file mode 100644
index 000000000..466f837ed
--- /dev/null
+++ b/library/fullcalendar/demos/json/events.json
@@ -0,0 +1,56 @@
+[
+ {
+ "title": "All Day Event",
+ "start": "2019-04-01"
+ },
+ {
+ "title": "Long Event",
+ "start": "2019-04-07",
+ "end": "2019-04-10"
+ },
+ {
+ "id": "999",
+ "title": "Repeating Event",
+ "start": "2019-04-09T16:00:00-05:00"
+ },
+ {
+ "id": "999",
+ "title": "Repeating Event",
+ "start": "2019-04-16T16:00:00-05:00"
+ },
+ {
+ "title": "Conference",
+ "start": "2019-04-11",
+ "end": "2019-04-13"
+ },
+ {
+ "title": "Meeting",
+ "start": "2019-04-12T10:30:00-05:00",
+ "end": "2019-04-12T12:30:00-05:00"
+ },
+ {
+ "title": "Lunch",
+ "start": "2019-04-12T12:00:00-05:00"
+ },
+ {
+ "title": "Meeting",
+ "start": "2019-04-12T14:30:00-05:00"
+ },
+ {
+ "title": "Happy Hour",
+ "start": "2019-04-12T17:30:00-05:00"
+ },
+ {
+ "title": "Dinner",
+ "start": "2019-04-12T20:00:00"
+ },
+ {
+ "title": "Birthday Party",
+ "start": "2019-04-13T07:00:00-05:00"
+ },
+ {
+ "title": "Click for Google",
+ "url": "http://google.com/",
+ "start": "2019-04-28"
+ }
+]
diff --git a/library/fullcalendar/demos/list-views.html b/library/fullcalendar/demos/list-views.html
new file mode 100644
index 000000000..744c08494
--- /dev/null
+++ b/library/fullcalendar/demos/list-views.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'list' ],
+
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'listDay,listWeek,dayGridMonth'
+ },
+
+ // customize the button names,
+ // otherwise they'd all just say "list"
+ views: {
+ listDay: { buttonText: 'list day' },
+ listWeek: { buttonText: 'list week' }
+ },
+
+ defaultView: 'listWeek',
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/locales.html b/library/fullcalendar/demos/locales.html
new file mode 100644
index 000000000..9e94b4b62
--- /dev/null
+++ b/library/fullcalendar/demos/locales.html
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/core/locales-all.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var initialLocaleCode = 'en';
+ var localeSelectorEl = document.getElementById('locale-selector');
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
+ },
+ defaultDate: '2019-04-12',
+ locale: initialLocaleCode,
+ buttonIcons: false, // show the prev/next text
+ weekNumbers: true,
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+
+ // build the locale selector's options
+ calendar.getAvailableLocaleCodes().forEach(function(localeCode) {
+ var optionEl = document.createElement('option');
+ optionEl.value = localeCode;
+ optionEl.selected = localeCode == initialLocaleCode;
+ optionEl.innerText = localeCode;
+ localeSelectorEl.appendChild(optionEl);
+ });
+
+ // when the selected option changes, dynamically change the calendar option
+ localeSelectorEl.addEventListener('change', function() {
+ if (this.value) {
+ calendar.setOption('locale', this.value);
+ }
+ });
+
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 0;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #top {
+ background: #eee;
+ border-bottom: 1px solid #ddd;
+ padding: 0 10px;
+ line-height: 40px;
+ font-size: 12px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 40px auto;
+ padding: 0 10px;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='top'>
+
+ Locales:
+ <select id='locale-selector'></select>
+
+ </div>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/php/get-events.php b/library/fullcalendar/demos/php/get-events.php
new file mode 100644
index 000000000..888201557
--- /dev/null
+++ b/library/fullcalendar/demos/php/get-events.php
@@ -0,0 +1,50 @@
+<?php
+
+//--------------------------------------------------------------------------------------------------
+// This script reads event data from a JSON file and outputs those events which are within the range
+// supplied by the "start" and "end" GET parameters.
+//
+// An optional "timeZone" GET parameter will force all ISO8601 date stings to a given timeZone.
+//
+// Requires PHP 5.2.0 or higher.
+//--------------------------------------------------------------------------------------------------
+
+// Require our Event class and datetime utilities
+require dirname(__FILE__) . '/utils.php';
+
+// Short-circuit if the client did not give us a date range.
+if (!isset($_GET['start']) || !isset($_GET['end'])) {
+ die("Please provide a date range.");
+}
+
+// Parse the start/end parameters.
+// These are assumed to be ISO8601 strings with no time nor timeZone, like "2013-12-29".
+// Since no timeZone will be present, they will parsed as UTC.
+$range_start = parseDateTime($_GET['start']);
+$range_end = parseDateTime($_GET['end']);
+
+// Parse the timeZone parameter if it is present.
+$timeZone = null;
+if (isset($_GET['timeZone'])) {
+ $timeZone = new DateTimeZone($_GET['timeZone']);
+}
+
+// Read and parse our events JSON file into an array of event data arrays.
+$json = file_get_contents(dirname(__FILE__) . '/../json/events.json');
+$input_arrays = json_decode($json, true);
+
+// Accumulate an output array of event data arrays.
+$output_arrays = array();
+foreach ($input_arrays as $array) {
+
+ // Convert the input array into a useful Event object
+ $event = new Event($array, $timeZone);
+
+ // If the event is in-bounds, add it to the output
+ if ($event->isWithinDayRange($range_start, $range_end)) {
+ $output_arrays[] = $event->toArray();
+ }
+}
+
+// Send JSON to the client.
+echo json_encode($output_arrays);
diff --git a/library/fullcalendar/demos/php/get-time-zones.php b/library/fullcalendar/demos/php/get-time-zones.php
new file mode 100644
index 000000000..241e1bd18
--- /dev/null
+++ b/library/fullcalendar/demos/php/get-time-zones.php
@@ -0,0 +1,9 @@
+<?php
+
+//--------------------------------------------------------------------------------------------------
+// This script outputs a JSON array of all timezones (like "America/Chicago") that PHP supports.
+//
+// Requires PHP 5.2.0 or higher.
+//--------------------------------------------------------------------------------------------------
+
+echo json_encode(DateTimeZone::listIdentifiers()); \ No newline at end of file
diff --git a/library/fullcalendar/demos/php/utils.php b/library/fullcalendar/demos/php/utils.php
new file mode 100644
index 000000000..aa67cda75
--- /dev/null
+++ b/library/fullcalendar/demos/php/utils.php
@@ -0,0 +1,130 @@
+<?php
+
+//--------------------------------------------------------------------------------------------------
+// Utilities for our event-fetching scripts.
+//
+// Requires PHP 5.2.0 or higher.
+//--------------------------------------------------------------------------------------------------
+
+// PHP will fatal error if we attempt to use the DateTime class without this being set.
+date_default_timezone_set('UTC');
+
+
+class Event {
+
+ // Tests whether the given ISO8601 string has a time-of-day or not
+ const ALL_DAY_REGEX = '/^\d{4}-\d\d-\d\d$/'; // matches strings like "2013-12-29"
+
+ public $title;
+ public $allDay; // a boolean
+ public $start; // a DateTime
+ public $end; // a DateTime, or null
+ public $properties = array(); // an array of other misc properties
+
+
+ // Constructs an Event object from the given array of key=>values.
+ // You can optionally force the timeZone of the parsed dates.
+ public function __construct($array, $timeZone=null) {
+
+ $this->title = $array['title'];
+
+ if (isset($array['allDay'])) {
+ // allDay has been explicitly specified
+ $this->allDay = (bool)$array['allDay'];
+ }
+ else {
+ // Guess allDay based off of ISO8601 date strings
+ $this->allDay = preg_match(self::ALL_DAY_REGEX, $array['start']) &&
+ (!isset($array['end']) || preg_match(self::ALL_DAY_REGEX, $array['end']));
+ }
+
+ if ($this->allDay) {
+ // If dates are allDay, we want to parse them in UTC to avoid DST issues.
+ $timeZone = null;
+ }
+
+ // Parse dates
+ $this->start = parseDateTime($array['start'], $timeZone);
+ $this->end = isset($array['end']) ? parseDateTime($array['end'], $timeZone) : null;
+
+ // Record misc properties
+ foreach ($array as $name => $value) {
+ if (!in_array($name, array('title', 'allDay', 'start', 'end'))) {
+ $this->properties[$name] = $value;
+ }
+ }
+ }
+
+
+ // Returns whether the date range of our event intersects with the given all-day range.
+ // $rangeStart and $rangeEnd are assumed to be dates in UTC with 00:00:00 time.
+ public function isWithinDayRange($rangeStart, $rangeEnd) {
+
+ // Normalize our event's dates for comparison with the all-day range.
+ $eventStart = stripTime($this->start);
+
+ if (isset($this->end)) {
+ $eventEnd = stripTime($this->end); // normalize
+ }
+ else {
+ $eventEnd = $eventStart; // consider this a zero-duration event
+ }
+
+ // Check if the two whole-day ranges intersect.
+ return $eventStart < $rangeEnd && $eventEnd >= $rangeStart;
+ }
+
+
+ // Converts this Event object back to a plain data array, to be used for generating JSON
+ public function toArray() {
+
+ // Start with the misc properties (don't worry, PHP won't affect the original array)
+ $array = $this->properties;
+
+ $array['title'] = $this->title;
+
+ // Figure out the date format. This essentially encodes allDay into the date string.
+ if ($this->allDay) {
+ $format = 'Y-m-d'; // output like "2013-12-29"
+ }
+ else {
+ $format = 'c'; // full ISO8601 output, like "2013-12-29T09:00:00+08:00"
+ }
+
+ // Serialize dates into strings
+ $array['start'] = $this->start->format($format);
+ if (isset($this->end)) {
+ $array['end'] = $this->end->format($format);
+ }
+
+ return $array;
+ }
+
+}
+
+
+// Date Utilities
+//----------------------------------------------------------------------------------------------
+
+
+// Parses a string into a DateTime object, optionally forced into the given timeZone.
+function parseDateTime($string, $timeZone=null) {
+ $date = new DateTime(
+ $string,
+ $timeZone ? $timeZone : new DateTimeZone('UTC')
+ // Used only when the string is ambiguous.
+ // Ignored if string has a timeZone offset in it.
+ );
+ if ($timeZone) {
+ // If our timeZone was ignored above, force it.
+ $date->setTimezone($timeZone);
+ }
+ return $date;
+}
+
+
+// Takes the year/month/date values of the given DateTime and converts them to a new DateTime,
+// but in UTC.
+function stripTime($datetime) {
+ return new DateTime($datetime->format('Y-m-d'));
+}
diff --git a/library/fullcalendar/demos/rrule.html b/library/fullcalendar/demos/rrule.html
new file mode 100644
index 000000000..d98234242
--- /dev/null
+++ b/library/fullcalendar/demos/rrule.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../vendor/rrule.js'></script>
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script src='../packages/rrule/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list', 'rrule' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
+ },
+ defaultDate: '2019-04-12',
+ editable: true,
+ events: [
+ {
+ title: 'rrule event',
+ rrule: {
+ dtstart: '2019-04-09T13:00:00',
+ // until: '2019-04-01',
+ freq: 'weekly'
+ },
+ duration: '02:00'
+ }
+ ],
+ eventClick: function(arg) {
+ if (confirm('delete event?')) {
+ arg.event.remove()
+ }
+ }
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/selectable.html b/library/fullcalendar/demos/selectable.html
new file mode 100644
index 000000000..3b0f84871
--- /dev/null
+++ b/library/fullcalendar/demos/selectable.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ selectable: true,
+ selectMirror: true,
+ select: function(arg) {
+ var title = prompt('Event Title:');
+ if (title) {
+ calendar.addEvent({
+ title: title,
+ start: arg.start,
+ end: arg.end,
+ allDay: arg.allDay
+ })
+ }
+ calendar.unselect()
+ },
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/themes.html b/library/fullcalendar/demos/themes.html
new file mode 100644
index 000000000..0f34ad04b
--- /dev/null
+++ b/library/fullcalendar/demos/themes.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='https://use.fontawesome.com/releases/v5.0.6/css/all.css' rel='stylesheet'>
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/bootstrap/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/bootstrap/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script src='js/theme-chooser.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+ var calendar;
+
+ initThemeChooser({
+
+ init: function(themeSystem) {
+ calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'bootstrap', 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ themeSystem: themeSystem,
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
+ },
+ defaultDate: '2019-04-12',
+ weekNumbers: true,
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+ calendar.render();
+ },
+
+ change: function(themeSystem) {
+ calendar.setOption('themeSystem', themeSystem);
+ }
+
+ });
+
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 0;
+ padding: 0;
+ font-size: 14px;
+ }
+
+ #top,
+ #calendar.fc-unthemed {
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ }
+
+ #top {
+ background: #eee;
+ border-bottom: 1px solid #ddd;
+ padding: 0 10px;
+ line-height: 40px;
+ font-size: 12px;
+ color: #000;
+ }
+
+ #top .selector {
+ display: inline-block;
+ margin-right: 10px;
+ }
+
+ #top select {
+ font: inherit; /* mock what Boostrap does, don't compete */
+ }
+
+ .left { float: left }
+ .right { float: right }
+ .clear { clear: both }
+
+ #calendar {
+ max-width: 900px;
+ margin: 40px auto;
+ padding: 0 10px;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='top'>
+
+ <div class='left'>
+
+ <div id='theme-system-selector' class='selector'>
+ Theme System:
+
+ <select>
+ <option value='bootstrap' selected>Bootstrap 4</option>
+ <option value='standard'>unthemed</option>
+ </select>
+ </div>
+
+ <div data-theme-system="bootstrap" class='selector' style='display:none'>
+ Theme Name:
+
+ <select>
+ <option value='' selected>Default</option>
+ <option value='cerulean'>Cerulean</option>
+ <option value='cosmo'>Cosmo</option>
+ <option value='cyborg'>Cyborg</option>
+ <option value='darkly'>Darkly</option>
+ <option value='flatly'>Flatly</option>
+ <option value='journal'>Journal</option>
+ <option value='litera'>Litera</option>
+ <option value='lumen'>Lumen</option>
+ <option value='lux'>Lux</option>
+ <option value='materia'>Materia</option>
+ <option value='minty'>Minty</option>
+ <option value='pulse'>Pulse</option>
+ <option value='sandstone'>Sandstone</option>
+ <option value='simplex'>Simplex</option>
+ <option value='sketchy'>Sketchy</option>
+ <option value='slate'>Slate</option>
+ <option value='solar'>Solar</option>
+ <option value='spacelab'>Spacelab</option>
+ <option value='superhero'>Superhero</option>
+ <option value='united'>United</option>
+ <option value='yeti'>Yeti</option>
+ </select>
+ </div>
+
+ <span id='loading' style='display:none'>loading theme...</span>
+
+ </div>
+
+ <div class='right'>
+ <span class='credits' data-credit-id='bootstrap-standard' style='display:none'>
+ <a href='https://getbootstrap.com/docs/3.3/' target='_blank'>Theme by Bootstrap</a>
+ </span>
+ <span class='credits' data-credit-id='bootstrap-custom' style='display:none'>
+ <a href='https://bootswatch.com/' target='_blank'>Theme by Bootswatch</a>
+ </span>
+ </div>
+
+ <div class='clear'></div>
+ </div>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/time-zones.html b/library/fullcalendar/demos/time-zones.html
new file mode 100644
index 000000000..5330fea9b
--- /dev/null
+++ b/library/fullcalendar/demos/time-zones.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var initialTimeZone = 'local';
+ var timeZoneSelectorEl = document.getElementById('time-zone-selector');
+ var loadingEl = document.getElementById('loading');
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ timeZone: initialTimeZone,
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ selectable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: {
+ url: 'php/get-events.php',
+ failure: function() {
+ document.getElementById('script-warning').style.display = 'inline'; // show
+ }
+ },
+ loading: function(bool) {
+ if (bool) {
+ loadingEl.style.display = 'inline'; // show
+ } else {
+ loadingEl.style.display = 'none'; // hide
+ }
+ },
+
+ eventTimeFormat: { hour: 'numeric', minute: '2-digit', timeZoneName: 'short' },
+
+ dateClick: function(arg) {
+ console.log('dateClick', calendar.formatIso(arg.date));
+ },
+ select: function(arg) {
+ console.log('select', calendar.formatIso(arg.start), calendar.formatIso(arg.end));
+ }
+ });
+
+ calendar.render();
+
+ // load the list of available timezones, build the <select> options
+ // it's HIGHLY recommended to use a different library for network requests, not this internal util func
+ FullCalendar.requestJson('GET', 'php/get-time-zones.php', {}, function(timeZones) {
+
+ timeZones.forEach(function(timeZone) {
+ var optionEl;
+
+ if (timeZone !== 'UTC') { // UTC is already in the list
+ optionEl = document.createElement('option');
+ optionEl.value = timeZone;
+ optionEl.innerText = timeZone;
+ timeZoneSelectorEl.appendChild(optionEl);
+ }
+ });
+ }, function() {
+ // TODO: handle error
+ });
+
+ // when the timezone selector changes, dynamically change the calendar option
+ timeZoneSelectorEl.addEventListener('change', function() {
+ calendar.setOption('timeZone', this.value);
+ });
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 0;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #top {
+ background: #eee;
+ border-bottom: 1px solid #ddd;
+ padding: 0 10px;
+ line-height: 40px;
+ font-size: 12px;
+ }
+ .left { float: left }
+ .right { float: right }
+ .clear { clear: both }
+
+ #script-warning, #loading { display: none }
+ #script-warning { font-weight: bold; color: red }
+
+ #calendar {
+ max-width: 900px;
+ margin: 40px auto;
+ padding: 0 10px;
+ }
+
+ .tzo {
+ color: #000;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='top'>
+
+ <div class='left'>
+ Timezone:
+ <select id='time-zone-selector'>
+ <option value='local' selected>local</option>
+ <option value='UTC'>UTC</option>
+ </select>
+ </div>
+
+ <div class='right'>
+ <span id='loading'>loading...</span>
+ <span id='script-warning'><code>php/get-events.php</code> must be running.</span>
+ </div>
+
+ <div class='clear'></div>
+
+ </div>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/timegrid-views.html b/library/fullcalendar/demos/timegrid-views.html
new file mode 100644
index 000000000..584991043
--- /dev/null
+++ b/library/fullcalendar/demos/timegrid-views.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'dayGrid', 'timeGrid', 'list', 'interaction' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01',
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/demos/week-numbers.html b/library/fullcalendar/demos/week-numbers.html
new file mode 100644
index 000000000..5ad5c4b1e
--- /dev/null
+++ b/library/fullcalendar/demos/week-numbers.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset='utf-8' />
+<link href='../packages/core/main.css' rel='stylesheet' />
+<link href='../packages/daygrid/main.css' rel='stylesheet' />
+<link href='../packages/timegrid/main.css' rel='stylesheet' />
+<link href='../packages/list/main.css' rel='stylesheet' />
+<script src='../packages/core/main.js'></script>
+<script src='../packages/interaction/main.js'></script>
+<script src='../packages/daygrid/main.js'></script>
+<script src='../packages/timegrid/main.js'></script>
+<script src='../packages/list/main.js'></script>
+<script>
+
+ document.addEventListener('DOMContentLoaded', function() {
+ var calendarEl = document.getElementById('calendar');
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+ },
+ defaultDate: '2019-04-12',
+ navLinks: true, // can click day/week names to navigate views
+
+ weekNumbers: true,
+ weekNumbersWithinDays: true,
+ weekNumberCalculation: 'ISO',
+
+ editable: true,
+ eventLimit: true, // allow "more" link when too many events
+ events: [
+ {
+ title: 'All Day Event',
+ start: '2019-04-01'
+ },
+ {
+ title: 'Long Event',
+ start: '2019-04-07',
+ end: '2019-04-10'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-09T16:00:00'
+ },
+ {
+ groupId: 999,
+ title: 'Repeating Event',
+ start: '2019-04-16T16:00:00'
+ },
+ {
+ title: 'Conference',
+ start: '2019-04-11',
+ end: '2019-04-13'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T10:30:00',
+ end: '2019-04-12T12:30:00'
+ },
+ {
+ title: 'Lunch',
+ start: '2019-04-12T12:00:00'
+ },
+ {
+ title: 'Meeting',
+ start: '2019-04-12T14:30:00'
+ },
+ {
+ title: 'Happy Hour',
+ start: '2019-04-12T17:30:00'
+ },
+ {
+ title: 'Dinner',
+ start: '2019-04-12T20:00:00'
+ },
+ {
+ title: 'Birthday Party',
+ start: '2019-04-13T07:00:00'
+ },
+ {
+ title: 'Click for Google',
+ url: 'http://google.com/',
+ start: '2019-04-28'
+ }
+ ]
+ });
+
+ calendar.render();
+ });
+
+</script>
+<style>
+
+ body {
+ margin: 40px 10px;
+ padding: 0;
+ font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
+ font-size: 14px;
+ }
+
+ #calendar {
+ max-width: 900px;
+ margin: 0 auto;
+ }
+
+</style>
+</head>
+<body>
+
+ <div id='calendar'></div>
+
+</body>
+</html>
diff --git a/library/fullcalendar/packages/bootstrap/main.css b/library/fullcalendar/packages/bootstrap/main.css
new file mode 100644
index 000000000..c639e307f
--- /dev/null
+++ b/library/fullcalendar/packages/bootstrap/main.css
@@ -0,0 +1,33 @@
+/*!
+FullCalendar Bootstrap Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+.fc.fc-bootstrap a {
+ text-decoration: none; }
+
+.fc.fc-bootstrap a[data-goto]:hover {
+ text-decoration: underline; }
+
+.fc-bootstrap hr.fc-divider {
+ border-color: inherit; }
+
+.fc-bootstrap .fc-today.alert {
+ border-radius: 0; }
+
+.fc-bootstrap a.fc-event:not([href]):not([tabindex]) {
+ color: #fff; }
+
+.fc-bootstrap .fc-popover.card {
+ position: absolute; }
+
+/* Popover
+--------------------------------------------------------------------------------------------------*/
+.fc-bootstrap .fc-popover .card-body {
+ padding: 0; }
+
+/* TimeGrid Slats (lines that run horizontally)
+--------------------------------------------------------------------------------------------------*/
+.fc-bootstrap .fc-time-grid .fc-slats table {
+ /* some themes have background color. see through to slats */
+ background: none; }
diff --git a/library/fullcalendar/packages/bootstrap/main.js b/library/fullcalendar/packages/bootstrap/main.js
new file mode 100644
index 000000000..78fe25b5c
--- /dev/null
+++ b/library/fullcalendar/packages/bootstrap/main.js
@@ -0,0 +1,90 @@
+/*!
+FullCalendar Bootstrap Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarBootstrap = {}, global.FullCalendar));
+}(this, function (exports, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var BootstrapTheme = /** @class */ (function (_super) {
+ __extends(BootstrapTheme, _super);
+ function BootstrapTheme() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ return BootstrapTheme;
+ }(core.Theme));
+ BootstrapTheme.prototype.classes = {
+ widget: 'fc-bootstrap',
+ tableGrid: 'table-bordered',
+ tableList: 'table',
+ tableListHeading: 'table-active',
+ buttonGroup: 'btn-group',
+ button: 'btn btn-primary',
+ buttonActive: 'active',
+ today: 'alert alert-info',
+ popover: 'card card-primary',
+ popoverHeader: 'card-header',
+ popoverContent: 'card-body',
+ // day grid
+ // for left/right border color when border is inset from edges (all-day in timeGrid view)
+ // avoid `table` class b/c don't want margins/padding/structure. only border color.
+ headerRow: 'table-bordered',
+ dayRow: 'table-bordered',
+ // list view
+ listView: 'card card-primary'
+ };
+ BootstrapTheme.prototype.baseIconClass = 'fa';
+ BootstrapTheme.prototype.iconClasses = {
+ close: 'fa-times',
+ prev: 'fa-chevron-left',
+ next: 'fa-chevron-right',
+ prevYear: 'fa-angle-double-left',
+ nextYear: 'fa-angle-double-right'
+ };
+ BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
+ BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
+ BootstrapTheme.prototype.iconOverridePrefix = 'fa-';
+ var main = core.createPlugin({
+ themeClasses: {
+ bootstrap: BootstrapTheme
+ }
+ });
+
+ exports.BootstrapTheme = BootstrapTheme;
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/bootstrap/main.min.css b/library/fullcalendar/packages/bootstrap/main.min.css
new file mode 100644
index 000000000..c2685e34e
--- /dev/null
+++ b/library/fullcalendar/packages/bootstrap/main.min.css
@@ -0,0 +1,5 @@
+/*!
+FullCalendar Bootstrap Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/.fc.fc-bootstrap a{text-decoration:none}.fc.fc-bootstrap a[data-goto]:hover{text-decoration:underline}.fc-bootstrap hr.fc-divider{border-color:inherit}.fc-bootstrap .fc-today.alert{border-radius:0}.fc-bootstrap a.fc-event:not([href]):not([tabindex]){color:#fff}.fc-bootstrap .fc-popover.card{position:absolute}.fc-bootstrap .fc-popover .card-body{padding:0}.fc-bootstrap .fc-time-grid .fc-slats table{background:0 0} \ No newline at end of file
diff --git a/library/fullcalendar/packages/bootstrap/main.min.js b/library/fullcalendar/packages/bootstrap/main.min.js
new file mode 100644
index 000000000..f8cca364c
--- /dev/null
+++ b/library/fullcalendar/packages/bootstrap/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Bootstrap Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarBootstrap={},e.FullCalendar))}(this,function(e,t){"use strict";function o(e,t){function o(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var o in t)t.hasOwnProperty(o)&&(e[o]=t[o])})(e,t)},a=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return o(t,e),t}(t.Theme);a.prototype.classes={widget:"fc-bootstrap",tableGrid:"table-bordered",tableList:"table",tableListHeading:"table-active",buttonGroup:"btn-group",button:"btn btn-primary",buttonActive:"active",today:"alert alert-info",popover:"card card-primary",popoverHeader:"card-header",popoverContent:"card-body",headerRow:"table-bordered",dayRow:"table-bordered",listView:"card card-primary"},a.prototype.baseIconClass="fa",a.prototype.iconClasses={close:"fa-times",prev:"fa-chevron-left",next:"fa-chevron-right",prevYear:"fa-angle-double-left",nextYear:"fa-angle-double-right"},a.prototype.iconOverrideOption="bootstrapFontAwesome",a.prototype.iconOverrideCustomButtonOption="bootstrapFontAwesome",a.prototype.iconOverridePrefix="fa-";var n=t.createPlugin({themeClasses:{bootstrap:a}});e.BootstrapTheme=a,e.default=n,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/core/locales-all.js b/library/fullcalendar/packages/core/locales-all.js
new file mode 100644
index 000000000..b21cd2d12
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales-all.js
@@ -0,0 +1,1353 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, global.FullCalendarLocalesAll = factory());
+}(this, function () { 'use strict';
+
+ var _m0 = {
+ code: "af",
+ week: {
+ dow: 1,
+ doy: 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
+ },
+ buttonText: {
+ prev: "Vorige",
+ next: "Volgende",
+ today: "Vandag",
+ year: "Jaar",
+ month: "Maand",
+ week: "Week",
+ day: "Dag",
+ list: "Agenda"
+ },
+ allDayHtml: "Heeldag",
+ eventLimitText: "Addisionele",
+ noEventsMessage: "Daar is geen gebeurtenisse nie"
+ };
+
+ var _m1 = {
+ code: "ar-dz",
+ week: {
+ dow: 0,
+ doy: 4 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m2 = {
+ code: "ar-kw",
+ week: {
+ dow: 0,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m3 = {
+ code: "ar-ly",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m4 = {
+ code: "ar-ma",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m5 = {
+ code: "ar-sa",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m6 = {
+ code: "ar-tn",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m7 = {
+ code: "ar",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ var _m8 = {
+ code: "bg",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "назад",
+ next: "напред",
+ today: "днес",
+ month: "Месец",
+ week: "Седмица",
+ day: "Ден",
+ list: "График"
+ },
+ allDayText: "Цял ден",
+ eventLimitText: function (n) {
+ return "+още " + n;
+ },
+ noEventsMessage: "Няма събития за показване"
+ };
+
+ var _m9 = {
+ code: "bs",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prošli",
+ next: "Sljedeći",
+ today: "Danas",
+ month: "Mjesec",
+ week: "Sedmica",
+ day: "Dan",
+ list: "Raspored"
+ },
+ weekLabel: "Sed",
+ allDayText: "Cijeli dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nema događaja za prikazivanje"
+ };
+
+ var _m10 = {
+ code: "ca",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Anterior",
+ next: "Següent",
+ today: "Avui",
+ month: "Mes",
+ week: "Setmana",
+ day: "Dia",
+ list: "Agenda"
+ },
+ weekLabel: "Set",
+ allDayText: "Tot el dia",
+ eventLimitText: "més",
+ noEventsMessage: "No hi ha esdeveniments per mostrar"
+ };
+
+ var _m11 = {
+ code: "cs",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Dříve",
+ next: "Později",
+ today: "Nyní",
+ month: "Měsíc",
+ week: "Týden",
+ day: "Den",
+ list: "Agenda"
+ },
+ weekLabel: "Týd",
+ allDayText: "Celý den",
+ eventLimitText: function (n) {
+ return "+další: " + n;
+ },
+ noEventsMessage: "Žádné akce k zobrazení"
+ };
+
+ var _m12 = {
+ code: "da",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Forrige",
+ next: "Næste",
+ today: "Idag",
+ month: "Måned",
+ week: "Uge",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Uge",
+ allDayText: "Hele dagen",
+ eventLimitText: "flere",
+ noEventsMessage: "Ingen arrangementer at vise"
+ };
+
+ var _m13 = {
+ code: "de",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Zurück",
+ next: "Vor",
+ today: "Heute",
+ year: "Jahr",
+ month: "Monat",
+ week: "Woche",
+ day: "Tag",
+ list: "Terminübersicht"
+ },
+ weekLabel: "KW",
+ allDayText: "Ganztägig",
+ eventLimitText: function (n) {
+ return "+ weitere " + n;
+ },
+ noEventsMessage: "Keine Ereignisse anzuzeigen"
+ };
+
+ var _m14 = {
+ code: "el",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Προηγούμενος",
+ next: "Επόμενος",
+ today: "Σήμερα",
+ month: "Μήνας",
+ week: "Εβδομάδα",
+ day: "Ημέρα",
+ list: "Ατζέντα"
+ },
+ weekLabel: "Εβδ",
+ allDayText: "Ολοήμερο",
+ eventLimitText: "περισσότερα",
+ noEventsMessage: "Δεν υπάρχουν γεγονότα για να εμφανιστεί"
+ };
+
+ var _m15 = {
+ code: "en-au",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ var _m16 = {
+ code: "en-gb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ var _m17 = {
+ code: "en-nz",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ var _m18 = {
+ code: "es",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Sig",
+ today: "Hoy",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>el día",
+ eventLimitText: "más",
+ noEventsMessage: "No hay eventos para mostrar"
+ };
+
+ var _m19 = {
+ code: "es",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Sig",
+ today: "Hoy",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>el día",
+ eventLimitText: "más",
+ noEventsMessage: "No hay eventos para mostrar"
+ };
+
+ var _m20 = {
+ code: "et",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Eelnev",
+ next: "Järgnev",
+ today: "Täna",
+ month: "Kuu",
+ week: "Nädal",
+ day: "Päev",
+ list: "Päevakord"
+ },
+ weekLabel: "näd",
+ allDayText: "Kogu päev",
+ eventLimitText: function (n) {
+ return "+ veel " + n;
+ },
+ noEventsMessage: "Kuvamiseks puuduvad sündmused"
+ };
+
+ var _m21 = {
+ code: "eu",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Aur",
+ next: "Hur",
+ today: "Gaur",
+ month: "Hilabetea",
+ week: "Astea",
+ day: "Eguna",
+ list: "Agenda"
+ },
+ weekLabel: "As",
+ allDayHtml: "Egun<br/>osoa",
+ eventLimitText: "gehiago",
+ noEventsMessage: "Ez dago ekitaldirik erakusteko"
+ };
+
+ var _m22 = {
+ code: "fa",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "قبلی",
+ next: "بعدی",
+ today: "امروز",
+ month: "ماه",
+ week: "هفته",
+ day: "روز",
+ list: "برنامه"
+ },
+ weekLabel: "هف",
+ allDayText: "تمام روز",
+ eventLimitText: function (n) {
+ return "بیش از " + n;
+ },
+ noEventsMessage: "هیچ رویدادی به نمایش"
+ };
+
+ var _m23 = {
+ code: "fi",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Edellinen",
+ next: "Seuraava",
+ today: "Tänään",
+ month: "Kuukausi",
+ week: "Viikko",
+ day: "Päivä",
+ list: "Tapahtumat"
+ },
+ weekLabel: "Vk",
+ allDayText: "Koko päivä",
+ eventLimitText: "lisää",
+ noEventsMessage: "Ei näytettäviä tapahtumia"
+ };
+
+ var _m24 = {
+ code: "fr",
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Aujourd'hui",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sem.",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ var _m25 = {
+ code: "fr-ch",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Courant",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ var _m26 = {
+ code: "fr",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Aujourd'hui",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sem.",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ var _m27 = {
+ code: "gl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Seg",
+ today: "Hoxe",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Axenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>o día",
+ eventLimitText: "máis",
+ noEventsMessage: "Non hai eventos para amosar"
+ };
+
+ var _m28 = {
+ code: "he",
+ dir: 'rtl',
+ buttonText: {
+ prev: "הקודם",
+ next: "הבא",
+ today: "היום",
+ month: "חודש",
+ week: "שבוע",
+ day: "יום",
+ list: "סדר יום"
+ },
+ allDayText: "כל היום",
+ eventLimitText: "אחר",
+ noEventsMessage: "אין אירועים להצגה",
+ weekLabel: "שבוע"
+ };
+
+ var _m29 = {
+ code: "hi",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "पिछला",
+ next: "अगला",
+ today: "आज",
+ month: "महीना",
+ week: "सप्ताह",
+ day: "दिन",
+ list: "कार्यसूची"
+ },
+ weekLabel: "हफ्ता",
+ allDayText: "सभी दिन",
+ eventLimitText: function (n) {
+ return "+अधिक " + n;
+ },
+ noEventsMessage: "कोई घटनाओं को प्रदर्शित करने के लिए"
+ };
+
+ var _m30 = {
+ code: "hr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prijašnji",
+ next: "Sljedeći",
+ today: "Danas",
+ month: "Mjesec",
+ week: "Tjedan",
+ day: "Dan",
+ list: "Raspored"
+ },
+ weekLabel: "Tje",
+ allDayText: "Cijeli dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nema događaja za prikaz"
+ };
+
+ var _m31 = {
+ code: "hu",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "vissza",
+ next: "előre",
+ today: "ma",
+ month: "Hónap",
+ week: "Hét",
+ day: "Nap",
+ list: "Napló"
+ },
+ weekLabel: "Hét",
+ allDayText: "Egész nap",
+ eventLimitText: "további",
+ noEventsMessage: "Nincs megjeleníthető esemény"
+ };
+
+ var _m32 = {
+ code: "id",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "mundur",
+ next: "maju",
+ today: "hari ini",
+ month: "Bulan",
+ week: "Minggu",
+ day: "Hari",
+ list: "Agenda"
+ },
+ weekLabel: "Mg",
+ allDayHtml: "Sehari<br/>penuh",
+ eventLimitText: "lebih",
+ noEventsMessage: "Tidak ada acara untuk ditampilkan"
+ };
+
+ var _m33 = {
+ code: "is",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Fyrri",
+ next: "Næsti",
+ today: "Í dag",
+ month: "Mánuður",
+ week: "Vika",
+ day: "Dagur",
+ list: "Dagskrá"
+ },
+ weekLabel: "Vika",
+ allDayHtml: "Allan<br/>daginn",
+ eventLimitText: "meira",
+ noEventsMessage: "Engir viðburðir til að sýna"
+ };
+
+ var _m34 = {
+ code: "it",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prec",
+ next: "Succ",
+ today: "Oggi",
+ month: "Mese",
+ week: "Settimana",
+ day: "Giorno",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Tutto il<br/>giorno",
+ eventLimitText: function (n) {
+ return "+altri " + n;
+ },
+ noEventsMessage: "Non ci sono eventi da visualizzare"
+ };
+
+ var _m35 = {
+ code: "ja",
+ buttonText: {
+ prev: "前",
+ next: "次",
+ today: "今日",
+ month: "月",
+ week: "週",
+ day: "日",
+ list: "予定リスト"
+ },
+ weekLabel: "週",
+ allDayText: "終日",
+ eventLimitText: function (n) {
+ return "他 " + n + " 件";
+ },
+ noEventsMessage: "表示する予定はありません"
+ };
+
+ var _m36 = {
+ code: "ka",
+ week: {
+ dow: 1,
+ doy: 7
+ },
+ buttonText: {
+ prev: "წინა",
+ next: "შემდეგი",
+ today: "დღეს",
+ month: "თვე",
+ week: "კვირა",
+ day: "დღე",
+ list: "დღის წესრიგი"
+ },
+ weekLabel: "კვ",
+ allDayText: "მთელი დღე",
+ eventLimitText: function (n) {
+ return "+ კიდევ " + n;
+ },
+ noEventsMessage: "ღონისძიებები არ არის"
+ };
+
+ var _m37 = {
+ code: "kk",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Алдыңғы",
+ next: "Келесі",
+ today: "Бүгін",
+ month: "Ай",
+ week: "Апта",
+ day: "Күн",
+ list: "Күн тәртібі"
+ },
+ weekLabel: "Не",
+ allDayText: "Күні бойы",
+ eventLimitText: function (n) {
+ return "+ тағы " + n;
+ },
+ noEventsMessage: "Көрсету үшін оқиғалар жоқ"
+ };
+
+ var _m38 = {
+ code: "ko",
+ buttonText: {
+ prev: "이전달",
+ next: "다음달",
+ today: "오늘",
+ month: "월",
+ week: "주",
+ day: "일",
+ list: "일정목록"
+ },
+ weekLabel: "주",
+ allDayText: "종일",
+ eventLimitText: "개",
+ noEventsMessage: "일정이 없습니다"
+ };
+
+ var _m39 = {
+ code: "lb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Zréck",
+ next: "Weider",
+ today: "Haut",
+ month: "Mount",
+ week: "Woch",
+ day: "Dag",
+ list: "Terminiwwersiicht"
+ },
+ weekLabel: "W",
+ allDayText: "Ganzen Dag",
+ eventLimitText: "méi",
+ noEventsMessage: "Nee Evenementer ze affichéieren"
+ };
+
+ var _m40 = {
+ code: "lt",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Atgal",
+ next: "Pirmyn",
+ today: "Šiandien",
+ month: "Mėnuo",
+ week: "Savaitė",
+ day: "Diena",
+ list: "Darbotvarkė"
+ },
+ weekLabel: "SAV",
+ allDayText: "Visą dieną",
+ eventLimitText: "daugiau",
+ noEventsMessage: "Nėra įvykių rodyti"
+ };
+
+ var _m41 = {
+ code: "lv",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Iepr.",
+ next: "Nāk.",
+ today: "Šodien",
+ month: "Mēnesis",
+ week: "Nedēļa",
+ day: "Diena",
+ list: "Dienas kārtība"
+ },
+ weekLabel: "Ned.",
+ allDayText: "Visu dienu",
+ eventLimitText: function (n) {
+ return "+vēl " + n;
+ },
+ noEventsMessage: "Nav notikumu"
+ };
+
+ var _m42 = {
+ code: "mk",
+ buttonText: {
+ prev: "претходно",
+ next: "следно",
+ today: "Денес",
+ month: "Месец",
+ week: "Недела",
+ day: "Ден",
+ list: "График"
+ },
+ weekLabel: "Сед",
+ allDayText: "Цел ден",
+ eventLimitText: function (n) {
+ return "+повеќе " + n;
+ },
+ noEventsMessage: "Нема настани за прикажување"
+ };
+
+ var _m43 = {
+ code: "ms",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Sebelum",
+ next: "Selepas",
+ today: "hari ini",
+ month: "Bulan",
+ week: "Minggu",
+ day: "Hari",
+ list: "Agenda"
+ },
+ weekLabel: "Mg",
+ allDayText: "Sepanjang hari",
+ eventLimitText: function (n) {
+ return "masih ada " + n + " acara";
+ },
+ noEventsMessage: "Tiada peristiwa untuk dipaparkan"
+ };
+
+ var _m44 = {
+ code: "nb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Forrige",
+ next: "Neste",
+ today: "I dag",
+ month: "Måned",
+ week: "Uke",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Uke",
+ allDayText: "Hele dagen",
+ eventLimitText: "til",
+ noEventsMessage: "Ingen hendelser å vise"
+ };
+
+ var _m45 = {
+ code: "nl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Voorgaand",
+ next: "Volgende",
+ today: "Vandaag",
+ year: "Jaar",
+ month: "Maand",
+ week: "Week",
+ day: "Dag",
+ list: "Agenda"
+ },
+ allDayText: "Hele dag",
+ eventLimitText: "extra",
+ noEventsMessage: "Geen evenementen om te laten zien"
+ };
+
+ var _m46 = {
+ code: "nn",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Førre",
+ next: "Neste",
+ today: "I dag",
+ month: "Månad",
+ week: "Veke",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Veke",
+ allDayText: "Heile dagen",
+ eventLimitText: "til",
+ noEventsMessage: "Ingen hendelser å vise"
+ };
+
+ var _m47 = {
+ code: "pl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Poprzedni",
+ next: "Następny",
+ today: "Dziś",
+ month: "Miesiąc",
+ week: "Tydzień",
+ day: "Dzień",
+ list: "Plan dnia"
+ },
+ weekLabel: "Tydz",
+ allDayText: "Cały dzień",
+ eventLimitText: "więcej",
+ noEventsMessage: "Brak wydarzeń do wyświetlenia"
+ };
+
+ var _m48 = {
+ code: "pt-br",
+ buttonText: {
+ prev: "Anterior",
+ next: "Próximo",
+ today: "Hoje",
+ month: "Mês",
+ week: "Semana",
+ day: "Dia",
+ list: "Compromissos"
+ },
+ weekLabel: "Sm",
+ allDayText: "dia inteiro",
+ eventLimitText: function (n) {
+ return "mais +" + n;
+ },
+ noEventsMessage: "Não há eventos para mostrar"
+ };
+
+ var _m49 = {
+ code: "pt",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Anterior",
+ next: "Seguinte",
+ today: "Hoje",
+ month: "Mês",
+ week: "Semana",
+ day: "Dia",
+ list: "Agenda"
+ },
+ weekLabel: "Sem",
+ allDayText: "Todo o dia",
+ eventLimitText: "mais",
+ noEventsMessage: "Não há eventos para mostrar"
+ };
+
+ var _m50 = {
+ code: "ro",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "precedentă",
+ next: "următoare",
+ today: "Azi",
+ month: "Lună",
+ week: "Săptămână",
+ day: "Zi",
+ list: "Agendă"
+ },
+ weekLabel: "Săpt",
+ allDayText: "Toată ziua",
+ eventLimitText: function (n) {
+ return "+alte " + n;
+ },
+ noEventsMessage: "Nu există evenimente de afișat"
+ };
+
+ var _m51 = {
+ code: "ru",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Пред",
+ next: "След",
+ today: "Сегодня",
+ month: "Месяц",
+ week: "Неделя",
+ day: "День",
+ list: "Повестка дня"
+ },
+ weekLabel: "Нед",
+ allDayText: "Весь день",
+ eventLimitText: function (n) {
+ return "+ ещё " + n;
+ },
+ noEventsMessage: "Нет событий для отображения"
+ };
+
+ var _m52 = {
+ code: "sk",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Predchádzajúci",
+ next: "Nasledujúci",
+ today: "Dnes",
+ month: "Mesiac",
+ week: "Týždeň",
+ day: "Deň",
+ list: "Rozvrh"
+ },
+ weekLabel: "Ty",
+ allDayText: "Celý deň",
+ eventLimitText: function (n) {
+ return "+ďalšie: " + n;
+ },
+ noEventsMessage: "Žiadne akcie na zobrazenie"
+ };
+
+ var _m53 = {
+ code: "sl",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prejšnji",
+ next: "Naslednji",
+ today: "Trenutni",
+ month: "Mesec",
+ week: "Teden",
+ day: "Dan",
+ list: "Dnevni red"
+ },
+ weekLabel: "Teden",
+ allDayText: "Ves dan",
+ eventLimitText: "več",
+ noEventsMessage: "Ni dogodkov za prikaz"
+ };
+
+ var _m54 = {
+ code: "sq",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "mbrapa",
+ next: "Përpara",
+ today: "sot",
+ month: "Muaj",
+ week: "Javë",
+ day: "Ditë",
+ list: "Listë"
+ },
+ weekLabel: "Ja",
+ allDayHtml: "Gjithë<br/>ditën",
+ eventLimitText: function (n) {
+ return "+më tepër " + n;
+ },
+ noEventsMessage: "Nuk ka evente për të shfaqur"
+ };
+
+ var _m55 = {
+ code: "sr-cyrl",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Претходна",
+ next: "следећи",
+ today: "Данас",
+ month: "Месец",
+ week: "Недеља",
+ day: "Дан",
+ list: "Планер"
+ },
+ weekLabel: "Сед",
+ allDayText: "Цео дан",
+ eventLimitText: function (n) {
+ return "+ још " + n;
+ },
+ noEventsMessage: "Нема догађаја за приказ"
+ };
+
+ var _m56 = {
+ code: "sr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prethodna",
+ next: "Sledeći",
+ today: "Danas",
+ month: "Mеsеc",
+ week: "Nеdеlja",
+ day: "Dan",
+ list: "Planеr"
+ },
+ weekLabel: "Sed",
+ allDayText: "Cеo dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nеma događaja za prikaz"
+ };
+
+ var _m57 = {
+ code: "sv",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Förra",
+ next: "Nästa",
+ today: "Idag",
+ month: "Månad",
+ week: "Vecka",
+ day: "Dag",
+ list: "Program"
+ },
+ weekLabel: "v.",
+ allDayText: "Heldag",
+ eventLimitText: "till",
+ noEventsMessage: "Inga händelser att visa"
+ };
+
+ var _m58 = {
+ code: "th",
+ buttonText: {
+ prev: "ย้อน",
+ next: "ถัดไป",
+ today: "วันนี้",
+ month: "เดือน",
+ week: "สัปดาห์",
+ day: "วัน",
+ list: "แผนงาน"
+ },
+ allDayText: "ตลอดวัน",
+ eventLimitText: "เพิ่มเติม",
+ noEventsMessage: "ไม่มีกิจกรรมที่จะแสดง"
+ };
+
+ var _m59 = {
+ code: "tr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "geri",
+ next: "ileri",
+ today: "bugün",
+ month: "Ay",
+ week: "Hafta",
+ day: "Gün",
+ list: "Ajanda"
+ },
+ weekLabel: "Hf",
+ allDayText: "Tüm gün",
+ eventLimitText: "daha fazla",
+ noEventsMessage: "Gösterilecek etkinlik yok"
+ };
+
+ var _m60 = {
+ code: "uk",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Попередній",
+ next: "далі",
+ today: "Сьогодні",
+ month: "Місяць",
+ week: "Тиждень",
+ day: "День",
+ list: "Порядок денний"
+ },
+ weekLabel: "Тиж",
+ allDayText: "Увесь день",
+ eventLimitText: function (n) {
+ return "+ще " + n + "...";
+ },
+ noEventsMessage: "Немає подій для відображення"
+ };
+
+ var _m61 = {
+ code: "vi",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Trước",
+ next: "Tiếp",
+ today: "Hôm nay",
+ month: "Tháng",
+ week: "Tuần",
+ day: "Ngày",
+ list: "Lịch biểu"
+ },
+ weekLabel: "Tu",
+ allDayText: "Cả ngày",
+ eventLimitText: function (n) {
+ return "+ thêm " + n;
+ },
+ noEventsMessage: "Không có sự kiện để hiển thị"
+ };
+
+ var _m62 = {
+ code: "zh-cn",
+ week: {
+ // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "上月",
+ next: "下月",
+ today: "今天",
+ month: "月",
+ week: "周",
+ day: "日",
+ list: "日程"
+ },
+ weekLabel: "周",
+ allDayText: "全天",
+ eventLimitText: function (n) {
+ return "另外 " + n + " 个";
+ },
+ noEventsMessage: "没有事件显示"
+ };
+
+ var _m63 = {
+ code: "zh-tw",
+ buttonText: {
+ prev: "上月",
+ next: "下月",
+ today: "今天",
+ month: "月",
+ week: "週",
+ day: "天",
+ list: "活動列表"
+ },
+ weekLabel: "周",
+ allDayText: "整天",
+ eventLimitText: '顯示更多',
+ noEventsMessage: "没有任何活動"
+ };
+
+ var _arrayEntry = [
+ _m0, _m1, _m2, _m3, _m4, _m5, _m6, _m7, _m8, _m9, _m10, _m11, _m12, _m13, _m14, _m15, _m16, _m17, _m18, _m19, _m20, _m21, _m22, _m23, _m24, _m25, _m26, _m27, _m28, _m29, _m30, _m31, _m32, _m33, _m34, _m35, _m36, _m37, _m38, _m39, _m40, _m41, _m42, _m43, _m44, _m45, _m46, _m47, _m48, _m49, _m50, _m51, _m52, _m53, _m54, _m55, _m56, _m57, _m58, _m59, _m60, _m61, _m62, _m63
+ ];
+
+ return _arrayEntry;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales-all.min.js b/library/fullcalendar/packages/core/locales-all.min.js
new file mode 100644
index 000000000..2b250c788
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales-all.min.js
@@ -0,0 +1,6 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,e.FullCalendarLocalesAll=t())}(this,function(){"use strict";return[{code:"af",week:{dow:1,doy:4},buttonText:{prev:"Vorige",next:"Volgende",today:"Vandag",year:"Jaar",month:"Maand",week:"Week",day:"Dag",list:"Agenda"},allDayHtml:"Heeldag",eventLimitText:"Addisionele",noEventsMessage:"Daar is geen gebeurtenisse nie"},{code:"ar-dz",week:{dow:0,doy:4},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar-kw",week:{dow:0,doy:12},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar-ly",week:{dow:6,doy:12},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar-ma",week:{dow:6,doy:12},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar-sa",week:{dow:0,doy:6},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar-tn",week:{dow:1,doy:4},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"ar",week:{dow:6,doy:12},dir:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekLabel:"أسبوع",allDayText:"اليوم كله",eventLimitText:"أخرى",noEventsMessage:"أي أحداث لعرض"},{code:"bg",week:{dow:1,doy:7},buttonText:{prev:"назад",next:"напред",today:"днес",month:"Месец",week:"Седмица",day:"Ден",list:"График"},allDayText:"Цял ден",eventLimitText:function(e){return"+още "+e},noEventsMessage:"Няма събития за показване"},{code:"bs",week:{dow:1,doy:7},buttonText:{prev:"Prošli",next:"Sljedeći",today:"Danas",month:"Mjesec",week:"Sedmica",day:"Dan",list:"Raspored"},weekLabel:"Sed",allDayText:"Cijeli dan",eventLimitText:function(e){return"+ još "+e},noEventsMessage:"Nema događaja za prikazivanje"},{code:"ca",week:{dow:1,doy:4},buttonText:{prev:"Anterior",next:"Següent",today:"Avui",month:"Mes",week:"Setmana",day:"Dia",list:"Agenda"},weekLabel:"Set",allDayText:"Tot el dia",eventLimitText:"més",noEventsMessage:"No hi ha esdeveniments per mostrar"},{code:"cs",week:{dow:1,doy:4},buttonText:{prev:"Dříve",next:"Později",today:"Nyní",month:"Měsíc",week:"Týden",day:"Den",list:"Agenda"},weekLabel:"Týd",allDayText:"Celý den",eventLimitText:function(e){return"+další: "+e},noEventsMessage:"Žádné akce k zobrazení"},{code:"da",week:{dow:1,doy:4},buttonText:{prev:"Forrige",next:"Næste",today:"Idag",month:"Måned",week:"Uge",day:"Dag",list:"Agenda"},weekLabel:"Uge",allDayText:"Hele dagen",eventLimitText:"flere",noEventsMessage:"Ingen arrangementer at vise"},{code:"de",week:{dow:1,doy:4},buttonText:{prev:"Zurück",next:"Vor",today:"Heute",year:"Jahr",month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},weekLabel:"KW",allDayText:"Ganztägig",eventLimitText:function(e){return"+ weitere "+e},noEventsMessage:"Keine Ereignisse anzuzeigen"},{code:"el",week:{dow:1,doy:4},buttonText:{prev:"Προηγούμενος",next:"Επόμενος",today:"Σήμερα",month:"Μήνας",week:"Εβδομάδα",day:"Ημέρα",list:"Ατζέντα"},weekLabel:"Εβδ",allDayText:"Ολοήμερο",eventLimitText:"περισσότερα",noEventsMessage:"Δεν υπάρχουν γεγονότα για να εμφανιστεί"},{code:"en-au",week:{dow:1,doy:4}},{code:"en-gb",week:{dow:1,doy:4}},{code:"en-nz",week:{dow:1,doy:4}},{code:"es",week:{dow:0,doy:6},buttonText:{prev:"Ant",next:"Sig",today:"Hoy",month:"Mes",week:"Semana",day:"Día",list:"Agenda"},weekLabel:"Sm",allDayHtml:"Todo<br/>el día",eventLimitText:"más",noEventsMessage:"No hay eventos para mostrar"},{code:"es",week:{dow:1,doy:4},buttonText:{prev:"Ant",next:"Sig",today:"Hoy",month:"Mes",week:"Semana",day:"Día",list:"Agenda"},weekLabel:"Sm",allDayHtml:"Todo<br/>el día",eventLimitText:"más",noEventsMessage:"No hay eventos para mostrar"},{code:"et",week:{dow:1,doy:4},buttonText:{prev:"Eelnev",next:"Järgnev",today:"Täna",month:"Kuu",week:"Nädal",day:"Päev",list:"Päevakord"},weekLabel:"näd",allDayText:"Kogu päev",eventLimitText:function(e){return"+ veel "+e},noEventsMessage:"Kuvamiseks puuduvad sündmused"},{code:"eu",week:{dow:1,doy:7},buttonText:{prev:"Aur",next:"Hur",today:"Gaur",month:"Hilabetea",week:"Astea",day:"Eguna",list:"Agenda"},weekLabel:"As",allDayHtml:"Egun<br/>osoa",eventLimitText:"gehiago",noEventsMessage:"Ez dago ekitaldirik erakusteko"},{code:"fa",week:{dow:6,doy:12},dir:"rtl",buttonText:{prev:"قبلی",next:"بعدی",today:"امروز",month:"ماه",week:"هفته",day:"روز",list:"برنامه"},weekLabel:"هف",allDayText:"تمام روز",eventLimitText:function(e){return"بیش از "+e},noEventsMessage:"هیچ رویدادی به نمایش"},{code:"fi",week:{dow:1,doy:4},buttonText:{prev:"Edellinen",next:"Seuraava",today:"Tänään",month:"Kuukausi",week:"Viikko",day:"Päivä",list:"Tapahtumat"},weekLabel:"Vk",allDayText:"Koko päivä",eventLimitText:"lisää",noEventsMessage:"Ei näytettäviä tapahtumia"},{code:"fr",buttonText:{prev:"Précédent",next:"Suivant",today:"Aujourd'hui",year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},weekLabel:"Sem.",allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus",noEventsMessage:"Aucun événement à afficher"},{code:"fr-ch",week:{dow:1,doy:4},buttonText:{prev:"Précédent",next:"Suivant",today:"Courant",year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},weekLabel:"Sm",allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus",noEventsMessage:"Aucun événement à afficher"},{code:"fr",week:{dow:1,doy:4},buttonText:{prev:"Précédent",next:"Suivant",today:"Aujourd'hui",year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},weekLabel:"Sem.",allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus",noEventsMessage:"Aucun événement à afficher"},{code:"gl",week:{dow:1,doy:4},buttonText:{prev:"Ant",next:"Seg",today:"Hoxe",month:"Mes",week:"Semana",day:"Día",list:"Axenda"},weekLabel:"Sm",allDayHtml:"Todo<br/>o día",eventLimitText:"máis",noEventsMessage:"Non hai eventos para amosar"},{code:"he",dir:"rtl",buttonText:{prev:"הקודם",next:"הבא",today:"היום",month:"חודש",week:"שבוע",day:"יום",list:"סדר יום"},allDayText:"כל היום",eventLimitText:"אחר",noEventsMessage:"אין אירועים להצגה",weekLabel:"שבוע"},{code:"hi",week:{dow:0,doy:6},buttonText:{prev:"पिछला",next:"अगला",today:"आज",month:"महीना",week:"सप्ताह",day:"दिन",list:"कार्यसूची"},weekLabel:"हफ्ता",allDayText:"सभी दिन",eventLimitText:function(e){return"+अधिक "+e},noEventsMessage:"कोई घटनाओं को प्रदर्शित करने के लिए"},{code:"hr",week:{dow:1,doy:7},buttonText:{prev:"Prijašnji",next:"Sljedeći",today:"Danas",month:"Mjesec",week:"Tjedan",day:"Dan",list:"Raspored"},weekLabel:"Tje",allDayText:"Cijeli dan",eventLimitText:function(e){return"+ još "+e},noEventsMessage:"Nema događaja za prikaz"},{code:"hu",week:{dow:1,doy:4},buttonText:{prev:"vissza",next:"előre",today:"ma",month:"Hónap",week:"Hét",day:"Nap",list:"Napló"},weekLabel:"Hét",allDayText:"Egész nap",eventLimitText:"további",noEventsMessage:"Nincs megjeleníthető esemény"},{code:"id",week:{dow:1,doy:7},buttonText:{prev:"mundur",next:"maju",today:"hari ini",month:"Bulan",week:"Minggu",day:"Hari",list:"Agenda"},weekLabel:"Mg",allDayHtml:"Sehari<br/>penuh",eventLimitText:"lebih",noEventsMessage:"Tidak ada acara untuk ditampilkan"},{code:"is",week:{dow:1,doy:4},buttonText:{prev:"Fyrri",next:"Næsti",today:"Í dag",month:"Mánuður",week:"Vika",day:"Dagur",list:"Dagskrá"},weekLabel:"Vika",allDayHtml:"Allan<br/>daginn",eventLimitText:"meira",noEventsMessage:"Engir viðburðir til að sýna"},{code:"it",week:{dow:1,doy:4},buttonText:{prev:"Prec",next:"Succ",today:"Oggi",month:"Mese",week:"Settimana",day:"Giorno",list:"Agenda"},weekLabel:"Sm",allDayHtml:"Tutto il<br/>giorno",eventLimitText:function(e){return"+altri "+e},noEventsMessage:"Non ci sono eventi da visualizzare"},{code:"ja",buttonText:{prev:"前",next:"次",today:"今日",month:"月",week:"週",day:"日",list:"予定リスト"},weekLabel:"週",allDayText:"終日",eventLimitText:function(e){return"他 "+e+" 件"},noEventsMessage:"表示する予定はありません"},{code:"ka",week:{dow:1,doy:7},buttonText:{prev:"წინა",next:"შემდეგი",today:"დღეს",month:"თვე",week:"კვირა",day:"დღე",list:"დღის წესრიგი"},weekLabel:"კვ",allDayText:"მთელი დღე",eventLimitText:function(e){return"+ კიდევ "+e},noEventsMessage:"ღონისძიებები არ არის"},{code:"kk",week:{dow:1,doy:7},buttonText:{prev:"Алдыңғы",next:"Келесі",today:"Бүгін",month:"Ай",week:"Апта",day:"Күн",list:"Күн тәртібі"},weekLabel:"Не",allDayText:"Күні бойы",eventLimitText:function(e){return"+ тағы "+e},noEventsMessage:"Көрсету үшін оқиғалар жоқ"},{code:"ko",buttonText:{prev:"이전달",next:"다음달",today:"오늘",month:"월",week:"주",day:"일",list:"일정목록"},weekLabel:"주",allDayText:"종일",eventLimitText:"개",noEventsMessage:"일정이 없습니다"},{code:"lb",week:{dow:1,doy:4},buttonText:{prev:"Zréck",next:"Weider",today:"Haut",month:"Mount",week:"Woch",day:"Dag",list:"Terminiwwersiicht"},weekLabel:"W",allDayText:"Ganzen Dag",eventLimitText:"méi",noEventsMessage:"Nee Evenementer ze affichéieren"},{code:"lt",week:{dow:1,doy:4},buttonText:{prev:"Atgal",next:"Pirmyn",today:"Šiandien",month:"Mėnuo",week:"Savaitė",day:"Diena",list:"Darbotvarkė"},weekLabel:"SAV",allDayText:"Visą dieną",eventLimitText:"daugiau",noEventsMessage:"Nėra įvykių rodyti"},{code:"lv",week:{dow:1,doy:4},buttonText:{prev:"Iepr.",next:"Nāk.",today:"Šodien",month:"Mēnesis",week:"Nedēļa",day:"Diena",list:"Dienas kārtība"},weekLabel:"Ned.",allDayText:"Visu dienu",eventLimitText:function(e){return"+vēl "+e},noEventsMessage:"Nav notikumu"},{code:"mk",buttonText:{prev:"претходно",next:"следно",today:"Денес",month:"Месец",week:"Недела",day:"Ден",list:"График"},weekLabel:"Сед",allDayText:"Цел ден",eventLimitText:function(e){return"+повеќе "+e},noEventsMessage:"Нема настани за прикажување"},{code:"ms",week:{dow:1,doy:7},buttonText:{prev:"Sebelum",next:"Selepas",today:"hari ini",month:"Bulan",week:"Minggu",day:"Hari",list:"Agenda"},weekLabel:"Mg",allDayText:"Sepanjang hari",eventLimitText:function(e){return"masih ada "+e+" acara"},noEventsMessage:"Tiada peristiwa untuk dipaparkan"},{code:"nb",week:{dow:1,doy:4},buttonText:{prev:"Forrige",next:"Neste",today:"I dag",month:"Måned",week:"Uke",day:"Dag",list:"Agenda"},weekLabel:"Uke",allDayText:"Hele dagen",eventLimitText:"til",noEventsMessage:"Ingen hendelser å vise"},{code:"nl",week:{dow:1,doy:4},buttonText:{prev:"Voorgaand",next:"Volgende",today:"Vandaag",year:"Jaar",month:"Maand",week:"Week",day:"Dag",list:"Agenda"},allDayText:"Hele dag",eventLimitText:"extra",noEventsMessage:"Geen evenementen om te laten zien"},{code:"nn",week:{dow:1,doy:4},buttonText:{prev:"Førre",next:"Neste",today:"I dag",month:"Månad",week:"Veke",day:"Dag",list:"Agenda"},weekLabel:"Veke",allDayText:"Heile dagen",eventLimitText:"til",noEventsMessage:"Ingen hendelser å vise"},{code:"pl",week:{dow:1,doy:4},buttonText:{prev:"Poprzedni",next:"Następny",today:"Dziś",month:"Miesiąc",week:"Tydzień",day:"Dzień",list:"Plan dnia"},weekLabel:"Tydz",allDayText:"Cały dzień",eventLimitText:"więcej",noEventsMessage:"Brak wydarzeń do wyświetlenia"},{code:"pt-br",buttonText:{prev:"Anterior",next:"Próximo",today:"Hoje",month:"Mês",week:"Semana",day:"Dia",list:"Compromissos"},weekLabel:"Sm",allDayText:"dia inteiro",eventLimitText:function(e){return"mais +"+e},noEventsMessage:"Não há eventos para mostrar"},{code:"pt",week:{dow:1,doy:4},buttonText:{prev:"Anterior",next:"Seguinte",today:"Hoje",month:"Mês",week:"Semana",day:"Dia",list:"Agenda"},weekLabel:"Sem",allDayText:"Todo o dia",eventLimitText:"mais",noEventsMessage:"Não há eventos para mostrar"},{code:"ro",week:{dow:1,doy:7},buttonText:{prev:"precedentă",next:"următoare",today:"Azi",month:"Lună",week:"Săptămână",day:"Zi",list:"Agendă"},weekLabel:"Săpt",allDayText:"Toată ziua",eventLimitText:function(e){return"+alte "+e},noEventsMessage:"Nu există evenimente de afișat"},{code:"ru",week:{dow:1,doy:4},buttonText:{prev:"Пред",next:"След",today:"Сегодня",month:"Месяц",week:"Неделя",day:"День",list:"Повестка дня"},weekLabel:"Нед",allDayText:"Весь день",eventLimitText:function(e){return"+ ещё "+e},noEventsMessage:"Нет событий для отображения"},{code:"sk",week:{dow:1,doy:4},buttonText:{prev:"Predchádzajúci",next:"Nasledujúci",today:"Dnes",month:"Mesiac",week:"Týždeň",day:"Deň",list:"Rozvrh"},weekLabel:"Ty",allDayText:"Celý deň",eventLimitText:function(e){return"+ďalšie: "+e},noEventsMessage:"Žiadne akcie na zobrazenie"},{code:"sl",week:{dow:1,doy:7},buttonText:{prev:"Prejšnji",next:"Naslednji",today:"Trenutni",month:"Mesec",week:"Teden",day:"Dan",list:"Dnevni red"},weekLabel:"Teden",allDayText:"Ves dan",eventLimitText:"več",noEventsMessage:"Ni dogodkov za prikaz"},{code:"sq",week:{dow:1,doy:4},buttonText:{prev:"mbrapa",next:"Përpara",today:"sot",month:"Muaj",week:"Javë",day:"Ditë",list:"Listë"},weekLabel:"Ja",allDayHtml:"Gjithë<br/>ditën",eventLimitText:function(e){return"+më tepër "+e},noEventsMessage:"Nuk ka evente për të shfaqur"},{code:"sr-cyrl",week:{dow:1,doy:7},buttonText:{prev:"Претходна",next:"следећи",today:"Данас",month:"Месец",week:"Недеља",day:"Дан",list:"Планер"},weekLabel:"Сед",allDayText:"Цео дан",eventLimitText:function(e){return"+ још "+e},noEventsMessage:"Нема догађаја за приказ"},{code:"sr",week:{dow:1,doy:7},buttonText:{prev:"Prethodna",next:"Sledeći",today:"Danas",month:"Mеsеc",week:"Nеdеlja",day:"Dan",list:"Planеr"},weekLabel:"Sed",allDayText:"Cеo dan",eventLimitText:function(e){return"+ još "+e},noEventsMessage:"Nеma događaja za prikaz"},{code:"sv",week:{dow:1,doy:4},buttonText:{prev:"Förra",next:"Nästa",today:"Idag",month:"Månad",week:"Vecka",day:"Dag",list:"Program"},weekLabel:"v.",allDayText:"Heldag",eventLimitText:"till",noEventsMessage:"Inga händelser att visa"},{code:"th",buttonText:{prev:"ย้อน",next:"ถัดไป",today:"วันนี้",month:"เดือน",week:"สัปดาห์",day:"วัน",list:"แผนงาน"},allDayText:"ตลอดวัน",eventLimitText:"เพิ่มเติม",noEventsMessage:"ไม่มีกิจกรรมที่จะแสดง"},{code:"tr",week:{dow:1,doy:7},buttonText:{prev:"geri",next:"ileri",today:"bugün",month:"Ay",week:"Hafta",day:"Gün",list:"Ajanda"},weekLabel:"Hf",allDayText:"Tüm gün",eventLimitText:"daha fazla",noEventsMessage:"Gösterilecek etkinlik yok"},{code:"uk",week:{dow:1,doy:7},buttonText:{prev:"Попередній",next:"далі",today:"Сьогодні",month:"Місяць",week:"Тиждень",day:"День",list:"Порядок денний"},weekLabel:"Тиж",allDayText:"Увесь день",eventLimitText:function(e){return"+ще "+e+"..."},noEventsMessage:"Немає подій для відображення"},{code:"vi",week:{dow:1,doy:4},buttonText:{prev:"Trước",next:"Tiếp",today:"Hôm nay",month:"Tháng",week:"Tuần",day:"Ngày",list:"Lịch biểu"},weekLabel:"Tu",allDayText:"Cả ngày",eventLimitText:function(e){return"+ thêm "+e},noEventsMessage:"Không có sự kiện để hiển thị"},{code:"zh-cn",week:{dow:1,doy:4},buttonText:{prev:"上月",next:"下月",today:"今天",month:"月",week:"周",day:"日",list:"日程"},weekLabel:"周",allDayText:"全天",eventLimitText:function(e){return"另外 "+e+" 个"},noEventsMessage:"没有事件显示"},{code:"zh-tw",buttonText:{prev:"上月",next:"下月",today:"今天",month:"月",week:"週",day:"天",list:"活動列表"},weekLabel:"周",allDayText:"整天",eventLimitText:"顯示更多",noEventsMessage:"没有任何活動"}]}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/core/locales/af.js b/library/fullcalendar/packages/core/locales/af.js
new file mode 100644
index 000000000..ee9f9f747
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/af.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.af = factory()));
+}(this, function () { 'use strict';
+
+ var af = {
+ code: "af",
+ week: {
+ dow: 1,
+ doy: 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
+ },
+ buttonText: {
+ prev: "Vorige",
+ next: "Volgende",
+ today: "Vandag",
+ year: "Jaar",
+ month: "Maand",
+ week: "Week",
+ day: "Dag",
+ list: "Agenda"
+ },
+ allDayHtml: "Heeldag",
+ eventLimitText: "Addisionele",
+ noEventsMessage: "Daar is geen gebeurtenisse nie"
+ };
+
+ return af;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-dz.js b/library/fullcalendar/packages/core/locales/ar-dz.js
new file mode 100644
index 000000000..201eb171a
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-dz.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-dz'] = factory()));
+}(this, function () { 'use strict';
+
+ var arDz = {
+ code: "ar-dz",
+ week: {
+ dow: 0,
+ doy: 4 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arDz;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-kw.js b/library/fullcalendar/packages/core/locales/ar-kw.js
new file mode 100644
index 000000000..94c690014
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-kw.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-kw'] = factory()));
+}(this, function () { 'use strict';
+
+ var arKw = {
+ code: "ar-kw",
+ week: {
+ dow: 0,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arKw;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-ly.js b/library/fullcalendar/packages/core/locales/ar-ly.js
new file mode 100644
index 000000000..e1c8aeb07
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-ly.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-ly'] = factory()));
+}(this, function () { 'use strict';
+
+ var arLy = {
+ code: "ar-ly",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arLy;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-ma.js b/library/fullcalendar/packages/core/locales/ar-ma.js
new file mode 100644
index 000000000..00cc7c679
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-ma.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-ma'] = factory()));
+}(this, function () { 'use strict';
+
+ var arMa = {
+ code: "ar-ma",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arMa;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-sa.js b/library/fullcalendar/packages/core/locales/ar-sa.js
new file mode 100644
index 000000000..0361f6d87
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-sa.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-sa'] = factory()));
+}(this, function () { 'use strict';
+
+ var arSa = {
+ code: "ar-sa",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arSa;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar-tn.js b/library/fullcalendar/packages/core/locales/ar-tn.js
new file mode 100644
index 000000000..57a07f8f5
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar-tn.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-tn'] = factory()));
+}(this, function () { 'use strict';
+
+ var arTn = {
+ code: "ar-tn",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return arTn;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ar.js b/library/fullcalendar/packages/core/locales/ar.js
new file mode 100644
index 000000000..f789afd15
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ar.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ar = factory()));
+}(this, function () { 'use strict';
+
+ var ar = {
+ code: "ar",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "السابق",
+ next: "التالي",
+ today: "اليوم",
+ month: "شهر",
+ week: "أسبوع",
+ day: "يوم",
+ list: "أجندة"
+ },
+ weekLabel: "أسبوع",
+ allDayText: "اليوم كله",
+ eventLimitText: "أخرى",
+ noEventsMessage: "أي أحداث لعرض"
+ };
+
+ return ar;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/bg.js b/library/fullcalendar/packages/core/locales/bg.js
new file mode 100644
index 000000000..e7343a6c5
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/bg.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.bg = factory()));
+}(this, function () { 'use strict';
+
+ var bg = {
+ code: "bg",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "назад",
+ next: "напред",
+ today: "днес",
+ month: "Месец",
+ week: "Седмица",
+ day: "Ден",
+ list: "График"
+ },
+ allDayText: "Цял ден",
+ eventLimitText: function (n) {
+ return "+още " + n;
+ },
+ noEventsMessage: "Няма събития за показване"
+ };
+
+ return bg;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/bs.js b/library/fullcalendar/packages/core/locales/bs.js
new file mode 100644
index 000000000..d96b8adb3
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/bs.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.bs = factory()));
+}(this, function () { 'use strict';
+
+ var bs = {
+ code: "bs",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prošli",
+ next: "Sljedeći",
+ today: "Danas",
+ month: "Mjesec",
+ week: "Sedmica",
+ day: "Dan",
+ list: "Raspored"
+ },
+ weekLabel: "Sed",
+ allDayText: "Cijeli dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nema događaja za prikazivanje"
+ };
+
+ return bs;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ca.js b/library/fullcalendar/packages/core/locales/ca.js
new file mode 100644
index 000000000..d2d3e2aa7
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ca.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ca = factory()));
+}(this, function () { 'use strict';
+
+ var ca = {
+ code: "ca",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Anterior",
+ next: "Següent",
+ today: "Avui",
+ month: "Mes",
+ week: "Setmana",
+ day: "Dia",
+ list: "Agenda"
+ },
+ weekLabel: "Set",
+ allDayText: "Tot el dia",
+ eventLimitText: "més",
+ noEventsMessage: "No hi ha esdeveniments per mostrar"
+ };
+
+ return ca;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/cs.js b/library/fullcalendar/packages/core/locales/cs.js
new file mode 100644
index 000000000..2624e3607
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/cs.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.cs = factory()));
+}(this, function () { 'use strict';
+
+ var cs = {
+ code: "cs",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Dříve",
+ next: "Později",
+ today: "Nyní",
+ month: "Měsíc",
+ week: "Týden",
+ day: "Den",
+ list: "Agenda"
+ },
+ weekLabel: "Týd",
+ allDayText: "Celý den",
+ eventLimitText: function (n) {
+ return "+další: " + n;
+ },
+ noEventsMessage: "Žádné akce k zobrazení"
+ };
+
+ return cs;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/da.js b/library/fullcalendar/packages/core/locales/da.js
new file mode 100644
index 000000000..2388d2e11
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/da.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.da = factory()));
+}(this, function () { 'use strict';
+
+ var da = {
+ code: "da",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Forrige",
+ next: "Næste",
+ today: "Idag",
+ month: "Måned",
+ week: "Uge",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Uge",
+ allDayText: "Hele dagen",
+ eventLimitText: "flere",
+ noEventsMessage: "Ingen arrangementer at vise"
+ };
+
+ return da;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/de.js b/library/fullcalendar/packages/core/locales/de.js
new file mode 100644
index 000000000..ab5a815a0
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/de.js
@@ -0,0 +1,33 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.de = factory()));
+}(this, function () { 'use strict';
+
+ var de = {
+ code: "de",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Zurück",
+ next: "Vor",
+ today: "Heute",
+ year: "Jahr",
+ month: "Monat",
+ week: "Woche",
+ day: "Tag",
+ list: "Terminübersicht"
+ },
+ weekLabel: "KW",
+ allDayText: "Ganztägig",
+ eventLimitText: function (n) {
+ return "+ weitere " + n;
+ },
+ noEventsMessage: "Keine Ereignisse anzuzeigen"
+ };
+
+ return de;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/el.js b/library/fullcalendar/packages/core/locales/el.js
new file mode 100644
index 000000000..9f59e3657
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/el.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.el = factory()));
+}(this, function () { 'use strict';
+
+ var el = {
+ code: "el",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Προηγούμενος",
+ next: "Επόμενος",
+ today: "Σήμερα",
+ month: "Μήνας",
+ week: "Εβδομάδα",
+ day: "Ημέρα",
+ list: "Ατζέντα"
+ },
+ weekLabel: "Εβδ",
+ allDayText: "Ολοήμερο",
+ eventLimitText: "περισσότερα",
+ noEventsMessage: "Δεν υπάρχουν γεγονότα για να εμφανιστεί"
+ };
+
+ return el;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/en-au.js b/library/fullcalendar/packages/core/locales/en-au.js
new file mode 100644
index 000000000..be10bfb66
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/en-au.js
@@ -0,0 +1,17 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-au'] = factory()));
+}(this, function () { 'use strict';
+
+ var enAu = {
+ code: "en-au",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ return enAu;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/en-gb.js b/library/fullcalendar/packages/core/locales/en-gb.js
new file mode 100644
index 000000000..8a4a84e6b
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/en-gb.js
@@ -0,0 +1,17 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-gb'] = factory()));
+}(this, function () { 'use strict';
+
+ var enGb = {
+ code: "en-gb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ return enGb;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/en-nz.js b/library/fullcalendar/packages/core/locales/en-nz.js
new file mode 100644
index 000000000..df56c1455
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/en-nz.js
@@ -0,0 +1,17 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-nz'] = factory()));
+}(this, function () { 'use strict';
+
+ var enNz = {
+ code: "en-nz",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ };
+
+ return enNz;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/es-us.js b/library/fullcalendar/packages/core/locales/es-us.js
new file mode 100644
index 000000000..1efa89a4d
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/es-us.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['es-us'] = factory()));
+}(this, function () { 'use strict';
+
+ var esUs = {
+ code: "es",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Sig",
+ today: "Hoy",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>el día",
+ eventLimitText: "más",
+ noEventsMessage: "No hay eventos para mostrar"
+ };
+
+ return esUs;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/es.js b/library/fullcalendar/packages/core/locales/es.js
new file mode 100644
index 000000000..bfd9af4c6
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/es.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.es = factory()));
+}(this, function () { 'use strict';
+
+ var es = {
+ code: "es",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Sig",
+ today: "Hoy",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>el día",
+ eventLimitText: "más",
+ noEventsMessage: "No hay eventos para mostrar"
+ };
+
+ return es;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/et.js b/library/fullcalendar/packages/core/locales/et.js
new file mode 100644
index 000000000..c44fcaec9
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/et.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.et = factory()));
+}(this, function () { 'use strict';
+
+ var et = {
+ code: "et",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Eelnev",
+ next: "Järgnev",
+ today: "Täna",
+ month: "Kuu",
+ week: "Nädal",
+ day: "Päev",
+ list: "Päevakord"
+ },
+ weekLabel: "näd",
+ allDayText: "Kogu päev",
+ eventLimitText: function (n) {
+ return "+ veel " + n;
+ },
+ noEventsMessage: "Kuvamiseks puuduvad sündmused"
+ };
+
+ return et;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/eu.js b/library/fullcalendar/packages/core/locales/eu.js
new file mode 100644
index 000000000..91903aaaf
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/eu.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.eu = factory()));
+}(this, function () { 'use strict';
+
+ var eu = {
+ code: "eu",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Aur",
+ next: "Hur",
+ today: "Gaur",
+ month: "Hilabetea",
+ week: "Astea",
+ day: "Eguna",
+ list: "Agenda"
+ },
+ weekLabel: "As",
+ allDayHtml: "Egun<br/>osoa",
+ eventLimitText: "gehiago",
+ noEventsMessage: "Ez dago ekitaldirik erakusteko"
+ };
+
+ return eu;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/fa.js b/library/fullcalendar/packages/core/locales/fa.js
new file mode 100644
index 000000000..031fc7b30
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/fa.js
@@ -0,0 +1,33 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fa = factory()));
+}(this, function () { 'use strict';
+
+ var fa = {
+ code: "fa",
+ week: {
+ dow: 6,
+ doy: 12 // The week that contains Jan 1st is the first week of the year.
+ },
+ dir: 'rtl',
+ buttonText: {
+ prev: "قبلی",
+ next: "بعدی",
+ today: "امروز",
+ month: "ماه",
+ week: "هفته",
+ day: "روز",
+ list: "برنامه"
+ },
+ weekLabel: "هف",
+ allDayText: "تمام روز",
+ eventLimitText: function (n) {
+ return "بیش از " + n;
+ },
+ noEventsMessage: "هیچ رویدادی به نمایش"
+ };
+
+ return fa;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/fi.js b/library/fullcalendar/packages/core/locales/fi.js
new file mode 100644
index 000000000..3912845cf
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/fi.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fi = factory()));
+}(this, function () { 'use strict';
+
+ var fi = {
+ code: "fi",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Edellinen",
+ next: "Seuraava",
+ today: "Tänään",
+ month: "Kuukausi",
+ week: "Viikko",
+ day: "Päivä",
+ list: "Tapahtumat"
+ },
+ weekLabel: "Vk",
+ allDayText: "Koko päivä",
+ eventLimitText: "lisää",
+ noEventsMessage: "Ei näytettäviä tapahtumia"
+ };
+
+ return fi;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/fr-ca.js b/library/fullcalendar/packages/core/locales/fr-ca.js
new file mode 100644
index 000000000..d554c1408
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/fr-ca.js
@@ -0,0 +1,27 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['fr-ca'] = factory()));
+}(this, function () { 'use strict';
+
+ var frCa = {
+ code: "fr",
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Aujourd'hui",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sem.",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ return frCa;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/fr-ch.js b/library/fullcalendar/packages/core/locales/fr-ch.js
new file mode 100644
index 000000000..358b8bf31
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/fr-ch.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['fr-ch'] = factory()));
+}(this, function () { 'use strict';
+
+ var frCh = {
+ code: "fr-ch",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Courant",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ return frCh;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/fr.js b/library/fullcalendar/packages/core/locales/fr.js
new file mode 100644
index 000000000..b679ceffd
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/fr.js
@@ -0,0 +1,31 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fr = factory()));
+}(this, function () { 'use strict';
+
+ var fr = {
+ code: "fr",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Précédent",
+ next: "Suivant",
+ today: "Aujourd'hui",
+ year: "Année",
+ month: "Mois",
+ week: "Semaine",
+ day: "Jour",
+ list: "Mon planning"
+ },
+ weekLabel: "Sem.",
+ allDayHtml: "Toute la<br/>journée",
+ eventLimitText: "en plus",
+ noEventsMessage: "Aucun événement à afficher"
+ };
+
+ return fr;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/gl.js b/library/fullcalendar/packages/core/locales/gl.js
new file mode 100644
index 000000000..721a6a89b
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/gl.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.gl = factory()));
+}(this, function () { 'use strict';
+
+ var gl = {
+ code: "gl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Ant",
+ next: "Seg",
+ today: "Hoxe",
+ month: "Mes",
+ week: "Semana",
+ day: "Día",
+ list: "Axenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Todo<br/>o día",
+ eventLimitText: "máis",
+ noEventsMessage: "Non hai eventos para amosar"
+ };
+
+ return gl;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/he.js b/library/fullcalendar/packages/core/locales/he.js
new file mode 100644
index 000000000..3521d9e33
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/he.js
@@ -0,0 +1,27 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.he = factory()));
+}(this, function () { 'use strict';
+
+ var he = {
+ code: "he",
+ dir: 'rtl',
+ buttonText: {
+ prev: "הקודם",
+ next: "הבא",
+ today: "היום",
+ month: "חודש",
+ week: "שבוע",
+ day: "יום",
+ list: "סדר יום"
+ },
+ allDayText: "כל היום",
+ eventLimitText: "אחר",
+ noEventsMessage: "אין אירועים להצגה",
+ weekLabel: "שבוע"
+ };
+
+ return he;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/hi.js b/library/fullcalendar/packages/core/locales/hi.js
new file mode 100644
index 000000000..15348e697
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/hi.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hi = factory()));
+}(this, function () { 'use strict';
+
+ var hi = {
+ code: "hi",
+ week: {
+ dow: 0,
+ doy: 6 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "पिछला",
+ next: "अगला",
+ today: "आज",
+ month: "महीना",
+ week: "सप्ताह",
+ day: "दिन",
+ list: "कार्यसूची"
+ },
+ weekLabel: "हफ्ता",
+ allDayText: "सभी दिन",
+ eventLimitText: function (n) {
+ return "+अधिक " + n;
+ },
+ noEventsMessage: "कोई घटनाओं को प्रदर्शित करने के लिए"
+ };
+
+ return hi;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/hr.js b/library/fullcalendar/packages/core/locales/hr.js
new file mode 100644
index 000000000..295b48566
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/hr.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hr = factory()));
+}(this, function () { 'use strict';
+
+ var hr = {
+ code: "hr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prijašnji",
+ next: "Sljedeći",
+ today: "Danas",
+ month: "Mjesec",
+ week: "Tjedan",
+ day: "Dan",
+ list: "Raspored"
+ },
+ weekLabel: "Tje",
+ allDayText: "Cijeli dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nema događaja za prikaz"
+ };
+
+ return hr;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/hu.js b/library/fullcalendar/packages/core/locales/hu.js
new file mode 100644
index 000000000..2f0fe8acb
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/hu.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hu = factory()));
+}(this, function () { 'use strict';
+
+ var hu = {
+ code: "hu",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "vissza",
+ next: "előre",
+ today: "ma",
+ month: "Hónap",
+ week: "Hét",
+ day: "Nap",
+ list: "Napló"
+ },
+ weekLabel: "Hét",
+ allDayText: "Egész nap",
+ eventLimitText: "további",
+ noEventsMessage: "Nincs megjeleníthető esemény"
+ };
+
+ return hu;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/id.js b/library/fullcalendar/packages/core/locales/id.js
new file mode 100644
index 000000000..b742e80dd
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/id.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.id = factory()));
+}(this, function () { 'use strict';
+
+ var id = {
+ code: "id",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "mundur",
+ next: "maju",
+ today: "hari ini",
+ month: "Bulan",
+ week: "Minggu",
+ day: "Hari",
+ list: "Agenda"
+ },
+ weekLabel: "Mg",
+ allDayHtml: "Sehari<br/>penuh",
+ eventLimitText: "lebih",
+ noEventsMessage: "Tidak ada acara untuk ditampilkan"
+ };
+
+ return id;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/is.js b/library/fullcalendar/packages/core/locales/is.js
new file mode 100644
index 000000000..dd569bce7
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/is.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.is = factory()));
+}(this, function () { 'use strict';
+
+ var is = {
+ code: "is",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Fyrri",
+ next: "Næsti",
+ today: "Í dag",
+ month: "Mánuður",
+ week: "Vika",
+ day: "Dagur",
+ list: "Dagskrá"
+ },
+ weekLabel: "Vika",
+ allDayHtml: "Allan<br/>daginn",
+ eventLimitText: "meira",
+ noEventsMessage: "Engir viðburðir til að sýna"
+ };
+
+ return is;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/it.js b/library/fullcalendar/packages/core/locales/it.js
new file mode 100644
index 000000000..39a2829e5
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/it.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.it = factory()));
+}(this, function () { 'use strict';
+
+ var it = {
+ code: "it",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prec",
+ next: "Succ",
+ today: "Oggi",
+ month: "Mese",
+ week: "Settimana",
+ day: "Giorno",
+ list: "Agenda"
+ },
+ weekLabel: "Sm",
+ allDayHtml: "Tutto il<br/>giorno",
+ eventLimitText: function (n) {
+ return "+altri " + n;
+ },
+ noEventsMessage: "Non ci sono eventi da visualizzare"
+ };
+
+ return it;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ja.js b/library/fullcalendar/packages/core/locales/ja.js
new file mode 100644
index 000000000..eb4245b2a
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ja.js
@@ -0,0 +1,28 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ja = factory()));
+}(this, function () { 'use strict';
+
+ var ja = {
+ code: "ja",
+ buttonText: {
+ prev: "前",
+ next: "次",
+ today: "今日",
+ month: "月",
+ week: "週",
+ day: "日",
+ list: "予定リスト"
+ },
+ weekLabel: "週",
+ allDayText: "終日",
+ eventLimitText: function (n) {
+ return "他 " + n + " 件";
+ },
+ noEventsMessage: "表示する予定はありません"
+ };
+
+ return ja;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ka.js b/library/fullcalendar/packages/core/locales/ka.js
new file mode 100644
index 000000000..b971c033f
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ka.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ka = factory()));
+}(this, function () { 'use strict';
+
+ var ka = {
+ code: "ka",
+ week: {
+ dow: 1,
+ doy: 7
+ },
+ buttonText: {
+ prev: "წინა",
+ next: "შემდეგი",
+ today: "დღეს",
+ month: "თვე",
+ week: "კვირა",
+ day: "დღე",
+ list: "დღის წესრიგი"
+ },
+ weekLabel: "კვ",
+ allDayText: "მთელი დღე",
+ eventLimitText: function (n) {
+ return "+ კიდევ " + n;
+ },
+ noEventsMessage: "ღონისძიებები არ არის"
+ };
+
+ return ka;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/kk.js b/library/fullcalendar/packages/core/locales/kk.js
new file mode 100644
index 000000000..5b19b99d5
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/kk.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.kk = factory()));
+}(this, function () { 'use strict';
+
+ var kk = {
+ code: "kk",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Алдыңғы",
+ next: "Келесі",
+ today: "Бүгін",
+ month: "Ай",
+ week: "Апта",
+ day: "Күн",
+ list: "Күн тәртібі"
+ },
+ weekLabel: "Не",
+ allDayText: "Күні бойы",
+ eventLimitText: function (n) {
+ return "+ тағы " + n;
+ },
+ noEventsMessage: "Көрсету үшін оқиғалар жоқ"
+ };
+
+ return kk;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ko.js b/library/fullcalendar/packages/core/locales/ko.js
new file mode 100644
index 000000000..ffe985d6c
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ko.js
@@ -0,0 +1,26 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ko = factory()));
+}(this, function () { 'use strict';
+
+ var ko = {
+ code: "ko",
+ buttonText: {
+ prev: "이전달",
+ next: "다음달",
+ today: "오늘",
+ month: "월",
+ week: "주",
+ day: "일",
+ list: "일정목록"
+ },
+ weekLabel: "주",
+ allDayText: "종일",
+ eventLimitText: "개",
+ noEventsMessage: "일정이 없습니다"
+ };
+
+ return ko;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/lb.js b/library/fullcalendar/packages/core/locales/lb.js
new file mode 100644
index 000000000..b9b17e3ec
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/lb.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lb = factory()));
+}(this, function () { 'use strict';
+
+ var lb = {
+ code: "lb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Zréck",
+ next: "Weider",
+ today: "Haut",
+ month: "Mount",
+ week: "Woch",
+ day: "Dag",
+ list: "Terminiwwersiicht"
+ },
+ weekLabel: "W",
+ allDayText: "Ganzen Dag",
+ eventLimitText: "méi",
+ noEventsMessage: "Nee Evenementer ze affichéieren"
+ };
+
+ return lb;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/lt.js b/library/fullcalendar/packages/core/locales/lt.js
new file mode 100644
index 000000000..ec641b750
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/lt.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lt = factory()));
+}(this, function () { 'use strict';
+
+ var lt = {
+ code: "lt",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Atgal",
+ next: "Pirmyn",
+ today: "Šiandien",
+ month: "Mėnuo",
+ week: "Savaitė",
+ day: "Diena",
+ list: "Darbotvarkė"
+ },
+ weekLabel: "SAV",
+ allDayText: "Visą dieną",
+ eventLimitText: "daugiau",
+ noEventsMessage: "Nėra įvykių rodyti"
+ };
+
+ return lt;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/lv.js b/library/fullcalendar/packages/core/locales/lv.js
new file mode 100644
index 000000000..5453630df
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/lv.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lv = factory()));
+}(this, function () { 'use strict';
+
+ var lv = {
+ code: "lv",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Iepr.",
+ next: "Nāk.",
+ today: "Šodien",
+ month: "Mēnesis",
+ week: "Nedēļa",
+ day: "Diena",
+ list: "Dienas kārtība"
+ },
+ weekLabel: "Ned.",
+ allDayText: "Visu dienu",
+ eventLimitText: function (n) {
+ return "+vēl " + n;
+ },
+ noEventsMessage: "Nav notikumu"
+ };
+
+ return lv;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/mk.js b/library/fullcalendar/packages/core/locales/mk.js
new file mode 100644
index 000000000..6729fa63d
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/mk.js
@@ -0,0 +1,28 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.mk = factory()));
+}(this, function () { 'use strict';
+
+ var mk = {
+ code: "mk",
+ buttonText: {
+ prev: "претходно",
+ next: "следно",
+ today: "Денес",
+ month: "Месец",
+ week: "Недела",
+ day: "Ден",
+ list: "График"
+ },
+ weekLabel: "Сед",
+ allDayText: "Цел ден",
+ eventLimitText: function (n) {
+ return "+повеќе " + n;
+ },
+ noEventsMessage: "Нема настани за прикажување"
+ };
+
+ return mk;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ms.js b/library/fullcalendar/packages/core/locales/ms.js
new file mode 100644
index 000000000..7205ecc72
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ms.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ms = factory()));
+}(this, function () { 'use strict';
+
+ var ms = {
+ code: "ms",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Sebelum",
+ next: "Selepas",
+ today: "hari ini",
+ month: "Bulan",
+ week: "Minggu",
+ day: "Hari",
+ list: "Agenda"
+ },
+ weekLabel: "Mg",
+ allDayText: "Sepanjang hari",
+ eventLimitText: function (n) {
+ return "masih ada " + n + " acara";
+ },
+ noEventsMessage: "Tiada peristiwa untuk dipaparkan"
+ };
+
+ return ms;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/nb.js b/library/fullcalendar/packages/core/locales/nb.js
new file mode 100644
index 000000000..6464461c6
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/nb.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nb = factory()));
+}(this, function () { 'use strict';
+
+ var nb = {
+ code: "nb",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Forrige",
+ next: "Neste",
+ today: "I dag",
+ month: "Måned",
+ week: "Uke",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Uke",
+ allDayText: "Hele dagen",
+ eventLimitText: "til",
+ noEventsMessage: "Ingen hendelser å vise"
+ };
+
+ return nb;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/nl.js b/library/fullcalendar/packages/core/locales/nl.js
new file mode 100644
index 000000000..c91b5e55f
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/nl.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nl = factory()));
+}(this, function () { 'use strict';
+
+ var nl = {
+ code: "nl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Voorgaand",
+ next: "Volgende",
+ today: "Vandaag",
+ year: "Jaar",
+ month: "Maand",
+ week: "Week",
+ day: "Dag",
+ list: "Agenda"
+ },
+ allDayText: "Hele dag",
+ eventLimitText: "extra",
+ noEventsMessage: "Geen evenementen om te laten zien"
+ };
+
+ return nl;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/nn.js b/library/fullcalendar/packages/core/locales/nn.js
new file mode 100644
index 000000000..a5cdd1626
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/nn.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nn = factory()));
+}(this, function () { 'use strict';
+
+ var nn = {
+ code: "nn",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Førre",
+ next: "Neste",
+ today: "I dag",
+ month: "Månad",
+ week: "Veke",
+ day: "Dag",
+ list: "Agenda"
+ },
+ weekLabel: "Veke",
+ allDayText: "Heile dagen",
+ eventLimitText: "til",
+ noEventsMessage: "Ingen hendelser å vise"
+ };
+
+ return nn;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/pl.js b/library/fullcalendar/packages/core/locales/pl.js
new file mode 100644
index 000000000..0a22e69c4
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/pl.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.pl = factory()));
+}(this, function () { 'use strict';
+
+ var pl = {
+ code: "pl",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Poprzedni",
+ next: "Następny",
+ today: "Dziś",
+ month: "Miesiąc",
+ week: "Tydzień",
+ day: "Dzień",
+ list: "Plan dnia"
+ },
+ weekLabel: "Tydz",
+ allDayText: "Cały dzień",
+ eventLimitText: "więcej",
+ noEventsMessage: "Brak wydarzeń do wyświetlenia"
+ };
+
+ return pl;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/pt-br.js b/library/fullcalendar/packages/core/locales/pt-br.js
new file mode 100644
index 000000000..0133cd6b1
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/pt-br.js
@@ -0,0 +1,28 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['pt-br'] = factory()));
+}(this, function () { 'use strict';
+
+ var ptBr = {
+ code: "pt-br",
+ buttonText: {
+ prev: "Anterior",
+ next: "Próximo",
+ today: "Hoje",
+ month: "Mês",
+ week: "Semana",
+ day: "Dia",
+ list: "Compromissos"
+ },
+ weekLabel: "Sm",
+ allDayText: "dia inteiro",
+ eventLimitText: function (n) {
+ return "mais +" + n;
+ },
+ noEventsMessage: "Não há eventos para mostrar"
+ };
+
+ return ptBr;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/pt.js b/library/fullcalendar/packages/core/locales/pt.js
new file mode 100644
index 000000000..5c54d8d40
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/pt.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.pt = factory()));
+}(this, function () { 'use strict';
+
+ var pt = {
+ code: "pt",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Anterior",
+ next: "Seguinte",
+ today: "Hoje",
+ month: "Mês",
+ week: "Semana",
+ day: "Dia",
+ list: "Agenda"
+ },
+ weekLabel: "Sem",
+ allDayText: "Todo o dia",
+ eventLimitText: "mais",
+ noEventsMessage: "Não há eventos para mostrar"
+ };
+
+ return pt;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ro.js b/library/fullcalendar/packages/core/locales/ro.js
new file mode 100644
index 000000000..e8992f276
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ro.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ro = factory()));
+}(this, function () { 'use strict';
+
+ var ro = {
+ code: "ro",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "precedentă",
+ next: "următoare",
+ today: "Azi",
+ month: "Lună",
+ week: "Săptămână",
+ day: "Zi",
+ list: "Agendă"
+ },
+ weekLabel: "Săpt",
+ allDayText: "Toată ziua",
+ eventLimitText: function (n) {
+ return "+alte " + n;
+ },
+ noEventsMessage: "Nu există evenimente de afișat"
+ };
+
+ return ro;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/ru.js b/library/fullcalendar/packages/core/locales/ru.js
new file mode 100644
index 000000000..77e0308e2
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/ru.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ru = factory()));
+}(this, function () { 'use strict';
+
+ var ru = {
+ code: "ru",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Пред",
+ next: "След",
+ today: "Сегодня",
+ month: "Месяц",
+ week: "Неделя",
+ day: "День",
+ list: "Повестка дня"
+ },
+ weekLabel: "Нед",
+ allDayText: "Весь день",
+ eventLimitText: function (n) {
+ return "+ ещё " + n;
+ },
+ noEventsMessage: "Нет событий для отображения"
+ };
+
+ return ru;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sk.js b/library/fullcalendar/packages/core/locales/sk.js
new file mode 100644
index 000000000..3513a64ad
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sk.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sk = factory()));
+}(this, function () { 'use strict';
+
+ var sk = {
+ code: "sk",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Predchádzajúci",
+ next: "Nasledujúci",
+ today: "Dnes",
+ month: "Mesiac",
+ week: "Týždeň",
+ day: "Deň",
+ list: "Rozvrh"
+ },
+ weekLabel: "Ty",
+ allDayText: "Celý deň",
+ eventLimitText: function (n) {
+ return "+ďalšie: " + n;
+ },
+ noEventsMessage: "Žiadne akcie na zobrazenie"
+ };
+
+ return sk;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sl.js b/library/fullcalendar/packages/core/locales/sl.js
new file mode 100644
index 000000000..323355359
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sl.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sl = factory()));
+}(this, function () { 'use strict';
+
+ var sl = {
+ code: "sl",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prejšnji",
+ next: "Naslednji",
+ today: "Trenutni",
+ month: "Mesec",
+ week: "Teden",
+ day: "Dan",
+ list: "Dnevni red"
+ },
+ weekLabel: "Teden",
+ allDayText: "Ves dan",
+ eventLimitText: "več",
+ noEventsMessage: "Ni dogodkov za prikaz"
+ };
+
+ return sl;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sq.js b/library/fullcalendar/packages/core/locales/sq.js
new file mode 100644
index 000000000..0d43a5220
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sq.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sq = factory()));
+}(this, function () { 'use strict';
+
+ var sq = {
+ code: "sq",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "mbrapa",
+ next: "Përpara",
+ today: "sot",
+ month: "Muaj",
+ week: "Javë",
+ day: "Ditë",
+ list: "Listë"
+ },
+ weekLabel: "Ja",
+ allDayHtml: "Gjithë<br/>ditën",
+ eventLimitText: function (n) {
+ return "+më tepër " + n;
+ },
+ noEventsMessage: "Nuk ka evente për të shfaqur"
+ };
+
+ return sq;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sr-cyrl.js b/library/fullcalendar/packages/core/locales/sr-cyrl.js
new file mode 100644
index 000000000..ba0d0dfa3
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sr-cyrl.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['sr-cyrl'] = factory()));
+}(this, function () { 'use strict';
+
+ var srCyrl = {
+ code: "sr-cyrl",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Претходна",
+ next: "следећи",
+ today: "Данас",
+ month: "Месец",
+ week: "Недеља",
+ day: "Дан",
+ list: "Планер"
+ },
+ weekLabel: "Сед",
+ allDayText: "Цео дан",
+ eventLimitText: function (n) {
+ return "+ још " + n;
+ },
+ noEventsMessage: "Нема догађаја за приказ"
+ };
+
+ return srCyrl;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sr.js b/library/fullcalendar/packages/core/locales/sr.js
new file mode 100644
index 000000000..23e5c9b23
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sr.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sr = factory()));
+}(this, function () { 'use strict';
+
+ var sr = {
+ code: "sr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Prethodna",
+ next: "Sledeći",
+ today: "Danas",
+ month: "Mеsеc",
+ week: "Nеdеlja",
+ day: "Dan",
+ list: "Planеr"
+ },
+ weekLabel: "Sed",
+ allDayText: "Cеo dan",
+ eventLimitText: function (n) {
+ return "+ još " + n;
+ },
+ noEventsMessage: "Nеma događaja za prikaz"
+ };
+
+ return sr;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/sv.js b/library/fullcalendar/packages/core/locales/sv.js
new file mode 100644
index 000000000..a887060ba
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/sv.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sv = factory()));
+}(this, function () { 'use strict';
+
+ var sv = {
+ code: "sv",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Förra",
+ next: "Nästa",
+ today: "Idag",
+ month: "Månad",
+ week: "Vecka",
+ day: "Dag",
+ list: "Program"
+ },
+ weekLabel: "v.",
+ allDayText: "Heldag",
+ eventLimitText: "till",
+ noEventsMessage: "Inga händelser att visa"
+ };
+
+ return sv;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/th.js b/library/fullcalendar/packages/core/locales/th.js
new file mode 100644
index 000000000..caa3fe9a6
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/th.js
@@ -0,0 +1,25 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.th = factory()));
+}(this, function () { 'use strict';
+
+ var th = {
+ code: "th",
+ buttonText: {
+ prev: "ย้อน",
+ next: "ถัดไป",
+ today: "วันนี้",
+ month: "เดือน",
+ week: "สัปดาห์",
+ day: "วัน",
+ list: "แผนงาน"
+ },
+ allDayText: "ตลอดวัน",
+ eventLimitText: "เพิ่มเติม",
+ noEventsMessage: "ไม่มีกิจกรรมที่จะแสดง"
+ };
+
+ return th;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/tr.js b/library/fullcalendar/packages/core/locales/tr.js
new file mode 100644
index 000000000..48458982f
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/tr.js
@@ -0,0 +1,30 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.tr = factory()));
+}(this, function () { 'use strict';
+
+ var tr = {
+ code: "tr",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "geri",
+ next: "ileri",
+ today: "bugün",
+ month: "Ay",
+ week: "Hafta",
+ day: "Gün",
+ list: "Ajanda"
+ },
+ weekLabel: "Hf",
+ allDayText: "Tüm gün",
+ eventLimitText: "daha fazla",
+ noEventsMessage: "Gösterilecek etkinlik yok"
+ };
+
+ return tr;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/uk.js b/library/fullcalendar/packages/core/locales/uk.js
new file mode 100644
index 000000000..de33f250c
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/uk.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.uk = factory()));
+}(this, function () { 'use strict';
+
+ var uk = {
+ code: "uk",
+ week: {
+ dow: 1,
+ doy: 7 // The week that contains Jan 1st is the first week of the year.
+ },
+ buttonText: {
+ prev: "Попередній",
+ next: "далі",
+ today: "Сьогодні",
+ month: "Місяць",
+ week: "Тиждень",
+ day: "День",
+ list: "Порядок денний"
+ },
+ weekLabel: "Тиж",
+ allDayText: "Увесь день",
+ eventLimitText: function (n) {
+ return "+ще " + n + "...";
+ },
+ noEventsMessage: "Немає подій для відображення"
+ };
+
+ return uk;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/vi.js b/library/fullcalendar/packages/core/locales/vi.js
new file mode 100644
index 000000000..167ce11d7
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/vi.js
@@ -0,0 +1,32 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.vi = factory()));
+}(this, function () { 'use strict';
+
+ var vi = {
+ code: "vi",
+ week: {
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "Trước",
+ next: "Tiếp",
+ today: "Hôm nay",
+ month: "Tháng",
+ week: "Tuần",
+ day: "Ngày",
+ list: "Lịch biểu"
+ },
+ weekLabel: "Tu",
+ allDayText: "Cả ngày",
+ eventLimitText: function (n) {
+ return "+ thêm " + n;
+ },
+ noEventsMessage: "Không có sự kiện để hiển thị"
+ };
+
+ return vi;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/zh-cn.js b/library/fullcalendar/packages/core/locales/zh-cn.js
new file mode 100644
index 000000000..4debbb9e6
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/zh-cn.js
@@ -0,0 +1,33 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['zh-cn'] = factory()));
+}(this, function () { 'use strict';
+
+ var zhCn = {
+ code: "zh-cn",
+ week: {
+ // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
+ dow: 1,
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ },
+ buttonText: {
+ prev: "上月",
+ next: "下月",
+ today: "今天",
+ month: "月",
+ week: "周",
+ day: "日",
+ list: "日程"
+ },
+ weekLabel: "周",
+ allDayText: "全天",
+ eventLimitText: function (n) {
+ return "另外 " + n + " 个";
+ },
+ noEventsMessage: "没有事件显示"
+ };
+
+ return zhCn;
+
+}));
diff --git a/library/fullcalendar/packages/core/locales/zh-tw.js b/library/fullcalendar/packages/core/locales/zh-tw.js
new file mode 100644
index 000000000..bc14dcd4b
--- /dev/null
+++ b/library/fullcalendar/packages/core/locales/zh-tw.js
@@ -0,0 +1,26 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['zh-tw'] = factory()));
+}(this, function () { 'use strict';
+
+ var zhTw = {
+ code: "zh-tw",
+ buttonText: {
+ prev: "上月",
+ next: "下月",
+ today: "今天",
+ month: "月",
+ week: "週",
+ day: "天",
+ list: "活動列表"
+ },
+ weekLabel: "周",
+ allDayText: "整天",
+ eventLimitText: '顯示更多',
+ noEventsMessage: "没有任何活動"
+ };
+
+ return zhTw;
+
+}));
diff --git a/library/fullcalendar/packages/core/main.css b/library/fullcalendar/packages/core/main.css
new file mode 100644
index 000000000..6dc6966ed
--- /dev/null
+++ b/library/fullcalendar/packages/core/main.css
@@ -0,0 +1,900 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+.fc {
+ direction: ltr;
+ text-align: left; }
+
+.fc-rtl {
+ text-align: right; }
+
+body .fc {
+ /* extra precedence to overcome jqui */
+ font-size: 1em; }
+
+/* Colors
+--------------------------------------------------------------------------------------------------*/
+.fc-highlight {
+ /* when user is selecting cells */
+ background: #bce8f1;
+ opacity: .3; }
+
+.fc-bgevent {
+ /* default look for background events */
+ background: #8fdf82;
+ opacity: .3; }
+
+.fc-nonbusiness {
+ /* default look for non-business-hours areas */
+ /* will inherit .fc-bgevent's styles */
+ background: #d7d7d7; }
+
+/* Popover
+--------------------------------------------------------------------------------------------------*/
+.fc-popover {
+ position: absolute;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); }
+
+.fc-popover .fc-header {
+ /* TODO: be more consistent with fc-head/fc-body */
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ padding: 2px 4px; }
+
+.fc-rtl .fc-popover .fc-header {
+ flex-direction: row-reverse; }
+
+.fc-popover .fc-header .fc-title {
+ margin: 0 2px; }
+
+.fc-popover .fc-header .fc-close {
+ cursor: pointer;
+ opacity: 0.65;
+ font-size: 1.1em; }
+
+/* Misc Reusable Components
+--------------------------------------------------------------------------------------------------*/
+.fc-divider {
+ border-style: solid;
+ border-width: 1px; }
+
+hr.fc-divider {
+ height: 0;
+ margin: 0;
+ padding: 0 0 2px;
+ /* height is unreliable across browsers, so use padding */
+ border-width: 1px 0; }
+
+.fc-bg,
+.fc-bgevent-skeleton,
+.fc-highlight-skeleton,
+.fc-mirror-skeleton {
+ /* these element should always cling to top-left/right corners */
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0; }
+
+.fc-bg {
+ bottom: 0;
+ /* strech bg to bottom edge */ }
+
+.fc-bg table {
+ height: 100%;
+ /* strech bg to bottom edge */ }
+
+/* Tables
+--------------------------------------------------------------------------------------------------*/
+.fc table {
+ width: 100%;
+ box-sizing: border-box;
+ /* fix scrollbar issue in firefox */
+ table-layout: fixed;
+ border-collapse: collapse;
+ border-spacing: 0;
+ font-size: 1em;
+ /* normalize cross-browser */ }
+
+.fc th {
+ text-align: center; }
+
+.fc th,
+.fc td {
+ border-style: solid;
+ border-width: 1px;
+ padding: 0;
+ vertical-align: top; }
+
+.fc td.fc-today {
+ border-style: double;
+ /* overcome neighboring borders */ }
+
+/* Internal Nav Links
+--------------------------------------------------------------------------------------------------*/
+a[data-goto] {
+ cursor: pointer; }
+
+a[data-goto]:hover {
+ text-decoration: underline; }
+
+/* Fake Table Rows
+--------------------------------------------------------------------------------------------------*/
+.fc .fc-row {
+ /* extra precedence to overcome themes forcing a 1px border */
+ /* no visible border by default. but make available if need be (scrollbar width compensation) */
+ border-style: solid;
+ border-width: 0; }
+
+.fc-row table {
+ /* don't put left/right border on anything within a fake row.
+ the outer tbody will worry about this */
+ border-left: 0 hidden transparent;
+ border-right: 0 hidden transparent;
+ /* no bottom borders on rows */
+ border-bottom: 0 hidden transparent; }
+
+.fc-row:first-child table {
+ border-top: 0 hidden transparent;
+ /* no top border on first row */ }
+
+/* Day Row (used within the header and the DayGrid)
+--------------------------------------------------------------------------------------------------*/
+.fc-row {
+ position: relative; }
+
+.fc-row .fc-bg {
+ z-index: 1; }
+
+/* highlighting cells & background event skeleton */
+.fc-row .fc-bgevent-skeleton,
+.fc-row .fc-highlight-skeleton {
+ bottom: 0;
+ /* stretch skeleton to bottom of row */ }
+
+.fc-row .fc-bgevent-skeleton table,
+.fc-row .fc-highlight-skeleton table {
+ height: 100%;
+ /* stretch skeleton to bottom of row */ }
+
+.fc-row .fc-highlight-skeleton td,
+.fc-row .fc-bgevent-skeleton td {
+ border-color: transparent; }
+
+.fc-row .fc-bgevent-skeleton {
+ z-index: 2; }
+
+.fc-row .fc-highlight-skeleton {
+ z-index: 3; }
+
+/*
+row content (which contains day/week numbers and events) as well as "mirror" (which contains
+temporary rendered events).
+*/
+.fc-row .fc-content-skeleton {
+ position: relative;
+ z-index: 4;
+ padding-bottom: 2px;
+ /* matches the space above the events */ }
+
+.fc-row .fc-mirror-skeleton {
+ z-index: 5; }
+
+.fc .fc-row .fc-content-skeleton table,
+.fc .fc-row .fc-content-skeleton td,
+.fc .fc-row .fc-mirror-skeleton td {
+ /* see-through to the background below */
+ /* extra precedence to prevent theme-provided backgrounds */
+ background: none;
+ /* in case <td>s are globally styled */
+ border-color: transparent; }
+
+.fc-row .fc-content-skeleton td,
+.fc-row .fc-mirror-skeleton td {
+ /* don't put a border between events and/or the day number */
+ border-bottom: 0; }
+
+.fc-row .fc-content-skeleton tbody td,
+.fc-row .fc-mirror-skeleton tbody td {
+ /* don't put a border between event cells */
+ border-top: 0; }
+
+/* Scrolling Container
+--------------------------------------------------------------------------------------------------*/
+.fc-scroller {
+ -webkit-overflow-scrolling: touch; }
+
+/* TODO: move to timegrid/daygrid */
+.fc-scroller > .fc-day-grid,
+.fc-scroller > .fc-time-grid {
+ position: relative;
+ /* re-scope all positions */
+ width: 100%;
+ /* hack to force re-sizing this inner element when scrollbars appear/disappear */ }
+
+/* Global Event Styles
+--------------------------------------------------------------------------------------------------*/
+.fc-event {
+ position: relative;
+ /* for resize handle and other inner positioning */
+ display: block;
+ /* make the <a> tag block */
+ font-size: .85em;
+ line-height: 1.4;
+ border-radius: 3px;
+ border: 1px solid #3788d8; }
+
+.fc-event,
+.fc-event-dot {
+ background-color: #3788d8;
+ /* default BACKGROUND color */ }
+
+.fc-event,
+.fc-event:hover {
+ color: #fff;
+ /* default TEXT color */
+ text-decoration: none;
+ /* if <a> has an href */ }
+
+.fc-event[href],
+.fc-event.fc-draggable {
+ cursor: pointer;
+ /* give events with links and draggable events a hand mouse pointer */ }
+
+.fc-not-allowed,
+.fc-not-allowed .fc-event {
+ /* to override an event's custom cursor */
+ cursor: not-allowed; }
+
+.fc-event .fc-content {
+ position: relative;
+ z-index: 2; }
+
+/* resizer (cursor AND touch devices) */
+.fc-event .fc-resizer {
+ position: absolute;
+ z-index: 4; }
+
+/* resizer (touch devices) */
+.fc-event .fc-resizer {
+ display: none; }
+
+.fc-event.fc-allow-mouse-resize .fc-resizer,
+.fc-event.fc-selected .fc-resizer {
+ /* only show when hovering or selected (with touch) */
+ display: block; }
+
+/* hit area */
+.fc-event.fc-selected .fc-resizer:before {
+ /* 40x40 touch area */
+ content: "";
+ position: absolute;
+ z-index: 9999;
+ /* user of this util can scope within a lower z-index */
+ top: 50%;
+ left: 50%;
+ width: 40px;
+ height: 40px;
+ margin-left: -20px;
+ margin-top: -20px; }
+
+/* Event Selection (only for touch devices)
+--------------------------------------------------------------------------------------------------*/
+.fc-event.fc-selected {
+ z-index: 9999 !important;
+ /* overcomes inline z-index */
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); }
+
+.fc-event.fc-selected:after {
+ content: "";
+ position: absolute;
+ z-index: 1;
+ /* same z-index as fc-bg, behind text */
+ /* overcome the borders */
+ top: -1px;
+ right: -1px;
+ bottom: -1px;
+ left: -1px;
+ /* darkening effect */
+ background: #000;
+ opacity: .25; }
+
+/* Event Dragging
+--------------------------------------------------------------------------------------------------*/
+.fc-event.fc-dragging.fc-selected {
+ box-shadow: 0 2px 7px rgba(0, 0, 0, 0.3); }
+
+.fc-event.fc-dragging:not(.fc-selected) {
+ opacity: .75; }
+
+/* Horizontal Events
+--------------------------------------------------------------------------------------------------*/
+/* bigger touch area when selected */
+.fc-h-event.fc-selected:before {
+ content: "";
+ position: absolute;
+ z-index: 3;
+ /* below resizers */
+ top: -10px;
+ bottom: -10px;
+ left: 0;
+ right: 0; }
+
+/* events that are continuing to/from another week. kill rounded corners and butt up against edge */
+.fc-ltr .fc-h-event.fc-not-start,
+.fc-rtl .fc-h-event.fc-not-end {
+ margin-left: 0;
+ border-left-width: 0;
+ padding-left: 1px;
+ /* replace the border with padding */
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0; }
+
+.fc-ltr .fc-h-event.fc-not-end,
+.fc-rtl .fc-h-event.fc-not-start {
+ margin-right: 0;
+ border-right-width: 0;
+ padding-right: 1px;
+ /* replace the border with padding */
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0; }
+
+/* resizer (cursor AND touch devices) */
+/* left resizer */
+.fc-ltr .fc-h-event .fc-start-resizer,
+.fc-rtl .fc-h-event .fc-end-resizer {
+ cursor: w-resize;
+ left: -1px;
+ /* overcome border */ }
+
+/* right resizer */
+.fc-ltr .fc-h-event .fc-end-resizer,
+.fc-rtl .fc-h-event .fc-start-resizer {
+ cursor: e-resize;
+ right: -1px;
+ /* overcome border */ }
+
+/* resizer (mouse devices) */
+.fc-h-event.fc-allow-mouse-resize .fc-resizer {
+ width: 7px;
+ top: -1px;
+ /* overcome top border */
+ bottom: -1px;
+ /* overcome bottom border */ }
+
+/* resizer (touch devices) */
+.fc-h-event.fc-selected .fc-resizer {
+ /* 8x8 little dot */
+ border-radius: 4px;
+ border-width: 1px;
+ width: 6px;
+ height: 6px;
+ border-style: solid;
+ border-color: inherit;
+ background: #fff;
+ /* vertically center */
+ top: 50%;
+ margin-top: -4px; }
+
+/* left resizer */
+.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,
+.fc-rtl .fc-h-event.fc-selected .fc-end-resizer {
+ margin-left: -4px;
+ /* centers the 8x8 dot on the left edge */ }
+
+/* right resizer */
+.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,
+.fc-rtl .fc-h-event.fc-selected .fc-start-resizer {
+ margin-right: -4px;
+ /* centers the 8x8 dot on the right edge */ }
+
+/* DayGrid events
+----------------------------------------------------------------------------------------------------
+We use the full "fc-day-grid-event" class instead of using descendants because the event won't
+be a descendant of the grid when it is being dragged.
+*/
+.fc-day-grid-event {
+ margin: 1px 2px 0;
+ /* spacing between events and edges */
+ padding: 0 1px; }
+
+tr:first-child > td > .fc-day-grid-event {
+ margin-top: 2px;
+ /* a little bit more space before the first event */ }
+
+.fc-mirror-skeleton tr:first-child > td > .fc-day-grid-event {
+ margin-top: 0;
+ /* except for mirror skeleton */ }
+
+.fc-day-grid-event .fc-content {
+ /* force events to be one-line tall */
+ white-space: nowrap;
+ overflow: hidden; }
+
+.fc-day-grid-event .fc-time {
+ font-weight: bold; }
+
+/* resizer (cursor devices) */
+/* left resizer */
+.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,
+.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer {
+ margin-left: -2px;
+ /* to the day cell's edge */ }
+
+/* right resizer */
+.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,
+.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer {
+ margin-right: -2px;
+ /* to the day cell's edge */ }
+
+/* Event Limiting
+--------------------------------------------------------------------------------------------------*/
+/* "more" link that represents hidden events */
+a.fc-more {
+ margin: 1px 3px;
+ font-size: .85em;
+ cursor: pointer;
+ text-decoration: none; }
+
+a.fc-more:hover {
+ text-decoration: underline; }
+
+.fc-limited {
+ /* rows and cells that are hidden because of a "more" link */
+ display: none; }
+
+/* popover that appears when "more" link is clicked */
+.fc-day-grid .fc-row {
+ z-index: 1;
+ /* make the "more" popover one higher than this */ }
+
+.fc-more-popover {
+ z-index: 2;
+ width: 220px; }
+
+.fc-more-popover .fc-event-container {
+ padding: 10px; }
+
+/* Now Indicator
+--------------------------------------------------------------------------------------------------*/
+.fc-now-indicator {
+ position: absolute;
+ border: 0 solid red; }
+
+/* Utilities
+--------------------------------------------------------------------------------------------------*/
+.fc-unselectable {
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-touch-callout: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
+
+/*
+TODO: more distinction between this file and common.css
+*/
+/* Colors
+--------------------------------------------------------------------------------------------------*/
+.fc-unthemed th,
+.fc-unthemed td,
+.fc-unthemed thead,
+.fc-unthemed tbody,
+.fc-unthemed .fc-divider,
+.fc-unthemed .fc-row,
+.fc-unthemed .fc-content,
+.fc-unthemed .fc-popover,
+.fc-unthemed .fc-list-view,
+.fc-unthemed .fc-list-heading td {
+ border-color: #ddd; }
+
+.fc-unthemed .fc-popover {
+ background-color: #fff; }
+
+.fc-unthemed .fc-divider,
+.fc-unthemed .fc-popover .fc-header,
+.fc-unthemed .fc-list-heading td {
+ background: #eee; }
+
+.fc-unthemed td.fc-today {
+ background: #fcf8e3; }
+
+.fc-unthemed .fc-disabled-day {
+ background: #d7d7d7;
+ opacity: .3; }
+
+/* Icons
+--------------------------------------------------------------------------------------------------
+from https://feathericons.com/ and built with IcoMoon
+*/
+@font-face {
+ font-family: 'fcicons';
+ src: url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype");
+ font-weight: normal;
+ font-style: normal; }
+.fc-icon {
+ /* use !important to prevent issues with browser extensions that change fonts */
+ font-family: 'fcicons' !important;
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale; }
+
+.fc-icon-chevron-left:before {
+ content: "\e900"; }
+
+.fc-icon-chevron-right:before {
+ content: "\e901"; }
+
+.fc-icon-chevrons-left:before {
+ content: "\e902"; }
+
+.fc-icon-chevrons-right:before {
+ content: "\e903"; }
+
+.fc-icon-minus-square:before {
+ content: "\e904"; }
+
+.fc-icon-plus-square:before {
+ content: "\e905"; }
+
+.fc-icon-x:before {
+ content: "\e906"; }
+
+.fc-icon {
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ text-align: center; }
+
+/* Buttons
+--------------------------------------------------------------------------------------------------
+Lots taken from Flatly (MIT): https://bootswatch.com/4/flatly/bootstrap.css
+*/
+/* reset */
+.fc-button {
+ border-radius: 0;
+ overflow: visible;
+ text-transform: none;
+ margin: 0;
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit; }
+
+.fc-button:focus {
+ outline: 1px dotted;
+ outline: 5px auto -webkit-focus-ring-color; }
+
+.fc-button {
+ -webkit-appearance: button; }
+
+.fc-button:not(:disabled) {
+ cursor: pointer; }
+
+.fc-button::-moz-focus-inner {
+ padding: 0;
+ border-style: none; }
+
+/* theme */
+.fc-button {
+ display: inline-block;
+ font-weight: 400;
+ color: #212529;
+ text-align: center;
+ vertical-align: middle;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-color: transparent;
+ border: 1px solid transparent;
+ padding: 0.4em 0.65em;
+ font-size: 1em;
+ line-height: 1.5;
+ border-radius: 0.25em; }
+
+.fc-button:hover {
+ color: #212529;
+ text-decoration: none; }
+
+.fc-button:focus {
+ outline: 0;
+ -webkit-box-shadow: 0 0 0 0.2rem rgba(44, 62, 80, 0.25);
+ box-shadow: 0 0 0 0.2rem rgba(44, 62, 80, 0.25); }
+
+.fc-button:disabled {
+ opacity: 0.65; }
+
+/* "primary" coloring */
+.fc-button-primary {
+ color: #fff;
+ background-color: #2C3E50;
+ border-color: #2C3E50; }
+
+.fc-button-primary:hover {
+ color: #fff;
+ background-color: #1e2b37;
+ border-color: #1a252f; }
+
+.fc-button-primary:focus {
+ -webkit-box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5);
+ box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5); }
+
+.fc-button-primary:disabled {
+ color: #fff;
+ background-color: #2C3E50;
+ border-color: #2C3E50; }
+
+.fc-button-primary:not(:disabled):active,
+.fc-button-primary:not(:disabled).fc-button-active {
+ color: #fff;
+ background-color: #1a252f;
+ border-color: #151e27; }
+
+.fc-button-primary:not(:disabled):active:focus,
+.fc-button-primary:not(:disabled).fc-button-active:focus {
+ -webkit-box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5);
+ box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5); }
+
+/* icons within buttons */
+.fc-button .fc-icon {
+ vertical-align: middle;
+ font-size: 1.5em; }
+
+/* Buttons Groups
+--------------------------------------------------------------------------------------------------*/
+.fc-button-group {
+ position: relative;
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+ vertical-align: middle; }
+
+.fc-button-group > .fc-button {
+ position: relative;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto; }
+
+.fc-button-group > .fc-button:hover {
+ z-index: 1; }
+
+.fc-button-group > .fc-button:focus,
+.fc-button-group > .fc-button:active,
+.fc-button-group > .fc-button.fc-button-active {
+ z-index: 1; }
+
+.fc-button-group > .fc-button:not(:first-child) {
+ margin-left: -1px; }
+
+.fc-button-group > .fc-button:not(:last-child) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.fc-button-group > .fc-button:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0; }
+
+/* Popover
+--------------------------------------------------------------------------------------------------*/
+.fc-unthemed .fc-popover {
+ border-width: 1px;
+ border-style: solid; }
+
+/* List View
+--------------------------------------------------------------------------------------------------*/
+.fc-unthemed .fc-list-item:hover td {
+ background-color: #f5f5f5; }
+
+/* Toolbar
+--------------------------------------------------------------------------------------------------*/
+.fc-toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center; }
+
+.fc-toolbar.fc-header-toolbar {
+ margin-bottom: 1.5em; }
+
+.fc-toolbar.fc-footer-toolbar {
+ margin-top: 1.5em; }
+
+/* inner content */
+.fc-toolbar > * > :not(:first-child) {
+ margin-left: .75em; }
+
+.fc-toolbar h2 {
+ font-size: 1.75em;
+ margin: 0; }
+
+/* View Structure
+--------------------------------------------------------------------------------------------------*/
+.fc-view-container {
+ position: relative; }
+
+/* undo twitter bootstrap's box-sizing rules. normalizes positioning techniques */
+/* don't do this for the toolbar because we'll want bootstrap to style those buttons as some pt */
+.fc-view-container *,
+.fc-view-container *:before,
+.fc-view-container *:after {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box; }
+
+.fc-view,
+.fc-view > table {
+ /* so dragged elements can be above the view's main element */
+ position: relative;
+ z-index: 1; }
+
+@media print {
+ .fc {
+ max-width: 100% !important; }
+
+ /* Global Event Restyling
+ --------------------------------------------------------------------------------------------------*/
+ .fc-event {
+ background: #fff !important;
+ color: #000 !important;
+ page-break-inside: avoid; }
+
+ .fc-event .fc-resizer {
+ display: none; }
+
+ /* Table & Day-Row Restyling
+ --------------------------------------------------------------------------------------------------*/
+ .fc th,
+ .fc td,
+ .fc hr,
+ .fc thead,
+ .fc tbody,
+ .fc-row {
+ border-color: #ccc !important;
+ background: #fff !important; }
+
+ /* kill the overlaid, absolutely-positioned components */
+ /* common... */
+ .fc-bg,
+ .fc-bgevent-skeleton,
+ .fc-highlight-skeleton,
+ .fc-mirror-skeleton,
+ .fc-bgevent-container,
+ .fc-business-container,
+ .fc-highlight-container,
+ .fc-mirror-container {
+ display: none; }
+
+ /* don't force a min-height on rows (for DayGrid) */
+ .fc tbody .fc-row {
+ height: auto !important;
+ /* undo height that JS set in distributeHeight */
+ min-height: 0 !important;
+ /* undo the min-height from each view's specific stylesheet */ }
+
+ .fc tbody .fc-row .fc-content-skeleton {
+ position: static;
+ /* undo .fc-rigid */
+ padding-bottom: 0 !important;
+ /* use a more border-friendly method for this... */ }
+
+ .fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td {
+ /* only works in newer browsers */
+ padding-bottom: 1em;
+ /* ...gives space within the skeleton. also ensures min height in a way */ }
+
+ .fc tbody .fc-row .fc-content-skeleton table {
+ /* provides a min-height for the row, but only effective for IE, which exaggerates this value,
+ making it look more like 3em. for other browers, it will already be this tall */
+ height: 1em; }
+
+ /* Undo month-view event limiting. Display all events and hide the "more" links
+ --------------------------------------------------------------------------------------------------*/
+ .fc-more-cell,
+ .fc-more {
+ display: none !important; }
+
+ .fc tr.fc-limited {
+ display: table-row !important; }
+
+ .fc td.fc-limited {
+ display: table-cell !important; }
+
+ .fc-popover {
+ display: none;
+ /* never display the "more.." popover in print mode */ }
+
+ /* TimeGrid Restyling
+ --------------------------------------------------------------------------------------------------*/
+ /* undo the min-height 100% trick used to fill the container's height */
+ .fc-time-grid {
+ min-height: 0 !important; }
+
+ /* don't display the side axis at all ("all-day" and time cells) */
+ .fc-timeGrid-view .fc-axis {
+ display: none; }
+
+ /* don't display the horizontal lines */
+ .fc-slats,
+ .fc-time-grid hr {
+ /* this hr is used when height is underused and needs to be filled */
+ display: none !important;
+ /* important overrides inline declaration */ }
+
+ /* let the container that holds the events be naturally positioned and create real height */
+ .fc-time-grid .fc-content-skeleton {
+ position: static; }
+
+ /* in case there are no events, we still want some height */
+ .fc-time-grid .fc-content-skeleton table {
+ height: 4em; }
+
+ /* kill the horizontal spacing made by the event container. event margins will be done below */
+ .fc-time-grid .fc-event-container {
+ margin: 0 !important; }
+
+ /* TimeGrid *Event* Restyling
+ --------------------------------------------------------------------------------------------------*/
+ /* naturally position events, vertically stacking them */
+ .fc-time-grid .fc-event {
+ position: static !important;
+ margin: 3px 2px !important; }
+
+ /* for events that continue to a future day, give the bottom border back */
+ .fc-time-grid .fc-event.fc-not-end {
+ border-bottom-width: 1px !important; }
+
+ /* indicate the event continues via "..." text */
+ .fc-time-grid .fc-event.fc-not-end:after {
+ content: "..."; }
+
+ /* for events that are continuations from previous days, give the top border back */
+ .fc-time-grid .fc-event.fc-not-start {
+ border-top-width: 1px !important; }
+
+ /* indicate the event is a continuation via "..." text */
+ .fc-time-grid .fc-event.fc-not-start:before {
+ content: "..."; }
+
+ /* time */
+ /* undo a previous declaration and let the time text span to a second line */
+ .fc-time-grid .fc-event .fc-time {
+ white-space: normal !important; }
+
+ /* hide the the time that is normally displayed... */
+ .fc-time-grid .fc-event .fc-time span {
+ display: none; }
+
+ /* ...replace it with a more verbose version (includes AM/PM) stored in an html attribute */
+ .fc-time-grid .fc-event .fc-time:after {
+ content: attr(data-full); }
+
+ /* Vertical Scroller & Containers
+ --------------------------------------------------------------------------------------------------*/
+ /* kill the scrollbars and allow natural height */
+ .fc-scroller,
+ .fc-day-grid-container,
+ .fc-time-grid-container {
+ /* */
+ overflow: visible !important;
+ height: auto !important; }
+
+ /* kill the horizontal border/padding used to compensate for scrollbars */
+ .fc-row {
+ border: 0 !important;
+ margin: 0 !important; }
+
+ /* Button Controls
+ --------------------------------------------------------------------------------------------------*/
+ .fc-button-group,
+ .fc button {
+ display: none;
+ /* don't display any button-related controls */ } }
diff --git a/library/fullcalendar/packages/core/main.js b/library/fullcalendar/packages/core/main.js
new file mode 100644
index 000000000..8225f1a9e
--- /dev/null
+++ b/library/fullcalendar/packages/core/main.js
@@ -0,0 +1,8791 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = global || self, factory(global.FullCalendar = {}));
+}(this, function (exports) { 'use strict';
+
+ // Creating
+ // ----------------------------------------------------------------------------------------------------------------
+ var elementPropHash = {
+ className: true,
+ colSpan: true,
+ rowSpan: true
+ };
+ var containerTagHash = {
+ '<tr': 'tbody',
+ '<td': 'tr'
+ };
+ function createElement(tagName, attrs, content) {
+ var el = document.createElement(tagName);
+ if (attrs) {
+ for (var attrName in attrs) {
+ if (attrName === 'style') {
+ applyStyle(el, attrs[attrName]);
+ }
+ else if (elementPropHash[attrName]) {
+ el[attrName] = attrs[attrName];
+ }
+ else {
+ el.setAttribute(attrName, attrs[attrName]);
+ }
+ }
+ }
+ if (typeof content === 'string') {
+ el.innerHTML = content; // shortcut. no need to process HTML in any way
+ }
+ else if (content != null) {
+ appendToElement(el, content);
+ }
+ return el;
+ }
+ function htmlToElement(html) {
+ html = html.trim();
+ var container = document.createElement(computeContainerTag(html));
+ container.innerHTML = html;
+ return container.firstChild;
+ }
+ function htmlToElements(html) {
+ return Array.prototype.slice.call(htmlToNodeList(html));
+ }
+ function htmlToNodeList(html) {
+ html = html.trim();
+ var container = document.createElement(computeContainerTag(html));
+ container.innerHTML = html;
+ return container.childNodes;
+ }
+ // assumes html already trimmed and tag names are lowercase
+ function computeContainerTag(html) {
+ return containerTagHash[html.substr(0, 3) // faster than using regex
+ ] || 'div';
+ }
+ function appendToElement(el, content) {
+ var childNodes = normalizeContent(content);
+ for (var i = 0; i < childNodes.length; i++) {
+ el.appendChild(childNodes[i]);
+ }
+ }
+ function prependToElement(parent, content) {
+ var newEls = normalizeContent(content);
+ var afterEl = parent.firstChild || null; // if no firstChild, will append to end, but that's okay, b/c there were no children
+ for (var i = 0; i < newEls.length; i++) {
+ parent.insertBefore(newEls[i], afterEl);
+ }
+ }
+ function insertAfterElement(refEl, content) {
+ var newEls = normalizeContent(content);
+ var afterEl = refEl.nextSibling || null;
+ for (var i = 0; i < newEls.length; i++) {
+ refEl.parentNode.insertBefore(newEls[i], afterEl);
+ }
+ }
+ function normalizeContent(content) {
+ var els;
+ if (typeof content === 'string') {
+ els = htmlToElements(content);
+ }
+ else if (content instanceof Node) {
+ els = [content];
+ }
+ else { // Node[] or NodeList
+ els = Array.prototype.slice.call(content);
+ }
+ return els;
+ }
+ function removeElement(el) {
+ if (el.parentNode) {
+ el.parentNode.removeChild(el);
+ }
+ }
+ // Querying
+ // ----------------------------------------------------------------------------------------------------------------
+ // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
+ var matchesMethod = Element.prototype.matches ||
+ Element.prototype.matchesSelector ||
+ Element.prototype.msMatchesSelector;
+ var closestMethod = Element.prototype.closest || function (selector) {
+ // polyfill
+ var el = this;
+ if (!document.documentElement.contains(el)) {
+ return null;
+ }
+ do {
+ if (elementMatches(el, selector)) {
+ return el;
+ }
+ el = el.parentElement || el.parentNode;
+ } while (el !== null && el.nodeType === 1);
+ return null;
+ };
+ function elementClosest(el, selector) {
+ return closestMethod.call(el, selector);
+ }
+ function elementMatches(el, selector) {
+ return matchesMethod.call(el, selector);
+ }
+ // accepts multiple subject els
+ // returns a real array. good for methods like forEach
+ function findElements(container, selector) {
+ var containers = container instanceof HTMLElement ? [container] : container;
+ var allMatches = [];
+ for (var i = 0; i < containers.length; i++) {
+ var matches = containers[i].querySelectorAll(selector);
+ for (var j = 0; j < matches.length; j++) {
+ allMatches.push(matches[j]);
+ }
+ }
+ return allMatches;
+ }
+ // accepts multiple subject els
+ // only queries direct child elements
+ function findChildren(parent, selector) {
+ var parents = parent instanceof HTMLElement ? [parent] : parent;
+ var allMatches = [];
+ for (var i = 0; i < parents.length; i++) {
+ var childNodes = parents[i].children; // only ever elements
+ for (var j = 0; j < childNodes.length; j++) {
+ var childNode = childNodes[j];
+ if (!selector || elementMatches(childNode, selector)) {
+ allMatches.push(childNode);
+ }
+ }
+ }
+ return allMatches;
+ }
+ // Attributes
+ // ----------------------------------------------------------------------------------------------------------------
+ function forceClassName(el, className, bool) {
+ if (bool) {
+ el.classList.add(className);
+ }
+ else {
+ el.classList.remove(className);
+ }
+ }
+ // Style
+ // ----------------------------------------------------------------------------------------------------------------
+ var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
+ function applyStyle(el, props) {
+ for (var propName in props) {
+ applyStyleProp(el, propName, props[propName]);
+ }
+ }
+ function applyStyleProp(el, name, val) {
+ if (val == null) {
+ el.style[name] = '';
+ }
+ else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
+ el.style[name] = val + 'px';
+ }
+ else {
+ el.style[name] = val;
+ }
+ }
+
+ function pointInsideRect(point, rect) {
+ return point.left >= rect.left &&
+ point.left < rect.right &&
+ point.top >= rect.top &&
+ point.top < rect.bottom;
+ }
+ // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
+ function intersectRects(rect1, rect2) {
+ var res = {
+ left: Math.max(rect1.left, rect2.left),
+ right: Math.min(rect1.right, rect2.right),
+ top: Math.max(rect1.top, rect2.top),
+ bottom: Math.min(rect1.bottom, rect2.bottom)
+ };
+ if (res.left < res.right && res.top < res.bottom) {
+ return res;
+ }
+ return false;
+ }
+ function translateRect(rect, deltaX, deltaY) {
+ return {
+ left: rect.left + deltaX,
+ right: rect.right + deltaX,
+ top: rect.top + deltaY,
+ bottom: rect.bottom + deltaY
+ };
+ }
+ // Returns a new point that will have been moved to reside within the given rectangle
+ function constrainPoint(point, rect) {
+ return {
+ left: Math.min(Math.max(point.left, rect.left), rect.right),
+ top: Math.min(Math.max(point.top, rect.top), rect.bottom)
+ };
+ }
+ // Returns a point that is the center of the given rectangle
+ function getRectCenter(rect) {
+ return {
+ left: (rect.left + rect.right) / 2,
+ top: (rect.top + rect.bottom) / 2
+ };
+ }
+ // Subtracts point2's coordinates from point1's coordinates, returning a delta
+ function diffPoints(point1, point2) {
+ return {
+ left: point1.left - point2.left,
+ top: point1.top - point2.top
+ };
+ }
+
+ // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
+ var isRtlScrollbarOnLeft = null;
+ function getIsRtlScrollbarOnLeft() {
+ if (isRtlScrollbarOnLeft === null) {
+ isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
+ }
+ return isRtlScrollbarOnLeft;
+ }
+ function computeIsRtlScrollbarOnLeft() {
+ var outerEl = createElement('div', {
+ style: {
+ position: 'absolute',
+ top: -1000,
+ left: 0,
+ border: 0,
+ padding: 0,
+ overflow: 'scroll',
+ direction: 'rtl'
+ }
+ }, '<div></div>');
+ document.body.appendChild(outerEl);
+ var innerEl = outerEl.firstChild;
+ var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
+ removeElement(outerEl);
+ return res;
+ }
+ // The scrollbar width computations in computeEdges are sometimes flawed when it comes to
+ // retina displays, rounding, and IE11. Massage them into a usable value.
+ function sanitizeScrollbarWidth(width) {
+ width = Math.max(0, width); // no negatives
+ width = Math.round(width);
+ return width;
+ }
+
+ function computeEdges(el, getPadding) {
+ if (getPadding === void 0) { getPadding = false; }
+ var computedStyle = window.getComputedStyle(el);
+ var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
+ var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
+ var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
+ var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
+ var scrollbarLeftRight = sanitizeScrollbarWidth(el.offsetWidth - el.clientWidth - borderLeft - borderRight);
+ var scrollbarBottom = sanitizeScrollbarWidth(el.offsetHeight - el.clientHeight - borderTop - borderBottom);
+ var res = {
+ borderLeft: borderLeft,
+ borderRight: borderRight,
+ borderTop: borderTop,
+ borderBottom: borderBottom,
+ scrollbarBottom: scrollbarBottom,
+ scrollbarLeft: 0,
+ scrollbarRight: 0
+ };
+ if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
+ res.scrollbarLeft = scrollbarLeftRight;
+ }
+ else {
+ res.scrollbarRight = scrollbarLeftRight;
+ }
+ if (getPadding) {
+ res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
+ res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
+ res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
+ res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
+ }
+ return res;
+ }
+ function computeInnerRect(el, goWithinPadding) {
+ if (goWithinPadding === void 0) { goWithinPadding = false; }
+ var outerRect = computeRect(el);
+ var edges = computeEdges(el, goWithinPadding);
+ var res = {
+ left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
+ right: outerRect.right - edges.borderRight - edges.scrollbarRight,
+ top: outerRect.top + edges.borderTop,
+ bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
+ };
+ if (goWithinPadding) {
+ res.left += edges.paddingLeft;
+ res.right -= edges.paddingRight;
+ res.top += edges.paddingTop;
+ res.bottom -= edges.paddingBottom;
+ }
+ return res;
+ }
+ function computeRect(el) {
+ var rect = el.getBoundingClientRect();
+ return {
+ left: rect.left + window.pageXOffset,
+ top: rect.top + window.pageYOffset,
+ right: rect.right + window.pageXOffset,
+ bottom: rect.bottom + window.pageYOffset
+ };
+ }
+ function computeViewportRect() {
+ return {
+ left: window.pageXOffset,
+ right: window.pageXOffset + document.documentElement.clientWidth,
+ top: window.pageYOffset,
+ bottom: window.pageYOffset + document.documentElement.clientHeight
+ };
+ }
+ function computeHeightAndMargins(el) {
+ var computed = window.getComputedStyle(el);
+ return el.getBoundingClientRect().height +
+ parseInt(computed.marginTop, 10) +
+ parseInt(computed.marginBottom, 10);
+ }
+ // does not return window
+ function getClippingParents(el) {
+ var parents = [];
+ while (el instanceof HTMLElement) { // will stop when gets to document or null
+ var computedStyle = window.getComputedStyle(el);
+ if (computedStyle.position === 'fixed') {
+ break;
+ }
+ if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
+ parents.push(el);
+ }
+ el = el.parentNode;
+ }
+ return parents;
+ }
+ function computeClippingRect(el) {
+ return getClippingParents(el)
+ .map(function (el) {
+ return computeInnerRect(el);
+ })
+ .concat(computeViewportRect())
+ .reduce(function (rect0, rect1) {
+ return intersectRects(rect0, rect1) || rect1; // should always intersect
+ });
+ }
+
+ // Stops a mouse/touch event from doing it's native browser action
+ function preventDefault(ev) {
+ ev.preventDefault();
+ }
+ // Event Delegation
+ // ----------------------------------------------------------------------------------------------------------------
+ function listenBySelector(container, eventType, selector, handler) {
+ function realHandler(ev) {
+ var matchedChild = elementClosest(ev.target, selector);
+ if (matchedChild) {
+ handler.call(matchedChild, ev, matchedChild);
+ }
+ }
+ container.addEventListener(eventType, realHandler);
+ return function () {
+ container.removeEventListener(eventType, realHandler);
+ };
+ }
+ function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
+ var currentMatchedChild;
+ return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) {
+ if (matchedChild !== currentMatchedChild) {
+ currentMatchedChild = matchedChild;
+ onMouseEnter(ev, matchedChild);
+ var realOnMouseLeave_1 = function (ev) {
+ currentMatchedChild = null;
+ onMouseLeave(ev, matchedChild);
+ matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
+ };
+ // listen to the next mouseleave, and then unattach
+ matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
+ }
+ });
+ }
+ // Animation
+ // ----------------------------------------------------------------------------------------------------------------
+ var transitionEventNames = [
+ 'webkitTransitionEnd',
+ 'otransitionend',
+ 'oTransitionEnd',
+ 'msTransitionEnd',
+ 'transitionend'
+ ];
+ // triggered only when the next single subsequent transition finishes
+ function whenTransitionDone(el, callback) {
+ var realCallback = function (ev) {
+ callback(ev);
+ transitionEventNames.forEach(function (eventName) {
+ el.removeEventListener(eventName, realCallback);
+ });
+ };
+ transitionEventNames.forEach(function (eventName) {
+ el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
+ });
+ }
+
+ var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
+ // Adding
+ function addWeeks(m, n) {
+ var a = dateToUtcArray(m);
+ a[2] += n * 7;
+ return arrayToUtcDate(a);
+ }
+ function addDays(m, n) {
+ var a = dateToUtcArray(m);
+ a[2] += n;
+ return arrayToUtcDate(a);
+ }
+ function addMs(m, n) {
+ var a = dateToUtcArray(m);
+ a[6] += n;
+ return arrayToUtcDate(a);
+ }
+ // Diffing (all return floats)
+ function diffWeeks(m0, m1) {
+ return diffDays(m0, m1) / 7;
+ }
+ function diffDays(m0, m1) {
+ return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
+ }
+ function diffHours(m0, m1) {
+ return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
+ }
+ function diffMinutes(m0, m1) {
+ return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
+ }
+ function diffSeconds(m0, m1) {
+ return (m1.valueOf() - m0.valueOf()) / 1000;
+ }
+ function diffDayAndTime(m0, m1) {
+ var m0day = startOfDay(m0);
+ var m1day = startOfDay(m1);
+ return {
+ years: 0,
+ months: 0,
+ days: Math.round(diffDays(m0day, m1day)),
+ milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf())
+ };
+ }
+ // Diffing Whole Units
+ function diffWholeWeeks(m0, m1) {
+ var d = diffWholeDays(m0, m1);
+ if (d !== null && d % 7 === 0) {
+ return d / 7;
+ }
+ return null;
+ }
+ function diffWholeDays(m0, m1) {
+ if (timeAsMs(m0) === timeAsMs(m1)) {
+ return Math.round(diffDays(m0, m1));
+ }
+ return null;
+ }
+ // Start-Of
+ function startOfDay(m) {
+ return arrayToUtcDate([
+ m.getUTCFullYear(),
+ m.getUTCMonth(),
+ m.getUTCDate()
+ ]);
+ }
+ function startOfHour(m) {
+ return arrayToUtcDate([
+ m.getUTCFullYear(),
+ m.getUTCMonth(),
+ m.getUTCDate(),
+ m.getUTCHours()
+ ]);
+ }
+ function startOfMinute(m) {
+ return arrayToUtcDate([
+ m.getUTCFullYear(),
+ m.getUTCMonth(),
+ m.getUTCDate(),
+ m.getUTCHours(),
+ m.getUTCMinutes()
+ ]);
+ }
+ function startOfSecond(m) {
+ return arrayToUtcDate([
+ m.getUTCFullYear(),
+ m.getUTCMonth(),
+ m.getUTCDate(),
+ m.getUTCHours(),
+ m.getUTCMinutes(),
+ m.getUTCSeconds()
+ ]);
+ }
+ // Week Computation
+ function weekOfYear(marker, dow, doy) {
+ var y = marker.getUTCFullYear();
+ var w = weekOfGivenYear(marker, y, dow, doy);
+ if (w < 1) {
+ return weekOfGivenYear(marker, y - 1, dow, doy);
+ }
+ var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
+ if (nextW >= 1) {
+ return Math.min(w, nextW);
+ }
+ return w;
+ }
+ function weekOfGivenYear(marker, year, dow, doy) {
+ var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
+ var dayStart = startOfDay(marker);
+ var days = Math.round(diffDays(firstWeekStart, dayStart));
+ return Math.floor(days / 7) + 1; // zero-indexed
+ }
+ // start-of-first-week - start-of-year
+ function firstWeekOffset(year, dow, doy) {
+ // first-week day -- which january is always in the first week (4 for iso, 1 for other)
+ var fwd = 7 + dow - doy;
+ // first-week day local weekday -- which local weekday is fwd
+ var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
+ return -fwdlw + fwd - 1;
+ }
+ // Array Conversion
+ function dateToLocalArray(date) {
+ return [
+ date.getFullYear(),
+ date.getMonth(),
+ date.getDate(),
+ date.getHours(),
+ date.getMinutes(),
+ date.getSeconds(),
+ date.getMilliseconds()
+ ];
+ }
+ function arrayToLocalDate(a) {
+ return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
+ a[3] || 0, a[4] || 0, a[5] || 0);
+ }
+ function dateToUtcArray(date) {
+ return [
+ date.getUTCFullYear(),
+ date.getUTCMonth(),
+ date.getUTCDate(),
+ date.getUTCHours(),
+ date.getUTCMinutes(),
+ date.getUTCSeconds(),
+ date.getUTCMilliseconds()
+ ];
+ }
+ function arrayToUtcDate(a) {
+ // according to web standards (and Safari), a month index is required.
+ // massage if only given a year.
+ if (a.length === 1) {
+ a = a.concat([0]);
+ }
+ return new Date(Date.UTC.apply(Date, a));
+ }
+ // Other Utils
+ function isValidDate(m) {
+ return !isNaN(m.valueOf());
+ }
+ function timeAsMs(m) {
+ return m.getUTCHours() * 1000 * 60 * 60 +
+ m.getUTCMinutes() * 1000 * 60 +
+ m.getUTCSeconds() * 1000 +
+ m.getUTCMilliseconds();
+ }
+
+ var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
+ var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
+ // Parsing and Creation
+ function createDuration(input, unit) {
+ var _a;
+ if (typeof input === 'string') {
+ return parseString(input);
+ }
+ else if (typeof input === 'object' && input) { // non-null object
+ return normalizeObject(input);
+ }
+ else if (typeof input === 'number') {
+ return normalizeObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
+ }
+ else {
+ return null;
+ }
+ }
+ function parseString(s) {
+ var m = PARSE_RE.exec(s);
+ if (m) {
+ var sign = m[1] ? -1 : 1;
+ return {
+ years: 0,
+ months: 0,
+ days: sign * (m[2] ? parseInt(m[2], 10) : 0),
+ milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
+ (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
+ (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
+ (m[6] ? parseInt(m[6], 10) : 0) // ms
+ )
+ };
+ }
+ return null;
+ }
+ function normalizeObject(obj) {
+ return {
+ years: obj.years || obj.year || 0,
+ months: obj.months || obj.month || 0,
+ days: (obj.days || obj.day || 0) +
+ getWeeksFromInput(obj) * 7,
+ milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
+ (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
+ (obj.seconds || obj.second || 0) * 1000 + // seconds
+ (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
+ };
+ }
+ function getWeeksFromInput(obj) {
+ return obj.weeks || obj.week || 0;
+ }
+ // Equality
+ function durationsEqual(d0, d1) {
+ return d0.years === d1.years &&
+ d0.months === d1.months &&
+ d0.days === d1.days &&
+ d0.milliseconds === d1.milliseconds;
+ }
+ function isSingleDay(dur) {
+ return dur.years === 0 && dur.months === 0 && dur.days === 1 && dur.milliseconds === 0;
+ }
+ // Simple Math
+ function addDurations(d0, d1) {
+ return {
+ years: d0.years + d1.years,
+ months: d0.months + d1.months,
+ days: d0.days + d1.days,
+ milliseconds: d0.milliseconds + d1.milliseconds
+ };
+ }
+ function subtractDurations(d1, d0) {
+ return {
+ years: d1.years - d0.years,
+ months: d1.months - d0.months,
+ days: d1.days - d0.days,
+ milliseconds: d1.milliseconds - d0.milliseconds
+ };
+ }
+ function multiplyDuration(d, n) {
+ return {
+ years: d.years * n,
+ months: d.months * n,
+ days: d.days * n,
+ milliseconds: d.milliseconds * n
+ };
+ }
+ // Conversions
+ // "Rough" because they are based on average-case Gregorian months/years
+ function asRoughYears(dur) {
+ return asRoughDays(dur) / 365;
+ }
+ function asRoughMonths(dur) {
+ return asRoughDays(dur) / 30;
+ }
+ function asRoughDays(dur) {
+ return asRoughMs(dur) / 864e5;
+ }
+ function asRoughMinutes(dur) {
+ return asRoughMs(dur) / (1000 * 60);
+ }
+ function asRoughSeconds(dur) {
+ return asRoughMs(dur) / 1000;
+ }
+ function asRoughMs(dur) {
+ return dur.years * (365 * 864e5) +
+ dur.months * (30 * 864e5) +
+ dur.days * 864e5 +
+ dur.milliseconds;
+ }
+ // Advanced Math
+ function wholeDivideDurations(numerator, denominator) {
+ var res = null;
+ for (var i = 0; i < INTERNAL_UNITS.length; i++) {
+ var unit = INTERNAL_UNITS[i];
+ if (denominator[unit]) {
+ var localRes = numerator[unit] / denominator[unit];
+ if (!isInt(localRes) || (res !== null && res !== localRes)) {
+ return null;
+ }
+ res = localRes;
+ }
+ else if (numerator[unit]) {
+ // needs to divide by something but can't!
+ return null;
+ }
+ }
+ return res;
+ }
+ function greatestDurationDenominator(dur, dontReturnWeeks) {
+ var ms = dur.milliseconds;
+ if (ms) {
+ if (ms % 1000 !== 0) {
+ return { unit: 'millisecond', value: ms };
+ }
+ if (ms % (1000 * 60) !== 0) {
+ return { unit: 'second', value: ms / 1000 };
+ }
+ if (ms % (1000 * 60 * 60) !== 0) {
+ return { unit: 'minute', value: ms / (1000 * 60) };
+ }
+ if (ms) {
+ return { unit: 'hour', value: ms / (1000 * 60 * 60) };
+ }
+ }
+ if (dur.days) {
+ if (!dontReturnWeeks && dur.days % 7 === 0) {
+ return { unit: 'week', value: dur.days / 7 };
+ }
+ return { unit: 'day', value: dur.days };
+ }
+ if (dur.months) {
+ return { unit: 'month', value: dur.months };
+ }
+ if (dur.years) {
+ return { unit: 'year', value: dur.years };
+ }
+ return { unit: 'millisecond', value: 0 };
+ }
+
+ /* FullCalendar-specific DOM Utilities
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
+ // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
+ function compensateScroll(rowEl, scrollbarWidths) {
+ if (scrollbarWidths.left) {
+ applyStyle(rowEl, {
+ borderLeftWidth: 1,
+ marginLeft: scrollbarWidths.left - 1
+ });
+ }
+ if (scrollbarWidths.right) {
+ applyStyle(rowEl, {
+ borderRightWidth: 1,
+ marginRight: scrollbarWidths.right - 1
+ });
+ }
+ }
+ // Undoes compensateScroll and restores all borders/margins
+ function uncompensateScroll(rowEl) {
+ applyStyle(rowEl, {
+ marginLeft: '',
+ marginRight: '',
+ borderLeftWidth: '',
+ borderRightWidth: ''
+ });
+ }
+ // Make the mouse cursor express that an event is not allowed in the current area
+ function disableCursor() {
+ document.body.classList.add('fc-not-allowed');
+ }
+ // Returns the mouse cursor to its original look
+ function enableCursor() {
+ document.body.classList.remove('fc-not-allowed');
+ }
+ // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
+ // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
+ // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
+ // reduces the available height.
+ function distributeHeight(els, availableHeight, shouldRedistribute) {
+ // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
+ // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
+ var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element
+ var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*
+ var flexEls = []; // elements that are allowed to expand. array of DOM nodes
+ var flexOffsets = []; // amount of vertical space it takes up
+ var flexHeights = []; // actual css height
+ var usedHeight = 0;
+ undistributeHeight(els); // give all elements their natural height
+ // find elements that are below the recommended height (expandable).
+ // important to query for heights in a single first pass (to avoid reflow oscillation).
+ els.forEach(function (el, i) {
+ var minOffset = i === els.length - 1 ? minOffset2 : minOffset1;
+ var naturalOffset = computeHeightAndMargins(el);
+ if (naturalOffset < minOffset) {
+ flexEls.push(el);
+ flexOffsets.push(naturalOffset);
+ flexHeights.push(el.offsetHeight);
+ }
+ else {
+ // this element stretches past recommended height (non-expandable). mark the space as occupied.
+ usedHeight += naturalOffset;
+ }
+ });
+ // readjust the recommended height to only consider the height available to non-maxed-out rows.
+ if (shouldRedistribute) {
+ availableHeight -= usedHeight;
+ minOffset1 = Math.floor(availableHeight / flexEls.length);
+ minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*
+ }
+ // assign heights to all expandable elements
+ flexEls.forEach(function (el, i) {
+ var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;
+ var naturalOffset = flexOffsets[i];
+ var naturalHeight = flexHeights[i];
+ var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding
+ if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things
+ el.style.height = newHeight + 'px';
+ }
+ });
+ }
+ // Undoes distrubuteHeight, restoring all els to their natural height
+ function undistributeHeight(els) {
+ els.forEach(function (el) {
+ el.style.height = '';
+ });
+ }
+ // Given `els`, a set of <td> cells, find the cell with the largest natural width and set the widths of all the
+ // cells to be that width.
+ // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
+ function matchCellWidths(els) {
+ var maxInnerWidth = 0;
+ els.forEach(function (el) {
+ var innerEl = el.firstChild; // hopefully an element
+ if (innerEl instanceof HTMLElement) {
+ var innerWidth_1 = innerEl.offsetWidth;
+ if (innerWidth_1 > maxInnerWidth) {
+ maxInnerWidth = innerWidth_1;
+ }
+ }
+ });
+ maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
+ els.forEach(function (el) {
+ el.style.width = maxInnerWidth + 'px';
+ });
+ return maxInnerWidth;
+ }
+ // Given one element that resides inside another,
+ // Subtracts the height of the inner element from the outer element.
+ function subtractInnerElHeight(outerEl, innerEl) {
+ // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
+ var reflowStyleProps = {
+ position: 'relative',
+ left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
+ };
+ applyStyle(outerEl, reflowStyleProps);
+ applyStyle(innerEl, reflowStyleProps);
+ var diff = outerEl.offsetHeight - innerEl.offsetHeight; // grab the dimensions
+ // undo hack
+ var resetStyleProps = { position: '', left: '' };
+ applyStyle(outerEl, resetStyleProps);
+ applyStyle(innerEl, resetStyleProps);
+ return diff;
+ }
+ /* Selection
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function preventSelection(el) {
+ el.classList.add('fc-unselectable');
+ el.addEventListener('selectstart', preventDefault);
+ }
+ function allowSelection(el) {
+ el.classList.remove('fc-unselectable');
+ el.removeEventListener('selectstart', preventDefault);
+ }
+ /* Context Menu
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function preventContextMenu(el) {
+ el.addEventListener('contextmenu', preventDefault);
+ }
+ function allowContextMenu(el) {
+ el.removeEventListener('contextmenu', preventDefault);
+ }
+ /* Object Ordering by Field
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function parseFieldSpecs(input) {
+ var specs = [];
+ var tokens = [];
+ var i;
+ var token;
+ if (typeof input === 'string') {
+ tokens = input.split(/\s*,\s*/);
+ }
+ else if (typeof input === 'function') {
+ tokens = [input];
+ }
+ else if (Array.isArray(input)) {
+ tokens = input;
+ }
+ for (i = 0; i < tokens.length; i++) {
+ token = tokens[i];
+ if (typeof token === 'string') {
+ specs.push(token.charAt(0) === '-' ?
+ { field: token.substring(1), order: -1 } :
+ { field: token, order: 1 });
+ }
+ else if (typeof token === 'function') {
+ specs.push({ func: token });
+ }
+ }
+ return specs;
+ }
+ function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
+ var i;
+ var cmp;
+ for (i = 0; i < fieldSpecs.length; i++) {
+ cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
+ if (cmp) {
+ return cmp;
+ }
+ }
+ return 0;
+ }
+ function compareByFieldSpec(obj0, obj1, fieldSpec) {
+ if (fieldSpec.func) {
+ return fieldSpec.func(obj0, obj1);
+ }
+ return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
+ * (fieldSpec.order || 1);
+ }
+ function flexibleCompare(a, b) {
+ if (!a && !b) {
+ return 0;
+ }
+ if (b == null) {
+ return -1;
+ }
+ if (a == null) {
+ return 1;
+ }
+ if (typeof a === 'string' || typeof b === 'string') {
+ return String(a).localeCompare(String(b));
+ }
+ return a - b;
+ }
+ /* String Utilities
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function capitaliseFirstLetter(str) {
+ return str.charAt(0).toUpperCase() + str.slice(1);
+ }
+ function padStart(val, len) {
+ var s = String(val);
+ return '000'.substr(0, len - s.length) + s;
+ }
+ /* Number Utilities
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function compareNumbers(a, b) {
+ return a - b;
+ }
+ function isInt(n) {
+ return n % 1 === 0;
+ }
+ /* Weird Utilities
+ ----------------------------------------------------------------------------------------------------------------------*/
+ function applyAll(functions, thisObj, args) {
+ if (typeof functions === 'function') { // supplied a single function
+ functions = [functions];
+ }
+ if (functions) {
+ var i = void 0;
+ var ret = void 0;
+ for (i = 0; i < functions.length; i++) {
+ ret = functions[i].apply(thisObj, args) || ret;
+ }
+ return ret;
+ }
+ }
+ function firstDefined() {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+ for (var i = 0; i < args.length; i++) {
+ if (args[i] !== undefined) {
+ return args[i];
+ }
+ }
+ }
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
+ function debounce(func, wait) {
+ var timeout;
+ var args;
+ var context;
+ var timestamp;
+ var result;
+ var later = function () {
+ var last = new Date().valueOf() - timestamp;
+ if (last < wait) {
+ timeout = setTimeout(later, wait - last);
+ }
+ else {
+ timeout = null;
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ };
+ return function () {
+ context = this;
+ args = arguments;
+ timestamp = new Date().valueOf();
+ if (!timeout) {
+ timeout = setTimeout(later, wait);
+ }
+ return result;
+ };
+ }
+ // Number and Boolean are only types that defaults or not computed for
+ // TODO: write more comments
+ function refineProps(rawProps, processors, defaults, leftoverProps) {
+ if (defaults === void 0) { defaults = {}; }
+ var refined = {};
+ for (var key in processors) {
+ var processor = processors[key];
+ if (rawProps[key] !== undefined) {
+ // found
+ if (processor === Function) {
+ refined[key] = typeof rawProps[key] === 'function' ? rawProps[key] : null;
+ }
+ else if (processor) { // a refining function?
+ refined[key] = processor(rawProps[key]);
+ }
+ else {
+ refined[key] = rawProps[key];
+ }
+ }
+ else if (defaults[key] !== undefined) {
+ // there's an explicit default
+ refined[key] = defaults[key];
+ }
+ else {
+ // must compute a default
+ if (processor === String) {
+ refined[key] = ''; // empty string is default for String
+ }
+ else if (!processor || processor === Number || processor === Boolean || processor === Function) {
+ refined[key] = null; // assign null for other non-custom processor funcs
+ }
+ else {
+ refined[key] = processor(null); // run the custom processor func
+ }
+ }
+ }
+ if (leftoverProps) {
+ for (var key in rawProps) {
+ if (processors[key] === undefined) {
+ leftoverProps[key] = rawProps[key];
+ }
+ }
+ }
+ return refined;
+ }
+ /*
+ Get a snapshot of an object, so we can compare it to later revisions.
+ Intentionally only works with arrays, jaja
+ */
+ function freezeRaw(raw) {
+ if (Array.isArray(raw)) {
+ return Array.prototype.slice.call(raw);
+ }
+ return raw;
+ }
+ /* Date stuff that doesn't belong in datelib core
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // given a timed range, computes an all-day range that has the same exact duration,
+ // but whose start time is aligned with the start of the day.
+ function computeAlignedDayRange(timedRange) {
+ var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
+ var start = startOfDay(timedRange.start);
+ var end = addDays(start, dayCnt);
+ return { start: start, end: end };
+ }
+ // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
+ // TODO: give nextDayThreshold a default arg
+ function computeVisibleDayRange(timedRange, nextDayThreshold) {
+ if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
+ var startDay = null;
+ var endDay = null;
+ if (timedRange.end) {
+ endDay = startOfDay(timedRange.end);
+ var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
+ // If the end time is actually inclusively part of the next day and is equal to or
+ // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
+ // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
+ if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
+ endDay = addDays(endDay, 1);
+ }
+ }
+ if (timedRange.start) {
+ startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
+ // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
+ if (endDay && endDay <= startDay) {
+ endDay = addDays(startDay, 1);
+ }
+ }
+ return { start: startDay, end: endDay };
+ }
+ // spans from one day into another?
+ function isMultiDayRange(range) {
+ var visibleRange = computeVisibleDayRange(range);
+ return diffDays(visibleRange.start, visibleRange.end) > 1;
+ }
+ function diffDates(date0, date1, dateEnv, largeUnit) {
+ if (largeUnit === 'year') {
+ return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
+ }
+ else if (largeUnit === 'month') {
+ return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
+ }
+ else {
+ return diffDayAndTime(date0, date1); // returns a duration
+ }
+ }
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ function parseRecurring(eventInput, allDayDefault, dateEnv, recurringTypes, leftovers) {
+ for (var i = 0; i < recurringTypes.length; i++) {
+ var localLeftovers = {};
+ var parsed = recurringTypes[i].parse(eventInput, localLeftovers, dateEnv);
+ if (parsed) {
+ var allDay = localLeftovers.allDay;
+ delete localLeftovers.allDay; // remove from leftovers
+ if (allDay == null) {
+ allDay = allDayDefault;
+ if (allDay == null) {
+ allDay = parsed.allDayGuess;
+ if (allDay == null) {
+ allDay = false;
+ }
+ }
+ }
+ __assign(leftovers, localLeftovers);
+ return {
+ allDay: allDay,
+ duration: parsed.duration,
+ typeData: parsed.typeData,
+ typeId: i
+ };
+ }
+ }
+ return null;
+ }
+ /*
+ Event MUST have a recurringDef
+ */
+ function expandRecurringRanges(eventDef, framingRange, dateEnv, recurringTypes) {
+ var typeDef = recurringTypes[eventDef.recurringDef.typeId];
+ var markers = typeDef.expand(eventDef.recurringDef.typeData, framingRange, dateEnv);
+ // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
+ if (eventDef.allDay) {
+ markers = markers.map(startOfDay);
+ }
+ return markers;
+ }
+
+ // Merges an array of objects into a single object.
+ // The second argument allows for an array of property names who's object values will be merged together.
+ function mergeProps(propObjs, complexProps) {
+ var dest = {};
+ var i;
+ var name;
+ var complexObjs;
+ var j;
+ var val;
+ var props;
+ if (complexProps) {
+ for (i = 0; i < complexProps.length; i++) {
+ name = complexProps[i];
+ complexObjs = [];
+ // collect the trailing object values, stopping when a non-object is discovered
+ for (j = propObjs.length - 1; j >= 0; j--) {
+ val = propObjs[j][name];
+ if (typeof val === 'object' && val) { // non-null object
+ complexObjs.unshift(val);
+ }
+ else if (val !== undefined) {
+ dest[name] = val; // if there were no objects, this value will be used
+ break;
+ }
+ }
+ // if the trailing values were objects, use the merged value
+ if (complexObjs.length) {
+ dest[name] = mergeProps(complexObjs);
+ }
+ }
+ }
+ // copy values into the destination, going from last to first
+ for (i = propObjs.length - 1; i >= 0; i--) {
+ props = propObjs[i];
+ for (name in props) {
+ if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
+ dest[name] = props[name];
+ }
+ }
+ }
+ return dest;
+ }
+ function filterHash(hash, func) {
+ var filtered = {};
+ for (var key in hash) {
+ if (func(hash[key], key)) {
+ filtered[key] = hash[key];
+ }
+ }
+ return filtered;
+ }
+ function mapHash(hash, func) {
+ var newHash = {};
+ for (var key in hash) {
+ newHash[key] = func(hash[key], key);
+ }
+ return newHash;
+ }
+ function arrayToHash(a) {
+ var hash = {};
+ for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
+ var item = a_1[_i];
+ hash[item] = true;
+ }
+ return hash;
+ }
+ function hashValuesToArray(obj) {
+ var a = [];
+ for (var key in obj) {
+ a.push(obj[key]);
+ }
+ return a;
+ }
+
+ function parseEvents(rawEvents, sourceId, calendar, allowOpenRange) {
+ var eventStore = createEmptyEventStore();
+ for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
+ var rawEvent = rawEvents_1[_i];
+ var tuple = parseEvent(rawEvent, sourceId, calendar, allowOpenRange);
+ if (tuple) {
+ eventTupleToStore(tuple, eventStore);
+ }
+ }
+ return eventStore;
+ }
+ function eventTupleToStore(tuple, eventStore) {
+ if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
+ eventStore.defs[tuple.def.defId] = tuple.def;
+ if (tuple.instance) {
+ eventStore.instances[tuple.instance.instanceId] = tuple.instance;
+ }
+ return eventStore;
+ }
+ function expandRecurring(eventStore, framingRange, calendar) {
+ var dateEnv = calendar.dateEnv;
+ var defs = eventStore.defs, instances = eventStore.instances;
+ // remove existing recurring instances
+ instances = filterHash(instances, function (instance) {
+ return !defs[instance.defId].recurringDef;
+ });
+ for (var defId in defs) {
+ var def = defs[defId];
+ if (def.recurringDef) {
+ var starts = expandRecurringRanges(def, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes);
+ var duration = def.recurringDef.duration;
+ if (!duration) {
+ duration = def.allDay ?
+ calendar.defaultAllDayEventDuration :
+ calendar.defaultTimedEventDuration;
+ }
+ for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
+ var start = starts_1[_i];
+ var instance = createEventInstance(defId, {
+ start: start,
+ end: dateEnv.add(start, duration)
+ });
+ instances[instance.instanceId] = instance;
+ }
+ }
+ }
+ return { defs: defs, instances: instances };
+ }
+ // retrieves events that have the same groupId as the instance specified by `instanceId`
+ // or they are the same as the instance.
+ // why might instanceId not be in the store? an event from another calendar?
+ function getRelevantEvents(eventStore, instanceId) {
+ var instance = eventStore.instances[instanceId];
+ if (instance) {
+ var def_1 = eventStore.defs[instance.defId];
+ // get events/instances with same group
+ var newStore = filterEventStoreDefs(eventStore, function (lookDef) {
+ return isEventDefsGrouped(def_1, lookDef);
+ });
+ // add the original
+ // TODO: wish we could use eventTupleToStore or something like it
+ newStore.defs[def_1.defId] = def_1;
+ newStore.instances[instance.instanceId] = instance;
+ return newStore;
+ }
+ return createEmptyEventStore();
+ }
+ function isEventDefsGrouped(def0, def1) {
+ return Boolean(def0.groupId && def0.groupId === def1.groupId);
+ }
+ function transformRawEvents(rawEvents, eventSource, calendar) {
+ var calEachTransform = calendar.opt('eventDataTransform');
+ var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
+ if (sourceEachTransform) {
+ rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
+ }
+ if (calEachTransform) {
+ rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
+ }
+ return rawEvents;
+ }
+ function transformEachRawEvent(rawEvents, func) {
+ var refinedEvents;
+ if (!func) {
+ refinedEvents = rawEvents;
+ }
+ else {
+ refinedEvents = [];
+ for (var _i = 0, rawEvents_2 = rawEvents; _i < rawEvents_2.length; _i++) {
+ var rawEvent = rawEvents_2[_i];
+ var refinedEvent = func(rawEvent);
+ if (refinedEvent) {
+ refinedEvents.push(refinedEvent);
+ }
+ else if (refinedEvent == null) {
+ refinedEvents.push(rawEvent);
+ } // if a different falsy value, do nothing
+ }
+ }
+ return refinedEvents;
+ }
+ function createEmptyEventStore() {
+ return { defs: {}, instances: {} };
+ }
+ function mergeEventStores(store0, store1) {
+ return {
+ defs: __assign({}, store0.defs, store1.defs),
+ instances: __assign({}, store0.instances, store1.instances)
+ };
+ }
+ function filterEventStoreDefs(eventStore, filterFunc) {
+ var defs = filterHash(eventStore.defs, filterFunc);
+ var instances = filterHash(eventStore.instances, function (instance) {
+ return defs[instance.defId]; // still exists?
+ });
+ return { defs: defs, instances: instances };
+ }
+
+ function parseRange(input, dateEnv) {
+ var start = null;
+ var end = null;
+ if (input.start) {
+ start = dateEnv.createMarker(input.start);
+ }
+ if (input.end) {
+ end = dateEnv.createMarker(input.end);
+ }
+ if (!start && !end) {
+ return null;
+ }
+ if (start && end && end < start) {
+ return null;
+ }
+ return { start: start, end: end };
+ }
+ // SIDE-EFFECT: will mutate ranges.
+ // Will return a new array result.
+ function invertRanges(ranges, constraintRange) {
+ var invertedRanges = [];
+ var start = constraintRange.start; // the end of the previous range. the start of the new range
+ var i;
+ var dateRange;
+ // ranges need to be in order. required for our date-walking algorithm
+ ranges.sort(compareRanges);
+ for (i = 0; i < ranges.length; i++) {
+ dateRange = ranges[i];
+ // add the span of time before the event (if there is any)
+ if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
+ invertedRanges.push({ start: start, end: dateRange.start });
+ }
+ if (dateRange.end > start) {
+ start = dateRange.end;
+ }
+ }
+ // add the span of time after the last event (if there is any)
+ if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
+ invertedRanges.push({ start: start, end: constraintRange.end });
+ }
+ return invertedRanges;
+ }
+ function compareRanges(range0, range1) {
+ return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
+ }
+ function intersectRanges(range0, range1) {
+ var start = range0.start;
+ var end = range0.end;
+ var newRange = null;
+ if (range1.start !== null) {
+ if (start === null) {
+ start = range1.start;
+ }
+ else {
+ start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
+ }
+ }
+ if (range1.end != null) {
+ if (end === null) {
+ end = range1.end;
+ }
+ else {
+ end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
+ }
+ }
+ if (start === null || end === null || start < end) {
+ newRange = { start: start, end: end };
+ }
+ return newRange;
+ }
+ function rangesEqual(range0, range1) {
+ return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
+ (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
+ }
+ function rangesIntersect(range0, range1) {
+ return (range0.end === null || range1.start === null || range0.end > range1.start) &&
+ (range0.start === null || range1.end === null || range0.start < range1.end);
+ }
+ function rangeContainsRange(outerRange, innerRange) {
+ return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
+ (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
+ }
+ function rangeContainsMarker(range, date) {
+ return (range.start === null || date >= range.start) &&
+ (range.end === null || date < range.end);
+ }
+ // If the given date is not within the given range, move it inside.
+ // (If it's past the end, make it one millisecond before the end).
+ function constrainMarkerToRange(date, range) {
+ if (range.start != null && date < range.start) {
+ return range.start;
+ }
+ if (range.end != null && date >= range.end) {
+ return new Date(range.end.valueOf() - 1);
+ }
+ return date;
+ }
+
+ function removeExact(array, exactVal) {
+ var removeCnt = 0;
+ var i = 0;
+ while (i < array.length) {
+ if (array[i] === exactVal) {
+ array.splice(i, 1);
+ removeCnt++;
+ }
+ else {
+ i++;
+ }
+ }
+ return removeCnt;
+ }
+ function isArraysEqual(a0, a1) {
+ var len = a0.length;
+ var i;
+ if (len !== a1.length) { // not array? or not same length?
+ return false;
+ }
+ for (i = 0; i < len; i++) {
+ if (a0[i] !== a1[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function memoize(workerFunc) {
+ var args;
+ var res;
+ return function () {
+ if (!args || !isArraysEqual(args, arguments)) {
+ args = arguments;
+ res = workerFunc.apply(this, arguments);
+ }
+ return res;
+ };
+ }
+ /*
+ always executes the workerFunc, but if the result is equal to the previous result,
+ return the previous result instead.
+ */
+ function memoizeOutput(workerFunc, equalityFunc) {
+ var cachedRes = null;
+ return function () {
+ var newRes = workerFunc.apply(this, arguments);
+ if (cachedRes === null || !(cachedRes === newRes || equalityFunc(cachedRes, newRes))) {
+ cachedRes = newRes;
+ }
+ return cachedRes;
+ };
+ }
+
+ var EXTENDED_SETTINGS_AND_SEVERITIES = {
+ week: 3,
+ separator: 0,
+ omitZeroMinute: 0,
+ meridiem: 0,
+ omitCommas: 0
+ };
+ var STANDARD_DATE_PROP_SEVERITIES = {
+ timeZoneName: 7,
+ era: 6,
+ year: 5,
+ month: 4,
+ day: 2,
+ weekday: 2,
+ hour: 1,
+ minute: 1,
+ second: 1
+ };
+ var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
+ var COMMA_RE = /,/g; // we need re for globalness
+ var MULTI_SPACE_RE = /\s+/g;
+ var LTR_RE = /\u200e/g; // control character
+ var UTC_RE = /UTC|GMT/;
+ var NativeFormatter = /** @class */ (function () {
+ function NativeFormatter(formatSettings) {
+ var standardDateProps = {};
+ var extendedSettings = {};
+ var severity = 0;
+ for (var name_1 in formatSettings) {
+ if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
+ extendedSettings[name_1] = formatSettings[name_1];
+ severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
+ }
+ else {
+ standardDateProps[name_1] = formatSettings[name_1];
+ if (name_1 in STANDARD_DATE_PROP_SEVERITIES) {
+ severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
+ }
+ }
+ }
+ this.standardDateProps = standardDateProps;
+ this.extendedSettings = extendedSettings;
+ this.severity = severity;
+ this.buildFormattingFunc = memoize(buildFormattingFunc);
+ }
+ NativeFormatter.prototype.format = function (date, context) {
+ return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
+ };
+ NativeFormatter.prototype.formatRange = function (start, end, context) {
+ var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
+ var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
+ if (!diffSeverity) {
+ return this.format(start, context);
+ }
+ var biggestUnitForPartial = diffSeverity;
+ if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
+ (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
+ (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
+ (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
+ biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
+ }
+ var full0 = this.format(start, context);
+ var full1 = this.format(end, context);
+ if (full0 === full1) {
+ return full0;
+ }
+ var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
+ var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
+ var partial0 = partialFormattingFunc(start);
+ var partial1 = partialFormattingFunc(end);
+ var insertion = findCommonInsertion(full0, partial0, full1, partial1);
+ var separator = extendedSettings.separator || '';
+ if (insertion) {
+ return insertion.before + partial0 + separator + partial1 + insertion.after;
+ }
+ return full0 + separator + full1;
+ };
+ NativeFormatter.prototype.getLargestUnit = function () {
+ switch (this.severity) {
+ case 7:
+ case 6:
+ case 5:
+ return 'year';
+ case 4:
+ return 'month';
+ case 3:
+ return 'week';
+ default:
+ return 'day';
+ }
+ };
+ return NativeFormatter;
+ }());
+ function buildFormattingFunc(standardDateProps, extendedSettings, context) {
+ var standardDatePropCnt = Object.keys(standardDateProps).length;
+ if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
+ return function (date) {
+ return formatTimeZoneOffset(date.timeZoneOffset);
+ };
+ }
+ if (standardDatePropCnt === 0 && extendedSettings.week) {
+ return function (date) {
+ return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekLabel, context.locale, extendedSettings.week);
+ };
+ }
+ return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
+ }
+ function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
+ standardDateProps = __assign({}, standardDateProps); // copy
+ extendedSettings = __assign({}, extendedSettings); // copy
+ sanitizeSettings(standardDateProps, extendedSettings);
+ standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
+ var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
+ var zeroFormat; // needed?
+ if (extendedSettings.omitZeroMinute) {
+ var zeroProps = __assign({}, standardDateProps);
+ delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
+ zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
+ }
+ return function (date) {
+ var marker = date.marker;
+ var format;
+ if (zeroFormat && !marker.getUTCMinutes()) {
+ format = zeroFormat;
+ }
+ else {
+ format = normalFormat;
+ }
+ var s = format.format(marker);
+ return postProcess(s, date, standardDateProps, extendedSettings, context);
+ };
+ }
+ function sanitizeSettings(standardDateProps, extendedSettings) {
+ // deal with a browser inconsistency where formatting the timezone
+ // requires that the hour/minute be present.
+ if (standardDateProps.timeZoneName) {
+ if (!standardDateProps.hour) {
+ standardDateProps.hour = '2-digit';
+ }
+ if (!standardDateProps.minute) {
+ standardDateProps.minute = '2-digit';
+ }
+ }
+ // only support short timezone names
+ if (standardDateProps.timeZoneName === 'long') {
+ standardDateProps.timeZoneName = 'short';
+ }
+ // if requesting to display seconds, MUST display minutes
+ if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
+ delete extendedSettings.omitZeroMinute;
+ }
+ }
+ function postProcess(s, date, standardDateProps, extendedSettings, context) {
+ s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
+ if (standardDateProps.timeZoneName === 'short') {
+ s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
+ 'UTC' : // important to normalize for IE, which does "GMT"
+ formatTimeZoneOffset(date.timeZoneOffset));
+ }
+ if (extendedSettings.omitCommas) {
+ s = s.replace(COMMA_RE, '').trim();
+ }
+ if (extendedSettings.omitZeroMinute) {
+ s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
+ }
+ // ^ do anything that might create adjacent spaces before this point,
+ // because MERIDIEM_RE likes to eat up loading spaces
+ if (extendedSettings.meridiem === false) {
+ s = s.replace(MERIDIEM_RE, '').trim();
+ }
+ else if (extendedSettings.meridiem === 'narrow') { // a/p
+ s = s.replace(MERIDIEM_RE, function (m0, m1) {
+ return m1.toLocaleLowerCase();
+ });
+ }
+ else if (extendedSettings.meridiem === 'short') { // am/pm
+ s = s.replace(MERIDIEM_RE, function (m0, m1) {
+ return m1.toLocaleLowerCase() + 'm';
+ });
+ }
+ else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
+ s = s.replace(MERIDIEM_RE, function (m0) {
+ return m0.toLocaleLowerCase();
+ });
+ }
+ s = s.replace(MULTI_SPACE_RE, ' ');
+ s = s.trim();
+ return s;
+ }
+ function injectTzoStr(s, tzoStr) {
+ var replaced = false;
+ s = s.replace(UTC_RE, function () {
+ replaced = true;
+ return tzoStr;
+ });
+ // IE11 doesn't include UTC/GMT in the original string, so append to end
+ if (!replaced) {
+ s += ' ' + tzoStr;
+ }
+ return s;
+ }
+ function formatWeekNumber(num, weekLabel, locale, display) {
+ var parts = [];
+ if (display === 'narrow') {
+ parts.push(weekLabel);
+ }
+ else if (display === 'short') {
+ parts.push(weekLabel, ' ');
+ }
+ // otherwise, considered 'numeric'
+ parts.push(locale.simpleNumberFormat.format(num));
+ if (locale.options.isRtl) { // TODO: use control characters instead?
+ parts.reverse();
+ }
+ return parts.join('');
+ }
+ // Range Formatting Utils
+ // 0 = exactly the same
+ // 1 = different by time
+ // and bigger
+ function computeMarkerDiffSeverity(d0, d1, ca) {
+ if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
+ return 5;
+ }
+ if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
+ return 4;
+ }
+ if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
+ return 2;
+ }
+ if (timeAsMs(d0) !== timeAsMs(d1)) {
+ return 1;
+ }
+ return 0;
+ }
+ function computePartialFormattingOptions(options, biggestUnit) {
+ var partialOptions = {};
+ for (var name_2 in options) {
+ if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
+ STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
+ partialOptions[name_2] = options[name_2];
+ }
+ }
+ return partialOptions;
+ }
+ function findCommonInsertion(full0, partial0, full1, partial1) {
+ var i0 = 0;
+ while (i0 < full0.length) {
+ var found0 = full0.indexOf(partial0, i0);
+ if (found0 === -1) {
+ break;
+ }
+ var before0 = full0.substr(0, found0);
+ i0 = found0 + partial0.length;
+ var after0 = full0.substr(i0);
+ var i1 = 0;
+ while (i1 < full1.length) {
+ var found1 = full1.indexOf(partial1, i1);
+ if (found1 === -1) {
+ break;
+ }
+ var before1 = full1.substr(0, found1);
+ i1 = found1 + partial1.length;
+ var after1 = full1.substr(i1);
+ if (before0 === before1 && after0 === after1) {
+ return {
+ before: before0,
+ after: after0
+ };
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ TODO: fix the terminology of "formatter" vs "formatting func"
+ */
+ /*
+ At the time of instantiation, this object does not know which cmd-formatting system it will use.
+ It receives this at the time of formatting, as a setting.
+ */
+ var CmdFormatter = /** @class */ (function () {
+ function CmdFormatter(cmdStr, separator) {
+ this.cmdStr = cmdStr;
+ this.separator = separator;
+ }
+ CmdFormatter.prototype.format = function (date, context) {
+ return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, this.separator));
+ };
+ CmdFormatter.prototype.formatRange = function (start, end, context) {
+ return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, this.separator));
+ };
+ return CmdFormatter;
+ }());
+
+ var FuncFormatter = /** @class */ (function () {
+ function FuncFormatter(func) {
+ this.func = func;
+ }
+ FuncFormatter.prototype.format = function (date, context) {
+ return this.func(createVerboseFormattingArg(date, null, context));
+ };
+ FuncFormatter.prototype.formatRange = function (start, end, context) {
+ return this.func(createVerboseFormattingArg(start, end, context));
+ };
+ return FuncFormatter;
+ }());
+
+ // Formatter Object Creation
+ function createFormatter(input, defaultSeparator) {
+ if (typeof input === 'object' && input) { // non-null object
+ if (typeof defaultSeparator === 'string') {
+ input = __assign({ separator: defaultSeparator }, input);
+ }
+ return new NativeFormatter(input);
+ }
+ else if (typeof input === 'string') {
+ return new CmdFormatter(input, defaultSeparator);
+ }
+ else if (typeof input === 'function') {
+ return new FuncFormatter(input);
+ }
+ }
+ // String Utils
+ // timeZoneOffset is in minutes
+ function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
+ if (stripZeroTime === void 0) { stripZeroTime = false; }
+ var s = marker.toISOString();
+ s = s.replace('.000', '');
+ if (stripZeroTime) {
+ s = s.replace('T00:00:00Z', '');
+ }
+ if (s.length > 10) { // time part wasn't stripped, can add timezone info
+ if (timeZoneOffset == null) {
+ s = s.replace('Z', '');
+ }
+ else if (timeZoneOffset !== 0) {
+ s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
+ }
+ // otherwise, its UTC-0 and we want to keep the Z
+ }
+ return s;
+ }
+ function formatIsoTimeString(marker) {
+ return padStart(marker.getUTCHours(), 2) + ':' +
+ padStart(marker.getUTCMinutes(), 2) + ':' +
+ padStart(marker.getUTCSeconds(), 2);
+ }
+ function formatTimeZoneOffset(minutes, doIso) {
+ if (doIso === void 0) { doIso = false; }
+ var sign = minutes < 0 ? '-' : '+';
+ var abs = Math.abs(minutes);
+ var hours = Math.floor(abs / 60);
+ var mins = Math.round(abs % 60);
+ if (doIso) {
+ return sign + padStart(hours, 2) + ':' + padStart(mins, 2);
+ }
+ else {
+ return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '');
+ }
+ }
+ // Arg Utils
+ function createVerboseFormattingArg(start, end, context, separator) {
+ var startInfo = expandZonedMarker(start, context.calendarSystem);
+ var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
+ return {
+ date: startInfo,
+ start: startInfo,
+ end: endInfo,
+ timeZone: context.timeZone,
+ localeCodes: context.locale.codes,
+ separator: separator
+ };
+ }
+ function expandZonedMarker(dateInfo, calendarSystem) {
+ var a = calendarSystem.markerToArray(dateInfo.marker);
+ return {
+ marker: dateInfo.marker,
+ timeZoneOffset: dateInfo.timeZoneOffset,
+ array: a,
+ year: a[0],
+ month: a[1],
+ day: a[2],
+ hour: a[3],
+ minute: a[4],
+ second: a[5],
+ millisecond: a[6]
+ };
+ }
+
+ var EventSourceApi = /** @class */ (function () {
+ function EventSourceApi(calendar, internalEventSource) {
+ this.calendar = calendar;
+ this.internalEventSource = internalEventSource;
+ }
+ EventSourceApi.prototype.remove = function () {
+ this.calendar.dispatch({
+ type: 'REMOVE_EVENT_SOURCE',
+ sourceId: this.internalEventSource.sourceId
+ });
+ };
+ EventSourceApi.prototype.refetch = function () {
+ this.calendar.dispatch({
+ type: 'FETCH_EVENT_SOURCES',
+ sourceIds: [this.internalEventSource.sourceId]
+ });
+ };
+ Object.defineProperty(EventSourceApi.prototype, "id", {
+ get: function () {
+ return this.internalEventSource.publicId;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventSourceApi.prototype, "url", {
+ // only relevant to json-feed event sources
+ get: function () {
+ return this.internalEventSource.meta.url;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ return EventSourceApi;
+ }());
+
+ var EventApi = /** @class */ (function () {
+ function EventApi(calendar, def, instance) {
+ this._calendar = calendar;
+ this._def = def;
+ this._instance = instance || null;
+ }
+ /*
+ TODO: make event struct more responsible for this
+ */
+ EventApi.prototype.setProp = function (name, val) {
+ var _a, _b;
+ if (name in DATE_PROPS) ;
+ else if (name in NON_DATE_PROPS) {
+ if (typeof NON_DATE_PROPS[name] === 'function') {
+ val = NON_DATE_PROPS[name](val);
+ }
+ this.mutate({
+ standardProps: (_a = {}, _a[name] = val, _a)
+ });
+ }
+ else if (name in UNSCOPED_EVENT_UI_PROPS) {
+ var ui = void 0;
+ if (typeof UNSCOPED_EVENT_UI_PROPS[name] === 'function') {
+ val = UNSCOPED_EVENT_UI_PROPS[name](val);
+ }
+ if (name === 'color') {
+ ui = { backgroundColor: val, borderColor: val };
+ }
+ else if (name === 'editable') {
+ ui = { startEditable: val, durationEditable: val };
+ }
+ else {
+ ui = (_b = {}, _b[name] = val, _b);
+ }
+ this.mutate({
+ standardProps: { ui: ui }
+ });
+ }
+ };
+ EventApi.prototype.setExtendedProp = function (name, val) {
+ var _a;
+ this.mutate({
+ extendedProps: (_a = {}, _a[name] = val, _a)
+ });
+ };
+ EventApi.prototype.setStart = function (startInput, options) {
+ if (options === void 0) { options = {}; }
+ var dateEnv = this._calendar.dateEnv;
+ var start = dateEnv.createMarker(startInput);
+ if (start && this._instance) { // TODO: warning if parsed bad
+ var instanceRange = this._instance.range;
+ var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
+ var endDelta = null;
+ if (options.maintainDuration) {
+ var origDuration = diffDates(instanceRange.start, instanceRange.end, dateEnv, options.granularity);
+ var newDuration = diffDates(start, instanceRange.end, dateEnv, options.granularity);
+ endDelta = subtractDurations(origDuration, newDuration);
+ }
+ this.mutate({ startDelta: startDelta, endDelta: endDelta });
+ }
+ };
+ EventApi.prototype.setEnd = function (endInput, options) {
+ if (options === void 0) { options = {}; }
+ var dateEnv = this._calendar.dateEnv;
+ var end;
+ if (endInput != null) {
+ end = dateEnv.createMarker(endInput);
+ if (!end) {
+ return; // TODO: warning if parsed bad
+ }
+ }
+ if (this._instance) {
+ if (end) {
+ var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
+ this.mutate({ endDelta: endDelta });
+ }
+ else {
+ this.mutate({ standardProps: { hasEnd: false } });
+ }
+ }
+ };
+ EventApi.prototype.setDates = function (startInput, endInput, options) {
+ if (options === void 0) { options = {}; }
+ var dateEnv = this._calendar.dateEnv;
+ var standardProps = { allDay: options.allDay };
+ var start = dateEnv.createMarker(startInput);
+ var end;
+ if (!start) {
+ return; // TODO: warning if parsed bad
+ }
+ if (endInput != null) {
+ end = dateEnv.createMarker(endInput);
+ if (!end) { // TODO: warning if parsed bad
+ return;
+ }
+ }
+ if (this._instance) {
+ var instanceRange = this._instance.range;
+ // when computing the diff for an event being converted to all-day,
+ // compute diff off of the all-day values the way event-mutation does.
+ if (options.allDay === true) {
+ instanceRange = computeAlignedDayRange(instanceRange);
+ }
+ var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
+ if (end) {
+ var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
+ this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
+ }
+ else {
+ standardProps.hasEnd = false;
+ this.mutate({ startDelta: startDelta, standardProps: standardProps });
+ }
+ }
+ };
+ EventApi.prototype.moveStart = function (deltaInput) {
+ var delta = createDuration(deltaInput);
+ if (delta) { // TODO: warning if parsed bad
+ this.mutate({ startDelta: delta });
+ }
+ };
+ EventApi.prototype.moveEnd = function (deltaInput) {
+ var delta = createDuration(deltaInput);
+ if (delta) { // TODO: warning if parsed bad
+ this.mutate({ endDelta: delta });
+ }
+ };
+ EventApi.prototype.moveDates = function (deltaInput) {
+ var delta = createDuration(deltaInput);
+ if (delta) { // TODO: warning if parsed bad
+ this.mutate({ startDelta: delta, endDelta: delta });
+ }
+ };
+ EventApi.prototype.setAllDay = function (allDay, options) {
+ if (options === void 0) { options = {}; }
+ var standardProps = { allDay: allDay };
+ var maintainDuration = options.maintainDuration;
+ if (maintainDuration == null) {
+ maintainDuration = this._calendar.opt('allDayMaintainDuration');
+ }
+ if (this._def.allDay !== allDay) {
+ standardProps.hasEnd = maintainDuration;
+ }
+ this.mutate({ standardProps: standardProps });
+ };
+ EventApi.prototype.formatRange = function (formatInput) {
+ var dateEnv = this._calendar.dateEnv;
+ var instance = this._instance;
+ var formatter = createFormatter(formatInput, this._calendar.opt('defaultRangeSeparator'));
+ if (this._def.hasEnd) {
+ return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
+ forcedStartTzo: instance.forcedStartTzo,
+ forcedEndTzo: instance.forcedEndTzo
+ });
+ }
+ else {
+ return dateEnv.format(instance.range.start, formatter, {
+ forcedTzo: instance.forcedStartTzo
+ });
+ }
+ };
+ EventApi.prototype.mutate = function (mutation) {
+ var def = this._def;
+ var instance = this._instance;
+ if (instance) {
+ this._calendar.dispatch({
+ type: 'MUTATE_EVENTS',
+ instanceId: instance.instanceId,
+ mutation: mutation,
+ fromApi: true
+ });
+ var eventStore = this._calendar.state.eventStore;
+ this._def = eventStore.defs[def.defId];
+ this._instance = eventStore.instances[instance.instanceId];
+ }
+ };
+ EventApi.prototype.remove = function () {
+ this._calendar.dispatch({
+ type: 'REMOVE_EVENT_DEF',
+ defId: this._def.defId
+ });
+ };
+ Object.defineProperty(EventApi.prototype, "source", {
+ get: function () {
+ var sourceId = this._def.sourceId;
+ if (sourceId) {
+ return new EventSourceApi(this._calendar, this._calendar.state.eventSources[sourceId]);
+ }
+ return null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "start", {
+ get: function () {
+ return this._instance ?
+ this._calendar.dateEnv.toDate(this._instance.range.start) :
+ null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "end", {
+ get: function () {
+ return (this._instance && this._def.hasEnd) ?
+ this._calendar.dateEnv.toDate(this._instance.range.end) :
+ null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "id", {
+ // computable props that all access the def
+ // TODO: find a TypeScript-compatible way to do this at scale
+ get: function () { return this._def.publicId; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "groupId", {
+ get: function () { return this._def.groupId; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "allDay", {
+ get: function () { return this._def.allDay; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "title", {
+ get: function () { return this._def.title; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "url", {
+ get: function () { return this._def.url; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "rendering", {
+ get: function () { return this._def.rendering; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "startEditable", {
+ get: function () { return this._def.ui.startEditable; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "durationEditable", {
+ get: function () { return this._def.ui.durationEditable; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "constraint", {
+ get: function () { return this._def.ui.constraints[0] || null; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "overlap", {
+ get: function () { return this._def.ui.overlap; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "allow", {
+ get: function () { return this._def.ui.allows[0] || null; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "backgroundColor", {
+ get: function () { return this._def.ui.backgroundColor; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "borderColor", {
+ get: function () { return this._def.ui.borderColor; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "textColor", {
+ get: function () { return this._def.ui.textColor; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "classNames", {
+ // NOTE: user can't modify these because Object.freeze was called in event-def parsing
+ get: function () { return this._def.ui.classNames; },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(EventApi.prototype, "extendedProps", {
+ get: function () { return this._def.extendedProps; },
+ enumerable: true,
+ configurable: true
+ });
+ return EventApi;
+ }());
+
+ /*
+ Specifying nextDayThreshold signals that all-day ranges should be sliced.
+ */
+ function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
+ var inverseBgByGroupId = {};
+ var inverseBgByDefId = {};
+ var defByGroupId = {};
+ var bgRanges = [];
+ var fgRanges = [];
+ var eventUis = compileEventUis(eventStore.defs, eventUiBases);
+ for (var defId in eventStore.defs) {
+ var def = eventStore.defs[defId];
+ if (def.rendering === 'inverse-background') {
+ if (def.groupId) {
+ inverseBgByGroupId[def.groupId] = [];
+ if (!defByGroupId[def.groupId]) {
+ defByGroupId[def.groupId] = def;
+ }
+ }
+ else {
+ inverseBgByDefId[defId] = [];
+ }
+ }
+ }
+ for (var instanceId in eventStore.instances) {
+ var instance = eventStore.instances[instanceId];
+ var def = eventStore.defs[instance.defId];
+ var ui = eventUis[def.defId];
+ var origRange = instance.range;
+ var normalRange = (!def.allDay && nextDayThreshold) ?
+ computeVisibleDayRange(origRange, nextDayThreshold) :
+ origRange;
+ var slicedRange = intersectRanges(normalRange, framingRange);
+ if (slicedRange) {
+ if (def.rendering === 'inverse-background') {
+ if (def.groupId) {
+ inverseBgByGroupId[def.groupId].push(slicedRange);
+ }
+ else {
+ inverseBgByDefId[instance.defId].push(slicedRange);
+ }
+ }
+ else {
+ (def.rendering === 'background' ? bgRanges : fgRanges).push({
+ def: def,
+ ui: ui,
+ instance: instance,
+ range: slicedRange,
+ isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
+ isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
+ });
+ }
+ }
+ }
+ for (var groupId in inverseBgByGroupId) { // BY GROUP
+ var ranges = inverseBgByGroupId[groupId];
+ var invertedRanges = invertRanges(ranges, framingRange);
+ for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
+ var invertedRange = invertedRanges_1[_i];
+ var def = defByGroupId[groupId];
+ var ui = eventUis[def.defId];
+ bgRanges.push({
+ def: def,
+ ui: ui,
+ instance: null,
+ range: invertedRange,
+ isStart: false,
+ isEnd: false
+ });
+ }
+ }
+ for (var defId in inverseBgByDefId) {
+ var ranges = inverseBgByDefId[defId];
+ var invertedRanges = invertRanges(ranges, framingRange);
+ for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
+ var invertedRange = invertedRanges_2[_a];
+ bgRanges.push({
+ def: eventStore.defs[defId],
+ ui: eventUis[defId],
+ instance: null,
+ range: invertedRange,
+ isStart: false,
+ isEnd: false
+ });
+ }
+ }
+ return { bg: bgRanges, fg: fgRanges };
+ }
+ function hasBgRendering(def) {
+ return def.rendering === 'background' || def.rendering === 'inverse-background';
+ }
+ function filterSegsViaEls(view, segs, isMirror) {
+ if (view.hasPublicHandlers('eventRender')) {
+ segs = segs.filter(function (seg) {
+ var custom = view.publiclyTrigger('eventRender', [
+ {
+ event: new EventApi(view.calendar, seg.eventRange.def, seg.eventRange.instance),
+ isMirror: isMirror,
+ isStart: seg.isStart,
+ isEnd: seg.isEnd,
+ // TODO: include seg.range once all components consistently generate it
+ el: seg.el,
+ view: view
+ }
+ ]);
+ if (custom === false) { // means don't render at all
+ return false;
+ }
+ else if (custom && custom !== true) {
+ seg.el = custom;
+ }
+ return true;
+ });
+ }
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+ var seg = segs_1[_i];
+ setElSeg(seg.el, seg);
+ }
+ return segs;
+ }
+ function setElSeg(el, seg) {
+ el.fcSeg = seg;
+ }
+ function getElSeg(el) {
+ return el.fcSeg || null;
+ }
+ // event ui computation
+ function compileEventUis(eventDefs, eventUiBases) {
+ return mapHash(eventDefs, function (eventDef) {
+ return compileEventUi(eventDef, eventUiBases);
+ });
+ }
+ function compileEventUi(eventDef, eventUiBases) {
+ var uis = [];
+ if (eventUiBases['']) {
+ uis.push(eventUiBases['']);
+ }
+ if (eventUiBases[eventDef.defId]) {
+ uis.push(eventUiBases[eventDef.defId]);
+ }
+ uis.push(eventDef.ui);
+ return combineEventUis(uis);
+ }
+
+ // applies the mutation to ALL defs/instances within the event store
+ function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) {
+ var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
+ var dest = createEmptyEventStore();
+ for (var defId in eventStore.defs) {
+ var def = eventStore.defs[defId];
+ dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar);
+ }
+ for (var instanceId in eventStore.instances) {
+ var instance = eventStore.instances[instanceId];
+ var def = dest.defs[instance.defId]; // important to grab the newly modified def
+ dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar);
+ }
+ return dest;
+ }
+ function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) {
+ var standardProps = mutation.standardProps || {};
+ // if hasEnd has not been specified, guess a good value based on deltas.
+ // if duration will change, there's no way the default duration will persist,
+ // and thus, we need to mark the event as having a real end
+ if (standardProps.hasEnd == null &&
+ eventConfig.durationEditable &&
+ willDeltasAffectDuration(eventConfig.startEditable ? mutation.startDelta : null, mutation.endDelta || null)) {
+ standardProps.hasEnd = true; // TODO: is this mutation okay?
+ }
+ var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) });
+ if (mutation.extendedProps) {
+ copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps);
+ }
+ for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) {
+ var applier = appliers_1[_i];
+ applier(copy, mutation, calendar);
+ }
+ if (!copy.hasEnd && calendar.opt('forceEventDuration')) {
+ copy.hasEnd = true;
+ }
+ return copy;
+ }
+ function willDeltasAffectDuration(startDelta, endDelta) {
+ if (startDelta && !asRoughMs(startDelta)) {
+ startDelta = null;
+ }
+ if (endDelta && !asRoughMs(endDelta)) {
+ endDelta = null;
+ }
+ if (!startDelta && !endDelta) {
+ return false;
+ }
+ if (Boolean(startDelta) !== Boolean(endDelta)) {
+ return true;
+ }
+ return !durationsEqual(startDelta, endDelta);
+ }
+ function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
+ eventConfig, mutation, calendar) {
+ var dateEnv = calendar.dateEnv;
+ var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
+ var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
+ var copy = __assign({}, eventInstance);
+ if (forceAllDay) {
+ copy.range = computeAlignedDayRange(copy.range);
+ }
+ if (mutation.startDelta && eventConfig.startEditable) {
+ copy.range = {
+ start: dateEnv.add(copy.range.start, mutation.startDelta),
+ end: copy.range.end
+ };
+ }
+ if (clearEnd) {
+ copy.range = {
+ start: copy.range.start,
+ end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start)
+ };
+ }
+ else if (mutation.endDelta &&
+ (eventConfig.durationEditable ||
+ !willDeltasAffectDuration(// TODO: nonDRY logic above
+ eventConfig.startEditable ? mutation.startDelta : null, mutation.endDelta))) {
+ copy.range = {
+ start: copy.range.start,
+ end: dateEnv.add(copy.range.end, mutation.endDelta)
+ };
+ }
+ // in case event was all-day but the supplied deltas were not
+ // better util for this?
+ if (eventDef.allDay) {
+ copy.range = {
+ start: startOfDay(copy.range.start),
+ end: startOfDay(copy.range.end)
+ };
+ }
+ // handle invalid durations
+ if (copy.range.end < copy.range.start) {
+ copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start);
+ }
+ return copy;
+ }
+
+ function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) {
+ switch (action.type) {
+ case 'RECEIVE_EVENTS': // raw
+ return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar);
+ case 'ADD_EVENTS': // already parsed, but not expanded
+ return addEvent(eventStore, action.eventStore, // new ones
+ dateProfile ? dateProfile.activeRange : null, calendar);
+ case 'MERGE_EVENTS': // already parsed and expanded
+ return mergeEventStores(eventStore, action.eventStore);
+ case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
+ case 'NEXT':
+ case 'SET_DATE':
+ case 'SET_VIEW_TYPE':
+ if (dateProfile) {
+ return expandRecurring(eventStore, dateProfile.activeRange, calendar);
+ }
+ else {
+ return eventStore;
+ }
+ case 'CHANGE_TIMEZONE':
+ return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv);
+ case 'MUTATE_EVENTS':
+ return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
+ case 'REMOVE_EVENT_INSTANCES':
+ return excludeInstances(eventStore, action.instances);
+ case 'REMOVE_EVENT_DEF':
+ return filterEventStoreDefs(eventStore, function (eventDef) {
+ return eventDef.defId !== action.defId;
+ });
+ case 'REMOVE_EVENT_SOURCE':
+ return excludeEventsBySourceId(eventStore, action.sourceId);
+ case 'REMOVE_ALL_EVENT_SOURCES':
+ return filterEventStoreDefs(eventStore, function (eventDef) {
+ return !eventDef.sourceId; // only keep events with no source id
+ });
+ case 'REMOVE_ALL_EVENTS':
+ return createEmptyEventStore();
+ case 'RESET_EVENTS':
+ return {
+ defs: eventStore.defs,
+ instances: eventStore.instances
+ };
+ default:
+ return eventStore;
+ }
+ }
+ function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) {
+ if (eventSource && // not already removed
+ fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
+ ) {
+ var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar);
+ if (fetchRange) {
+ subset = expandRecurring(subset, fetchRange, calendar);
+ }
+ return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
+ }
+ return eventStore;
+ }
+ function addEvent(eventStore, subset, expandRange, calendar) {
+ if (expandRange) {
+ subset = expandRecurring(subset, expandRange, calendar);
+ }
+ return mergeEventStores(eventStore, subset);
+ }
+ function rezoneDates(eventStore, oldDateEnv, newDateEnv) {
+ var defs = eventStore.defs;
+ var instances = mapHash(eventStore.instances, function (instance) {
+ var def = defs[instance.defId];
+ if (def.allDay || def.recurringDef) {
+ return instance; // isn't dependent on timezone
+ }
+ else {
+ return __assign({}, instance, { range: {
+ start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
+ end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
+ }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
+ }
+ });
+ return { defs: defs, instances: instances };
+ }
+ function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) {
+ var relevant = getRelevantEvents(eventStore, instanceId);
+ var eventConfigBase = fromApi ?
+ { '': {
+ startEditable: true,
+ durationEditable: true,
+ constraints: [],
+ overlap: null,
+ allows: [],
+ backgroundColor: '',
+ borderColor: '',
+ textColor: '',
+ classNames: []
+ } } :
+ calendar.eventUiBases;
+ relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar);
+ return mergeEventStores(eventStore, relevant);
+ }
+ function excludeEventsBySourceId(eventStore, sourceId) {
+ return filterEventStoreDefs(eventStore, function (eventDef) {
+ return eventDef.sourceId !== sourceId;
+ });
+ }
+ // QUESTION: why not just return instances? do a general object-property-exclusion util
+ function excludeInstances(eventStore, removals) {
+ return {
+ defs: eventStore.defs,
+ instances: filterHash(eventStore.instances, function (instance) {
+ return !removals[instance.instanceId];
+ })
+ };
+ }
+
+ // high-level segmenting-aware tester functions
+ // ------------------------------------------------------------------------------------------------------------------------
+ function isInteractionValid(interaction, calendar) {
+ return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions
+ }
+ function isDateSelectionValid(dateSelection, calendar) {
+ return isNewPropsValid({ dateSelection: dateSelection }, calendar);
+ }
+ function isNewPropsValid(newProps, calendar) {
+ var view = calendar.view;
+ var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
+ return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar);
+ }
+ function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
+ if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
+ if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
+ return false;
+ }
+ if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
+ return false;
+ }
+ return true;
+ }
+ // Moving Event Validation
+ // ------------------------------------------------------------------------------------------------------------------------
+ function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
+ var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
+ var subjectEventStore = interaction.mutatedEvents;
+ var subjectDefs = subjectEventStore.defs;
+ var subjectInstances = subjectEventStore.instances;
+ var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
+ state.eventUiBases :
+ { '': calendar.selectionConfig } // if not a real event, validate as a selection
+ );
+ if (filterConfig) {
+ subjectConfigs = mapHash(subjectConfigs, filterConfig);
+ }
+ var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
+ var otherDefs = otherEventStore.defs;
+ var otherInstances = otherEventStore.instances;
+ var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
+ for (var subjectInstanceId in subjectInstances) {
+ var subjectInstance = subjectInstances[subjectInstanceId];
+ var subjectRange = subjectInstance.range;
+ var subjectConfig = subjectConfigs[subjectInstance.defId];
+ var subjectDef = subjectDefs[subjectInstance.defId];
+ // constraint
+ if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) {
+ return false;
+ }
+ // overlap
+ var overlapFunc = calendar.opt('eventOverlap');
+ if (typeof overlapFunc !== 'function') {
+ overlapFunc = null;
+ }
+ for (var otherInstanceId in otherInstances) {
+ var otherInstance = otherInstances[otherInstanceId];
+ // intersect! evaluate
+ if (rangesIntersect(subjectRange, otherInstance.range)) {
+ var otherOverlap = otherConfigs[otherInstance.defId].overlap;
+ // consider the other event's overlap. only do this if the subject event is a "real" event
+ if (otherOverlap === false && interaction.isEvent) {
+ return false;
+ }
+ if (subjectConfig.overlap === false) {
+ return false;
+ }
+ if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event
+ new EventApi(calendar, subjectDef, subjectInstance) // moving event
+ )) {
+ return false;
+ }
+ }
+ }
+ // allow (a function)
+ for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
+ var subjectAllow = _a[_i];
+ var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay });
+ var origDef = state.eventStore.defs[subjectDef.defId];
+ var origInstance = state.eventStore.instances[subjectInstanceId];
+ var eventApi = void 0;
+ if (origDef) { // was previously in the calendar
+ eventApi = new EventApi(calendar, origDef, origInstance);
+ }
+ else { // was an external event
+ eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates
+ }
+ if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ // Date Selection Validation
+ // ------------------------------------------------------------------------------------------------------------------------
+ function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
+ var relevantEventStore = state.eventStore;
+ var relevantDefs = relevantEventStore.defs;
+ var relevantInstances = relevantEventStore.instances;
+ var selection = state.dateSelection;
+ var selectionRange = selection.range;
+ var selectionConfig = calendar.selectionConfig;
+ if (filterConfig) {
+ selectionConfig = filterConfig(selectionConfig);
+ }
+ // constraint
+ if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) {
+ return false;
+ }
+ // overlap
+ var overlapFunc = calendar.opt('selectOverlap');
+ if (typeof overlapFunc !== 'function') {
+ overlapFunc = null;
+ }
+ for (var relevantInstanceId in relevantInstances) {
+ var relevantInstance = relevantInstances[relevantInstanceId];
+ // intersect! evaluate
+ if (rangesIntersect(selectionRange, relevantInstance.range)) {
+ if (selectionConfig.overlap === false) {
+ return false;
+ }
+ if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) {
+ return false;
+ }
+ }
+ }
+ // allow (a function)
+ for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
+ var selectionAllow = _a[_i];
+ var fullDateSpan = __assign({}, dateSpanMeta, selection);
+ if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // Constraint Utils
+ // ------------------------------------------------------------------------------------------------------------------------
+ function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) {
+ for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
+ var constraint = constraints_1[_i];
+ if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
+ otherEventStore, // for if constraint is an even group ID
+ businessHoursUnexpanded, // for if constraint is 'businessHours'
+ calendar // for expanding businesshours
+ ) {
+ if (constraint === 'businessHours') {
+ return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar));
+ }
+ else if (typeof constraint === 'string') { // an group ID
+ return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
+ return eventDef.groupId === constraint;
+ }));
+ }
+ else if (typeof constraint === 'object' && constraint) { // non-null object
+ return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar));
+ }
+ return []; // if it's false
+ }
+ // TODO: move to event-store file?
+ function eventStoreToRanges(eventStore) {
+ var instances = eventStore.instances;
+ var ranges = [];
+ for (var instanceId in instances) {
+ ranges.push(instances[instanceId].range);
+ }
+ return ranges;
+ }
+ // TODO: move to geom file?
+ function anyRangesContainRange(outerRanges, innerRange) {
+ for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
+ var outerRange = outerRanges_1[_i];
+ if (rangeContainsRange(outerRange, innerRange)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Parsing
+ // ------------------------------------------------------------------------------------------------------------------------
+ function normalizeConstraint(input, calendar) {
+ if (Array.isArray(input)) {
+ return parseEvents(input, '', calendar, true); // allowOpenRange=true
+ }
+ else if (typeof input === 'object' && input) { // non-null object
+ return parseEvents([input], '', calendar, true); // allowOpenRange=true
+ }
+ else if (input != null) {
+ return String(input);
+ }
+ else {
+ return null;
+ }
+ }
+
+ function htmlEscape(s) {
+ return (s + '').replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/'/g, '&#039;')
+ .replace(/"/g, '&quot;')
+ .replace(/\n/g, '<br />');
+ }
+ // Given a hash of CSS properties, returns a string of CSS.
+ // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
+ function cssToStr(cssProps) {
+ var statements = [];
+ for (var name_1 in cssProps) {
+ var val = cssProps[name_1];
+ if (val != null && val !== '') {
+ statements.push(name_1 + ':' + val);
+ }
+ }
+ return statements.join(';');
+ }
+ // Given an object hash of HTML attribute names to values,
+ // generates a string that can be injected between < > in HTML
+ function attrsToStr(attrs) {
+ var parts = [];
+ for (var name_2 in attrs) {
+ var val = attrs[name_2];
+ if (val != null) {
+ parts.push(name_2 + '="' + htmlEscape(val) + '"');
+ }
+ }
+ return parts.join(' ');
+ }
+ function parseClassName(raw) {
+ if (Array.isArray(raw)) {
+ return raw;
+ }
+ else if (typeof raw === 'string') {
+ return raw.split(/\s+/);
+ }
+ else {
+ return [];
+ }
+ }
+
+ var UNSCOPED_EVENT_UI_PROPS = {
+ editable: Boolean,
+ startEditable: Boolean,
+ durationEditable: Boolean,
+ constraint: null,
+ overlap: null,
+ allow: null,
+ className: parseClassName,
+ classNames: parseClassName,
+ color: String,
+ backgroundColor: String,
+ borderColor: String,
+ textColor: String
+ };
+ function processUnscopedUiProps(rawProps, calendar, leftovers) {
+ var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers);
+ var constraint = normalizeConstraint(props.constraint, calendar);
+ return {
+ startEditable: props.startEditable != null ? props.startEditable : props.editable,
+ durationEditable: props.durationEditable != null ? props.durationEditable : props.editable,
+ constraints: constraint != null ? [constraint] : [],
+ overlap: props.overlap,
+ allows: props.allow != null ? [props.allow] : [],
+ backgroundColor: props.backgroundColor || props.color,
+ borderColor: props.borderColor || props.color,
+ textColor: props.textColor,
+ classNames: props.classNames.concat(props.className)
+ };
+ }
+ function processScopedUiProps(prefix, rawScoped, calendar, leftovers) {
+ var rawUnscoped = {};
+ var wasFound = {};
+ for (var key in UNSCOPED_EVENT_UI_PROPS) {
+ var scopedKey = prefix + capitaliseFirstLetter(key);
+ rawUnscoped[key] = rawScoped[scopedKey];
+ wasFound[scopedKey] = true;
+ }
+ if (prefix === 'event') {
+ rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable'
+ }
+ if (leftovers) {
+ for (var key in rawScoped) {
+ if (!wasFound[key]) {
+ leftovers[key] = rawScoped[key];
+ }
+ }
+ }
+ return processUnscopedUiProps(rawUnscoped, calendar);
+ }
+ var EMPTY_EVENT_UI = {
+ startEditable: null,
+ durationEditable: null,
+ constraints: [],
+ overlap: null,
+ allows: [],
+ backgroundColor: '',
+ borderColor: '',
+ textColor: '',
+ classNames: []
+ };
+ // prevent against problems with <2 args!
+ function combineEventUis(uis) {
+ return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
+ }
+ function combineTwoEventUis(item0, item1) {
+ return {
+ startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
+ durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
+ constraints: item0.constraints.concat(item1.constraints),
+ overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
+ allows: item0.allows.concat(item1.allows),
+ backgroundColor: item1.backgroundColor || item0.backgroundColor,
+ borderColor: item1.borderColor || item0.borderColor,
+ textColor: item1.textColor || item0.textColor,
+ classNames: item0.classNames.concat(item1.classNames)
+ };
+ }
+
+ var NON_DATE_PROPS = {
+ id: String,
+ groupId: String,
+ title: String,
+ url: String,
+ rendering: String,
+ extendedProps: null
+ };
+ var DATE_PROPS = {
+ start: null,
+ date: null,
+ end: null,
+ allDay: null
+ };
+ var uid = 0;
+ function parseEvent(raw, sourceId, calendar, allowOpenRange) {
+ var allDayDefault = computeIsAllDayDefault(sourceId, calendar);
+ var leftovers0 = {};
+ var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out
+ allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props
+ );
+ if (recurringRes) {
+ var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar);
+ def.recurringDef = {
+ typeId: recurringRes.typeId,
+ typeData: recurringRes.typeData,
+ duration: recurringRes.duration
+ };
+ return { def: def, instance: null };
+ }
+ else {
+ var leftovers1 = {};
+ var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange);
+ if (singleRes) {
+ var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar);
+ var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
+ return { def: def, instance: instance };
+ }
+ }
+ return null;
+ }
+ /*
+ Will NOT populate extendedProps with the leftover properties.
+ Will NOT populate date-related props.
+ The EventNonDateInput has been normalized (id => publicId, etc).
+ */
+ function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) {
+ var leftovers = {};
+ var def = pluckNonDateProps(raw, calendar, leftovers);
+ def.defId = String(uid++);
+ def.sourceId = sourceId;
+ def.allDay = allDay;
+ def.hasEnd = hasEnd;
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) {
+ var eventDefParser = _a[_i];
+ var newLeftovers = {};
+ eventDefParser(def, leftovers, newLeftovers);
+ leftovers = newLeftovers;
+ }
+ def.extendedProps = __assign(leftovers, def.extendedProps || {});
+ // help out EventApi from having user modify props
+ Object.freeze(def.ui.classNames);
+ Object.freeze(def.extendedProps);
+ return def;
+ }
+ function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
+ return {
+ instanceId: String(uid++),
+ defId: defId,
+ range: range,
+ forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
+ forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
+ };
+ }
+ function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) {
+ var props = pluckDateProps(raw, leftovers);
+ var allDay = props.allDay;
+ var startMeta;
+ var startMarker = null;
+ var hasEnd = false;
+ var endMeta;
+ var endMarker = null;
+ startMeta = calendar.dateEnv.createMarkerMeta(props.start);
+ if (startMeta) {
+ startMarker = startMeta.marker;
+ }
+ else if (!allowOpenRange) {
+ return null;
+ }
+ if (props.end != null) {
+ endMeta = calendar.dateEnv.createMarkerMeta(props.end);
+ }
+ if (allDay == null) {
+ if (allDayDefault != null) {
+ allDay = allDayDefault;
+ }
+ else {
+ // fall back to the date props LAST
+ allDay = (!startMeta || startMeta.isTimeUnspecified) &&
+ (!endMeta || endMeta.isTimeUnspecified);
+ }
+ }
+ if (allDay && startMarker) {
+ startMarker = startOfDay(startMarker);
+ }
+ if (endMeta) {
+ endMarker = endMeta.marker;
+ if (allDay) {
+ endMarker = startOfDay(endMarker);
+ }
+ if (startMarker && endMarker <= startMarker) {
+ endMarker = null;
+ }
+ }
+ if (endMarker) {
+ hasEnd = true;
+ }
+ else if (!allowOpenRange) {
+ hasEnd = calendar.opt('forceEventDuration') || false;
+ endMarker = calendar.dateEnv.add(startMarker, allDay ?
+ calendar.defaultAllDayEventDuration :
+ calendar.defaultTimedEventDuration);
+ }
+ return {
+ allDay: allDay,
+ hasEnd: hasEnd,
+ range: { start: startMarker, end: endMarker },
+ forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
+ forcedEndTzo: endMeta ? endMeta.forcedTzo : null
+ };
+ }
+ function pluckDateProps(raw, leftovers) {
+ var props = refineProps(raw, DATE_PROPS, {}, leftovers);
+ props.start = (props.start !== null) ? props.start : props.date;
+ delete props.date;
+ return props;
+ }
+ function pluckNonDateProps(raw, calendar, leftovers) {
+ var preLeftovers = {};
+ var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers);
+ var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers);
+ props.publicId = props.id;
+ delete props.id;
+ props.ui = ui;
+ return props;
+ }
+ function computeIsAllDayDefault(sourceId, calendar) {
+ var res = null;
+ if (sourceId) {
+ var source = calendar.state.eventSources[sourceId];
+ res = source.allDayDefault;
+ }
+ if (res == null) {
+ res = calendar.opt('allDayDefault');
+ }
+ return res;
+ }
+
+ var DEF_DEFAULTS = {
+ startTime: '09:00',
+ endTime: '17:00',
+ daysOfWeek: [1, 2, 3, 4, 5],
+ rendering: 'inverse-background',
+ classNames: 'fc-nonbusiness',
+ groupId: '_businessHours' // so multiple defs get grouped
+ };
+ /*
+ TODO: pass around as EventDefHash!!!
+ */
+ function parseBusinessHours(input, calendar) {
+ return parseEvents(refineInputs(input), '', calendar);
+ }
+ function refineInputs(input) {
+ var rawDefs;
+ if (input === true) {
+ rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
+ }
+ else if (Array.isArray(input)) {
+ // if specifying an array, every sub-definition NEEDS a day-of-week
+ rawDefs = input.filter(function (rawDef) {
+ return rawDef.daysOfWeek;
+ });
+ }
+ else if (typeof input === 'object' && input) { // non-null object
+ rawDefs = [input];
+ }
+ else { // is probably false
+ rawDefs = [];
+ }
+ rawDefs = rawDefs.map(function (rawDef) {
+ return __assign({}, DEF_DEFAULTS, rawDef);
+ });
+ return rawDefs;
+ }
+
+ function memoizeRendering(renderFunc, unrenderFunc, dependencies) {
+ if (dependencies === void 0) { dependencies = []; }
+ var dependents = [];
+ var thisContext;
+ var prevArgs;
+ function unrender() {
+ if (prevArgs) {
+ for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) {
+ var dependent = dependents_1[_i];
+ dependent.unrender();
+ }
+ if (unrenderFunc) {
+ unrenderFunc.apply(thisContext, prevArgs);
+ }
+ prevArgs = null;
+ }
+ }
+ function res() {
+ if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
+ unrender();
+ thisContext = this;
+ prevArgs = arguments;
+ renderFunc.apply(this, arguments);
+ }
+ }
+ res.dependents = dependents;
+ res.unrender = unrender;
+ for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
+ var dependency = dependencies_1[_i];
+ dependency.dependents.push(res);
+ }
+ return res;
+ }
+
+ function isValuesSimilar(val0, val1, depth) {
+ if (depth === void 0) { depth = 1; }
+ if (val0 === val1) {
+ return true;
+ }
+ else if (Array.isArray(val0) && Array.isArray(val1)) {
+ return isArraysSimilar(val0, val1, depth);
+ }
+ else if (typeof val0 === 'object' && val0 && typeof val1 === 'object' && val1) { // non-null objects
+ return isObjectsSimilar(val0, val1, depth);
+ }
+ else {
+ return false;
+ }
+ }
+ function isArraysSimilar(a0, a1, depth) {
+ if (depth === void 0) { depth = 1; }
+ if (a0 === a1) {
+ return true;
+ }
+ else if (depth > 0) {
+ if (a0.length !== a1.length) {
+ return false;
+ }
+ else {
+ for (var i = 0; i < a0.length; i++) {
+ if (!isValuesSimilar(a0[i], a1[i], depth - 1)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ function isObjectsSimilar(obj0, obj1, depth) {
+ if (depth === void 0) { depth = 1; }
+ if (obj0 === obj1) {
+ return true;
+ }
+ else if (depth > 0) {
+ for (var prop in obj0) {
+ if (!(prop in obj1)) {
+ return false;
+ }
+ }
+ for (var prop in obj1) {
+ if (!(prop in obj0)) {
+ return false;
+ }
+ else {
+ if (!isValuesSimilar(obj0[prop], obj1[prop], depth - 1)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ function computeChangedProps(obj0, obj1, depth) {
+ if (depth === void 0) { depth = 1; }
+ var res = {};
+ for (var prop in obj1) {
+ if (!(prop in obj0) ||
+ !isValuesSimilar(obj0[prop], obj1[prop], depth - 1)) {
+ res[prop] = obj1[prop];
+ }
+ }
+ return res;
+ }
+ function anyKeysRemoved(obj0, obj1) {
+ for (var prop in obj0) {
+ if (!(prop in obj1)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
+ var Splitter = /** @class */ (function () {
+ function Splitter() {
+ this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
+ this.splitDateSelection = memoize(this._splitDateSpan);
+ this.splitEventStore = memoize(this._splitEventStore);
+ this.splitIndividualUi = memoize(this._splitIndividualUi);
+ this.splitEventDrag = memoize(this._splitInteraction);
+ this.splitEventResize = memoize(this._splitInteraction);
+ this.eventUiBuilders = {}; // TODO: typescript protection
+ }
+ Splitter.prototype.splitProps = function (props) {
+ var _this = this;
+ var keyInfos = this.getKeyInfo(props);
+ var defKeys = this.getKeysForEventDefs(props.eventStore);
+ var dateSelections = this.splitDateSelection(props.dateSelection);
+ var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
+ var eventStores = this.splitEventStore(props.eventStore, defKeys);
+ var eventDrags = this.splitEventDrag(props.eventDrag);
+ var eventResizes = this.splitEventResize(props.eventResize);
+ var splitProps = {};
+ this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
+ return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
+ });
+ for (var key in keyInfos) {
+ var keyInfo = keyInfos[key];
+ var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
+ var buildEventUi = this.eventUiBuilders[key];
+ splitProps[key] = {
+ businessHours: keyInfo.businessHours || props.businessHours,
+ dateSelection: dateSelections[key] || null,
+ eventStore: eventStore,
+ eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
+ eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
+ eventDrag: eventDrags[key] || null,
+ eventResize: eventResizes[key] || null
+ };
+ }
+ return splitProps;
+ };
+ Splitter.prototype._splitDateSpan = function (dateSpan) {
+ var dateSpans = {};
+ if (dateSpan) {
+ var keys = this.getKeysForDateSpan(dateSpan);
+ for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
+ var key = keys_1[_i];
+ dateSpans[key] = dateSpan;
+ }
+ }
+ return dateSpans;
+ };
+ Splitter.prototype._getKeysForEventDefs = function (eventStore) {
+ var _this = this;
+ return mapHash(eventStore.defs, function (eventDef) {
+ return _this.getKeysForEventDef(eventDef);
+ });
+ };
+ Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
+ var defs = eventStore.defs, instances = eventStore.instances;
+ var splitStores = {};
+ for (var defId in defs) {
+ for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
+ var key = _a[_i];
+ if (!splitStores[key]) {
+ splitStores[key] = createEmptyEventStore();
+ }
+ splitStores[key].defs[defId] = defs[defId];
+ }
+ }
+ for (var instanceId in instances) {
+ var instance = instances[instanceId];
+ for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
+ var key = _c[_b];
+ if (splitStores[key]) { // must have already been created
+ splitStores[key].instances[instanceId] = instance;
+ }
+ }
+ }
+ return splitStores;
+ };
+ Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
+ var splitHashes = {};
+ for (var defId in eventUiBases) {
+ if (defId) { // not the '' key
+ for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
+ var key = _a[_i];
+ if (!splitHashes[key]) {
+ splitHashes[key] = {};
+ }
+ splitHashes[key][defId] = eventUiBases[defId];
+ }
+ }
+ }
+ return splitHashes;
+ };
+ Splitter.prototype._splitInteraction = function (interaction) {
+ var splitStates = {};
+ if (interaction) {
+ var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
+ );
+ // can't rely on defKeys because event data is mutated
+ var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
+ var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
+ var populate = function (key) {
+ if (!splitStates[key]) {
+ splitStates[key] = {
+ affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
+ mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
+ isEvent: interaction.isEvent,
+ origSeg: interaction.origSeg
+ };
+ }
+ };
+ for (var key in affectedStores_1) {
+ populate(key);
+ }
+ for (var key in mutatedStores_1) {
+ populate(key);
+ }
+ }
+ return splitStates;
+ };
+ return Splitter;
+ }());
+ function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
+ var baseParts = [];
+ if (allUi) {
+ baseParts.push(allUi);
+ }
+ if (eventUiForKey) {
+ baseParts.push(eventUiForKey);
+ }
+ var stuff = {
+ '': combineEventUis(baseParts)
+ };
+ if (individualUi) {
+ __assign(stuff, individualUi);
+ }
+ return stuff;
+ }
+
+ // Generates HTML for an anchor to another view into the calendar.
+ // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
+ // `gotoOptions` can either be a DateMarker, or an object with the form:
+ // { date, type, forceOff }
+ // `type` is a view-type like "day" or "week". default value is "day".
+ // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
+ function buildGotoAnchorHtml(component, gotoOptions, attrs, innerHtml) {
+ var dateEnv = component.dateEnv;
+ var date;
+ var type;
+ var forceOff;
+ var finalOptions;
+ if (gotoOptions instanceof Date) {
+ date = gotoOptions; // a single date-like input
+ }
+ else {
+ date = gotoOptions.date;
+ type = gotoOptions.type;
+ forceOff = gotoOptions.forceOff;
+ }
+ finalOptions = {
+ date: dateEnv.formatIso(date, { omitTime: true }),
+ type: type || 'day'
+ };
+ if (typeof attrs === 'string') {
+ innerHtml = attrs;
+ attrs = null;
+ }
+ attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
+ innerHtml = innerHtml || '';
+ if (!forceOff && component.opt('navLinks')) {
+ return '<a' + attrs +
+ ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
+ innerHtml +
+ '</a>';
+ }
+ else {
+ return '<span' + attrs + '>' +
+ innerHtml +
+ '</span>';
+ }
+ }
+ function getAllDayHtml(component) {
+ return component.opt('allDayHtml') || htmlEscape(component.opt('allDayText'));
+ }
+ // Computes HTML classNames for a single-day element
+ function getDayClasses(date, dateProfile, context, noThemeHighlight) {
+ var calendar = context.calendar, view = context.view, theme = context.theme, dateEnv = context.dateEnv;
+ var classes = [];
+ var todayStart;
+ var todayEnd;
+ if (!rangeContainsMarker(dateProfile.activeRange, date)) {
+ classes.push('fc-disabled-day');
+ }
+ else {
+ classes.push('fc-' + DAY_IDS[date.getUTCDay()]);
+ if (view.opt('monthMode') &&
+ dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) {
+ classes.push('fc-other-month');
+ }
+ todayStart = startOfDay(calendar.getNow());
+ todayEnd = addDays(todayStart, 1);
+ if (date < todayStart) {
+ classes.push('fc-past');
+ }
+ else if (date >= todayEnd) {
+ classes.push('fc-future');
+ }
+ else {
+ classes.push('fc-today');
+ if (noThemeHighlight !== true) {
+ classes.push(theme.getClass('today'));
+ }
+ }
+ }
+ return classes;
+ }
+
+ // given a function that resolves a result asynchronously.
+ // the function can either call passed-in success and failure callbacks,
+ // or it can return a promise.
+ // if you need to pass additional params to func, bind them first.
+ function unpromisify(func, success, failure) {
+ // guard against success/failure callbacks being called more than once
+ // and guard against a promise AND callback being used together.
+ var isResolved = false;
+ var wrappedSuccess = function () {
+ if (!isResolved) {
+ isResolved = true;
+ success.apply(this, arguments);
+ }
+ };
+ var wrappedFailure = function () {
+ if (!isResolved) {
+ isResolved = true;
+ if (failure) {
+ failure.apply(this, arguments);
+ }
+ }
+ };
+ var res = func(wrappedSuccess, wrappedFailure);
+ if (res && typeof res.then === 'function') {
+ res.then(wrappedSuccess, wrappedFailure);
+ }
+ }
+
+ var Mixin = /** @class */ (function () {
+ function Mixin() {
+ }
+ // mix into a CLASS
+ Mixin.mixInto = function (destClass) {
+ this.mixIntoObj(destClass.prototype);
+ };
+ // mix into ANY object
+ Mixin.mixIntoObj = function (destObj) {
+ var _this = this;
+ Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
+ if (!destObj[name]) { // if destination doesn't already define it
+ destObj[name] = _this.prototype[name];
+ }
+ });
+ };
+ /*
+ will override existing methods
+ TODO: remove! not used anymore
+ */
+ Mixin.mixOver = function (destClass) {
+ var _this = this;
+ Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
+ destClass.prototype[name] = _this.prototype[name];
+ });
+ };
+ return Mixin;
+ }());
+
+ /*
+ USAGE:
+ import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
+ in class:
+ on: EmitterInterface['on']
+ one: EmitterInterface['one']
+ off: EmitterInterface['off']
+ trigger: EmitterInterface['trigger']
+ triggerWith: EmitterInterface['triggerWith']
+ hasHandlers: EmitterInterface['hasHandlers']
+ after class:
+ EmitterMixin.mixInto(TheClass)
+ */
+ var EmitterMixin = /** @class */ (function (_super) {
+ __extends(EmitterMixin, _super);
+ function EmitterMixin() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ EmitterMixin.prototype.on = function (type, handler) {
+ addToHash(this._handlers || (this._handlers = {}), type, handler);
+ return this; // for chaining
+ };
+ // todo: add comments
+ EmitterMixin.prototype.one = function (type, handler) {
+ addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler);
+ return this; // for chaining
+ };
+ EmitterMixin.prototype.off = function (type, handler) {
+ if (this._handlers) {
+ removeFromHash(this._handlers, type, handler);
+ }
+ if (this._oneHandlers) {
+ removeFromHash(this._oneHandlers, type, handler);
+ }
+ return this; // for chaining
+ };
+ EmitterMixin.prototype.trigger = function (type) {
+ var args = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ args[_i - 1] = arguments[_i];
+ }
+ this.triggerWith(type, this, args);
+ return this; // for chaining
+ };
+ EmitterMixin.prototype.triggerWith = function (type, context, args) {
+ if (this._handlers) {
+ applyAll(this._handlers[type], context, args);
+ }
+ if (this._oneHandlers) {
+ applyAll(this._oneHandlers[type], context, args);
+ delete this._oneHandlers[type]; // will never fire again
+ }
+ return this; // for chaining
+ };
+ EmitterMixin.prototype.hasHandlers = function (type) {
+ return (this._handlers && this._handlers[type] && this._handlers[type].length) ||
+ (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length);
+ };
+ return EmitterMixin;
+ }(Mixin));
+ function addToHash(hash, type, handler) {
+ (hash[type] || (hash[type] = []))
+ .push(handler);
+ }
+ function removeFromHash(hash, type, handler) {
+ if (handler) {
+ if (hash[type]) {
+ hash[type] = hash[type].filter(function (func) {
+ return func !== handler;
+ });
+ }
+ }
+ else {
+ delete hash[type]; // remove all handler funcs for this type
+ }
+ }
+
+ /*
+ Records offset information for a set of elements, relative to an origin element.
+ Can record the left/right OR the top/bottom OR both.
+ Provides methods for querying the cache by position.
+ */
+ var PositionCache = /** @class */ (function () {
+ function PositionCache(originEl, els, isHorizontal, isVertical) {
+ this.originEl = originEl;
+ this.els = els;
+ this.isHorizontal = isHorizontal;
+ this.isVertical = isVertical;
+ }
+ // Queries the els for coordinates and stores them.
+ // Call this method before using and of the get* methods below.
+ PositionCache.prototype.build = function () {
+ var originEl = this.originEl;
+ var originClientRect = this.originClientRect =
+ originEl.getBoundingClientRect(); // relative to viewport top-left
+ if (this.isHorizontal) {
+ this.buildElHorizontals(originClientRect.left);
+ }
+ if (this.isVertical) {
+ this.buildElVerticals(originClientRect.top);
+ }
+ };
+ // Populates the left/right internal coordinate arrays
+ PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
+ var lefts = [];
+ var rights = [];
+ for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
+ var el = _a[_i];
+ var rect = el.getBoundingClientRect();
+ lefts.push(rect.left - originClientLeft);
+ rights.push(rect.right - originClientLeft);
+ }
+ this.lefts = lefts;
+ this.rights = rights;
+ };
+ // Populates the top/bottom internal coordinate arrays
+ PositionCache.prototype.buildElVerticals = function (originClientTop) {
+ var tops = [];
+ var bottoms = [];
+ for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
+ var el = _a[_i];
+ var rect = el.getBoundingClientRect();
+ tops.push(rect.top - originClientTop);
+ bottoms.push(rect.bottom - originClientTop);
+ }
+ this.tops = tops;
+ this.bottoms = bottoms;
+ };
+ // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
+ // If no intersection is made, returns undefined.
+ PositionCache.prototype.leftToIndex = function (leftPosition) {
+ var lefts = this.lefts;
+ var rights = this.rights;
+ var len = lefts.length;
+ var i;
+ for (i = 0; i < len; i++) {
+ if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
+ return i;
+ }
+ }
+ };
+ // Given a top offset (from document top), returns the index of the el that it vertically intersects.
+ // If no intersection is made, returns undefined.
+ PositionCache.prototype.topToIndex = function (topPosition) {
+ var tops = this.tops;
+ var bottoms = this.bottoms;
+ var len = tops.length;
+ var i;
+ for (i = 0; i < len; i++) {
+ if (topPosition >= tops[i] && topPosition < bottoms[i]) {
+ return i;
+ }
+ }
+ };
+ // Gets the width of the element at the given index
+ PositionCache.prototype.getWidth = function (leftIndex) {
+ return this.rights[leftIndex] - this.lefts[leftIndex];
+ };
+ // Gets the height of the element at the given index
+ PositionCache.prototype.getHeight = function (topIndex) {
+ return this.bottoms[topIndex] - this.tops[topIndex];
+ };
+ return PositionCache;
+ }());
+
+ /*
+ An object for getting/setting scroll-related information for an element.
+ Internally, this is done very differently for window versus DOM element,
+ so this object serves as a common interface.
+ */
+ var ScrollController = /** @class */ (function () {
+ function ScrollController() {
+ }
+ ScrollController.prototype.getMaxScrollTop = function () {
+ return this.getScrollHeight() - this.getClientHeight();
+ };
+ ScrollController.prototype.getMaxScrollLeft = function () {
+ return this.getScrollWidth() - this.getClientWidth();
+ };
+ ScrollController.prototype.canScrollVertically = function () {
+ return this.getMaxScrollTop() > 0;
+ };
+ ScrollController.prototype.canScrollHorizontally = function () {
+ return this.getMaxScrollLeft() > 0;
+ };
+ ScrollController.prototype.canScrollUp = function () {
+ return this.getScrollTop() > 0;
+ };
+ ScrollController.prototype.canScrollDown = function () {
+ return this.getScrollTop() < this.getMaxScrollTop();
+ };
+ ScrollController.prototype.canScrollLeft = function () {
+ return this.getScrollLeft() > 0;
+ };
+ ScrollController.prototype.canScrollRight = function () {
+ return this.getScrollLeft() < this.getMaxScrollLeft();
+ };
+ return ScrollController;
+ }());
+ var ElementScrollController = /** @class */ (function (_super) {
+ __extends(ElementScrollController, _super);
+ function ElementScrollController(el) {
+ var _this = _super.call(this) || this;
+ _this.el = el;
+ return _this;
+ }
+ ElementScrollController.prototype.getScrollTop = function () {
+ return this.el.scrollTop;
+ };
+ ElementScrollController.prototype.getScrollLeft = function () {
+ return this.el.scrollLeft;
+ };
+ ElementScrollController.prototype.setScrollTop = function (top) {
+ this.el.scrollTop = top;
+ };
+ ElementScrollController.prototype.setScrollLeft = function (left) {
+ this.el.scrollLeft = left;
+ };
+ ElementScrollController.prototype.getScrollWidth = function () {
+ return this.el.scrollWidth;
+ };
+ ElementScrollController.prototype.getScrollHeight = function () {
+ return this.el.scrollHeight;
+ };
+ ElementScrollController.prototype.getClientHeight = function () {
+ return this.el.clientHeight;
+ };
+ ElementScrollController.prototype.getClientWidth = function () {
+ return this.el.clientWidth;
+ };
+ return ElementScrollController;
+ }(ScrollController));
+ var WindowScrollController = /** @class */ (function (_super) {
+ __extends(WindowScrollController, _super);
+ function WindowScrollController() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ WindowScrollController.prototype.getScrollTop = function () {
+ return window.pageYOffset;
+ };
+ WindowScrollController.prototype.getScrollLeft = function () {
+ return window.pageXOffset;
+ };
+ WindowScrollController.prototype.setScrollTop = function (n) {
+ window.scroll(window.pageXOffset, n);
+ };
+ WindowScrollController.prototype.setScrollLeft = function (n) {
+ window.scroll(n, window.pageYOffset);
+ };
+ WindowScrollController.prototype.getScrollWidth = function () {
+ return document.documentElement.scrollWidth;
+ };
+ WindowScrollController.prototype.getScrollHeight = function () {
+ return document.documentElement.scrollHeight;
+ };
+ WindowScrollController.prototype.getClientHeight = function () {
+ return document.documentElement.clientHeight;
+ };
+ WindowScrollController.prototype.getClientWidth = function () {
+ return document.documentElement.clientWidth;
+ };
+ return WindowScrollController;
+ }(ScrollController));
+
+ /*
+ Embodies a div that has potential scrollbars
+ */
+ var ScrollComponent = /** @class */ (function (_super) {
+ __extends(ScrollComponent, _super);
+ function ScrollComponent(overflowX, overflowY) {
+ var _this = _super.call(this, createElement('div', {
+ className: 'fc-scroller'
+ })) || this;
+ _this.overflowX = overflowX;
+ _this.overflowY = overflowY;
+ _this.applyOverflow();
+ return _this;
+ }
+ // sets to natural height, unlocks overflow
+ ScrollComponent.prototype.clear = function () {
+ this.setHeight('auto');
+ this.applyOverflow();
+ };
+ ScrollComponent.prototype.destroy = function () {
+ removeElement(this.el);
+ };
+ // Overflow
+ // -----------------------------------------------------------------------------------------------------------------
+ ScrollComponent.prototype.applyOverflow = function () {
+ applyStyle(this.el, {
+ overflowX: this.overflowX,
+ overflowY: this.overflowY
+ });
+ };
+ // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
+ // Useful for preserving scrollbar widths regardless of future resizes.
+ // Can pass in scrollbarWidths for optimization.
+ ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) {
+ var overflowX = this.overflowX;
+ var overflowY = this.overflowY;
+ scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
+ if (overflowX === 'auto') {
+ overflowX = (scrollbarWidths.bottom || // horizontal scrollbars?
+ this.canScrollHorizontally() // OR scrolling pane with massless scrollbars?
+ ) ? 'scroll' : 'hidden';
+ }
+ if (overflowY === 'auto') {
+ overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars?
+ this.canScrollVertically() // OR scrolling pane with massless scrollbars?
+ ) ? 'scroll' : 'hidden';
+ }
+ applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY });
+ };
+ ScrollComponent.prototype.setHeight = function (height) {
+ applyStyleProp(this.el, 'height', height);
+ };
+ ScrollComponent.prototype.getScrollbarWidths = function () {
+ var edges = computeEdges(this.el);
+ return {
+ left: edges.scrollbarLeft,
+ right: edges.scrollbarRight,
+ bottom: edges.scrollbarBottom
+ };
+ };
+ return ScrollComponent;
+ }(ElementScrollController));
+
+ var Theme = /** @class */ (function () {
+ function Theme(calendarOptions) {
+ this.calendarOptions = calendarOptions;
+ this.processIconOverride();
+ }
+ Theme.prototype.processIconOverride = function () {
+ if (this.iconOverrideOption) {
+ this.setIconOverride(this.calendarOptions[this.iconOverrideOption]);
+ }
+ };
+ Theme.prototype.setIconOverride = function (iconOverrideHash) {
+ var iconClassesCopy;
+ var buttonName;
+ if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
+ iconClassesCopy = __assign({}, this.iconClasses);
+ for (buttonName in iconOverrideHash) {
+ iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
+ }
+ this.iconClasses = iconClassesCopy;
+ }
+ else if (iconOverrideHash === false) {
+ this.iconClasses = {};
+ }
+ };
+ Theme.prototype.applyIconOverridePrefix = function (className) {
+ var prefix = this.iconOverridePrefix;
+ if (prefix && className.indexOf(prefix) !== 0) { // if not already present
+ className = prefix + className;
+ }
+ return className;
+ };
+ Theme.prototype.getClass = function (key) {
+ return this.classes[key] || '';
+ };
+ Theme.prototype.getIconClass = function (buttonName) {
+ var className = this.iconClasses[buttonName];
+ if (className) {
+ return this.baseIconClass + ' ' + className;
+ }
+ return '';
+ };
+ Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
+ var className;
+ if (this.iconOverrideCustomButtonOption) {
+ className = customButtonProps[this.iconOverrideCustomButtonOption];
+ if (className) {
+ return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
+ }
+ }
+ return '';
+ };
+ return Theme;
+ }());
+ Theme.prototype.classes = {};
+ Theme.prototype.iconClasses = {};
+ Theme.prototype.baseIconClass = '';
+ Theme.prototype.iconOverridePrefix = '';
+
+ var guid = 0;
+ var Component = /** @class */ (function () {
+ function Component(context, isView) {
+ // HACK to populate view at top of component instantiation call chain
+ if (isView) {
+ context.view = this;
+ }
+ this.uid = String(guid++);
+ this.context = context;
+ this.dateEnv = context.dateEnv;
+ this.theme = context.theme;
+ this.view = context.view;
+ this.calendar = context.calendar;
+ this.isRtl = this.opt('dir') === 'rtl';
+ }
+ Component.addEqualityFuncs = function (newFuncs) {
+ this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs);
+ };
+ Component.prototype.opt = function (name) {
+ return this.context.options[name];
+ };
+ Component.prototype.receiveProps = function (props) {
+ var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps;
+ this.props = comboProps;
+ if (anyChanges) {
+ this.render(comboProps);
+ }
+ };
+ Component.prototype.render = function (props) {
+ };
+ // after destroy is called, this component won't ever be used again
+ Component.prototype.destroy = function () {
+ };
+ return Component;
+ }());
+ Component.prototype.equalityFuncs = {};
+ /*
+ Reuses old values when equal. If anything is unequal, returns newProps as-is.
+ Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
+ */
+ function recycleProps(oldProps, newProps, equalityFuncs) {
+ var comboProps = {}; // some old, some new
+ var anyChanges = false;
+ for (var key in newProps) {
+ if (key in oldProps && (oldProps[key] === newProps[key] ||
+ (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) {
+ // equal to old? use old prop
+ comboProps[key] = oldProps[key];
+ }
+ else {
+ comboProps[key] = newProps[key];
+ anyChanges = true;
+ }
+ }
+ for (var key in oldProps) {
+ if (!(key in newProps)) {
+ anyChanges = true;
+ break;
+ }
+ }
+ return { anyChanges: anyChanges, comboProps: comboProps };
+ }
+
+ /*
+ PURPOSES:
+ - hook up to fg, fill, and mirror renderers
+ - interface for dragging and hits
+ */
+ var DateComponent = /** @class */ (function (_super) {
+ __extends(DateComponent, _super);
+ function DateComponent(context, el, isView) {
+ var _this = _super.call(this, context, isView) || this;
+ _this.el = el;
+ return _this;
+ }
+ DateComponent.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ removeElement(this.el);
+ };
+ // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror)
+ //
+ // Event Drag-n-Drop Rendering (for both events and external elements)
+ // ---------------------------------------------------------------------------------------------------------------
+ /*
+ renderEventDragSegs(state: EventSegUiInteractionState) {
+ if (state) {
+ let { isEvent, segs, sourceSeg } = state
+
+ if (this.eventRenderer) {
+ this.eventRenderer.hideByHash(state.affectedInstances)
+ }
+
+ // if the user is dragging something that is considered an event with real event data,
+ // and this component likes to do drag mirrors OR the component where the seg came from
+ // likes to do drag mirrors, then render a drag mirror.
+ if (isEvent && (this.doesDragMirror || sourceSeg && sourceSeg.component.doesDragMirror)) {
+ if (this.mirrorRenderer) {
+ this.mirrorRenderer.renderSegs(segs, { isDragging: true, sourceSeg })
+ }
+ }
+
+ // if it would be impossible to render a drag mirror OR this component likes to render
+ // highlights, then render a highlight.
+ if (!isEvent || this.doesDragHighlight) {
+ if (this.fillRenderer) {
+ this.fillRenderer.renderSegs('highlight', segs)
+ }
+ }
+ }
+ }
+ */
+ // Hit System
+ // -----------------------------------------------------------------------------------------------------------------
+ DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
+ return null; // this should be abstract
+ };
+ // Validation
+ // -----------------------------------------------------------------------------------------------------------------
+ DateComponent.prototype.isInteractionValid = function (interaction) {
+ var calendar = this.calendar;
+ var dateProfile = this.props.dateProfile; // HACK
+ var instances = interaction.mutatedEvents.instances;
+ if (dateProfile) { // HACK for DayTile
+ for (var instanceId in instances) {
+ if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
+ return false;
+ }
+ }
+ }
+ return isInteractionValid(interaction, calendar);
+ };
+ DateComponent.prototype.isDateSelectionValid = function (selection) {
+ var dateProfile = this.props.dateProfile; // HACK
+ if (dateProfile && // HACK for DayTile
+ !rangeContainsRange(dateProfile.validRange, selection.range)) {
+ return false;
+ }
+ return isDateSelectionValid(selection, this.calendar);
+ };
+ // Triggering
+ // -----------------------------------------------------------------------------------------------------------------
+ // TODO: move to Calendar
+ DateComponent.prototype.publiclyTrigger = function (name, args) {
+ var calendar = this.calendar;
+ return calendar.publiclyTrigger(name, args);
+ };
+ DateComponent.prototype.publiclyTriggerAfterSizing = function (name, args) {
+ var calendar = this.calendar;
+ return calendar.publiclyTriggerAfterSizing(name, args);
+ };
+ DateComponent.prototype.hasPublicHandlers = function (name) {
+ var calendar = this.calendar;
+ return calendar.hasPublicHandlers(name);
+ };
+ DateComponent.prototype.triggerRenderedSegs = function (segs, isMirrors) {
+ var calendar = this.calendar;
+ if (this.hasPublicHandlers('eventPositioned')) {
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+ var seg = segs_1[_i];
+ this.publiclyTriggerAfterSizing('eventPositioned', [
+ {
+ event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
+ isMirror: isMirrors,
+ isStart: seg.isStart,
+ isEnd: seg.isEnd,
+ el: seg.el,
+ view: this // ?
+ }
+ ]);
+ }
+ }
+ if (!calendar.state.loadingLevel) { // avoid initial empty state while pending
+ calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once
+ }
+ };
+ DateComponent.prototype.triggerWillRemoveSegs = function (segs, isMirrors) {
+ var calendar = this.calendar;
+ for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
+ var seg = segs_2[_i];
+ calendar.trigger('eventElRemove', seg.el);
+ }
+ if (this.hasPublicHandlers('eventDestroy')) {
+ for (var _a = 0, segs_3 = segs; _a < segs_3.length; _a++) {
+ var seg = segs_3[_a];
+ this.publiclyTrigger('eventDestroy', [
+ {
+ event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
+ isMirror: isMirrors,
+ el: seg.el,
+ view: this // ?
+ }
+ ]);
+ }
+ }
+ };
+ // Pointer Interaction Utils
+ // -----------------------------------------------------------------------------------------------------------------
+ DateComponent.prototype.isValidSegDownEl = function (el) {
+ return !this.props.eventDrag && // HACK
+ !this.props.eventResize && // HACK
+ !elementClosest(el, '.fc-mirror') &&
+ (this.isPopover() || !this.isInPopover(el));
+ // ^above line ensures we don't detect a seg interaction within a nested component.
+ // it's a HACK because it only supports a popover as the nested component.
+ };
+ DateComponent.prototype.isValidDateDownEl = function (el) {
+ var segEl = elementClosest(el, this.fgSegSelector);
+ return (!segEl || segEl.classList.contains('fc-mirror')) &&
+ !elementClosest(el, '.fc-more') && // a "more.." link
+ !elementClosest(el, 'a[data-goto]') && // a clickable nav link
+ !this.isInPopover(el);
+ };
+ DateComponent.prototype.isPopover = function () {
+ return this.el.classList.contains('fc-popover');
+ };
+ DateComponent.prototype.isInPopover = function (el) {
+ return Boolean(elementClosest(el, '.fc-popover'));
+ };
+ return DateComponent;
+ }(Component));
+ DateComponent.prototype.fgSegSelector = '.fc-event-container > *';
+ DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)';
+
+ var uid$1 = 0;
+ function createPlugin(input) {
+ return {
+ id: String(uid$1++),
+ deps: input.deps || [],
+ reducers: input.reducers || [],
+ eventDefParsers: input.eventDefParsers || [],
+ eventDragMutationMassagers: input.eventDragMutationMassagers || [],
+ eventDefMutationAppliers: input.eventDefMutationAppliers || [],
+ dateSelectionTransformers: input.dateSelectionTransformers || [],
+ datePointTransforms: input.datePointTransforms || [],
+ dateSpanTransforms: input.dateSpanTransforms || [],
+ views: input.views || {},
+ viewPropsTransformers: input.viewPropsTransformers || [],
+ isPropsValid: input.isPropsValid || null,
+ externalDefTransforms: input.externalDefTransforms || [],
+ eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
+ viewContainerModifiers: input.viewContainerModifiers || [],
+ eventDropTransformers: input.eventDropTransformers || [],
+ componentInteractions: input.componentInteractions || [],
+ calendarInteractions: input.calendarInteractions || [],
+ themeClasses: input.themeClasses || {},
+ eventSourceDefs: input.eventSourceDefs || [],
+ cmdFormatter: input.cmdFormatter,
+ recurringTypes: input.recurringTypes || [],
+ namedTimeZonedImpl: input.namedTimeZonedImpl,
+ defaultView: input.defaultView || '',
+ elementDraggingImpl: input.elementDraggingImpl,
+ optionChangeHandlers: input.optionChangeHandlers || {}
+ };
+ }
+ var PluginSystem = /** @class */ (function () {
+ function PluginSystem() {
+ this.hooks = {
+ reducers: [],
+ eventDefParsers: [],
+ eventDragMutationMassagers: [],
+ eventDefMutationAppliers: [],
+ dateSelectionTransformers: [],
+ datePointTransforms: [],
+ dateSpanTransforms: [],
+ views: {},
+ viewPropsTransformers: [],
+ isPropsValid: null,
+ externalDefTransforms: [],
+ eventResizeJoinTransforms: [],
+ viewContainerModifiers: [],
+ eventDropTransformers: [],
+ componentInteractions: [],
+ calendarInteractions: [],
+ themeClasses: {},
+ eventSourceDefs: [],
+ cmdFormatter: null,
+ recurringTypes: [],
+ namedTimeZonedImpl: null,
+ defaultView: '',
+ elementDraggingImpl: null,
+ optionChangeHandlers: {}
+ };
+ this.addedHash = {};
+ }
+ PluginSystem.prototype.add = function (plugin) {
+ if (!this.addedHash[plugin.id]) {
+ this.addedHash[plugin.id] = true;
+ for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) {
+ var dep = _a[_i];
+ this.add(dep);
+ }
+ this.hooks = combineHooks(this.hooks, plugin);
+ }
+ };
+ return PluginSystem;
+ }());
+ function combineHooks(hooks0, hooks1) {
+ return {
+ reducers: hooks0.reducers.concat(hooks1.reducers),
+ eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers),
+ eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
+ eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
+ dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
+ datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
+ dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
+ views: __assign({}, hooks0.views, hooks1.views),
+ viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
+ isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
+ externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
+ eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
+ viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers),
+ eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
+ calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
+ componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
+ themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
+ eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
+ cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
+ recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
+ namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
+ defaultView: hooks0.defaultView || hooks1.defaultView,
+ elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
+ optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers)
+ };
+ }
+
+ var eventSourceDef = {
+ ignoreRange: true,
+ parseMeta: function (raw) {
+ if (Array.isArray(raw)) { // short form
+ return raw;
+ }
+ else if (Array.isArray(raw.events)) {
+ return raw.events;
+ }
+ return null;
+ },
+ fetch: function (arg, success) {
+ success({
+ rawEvents: arg.eventSource.meta
+ });
+ }
+ };
+ var ArrayEventSourcePlugin = createPlugin({
+ eventSourceDefs: [eventSourceDef]
+ });
+
+ var eventSourceDef$1 = {
+ parseMeta: function (raw) {
+ if (typeof raw === 'function') { // short form
+ return raw;
+ }
+ else if (typeof raw.events === 'function') {
+ return raw.events;
+ }
+ return null;
+ },
+ fetch: function (arg, success, failure) {
+ var dateEnv = arg.calendar.dateEnv;
+ var func = arg.eventSource.meta;
+ unpromisify(func.bind(null, {
+ start: dateEnv.toDate(arg.range.start),
+ end: dateEnv.toDate(arg.range.end),
+ startStr: dateEnv.formatIso(arg.range.start),
+ endStr: dateEnv.formatIso(arg.range.end),
+ timeZone: dateEnv.timeZone
+ }), function (rawEvents) {
+ success({ rawEvents: rawEvents }); // needs an object response
+ }, failure // send errorObj directly to failure callback
+ );
+ }
+ };
+ var FuncEventSourcePlugin = createPlugin({
+ eventSourceDefs: [eventSourceDef$1]
+ });
+
+ function requestJson(method, url, params, successCallback, failureCallback) {
+ method = method.toUpperCase();
+ var body = null;
+ if (method === 'GET') {
+ url = injectQueryStringParams(url, params);
+ }
+ else {
+ body = encodeParams(params);
+ }
+ var xhr = new XMLHttpRequest();
+ xhr.open(method, url, true);
+ if (method !== 'GET') {
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ }
+ xhr.onload = function () {
+ if (xhr.status >= 200 && xhr.status < 400) {
+ try {
+ var res = JSON.parse(xhr.responseText);
+ successCallback(res, xhr);
+ }
+ catch (err) {
+ failureCallback('Failure parsing JSON', xhr);
+ }
+ }
+ else {
+ failureCallback('Request failed', xhr);
+ }
+ };
+ xhr.onerror = function () {
+ failureCallback('Request failed', xhr);
+ };
+ xhr.send(body);
+ }
+ function injectQueryStringParams(url, params) {
+ return url +
+ (url.indexOf('?') === -1 ? '?' : '&') +
+ encodeParams(params);
+ }
+ function encodeParams(params) {
+ var parts = [];
+ for (var key in params) {
+ parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
+ }
+ return parts.join('&');
+ }
+
+ var eventSourceDef$2 = {
+ parseMeta: function (raw) {
+ if (typeof raw === 'string') { // short form
+ raw = { url: raw };
+ }
+ else if (!raw || typeof raw !== 'object' || !raw.url) {
+ return null;
+ }
+ return {
+ url: raw.url,
+ method: (raw.method || 'GET').toUpperCase(),
+ extraParams: raw.extraParams,
+ startParam: raw.startParam,
+ endParam: raw.endParam,
+ timeZoneParam: raw.timeZoneParam
+ };
+ },
+ fetch: function (arg, success, failure) {
+ var meta = arg.eventSource.meta;
+ var requestParams = buildRequestParams(meta, arg.range, arg.calendar);
+ requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
+ success({ rawEvents: rawEvents, xhr: xhr });
+ }, function (errorMessage, xhr) {
+ failure({ message: errorMessage, xhr: xhr });
+ });
+ }
+ };
+ var JsonFeedEventSourcePlugin = createPlugin({
+ eventSourceDefs: [eventSourceDef$2]
+ });
+ function buildRequestParams(meta, range, calendar) {
+ var dateEnv = calendar.dateEnv;
+ var startParam;
+ var endParam;
+ var timeZoneParam;
+ var customRequestParams;
+ var params = {};
+ startParam = meta.startParam;
+ if (startParam == null) {
+ startParam = calendar.opt('startParam');
+ }
+ endParam = meta.endParam;
+ if (endParam == null) {
+ endParam = calendar.opt('endParam');
+ }
+ timeZoneParam = meta.timeZoneParam;
+ if (timeZoneParam == null) {
+ timeZoneParam = calendar.opt('timeZoneParam');
+ }
+ // retrieve any outbound GET/POST data from the options
+ if (typeof meta.extraParams === 'function') {
+ // supplied as a function that returns a key/value object
+ customRequestParams = meta.extraParams();
+ }
+ else {
+ // probably supplied as a straight key/value object
+ customRequestParams = meta.extraParams || {};
+ }
+ __assign(params, customRequestParams);
+ params[startParam] = dateEnv.formatIso(range.start);
+ params[endParam] = dateEnv.formatIso(range.end);
+ if (dateEnv.timeZone !== 'local') {
+ params[timeZoneParam] = dateEnv.timeZone;
+ }
+ return params;
+ }
+
+ var recurring = {
+ parse: function (rawEvent, leftoverProps, dateEnv) {
+ var createMarker = dateEnv.createMarker.bind(dateEnv);
+ var processors = {
+ daysOfWeek: null,
+ startTime: createDuration,
+ endTime: createDuration,
+ startRecur: createMarker,
+ endRecur: createMarker
+ };
+ var props = refineProps(rawEvent, processors, {}, leftoverProps);
+ var anyValid = false;
+ for (var propName in props) {
+ if (props[propName] != null) {
+ anyValid = true;
+ break;
+ }
+ }
+ if (anyValid) {
+ return {
+ allDayGuess: Boolean(!props.startTime && !props.endTime),
+ duration: (props.startTime && props.endTime) ?
+ subtractDurations(props.endTime, props.startTime) :
+ null,
+ typeData: props // doesn't need endTime anymore but oh well
+ };
+ }
+ return null;
+ },
+ expand: function (typeData, framingRange, dateEnv) {
+ var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
+ if (clippedFramingRange) {
+ return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
+ }
+ else {
+ return [];
+ }
+ }
+ };
+ var SimpleRecurrencePlugin = createPlugin({
+ recurringTypes: [recurring]
+ });
+ function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
+ var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
+ var dayMarker = startOfDay(framingRange.start);
+ var endMarker = framingRange.end;
+ var instanceStarts = [];
+ while (dayMarker < endMarker) {
+ var instanceStart
+ // if everyday, or this particular day-of-week
+ = void 0;
+ // if everyday, or this particular day-of-week
+ if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
+ if (startTime) {
+ instanceStart = dateEnv.add(dayMarker, startTime);
+ }
+ else {
+ instanceStart = dayMarker;
+ }
+ instanceStarts.push(instanceStart);
+ }
+ dayMarker = addDays(dayMarker, 1);
+ }
+ return instanceStarts;
+ }
+
+ var DefaultOptionChangeHandlers = createPlugin({
+ optionChangeHandlers: {
+ events: function (events, calendar) {
+ handleEventSources([events], calendar);
+ },
+ eventSources: handleEventSources,
+ plugins: handlePlugins
+ }
+ });
+ function handleEventSources(inputs, calendar) {
+ var unfoundSources = hashValuesToArray(calendar.state.eventSources);
+ var newInputs = [];
+ for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
+ var input = inputs_1[_i];
+ var inputFound = false;
+ for (var i = 0; i < unfoundSources.length; i++) {
+ if (isValuesSimilar(unfoundSources[i]._raw, input, 2)) {
+ unfoundSources.splice(i, 1); // delete
+ inputFound = true;
+ break;
+ }
+ }
+ if (!inputFound) {
+ newInputs.push(input);
+ }
+ }
+ for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
+ var unfoundSource = unfoundSources_1[_a];
+ calendar.dispatch({
+ type: 'REMOVE_EVENT_SOURCE',
+ sourceId: unfoundSource.sourceId
+ });
+ }
+ for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
+ var newInput = newInputs_1[_b];
+ calendar.addEventSource(newInput);
+ }
+ }
+ // shortcoming: won't remove plugins
+ function handlePlugins(inputs, calendar) {
+ calendar.addPluginInputs(inputs); // will gracefully handle duplicates
+ }
+
+ var config = {}; // TODO: make these options
+ var globalDefaults = {
+ defaultRangeSeparator: ' - ',
+ titleRangeSeparator: ' \u2013 ',
+ defaultTimedEventDuration: '01:00:00',
+ defaultAllDayEventDuration: { day: 1 },
+ forceEventDuration: false,
+ nextDayThreshold: '00:00:00',
+ // display
+ columnHeader: true,
+ defaultView: '',
+ aspectRatio: 1.35,
+ header: {
+ left: 'title',
+ center: '',
+ right: 'today prev,next'
+ },
+ weekends: true,
+ weekNumbers: false,
+ weekNumberCalculation: 'local',
+ editable: false,
+ // nowIndicator: false,
+ scrollTime: '06:00:00',
+ minTime: '00:00:00',
+ maxTime: '24:00:00',
+ showNonCurrentDates: true,
+ // event ajax
+ lazyFetching: true,
+ startParam: 'start',
+ endParam: 'end',
+ timeZoneParam: 'timeZone',
+ timeZone: 'local',
+ // allDayDefault: undefined,
+ // locale
+ locales: [],
+ locale: '',
+ // dir: will get this from the default locale
+ // buttonIcons: null,
+ // allows setting a min-height to the event segment to prevent short events overlapping each other
+ timeGridEventMinHeight: 0,
+ themeSystem: 'standard',
+ // eventResizableFromStart: false,
+ dragRevertDuration: 500,
+ dragScroll: true,
+ allDayMaintainDuration: false,
+ // selectable: false,
+ unselectAuto: true,
+ // selectMinDistance: 0,
+ dropAccept: '*',
+ eventOrder: 'start,-duration,allDay,title',
+ // ^ if start tie, longer events go before shorter. final tie-breaker is title text
+ // rerenderDelay: null,
+ eventLimit: false,
+ eventLimitClick: 'popover',
+ dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
+ handleWindowResize: true,
+ windowResizeDelay: 100,
+ longPressDelay: 1000,
+ eventDragMinDistance: 5 // only applies to mouse
+ };
+ var rtlDefaults = {
+ header: {
+ left: 'next,prev today',
+ center: '',
+ right: 'title'
+ },
+ buttonIcons: {
+ // TODO: make RTL support the responibility of the theme
+ prev: 'fc-icon-chevron-right',
+ next: 'fc-icon-chevron-left',
+ prevYear: 'fc-icon-chevrons-right',
+ nextYear: 'fc-icon-chevrons-left'
+ }
+ };
+ var complexOptions = [
+ 'header',
+ 'footer',
+ 'buttonText',
+ 'buttonIcons'
+ ];
+ // Merges an array of option objects into a single object
+ function mergeOptions(optionObjs) {
+ return mergeProps(optionObjs, complexOptions);
+ }
+ // TODO: move this stuff to a "plugin"-related file...
+ var INTERNAL_PLUGINS = [
+ ArrayEventSourcePlugin,
+ FuncEventSourcePlugin,
+ JsonFeedEventSourcePlugin,
+ SimpleRecurrencePlugin,
+ DefaultOptionChangeHandlers
+ ];
+ function refinePluginDefs(pluginInputs) {
+ var plugins = [];
+ for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) {
+ var pluginInput = pluginInputs_1[_i];
+ if (typeof pluginInput === 'string') {
+ var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput);
+ if (!window[globalName]) {
+ console.warn('Plugin file not loaded for ' + pluginInput);
+ }
+ else {
+ plugins.push(window[globalName].default); // is an ES6 module
+ }
+ }
+ else {
+ plugins.push(pluginInput);
+ }
+ }
+ return INTERNAL_PLUGINS.concat(plugins);
+ }
+
+ var RAW_EN_LOCALE = {
+ code: 'en',
+ week: {
+ dow: 0,
+ doy: 4 // 4 days need to be within the year to be considered the first week
+ },
+ dir: 'ltr',
+ buttonText: {
+ prev: 'prev',
+ next: 'next',
+ prevYear: 'prev year',
+ nextYear: 'next year',
+ year: 'year',
+ today: 'today',
+ month: 'month',
+ week: 'week',
+ day: 'day',
+ list: 'list'
+ },
+ weekLabel: 'W',
+ allDayText: 'all-day',
+ eventLimitText: 'more',
+ noEventsMessage: 'No events to display'
+ };
+ function parseRawLocales(explicitRawLocales) {
+ var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
+ var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js
+ var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless
+ var allRawLocales = globalArray.concat(// globalArray is low prio
+ hashValuesToArray(globalObject), // medium prio
+ explicitRawLocales // highest prio
+ );
+ var rawLocaleMap = {
+ en: RAW_EN_LOCALE // necessary?
+ };
+ for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
+ var rawLocale = allRawLocales_1[_i];
+ rawLocaleMap[rawLocale.code] = rawLocale;
+ }
+ return {
+ map: rawLocaleMap,
+ defaultCode: defaultCode
+ };
+ }
+ function buildLocale(inputSingular, available) {
+ if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
+ return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
+ }
+ else {
+ return queryLocale(inputSingular, available);
+ }
+ }
+ function queryLocale(codeArg, available) {
+ var codes = [].concat(codeArg || []); // will convert to array
+ var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
+ return parseLocale(codeArg, codes, raw);
+ }
+ function queryRawLocale(codes, available) {
+ for (var i = 0; i < codes.length; i++) {
+ var parts = codes[i].toLocaleLowerCase().split('-');
+ for (var j = parts.length; j > 0; j--) {
+ var simpleId = parts.slice(0, j).join('-');
+ if (available[simpleId]) {
+ return available[simpleId];
+ }
+ }
+ }
+ return null;
+ }
+ function parseLocale(codeArg, codes, raw) {
+ var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
+ delete merged.code; // don't want this part of the options
+ var week = merged.week;
+ delete merged.week;
+ return {
+ codeArg: codeArg,
+ codes: codes,
+ week: week,
+ simpleNumberFormat: new Intl.NumberFormat(codeArg),
+ options: merged
+ };
+ }
+
+ var OptionsManager = /** @class */ (function () {
+ function OptionsManager(overrides) {
+ this.overrides = __assign({}, overrides); // make a copy
+ this.dynamicOverrides = {};
+ this.compute();
+ }
+ OptionsManager.prototype.add = function (props) {
+ __assign(this.overrides, props);
+ this.compute();
+ };
+ OptionsManager.prototype.addDynamic = function (props) {
+ __assign(this.dynamicOverrides, props);
+ this.compute();
+ };
+ OptionsManager.prototype.reset = function (props) {
+ this.overrides = props;
+ this.compute();
+ };
+ // Computes the flattened options hash for the calendar and assigns to `this.options`.
+ // Assumes this.overrides and this.dynamicOverrides have already been initialized.
+ OptionsManager.prototype.compute = function () {
+ // TODO: not a very efficient system
+ var locales = firstDefined(// explicit locale option given?
+ this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales);
+ var locale = firstDefined(// explicit locales option given?
+ this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale);
+ var available = parseRawLocales(locales);
+ var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options;
+ var dir = firstDefined(// based on options computed so far, is direction RTL?
+ this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir);
+ var dirDefaults = dir === 'rtl' ? rtlDefaults : {};
+ this.dirDefaults = dirDefaults;
+ this.localeDefaults = localeDefaults;
+ this.computed = mergeOptions([
+ globalDefaults,
+ dirDefaults,
+ localeDefaults,
+ this.overrides,
+ this.dynamicOverrides
+ ]);
+ };
+ return OptionsManager;
+ }());
+
+ var calendarSystemClassMap = {};
+ function registerCalendarSystem(name, theClass) {
+ calendarSystemClassMap[name] = theClass;
+ }
+ function createCalendarSystem(name) {
+ return new calendarSystemClassMap[name]();
+ }
+ var GregorianCalendarSystem = /** @class */ (function () {
+ function GregorianCalendarSystem() {
+ }
+ GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
+ return d.getUTCFullYear();
+ };
+ GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
+ return d.getUTCMonth();
+ };
+ GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
+ return d.getUTCDate();
+ };
+ GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
+ return arrayToUtcDate(arr);
+ };
+ GregorianCalendarSystem.prototype.markerToArray = function (marker) {
+ return dateToUtcArray(marker);
+ };
+ return GregorianCalendarSystem;
+ }());
+ registerCalendarSystem('gregory', GregorianCalendarSystem);
+
+ var ISO_START = /^\s*\d{4}-\d\d-\d\d([T ]\d)?/;
+ var ISO_TZO_RE = /(?:(Z)|([-+])(\d\d)(?::(\d\d))?)$/;
+ function parse(str) {
+ var timeZoneOffset = null;
+ var isTimeUnspecified = false;
+ var m = ISO_START.exec(str);
+ if (m) {
+ isTimeUnspecified = !m[1];
+ if (isTimeUnspecified) {
+ str += 'T00:00:00Z';
+ }
+ else {
+ str = str.replace(ISO_TZO_RE, function (whole, z, sign, minutes, seconds) {
+ if (z) {
+ timeZoneOffset = 0;
+ }
+ else {
+ timeZoneOffset = (parseInt(minutes, 10) * 60 +
+ parseInt(seconds || 0, 10)) * (sign === '-' ? -1 : 1);
+ }
+ return '';
+ }) + 'Z'; // otherwise will parse in local
+ }
+ }
+ var marker = new Date(str);
+ if (!isValidDate(marker)) {
+ return null;
+ }
+ return {
+ marker: marker,
+ isTimeUnspecified: isTimeUnspecified,
+ timeZoneOffset: timeZoneOffset
+ };
+ }
+
+ var DateEnv = /** @class */ (function () {
+ function DateEnv(settings) {
+ var timeZone = this.timeZone = settings.timeZone;
+ var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
+ if (settings.namedTimeZoneImpl && isNamedTimeZone) {
+ this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
+ }
+ this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
+ this.calendarSystem = createCalendarSystem(settings.calendarSystem);
+ this.locale = settings.locale;
+ this.weekDow = settings.locale.week.dow;
+ this.weekDoy = settings.locale.week.doy;
+ if (settings.weekNumberCalculation === 'ISO') {
+ this.weekDow = 1;
+ this.weekDoy = 4;
+ }
+ else if (typeof settings.firstDay === 'number') {
+ this.weekDow = settings.firstDay;
+ }
+ if (typeof settings.weekNumberCalculation === 'function') {
+ this.weekNumberFunc = settings.weekNumberCalculation;
+ }
+ this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel;
+ this.cmdFormatter = settings.cmdFormatter;
+ }
+ // Creating / Parsing
+ DateEnv.prototype.createMarker = function (input) {
+ var meta = this.createMarkerMeta(input);
+ if (meta === null) {
+ return null;
+ }
+ return meta.marker;
+ };
+ DateEnv.prototype.createNowMarker = function () {
+ if (this.canComputeOffset) {
+ return this.timestampToMarker(new Date().valueOf());
+ }
+ else {
+ // if we can't compute the current date val for a timezone,
+ // better to give the current local date vals than UTC
+ return arrayToUtcDate(dateToLocalArray(new Date()));
+ }
+ };
+ DateEnv.prototype.createMarkerMeta = function (input) {
+ if (typeof input === 'string') {
+ return this.parse(input);
+ }
+ var marker = null;
+ if (typeof input === 'number') {
+ marker = this.timestampToMarker(input);
+ }
+ else if (input instanceof Date) {
+ input = input.valueOf();
+ if (!isNaN(input)) {
+ marker = this.timestampToMarker(input);
+ }
+ }
+ else if (Array.isArray(input)) {
+ marker = arrayToUtcDate(input);
+ }
+ if (marker === null || !isValidDate(marker)) {
+ return null;
+ }
+ return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
+ };
+ DateEnv.prototype.parse = function (s) {
+ var parts = parse(s);
+ if (parts === null) {
+ return null;
+ }
+ var marker = parts.marker;
+ var forcedTzo = null;
+ if (parts.timeZoneOffset !== null) {
+ if (this.canComputeOffset) {
+ marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
+ }
+ else {
+ forcedTzo = parts.timeZoneOffset;
+ }
+ }
+ return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
+ };
+ // Accessors
+ DateEnv.prototype.getYear = function (marker) {
+ return this.calendarSystem.getMarkerYear(marker);
+ };
+ DateEnv.prototype.getMonth = function (marker) {
+ return this.calendarSystem.getMarkerMonth(marker);
+ };
+ // Adding / Subtracting
+ DateEnv.prototype.add = function (marker, dur) {
+ var a = this.calendarSystem.markerToArray(marker);
+ a[0] += dur.years;
+ a[1] += dur.months;
+ a[2] += dur.days;
+ a[6] += dur.milliseconds;
+ return this.calendarSystem.arrayToMarker(a);
+ };
+ DateEnv.prototype.subtract = function (marker, dur) {
+ var a = this.calendarSystem.markerToArray(marker);
+ a[0] -= dur.years;
+ a[1] -= dur.months;
+ a[2] -= dur.days;
+ a[6] -= dur.milliseconds;
+ return this.calendarSystem.arrayToMarker(a);
+ };
+ DateEnv.prototype.addYears = function (marker, n) {
+ var a = this.calendarSystem.markerToArray(marker);
+ a[0] += n;
+ return this.calendarSystem.arrayToMarker(a);
+ };
+ DateEnv.prototype.addMonths = function (marker, n) {
+ var a = this.calendarSystem.markerToArray(marker);
+ a[1] += n;
+ return this.calendarSystem.arrayToMarker(a);
+ };
+ // Diffing Whole Units
+ DateEnv.prototype.diffWholeYears = function (m0, m1) {
+ var calendarSystem = this.calendarSystem;
+ if (timeAsMs(m0) === timeAsMs(m1) &&
+ calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
+ calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
+ return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
+ }
+ return null;
+ };
+ DateEnv.prototype.diffWholeMonths = function (m0, m1) {
+ var calendarSystem = this.calendarSystem;
+ if (timeAsMs(m0) === timeAsMs(m1) &&
+ calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
+ return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
+ (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
+ }
+ return null;
+ };
+ // Range / Duration
+ DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
+ var n = this.diffWholeYears(m0, m1);
+ if (n !== null) {
+ return { unit: 'year', value: n };
+ }
+ n = this.diffWholeMonths(m0, m1);
+ if (n !== null) {
+ return { unit: 'month', value: n };
+ }
+ n = diffWholeWeeks(m0, m1);
+ if (n !== null) {
+ return { unit: 'week', value: n };
+ }
+ n = diffWholeDays(m0, m1);
+ if (n !== null) {
+ return { unit: 'day', value: n };
+ }
+ n = diffHours(m0, m1);
+ if (isInt(n)) {
+ return { unit: 'hour', value: n };
+ }
+ n = diffMinutes(m0, m1);
+ if (isInt(n)) {
+ return { unit: 'minute', value: n };
+ }
+ n = diffSeconds(m0, m1);
+ if (isInt(n)) {
+ return { unit: 'second', value: n };
+ }
+ return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
+ };
+ DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
+ // TODO: can use greatestWholeUnit
+ var diff;
+ if (d.years) {
+ diff = this.diffWholeYears(m0, m1);
+ if (diff !== null) {
+ return diff / asRoughYears(d);
+ }
+ }
+ if (d.months) {
+ diff = this.diffWholeMonths(m0, m1);
+ if (diff !== null) {
+ return diff / asRoughMonths(d);
+ }
+ }
+ if (d.days) {
+ diff = diffWholeDays(m0, m1);
+ if (diff !== null) {
+ return diff / asRoughDays(d);
+ }
+ }
+ return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
+ };
+ // Start-Of
+ DateEnv.prototype.startOf = function (m, unit) {
+ if (unit === 'year') {
+ return this.startOfYear(m);
+ }
+ else if (unit === 'month') {
+ return this.startOfMonth(m);
+ }
+ else if (unit === 'week') {
+ return this.startOfWeek(m);
+ }
+ else if (unit === 'day') {
+ return startOfDay(m);
+ }
+ else if (unit === 'hour') {
+ return startOfHour(m);
+ }
+ else if (unit === 'minute') {
+ return startOfMinute(m);
+ }
+ else if (unit === 'second') {
+ return startOfSecond(m);
+ }
+ };
+ DateEnv.prototype.startOfYear = function (m) {
+ return this.calendarSystem.arrayToMarker([
+ this.calendarSystem.getMarkerYear(m)
+ ]);
+ };
+ DateEnv.prototype.startOfMonth = function (m) {
+ return this.calendarSystem.arrayToMarker([
+ this.calendarSystem.getMarkerYear(m),
+ this.calendarSystem.getMarkerMonth(m)
+ ]);
+ };
+ DateEnv.prototype.startOfWeek = function (m) {
+ return this.calendarSystem.arrayToMarker([
+ this.calendarSystem.getMarkerYear(m),
+ this.calendarSystem.getMarkerMonth(m),
+ m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
+ ]);
+ };
+ // Week Number
+ DateEnv.prototype.computeWeekNumber = function (marker) {
+ if (this.weekNumberFunc) {
+ return this.weekNumberFunc(this.toDate(marker));
+ }
+ else {
+ return weekOfYear(marker, this.weekDow, this.weekDoy);
+ }
+ };
+ // TODO: choke on timeZoneName: long
+ DateEnv.prototype.format = function (marker, formatter, dateOptions) {
+ if (dateOptions === void 0) { dateOptions = {}; }
+ return formatter.format({
+ marker: marker,
+ timeZoneOffset: dateOptions.forcedTzo != null ?
+ dateOptions.forcedTzo :
+ this.offsetForMarker(marker)
+ }, this);
+ };
+ DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
+ if (dateOptions === void 0) { dateOptions = {}; }
+ if (dateOptions.isEndExclusive) {
+ end = addMs(end, -1);
+ }
+ return formatter.formatRange({
+ marker: start,
+ timeZoneOffset: dateOptions.forcedStartTzo != null ?
+ dateOptions.forcedStartTzo :
+ this.offsetForMarker(start)
+ }, {
+ marker: end,
+ timeZoneOffset: dateOptions.forcedEndTzo != null ?
+ dateOptions.forcedEndTzo :
+ this.offsetForMarker(end)
+ }, this);
+ };
+ DateEnv.prototype.formatIso = function (marker, extraOptions) {
+ if (extraOptions === void 0) { extraOptions = {}; }
+ var timeZoneOffset = null;
+ if (!extraOptions.omitTimeZoneOffset) {
+ if (extraOptions.forcedTzo != null) {
+ timeZoneOffset = extraOptions.forcedTzo;
+ }
+ else {
+ timeZoneOffset = this.offsetForMarker(marker);
+ }
+ }
+ return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
+ };
+ // TimeZone
+ DateEnv.prototype.timestampToMarker = function (ms) {
+ if (this.timeZone === 'local') {
+ return arrayToUtcDate(dateToLocalArray(new Date(ms)));
+ }
+ else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
+ return new Date(ms);
+ }
+ else {
+ return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
+ }
+ };
+ DateEnv.prototype.offsetForMarker = function (m) {
+ if (this.timeZone === 'local') {
+ return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
+ }
+ else if (this.timeZone === 'UTC') {
+ return 0;
+ }
+ else if (this.namedTimeZoneImpl) {
+ return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
+ }
+ return null;
+ };
+ // Conversion
+ DateEnv.prototype.toDate = function (m, forcedTzo) {
+ if (this.timeZone === 'local') {
+ return arrayToLocalDate(dateToUtcArray(m));
+ }
+ else if (this.timeZone === 'UTC') {
+ return new Date(m.valueOf()); // make sure it's a copy
+ }
+ else if (!this.namedTimeZoneImpl) {
+ return new Date(m.valueOf() - (forcedTzo || 0));
+ }
+ else {
+ return new Date(m.valueOf() -
+ this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
+ );
+ }
+ };
+ return DateEnv;
+ }());
+
+ var SIMPLE_SOURCE_PROPS = {
+ id: String,
+ allDayDefault: Boolean,
+ eventDataTransform: Function,
+ success: Function,
+ failure: Function
+ };
+ var uid$2 = 0;
+ function doesSourceNeedRange(eventSource, calendar) {
+ var defs = calendar.pluginSystem.hooks.eventSourceDefs;
+ return !defs[eventSource.sourceDefId].ignoreRange;
+ }
+ function parseEventSource(raw, calendar) {
+ var defs = calendar.pluginSystem.hooks.eventSourceDefs;
+ for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
+ var def = defs[i];
+ var meta = def.parseMeta(raw);
+ if (meta) {
+ var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar);
+ res._raw = freezeRaw(raw);
+ return res;
+ }
+ }
+ return null;
+ }
+ function parseEventSourceProps(raw, meta, sourceDefId, calendar) {
+ var leftovers0 = {};
+ var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0);
+ var leftovers1 = {};
+ var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1);
+ props.isFetching = false;
+ props.latestFetchId = '';
+ props.fetchRange = null;
+ props.publicId = String(raw.id || '');
+ props.sourceId = String(uid$2++);
+ props.sourceDefId = sourceDefId;
+ props.meta = meta;
+ props.ui = ui;
+ props.extendedProps = leftovers1;
+ return props;
+ }
+
+ function reduceEventSources (eventSources, action, dateProfile, calendar) {
+ switch (action.type) {
+ case 'ADD_EVENT_SOURCES': // already parsed
+ return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
+ case 'REMOVE_EVENT_SOURCE':
+ return removeSource(eventSources, action.sourceId);
+ case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
+ case 'NEXT':
+ case 'SET_DATE':
+ case 'SET_VIEW_TYPE':
+ if (dateProfile) {
+ return fetchDirtySources(eventSources, dateProfile.activeRange, calendar);
+ }
+ else {
+ return eventSources;
+ }
+ case 'FETCH_EVENT_SOURCES':
+ case 'CHANGE_TIMEZONE':
+ return fetchSourcesByIds(eventSources, action.sourceIds ?
+ arrayToHash(action.sourceIds) :
+ excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar);
+ case 'RECEIVE_EVENTS':
+ case 'RECEIVE_EVENT_ERROR':
+ return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
+ case 'REMOVE_ALL_EVENT_SOURCES':
+ return {};
+ default:
+ return eventSources;
+ }
+ }
+ var uid$3 = 0;
+ function addSources(eventSourceHash, sources, fetchRange, calendar) {
+ var hash = {};
+ for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
+ var source = sources_1[_i];
+ hash[source.sourceId] = source;
+ }
+ if (fetchRange) {
+ hash = fetchDirtySources(hash, fetchRange, calendar);
+ }
+ return __assign({}, eventSourceHash, hash);
+ }
+ function removeSource(eventSourceHash, sourceId) {
+ return filterHash(eventSourceHash, function (eventSource) {
+ return eventSource.sourceId !== sourceId;
+ });
+ }
+ function fetchDirtySources(sourceHash, fetchRange, calendar) {
+ return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
+ return isSourceDirty(eventSource, fetchRange, calendar);
+ }), fetchRange, calendar);
+ }
+ function isSourceDirty(eventSource, fetchRange, calendar) {
+ if (!doesSourceNeedRange(eventSource, calendar)) {
+ return !eventSource.latestFetchId;
+ }
+ else {
+ return !calendar.opt('lazyFetching') ||
+ !eventSource.fetchRange ||
+ fetchRange.start < eventSource.fetchRange.start ||
+ fetchRange.end > eventSource.fetchRange.end;
+ }
+ }
+ function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) {
+ var nextSources = {};
+ for (var sourceId in prevSources) {
+ var source = prevSources[sourceId];
+ if (sourceIdHash[sourceId]) {
+ nextSources[sourceId] = fetchSource(source, fetchRange, calendar);
+ }
+ else {
+ nextSources[sourceId] = source;
+ }
+ }
+ return nextSources;
+ }
+ function fetchSource(eventSource, fetchRange, calendar) {
+ var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId];
+ var fetchId = String(uid$3++);
+ sourceDef.fetch({
+ eventSource: eventSource,
+ calendar: calendar,
+ range: fetchRange
+ }, function (res) {
+ var rawEvents = res.rawEvents;
+ var calSuccess = calendar.opt('eventSourceSuccess');
+ var calSuccessRes;
+ var sourceSuccessRes;
+ if (eventSource.success) {
+ sourceSuccessRes = eventSource.success(rawEvents, res.xhr);
+ }
+ if (calSuccess) {
+ calSuccessRes = calSuccess(rawEvents, res.xhr);
+ }
+ rawEvents = sourceSuccessRes || calSuccessRes || rawEvents;
+ calendar.dispatch({
+ type: 'RECEIVE_EVENTS',
+ sourceId: eventSource.sourceId,
+ fetchId: fetchId,
+ fetchRange: fetchRange,
+ rawEvents: rawEvents
+ });
+ }, function (error) {
+ var callFailure = calendar.opt('eventSourceFailure');
+ console.warn(error.message, error);
+ if (eventSource.failure) {
+ eventSource.failure(error);
+ }
+ if (callFailure) {
+ callFailure(error);
+ }
+ calendar.dispatch({
+ type: 'RECEIVE_EVENT_ERROR',
+ sourceId: eventSource.sourceId,
+ fetchId: fetchId,
+ fetchRange: fetchRange,
+ error: error
+ });
+ });
+ return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId });
+ }
+ function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
+ var _a;
+ var eventSource = sourceHash[sourceId];
+ if (eventSource && // not already removed
+ fetchId === eventSource.latestFetchId) {
+ return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange }), _a));
+ }
+ return sourceHash;
+ }
+ function excludeStaticSources(eventSources, calendar) {
+ return filterHash(eventSources, function (eventSource) {
+ return doesSourceNeedRange(eventSource, calendar);
+ });
+ }
+
+ var DateProfileGenerator = /** @class */ (function () {
+ function DateProfileGenerator(viewSpec, calendar) {
+ this.viewSpec = viewSpec;
+ this.options = viewSpec.options;
+ this.dateEnv = calendar.dateEnv;
+ this.calendar = calendar;
+ this.initHiddenDays();
+ }
+ /* Date Range Computation
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Builds a structure with info about what the dates/ranges will be for the "prev" view.
+ DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) {
+ var dateEnv = this.dateEnv;
+ var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
+ currentDateProfile.dateIncrement);
+ return this.build(prevDate, -1);
+ };
+ // Builds a structure with info about what the dates/ranges will be for the "next" view.
+ DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) {
+ var dateEnv = this.dateEnv;
+ var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
+ currentDateProfile.dateIncrement);
+ return this.build(nextDate, 1);
+ };
+ // Builds a structure holding dates/ranges for rendering around the given date.
+ // Optional direction param indicates whether the date is being incremented/decremented
+ // from its previous value. decremented = -1, incremented = 1 (default).
+ DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
+ if (forceToValid === void 0) { forceToValid = false; }
+ var validRange;
+ var minTime = null;
+ var maxTime = null;
+ var currentInfo;
+ var isRangeAllDay;
+ var renderRange;
+ var activeRange;
+ var isValid;
+ validRange = this.buildValidRange();
+ validRange = this.trimHiddenDays(validRange);
+ if (forceToValid) {
+ currentDate = constrainMarkerToRange(currentDate, validRange);
+ }
+ currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
+ isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
+ renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
+ renderRange = this.trimHiddenDays(renderRange);
+ activeRange = renderRange;
+ if (!this.options.showNonCurrentDates) {
+ activeRange = intersectRanges(activeRange, currentInfo.range);
+ }
+ minTime = createDuration(this.options.minTime);
+ maxTime = createDuration(this.options.maxTime);
+ activeRange = this.adjustActiveRange(activeRange, minTime, maxTime);
+ activeRange = intersectRanges(activeRange, validRange); // might return null
+ // it's invalid if the originally requested date is not contained,
+ // or if the range is completely outside of the valid range.
+ isValid = rangesIntersect(currentInfo.range, validRange);
+ return {
+ // constraint for where prev/next operations can go and where events can be dragged/resized to.
+ // an object with optional start and end properties.
+ validRange: validRange,
+ // range the view is formally responsible for.
+ // for example, a month view might have 1st-31st, excluding padded dates
+ currentRange: currentInfo.range,
+ // name of largest unit being displayed, like "month" or "week"
+ currentRangeUnit: currentInfo.unit,
+ isRangeAllDay: isRangeAllDay,
+ // dates that display events and accept drag-n-drop
+ // will be `null` if no dates accept events
+ activeRange: activeRange,
+ // date range with a rendered skeleton
+ // includes not-active days that need some sort of DOM
+ renderRange: renderRange,
+ // Duration object that denotes the first visible time of any given day
+ minTime: minTime,
+ // Duration object that denotes the exclusive visible end time of any given day
+ maxTime: maxTime,
+ isValid: isValid,
+ // how far the current date will move for a prev/next operation
+ dateIncrement: this.buildDateIncrement(currentInfo.duration)
+ // pass a fallback (might be null) ^
+ };
+ };
+ // Builds an object with optional start/end properties.
+ // Indicates the minimum/maximum dates to display.
+ // not responsible for trimming hidden days.
+ DateProfileGenerator.prototype.buildValidRange = function () {
+ return this.getRangeOption('validRange', this.calendar.getNow()) ||
+ { start: null, end: null }; // completely open-ended
+ };
+ // Builds a structure with info about the "current" range, the range that is
+ // highlighted as being the current month for example.
+ // See build() for a description of `direction`.
+ // Guaranteed to have `range` and `unit` properties. `duration` is optional.
+ DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
+ var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv;
+ var duration = null;
+ var unit = null;
+ var range = null;
+ var dayCount;
+ if (viewSpec.duration) {
+ duration = viewSpec.duration;
+ unit = viewSpec.durationUnit;
+ range = this.buildRangeFromDuration(date, direction, duration, unit);
+ }
+ else if ((dayCount = this.options.dayCount)) {
+ unit = 'day';
+ range = this.buildRangeFromDayCount(date, direction, dayCount);
+ }
+ else if ((range = this.buildCustomVisibleRange(date))) {
+ unit = dateEnv.greatestWholeUnit(range.start, range.end).unit;
+ }
+ else {
+ duration = this.getFallbackDuration();
+ unit = greatestDurationDenominator(duration).unit;
+ range = this.buildRangeFromDuration(date, direction, duration, unit);
+ }
+ return { duration: duration, unit: unit, range: range };
+ };
+ DateProfileGenerator.prototype.getFallbackDuration = function () {
+ return createDuration({ day: 1 });
+ };
+ // Returns a new activeRange to have time values (un-ambiguate)
+ // minTime or maxTime causes the range to expand.
+ DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) {
+ var dateEnv = this.dateEnv;
+ var start = range.start;
+ var end = range.end;
+ if (this.viewSpec.class.prototype.usesMinMaxTime) {
+ // expand active range if minTime is negative (why not when positive?)
+ if (asRoughDays(minTime) < 0) {
+ start = startOfDay(start); // necessary?
+ start = dateEnv.add(start, minTime);
+ }
+ // expand active range if maxTime is beyond one day (why not when positive?)
+ if (asRoughDays(maxTime) > 1) {
+ end = startOfDay(end); // necessary?
+ end = addDays(end, -1);
+ end = dateEnv.add(end, maxTime);
+ }
+ }
+ return { start: start, end: end };
+ };
+ // Builds the "current" range when it is specified as an explicit duration.
+ // `unit` is the already-computed greatestDurationDenominator unit of duration.
+ DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
+ var dateEnv = this.dateEnv;
+ var alignment = this.options.dateAlignment;
+ var dateIncrementInput;
+ var dateIncrementDuration;
+ var start;
+ var end;
+ var res;
+ // compute what the alignment should be
+ if (!alignment) {
+ dateIncrementInput = this.options.dateIncrement;
+ if (dateIncrementInput) {
+ dateIncrementDuration = createDuration(dateIncrementInput);
+ // use the smaller of the two units
+ if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) {
+ alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit;
+ }
+ else {
+ alignment = unit;
+ }
+ }
+ else {
+ alignment = unit;
+ }
+ }
+ // if the view displays a single day or smaller
+ if (asRoughDays(duration) <= 1) {
+ if (this.isHiddenDay(start)) {
+ start = this.skipHiddenDays(start, direction);
+ start = startOfDay(start);
+ }
+ }
+ function computeRes() {
+ start = dateEnv.startOf(date, alignment);
+ end = dateEnv.add(start, duration);
+ res = { start: start, end: end };
+ }
+ computeRes();
+ // if range is completely enveloped by hidden days, go past the hidden days
+ if (!this.trimHiddenDays(res)) {
+ date = this.skipHiddenDays(date, direction);
+ computeRes();
+ }
+ return res;
+ };
+ // Builds the "current" range when a dayCount is specified.
+ DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
+ var dateEnv = this.dateEnv;
+ var customAlignment = this.options.dateAlignment;
+ var runningCount = 0;
+ var start = date;
+ var end;
+ if (customAlignment) {
+ start = dateEnv.startOf(start, customAlignment);
+ }
+ start = startOfDay(start);
+ start = this.skipHiddenDays(start, direction);
+ end = start;
+ do {
+ end = addDays(end, 1);
+ if (!this.isHiddenDay(end)) {
+ runningCount++;
+ }
+ } while (runningCount < dayCount);
+ return { start: start, end: end };
+ };
+ // Builds a normalized range object for the "visible" range,
+ // which is a way to define the currentRange and activeRange at the same time.
+ DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
+ var dateEnv = this.dateEnv;
+ var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date));
+ if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) {
+ return null;
+ }
+ return visibleRange;
+ };
+ // Computes the range that will represent the element/cells for *rendering*,
+ // but which may have voided days/times.
+ // not responsible for trimming hidden days.
+ DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
+ return currentRange;
+ };
+ // Compute the duration value that should be added/substracted to the current date
+ // when a prev/next operation happens.
+ DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
+ var dateIncrementInput = this.options.dateIncrement;
+ var customAlignment;
+ if (dateIncrementInput) {
+ return createDuration(dateIncrementInput);
+ }
+ else if ((customAlignment = this.options.dateAlignment)) {
+ return createDuration(1, customAlignment);
+ }
+ else if (fallback) {
+ return fallback;
+ }
+ else {
+ return createDuration({ days: 1 });
+ }
+ };
+ // Arguments after name will be forwarded to a hypothetical function value
+ // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
+ // Always clone your objects if you fear mutation.
+ DateProfileGenerator.prototype.getRangeOption = function (name) {
+ var otherArgs = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ otherArgs[_i - 1] = arguments[_i];
+ }
+ var val = this.options[name];
+ if (typeof val === 'function') {
+ val = val.apply(null, otherArgs);
+ }
+ if (val) {
+ val = parseRange(val, this.dateEnv);
+ }
+ if (val) {
+ val = computeVisibleDayRange(val);
+ }
+ return val;
+ };
+ /* Hidden Days
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Initializes internal variables related to calculating hidden days-of-week
+ DateProfileGenerator.prototype.initHiddenDays = function () {
+ var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
+ var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
+ var dayCnt = 0;
+ var i;
+ if (this.options.weekends === false) {
+ hiddenDays.push(0, 6); // 0=sunday, 6=saturday
+ }
+ for (i = 0; i < 7; i++) {
+ if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
+ dayCnt++;
+ }
+ }
+ if (!dayCnt) {
+ throw new Error('invalid hiddenDays'); // all days were hidden? bad.
+ }
+ this.isHiddenDayHash = isHiddenDayHash;
+ };
+ // Remove days from the beginning and end of the range that are computed as hidden.
+ // If the whole range is trimmed off, returns null
+ DateProfileGenerator.prototype.trimHiddenDays = function (range) {
+ var start = range.start;
+ var end = range.end;
+ if (start) {
+ start = this.skipHiddenDays(start);
+ }
+ if (end) {
+ end = this.skipHiddenDays(end, -1, true);
+ }
+ if (start == null || end == null || start < end) {
+ return { start: start, end: end };
+ }
+ return null;
+ };
+ // Is the current day hidden?
+ // `day` is a day-of-week index (0-6), or a Date (used for UTC)
+ DateProfileGenerator.prototype.isHiddenDay = function (day) {
+ if (day instanceof Date) {
+ day = day.getUTCDay();
+ }
+ return this.isHiddenDayHash[day];
+ };
+ // Incrementing the current day until it is no longer a hidden day, returning a copy.
+ // DOES NOT CONSIDER validRange!
+ // If the initial value of `date` is not a hidden day, don't do anything.
+ // Pass `isExclusive` as `true` if you are dealing with an end date.
+ // `inc` defaults to `1` (increment one day forward each time)
+ DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
+ if (inc === void 0) { inc = 1; }
+ if (isExclusive === void 0) { isExclusive = false; }
+ while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
+ date = addDays(date, inc);
+ }
+ return date;
+ };
+ return DateProfileGenerator;
+ }());
+ // TODO: find a way to avoid comparing DateProfiles. it's tedious
+ function isDateProfilesEqual(p0, p1) {
+ return rangesEqual(p0.activeRange, p1.activeRange) &&
+ rangesEqual(p0.validRange, p1.validRange) &&
+ durationsEqual(p0.minTime, p1.minTime) &&
+ durationsEqual(p0.maxTime, p1.maxTime);
+ }
+
+ function reduce (state, action, calendar) {
+ var viewType = reduceViewType(state.viewType, action);
+ var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar);
+ var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar);
+ var nextState = __assign({}, state, { viewType: viewType,
+ dateProfile: dateProfile, currentDate: reduceCurrentDate(state.currentDate, action, dateProfile), eventSources: eventSources, eventStore: reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendar), dateSelection: reduceDateSelection(state.dateSelection, action, calendar), eventSelection: reduceSelectedEvent(state.eventSelection, action), eventDrag: reduceEventDrag(state.eventDrag, action, eventSources, calendar), eventResize: reduceEventResize(state.eventResize, action, eventSources, calendar), eventSourceLoadingLevel: computeLoadingLevel(eventSources), loadingLevel: computeLoadingLevel(eventSources) });
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) {
+ var reducerFunc = _a[_i];
+ nextState = reducerFunc(nextState, action, calendar);
+ }
+ // console.log(action.type, nextState)
+ return nextState;
+ }
+ function reduceViewType(currentViewType, action) {
+ switch (action.type) {
+ case 'SET_VIEW_TYPE':
+ return action.viewType;
+ default:
+ return currentViewType;
+ }
+ }
+ function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) {
+ var newDateProfile;
+ switch (action.type) {
+ case 'PREV':
+ newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate);
+ break;
+ case 'NEXT':
+ newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate);
+ break;
+ case 'SET_DATE':
+ if (!currentDateProfile.activeRange ||
+ !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) {
+ newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid
+ );
+ }
+ break;
+ case 'SET_VIEW_TYPE':
+ var generator = calendar.dateProfileGenerators[viewType];
+ if (!generator) {
+ throw new Error(viewType ?
+ 'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' :
+ 'No available FullCalendar view plugins.');
+ }
+ newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid
+ );
+ break;
+ }
+ if (newDateProfile &&
+ newDateProfile.isValid &&
+ !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) {
+ return newDateProfile;
+ }
+ else {
+ return currentDateProfile;
+ }
+ }
+ function reduceCurrentDate(currentDate, action, dateProfile) {
+ switch (action.type) {
+ case 'PREV':
+ case 'NEXT':
+ if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
+ return dateProfile.currentRange.start;
+ }
+ else {
+ return currentDate;
+ }
+ case 'SET_DATE':
+ case 'SET_VIEW_TYPE':
+ var newDate = action.dateMarker || currentDate;
+ if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newDate)) {
+ return dateProfile.currentRange.start;
+ }
+ else {
+ return newDate;
+ }
+ default:
+ return currentDate;
+ }
+ }
+ function reduceDateSelection(currentSelection, action, calendar) {
+ switch (action.type) {
+ case 'SELECT_DATES':
+ return action.selection;
+ case 'UNSELECT_DATES':
+ return null;
+ default:
+ return currentSelection;
+ }
+ }
+ function reduceSelectedEvent(currentInstanceId, action) {
+ switch (action.type) {
+ case 'SELECT_EVENT':
+ return action.eventInstanceId;
+ case 'UNSELECT_EVENT':
+ return '';
+ default:
+ return currentInstanceId;
+ }
+ }
+ function reduceEventDrag(currentDrag, action, sources, calendar) {
+ switch (action.type) {
+ case 'SET_EVENT_DRAG':
+ var newDrag = action.state;
+ return {
+ affectedEvents: newDrag.affectedEvents,
+ mutatedEvents: newDrag.mutatedEvents,
+ isEvent: newDrag.isEvent,
+ origSeg: newDrag.origSeg
+ };
+ case 'UNSET_EVENT_DRAG':
+ return null;
+ default:
+ return currentDrag;
+ }
+ }
+ function reduceEventResize(currentResize, action, sources, calendar) {
+ switch (action.type) {
+ case 'SET_EVENT_RESIZE':
+ var newResize = action.state;
+ return {
+ affectedEvents: newResize.affectedEvents,
+ mutatedEvents: newResize.mutatedEvents,
+ isEvent: newResize.isEvent,
+ origSeg: newResize.origSeg
+ };
+ case 'UNSET_EVENT_RESIZE':
+ return null;
+ default:
+ return currentResize;
+ }
+ }
+ function computeLoadingLevel(eventSources) {
+ var cnt = 0;
+ for (var sourceId in eventSources) {
+ if (eventSources[sourceId].isFetching) {
+ cnt++;
+ }
+ }
+ return cnt;
+ }
+
+ var STANDARD_PROPS = {
+ start: null,
+ end: null,
+ allDay: Boolean
+ };
+ function parseDateSpan(raw, dateEnv, defaultDuration) {
+ var span = parseOpenDateSpan(raw, dateEnv);
+ var range = span.range;
+ if (!range.start) {
+ return null;
+ }
+ if (!range.end) {
+ if (defaultDuration == null) {
+ return null;
+ }
+ else {
+ range.end = dateEnv.add(range.start, defaultDuration);
+ }
+ }
+ return span;
+ }
+ /*
+ TODO: somehow combine with parseRange?
+ Will return null if the start/end props were present but parsed invalidly.
+ */
+ function parseOpenDateSpan(raw, dateEnv) {
+ var leftovers = {};
+ var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers);
+ var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
+ var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
+ var allDay = standardProps.allDay;
+ if (allDay == null) {
+ allDay = (startMeta && startMeta.isTimeUnspecified) &&
+ (!endMeta || endMeta.isTimeUnspecified);
+ }
+ // use this leftover object as the selection object
+ leftovers.range = {
+ start: startMeta ? startMeta.marker : null,
+ end: endMeta ? endMeta.marker : null
+ };
+ leftovers.allDay = allDay;
+ return leftovers;
+ }
+ function isDateSpansEqual(span0, span1) {
+ return rangesEqual(span0.range, span1.range) &&
+ span0.allDay === span1.allDay &&
+ isSpanPropsEqual(span0, span1);
+ }
+ // the NON-DATE-RELATED props
+ function isSpanPropsEqual(span0, span1) {
+ for (var propName in span1) {
+ if (propName !== 'range' && propName !== 'allDay') {
+ if (span0[propName] !== span1[propName]) {
+ return false;
+ }
+ }
+ }
+ // are there any props that span0 has that span1 DOESN'T have?
+ // both have range/allDay, so no need to special-case.
+ for (var propName in span0) {
+ if (!(propName in span1)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function buildDateSpanApi(span, dateEnv) {
+ return {
+ start: dateEnv.toDate(span.range.start),
+ end: dateEnv.toDate(span.range.end),
+ startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
+ endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }),
+ allDay: span.allDay
+ };
+ }
+ function buildDatePointApi(span, dateEnv) {
+ return {
+ date: dateEnv.toDate(span.range.start),
+ dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
+ allDay: span.allDay
+ };
+ }
+ function fabricateEventRange(dateSpan, eventUiBases, calendar) {
+ var def = parseEventDef({ editable: false }, '', // sourceId
+ dateSpan.allDay, true, // hasEnd
+ calendar);
+ return {
+ def: def,
+ ui: compileEventUi(def, eventUiBases),
+ instance: createEventInstance(def.defId, dateSpan.range),
+ range: dateSpan.range,
+ isStart: true,
+ isEnd: true
+ };
+ }
+
+ function compileViewDefs(defaultConfigs, overrideConfigs) {
+ var hash = {};
+ var viewType;
+ for (viewType in defaultConfigs) {
+ ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+ }
+ for (viewType in overrideConfigs) {
+ ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+ }
+ return hash;
+ }
+ function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
+ if (hash[viewType]) {
+ return hash[viewType];
+ }
+ var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+ if (viewDef) {
+ hash[viewType] = viewDef;
+ }
+ return viewDef;
+ }
+ function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
+ var defaultConfig = defaultConfigs[viewType];
+ var overrideConfig = overrideConfigs[viewType];
+ var queryProp = function (name) {
+ return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
+ ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
+ };
+ var theClass = queryProp('class');
+ var superType = queryProp('superType');
+ if (!superType && theClass) {
+ superType =
+ findViewNameBySubclass(theClass, overrideConfigs) ||
+ findViewNameBySubclass(theClass, defaultConfigs);
+ }
+ var superDef = superType ? ensureViewDef(superType, hash, defaultConfigs, overrideConfigs) : null;
+ if (!theClass && superDef) {
+ theClass = superDef.class;
+ }
+ if (!theClass) {
+ return null; // don't throw a warning, might be settings for a single-unit view
+ }
+ return {
+ type: viewType,
+ class: theClass,
+ defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})),
+ overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {}))
+ };
+ }
+ function findViewNameBySubclass(viewSubclass, configs) {
+ var superProto = Object.getPrototypeOf(viewSubclass.prototype);
+ for (var viewType in configs) {
+ var parsed = configs[viewType];
+ // need DIRECT subclass, so instanceof won't do it
+ if (parsed.class && parsed.class.prototype === superProto) {
+ return viewType;
+ }
+ }
+ return '';
+ }
+
+ function parseViewConfigs(inputs) {
+ return mapHash(inputs, parseViewConfig);
+ }
+ var VIEW_DEF_PROPS = {
+ type: String,
+ class: null
+ };
+ function parseViewConfig(input) {
+ if (typeof input === 'function') {
+ input = { class: input };
+ }
+ var options = {};
+ var props = refineProps(input, VIEW_DEF_PROPS, {}, options);
+ return {
+ superType: props.type,
+ class: props.class,
+ options: options
+ };
+ }
+
+ function buildViewSpecs(defaultInputs, optionsManager) {
+ var defaultConfigs = parseViewConfigs(defaultInputs);
+ var overrideConfigs = parseViewConfigs(optionsManager.overrides.views);
+ var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
+ return mapHash(viewDefs, function (viewDef) {
+ return buildViewSpec(viewDef, overrideConfigs, optionsManager);
+ });
+ }
+ function buildViewSpec(viewDef, overrideConfigs, optionsManager) {
+ var durationInput = viewDef.overrides.duration ||
+ viewDef.defaults.duration ||
+ optionsManager.dynamicOverrides.duration ||
+ optionsManager.overrides.duration;
+ var duration = null;
+ var durationUnit = '';
+ var singleUnit = '';
+ var singleUnitOverrides = {};
+ if (durationInput) {
+ duration = createDuration(durationInput);
+ if (duration) { // valid?
+ var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput));
+ durationUnit = denom.unit;
+ if (denom.value === 1) {
+ singleUnit = durationUnit;
+ singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {};
+ }
+ }
+ }
+ var queryButtonText = function (options) {
+ var buttonTextMap = options.buttonText || {};
+ var buttonTextKey = viewDef.defaults.buttonTextKey;
+ if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
+ return buttonTextMap[buttonTextKey];
+ }
+ if (buttonTextMap[viewDef.type] != null) {
+ return buttonTextMap[viewDef.type];
+ }
+ if (buttonTextMap[singleUnit] != null) {
+ return buttonTextMap[singleUnit];
+ }
+ };
+ return {
+ type: viewDef.type,
+ class: viewDef.class,
+ duration: duration,
+ durationUnit: durationUnit,
+ singleUnit: singleUnit,
+ options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides),
+ buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) ||
+ queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
+ viewDef.overrides.buttonText,
+ buttonTextDefault: queryButtonText(optionsManager.localeDefaults) ||
+ queryButtonText(optionsManager.dirDefaults) ||
+ viewDef.defaults.buttonText ||
+ queryButtonText(globalDefaults) ||
+ viewDef.type // fall back to given view name
+ };
+ }
+
+ var Toolbar = /** @class */ (function (_super) {
+ __extends(Toolbar, _super);
+ function Toolbar(context, extraClassName) {
+ var _this = _super.call(this, context) || this;
+ _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout);
+ _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]);
+ _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]);
+ _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]);
+ _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]);
+ _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]);
+ _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName });
+ return _this;
+ }
+ Toolbar.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this._renderLayout.unrender(); // should unrender everything else
+ removeElement(this.el);
+ };
+ Toolbar.prototype.render = function (props) {
+ this._renderLayout(props.layout);
+ this._updateTitle(props.title);
+ this._updateActiveButton(props.activeButton);
+ this._updateToday(props.isTodayEnabled);
+ this._updatePrev(props.isPrevEnabled);
+ this._updateNext(props.isNextEnabled);
+ };
+ Toolbar.prototype.renderLayout = function (layout) {
+ var el = this.el;
+ this.viewsWithButtons = [];
+ appendToElement(el, this.renderSection('left', layout.left));
+ appendToElement(el, this.renderSection('center', layout.center));
+ appendToElement(el, this.renderSection('right', layout.right));
+ };
+ Toolbar.prototype.unrenderLayout = function () {
+ this.el.innerHTML = '';
+ };
+ Toolbar.prototype.renderSection = function (position, buttonStr) {
+ var _this = this;
+ var _a = this, theme = _a.theme, calendar = _a.calendar;
+ var optionsManager = calendar.optionsManager;
+ var viewSpecs = calendar.viewSpecs;
+ var sectionEl = createElement('div', { className: 'fc-' + position });
+ var calendarCustomButtons = optionsManager.computed.customButtons || {};
+ var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
+ var calendarButtonText = optionsManager.computed.buttonText || {};
+ if (buttonStr) {
+ buttonStr.split(' ').forEach(function (buttonGroupStr, i) {
+ var groupChildren = [];
+ var isOnlyButtons = true;
+ var groupEl;
+ buttonGroupStr.split(',').forEach(function (buttonName, j) {
+ var customButtonProps;
+ var viewSpec;
+ var buttonClick;
+ var buttonIcon; // only one of these will be set
+ var buttonText; // "
+ var buttonInnerHtml;
+ var buttonClasses;
+ var buttonEl;
+ var buttonAriaAttr;
+ if (buttonName === 'title') {
+ groupChildren.push(htmlToElement('<h2>&nbsp;</h2>')); // we always want it to take up height
+ isOnlyButtons = false;
+ }
+ else {
+ if ((customButtonProps = calendarCustomButtons[buttonName])) {
+ buttonClick = function (ev) {
+ if (customButtonProps.click) {
+ customButtonProps.click.call(buttonEl, ev);
+ }
+ };
+ (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
+ (buttonIcon = theme.getIconClass(buttonName)) ||
+ (buttonText = customButtonProps.text);
+ }
+ else if ((viewSpec = viewSpecs[buttonName])) {
+ _this.viewsWithButtons.push(buttonName);
+ buttonClick = function () {
+ calendar.changeView(buttonName);
+ };
+ (buttonText = viewSpec.buttonTextOverride) ||
+ (buttonIcon = theme.getIconClass(buttonName)) ||
+ (buttonText = viewSpec.buttonTextDefault);
+ }
+ else if (calendar[buttonName]) { // a calendar method
+ buttonClick = function () {
+ calendar[buttonName]();
+ };
+ (buttonText = calendarButtonTextOverrides[buttonName]) ||
+ (buttonIcon = theme.getIconClass(buttonName)) ||
+ (buttonText = calendarButtonText[buttonName]);
+ // ^ everything else is considered default
+ }
+ if (buttonClick) {
+ buttonClasses = [
+ 'fc-' + buttonName + '-button',
+ theme.getClass('button')
+ ];
+ if (buttonText) {
+ buttonInnerHtml = htmlEscape(buttonText);
+ buttonAriaAttr = '';
+ }
+ else if (buttonIcon) {
+ buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
+ buttonAriaAttr = ' aria-label="' + buttonName + '"';
+ }
+ buttonEl = htmlToElement(// type="button" so that it doesn't submit a form
+ '<button type="button" class="' + buttonClasses.join(' ') + '"' +
+ buttonAriaAttr +
+ '>' + buttonInnerHtml + '</button>');
+ buttonEl.addEventListener('click', buttonClick);
+ groupChildren.push(buttonEl);
+ }
+ }
+ });
+ if (groupChildren.length > 1) {
+ groupEl = document.createElement('div');
+ var buttonGroupClassName = theme.getClass('buttonGroup');
+ if (isOnlyButtons && buttonGroupClassName) {
+ groupEl.classList.add(buttonGroupClassName);
+ }
+ appendToElement(groupEl, groupChildren);
+ sectionEl.appendChild(groupEl);
+ }
+ else {
+ appendToElement(sectionEl, groupChildren); // 1 or 0 children
+ }
+ });
+ }
+ return sectionEl;
+ };
+ Toolbar.prototype.updateToday = function (isTodayEnabled) {
+ this.toggleButtonEnabled('today', isTodayEnabled);
+ };
+ Toolbar.prototype.updatePrev = function (isPrevEnabled) {
+ this.toggleButtonEnabled('prev', isPrevEnabled);
+ };
+ Toolbar.prototype.updateNext = function (isNextEnabled) {
+ this.toggleButtonEnabled('next', isNextEnabled);
+ };
+ Toolbar.prototype.updateTitle = function (text) {
+ findElements(this.el, 'h2').forEach(function (titleEl) {
+ titleEl.innerText = text;
+ });
+ };
+ Toolbar.prototype.updateActiveButton = function (buttonName) {
+ var className = this.theme.getClass('buttonActive');
+ findElements(this.el, 'button').forEach(function (buttonEl) {
+ if (buttonName && buttonEl.classList.contains('fc-' + buttonName + '-button')) {
+ buttonEl.classList.add(className);
+ }
+ else {
+ buttonEl.classList.remove(className);
+ }
+ });
+ };
+ Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) {
+ findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) {
+ buttonEl.disabled = !bool;
+ });
+ };
+ return Toolbar;
+ }(Component));
+
+ var CalendarComponent = /** @class */ (function (_super) {
+ __extends(CalendarComponent, _super);
+ function CalendarComponent(context, el) {
+ var _this = _super.call(this, context) || this;
+ _this._renderToolbars = memoizeRendering(_this.renderToolbars);
+ _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
+ _this.el = el;
+ prependToElement(el, _this.contentEl = createElement('div', { className: 'fc-view-container' }));
+ var calendar = _this.calendar;
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) {
+ var modifyViewContainer = _a[_i];
+ modifyViewContainer(_this.contentEl, calendar);
+ }
+ _this.toggleElClassNames(true);
+ _this.computeTitle = memoize(computeTitle);
+ _this.parseBusinessHours = memoize(function (input) {
+ return parseBusinessHours(input, _this.calendar);
+ });
+ return _this;
+ }
+ CalendarComponent.prototype.destroy = function () {
+ if (this.header) {
+ this.header.destroy();
+ }
+ if (this.footer) {
+ this.footer.destroy();
+ }
+ if (this.view) {
+ this.view.destroy();
+ }
+ removeElement(this.contentEl);
+ this.toggleElClassNames(false);
+ _super.prototype.destroy.call(this);
+ };
+ CalendarComponent.prototype.toggleElClassNames = function (bool) {
+ var classList = this.el.classList;
+ var dirClassName = 'fc-' + this.opt('dir');
+ var themeClassName = this.theme.getClass('widget');
+ if (bool) {
+ classList.add('fc');
+ classList.add(dirClassName);
+ classList.add(themeClassName);
+ }
+ else {
+ classList.remove('fc');
+ classList.remove(dirClassName);
+ classList.remove(themeClassName);
+ }
+ };
+ CalendarComponent.prototype.render = function (props) {
+ this.freezeHeight();
+ var title = this.computeTitle(props.dateProfile, props.viewSpec.options);
+ this._renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, props.dateProfileGenerator, title);
+ this.renderView(props, title);
+ this.updateSize();
+ this.thawHeight();
+ };
+ CalendarComponent.prototype.renderToolbars = function (viewSpec, dateProfile, currentDate, dateProfileGenerator, title) {
+ var headerLayout = this.opt('header');
+ var footerLayout = this.opt('footer');
+ var now = this.calendar.getNow();
+ var todayInfo = dateProfileGenerator.build(now);
+ var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate);
+ var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate);
+ var toolbarProps = {
+ title: title,
+ activeButton: viewSpec.type,
+ isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
+ isPrevEnabled: prevInfo.isValid,
+ isNextEnabled: nextInfo.isValid
+ };
+ if (headerLayout) {
+ if (!this.header) {
+ this.header = new Toolbar(this.context, 'fc-header-toolbar');
+ prependToElement(this.el, this.header.el);
+ }
+ this.header.receiveProps(__assign({ layout: headerLayout }, toolbarProps));
+ }
+ else if (this.header) {
+ this.header.destroy();
+ this.header = null;
+ }
+ if (footerLayout) {
+ if (!this.footer) {
+ this.footer = new Toolbar(this.context, 'fc-footer-toolbar');
+ appendToElement(this.el, this.footer.el);
+ }
+ this.footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps));
+ }
+ else if (this.footer) {
+ this.footer.destroy();
+ this.footer = null;
+ }
+ };
+ CalendarComponent.prototype.renderView = function (props, title) {
+ var view = this.view;
+ var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator;
+ if (!view || view.viewSpec !== viewSpec) {
+ if (view) {
+ view.destroy();
+ }
+ view = this.view = new viewSpec['class']({
+ calendar: this.calendar,
+ view: null,
+ dateEnv: this.dateEnv,
+ theme: this.theme,
+ options: viewSpec.options
+ }, viewSpec, dateProfileGenerator, this.contentEl);
+ }
+ else {
+ view.addScroll(view.queryScroll());
+ }
+ view.title = title; // for the API
+ var viewProps = {
+ dateProfile: props.dateProfile,
+ businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
+ eventStore: props.eventStore,
+ eventUiBases: props.eventUiBases,
+ dateSelection: props.dateSelection,
+ eventSelection: props.eventSelection,
+ eventDrag: props.eventDrag,
+ eventResize: props.eventResize
+ };
+ var transformers = this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers);
+ for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
+ var transformer = transformers_1[_i];
+ __assign(viewProps, transformer.transform(viewProps, viewSpec, props, view));
+ }
+ view.receiveProps(viewProps);
+ };
+ // Sizing
+ // -----------------------------------------------------------------------------------------------------------------
+ CalendarComponent.prototype.updateSize = function (isResize) {
+ if (isResize === void 0) { isResize = false; }
+ var view = this.view;
+ if (isResize) {
+ view.addScroll(view.queryScroll());
+ }
+ if (isResize || this.isHeightAuto == null) {
+ this.computeHeightVars();
+ }
+ view.updateSize(isResize, this.viewHeight, this.isHeightAuto);
+ view.updateNowIndicator(); // we need to guarantee this will run after updateSize
+ view.popScroll(isResize);
+ };
+ CalendarComponent.prototype.computeHeightVars = function () {
+ var calendar = this.calendar; // yuck. need to handle dynamic options
+ var heightInput = calendar.opt('height');
+ var contentHeightInput = calendar.opt('contentHeight');
+ this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto';
+ if (typeof contentHeightInput === 'number') { // exists and not 'auto'
+ this.viewHeight = contentHeightInput;
+ }
+ else if (typeof contentHeightInput === 'function') { // exists and is a function
+ this.viewHeight = contentHeightInput();
+ }
+ else if (typeof heightInput === 'number') { // exists and not 'auto'
+ this.viewHeight = heightInput - this.queryToolbarsHeight();
+ }
+ else if (typeof heightInput === 'function') { // exists and is a function
+ this.viewHeight = heightInput() - this.queryToolbarsHeight();
+ }
+ else if (heightInput === 'parent') { // set to height of parent element
+ this.viewHeight = this.el.parentNode.offsetHeight - this.queryToolbarsHeight();
+ }
+ else {
+ this.viewHeight = Math.round(this.contentEl.offsetWidth /
+ Math.max(calendar.opt('aspectRatio'), .5));
+ }
+ };
+ CalendarComponent.prototype.queryToolbarsHeight = function () {
+ var height = 0;
+ if (this.header) {
+ height += computeHeightAndMargins(this.header.el);
+ }
+ if (this.footer) {
+ height += computeHeightAndMargins(this.footer.el);
+ }
+ return height;
+ };
+ // Height "Freezing"
+ // -----------------------------------------------------------------------------------------------------------------
+ CalendarComponent.prototype.freezeHeight = function () {
+ applyStyle(this.el, {
+ height: this.el.offsetHeight,
+ overflow: 'hidden'
+ });
+ };
+ CalendarComponent.prototype.thawHeight = function () {
+ applyStyle(this.el, {
+ height: '',
+ overflow: ''
+ });
+ };
+ return CalendarComponent;
+ }(Component));
+ // Title and Date Formatting
+ // -----------------------------------------------------------------------------------------------------------------
+ // Computes what the title at the top of the calendar should be for this view
+ function computeTitle(dateProfile, viewOptions) {
+ var range;
+ // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
+ if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
+ range = dateProfile.currentRange;
+ }
+ else { // for day units or smaller, use the actual day range
+ range = dateProfile.activeRange;
+ }
+ return this.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay });
+ }
+ // Generates the format string that should be used to generate the title for the current date range.
+ // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
+ function computeTitleFormat(dateProfile) {
+ var currentRangeUnit = dateProfile.currentRangeUnit;
+ if (currentRangeUnit === 'year') {
+ return { year: 'numeric' };
+ }
+ else if (currentRangeUnit === 'month') {
+ return { year: 'numeric', month: 'long' }; // like "September 2014"
+ }
+ else {
+ var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
+ if (days !== null && days > 1) {
+ // multi-day range. shorter, like "Sep 9 - 10 2014"
+ return { year: 'numeric', month: 'short', day: 'numeric' };
+ }
+ else {
+ // one day. longer, like "September 9 2014"
+ return { year: 'numeric', month: 'long', day: 'numeric' };
+ }
+ }
+ }
+ // Plugin
+ // -----------------------------------------------------------------------------------------------------------------
+ function buildViewPropTransformers(theClasses) {
+ return theClasses.map(function (theClass) {
+ return new theClass();
+ });
+ }
+
+ var Interaction = /** @class */ (function () {
+ function Interaction(settings) {
+ this.component = settings.component;
+ }
+ Interaction.prototype.destroy = function () {
+ };
+ return Interaction;
+ }());
+ function parseInteractionSettings(component, input) {
+ return {
+ component: component,
+ el: input.el,
+ useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
+ };
+ }
+ function interactionSettingsToStore(settings) {
+ var _a;
+ return _a = {},
+ _a[settings.component.uid] = settings,
+ _a;
+ }
+ // global state
+ var interactionSettingsStore = {};
+
+ /*
+ Detects when the user clicks on an event within a DateComponent
+ */
+ var EventClicking = /** @class */ (function (_super) {
+ __extends(EventClicking, _super);
+ function EventClicking(settings) {
+ var _this = _super.call(this, settings) || this;
+ _this.handleSegClick = function (ev, segEl) {
+ var component = _this.component;
+ var seg = getElSeg(segEl);
+ if (seg && // might be the <div> surrounding the more link
+ component.isValidSegDownEl(ev.target)) {
+ // our way to simulate a link click for elements that can't be <a> tags
+ // grab before trigger fired in case trigger trashes DOM thru rerendering
+ var hasUrlContainer = elementClosest(ev.target, '.fc-has-url');
+ var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
+ component.publiclyTrigger('eventClick', [
+ {
+ el: segEl,
+ event: new EventApi(component.calendar, seg.eventRange.def, seg.eventRange.instance),
+ jsEvent: ev,
+ view: component.view
+ }
+ ]);
+ if (url && !ev.defaultPrevented) {
+ window.location.href = url;
+ }
+ }
+ };
+ var component = settings.component;
+ _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick);
+ return _this;
+ }
+ return EventClicking;
+ }(Interaction));
+
+ /*
+ Triggers events and adds/removes core classNames when the user's pointer
+ enters/leaves event-elements of a component.
+ */
+ var EventHovering = /** @class */ (function (_super) {
+ __extends(EventHovering, _super);
+ function EventHovering(settings) {
+ var _this = _super.call(this, settings) || this;
+ // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
+ _this.handleEventElRemove = function (el) {
+ if (el === _this.currentSegEl) {
+ _this.handleSegLeave(null, _this.currentSegEl);
+ }
+ };
+ _this.handleSegEnter = function (ev, segEl) {
+ if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
+ segEl.classList.add('fc-allow-mouse-resize');
+ _this.currentSegEl = segEl;
+ _this.triggerEvent('eventMouseEnter', ev, segEl);
+ }
+ };
+ _this.handleSegLeave = function (ev, segEl) {
+ if (_this.currentSegEl) {
+ segEl.classList.remove('fc-allow-mouse-resize');
+ _this.currentSegEl = null;
+ _this.triggerEvent('eventMouseLeave', ev, segEl);
+ }
+ };
+ var component = settings.component;
+ _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave);
+ component.calendar.on('eventElRemove', _this.handleEventElRemove);
+ return _this;
+ }
+ EventHovering.prototype.destroy = function () {
+ this.removeHoverListeners();
+ this.component.calendar.off('eventElRemove', this.handleEventElRemove);
+ };
+ EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
+ var component = this.component;
+ var seg = getElSeg(segEl);
+ if (!ev || component.isValidSegDownEl(ev.target)) {
+ component.publiclyTrigger(publicEvName, [
+ {
+ el: segEl,
+ event: new EventApi(this.component.calendar, seg.eventRange.def, seg.eventRange.instance),
+ jsEvent: ev,
+ view: component.view
+ }
+ ]);
+ }
+ };
+ return EventHovering;
+ }(Interaction));
+
+ var StandardTheme = /** @class */ (function (_super) {
+ __extends(StandardTheme, _super);
+ function StandardTheme() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ return StandardTheme;
+ }(Theme));
+ StandardTheme.prototype.classes = {
+ widget: 'fc-unthemed',
+ widgetHeader: 'fc-widget-header',
+ widgetContent: 'fc-widget-content',
+ buttonGroup: 'fc-button-group',
+ button: 'fc-button fc-button-primary',
+ buttonActive: 'fc-button-active',
+ popoverHeader: 'fc-widget-header',
+ popoverContent: 'fc-widget-content',
+ // day grid
+ headerRow: 'fc-widget-header',
+ dayRow: 'fc-widget-content',
+ // list view
+ listView: 'fc-widget-content'
+ };
+ StandardTheme.prototype.baseIconClass = 'fc-icon';
+ StandardTheme.prototype.iconClasses = {
+ close: 'fc-icon-x',
+ prev: 'fc-icon-chevron-left',
+ next: 'fc-icon-chevron-right',
+ prevYear: 'fc-icon-chevrons-left',
+ nextYear: 'fc-icon-chevrons-right'
+ };
+ StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
+ StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
+ StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
+
+ var Calendar = /** @class */ (function () {
+ function Calendar(el, overrides) {
+ var _this = this;
+ this.parseRawLocales = memoize(parseRawLocales);
+ this.buildLocale = memoize(buildLocale);
+ this.buildDateEnv = memoize(buildDateEnv);
+ this.buildTheme = memoize(buildTheme);
+ this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase);
+ this.buildSelectionConfig = memoize(this._buildSelectionConfig);
+ this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isObjectsSimilar);
+ this.buildEventUiBases = memoize(buildEventUiBases);
+ this.interactionsStore = {};
+ this.actionQueue = [];
+ this.isReducing = false;
+ // isDisplaying: boolean = false // installed in DOM? accepting renders?
+ this.needsRerender = false; // needs a render?
+ this.needsFullRerender = false;
+ this.isRendering = false; // currently in the executeRender function?
+ this.renderingPauseDepth = 0;
+ this.buildDelayedRerender = memoize(buildDelayedRerender);
+ this.afterSizingTriggers = {};
+ this.isViewUpdated = false;
+ this.isDatesUpdated = false;
+ this.isEventsUpdated = false;
+ this.el = el;
+ this.optionsManager = new OptionsManager(overrides || {});
+ this.pluginSystem = new PluginSystem();
+ // only do once. don't do in handleOptions. because can't remove plugins
+ this.addPluginInputs(this.optionsManager.computed.plugins || []);
+ this.handleOptions(this.optionsManager.computed);
+ this.publiclyTrigger('_init'); // for tests
+ this.hydrate();
+ this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions
+ .map(function (calendarInteractionClass) {
+ return new calendarInteractionClass(_this);
+ });
+ }
+ Calendar.prototype.addPluginInputs = function (pluginInputs) {
+ var pluginDefs = refinePluginDefs(pluginInputs);
+ for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) {
+ var pluginDef = pluginDefs_1[_i];
+ this.pluginSystem.add(pluginDef);
+ }
+ };
+ Object.defineProperty(Calendar.prototype, "view", {
+ // public API
+ get: function () {
+ return this.component ? this.component.view : null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ // Public API for rendering
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.render = function () {
+ if (!this.component) {
+ this.renderableEventStore = createEmptyEventStore();
+ this.bindHandlers();
+ this.executeRender();
+ }
+ else {
+ this.requestRerender(true);
+ }
+ };
+ Calendar.prototype.destroy = function () {
+ if (this.component) {
+ this.unbindHandlers();
+ this.component.destroy(); // don't null-out. in case API needs access
+ this.component = null; // umm ???
+ for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
+ var interaction = _a[_i];
+ interaction.destroy();
+ }
+ this.publiclyTrigger('_destroyed');
+ }
+ };
+ // Handlers
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.bindHandlers = function () {
+ var _this = this;
+ // event delegation for nav links
+ this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) {
+ var gotoOptions = anchorEl.getAttribute('data-goto');
+ gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {};
+ var dateEnv = _this.dateEnv;
+ var dateMarker = dateEnv.createMarker(gotoOptions.date);
+ var viewType = gotoOptions.type;
+ // property like "navLinkDayClick". might be a string or a function
+ var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click');
+ if (typeof customAction === 'function') {
+ customAction(dateEnv.toDate(dateMarker), ev);
+ }
+ else {
+ if (typeof customAction === 'string') {
+ viewType = customAction;
+ }
+ _this.zoomTo(dateMarker, viewType);
+ }
+ });
+ if (this.opt('handleWindowResize')) {
+ window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls
+ this.windowResize.bind(this), this.opt('windowResizeDelay')));
+ }
+ };
+ Calendar.prototype.unbindHandlers = function () {
+ this.removeNavLinkListener();
+ if (this.windowResizeProxy) {
+ window.removeEventListener('resize', this.windowResizeProxy);
+ this.windowResizeProxy = null;
+ }
+ };
+ // Dispatcher
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.hydrate = function () {
+ var _this = this;
+ this.state = this.buildInitialState();
+ var rawSources = this.opt('eventSources') || [];
+ var singleRawSource = this.opt('events');
+ var sources = []; // parsed
+ if (singleRawSource) {
+ rawSources.unshift(singleRawSource);
+ }
+ for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
+ var rawSource = rawSources_1[_i];
+ var source = parseEventSource(rawSource, this);
+ if (source) {
+ sources.push(source);
+ }
+ }
+ this.batchRendering(function () {
+ _this.dispatch({ type: 'INIT' }); // pass in sources here?
+ _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources });
+ _this.dispatch({
+ type: 'SET_VIEW_TYPE',
+ viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView
+ });
+ });
+ };
+ Calendar.prototype.buildInitialState = function () {
+ return {
+ viewType: null,
+ loadingLevel: 0,
+ eventSourceLoadingLevel: 0,
+ currentDate: this.getInitialDate(),
+ dateProfile: null,
+ eventSources: {},
+ eventStore: createEmptyEventStore(),
+ dateSelection: null,
+ eventSelection: '',
+ eventDrag: null,
+ eventResize: null
+ };
+ };
+ Calendar.prototype.dispatch = function (action) {
+ this.actionQueue.push(action);
+ if (!this.isReducing) {
+ this.isReducing = true;
+ var oldState = this.state;
+ while (this.actionQueue.length) {
+ this.state = this.reduce(this.state, this.actionQueue.shift(), this);
+ }
+ var newState = this.state;
+ this.isReducing = false;
+ if (!oldState.loadingLevel && newState.loadingLevel) {
+ this.publiclyTrigger('loading', [true]);
+ }
+ else if (oldState.loadingLevel && !newState.loadingLevel) {
+ this.publiclyTrigger('loading', [false]);
+ }
+ var view = this.component && this.component.view;
+ if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) {
+ if (oldState.eventStore) {
+ this.isEventsUpdated = true;
+ }
+ }
+ if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) {
+ if (oldState.dateProfile && view) { // why would view be null!?
+ this.publiclyTrigger('datesDestroy', [
+ {
+ view: view,
+ el: view.el
+ }
+ ]);
+ }
+ this.isDatesUpdated = true;
+ }
+ if (oldState.viewType !== newState.viewType || this.needsFullRerender) {
+ if (oldState.viewType && view) { // why would view be null!?
+ this.publiclyTrigger('viewSkeletonDestroy', [
+ {
+ view: view,
+ el: view.el
+ }
+ ]);
+ }
+ this.isViewUpdated = true;
+ }
+ this.requestRerender();
+ }
+ };
+ Calendar.prototype.reduce = function (state, action, calendar) {
+ return reduce(state, action, calendar);
+ };
+ // Render Queue
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.requestRerender = function (needsFull) {
+ if (needsFull === void 0) { needsFull = false; }
+ this.needsRerender = true;
+ this.needsFullRerender = this.needsFullRerender || needsFull;
+ this.delayedRerender(); // will call a debounced-version of tryRerender
+ };
+ Calendar.prototype.tryRerender = function () {
+ if (this.component && // must be accepting renders
+ this.needsRerender && // indicates that a rerender was requested
+ !this.renderingPauseDepth && // not paused
+ !this.isRendering // not currently in the render loop
+ ) {
+ this.executeRender();
+ }
+ };
+ Calendar.prototype.batchRendering = function (func) {
+ this.renderingPauseDepth++;
+ func();
+ this.renderingPauseDepth--;
+ if (this.needsRerender) {
+ this.requestRerender();
+ }
+ };
+ // Rendering
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.executeRender = function () {
+ var needsFullRerender = this.needsFullRerender; // save before clearing
+ // clear these BEFORE the render so that new values will accumulate during render
+ this.needsRerender = false;
+ this.needsFullRerender = false;
+ this.isRendering = true;
+ this.renderComponent(needsFullRerender);
+ this.isRendering = false;
+ // received a rerender request while rendering
+ if (this.needsRerender) {
+ this.delayedRerender();
+ }
+ };
+ /*
+ don't call this directly. use executeRender instead
+ */
+ Calendar.prototype.renderComponent = function (needsFull) {
+ var _a = this, state = _a.state, component = _a.component;
+ var viewType = state.viewType;
+ var viewSpec = this.viewSpecs[viewType];
+ var savedScroll = (needsFull && component) ? component.view.queryScroll() : null;
+ if (!viewSpec) {
+ throw new Error("View type \"" + viewType + "\" is not valid");
+ }
+ // if event sources are still loading and progressive rendering hasn't been enabled,
+ // keep rendering the last fully loaded set of events
+ var renderableEventStore = this.renderableEventStore =
+ (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ?
+ this.renderableEventStore :
+ state.eventStore;
+ var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options);
+ var eventUiBySource = this.buildEventUiBySource(state.eventSources);
+ var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
+ if (needsFull || !component) {
+ if (component) {
+ component.freezeHeight(); // next component will unfreeze it
+ component.destroy();
+ }
+ component = this.component = new CalendarComponent({
+ calendar: this,
+ view: null,
+ dateEnv: this.dateEnv,
+ theme: this.theme,
+ options: this.optionsManager.computed
+ }, this.el);
+ }
+ component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfile: state.dateProfile, dateProfileGenerator: this.dateProfileGenerators[viewType], eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize }));
+ if (savedScroll) {
+ component.view.applyScroll(savedScroll, false);
+ }
+ if (this.isViewUpdated) {
+ this.isViewUpdated = false;
+ this.publiclyTrigger('viewSkeletonRender', [
+ {
+ view: component.view,
+ el: component.view.el
+ }
+ ]);
+ }
+ if (this.isDatesUpdated) {
+ this.isDatesUpdated = false;
+ this.publiclyTrigger('datesRender', [
+ {
+ view: component.view,
+ el: component.view.el
+ }
+ ]);
+ }
+ if (this.isEventsUpdated) {
+ this.isEventsUpdated = false;
+ }
+ this.releaseAfterSizingTriggers();
+ };
+ // Options
+ // -----------------------------------------------------------------------------------------------------------------
+ /*
+ Not meant for public API
+ */
+ Calendar.prototype.resetOptions = function (options) {
+ var _this = this;
+ var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
+ var oldOptions = this.optionsManager.overrides;
+ var oldNormalOptions = {};
+ var normalOptions = {};
+ var specialOptions = {};
+ for (var name_1 in oldOptions) {
+ if (!changeHandlers[name_1]) {
+ oldNormalOptions[name_1] = oldOptions[name_1];
+ }
+ }
+ for (var name_2 in options) {
+ if (changeHandlers[name_2]) {
+ specialOptions[name_2] = options[name_2];
+ }
+ else {
+ normalOptions[name_2] = options[name_2];
+ }
+ }
+ this.batchRendering(function () {
+ if (anyKeysRemoved(oldNormalOptions, normalOptions)) {
+ _this.processOptions(options, 'reset');
+ }
+ else {
+ _this.processOptions(computeChangedProps(oldNormalOptions, normalOptions));
+ }
+ // handle special options last
+ for (var name_3 in specialOptions) {
+ changeHandlers[name_3](specialOptions[name_3], _this);
+ }
+ });
+ };
+ /*
+ Not meant for public API. Won't give the same precedence that setOption does
+ */
+ Calendar.prototype.setOptions = function (options) {
+ var _this = this;
+ var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
+ var normalOptions = {};
+ var specialOptions = {};
+ for (var name_4 in options) {
+ if (changeHandlers[name_4]) {
+ specialOptions[name_4] = options[name_4];
+ }
+ else {
+ normalOptions[name_4] = options[name_4];
+ }
+ }
+ this.batchRendering(function () {
+ _this.processOptions(normalOptions);
+ // handle special options last
+ for (var name_5 in specialOptions) {
+ changeHandlers[name_5](specialOptions[name_5], _this);
+ }
+ });
+ };
+ Calendar.prototype.processOptions = function (options, mode) {
+ var _this = this;
+ var oldDateEnv = this.dateEnv; // do this before handleOptions
+ var isTimeZoneDirty = false;
+ var isSizeDirty = false;
+ var anyDifficultOptions = false;
+ for (var name_6 in options) {
+ if (/^(height|contentHeight|aspectRatio)$/.test(name_6)) {
+ isSizeDirty = true;
+ }
+ else if (/^(defaultDate|defaultView)$/.test(name_6)) ;
+ else {
+ anyDifficultOptions = true;
+ if (name_6 === 'timeZone') {
+ isTimeZoneDirty = true;
+ }
+ }
+ }
+ if (mode === 'reset') {
+ anyDifficultOptions = true;
+ this.optionsManager.reset(options);
+ }
+ else if (mode === 'dynamic') {
+ this.optionsManager.addDynamic(options); // takes higher precedence
+ }
+ else {
+ this.optionsManager.add(options);
+ }
+ if (anyDifficultOptions) {
+ this.handleOptions(this.optionsManager.computed); // only for "difficult" options
+ this.needsFullRerender = true;
+ this.batchRendering(function () {
+ if (isTimeZoneDirty) {
+ _this.dispatch({
+ type: 'CHANGE_TIMEZONE',
+ oldDateEnv: oldDateEnv
+ });
+ }
+ /* HACK
+ has the same effect as calling this.requestRerender(true)
+ but recomputes the state's dateProfile
+ */
+ _this.dispatch({
+ type: 'SET_VIEW_TYPE',
+ viewType: _this.state.viewType
+ });
+ });
+ }
+ if (isSizeDirty) {
+ this.updateSize();
+ }
+ };
+ Calendar.prototype.setOption = function (name, val) {
+ var _a;
+ this.processOptions((_a = {}, _a[name] = val, _a), 'dynamic');
+ };
+ Calendar.prototype.getOption = function (name) {
+ return this.optionsManager.computed[name];
+ };
+ Calendar.prototype.opt = function (name) {
+ return this.optionsManager.computed[name];
+ };
+ Calendar.prototype.viewOpt = function (name) {
+ return this.viewOpts()[name];
+ };
+ Calendar.prototype.viewOpts = function () {
+ return this.viewSpecs[this.state.viewType].options;
+ };
+ /*
+ rebuilds things based off of a complete set of refined options
+ */
+ Calendar.prototype.handleOptions = function (options) {
+ var _this = this;
+ var pluginHooks = this.pluginSystem.hooks;
+ this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration);
+ this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration);
+ this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay);
+ this.theme = this.buildTheme(options);
+ var available = this.parseRawLocales(options.locales);
+ this.availableRawLocales = available.map;
+ var locale = this.buildLocale(options.locale || available.defaultCode, available.map);
+ this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter);
+ this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :(
+ // ineffecient to do every time?
+ this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager);
+ // ineffecient to do every time?
+ this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) {
+ return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this);
+ });
+ };
+ Calendar.prototype.getAvailableLocaleCodes = function () {
+ return Object.keys(this.availableRawLocales);
+ };
+ Calendar.prototype._buildSelectionConfig = function (rawOpts) {
+ return processScopedUiProps('select', rawOpts, this);
+ };
+ Calendar.prototype._buildEventUiSingleBase = function (rawOpts) {
+ if (rawOpts.editable) { // so 'editable' affected events
+ rawOpts = __assign({}, rawOpts, { eventEditable: true });
+ }
+ return processScopedUiProps('event', rawOpts, this);
+ };
+ // Trigger
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.hasPublicHandlers = function (name) {
+ return this.hasHandlers(name) ||
+ this.opt(name); // handler specified in options
+ };
+ Calendar.prototype.publiclyTrigger = function (name, args) {
+ var optHandler = this.opt(name);
+ this.triggerWith(name, this, args);
+ if (optHandler) {
+ return optHandler.apply(this, args);
+ }
+ };
+ Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) {
+ var afterSizingTriggers = this.afterSizingTriggers;
+ (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args);
+ };
+ Calendar.prototype.releaseAfterSizingTriggers = function () {
+ var afterSizingTriggers = this.afterSizingTriggers;
+ for (var name_7 in afterSizingTriggers) {
+ for (var _i = 0, _a = afterSizingTriggers[name_7]; _i < _a.length; _i++) {
+ var args = _a[_i];
+ this.publiclyTrigger(name_7, args);
+ }
+ }
+ this.afterSizingTriggers = {};
+ };
+ // View
+ // -----------------------------------------------------------------------------------------------------------------
+ // Returns a boolean about whether the view is okay to instantiate at some point
+ Calendar.prototype.isValidViewType = function (viewType) {
+ return Boolean(this.viewSpecs[viewType]);
+ };
+ Calendar.prototype.changeView = function (viewType, dateOrRange) {
+ var dateMarker = null;
+ if (dateOrRange) {
+ if (dateOrRange.start && dateOrRange.end) { // a range
+ this.optionsManager.addDynamic({ visibleRange: dateOrRange }); // will not rerender
+ this.handleOptions(this.optionsManager.computed); // ...but yuck
+ }
+ else { // a date
+ dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate
+ }
+ }
+ this.unselect();
+ this.dispatch({
+ type: 'SET_VIEW_TYPE',
+ viewType: viewType,
+ dateMarker: dateMarker
+ });
+ };
+ // Forces navigation to a view for the given date.
+ // `viewType` can be a specific view name or a generic one like "week" or "day".
+ // needs to change
+ Calendar.prototype.zoomTo = function (dateMarker, viewType) {
+ var spec;
+ viewType = viewType || 'day'; // day is default zoom
+ spec = this.viewSpecs[viewType] ||
+ this.getUnitViewSpec(viewType);
+ this.unselect();
+ if (spec) {
+ this.dispatch({
+ type: 'SET_VIEW_TYPE',
+ viewType: spec.type,
+ dateMarker: dateMarker
+ });
+ }
+ else {
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: dateMarker
+ });
+ }
+ };
+ // Given a duration singular unit, like "week" or "day", finds a matching view spec.
+ // Preference is given to views that have corresponding buttons.
+ Calendar.prototype.getUnitViewSpec = function (unit) {
+ var viewTypes;
+ var i;
+ var spec;
+ // put views that have buttons first. there will be duplicates, but oh well
+ viewTypes = this.component.header.viewsWithButtons; // TODO: include footer as well?
+ for (var viewType in this.viewSpecs) {
+ viewTypes.push(viewType);
+ }
+ for (i = 0; i < viewTypes.length; i++) {
+ spec = this.viewSpecs[viewTypes[i]];
+ if (spec) {
+ if (spec.singleUnit === unit) {
+ return spec;
+ }
+ }
+ }
+ };
+ // Current Date
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.getInitialDate = function () {
+ var defaultDateInput = this.opt('defaultDate');
+ // compute the initial ambig-timezone date
+ if (defaultDateInput != null) {
+ return this.dateEnv.createMarker(defaultDateInput);
+ }
+ else {
+ return this.getNow(); // getNow already returns unzoned
+ }
+ };
+ Calendar.prototype.prev = function () {
+ this.unselect();
+ this.dispatch({ type: 'PREV' });
+ };
+ Calendar.prototype.next = function () {
+ this.unselect();
+ this.dispatch({ type: 'NEXT' });
+ };
+ Calendar.prototype.prevYear = function () {
+ this.unselect();
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: this.dateEnv.addYears(this.state.currentDate, -1)
+ });
+ };
+ Calendar.prototype.nextYear = function () {
+ this.unselect();
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: this.dateEnv.addYears(this.state.currentDate, 1)
+ });
+ };
+ Calendar.prototype.today = function () {
+ this.unselect();
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: this.getNow()
+ });
+ };
+ Calendar.prototype.gotoDate = function (zonedDateInput) {
+ this.unselect();
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: this.dateEnv.createMarker(zonedDateInput)
+ });
+ };
+ Calendar.prototype.incrementDate = function (deltaInput) {
+ var delta = createDuration(deltaInput);
+ if (delta) { // else, warn about invalid input?
+ this.unselect();
+ this.dispatch({
+ type: 'SET_DATE',
+ dateMarker: this.dateEnv.add(this.state.currentDate, delta)
+ });
+ }
+ };
+ // for external API
+ Calendar.prototype.getDate = function () {
+ return this.dateEnv.toDate(this.state.currentDate);
+ };
+ // Date Formatting Utils
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.formatDate = function (d, formatter) {
+ var dateEnv = this.dateEnv;
+ return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
+ };
+ // `settings` is for formatter AND isEndExclusive
+ Calendar.prototype.formatRange = function (d0, d1, settings) {
+ var dateEnv = this.dateEnv;
+ return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings);
+ };
+ Calendar.prototype.formatIso = function (d, omitTime) {
+ var dateEnv = this.dateEnv;
+ return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
+ };
+ // Sizing
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.windowResize = function (ev) {
+ if (!this.isHandlingWindowResize &&
+ this.component && // why?
+ ev.target === window // not a jqui resize event
+ ) {
+ this.isHandlingWindowResize = true;
+ this.updateSize();
+ this.publiclyTrigger('windowResize', [this.view]);
+ this.isHandlingWindowResize = false;
+ }
+ };
+ Calendar.prototype.updateSize = function () {
+ if (this.component) { // when?
+ this.component.updateSize(true);
+ }
+ };
+ // Component Registration
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) {
+ var settings = parseInteractionSettings(component, settingsInput);
+ var DEFAULT_INTERACTIONS = [
+ EventClicking,
+ EventHovering
+ ];
+ var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions);
+ var interactions = interactionClasses.map(function (interactionClass) {
+ return new interactionClass(settings);
+ });
+ this.interactionsStore[component.uid] = interactions;
+ interactionSettingsStore[component.uid] = settings;
+ };
+ Calendar.prototype.unregisterInteractiveComponent = function (component) {
+ for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) {
+ var listener = _a[_i];
+ listener.destroy();
+ }
+ delete this.interactionsStore[component.uid];
+ delete interactionSettingsStore[component.uid];
+ };
+ // Date Selection / Event Selection / DayClick
+ // -----------------------------------------------------------------------------------------------------------------
+ // this public method receives start/end dates in any format, with any timezone
+ // NOTE: args were changed from v3
+ Calendar.prototype.select = function (dateOrObj, endDate) {
+ var selectionInput;
+ if (endDate == null) {
+ if (dateOrObj.start != null) {
+ selectionInput = dateOrObj;
+ }
+ else {
+ selectionInput = {
+ start: dateOrObj,
+ end: null
+ };
+ }
+ }
+ else {
+ selectionInput = {
+ start: dateOrObj,
+ end: endDate
+ };
+ }
+ var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
+ );
+ if (selection) { // throw parse error otherwise?
+ this.dispatch({ type: 'SELECT_DATES', selection: selection });
+ this.triggerDateSelect(selection);
+ }
+ };
+ // public method
+ Calendar.prototype.unselect = function (pev) {
+ if (this.state.dateSelection) {
+ this.dispatch({ type: 'UNSELECT_DATES' });
+ this.triggerDateUnselect(pev);
+ }
+ };
+ Calendar.prototype.triggerDateSelect = function (selection, pev) {
+ var arg = this.buildDateSpanApi(selection);
+ arg.jsEvent = pev ? pev.origEvent : null;
+ arg.view = this.view;
+ this.publiclyTrigger('select', [arg]);
+ };
+ Calendar.prototype.triggerDateUnselect = function (pev) {
+ this.publiclyTrigger('unselect', [
+ {
+ jsEvent: pev ? pev.origEvent : null,
+ view: this.view
+ }
+ ]);
+ };
+ // TODO: receive pev?
+ Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) {
+ var arg = this.buildDatePointApi(dateSpan);
+ arg.dayEl = dayEl;
+ arg.jsEvent = ev;
+ arg.view = view;
+ this.publiclyTrigger('dateClick', [arg]);
+ };
+ Calendar.prototype.buildDatePointApi = function (dateSpan) {
+ var props = {};
+ for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) {
+ var transform = _a[_i];
+ __assign(props, transform(dateSpan, this));
+ }
+ __assign(props, buildDatePointApi(dateSpan, this.dateEnv));
+ return props;
+ };
+ Calendar.prototype.buildDateSpanApi = function (dateSpan) {
+ var props = {};
+ for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) {
+ var transform = _a[_i];
+ __assign(props, transform(dateSpan, this));
+ }
+ __assign(props, buildDateSpanApi(dateSpan, this.dateEnv));
+ return props;
+ };
+ // Date Utils
+ // -----------------------------------------------------------------------------------------------------------------
+ // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option
+ Calendar.prototype.getNow = function () {
+ var now = this.opt('now');
+ if (typeof now === 'function') {
+ now = now();
+ }
+ if (now == null) {
+ return this.dateEnv.createNowMarker();
+ }
+ return this.dateEnv.createMarker(now);
+ };
+ // Event-Date Utilities
+ // -----------------------------------------------------------------------------------------------------------------
+ // Given an event's allDay status and start date, return what its fallback end date should be.
+ // TODO: rename to computeDefaultEventEnd
+ Calendar.prototype.getDefaultEventEnd = function (allDay, marker) {
+ var end = marker;
+ if (allDay) {
+ end = startOfDay(end);
+ end = this.dateEnv.add(end, this.defaultAllDayEventDuration);
+ }
+ else {
+ end = this.dateEnv.add(end, this.defaultTimedEventDuration);
+ }
+ return end;
+ };
+ // Public Events API
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.addEvent = function (eventInput, sourceInput) {
+ if (eventInput instanceof EventApi) {
+ var def = eventInput._def;
+ var instance = eventInput._instance;
+ // not already present? don't want to add an old snapshot
+ if (!this.state.eventStore.defs[def.defId]) {
+ this.dispatch({
+ type: 'ADD_EVENTS',
+ eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
+ });
+ }
+ return eventInput;
+ }
+ var sourceId;
+ if (sourceInput instanceof EventSourceApi) {
+ sourceId = sourceInput.internalEventSource.sourceId;
+ }
+ else if (sourceInput != null) {
+ var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
+ if (!sourceApi) {
+ console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
+ return null;
+ }
+ else {
+ sourceId = sourceApi.internalEventSource.sourceId;
+ }
+ }
+ var tuple = parseEvent(eventInput, sourceId, this);
+ if (tuple) {
+ this.dispatch({
+ type: 'ADD_EVENTS',
+ eventStore: eventTupleToStore(tuple)
+ });
+ return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
+ }
+ return null;
+ };
+ // TODO: optimize
+ Calendar.prototype.getEventById = function (id) {
+ var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
+ id = String(id);
+ for (var defId in defs) {
+ var def = defs[defId];
+ if (def.publicId === id) {
+ if (def.recurringDef) {
+ return new EventApi(this, def, null);
+ }
+ else {
+ for (var instanceId in instances) {
+ var instance = instances[instanceId];
+ if (instance.defId === def.defId) {
+ return new EventApi(this, def, instance);
+ }
+ }
+ }
+ }
+ }
+ return null;
+ };
+ Calendar.prototype.getEvents = function () {
+ var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
+ var eventApis = [];
+ for (var id in instances) {
+ var instance = instances[id];
+ var def = defs[instance.defId];
+ eventApis.push(new EventApi(this, def, instance));
+ }
+ return eventApis;
+ };
+ Calendar.prototype.removeAllEvents = function () {
+ this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
+ };
+ Calendar.prototype.rerenderEvents = function () {
+ this.dispatch({ type: 'RESET_EVENTS' });
+ };
+ // Public Event Sources API
+ // -----------------------------------------------------------------------------------------------------------------
+ Calendar.prototype.getEventSources = function () {
+ var sourceHash = this.state.eventSources;
+ var sourceApis = [];
+ for (var internalId in sourceHash) {
+ sourceApis.push(new EventSourceApi(this, sourceHash[internalId]));
+ }
+ return sourceApis;
+ };
+ Calendar.prototype.getEventSourceById = function (id) {
+ var sourceHash = this.state.eventSources;
+ id = String(id);
+ for (var sourceId in sourceHash) {
+ if (sourceHash[sourceId].publicId === id) {
+ return new EventSourceApi(this, sourceHash[sourceId]);
+ }
+ }
+ return null;
+ };
+ Calendar.prototype.addEventSource = function (sourceInput) {
+ if (sourceInput instanceof EventSourceApi) {
+ // not already present? don't want to add an old snapshot
+ if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) {
+ this.dispatch({
+ type: 'ADD_EVENT_SOURCES',
+ sources: [sourceInput.internalEventSource]
+ });
+ }
+ return sourceInput;
+ }
+ var eventSource = parseEventSource(sourceInput, this);
+ if (eventSource) { // TODO: error otherwise?
+ this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
+ return new EventSourceApi(this, eventSource);
+ }
+ return null;
+ };
+ Calendar.prototype.removeAllEventSources = function () {
+ this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
+ };
+ Calendar.prototype.refetchEvents = function () {
+ this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
+ };
+ return Calendar;
+ }());
+ EmitterMixin.mixInto(Calendar);
+ // for memoizers
+ // -----------------------------------------------------------------------------------------------------------------
+ function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) {
+ return new DateEnv({
+ calendarSystem: 'gregory',
+ timeZone: timeZone,
+ namedTimeZoneImpl: namedTimeZoneImpl,
+ locale: locale,
+ weekNumberCalculation: weekNumberCalculation,
+ firstDay: firstDay,
+ weekLabel: weekLabel,
+ cmdFormatter: cmdFormatter
+ });
+ }
+ function buildTheme(calendarOptions) {
+ var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme;
+ return new themeClass(calendarOptions);
+ }
+ function buildDelayedRerender(wait) {
+ var func = this.tryRerender.bind(this);
+ if (wait != null) {
+ func = debounce(func, wait);
+ }
+ return func;
+ }
+ function buildEventUiBySource(eventSources) {
+ return mapHash(eventSources, function (eventSource) {
+ return eventSource.ui;
+ });
+ }
+ function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
+ var eventUiBases = { '': eventUiSingleBase };
+ for (var defId in eventDefs) {
+ var def = eventDefs[defId];
+ if (def.sourceId && eventUiBySource[def.sourceId]) {
+ eventUiBases[defId] = eventUiBySource[def.sourceId];
+ }
+ }
+ return eventUiBases;
+ }
+
+ var View = /** @class */ (function (_super) {
+ __extends(View, _super);
+ function View(context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, context, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' }), true // isView (HACK)
+ ) || this;
+ _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap);
+ _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]);
+ _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]);
+ _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]);
+ _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]);
+ _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]);
+ _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]);
+ _this.viewSpec = viewSpec;
+ _this.dateProfileGenerator = dateProfileGenerator;
+ _this.type = viewSpec.type;
+ _this.eventOrderSpecs = parseFieldSpecs(_this.opt('eventOrder'));
+ _this.nextDayThreshold = createDuration(_this.opt('nextDayThreshold'));
+ parentEl.appendChild(_this.el);
+ _this.initialize();
+ return _this;
+ }
+ View.prototype.initialize = function () {
+ };
+ Object.defineProperty(View.prototype, "activeStart", {
+ // Date Setting/Unsetting
+ // -----------------------------------------------------------------------------------------------------------------
+ get: function () {
+ return this.dateEnv.toDate(this.props.dateProfile.activeRange.start);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(View.prototype, "activeEnd", {
+ get: function () {
+ return this.dateEnv.toDate(this.props.dateProfile.activeRange.end);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(View.prototype, "currentStart", {
+ get: function () {
+ return this.dateEnv.toDate(this.props.dateProfile.currentRange.start);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(View.prototype, "currentEnd", {
+ get: function () {
+ return this.dateEnv.toDate(this.props.dateProfile.currentRange.end);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ // General Rendering
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.render = function (props) {
+ this.renderDatesMem(props.dateProfile);
+ this.renderBusinessHoursMem(props.businessHours);
+ this.renderDateSelectionMem(props.dateSelection);
+ this.renderEventsMem(props.eventStore);
+ this.renderEventSelectionMem(props.eventSelection);
+ this.renderEventDragMem(props.eventDrag);
+ this.renderEventResizeMem(props.eventResize);
+ };
+ View.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.renderDatesMem.unrender(); // should unrender everything else
+ };
+ // Sizing
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.updateSize = function (isResize, viewHeight, isAuto) {
+ var calendar = this.calendar;
+ if (isResize || calendar.isViewUpdated || calendar.isDatesUpdated || calendar.isEventsUpdated) {
+ // sort of the catch-all sizing
+ // anything that might cause dimension changes
+ this.updateBaseSize(isResize, viewHeight, isAuto);
+ }
+ };
+ View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
+ };
+ // Date Rendering
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderDatesWrap = function (dateProfile) {
+ this.renderDates(dateProfile);
+ this.addScroll({ isDateInit: true });
+ this.startNowIndicator(dateProfile); // shouldn't render yet because updateSize will be called soon
+ };
+ View.prototype.unrenderDatesWrap = function () {
+ this.stopNowIndicator();
+ this.unrenderDates();
+ };
+ View.prototype.renderDates = function (dateProfile) { };
+ View.prototype.unrenderDates = function () { };
+ // Business Hours
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderBusinessHours = function (businessHours) { };
+ View.prototype.unrenderBusinessHours = function () { };
+ // Date Selection
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderDateSelectionWrap = function (selection) {
+ if (selection) {
+ this.renderDateSelection(selection);
+ }
+ };
+ View.prototype.unrenderDateSelectionWrap = function (selection) {
+ if (selection) {
+ this.unrenderDateSelection(selection);
+ }
+ };
+ View.prototype.renderDateSelection = function (selection) { };
+ View.prototype.unrenderDateSelection = function (selection) { };
+ // Event Rendering
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderEvents = function (eventStore) { };
+ View.prototype.unrenderEvents = function () { };
+ // util for subclasses
+ View.prototype.sliceEvents = function (eventStore, allDay) {
+ var props = this.props;
+ return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.nextDayThreshold : null).fg;
+ };
+ // Event Selection
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderEventSelectionWrap = function (instanceId) {
+ if (instanceId) {
+ this.renderEventSelection(instanceId);
+ }
+ };
+ View.prototype.unrenderEventSelectionWrap = function (instanceId) {
+ if (instanceId) {
+ this.unrenderEventSelection(instanceId);
+ }
+ };
+ View.prototype.renderEventSelection = function (instanceId) { };
+ View.prototype.unrenderEventSelection = function (instanceId) { };
+ // Event Drag
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderEventDragWrap = function (state) {
+ if (state) {
+ this.renderEventDrag(state);
+ }
+ };
+ View.prototype.unrenderEventDragWrap = function (state) {
+ if (state) {
+ this.unrenderEventDrag(state);
+ }
+ };
+ View.prototype.renderEventDrag = function (state) { };
+ View.prototype.unrenderEventDrag = function (state) { };
+ // Event Resize
+ // -----------------------------------------------------------------------------------------------------------------
+ View.prototype.renderEventResizeWrap = function (state) {
+ if (state) {
+ this.renderEventResize(state);
+ }
+ };
+ View.prototype.unrenderEventResizeWrap = function (state) {
+ if (state) {
+ this.unrenderEventResize(state);
+ }
+ };
+ View.prototype.renderEventResize = function (state) { };
+ View.prototype.unrenderEventResize = function (state) { };
+ /* Now Indicator
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Immediately render the current time indicator and begins re-rendering it at an interval,
+ // which is defined by this.getNowIndicatorUnit().
+ // TODO: somehow do this for the current whole day's background too
+ View.prototype.startNowIndicator = function (dateProfile) {
+ var _this = this;
+ var dateEnv = this.dateEnv;
+ var unit;
+ var update;
+ var delay; // ms wait value
+ if (this.opt('nowIndicator')) {
+ unit = this.getNowIndicatorUnit(dateProfile);
+ if (unit) {
+ update = this.updateNowIndicator.bind(this);
+ this.initialNowDate = this.calendar.getNow();
+ this.initialNowQueriedMs = new Date().valueOf();
+ // wait until the beginning of the next interval
+ delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf();
+ // TODO: maybe always use setTimeout, waiting until start of next unit
+ this.nowIndicatorTimeoutID = setTimeout(function () {
+ _this.nowIndicatorTimeoutID = null;
+ update();
+ if (unit === 'second') {
+ delay = 1000; // every second
+ }
+ else {
+ delay = 1000 * 60; // otherwise, every minute
+ }
+ _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
+ }, delay);
+ }
+ // rendering will be initiated in updateSize
+ }
+ };
+ // rerenders the now indicator, computing the new current time from the amount of time that has passed
+ // since the initial getNow call.
+ View.prototype.updateNowIndicator = function () {
+ if (this.props.dateProfile && // a way to determine if dates were rendered yet
+ this.initialNowDate // activated before?
+ ) {
+ this.unrenderNowIndicator(); // won't unrender if unnecessary
+ this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs));
+ this.isNowIndicatorRendered = true;
+ }
+ };
+ // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
+ // Won't cause side effects if indicator isn't rendered.
+ View.prototype.stopNowIndicator = function () {
+ if (this.isNowIndicatorRendered) {
+ if (this.nowIndicatorTimeoutID) {
+ clearTimeout(this.nowIndicatorTimeoutID);
+ this.nowIndicatorTimeoutID = null;
+ }
+ if (this.nowIndicatorIntervalID) {
+ clearInterval(this.nowIndicatorIntervalID);
+ this.nowIndicatorIntervalID = null;
+ }
+ this.unrenderNowIndicator();
+ this.isNowIndicatorRendered = false;
+ }
+ };
+ View.prototype.getNowIndicatorUnit = function (dateProfile) {
+ // subclasses should implement
+ };
+ // Renders a current time indicator at the given datetime
+ View.prototype.renderNowIndicator = function (date) {
+ // SUBCLASSES MUST PASS TO CHILDREN!
+ };
+ // Undoes the rendering actions from renderNowIndicator
+ View.prototype.unrenderNowIndicator = function () {
+ // SUBCLASSES MUST PASS TO CHILDREN!
+ };
+ /* Scroller
+ ------------------------------------------------------------------------------------------------------------------*/
+ View.prototype.addScroll = function (scroll) {
+ var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
+ __assign(queuedScroll, scroll);
+ };
+ View.prototype.popScroll = function (isResize) {
+ this.applyQueuedScroll(isResize);
+ this.queuedScroll = null;
+ };
+ View.prototype.applyQueuedScroll = function (isResize) {
+ this.applyScroll(this.queuedScroll || {}, isResize);
+ };
+ View.prototype.queryScroll = function () {
+ var scroll = {};
+ if (this.props.dateProfile) { // dates rendered yet?
+ __assign(scroll, this.queryDateScroll());
+ }
+ return scroll;
+ };
+ View.prototype.applyScroll = function (scroll, isResize) {
+ if (scroll.isDateInit) {
+ delete scroll.isDateInit;
+ if (this.props.dateProfile) { // dates rendered yet?
+ __assign(scroll, this.computeInitialDateScroll());
+ }
+ }
+ if (this.props.dateProfile) { // dates rendered yet?
+ this.applyDateScroll(scroll);
+ }
+ };
+ View.prototype.computeInitialDateScroll = function () {
+ return {}; // subclasses must implement
+ };
+ View.prototype.queryDateScroll = function () {
+ return {}; // subclasses must implement
+ };
+ View.prototype.applyDateScroll = function (scroll) {
+ // subclasses must implement
+ };
+ return View;
+ }(DateComponent));
+ EmitterMixin.mixInto(View);
+ View.prototype.usesMinMaxTime = false;
+ View.prototype.dateProfileGeneratorClass = DateProfileGenerator;
+
+ var FgEventRenderer = /** @class */ (function () {
+ function FgEventRenderer(context) {
+ this.segs = [];
+ this.isSizeDirty = false;
+ this.context = context;
+ }
+ FgEventRenderer.prototype.renderSegs = function (segs, mirrorInfo) {
+ this.rangeUpdated(); // called too frequently :(
+ // render an `.el` on each seg
+ // returns a subset of the segs. segs that were actually rendered
+ segs = this.renderSegEls(segs, mirrorInfo);
+ this.segs = segs;
+ this.attachSegs(segs, mirrorInfo);
+ this.isSizeDirty = true;
+ this.context.view.triggerRenderedSegs(this.segs, Boolean(mirrorInfo));
+ };
+ FgEventRenderer.prototype.unrender = function (_segs, mirrorInfo) {
+ this.context.view.triggerWillRemoveSegs(this.segs, Boolean(mirrorInfo));
+ this.detachSegs(this.segs);
+ this.segs = [];
+ };
+ // Updates values that rely on options and also relate to range
+ FgEventRenderer.prototype.rangeUpdated = function () {
+ var options = this.context.options;
+ var displayEventTime;
+ var displayEventEnd;
+ this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator);
+ displayEventTime = options.displayEventTime;
+ if (displayEventTime == null) {
+ displayEventTime = this.computeDisplayEventTime(); // might be based off of range
+ }
+ displayEventEnd = options.displayEventEnd;
+ if (displayEventEnd == null) {
+ displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
+ }
+ this.displayEventTime = displayEventTime;
+ this.displayEventEnd = displayEventEnd;
+ };
+ // Renders and assigns an `el` property for each foreground event segment.
+ // Only returns segments that successfully rendered.
+ FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) {
+ var html = '';
+ var i;
+ if (segs.length) { // don't build an empty html string
+ // build a large concatenation of event segment HTML
+ for (i = 0; i < segs.length; i++) {
+ html += this.renderSegHtml(segs[i], mirrorInfo);
+ }
+ // Grab individual elements from the combined HTML string. Use each as the default rendering.
+ // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
+ htmlToElements(html).forEach(function (el, i) {
+ var seg = segs[i];
+ if (el) {
+ seg.el = el;
+ }
+ });
+ segs = filterSegsViaEls(this.context.view, segs, Boolean(mirrorInfo));
+ }
+ return segs;
+ };
+ // Generic utility for generating the HTML classNames for an event segment's element
+ FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) {
+ var classes = [
+ 'fc-event',
+ seg.isStart ? 'fc-start' : 'fc-not-start',
+ seg.isEnd ? 'fc-end' : 'fc-not-end'
+ ].concat(seg.eventRange.ui.classNames);
+ if (isDraggable) {
+ classes.push('fc-draggable');
+ }
+ if (isResizable) {
+ classes.push('fc-resizable');
+ }
+ if (mirrorInfo) {
+ classes.push('fc-mirror');
+ if (mirrorInfo.isDragging) {
+ classes.push('fc-dragging');
+ }
+ if (mirrorInfo.isResizing) {
+ classes.push('fc-resizing');
+ }
+ }
+ return classes;
+ };
+ // Compute the text that should be displayed on an event's element.
+ // `range` can be the Event object itself, or something range-like, with at least a `start`.
+ // If event times are disabled, or the event has no time, will return a blank string.
+ // If not specified, formatter will default to the eventTimeFormat setting,
+ // and displayEnd will default to the displayEventEnd setting.
+ FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) {
+ var def = eventRange.def, instance = eventRange.instance;
+ return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo);
+ };
+ FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) {
+ var dateEnv = this.context.dateEnv;
+ if (formatter == null) {
+ formatter = this.eventTimeFormat;
+ }
+ if (displayEnd == null) {
+ displayEnd = this.displayEventEnd;
+ }
+ if (this.displayEventTime && !allDay) {
+ if (displayEnd && end) {
+ return dateEnv.formatRange(start, end, formatter, {
+ forcedStartTzo: forcedStartTzo,
+ forcedEndTzo: forcedEndTzo
+ });
+ }
+ else {
+ return dateEnv.format(start, formatter, {
+ forcedTzo: forcedStartTzo
+ });
+ }
+ }
+ return '';
+ };
+ FgEventRenderer.prototype.computeEventTimeFormat = function () {
+ return {
+ hour: 'numeric',
+ minute: '2-digit',
+ omitZeroMinute: true
+ };
+ };
+ FgEventRenderer.prototype.computeDisplayEventTime = function () {
+ return true;
+ };
+ FgEventRenderer.prototype.computeDisplayEventEnd = function () {
+ return true;
+ };
+ // Utility for generating event skin-related CSS properties
+ FgEventRenderer.prototype.getSkinCss = function (ui) {
+ return {
+ 'background-color': ui.backgroundColor,
+ 'border-color': ui.borderColor,
+ color: ui.textColor
+ };
+ };
+ FgEventRenderer.prototype.sortEventSegs = function (segs) {
+ var specs = this.context.view.eventOrderSpecs;
+ var objs = segs.map(buildSegCompareObj);
+ objs.sort(function (obj0, obj1) {
+ return compareByFieldSpecs(obj0, obj1, specs);
+ });
+ return objs.map(function (c) {
+ return c._seg;
+ });
+ };
+ FgEventRenderer.prototype.computeSizes = function (force) {
+ if (force || this.isSizeDirty) {
+ this.computeSegSizes(this.segs);
+ }
+ };
+ FgEventRenderer.prototype.assignSizes = function (force) {
+ if (force || this.isSizeDirty) {
+ this.assignSegSizes(this.segs);
+ this.isSizeDirty = false;
+ }
+ };
+ FgEventRenderer.prototype.computeSegSizes = function (segs) {
+ };
+ FgEventRenderer.prototype.assignSegSizes = function (segs) {
+ };
+ // Manipulation on rendered segs
+ FgEventRenderer.prototype.hideByHash = function (hash) {
+ if (hash) {
+ for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
+ var seg = _a[_i];
+ if (hash[seg.eventRange.instance.instanceId]) {
+ seg.el.style.visibility = 'hidden';
+ }
+ }
+ }
+ };
+ FgEventRenderer.prototype.showByHash = function (hash) {
+ if (hash) {
+ for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
+ var seg = _a[_i];
+ if (hash[seg.eventRange.instance.instanceId]) {
+ seg.el.style.visibility = '';
+ }
+ }
+ }
+ };
+ FgEventRenderer.prototype.selectByInstanceId = function (instanceId) {
+ if (instanceId) {
+ for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
+ var seg = _a[_i];
+ var eventInstance = seg.eventRange.instance;
+ if (eventInstance && eventInstance.instanceId === instanceId &&
+ seg.el // necessary?
+ ) {
+ seg.el.classList.add('fc-selected');
+ }
+ }
+ }
+ };
+ FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) {
+ if (instanceId) {
+ for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
+ var seg = _a[_i];
+ if (seg.el) { // necessary?
+ seg.el.classList.remove('fc-selected');
+ }
+ }
+ }
+ };
+ return FgEventRenderer;
+ }());
+ // returns a object with all primitive props that can be compared
+ function buildSegCompareObj(seg) {
+ var eventDef = seg.eventRange.def;
+ var range = seg.eventRange.instance.range;
+ var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
+ var end = range.end ? range.end.valueOf() : 0; // "
+ return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start,
+ end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
+ });
+ }
+
+ var FillRenderer = /** @class */ (function () {
+ function FillRenderer(context) {
+ this.fillSegTag = 'div';
+ this.dirtySizeFlags = {};
+ this.context = context;
+ this.containerElsByType = {};
+ this.segsByType = {};
+ }
+ FillRenderer.prototype.getSegsByType = function (type) {
+ return this.segsByType[type] || [];
+ };
+ FillRenderer.prototype.renderSegs = function (type, segs) {
+ var _a;
+ var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
+ var containerEls = this.attachSegs(type, renderedSegs);
+ if (containerEls) {
+ (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls);
+ }
+ this.segsByType[type] = renderedSegs;
+ if (type === 'bgEvent') {
+ this.context.view.triggerRenderedSegs(renderedSegs, false); // isMirror=false
+ }
+ this.dirtySizeFlags[type] = true;
+ };
+ // Unrenders a specific type of fill that is currently rendered on the grid
+ FillRenderer.prototype.unrender = function (type) {
+ var segs = this.segsByType[type];
+ if (segs) {
+ if (type === 'bgEvent') {
+ this.context.view.triggerWillRemoveSegs(segs, false); // isMirror=false
+ }
+ this.detachSegs(type, segs);
+ }
+ };
+ // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
+ // Only returns segments that successfully rendered.
+ FillRenderer.prototype.renderSegEls = function (type, segs) {
+ var _this = this;
+ var html = '';
+ var i;
+ if (segs.length) {
+ // build a large concatenation of segment HTML
+ for (i = 0; i < segs.length; i++) {
+ html += this.renderSegHtml(type, segs[i]);
+ }
+ // Grab individual elements from the combined HTML string. Use each as the default rendering.
+ // Then, compute the 'el' for each segment.
+ htmlToElements(html).forEach(function (el, i) {
+ var seg = segs[i];
+ if (el) {
+ seg.el = el;
+ }
+ });
+ if (type === 'bgEvent') {
+ segs = filterSegsViaEls(this.context.view, segs, false // isMirror. background events can never be mirror elements
+ );
+ }
+ // correct element type? (would be bad if a non-TD were inserted into a table for example)
+ segs = segs.filter(function (seg) {
+ return elementMatches(seg.el, _this.fillSegTag);
+ });
+ }
+ return segs;
+ };
+ // Builds the HTML needed for one fill segment. Generic enough to work with different types.
+ FillRenderer.prototype.renderSegHtml = function (type, seg) {
+ var css = null;
+ var classNames = [];
+ if (type !== 'highlight' && type !== 'businessHours') {
+ css = {
+ 'background-color': seg.eventRange.ui.backgroundColor
+ };
+ }
+ if (type !== 'highlight') {
+ classNames = classNames.concat(seg.eventRange.ui.classNames);
+ }
+ if (type === 'businessHours') {
+ classNames.push('fc-bgevent');
+ }
+ else {
+ classNames.push('fc-' + type.toLowerCase());
+ }
+ return '<' + this.fillSegTag +
+ (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
+ (css ? ' style="' + cssToStr(css) + '"' : '') +
+ '></' + this.fillSegTag + '>';
+ };
+ FillRenderer.prototype.detachSegs = function (type, segs) {
+ var containerEls = this.containerElsByType[type];
+ if (containerEls) {
+ containerEls.forEach(removeElement);
+ delete this.containerElsByType[type];
+ }
+ };
+ FillRenderer.prototype.computeSizes = function (force) {
+ for (var type in this.segsByType) {
+ if (force || this.dirtySizeFlags[type]) {
+ this.computeSegSizes(this.segsByType[type]);
+ }
+ }
+ };
+ FillRenderer.prototype.assignSizes = function (force) {
+ for (var type in this.segsByType) {
+ if (force || this.dirtySizeFlags[type]) {
+ this.assignSegSizes(this.segsByType[type]);
+ }
+ }
+ this.dirtySizeFlags = {};
+ };
+ FillRenderer.prototype.computeSegSizes = function (segs) {
+ };
+ FillRenderer.prototype.assignSegSizes = function (segs) {
+ };
+ return FillRenderer;
+ }());
+
+ var NamedTimeZoneImpl = /** @class */ (function () {
+ function NamedTimeZoneImpl(timeZoneName) {
+ this.timeZoneName = timeZoneName;
+ }
+ return NamedTimeZoneImpl;
+ }());
+
+ /*
+ An abstraction for a dragging interaction originating on an event.
+ Does higher-level things than PointerDragger, such as possibly:
+ - a "mirror" that moves with the pointer
+ - a minimum number of pixels or other criteria for a true drag to begin
+
+ subclasses must emit:
+ - pointerdown
+ - dragstart
+ - dragmove
+ - pointerup
+ - dragend
+ */
+ var ElementDragging = /** @class */ (function () {
+ function ElementDragging(el) {
+ this.emitter = new EmitterMixin();
+ }
+ ElementDragging.prototype.destroy = function () {
+ };
+ ElementDragging.prototype.setMirrorIsVisible = function (bool) {
+ // optional if subclass doesn't want to support a mirror
+ };
+ ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
+ // optional if subclass doesn't want to support a mirror
+ };
+ ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
+ // optional
+ };
+ return ElementDragging;
+ }());
+
+ function formatDate(dateInput, settings) {
+ if (settings === void 0) { settings = {}; }
+ var dateEnv = buildDateEnv$1(settings);
+ var formatter = createFormatter(settings);
+ var dateMeta = dateEnv.createMarkerMeta(dateInput);
+ if (!dateMeta) { // TODO: warning?
+ return '';
+ }
+ return dateEnv.format(dateMeta.marker, formatter, {
+ forcedTzo: dateMeta.forcedTzo
+ });
+ }
+ function formatRange(startInput, endInput, settings // mixture of env and formatter settings
+ ) {
+ var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object
+ var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator);
+ var startMeta = dateEnv.createMarkerMeta(startInput);
+ var endMeta = dateEnv.createMarkerMeta(endInput);
+ if (!startMeta || !endMeta) { // TODO: warning?
+ return '';
+ }
+ return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
+ forcedStartTzo: startMeta.forcedTzo,
+ forcedEndTzo: endMeta.forcedTzo,
+ isEndExclusive: settings.isEndExclusive
+ });
+ }
+ // TODO: more DRY and optimized
+ function buildDateEnv$1(settings) {
+ var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
+ // ensure required settings
+ settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale });
+ return new DateEnv(settings);
+ }
+
+ var DRAG_META_PROPS = {
+ startTime: createDuration,
+ duration: createDuration,
+ create: Boolean,
+ sourceId: String
+ };
+ var DRAG_META_DEFAULTS = {
+ create: true
+ };
+ function parseDragMeta(raw) {
+ var leftoverProps = {};
+ var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps);
+ refined.leftoverProps = leftoverProps;
+ return refined;
+ }
+
+ // Computes a default column header formatting string if `colFormat` is not explicitly defined
+ function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
+ // if more than one week row, or if there are a lot of columns with not much space,
+ // put just the day numbers will be in each cell
+ if (!datesRepDistinctDays || dayCnt > 10) {
+ return { weekday: 'short' }; // "Sat"
+ }
+ else if (dayCnt > 1) {
+ return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12"
+ }
+ else {
+ return { weekday: 'long' }; // "Saturday"
+ }
+ }
+ function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) {
+ var view = context.view, dateEnv = context.dateEnv, theme = context.theme, options = context.options;
+ var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow.
+ var classNames = [
+ 'fc-day-header',
+ theme.getClass('widgetHeader')
+ ];
+ var innerHtml;
+ if (typeof options.columnHeaderHtml === 'function') {
+ innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker));
+ }
+ else if (typeof options.columnHeaderText === 'function') {
+ innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker)));
+ }
+ else {
+ innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat));
+ }
+ // if only one row of days, the classNames on the header can represent the specific days beneath
+ if (datesRepDistinctDays) {
+ classNames = classNames.concat(
+ // includes the day-of-week class
+ // noThemeHighlight=true (don't highlight the header)
+ getDayClasses(dateMarker, dateProfile, context, true));
+ }
+ else {
+ classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class
+ }
+ return '' +
+ '<th class="' + classNames.join(' ') + '"' +
+ ((isDateValid && datesRepDistinctDays) ?
+ ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' :
+ '') +
+ (colspan > 1 ?
+ ' colspan="' + colspan + '"' :
+ '') +
+ (otherAttrs ?
+ ' ' + otherAttrs :
+ '') +
+ '>' +
+ (isDateValid ?
+ // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
+ buildGotoAnchorHtml(view, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) :
+ // if not valid, display text, but no link
+ innerHtml) +
+ '</th>';
+ }
+
+ var DayHeader = /** @class */ (function (_super) {
+ __extends(DayHeader, _super);
+ function DayHeader(context, parentEl) {
+ var _this = _super.call(this, context) || this;
+ parentEl.innerHTML = ''; // because might be nbsp
+ parentEl.appendChild(_this.el = htmlToElement('<div class="fc-row ' + _this.theme.getClass('headerRow') + '">' +
+ '<table class="' + _this.theme.getClass('tableGrid') + '">' +
+ '<thead></thead>' +
+ '</table>' +
+ '</div>'));
+ _this.thead = _this.el.querySelector('thead');
+ return _this;
+ }
+ DayHeader.prototype.destroy = function () {
+ removeElement(this.el);
+ };
+ DayHeader.prototype.render = function (props) {
+ var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays;
+ var parts = [];
+ if (props.renderIntroHtml) {
+ parts.push(props.renderIntroHtml());
+ }
+ var colHeadFormat = createFormatter(this.opt('columnHeaderFormat') ||
+ computeFallbackHeaderFormat(datesRepDistinctDays, dates.length));
+ for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) {
+ var date = dates_1[_i];
+ parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, this.context));
+ }
+ if (this.isRtl) {
+ parts.reverse();
+ }
+ this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>';
+ };
+ return DayHeader;
+ }(Component));
+
+ var DaySeries = /** @class */ (function () {
+ function DaySeries(range, dateProfileGenerator) {
+ var date = range.start;
+ var end = range.end;
+ var indices = [];
+ var dates = [];
+ var dayIndex = -1;
+ while (date < end) { // loop each day from start to end
+ if (dateProfileGenerator.isHiddenDay(date)) {
+ indices.push(dayIndex + 0.5); // mark that it's between indices
+ }
+ else {
+ dayIndex++;
+ indices.push(dayIndex);
+ dates.push(date);
+ }
+ date = addDays(date, 1);
+ }
+ this.dates = dates;
+ this.indices = indices;
+ this.cnt = dates.length;
+ }
+ DaySeries.prototype.sliceRange = function (range) {
+ var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
+ var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
+ var clippedFirstIndex = Math.max(0, firstIndex);
+ var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
+ // deal with in-between indices
+ clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
+ clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
+ if (clippedFirstIndex <= clippedLastIndex) {
+ return {
+ firstIndex: clippedFirstIndex,
+ lastIndex: clippedLastIndex,
+ isStart: firstIndex === clippedFirstIndex,
+ isEnd: lastIndex === clippedLastIndex
+ };
+ }
+ else {
+ return null;
+ }
+ };
+ // Given a date, returns its chronolocial cell-index from the first cell of the grid.
+ // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
+ // If before the first offset, returns a negative number.
+ // If after the last offset, returns an offset past the last cell offset.
+ // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
+ DaySeries.prototype.getDateDayIndex = function (date) {
+ var indices = this.indices;
+ var dayOffset = Math.floor(diffDays(this.dates[0], date));
+ if (dayOffset < 0) {
+ return indices[0] - 1;
+ }
+ else if (dayOffset >= indices.length) {
+ return indices[indices.length - 1] + 1;
+ }
+ else {
+ return indices[dayOffset];
+ }
+ };
+ return DaySeries;
+ }());
+
+ var DayTable = /** @class */ (function () {
+ function DayTable(daySeries, breakOnWeeks) {
+ var dates = daySeries.dates;
+ var daysPerRow;
+ var firstDay;
+ var rowCnt;
+ if (breakOnWeeks) {
+ // count columns until the day-of-week repeats
+ firstDay = dates[0].getUTCDay();
+ for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
+ if (dates[daysPerRow].getUTCDay() === firstDay) {
+ break;
+ }
+ }
+ rowCnt = Math.ceil(dates.length / daysPerRow);
+ }
+ else {
+ rowCnt = 1;
+ daysPerRow = dates.length;
+ }
+ this.rowCnt = rowCnt;
+ this.colCnt = daysPerRow;
+ this.daySeries = daySeries;
+ this.cells = this.buildCells();
+ this.headerDates = this.buildHeaderDates();
+ }
+ DayTable.prototype.buildCells = function () {
+ var rows = [];
+ for (var row = 0; row < this.rowCnt; row++) {
+ var cells = [];
+ for (var col = 0; col < this.colCnt; col++) {
+ cells.push(this.buildCell(row, col));
+ }
+ rows.push(cells);
+ }
+ return rows;
+ };
+ DayTable.prototype.buildCell = function (row, col) {
+ return {
+ date: this.daySeries.dates[row * this.colCnt + col]
+ };
+ };
+ DayTable.prototype.buildHeaderDates = function () {
+ var dates = [];
+ for (var col = 0; col < this.colCnt; col++) {
+ dates.push(this.cells[0][col].date);
+ }
+ return dates;
+ };
+ DayTable.prototype.sliceRange = function (range) {
+ var colCnt = this.colCnt;
+ var seriesSeg = this.daySeries.sliceRange(range);
+ var segs = [];
+ if (seriesSeg) {
+ var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
+ var index = firstIndex;
+ while (index <= lastIndex) {
+ var row = Math.floor(index / colCnt);
+ var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
+ segs.push({
+ row: row,
+ firstCol: index % colCnt,
+ lastCol: (nextIndex - 1) % colCnt,
+ isStart: seriesSeg.isStart && index === firstIndex,
+ isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
+ });
+ index = nextIndex;
+ }
+ }
+ return segs;
+ };
+ return DayTable;
+ }());
+
+ var Slicer = /** @class */ (function () {
+ function Slicer() {
+ this.sliceBusinessHours = memoize(this._sliceBusinessHours);
+ this.sliceDateSelection = memoize(this._sliceDateSpan);
+ this.sliceEventStore = memoize(this._sliceEventStore);
+ this.sliceEventDrag = memoize(this._sliceInteraction);
+ this.sliceEventResize = memoize(this._sliceInteraction);
+ }
+ Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, component) {
+ var extraArgs = [];
+ for (var _i = 4; _i < arguments.length; _i++) {
+ extraArgs[_i - 4] = arguments[_i];
+ }
+ var eventUiBases = props.eventUiBases;
+ var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs));
+ return {
+ dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)),
+ businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, component].concat(extraArgs)),
+ fgEventSegs: eventSegs.fg,
+ bgEventSegs: eventSegs.bg,
+ eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
+ eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
+ eventSelection: props.eventSelection
+ }; // TODO: give interactionSegs?
+ };
+ Slicer.prototype.sliceNowDate = function (// does not memoize
+ date, component) {
+ var extraArgs = [];
+ for (var _i = 2; _i < arguments.length; _i++) {
+ extraArgs[_i - 2] = arguments[_i];
+ }
+ return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false },
+ {},
+ component].concat(extraArgs));
+ };
+ Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, component) {
+ var extraArgs = [];
+ for (var _i = 4; _i < arguments.length; _i++) {
+ extraArgs[_i - 4] = arguments[_i];
+ }
+ if (!businessHours) {
+ return [];
+ }
+ return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), component.calendar),
+ {},
+ dateProfile,
+ nextDayThreshold,
+ component].concat(extraArgs)).bg;
+ };
+ Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) {
+ var extraArgs = [];
+ for (var _i = 5; _i < arguments.length; _i++) {
+ extraArgs[_i - 5] = arguments[_i];
+ }
+ if (eventStore) {
+ var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
+ return {
+ bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs),
+ fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs)
+ };
+ }
+ else {
+ return { bg: [], fg: [] };
+ }
+ };
+ Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) {
+ var extraArgs = [];
+ for (var _i = 5; _i < arguments.length; _i++) {
+ extraArgs[_i - 5] = arguments[_i];
+ }
+ if (!interaction) {
+ return null;
+ }
+ var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
+ return {
+ segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs),
+ affectedInstances: interaction.affectedEvents.instances,
+ isEvent: interaction.isEvent,
+ sourceSeg: interaction.origSeg
+ };
+ };
+ Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) {
+ var extraArgs = [];
+ for (var _i = 3; _i < arguments.length; _i++) {
+ extraArgs[_i - 3] = arguments[_i];
+ }
+ if (!dateSpan) {
+ return [];
+ }
+ var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.calendar);
+ var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs));
+ for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
+ var seg = segs_1[_a];
+ seg.component = component;
+ seg.eventRange = eventRange;
+ }
+ return segs;
+ };
+ /*
+ "complete" seg means it has component and eventRange
+ */
+ Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill
+ extraArgs) {
+ var segs = [];
+ for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
+ var eventRange = eventRanges_1[_i];
+ segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs));
+ }
+ return segs;
+ };
+ /*
+ "complete" seg means it has component and eventRange
+ */
+ Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill
+ extraArgs) {
+ var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs));
+ for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
+ var seg = segs_2[_i];
+ seg.component = component;
+ seg.eventRange = eventRange;
+ seg.isStart = eventRange.isStart && seg.isStart;
+ seg.isEnd = eventRange.isEnd && seg.isEnd;
+ }
+ return segs;
+ };
+ return Slicer;
+ }());
+ /*
+ for incorporating minTime/maxTime if appropriate
+ TODO: should be part of DateProfile!
+ TimelineDateProfile already does this btw
+ */
+ function computeActiveRange(dateProfile, isComponentAllDay) {
+ var range = dateProfile.activeRange;
+ if (isComponentAllDay) {
+ return range;
+ }
+ return {
+ start: addMs(range.start, dateProfile.minTime.milliseconds),
+ end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day
+ };
+ }
+
+ // exports
+ // --------------------------------------------------------------------------------------------------
+ var version = '4.0.2';
+
+ exports.Calendar = Calendar;
+ exports.Component = Component;
+ exports.DateComponent = DateComponent;
+ exports.DateEnv = DateEnv;
+ exports.DateProfileGenerator = DateProfileGenerator;
+ exports.DayHeader = DayHeader;
+ exports.DaySeries = DaySeries;
+ exports.DayTable = DayTable;
+ exports.ElementDragging = ElementDragging;
+ exports.ElementScrollController = ElementScrollController;
+ exports.EmitterMixin = EmitterMixin;
+ exports.EventApi = EventApi;
+ exports.FgEventRenderer = FgEventRenderer;
+ exports.FillRenderer = FillRenderer;
+ exports.Interaction = Interaction;
+ exports.Mixin = Mixin;
+ exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
+ exports.PositionCache = PositionCache;
+ exports.ScrollComponent = ScrollComponent;
+ exports.ScrollController = ScrollController;
+ exports.Slicer = Slicer;
+ exports.Splitter = Splitter;
+ exports.Theme = Theme;
+ exports.View = View;
+ exports.WindowScrollController = WindowScrollController;
+ exports.addDays = addDays;
+ exports.addDurations = addDurations;
+ exports.addMs = addMs;
+ exports.addWeeks = addWeeks;
+ exports.allowContextMenu = allowContextMenu;
+ exports.allowSelection = allowSelection;
+ exports.appendToElement = appendToElement;
+ exports.applyAll = applyAll;
+ exports.applyMutationToEventStore = applyMutationToEventStore;
+ exports.applyStyle = applyStyle;
+ exports.applyStyleProp = applyStyleProp;
+ exports.asRoughMinutes = asRoughMinutes;
+ exports.asRoughMs = asRoughMs;
+ exports.asRoughSeconds = asRoughSeconds;
+ exports.buildGotoAnchorHtml = buildGotoAnchorHtml;
+ exports.buildSegCompareObj = buildSegCompareObj;
+ exports.capitaliseFirstLetter = capitaliseFirstLetter;
+ exports.combineEventUis = combineEventUis;
+ exports.compareByFieldSpec = compareByFieldSpec;
+ exports.compareByFieldSpecs = compareByFieldSpecs;
+ exports.compareNumbers = compareNumbers;
+ exports.compensateScroll = compensateScroll;
+ exports.computeClippingRect = computeClippingRect;
+ exports.computeEdges = computeEdges;
+ exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
+ exports.computeHeightAndMargins = computeHeightAndMargins;
+ exports.computeInnerRect = computeInnerRect;
+ exports.computeRect = computeRect;
+ exports.computeVisibleDayRange = computeVisibleDayRange;
+ exports.config = config;
+ exports.constrainPoint = constrainPoint;
+ exports.createDuration = createDuration;
+ exports.createElement = createElement;
+ exports.createEmptyEventStore = createEmptyEventStore;
+ exports.createEventInstance = createEventInstance;
+ exports.createFormatter = createFormatter;
+ exports.createPlugin = createPlugin;
+ exports.cssToStr = cssToStr;
+ exports.debounce = debounce;
+ exports.diffDates = diffDates;
+ exports.diffDayAndTime = diffDayAndTime;
+ exports.diffDays = diffDays;
+ exports.diffPoints = diffPoints;
+ exports.diffWeeks = diffWeeks;
+ exports.diffWholeDays = diffWholeDays;
+ exports.diffWholeWeeks = diffWholeWeeks;
+ exports.disableCursor = disableCursor;
+ exports.distributeHeight = distributeHeight;
+ exports.elementClosest = elementClosest;
+ exports.elementMatches = elementMatches;
+ exports.enableCursor = enableCursor;
+ exports.eventTupleToStore = eventTupleToStore;
+ exports.filterEventStoreDefs = filterEventStoreDefs;
+ exports.filterHash = filterHash;
+ exports.findChildren = findChildren;
+ exports.findElements = findElements;
+ exports.flexibleCompare = flexibleCompare;
+ exports.forceClassName = forceClassName;
+ exports.formatDate = formatDate;
+ exports.formatIsoTimeString = formatIsoTimeString;
+ exports.formatRange = formatRange;
+ exports.freezeRaw = freezeRaw;
+ exports.getAllDayHtml = getAllDayHtml;
+ exports.getClippingParents = getClippingParents;
+ exports.getDayClasses = getDayClasses;
+ exports.getElSeg = getElSeg;
+ exports.getRectCenter = getRectCenter;
+ exports.getRelevantEvents = getRelevantEvents;
+ exports.globalDefaults = globalDefaults;
+ exports.greatestDurationDenominator = greatestDurationDenominator;
+ exports.hasBgRendering = hasBgRendering;
+ exports.htmlEscape = htmlEscape;
+ exports.htmlToElement = htmlToElement;
+ exports.insertAfterElement = insertAfterElement;
+ exports.interactionSettingsStore = interactionSettingsStore;
+ exports.interactionSettingsToStore = interactionSettingsToStore;
+ exports.intersectRanges = intersectRanges;
+ exports.intersectRects = intersectRects;
+ exports.isArraysEqual = isArraysEqual;
+ exports.isDateSpansEqual = isDateSpansEqual;
+ exports.isInt = isInt;
+ exports.isInteractionValid = isInteractionValid;
+ exports.isMultiDayRange = isMultiDayRange;
+ exports.isObjectsSimilar = isObjectsSimilar;
+ exports.isPropsValid = isPropsValid;
+ exports.isSingleDay = isSingleDay;
+ exports.isValidDate = isValidDate;
+ exports.isValuesSimilar = isValuesSimilar;
+ exports.listenBySelector = listenBySelector;
+ exports.mapHash = mapHash;
+ exports.matchCellWidths = matchCellWidths;
+ exports.memoize = memoize;
+ exports.memoizeOutput = memoizeOutput;
+ exports.memoizeRendering = memoizeRendering;
+ exports.mergeEventStores = mergeEventStores;
+ exports.multiplyDuration = multiplyDuration;
+ exports.padStart = padStart;
+ exports.parseBusinessHours = parseBusinessHours;
+ exports.parseDragMeta = parseDragMeta;
+ exports.parseEventDef = parseEventDef;
+ exports.parseFieldSpecs = parseFieldSpecs;
+ exports.parseMarker = parse;
+ exports.pointInsideRect = pointInsideRect;
+ exports.prependToElement = prependToElement;
+ exports.preventContextMenu = preventContextMenu;
+ exports.preventDefault = preventDefault;
+ exports.preventSelection = preventSelection;
+ exports.processScopedUiProps = processScopedUiProps;
+ exports.rangeContainsMarker = rangeContainsMarker;
+ exports.rangeContainsRange = rangeContainsRange;
+ exports.rangesEqual = rangesEqual;
+ exports.rangesIntersect = rangesIntersect;
+ exports.refineProps = refineProps;
+ exports.removeElement = removeElement;
+ exports.removeExact = removeExact;
+ exports.renderDateCell = renderDateCell;
+ exports.requestJson = requestJson;
+ exports.sliceEventStore = sliceEventStore;
+ exports.startOfDay = startOfDay;
+ exports.subtractInnerElHeight = subtractInnerElHeight;
+ exports.translateRect = translateRect;
+ exports.uncompensateScroll = uncompensateScroll;
+ exports.undistributeHeight = undistributeHeight;
+ exports.unpromisify = unpromisify;
+ exports.version = version;
+ exports.whenTransitionDone = whenTransitionDone;
+ exports.wholeDivideDurations = wholeDivideDurations;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/core/main.min.css b/library/fullcalendar/packages/core/main.min.css
new file mode 100644
index 000000000..3ac6b3e2f
--- /dev/null
+++ b/library/fullcalendar/packages/core/main.min.css
@@ -0,0 +1,5 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/.fc-button:not(:disabled),.fc-event.fc-draggable,.fc-event[href],.fc-popover .fc-header .fc-close,a.fc-more,a[data-goto]{cursor:pointer}.fc-bg,.fc-row .fc-bgevent-skeleton,.fc-row .fc-highlight-skeleton{bottom:0}.fc{direction:ltr;text-align:left}.fc-rtl{text-align:right}body .fc{font-size:1em}.fc-highlight{background:#bce8f1;opacity:.3}.fc-bgevent{background:#8fdf82;opacity:.3}.fc-nonbusiness{background:#d7d7d7}.fc-popover{position:absolute;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc-popover .fc-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding:2px 4px}.fc-rtl .fc-popover .fc-header{flex-direction:row-reverse}.fc-popover .fc-header .fc-title{margin:0 2px}.fc-popover .fc-header .fc-close{opacity:.65;font-size:1.1em}.fc-divider{border-style:solid;border-width:1px}hr.fc-divider{height:0;margin:0;padding:0 0 2px;border-width:1px 0}.fc-bg table,.fc-row .fc-bgevent-skeleton table,.fc-row .fc-highlight-skeleton table{height:100%}.fc-bg,.fc-bgevent-skeleton,.fc-highlight-skeleton,.fc-mirror-skeleton{position:absolute;top:0;left:0;right:0}.fc table{width:100%;box-sizing:border-box;table-layout:fixed;border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{border-style:solid;border-width:1px;padding:0;vertical-align:top}.fc td.fc-today{border-style:double}a[data-goto]:hover{text-decoration:underline}.fc .fc-row{border-style:solid;border-width:0}.fc-row table{border-left:0 hidden transparent;border-right:0 hidden transparent;border-bottom:0 hidden transparent}.fc-row:first-child table{border-top:0 hidden transparent}.fc-row{position:relative}.fc-row .fc-bg{z-index:1}.fc-row .fc-bgevent-skeleton td,.fc-row .fc-highlight-skeleton td{border-color:transparent}.fc-row .fc-bgevent-skeleton{z-index:2}.fc-row .fc-highlight-skeleton{z-index:3}.fc-row .fc-content-skeleton{position:relative;z-index:4;padding-bottom:2px}.fc-row .fc-mirror-skeleton{z-index:5}.fc .fc-row .fc-content-skeleton table,.fc .fc-row .fc-content-skeleton td,.fc .fc-row .fc-mirror-skeleton td{background:0 0;border-color:transparent}.fc-row .fc-content-skeleton td,.fc-row .fc-mirror-skeleton td{border-bottom:0}.fc-row .fc-content-skeleton tbody td,.fc-row .fc-mirror-skeleton tbody td{border-top:0}.fc-scroller{-webkit-overflow-scrolling:touch}.fc-scroller>.fc-day-grid,.fc-scroller>.fc-time-grid{position:relative;width:100%}.fc-event{position:relative;display:block;font-size:.85em;line-height:1.4;border-radius:3px;border:1px solid #3788d8}.fc-event,.fc-event-dot{background-color:#3788d8}.fc-event,.fc-event:hover{color:#fff;text-decoration:none}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-event .fc-content{position:relative;z-index:2}.fc-event .fc-resizer{position:absolute;z-index:4;display:none}.fc-event.fc-allow-mouse-resize .fc-resizer,.fc-event.fc-selected .fc-resizer{display:block}.fc-event.fc-selected .fc-resizer:before{content:"";position:absolute;z-index:9999;top:50%;left:50%;width:40px;height:40px;margin-left:-20px;margin-top:-20px}.fc-event.fc-selected{z-index:9999!important;box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event.fc-selected:after{content:"";position:absolute;z-index:1;top:-1px;right:-1px;bottom:-1px;left:-1px;background:#000;opacity:.25}.fc-event.fc-dragging.fc-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event.fc-dragging:not(.fc-selected){opacity:.75}.fc-h-event.fc-selected:before{content:"";position:absolute;z-index:3;top:-10px;bottom:-10px;left:0;right:0}.fc-ltr .fc-h-event.fc-not-start,.fc-rtl .fc-h-event.fc-not-end{margin-left:0;border-left-width:0;padding-left:1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-ltr .fc-h-event.fc-not-end,.fc-rtl .fc-h-event.fc-not-start{margin-right:0;border-right-width:0;padding-right:1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-ltr .fc-h-event .fc-start-resizer,.fc-rtl .fc-h-event .fc-end-resizer{cursor:w-resize;left:-1px}.fc-ltr .fc-h-event .fc-end-resizer,.fc-rtl .fc-h-event .fc-start-resizer{cursor:e-resize;right:-1px}.fc-h-event.fc-allow-mouse-resize .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-h-event.fc-selected .fc-resizer{border-radius:4px;border-width:1px;width:6px;height:6px;border-style:solid;border-color:inherit;background:#fff;top:50%;margin-top:-4px}.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,.fc-rtl .fc-h-event.fc-selected .fc-end-resizer{margin-left:-4px}.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,.fc-rtl .fc-h-event.fc-selected .fc-start-resizer{margin-right:-4px}.fc-day-grid-event{margin:1px 2px 0;padding:0 1px}tr:first-child>td>.fc-day-grid-event{margin-top:2px}.fc-mirror-skeleton tr:first-child>td>.fc-day-grid-event{margin-top:0}.fc-day-grid-event .fc-content{white-space:nowrap;overflow:hidden}.fc-day-grid-event .fc-time{font-weight:700}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer{margin-left:-2px}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer{margin-right:-2px}a.fc-more{margin:1px 3px;font-size:.85em;text-decoration:none}a.fc-more:hover{text-decoration:underline}.fc-limited{display:none}.fc-button,.fc-icon{display:inline-block;font-weight:400;text-align:center}.fc-day-grid .fc-row{z-index:1}.fc-more-popover{z-index:2;width:220px}.fc-more-popover .fc-event-container{padding:10px}.fc-now-indicator{position:absolute;border:0 solid red}.fc-unselectable{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.fc-unthemed .fc-content,.fc-unthemed .fc-divider,.fc-unthemed .fc-list-heading td,.fc-unthemed .fc-list-view,.fc-unthemed .fc-popover,.fc-unthemed .fc-row,.fc-unthemed tbody,.fc-unthemed td,.fc-unthemed th,.fc-unthemed thead{border-color:#ddd}.fc-unthemed .fc-popover{background-color:#fff}.fc-unthemed .fc-divider,.fc-unthemed .fc-list-heading td,.fc-unthemed .fc-popover .fc-header{background:#eee}.fc-unthemed td.fc-today{background:#fcf8e3}.fc-unthemed .fc-disabled-day{background:#d7d7d7;opacity:.3}@font-face{font-family:fcicons;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype");font-weight:400;font-style:normal}.fc-icon{font-family:fcicons!important;speak:none;font-style:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:1em;height:1em}.fc-icon-chevron-left:before{content:"\e900"}.fc-icon-chevron-right:before{content:"\e901"}.fc-icon-chevrons-left:before{content:"\e902"}.fc-icon-chevrons-right:before{content:"\e903"}.fc-icon-minus-square:before{content:"\e904"}.fc-icon-plus-square:before{content:"\e905"}.fc-icon-x:before{content:"\e906"}.fc-button{overflow:visible;text-transform:none;margin:0;font-family:inherit}.fc-button::-moz-focus-inner{padding:0;border-style:none}.fc-button{-webkit-appearance:button;color:#212529;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.4em .65em;font-size:1em;line-height:1.5;border-radius:.25em}.fc-button:hover{color:#212529;text-decoration:none}.fc-button:focus{outline:0;-webkit-box-shadow:0 0 0 .2rem rgba(44,62,80,.25);box-shadow:0 0 0 .2rem rgba(44,62,80,.25)}.fc-button:disabled{opacity:.65}.fc-button-primary{color:#fff;background-color:#2C3E50;border-color:#2C3E50}.fc-button-primary:hover{color:#fff;background-color:#1e2b37;border-color:#1a252f}.fc-button-primary:focus{-webkit-box-shadow:0 0 0 .2rem rgba(76,91,106,.5);box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc-button-primary:disabled{color:#fff;background-color:#2C3E50;border-color:#2C3E50}.fc-button-primary:not(:disabled).fc-button-active,.fc-button-primary:not(:disabled):active{color:#fff;background-color:#1a252f;border-color:#151e27}.fc-button-primary:not(:disabled).fc-button-active:focus,.fc-button-primary:not(:disabled):active:focus{-webkit-box-shadow:0 0 0 .2rem rgba(76,91,106,.5);box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc-button .fc-icon{vertical-align:middle;font-size:1.5em}.fc-button-group{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.fc-button-group>.fc-button{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.fc-button-group>.fc-button.fc-button-active,.fc-button-group>.fc-button:active,.fc-button-group>.fc-button:focus,.fc-button-group>.fc-button:hover{z-index:1}.fc-button-group>.fc-button:not(:first-child){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-button-group>.fc-button:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.fc-unthemed .fc-popover{border-width:1px;border-style:solid}.fc-unthemed .fc-list-item:hover td{background-color:#f5f5f5}.fc-toolbar{display:flex;justify-content:space-between;align-items:center}.fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-toolbar h2{font-size:1.75em;margin:0}.fc-view-container{position:relative}.fc-view-container *,.fc-view-container :after,.fc-view-container :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fc-view,.fc-view>table{position:relative;z-index:1}@media print{.fc-bg,.fc-bgevent-container,.fc-bgevent-skeleton,.fc-business-container,.fc-event .fc-resizer,.fc-highlight-container,.fc-highlight-skeleton,.fc-mirror-container,.fc-mirror-skeleton{display:none}.fc tbody .fc-row,.fc-time-grid{min-height:0!important}.fc-time-grid .fc-event.fc-not-end:after,.fc-time-grid .fc-event.fc-not-start:before{content:"..."}.fc{max-width:100%!important}.fc-event{background:#fff!important;color:#000!important;page-break-inside:avoid}.fc hr,.fc tbody,.fc td,.fc th,.fc thead,.fc-row{border-color:#ccc!important;background:#fff!important}.fc tbody .fc-row{height:auto!important}.fc tbody .fc-row .fc-content-skeleton{position:static;padding-bottom:0!important}.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td{padding-bottom:1em}.fc tbody .fc-row .fc-content-skeleton table{height:1em}.fc-more,.fc-more-cell{display:none!important}.fc tr.fc-limited{display:table-row!important}.fc td.fc-limited{display:table-cell!important}.fc-popover,.fc-timeGrid-view .fc-axis{display:none}.fc-slats,.fc-time-grid hr{display:none!important}.fc button,.fc-button-group,.fc-time-grid .fc-event .fc-time span{display:none}.fc-time-grid .fc-content-skeleton{position:static}.fc-time-grid .fc-content-skeleton table{height:4em}.fc-time-grid .fc-event-container{margin:0!important}.fc-time-grid .fc-event{position:static!important;margin:3px 2px!important}.fc-time-grid .fc-event.fc-not-end{border-bottom-width:1px!important}.fc-time-grid .fc-event.fc-not-start{border-top-width:1px!important}.fc-time-grid .fc-event .fc-time{white-space:normal!important}.fc-time-grid .fc-event .fc-time:after{content:attr(data-full)}.fc-day-grid-container,.fc-scroller,.fc-time-grid-container{overflow:visible!important;height:auto!important}.fc-row{border:0!important;margin:0!important}} \ No newline at end of file
diff --git a/library/fullcalendar/packages/core/main.min.js b/library/fullcalendar/packages/core/main.min.js
new file mode 100644
index 000000000..a961abf95
--- /dev/null
+++ b/library/fullcalendar/packages/core/main.min.js
@@ -0,0 +1,9 @@
+/*!
+FullCalendar Core Package v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):(e=e||self,t(e.FullCalendar={}))}(this,function(e){"use strict";function t(e,t,n){var r=document.createElement(e);if(t)for(var i in t)"style"===i?g(r,t[i]):mi[i]?r[i]=t[i]:r.setAttribute(i,t[i]);return"string"==typeof n?r.innerHTML=n:null!=n&&a(r,n),r}function n(e){e=e.trim();var t=document.createElement(o(e));return t.innerHTML=e,t.firstChild}function r(e){return Array.prototype.slice.call(i(e))}function i(e){e=e.trim();var t=document.createElement(o(e));return t.innerHTML=e,t.childNodes}function o(e){return Ei[e.substr(0,3)]||"div"}function a(e,t){for(var n=l(t),r=0;r<n.length;r++)e.appendChild(n[r])}function s(e,t){for(var n=l(t),r=e.firstChild||null,i=0;i<n.length;i++)e.insertBefore(n[i],r)}function u(e,t){for(var n=l(t),r=e.nextSibling||null,i=0;i<n.length;i++)e.parentNode.insertBefore(n[i],r)}function l(e){return"string"==typeof e?r(e):e instanceof Node?[e]:Array.prototype.slice.call(e)}function c(e){e.parentNode&&e.parentNode.removeChild(e)}function d(e,t){return Di.call(e,t)}function f(e,t){return Si.call(e,t)}function p(e,t){for(var n=e instanceof HTMLElement?[e]:e,r=[],i=0;i<n.length;i++)for(var o=n[i].querySelectorAll(t),a=0;a<o.length;a++)r.push(o[a]);return r}function h(e,t){for(var n=e instanceof HTMLElement?[e]:e,r=[],i=0;i<n.length;i++)for(var o=n[i].children,a=0;a<o.length;a++){var s=o[a];t&&!f(s,t)||r.push(s)}return r}function v(e,t,n){n?e.classList.add(t):e.classList.remove(t)}function g(e,t){for(var n in t)y(e,n,t[n])}function y(e,t,n){null==n?e.style[t]="":"number"==typeof n&&bi.test(t)?e.style[t]=n+"px":e.style[t]=n}function m(e,t){return e.left>=t.left&&e.left<t.right&&e.top>=t.top&&e.top<t.bottom}function E(e,t){var n={left:Math.max(e.left,t.left),right:Math.min(e.right,t.right),top:Math.max(e.top,t.top),bottom:Math.min(e.bottom,t.bottom)};return n.left<n.right&&n.top<n.bottom&&n}function S(e,t,n){return{left:e.left+t,right:e.right+t,top:e.top+n,bottom:e.bottom+n}}function D(e,t){return{left:Math.min(Math.max(e.left,t.left),t.right),top:Math.min(Math.max(e.top,t.top),t.bottom)}}function b(e){return{left:(e.left+e.right)/2,top:(e.top+e.bottom)/2}}function T(e,t){return{left:e.left-t.left,top:e.top-t.top}}function w(){return null===Ti&&(Ti=R()),Ti}function R(){var e=t("div",{style:{position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}},"<div></div>");document.body.appendChild(e);var n=e.firstChild,r=n.getBoundingClientRect().left>e.getBoundingClientRect().left;return c(e),r}function I(e){return e=Math.max(0,e),e=Math.round(e)}function C(e,t){void 0===t&&(t=!1);var n=window.getComputedStyle(e),r=parseInt(n.borderLeftWidth,10)||0,i=parseInt(n.borderRightWidth,10)||0,o=parseInt(n.borderTopWidth,10)||0,a=parseInt(n.borderBottomWidth,10)||0,s=I(e.offsetWidth-e.clientWidth-r-i),u=I(e.offsetHeight-e.clientHeight-o-a),l={borderLeft:r,borderRight:i,borderTop:o,borderBottom:a,scrollbarBottom:u,scrollbarLeft:0,scrollbarRight:0};return w()&&"rtl"===n.direction?l.scrollbarLeft=s:l.scrollbarRight=s,t&&(l.paddingLeft=parseInt(n.paddingLeft,10)||0,l.paddingRight=parseInt(n.paddingRight,10)||0,l.paddingTop=parseInt(n.paddingTop,10)||0,l.paddingBottom=parseInt(n.paddingBottom,10)||0),l}function M(e,t){void 0===t&&(t=!1);var n=k(e),r=C(e,t),i={left:n.left+r.borderLeft+r.scrollbarLeft,right:n.right-r.borderRight-r.scrollbarRight,top:n.top+r.borderTop,bottom:n.bottom-r.borderBottom-r.scrollbarBottom};return t&&(i.left+=r.paddingLeft,i.right-=r.paddingRight,i.top+=r.paddingTop,i.bottom-=r.paddingBottom),i}function k(e){var t=e.getBoundingClientRect();return{left:t.left+window.pageXOffset,top:t.top+window.pageYOffset,right:t.right+window.pageXOffset,bottom:t.bottom+window.pageYOffset}}function O(){return{left:window.pageXOffset,right:window.pageXOffset+document.documentElement.clientWidth,top:window.pageYOffset,bottom:window.pageYOffset+document.documentElement.clientHeight}}function _(e){var t=window.getComputedStyle(e);return e.getBoundingClientRect().height+parseInt(t.marginTop,10)+parseInt(t.marginBottom,10)}function P(e){for(var t=[];e instanceof HTMLElement;){var n=window.getComputedStyle(e);if("fixed"===n.position)break;/(auto|scroll)/.test(n.overflow+n.overflowY+n.overflowX)&&t.push(e),e=e.parentNode}return t}function H(e){return P(e).map(function(e){return M(e)}).concat(O()).reduce(function(e,t){return E(e,t)||t})}function x(e){e.preventDefault()}function N(e,t,n,r){function i(e){var t=d(e.target,n);t&&r.call(t,e,t)}return e.addEventListener(t,i),function(){e.removeEventListener(t,i)}}function z(e,t,n,r){var i;return N(e,"mouseover",t,function(e,t){if(t!==i){i=t,n(e,t);var o=function(e){i=null,r(e,t),t.removeEventListener("mouseleave",o)};t.addEventListener("mouseleave",o)}})}function U(e,t){var n=function(r){t(r),wi.forEach(function(t){e.removeEventListener(t,n)})};wi.forEach(function(t){e.addEventListener(t,n)})}function L(e,t){var n=ie(e);return n[2]+=7*t,oe(n)}function A(e,t){var n=ie(e);return n[2]+=t,oe(n)}function V(e,t){var n=ie(e);return n[6]+=t,oe(n)}function B(e,t){return F(e,t)/7}function F(e,t){return(t.valueOf()-e.valueOf())/864e5}function W(e,t){return(t.valueOf()-e.valueOf())/36e5}function Z(e,t){return(t.valueOf()-e.valueOf())/6e4}function j(e,t){return(t.valueOf()-e.valueOf())/1e3}function Y(e,t){var n=X(e),r=X(t);return{years:0,months:0,days:Math.round(F(n,r)),milliseconds:t.valueOf()-r.valueOf()-(e.valueOf()-n.valueOf())}}function q(e,t){var n=G(e,t);return null!==n&&n%7==0?n/7:null}function G(e,t){return se(e)===se(t)?Math.round(F(e,t)):null}function X(e){return oe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()])}function J(e){return oe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours()])}function K(e){return oe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes()])}function Q(e){return oe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds()])}function $(e,t,n){var r=e.getUTCFullYear(),i=ee(e,r,t,n);if(i<1)return ee(e,r-1,t,n);var o=ee(e,r+1,t,n);return o>=1?Math.min(i,o):i}function ee(e,t,n,r){var i=oe([t,0,1+te(t,n,r)]),o=X(e),a=Math.round(F(i,o));return Math.floor(a/7)+1}function te(e,t,n){var r=7+t-n;return-(7+oe([e,0,r]).getUTCDay()-t)%7+r-1}function ne(e){return[e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()]}function re(e){return new Date(e[0],e[1]||0,null==e[2]?1:e[2],e[3]||0,e[4]||0,e[5]||0)}function ie(e){return[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()]}function oe(e){return 1===e.length&&(e=e.concat([0])),new Date(Date.UTC.apply(Date,e))}function ae(e){return!isNaN(e.valueOf())}function se(e){return 1e3*e.getUTCHours()*60*60+1e3*e.getUTCMinutes()*60+1e3*e.getUTCSeconds()+e.getUTCMilliseconds()}function ue(e,t){var n;return"string"==typeof e?le(e):"object"==typeof e&&e?ce(e):"number"==typeof e?ce((n={},n[t||"milliseconds"]=e,n)):null}function le(e){var t=Ci.exec(e);if(t){var n=t[1]?-1:1;return{years:0,months:0,days:n*(t[2]?parseInt(t[2],10):0),milliseconds:n*(60*(t[3]?parseInt(t[3],10):0)*60*1e3+60*(t[4]?parseInt(t[4],10):0)*1e3+1e3*(t[5]?parseInt(t[5],10):0)+(t[6]?parseInt(t[6],10):0))}}return null}function ce(e){return{years:e.years||e.year||0,months:e.months||e.month||0,days:(e.days||e.day||0)+7*de(e),milliseconds:60*(e.hours||e.hour||0)*60*1e3+60*(e.minutes||e.minute||0)*1e3+1e3*(e.seconds||e.second||0)+(e.milliseconds||e.millisecond||e.ms||0)}}function de(e){return e.weeks||e.week||0}function fe(e,t){return e.years===t.years&&e.months===t.months&&e.days===t.days&&e.milliseconds===t.milliseconds}function pe(e){return 0===e.years&&0===e.months&&1===e.days&&0===e.milliseconds}function he(e,t){return{years:e.years+t.years,months:e.months+t.months,days:e.days+t.days,milliseconds:e.milliseconds+t.milliseconds}}function ve(e,t){return{years:e.years-t.years,months:e.months-t.months,days:e.days-t.days,milliseconds:e.milliseconds-t.milliseconds}}function ge(e,t){return{years:e.years*t,months:e.months*t,days:e.days*t,milliseconds:e.milliseconds*t}}function ye(e){return Ee(e)/365}function me(e){return Ee(e)/30}function Ee(e){return be(e)/864e5}function Se(e){return be(e)/6e4}function De(e){return be(e)/1e3}function be(e){return 31536e6*e.years+2592e6*e.months+864e5*e.days+e.milliseconds}function Te(e,t){for(var n=null,r=0;r<Ii.length;r++){var i=Ii[r];if(t[i]){var o=e[i]/t[i];if(!Ze(o)||null!==n&&n!==o)return null;n=o}else if(e[i])return null}return n}function we(e,t){var n=e.milliseconds;if(n){if(n%1e3!=0)return{unit:"millisecond",value:n};if(n%6e4!=0)return{unit:"second",value:n/1e3};if(n%36e5!=0)return{unit:"minute",value:n/6e4};if(n)return{unit:"hour",value:n/36e5}}return e.days?t||e.days%7!=0?{unit:"day",value:e.days}:{unit:"week",value:e.days/7}:e.months?{unit:"month",value:e.months}:e.years?{unit:"year",value:e.years}:{unit:"millisecond",value:0}}function Re(e,t){t.left&&g(e,{borderLeftWidth:1,marginLeft:t.left-1}),t.right&&g(e,{borderRightWidth:1,marginRight:t.right-1})}function Ie(e){g(e,{marginLeft:"",marginRight:"",borderLeftWidth:"",borderRightWidth:""})}function Ce(){document.body.classList.add("fc-not-allowed")}function Me(){document.body.classList.remove("fc-not-allowed")}function ke(e,t,n){var r=Math.floor(t/e.length),i=Math.floor(t-r*(e.length-1)),o=[],a=[],s=[],u=0;Oe(e),e.forEach(function(t,n){var l=n===e.length-1?i:r,c=_(t);c<l?(o.push(t),a.push(c),s.push(t.offsetHeight)):u+=c}),n&&(t-=u,r=Math.floor(t/o.length),i=Math.floor(t-r*(o.length-1))),o.forEach(function(e,t){var n=t===o.length-1?i:r,u=a[t],l=s[t],c=n-(u-l);u<n&&(e.style.height=c+"px")})}function Oe(e){e.forEach(function(e){e.style.height=""})}function _e(e){var t=0;return e.forEach(function(e){var n=e.firstChild;if(n instanceof HTMLElement){var r=n.offsetWidth;r>t&&(t=r)}}),t++,e.forEach(function(e){e.style.width=t+"px"}),t}function Pe(e,t){var n={position:"relative",left:-1};g(e,n),g(t,n);var r=e.offsetHeight-t.offsetHeight,i={position:"",left:""};return g(e,i),g(t,i),r}function He(e){e.classList.add("fc-unselectable"),e.addEventListener("selectstart",x)}function xe(e){e.classList.remove("fc-unselectable"),e.removeEventListener("selectstart",x)}function Ne(e){e.addEventListener("contextmenu",x)}function ze(e){e.removeEventListener("contextmenu",x)}function Ue(e){var t,n,r=[],i=[];for("string"==typeof e?i=e.split(/\s*,\s*/):"function"==typeof e?i=[e]:Array.isArray(e)&&(i=e),t=0;t<i.length;t++)n=i[t],"string"==typeof n?r.push("-"===n.charAt(0)?{field:n.substring(1),order:-1}:{field:n,order:1}):"function"==typeof n&&r.push({func:n});return r}function Le(e,t,n){var r,i;for(r=0;r<n.length;r++)if(i=Ae(e,t,n[r]))return i;return 0}function Ae(e,t,n){return n.func?n.func(e,t):Ve(e[n.field],t[n.field])*(n.order||1)}function Ve(e,t){return e||t?null==t?-1:null==e?1:"string"==typeof e||"string"==typeof t?String(e).localeCompare(String(t)):e-t:0}function Be(e){return e.charAt(0).toUpperCase()+e.slice(1)}function Fe(e,t){var n=String(e);return"000".substr(0,t-n.length)+n}function We(e,t){return e-t}function Ze(e){return e%1==0}function je(e,t,n){if("function"==typeof e&&(e=[e]),e){var r=void 0,i=void 0;for(r=0;r<e.length;r++)i=e[r].apply(t,n)||i;return i}}function Ye(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];for(var n=0;n<e.length;n++)if(void 0!==e[n])return e[n]}function qe(e,t){var n,r,i,o,a,s=function(){var u=(new Date).valueOf()-o;u<t?n=setTimeout(s,t-u):(n=null,a=e.apply(i,r),i=r=null)};return function(){return i=this,r=arguments,o=(new Date).valueOf(),n||(n=setTimeout(s,t)),a}}function Ge(e,t,n,r){void 0===n&&(n={});var i={};for(var o in t){var a=t[o];void 0!==e[o]?a===Function?i[o]="function"==typeof e[o]?e[o]:null:i[o]=a?a(e[o]):e[o]:void 0!==n[o]?i[o]=n[o]:a===String?i[o]="":a&&a!==Number&&a!==Boolean&&a!==Function?i[o]=a(null):i[o]=null}if(r)for(var o in e)void 0===t[o]&&(r[o]=e[o]);return i}function Xe(e){return Array.isArray(e)?Array.prototype.slice.call(e):e}function Je(e){var t=Math.floor(F(e.start,e.end))||1,n=X(e.start);return{start:n,end:A(n,t)}}function Ke(e,t){void 0===t&&(t=ue(0));var n=null,r=null;if(e.end){r=X(e.end);var i=e.end.valueOf()-r.valueOf();i&&i>=be(t)&&(r=A(r,1))}return e.start&&(n=X(e.start),r&&r<=n&&(r=A(n,1))),{start:n,end:r}}function Qe(e){var t=Ke(e);return F(t.start,t.end)>1}function $e(e,t,n,r){return"year"===r?ue(n.diffWholeYears(e,t),"year"):"month"===r?ue(n.diffWholeMonths(e,t),"month"):Y(e,t)}function et(e,t){function n(){this.constructor=e}Mi(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}function tt(e,t,n,r,i){for(var o=0;o<r.length;o++){var a={},s=r[o].parse(e,a,n);if(s){var u=a.allDay;return delete a.allDay,null==u&&null==(u=t)&&null==(u=s.allDayGuess)&&(u=!1),ki(i,a),{allDay:u,duration:s.duration,typeData:s.typeData,typeId:o}}}return null}function nt(e,t,n,r){var i=r[e.recurringDef.typeId],o=i.expand(e.recurringDef.typeData,t,n);return e.allDay&&(o=o.map(X)),o}function rt(e,t){var n,r,i,o,a,s,u={};if(t)for(n=0;n<t.length;n++){for(r=t[n],i=[],o=e.length-1;o>=0;o--)if("object"==typeof(a=e[o][r])&&a)i.unshift(a);else if(void 0!==a){u[r]=a;break}i.length&&(u[r]=rt(i))}for(n=e.length-1;n>=0;n--){s=e[n];for(r in s)r in u||(u[r]=s[r])}return u}function it(e,t){var n={};for(var r in e)t(e[r],r)&&(n[r]=e[r]);return n}function ot(e,t){var n={};for(var r in e)n[r]=t(e[r],r);return n}function at(e){for(var t={},n=0,r=e;n<r.length;n++){t[r[n]]=!0}return t}function st(e){var t=[];for(var n in e)t.push(e[n]);return t}function ut(e,t,n,r){for(var i=vt(),o=0,a=e;o<a.length;o++){var s=a[o],u=On(s,t,n,r);u&&lt(u,i)}return i}function lt(e,t){return void 0===t&&(t=vt()),t.defs[e.def.defId]=e.def,e.instance&&(t.instances[e.instance.instanceId]=e.instance),t}function ct(e,t,n){var r=n.dateEnv,i=e.defs,o=e.instances;o=it(o,function(e){return!i[e.defId].recurringDef});for(var a in i){var s=i[a];if(s.recurringDef){var u=nt(s,t,n.dateEnv,n.pluginSystem.hooks.recurringTypes),l=s.recurringDef.duration;l||(l=s.allDay?n.defaultAllDayEventDuration:n.defaultTimedEventDuration);for(var c=0,d=u;c<d.length;c++){var f=d[c],p=Pn(a,{start:f,end:r.add(f,l)});o[p.instanceId]=p}}}return{defs:i,instances:o}}function dt(e,t){var n=e.instances[t];if(n){var r=e.defs[n.defId],i=yt(e,function(e){return ft(r,e)});return i.defs[r.defId]=r,i.instances[n.instanceId]=n,i}return vt()}function ft(e,t){return Boolean(e.groupId&&e.groupId===t.groupId)}function pt(e,t,n){var r=n.opt("eventDataTransform"),i=t?t.eventDataTransform:null;return i&&(e=ht(e,i)),r&&(e=ht(e,r)),e}function ht(e,t){var n;if(t){n=[];for(var r=0,i=e;r<i.length;r++){var o=i[r],a=t(o);a?n.push(a):null==a&&n.push(o)}}else n=e;return n}function vt(){return{defs:{},instances:{}}}function gt(e,t){return{defs:ki({},e.defs,t.defs),instances:ki({},e.instances,t.instances)}}function yt(e,t){var n=it(e.defs,t),r=it(e.instances,function(e){return n[e.defId]});return{defs:n,instances:r}}function mt(e,t){var n=null,r=null;return e.start&&(n=t.createMarker(e.start)),e.end&&(r=t.createMarker(e.end)),n||r?n&&r&&r<n?null:{start:n,end:r}:null}function Et(e,t){var n,r,i=[],o=t.start;for(e.sort(St),n=0;n<e.length;n++)r=e[n],r.start>o&&i.push({start:o,end:r.start}),r.end>o&&(o=r.end);return o<t.end&&i.push({start:o,end:t.end}),i}function St(e,t){return e.start.valueOf()-t.start.valueOf()}function Dt(e,t){var n=e.start,r=e.end,i=null;return null!==t.start&&(n=null===n?t.start:new Date(Math.max(n.valueOf(),t.start.valueOf()))),null!=t.end&&(r=null===r?t.end:new Date(Math.min(r.valueOf(),t.end.valueOf()))),(null===n||null===r||n<r)&&(i={start:n,end:r}),i}function bt(e,t){return(null===e.start?null:e.start.valueOf())===(null===t.start?null:t.start.valueOf())&&(null===e.end?null:e.end.valueOf())===(null===t.end?null:t.end.valueOf())}function Tt(e,t){return(null===e.end||null===t.start||e.end>t.start)&&(null===e.start||null===t.end||e.start<t.end)}function wt(e,t){return(null===e.start||null!==t.start&&t.start>=e.start)&&(null===e.end||null!==t.end&&t.end<=e.end)}function Rt(e,t){return(null===e.start||t>=e.start)&&(null===e.end||t<e.end)}function It(e,t){return null!=t.start&&e<t.start?t.start:null!=t.end&&e>=t.end?new Date(t.end.valueOf()-1):e}function Ct(e,t){for(var n=0,r=0;r<e.length;)e[r]===t?(e.splice(r,1),n++):r++;return n}function Mt(e,t){var n,r=e.length;if(r!==t.length)return!1;for(n=0;n<r;n++)if(e[n]!==t[n])return!1;return!0}function kt(e){var t,n;return function(){return t&&Mt(t,arguments)||(t=arguments,n=e.apply(this,arguments)),n}}function Ot(e,t){var n=null;return function(){var r=e.apply(this,arguments);return(null===n||n!==r&&!t(n,r))&&(n=r),n}}function _t(e,t,n){var r=Object.keys(e).length;return 1===r&&"short"===e.timeZoneName?function(e){return Wt(e.timeZoneOffset)}:0===r&&t.week?function(e){return zt(n.computeWeekNumber(e.marker),n.weekLabel,n.locale,t.week)}:Pt(e,t,n)}function Pt(e,t,n){e=ki({},e),t=ki({},t),Ht(e,t),e.timeZone="UTC";var r,i=new Intl.DateTimeFormat(n.locale.codes,e);if(t.omitZeroMinute){var o=ki({},e);delete o.minute,r=new Intl.DateTimeFormat(n.locale.codes,o)}return function(o){var a,s=o.marker;return a=r&&!s.getUTCMinutes()?r:i,xt(a.format(s),o,e,t,n)}}function Ht(e,t){e.timeZoneName&&(e.hour||(e.hour="2-digit"),e.minute||(e.minute="2-digit")),"long"===e.timeZoneName&&(e.timeZoneName="short"),t.omitZeroMinute&&(e.second||e.millisecond)&&delete t.omitZeroMinute}function xt(e,t,n,r,i){return e=e.replace(Ni,""),"short"===n.timeZoneName&&(e=Nt(e,"UTC"===i.timeZone||null==t.timeZoneOffset?"UTC":Wt(t.timeZoneOffset))),r.omitCommas&&(e=e.replace(Hi,"").trim()),r.omitZeroMinute&&(e=e.replace(":00","")),!1===r.meridiem?e=e.replace(Pi,"").trim():"narrow"===r.meridiem?e=e.replace(Pi,function(e,t){return t.toLocaleLowerCase()}):"short"===r.meridiem?e=e.replace(Pi,function(e,t){return t.toLocaleLowerCase()+"m"}):"lowercase"===r.meridiem&&(e=e.replace(Pi,function(e){return e.toLocaleLowerCase()})),e=e.replace(xi," "),e=e.trim()}function Nt(e,t){var n=!1;return e=e.replace(zi,function(){return n=!0,t}),n||(e+=" "+t),e}function zt(e,t,n,r){var i=[];return"narrow"===r?i.push(t):"short"===r&&i.push(t," "),i.push(n.simpleNumberFormat.format(e)),n.options.isRtl&&i.reverse(),i.join("")}function Ut(e,t,n){return n.getMarkerYear(e)!==n.getMarkerYear(t)?5:n.getMarkerMonth(e)!==n.getMarkerMonth(t)?4:n.getMarkerDay(e)!==n.getMarkerDay(t)?2:se(e)!==se(t)?1:0}function Lt(e,t){var n={};for(var r in e)r in _i&&!(_i[r]<=t)||(n[r]=e[r]);return n}function At(e,t,n,r){for(var i=0;i<e.length;){var o=e.indexOf(t,i);if(-1===o)break;var a=e.substr(0,o);i=o+t.length;for(var s=e.substr(i),u=0;u<n.length;){var l=n.indexOf(r,u);if(-1===l)break;var c=n.substr(0,l);u=l+r.length;var d=n.substr(u);if(a===c&&s===d)return{before:a,after:s}}}return null}function Vt(e,t){return"object"==typeof e&&e?("string"==typeof t&&(e=ki({separator:t},e)),new Ui(e)):"string"==typeof e?new Li(e,t):"function"==typeof e?new Ai(e):void 0}function Bt(e,t,n){void 0===n&&(n=!1);var r=e.toISOString();return r=r.replace(".000",""),n&&(r=r.replace("T00:00:00Z","")),r.length>10&&(null==t?r=r.replace("Z",""):0!==t&&(r=r.replace("Z",Wt(t,!0)))),r}function Ft(e){return Fe(e.getUTCHours(),2)+":"+Fe(e.getUTCMinutes(),2)+":"+Fe(e.getUTCSeconds(),2)}function Wt(e,t){void 0===t&&(t=!1);var n=e<0?"-":"+",r=Math.abs(e),i=Math.floor(r/60),o=Math.round(r%60);return t?n+Fe(i,2)+":"+Fe(o,2):"GMT"+n+i+(o?":"+Fe(o,2):"")}function Zt(e,t,n,r){var i=jt(e,n.calendarSystem);return{date:i,start:i,end:t?jt(t,n.calendarSystem):null,timeZone:n.timeZone,localeCodes:n.locale.codes,separator:r}}function jt(e,t){var n=t.markerToArray(e.marker);return{marker:e.marker,timeZoneOffset:e.timeZoneOffset,array:n,year:n[0],month:n[1],day:n[2],hour:n[3],minute:n[4],second:n[5],millisecond:n[6]}}function Yt(e,t,n,r){var i={},o={},a={},s=[],u=[],l=Kt(e.defs,t);for(var c in e.defs){var d=e.defs[c];"inverse-background"===d.rendering&&(d.groupId?(i[d.groupId]=[],a[d.groupId]||(a[d.groupId]=d)):o[c]=[])}for(var f in e.instances){var p=e.instances[f],d=e.defs[p.defId],h=l[d.defId],v=p.range,g=!d.allDay&&r?Ke(v,r):v,y=Dt(g,n);y&&("inverse-background"===d.rendering?d.groupId?i[d.groupId].push(y):o[p.defId].push(y):("background"===d.rendering?s:u).push({def:d,ui:h,instance:p,range:y,isStart:g.start&&g.start.valueOf()===y.start.valueOf(),isEnd:g.end&&g.end.valueOf()===y.end.valueOf()}))}for(var m in i)for(var E=i[m],S=Et(E,n),D=0,b=S;D<b.length;D++){var T=b[D],d=a[m],h=l[d.defId];s.push({def:d,ui:h,instance:null,range:T,isStart:!1,isEnd:!1})}for(var c in o)for(var E=o[c],S=Et(E,n),w=0,R=S;w<R.length;w++){var T=R[w];s.push({def:e.defs[c],ui:l[c],instance:null,range:T,isStart:!1,isEnd:!1})}return{bg:s,fg:u}}function qt(e){return"background"===e.rendering||"inverse-background"===e.rendering}function Gt(e,t,n){e.hasPublicHandlers("eventRender")&&(t=t.filter(function(t){var r=e.publiclyTrigger("eventRender",[{event:new Bi(e.calendar,t.eventRange.def,t.eventRange.instance),isMirror:n,isStart:t.isStart,isEnd:t.isEnd,el:t.el,view:e}]);return!1!==r&&(r&&!0!==r&&(t.el=r),!0)}));for(var r=0,i=t;r<i.length;r++){var o=i[r];Xt(o.el,o)}return t}function Xt(e,t){e.fcSeg=t}function Jt(e){return e.fcSeg||null}function Kt(e,t){return ot(e,function(e){return Qt(e,t)})}function Qt(e,t){var n=[];return t[""]&&n.push(t[""]),t[e.defId]&&n.push(t[e.defId]),n.push(e.ui),Mn(n)}function $t(e,t,n,r){var i=Kt(e.defs,t),o=vt();for(var a in e.defs){var s=e.defs[a];o.defs[a]=en(s,i[a],n,r.pluginSystem.hooks.eventDefMutationAppliers,r)}for(var u in e.instances){var l=e.instances[u],s=o.defs[l.defId];o.instances[u]=nn(l,s,i[l.defId],n,r)}return o}function en(e,t,n,r,i){var o=n.standardProps||{};null==o.hasEnd&&t.durationEditable&&tn(t.startEditable?n.startDelta:null,n.endDelta||null)&&(o.hasEnd=!0);var a=ki({},e,o,{ui:ki({},e.ui,o.ui)});n.extendedProps&&(a.extendedProps=ki({},a.extendedProps,n.extendedProps));for(var s=0,u=r;s<u.length;s++){(0,u[s])(a,n,i)}return!a.hasEnd&&i.opt("forceEventDuration")&&(a.hasEnd=!0),a}function tn(e,t){return e&&!be(e)&&(e=null),t&&!be(t)&&(t=null),!(!e&&!t)&&(Boolean(e)!==Boolean(t)||!fe(e,t))}function nn(e,t,n,r,i){var o=i.dateEnv,a=r.standardProps&&!0===r.standardProps.allDay,s=r.standardProps&&!1===r.standardProps.hasEnd,u=ki({},e);return a&&(u.range=Je(u.range)),r.startDelta&&n.startEditable&&(u.range={start:o.add(u.range.start,r.startDelta),end:u.range.end}),s?u.range={start:u.range.start,end:i.getDefaultEventEnd(t.allDay,u.range.start)}:!r.endDelta||!n.durationEditable&&tn(n.startEditable?r.startDelta:null,r.endDelta)||(u.range={start:u.range.start,end:o.add(u.range.end,r.endDelta)}),t.allDay&&(u.range={start:X(u.range.start),end:X(u.range.end)}),u.range.end<u.range.start&&(u.range.end=i.getDefaultEventEnd(t.allDay,u.range.start)),u}function rn(e,t,n,r,i){switch(t.type){case"RECEIVE_EVENTS":return on(e,n[t.sourceId],t.fetchId,t.fetchRange,t.rawEvents,i);case"ADD_EVENTS":return an(e,t.eventStore,r?r.activeRange:null,i);case"MERGE_EVENTS":return gt(e,t.eventStore);case"PREV":case"NEXT":case"SET_DATE":case"SET_VIEW_TYPE":return r?ct(e,r.activeRange,i):e;case"CHANGE_TIMEZONE":return sn(e,t.oldDateEnv,i.dateEnv);case"MUTATE_EVENTS":return un(e,t.instanceId,t.mutation,t.fromApi,i);case"REMOVE_EVENT_INSTANCES":return cn(e,t.instances);case"REMOVE_EVENT_DEF":return yt(e,function(e){return e.defId!==t.defId});case"REMOVE_EVENT_SOURCE":return ln(e,t.sourceId);case"REMOVE_ALL_EVENT_SOURCES":return yt(e,function(e){return!e.sourceId});case"REMOVE_ALL_EVENTS":return vt();case"RESET_EVENTS":return{defs:e.defs,instances:e.instances};default:return e}}function on(e,t,n,r,i,o){if(t&&n===t.latestFetchId){var a=ut(pt(i,t,o),t.sourceId,o);return r&&(a=ct(a,r,o)),gt(ln(e,t.sourceId),a)}return e}function an(e,t,n,r){return n&&(t=ct(t,n,r)),gt(e,t)}function sn(e,t,n){var r=e.defs,i=ot(e.instances,function(e){var i=r[e.defId];return i.allDay||i.recurringDef?e:ki({},e,{range:{start:n.createMarker(t.toDate(e.range.start,e.forcedStartTzo)),end:n.createMarker(t.toDate(e.range.end,e.forcedEndTzo))},forcedStartTzo:n.canComputeOffset?null:e.forcedStartTzo,forcedEndTzo:n.canComputeOffset?null:e.forcedEndTzo})});return{defs:r,instances:i}}function un(e,t,n,r,i){var o=dt(e,t);return o=$t(o,r?{"":{startEditable:!0,durationEditable:!0,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]}}:i.eventUiBases,n,i),gt(e,o)}function ln(e,t){return yt(e,function(e){return e.sourceId!==t})}function cn(e,t){return{defs:e.defs,instances:it(e.instances,function(e){return!t[e.instanceId]})}}function dn(e,t){return pn({eventDrag:e},t)}function fn(e,t){return pn({dateSelection:e},t)}function pn(e,t){var n=t.view,r=ki({businessHours:n?n.props.businessHours:vt(),dateSelection:"",eventStore:t.state.eventStore,eventUiBases:t.eventUiBases,eventSelection:"",eventDrag:null,eventResize:null},e);return(t.pluginSystem.hooks.isPropsValid||hn)(r,t)}function hn(e,t,n,r){return void 0===n&&(n={}),!(e.eventDrag&&!vn(e,t,n,r))&&!(e.dateSelection&&!gn(e,t,n,r))}function vn(e,t,n,r){var i=e.eventDrag,o=i.mutatedEvents,a=o.defs,s=o.instances,u=Kt(a,i.isEvent?e.eventUiBases:{"":t.selectionConfig});r&&(u=ot(u,r));var l=cn(e.eventStore,i.affectedEvents.instances),c=l.defs,d=l.instances,f=Kt(c,e.eventUiBases);for(var p in s){var h=s[p],v=h.range,g=u[h.defId],y=a[h.defId];if(!yn(g.constraints,v,l,e.businessHours,t))return!1;var m=t.opt("eventOverlap");"function"!=typeof m&&(m=null);for(var E in d){var S=d[E];if(Tt(v,S.range)){if(!1===f[S.defId].overlap&&i.isEvent)return!1;if(!1===g.overlap)return!1;if(m&&!m(new Bi(t,c[S.defId],S),new Bi(t,y,h)))return!1}}for(var D=0,b=g.allows;D<b.length;D++){var T=b[D],w=ki({},n,{range:h.range,allDay:y.allDay}),R=e.eventStore.defs[y.defId],I=e.eventStore.instances[p],C=void 0;if(C=R?new Bi(t,R,I):new Bi(t,y),!T(t.buildDateSpanApi(w),C))return!1}}return!0}function gn(e,t,n,r){var i=e.eventStore,o=i.defs,a=i.instances,s=e.dateSelection,u=s.range,l=t.selectionConfig;if(r&&(l=r(l)),!yn(l.constraints,u,i,e.businessHours,t))return!1;var c=t.opt("selectOverlap");"function"!=typeof c&&(c=null);for(var d in a){var f=a[d];if(Tt(u,f.range)){if(!1===l.overlap)return!1;if(c&&!c(new Bi(t,o[f.defId],f)))return!1}}for(var p=0,h=l.allows;p<h.length;p++){var v=h[p],g=ki({},n,s);if(!v(t.buildDateSpanApi(g),null))return!1}return!0}function yn(e,t,n,r,i){for(var o=0,a=e;o<a.length;o++){if(!Sn(mn(a[o],t,n,r,i),t))return!1}return!0}function mn(e,t,n,r,i){return"businessHours"===e?En(ct(r,t,i)):"string"==typeof e?En(yt(n,function(t){return t.groupId===e})):"object"==typeof e&&e?En(ct(e,t,i)):[]}function En(e){var t=e.instances,n=[];for(var r in t)n.push(t[r].range);return n}function Sn(e,t){for(var n=0,r=e;n<r.length;n++){if(wt(r[n],t))return!0}return!1}function Dn(e,t){return Array.isArray(e)?ut(e,"",t,!0):"object"==typeof e&&e?ut([e],"",t,!0):null!=e?String(e):null}function bn(e){return(e+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#039;").replace(/"/g,"&quot;").replace(/\n/g,"<br />")}function Tn(e){var t=[];for(var n in e){var r=e[n];null!=r&&""!==r&&t.push(n+":"+r)}return t.join(";")}function wn(e){var t=[];for(var n in e){var r=e[n];null!=r&&t.push(n+'="'+bn(r)+'"')}return t.join(" ")}function Rn(e){return Array.isArray(e)?e:"string"==typeof e?e.split(/\s+/):[]}function In(e,t,n){var r=Ge(e,Fi,{},n),i=Dn(r.constraint,t);return{startEditable:null!=r.startEditable?r.startEditable:r.editable,durationEditable:null!=r.durationEditable?r.durationEditable:r.editable,constraints:null!=i?[i]:[],overlap:r.overlap,allows:null!=r.allow?[r.allow]:[],backgroundColor:r.backgroundColor||r.color,borderColor:r.borderColor||r.color,textColor:r.textColor,classNames:r.classNames.concat(r.className)}}function Cn(e,t,n,r){var i={},o={};for(var a in Fi){var s=e+Be(a);i[a]=t[s],o[s]=!0}if("event"===e&&(i.editable=t.editable),r)for(var a in t)o[a]||(r[a]=t[a]);return In(i,n)}function Mn(e){return e.reduce(kn,Wi)}function kn(e,t){return{startEditable:null!=t.startEditable?t.startEditable:e.startEditable,durationEditable:null!=t.durationEditable?t.durationEditable:e.durationEditable,constraints:e.constraints.concat(t.constraints),overlap:"boolean"==typeof t.overlap?t.overlap:e.overlap,allows:e.allows.concat(t.allows),backgroundColor:t.backgroundColor||e.backgroundColor,borderColor:t.borderColor||e.borderColor,textColor:t.textColor||e.textColor,classNames:e.classNames.concat(t.classNames)}}function On(e,t,n,r){var i=zn(t,n),o={},a=tt(e,i,n.dateEnv,n.pluginSystem.hooks.recurringTypes,o);if(a){var s=_n(o,t,a.allDay,Boolean(a.duration),n);return s.recurringDef={typeId:a.typeId,typeData:a.typeData,duration:a.duration},{def:s,instance:null}}var u={},l=Hn(e,i,n,u,r);if(l){var s=_n(u,t,l.allDay,l.hasEnd,n);return{def:s,instance:Pn(s.defId,l.range,l.forcedStartTzo,l.forcedEndTzo)}}return null}function _n(e,t,n,r,i){var o={},a=Nn(e,i,o);a.defId=String(Yi++),a.sourceId=t,a.allDay=n,a.hasEnd=r;for(var s=0,u=i.pluginSystem.hooks.eventDefParsers;s<u.length;s++){var l=u[s],c={};l(a,o,c),o=c}return a.extendedProps=ki(o,a.extendedProps||{}),Object.freeze(a.ui.classNames),Object.freeze(a.extendedProps),a}function Pn(e,t,n,r){return{instanceId:String(Yi++),defId:e,range:t,forcedStartTzo:null==n?null:n,forcedEndTzo:null==r?null:r}}function Hn(e,t,n,r,i){var o,a,s=xn(e,r),u=s.allDay,l=null,c=!1,d=null;if(o=n.dateEnv.createMarkerMeta(s.start))l=o.marker;else if(!i)return null;return null!=s.end&&(a=n.dateEnv.createMarkerMeta(s.end)),null==u&&(u=null!=t?t:(!o||o.isTimeUnspecified)&&(!a||a.isTimeUnspecified)),u&&l&&(l=X(l)),a&&(d=a.marker,u&&(d=X(d)),l&&d<=l&&(d=null)),d?c=!0:i||(c=n.opt("forceEventDuration")||!1,d=n.dateEnv.add(l,u?n.defaultAllDayEventDuration:n.defaultTimedEventDuration)),{allDay:u,hasEnd:c,range:{start:l,end:d},forcedStartTzo:o?o.forcedTzo:null,forcedEndTzo:a?a.forcedTzo:null}}function xn(e,t){var n=Ge(e,ji,{},t);return n.start=null!==n.start?n.start:n.date,delete n.date,n}function Nn(e,t,n){var r={},i=Ge(e,Zi,{},r),o=In(r,t,n);return i.publicId=i.id,delete i.id,i.ui=o,i}function zn(e,t){var n=null;if(e){n=t.state.eventSources[e].allDayDefault}return null==n&&(n=t.opt("allDayDefault")),n}function Un(e,t){return ut(Ln(e),"",t)}function Ln(e){var t;return t=!0===e?[{}]:Array.isArray(e)?e.filter(function(e){return e.daysOfWeek}):"object"==typeof e&&e?[e]:[],t=t.map(function(e){return ki({},qi,e)})}function An(e,t,n){function r(){if(a){for(var e=0,n=s;e<n.length;e++){n[e].unrender()}t&&t.apply(o,a),a=null}}function i(){a&&Mt(a,arguments)||(r(),o=this,a=arguments,e.apply(this,arguments))}void 0===n&&(n=[]);var o,a,s=[];i.dependents=s,i.unrender=r;for(var u=0,l=n;u<l.length;u++){l[u].dependents.push(i)}return i}function Vn(e,t,n){return void 0===n&&(n=1),e===t||(Array.isArray(e)&&Array.isArray(t)?Bn(e,t,n):!("object"!=typeof e||!e||"object"!=typeof t||!t)&&Fn(e,t,n))}function Bn(e,t,n){if(void 0===n&&(n=1),e===t)return!0;if(n>0){if(e.length!==t.length)return!1;for(var r=0;r<e.length;r++)if(!Vn(e[r],t[r],n-1))return!1;return!0}return!1}function Fn(e,t,n){if(void 0===n&&(n=1),e===t)return!0;if(n>0){for(var r in e)if(!(r in t))return!1;for(var r in t){if(!(r in e))return!1;if(!Vn(e[r],t[r],n-1))return!1}return!0}return!1}function Wn(e,t,n){void 0===n&&(n=1);var r={};for(var i in t)i in e&&Vn(e[i],t[i],n-1)||(r[i]=t[i]);return r}function Zn(e,t){for(var n in e)if(!(n in t))return!0;return!1}function jn(e,t,n){var r=[];e&&r.push(e),t&&r.push(t);var i={"":Mn(r)};return n&&ki(i,n),i}function Yn(e,t,n,r){var i,o,a,s,u=e.dateEnv;return t instanceof Date?i=t:(i=t.date,o=t.type,a=t.forceOff),s={date:u.formatIso(i,{omitTime:!0}),type:o||"day"},"string"==typeof n&&(r=n,n=null),n=n?" "+wn(n):"",r=r||"",!a&&e.opt("navLinks")?"<a"+n+' data-goto="'+bn(JSON.stringify(s))+'">'+r+"</a>":"<span"+n+">"+r+"</span>"}function qn(e){return e.opt("allDayHtml")||bn(e.opt("allDayText"))}
+function Gn(e,t,n,r){var i,o,a=n.calendar,s=n.view,u=n.theme,l=n.dateEnv,c=[];return Rt(t.activeRange,e)?(c.push("fc-"+Ri[e.getUTCDay()]),s.opt("monthMode")&&l.getMonth(e)!==l.getMonth(t.currentRange.start)&&c.push("fc-other-month"),i=X(a.getNow()),o=A(i,1),e<i?c.push("fc-past"):e>=o?c.push("fc-future"):(c.push("fc-today"),!0!==r&&c.push(u.getClass("today")))):c.push("fc-disabled-day"),c}function Xn(e,t,n){var r=!1,i=function(){r||(r=!0,t.apply(this,arguments))},o=function(){r||(r=!0,n&&n.apply(this,arguments))},a=e(i,o);a&&"function"==typeof a.then&&a.then(i,o)}function Jn(e,t,n){(e[t]||(e[t]=[])).push(n)}function Kn(e,t,n){n?e[t]&&(e[t]=e[t].filter(function(e){return e!==n})):delete e[t]}function Qn(e,t,n){var r={},i=!1;for(var o in t)o in e&&(e[o]===t[o]||n[o]&&n[o](e[o],t[o]))?r[o]=e[o]:(r[o]=t[o],i=!0);for(var o in e)if(!(o in t)){i=!0;break}return{anyChanges:i,comboProps:r}}function $n(e){return{id:String(so++),deps:e.deps||[],reducers:e.reducers||[],eventDefParsers:e.eventDefParsers||[],eventDragMutationMassagers:e.eventDragMutationMassagers||[],eventDefMutationAppliers:e.eventDefMutationAppliers||[],dateSelectionTransformers:e.dateSelectionTransformers||[],datePointTransforms:e.datePointTransforms||[],dateSpanTransforms:e.dateSpanTransforms||[],views:e.views||{},viewPropsTransformers:e.viewPropsTransformers||[],isPropsValid:e.isPropsValid||null,externalDefTransforms:e.externalDefTransforms||[],eventResizeJoinTransforms:e.eventResizeJoinTransforms||[],viewContainerModifiers:e.viewContainerModifiers||[],eventDropTransformers:e.eventDropTransformers||[],componentInteractions:e.componentInteractions||[],calendarInteractions:e.calendarInteractions||[],themeClasses:e.themeClasses||{},eventSourceDefs:e.eventSourceDefs||[],cmdFormatter:e.cmdFormatter,recurringTypes:e.recurringTypes||[],namedTimeZonedImpl:e.namedTimeZonedImpl,defaultView:e.defaultView||"",elementDraggingImpl:e.elementDraggingImpl,optionChangeHandlers:e.optionChangeHandlers||{}}}function er(e,t){return{reducers:e.reducers.concat(t.reducers),eventDefParsers:e.eventDefParsers.concat(t.eventDefParsers),eventDragMutationMassagers:e.eventDragMutationMassagers.concat(t.eventDragMutationMassagers),eventDefMutationAppliers:e.eventDefMutationAppliers.concat(t.eventDefMutationAppliers),dateSelectionTransformers:e.dateSelectionTransformers.concat(t.dateSelectionTransformers),datePointTransforms:e.datePointTransforms.concat(t.datePointTransforms),dateSpanTransforms:e.dateSpanTransforms.concat(t.dateSpanTransforms),views:ki({},e.views,t.views),viewPropsTransformers:e.viewPropsTransformers.concat(t.viewPropsTransformers),isPropsValid:t.isPropsValid||e.isPropsValid,externalDefTransforms:e.externalDefTransforms.concat(t.externalDefTransforms),eventResizeJoinTransforms:e.eventResizeJoinTransforms.concat(t.eventResizeJoinTransforms),viewContainerModifiers:e.viewContainerModifiers.concat(t.viewContainerModifiers),eventDropTransformers:e.eventDropTransformers.concat(t.eventDropTransformers),calendarInteractions:e.calendarInteractions.concat(t.calendarInteractions),componentInteractions:e.componentInteractions.concat(t.componentInteractions),themeClasses:ki({},e.themeClasses,t.themeClasses),eventSourceDefs:e.eventSourceDefs.concat(t.eventSourceDefs),cmdFormatter:t.cmdFormatter||e.cmdFormatter,recurringTypes:e.recurringTypes.concat(t.recurringTypes),namedTimeZonedImpl:t.namedTimeZonedImpl||e.namedTimeZonedImpl,defaultView:e.defaultView||t.defaultView,elementDraggingImpl:e.elementDraggingImpl||t.elementDraggingImpl,optionChangeHandlers:ki({},e.optionChangeHandlers,t.optionChangeHandlers)}}function tr(e,t,n,r,i){e=e.toUpperCase();var o=null;"GET"===e?t=nr(t,n):o=rr(n);var a=new XMLHttpRequest;a.open(e,t,!0),"GET"!==e&&a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.onload=function(){if(a.status>=200&&a.status<400)try{var e=JSON.parse(a.responseText);r(e,a)}catch(e){i("Failure parsing JSON",a)}else i("Request failed",a)},a.onerror=function(){i("Request failed",a)},a.send(o)}function nr(e,t){return e+(-1===e.indexOf("?")?"?":"&")+rr(t)}function rr(e){var t=[];for(var n in e)t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&")}function ir(e,t,n){var r,i,o,a,s=n.dateEnv,u={};return r=e.startParam,null==r&&(r=n.opt("startParam")),i=e.endParam,null==i&&(i=n.opt("endParam")),o=e.timeZoneParam,null==o&&(o=n.opt("timeZoneParam")),a="function"==typeof e.extraParams?e.extraParams():e.extraParams||{},ki(u,a),u[r]=s.formatIso(t.start),u[i]=s.formatIso(t.end),"local"!==s.timeZone&&(u[o]=s.timeZone),u}function or(e,t,n,r){for(var i=e?at(e):null,o=X(n.start),a=n.end,s=[];o<a;){var u=void 0;i&&!i[o.getUTCDay()]||(u=t?r.add(o,t):o,s.push(u)),o=A(o,1)}return s}function ar(e,t){for(var n=st(t.state.eventSources),r=[],i=0,o=e;i<o.length;i++){for(var a=o[i],s=!1,u=0;u<n.length;u++)if(Vn(n[u]._raw,a,2)){n.splice(u,1),s=!0;break}s||r.push(a)}for(var l=0,c=n;l<c.length;l++){var d=c[l];t.dispatch({type:"REMOVE_EVENT_SOURCE",sourceId:d.sourceId})}for(var f=0,p=r;f<p.length;f++){var h=p[f];t.addEventSource(h)}}function sr(e,t){t.addPluginInputs(e)}function ur(e){return rt(e,bo)}function lr(e){for(var t=[],n=0,r=e;n<r.length;n++){var i=r[n];if("string"==typeof i){var o="FullCalendar"+Be(i);window[o]?t.push(window[o].default):console.warn("Plugin file not loaded for "+i)}else t.push(i)}return To.concat(t)}function cr(e){for(var t=e.length>0?e[0].code:"en",n=window.FullCalendarLocalesAll||[],r=window.FullCalendarLocales||{},i=n.concat(st(r),e),o={en:wo},a=0,s=i;a<s.length;a++){var u=s[a];o[u.code]=u}return{map:o,defaultCode:t}}function dr(e,t){return"object"!=typeof e||Array.isArray(e)?fr(e,t):hr(e.code,[e.code],e)}function fr(e,t){var n=[].concat(e||[]);return hr(e,n,pr(n,t)||wo)}function pr(e,t){for(var n=0;n<e.length;n++)for(var r=e[n].toLocaleLowerCase().split("-"),i=r.length;i>0;i--){var o=r.slice(0,i).join("-");if(t[o])return t[o]}return null}function hr(e,t,n){var r=rt([wo,n],["buttonText"]);delete r.code;var i=r.week;return delete r.week,{codeArg:e,codes:t,week:i,simpleNumberFormat:new Intl.NumberFormat(e),options:r}}function vr(e){return new Io[e]}function gr(e){var t=null,n=!1,r=Mo.exec(e);r&&(n=!r[1],n?e+="T00:00:00Z":e=e.replace(ko,function(e,n,r,i,o){return t=n?0:(60*parseInt(i,10)+parseInt(o||0,10))*("-"===r?-1:1),""})+"Z");var i=new Date(e);return ae(i)?{marker:i,isTimeUnspecified:n,timeZoneOffset:t}:null}function yr(e,t){return!t.pluginSystem.hooks.eventSourceDefs[e.sourceDefId].ignoreRange}function mr(e,t){for(var n=t.pluginSystem.hooks.eventSourceDefs,r=n.length-1;r>=0;r--){var i=n[r],o=i.parseMeta(e);if(o){var a=Er("object"==typeof e?e:{},o,r,t);return a._raw=Xe(e),a}}return null}function Er(e,t,n,r){var i={},o=Ge(e,_o,{},i),a={},s=In(i,r,a);return o.isFetching=!1,o.latestFetchId="",o.fetchRange=null,o.publicId=String(e.id||""),o.sourceId=String(Po++),o.sourceDefId=n,o.meta=t,o.ui=s,o.extendedProps=a,o}function Sr(e,t,n,r){switch(t.type){case"ADD_EVENT_SOURCES":return Dr(e,t.sources,n?n.activeRange:null,r);case"REMOVE_EVENT_SOURCE":return br(e,t.sourceId);case"PREV":case"NEXT":case"SET_DATE":case"SET_VIEW_TYPE":return n?Tr(e,n.activeRange,r):e;case"FETCH_EVENT_SOURCES":case"CHANGE_TIMEZONE":return Rr(e,t.sourceIds?at(t.sourceIds):Mr(e,r),n?n.activeRange:null,r);case"RECEIVE_EVENTS":case"RECEIVE_EVENT_ERROR":return Cr(e,t.sourceId,t.fetchId,t.fetchRange);case"REMOVE_ALL_EVENT_SOURCES":return{};default:return e}}function Dr(e,t,n,r){for(var i={},o=0,a=t;o<a.length;o++){var s=a[o];i[s.sourceId]=s}return n&&(i=Tr(i,n,r)),ki({},e,i)}function br(e,t){return it(e,function(e){return e.sourceId!==t})}function Tr(e,t,n){return Rr(e,it(e,function(e){return wr(e,t,n)}),t,n)}function wr(e,t,n){return yr(e,n)?!n.opt("lazyFetching")||!e.fetchRange||t.start<e.fetchRange.start||t.end>e.fetchRange.end:!e.latestFetchId}function Rr(e,t,n,r){var i={};for(var o in e){var a=e[o];t[o]?i[o]=Ir(a,n,r):i[o]=a}return i}function Ir(e,t,n){var r=n.pluginSystem.hooks.eventSourceDefs[e.sourceDefId],i=String(Ho++);return r.fetch({eventSource:e,calendar:n,range:t},function(r){var o,a,s=r.rawEvents,u=n.opt("eventSourceSuccess");e.success&&(a=e.success(s,r.xhr)),u&&(o=u(s,r.xhr)),s=a||o||s,n.dispatch({type:"RECEIVE_EVENTS",sourceId:e.sourceId,fetchId:i,fetchRange:t,rawEvents:s})},function(r){var o=n.opt("eventSourceFailure");console.warn(r.message,r),e.failure&&e.failure(r),o&&o(r),n.dispatch({type:"RECEIVE_EVENT_ERROR",sourceId:e.sourceId,fetchId:i,fetchRange:t,error:r})}),ki({},e,{isFetching:!0,latestFetchId:i})}function Cr(e,t,n,r){var i,o=e[t];return o&&n===o.latestFetchId?ki({},e,(i={},i[t]=ki({},o,{isFetching:!1,fetchRange:r}),i)):e}function Mr(e,t){return it(e,function(e){return yr(e,t)})}function kr(e,t){return bt(e.activeRange,t.activeRange)&&bt(e.validRange,t.validRange)&&fe(e.minTime,t.minTime)&&fe(e.maxTime,t.maxTime)}function Or(e,t,n){for(var r=_r(e.viewType,t),i=Pr(e.dateProfile,t,e.currentDate,r,n),o=Sr(e.eventSources,t,i,n),a=ki({},e,{viewType:r,dateProfile:i,currentDate:Hr(e.currentDate,t,i),eventSources:o,eventStore:rn(e.eventStore,t,o,i,n),dateSelection:xr(e.dateSelection,t,n),eventSelection:Nr(e.eventSelection,t),eventDrag:zr(e.eventDrag,t,o,n),eventResize:Ur(e.eventResize,t,o,n),eventSourceLoadingLevel:Lr(o),loadingLevel:Lr(o)}),s=0,u=n.pluginSystem.hooks.reducers;s<u.length;s++){a=(0,u[s])(a,t,n)}return a}function _r(e,t){switch(t.type){case"SET_VIEW_TYPE":return t.viewType;default:return e}}function Pr(e,t,n,r,i){var o;switch(t.type){case"PREV":o=i.dateProfileGenerators[r].buildPrev(e,n);break;case"NEXT":o=i.dateProfileGenerators[r].buildNext(e,n);break;case"SET_DATE":e.activeRange&&Rt(e.currentRange,t.dateMarker)||(o=i.dateProfileGenerators[r].build(t.dateMarker,void 0,!0));break;case"SET_VIEW_TYPE":var a=i.dateProfileGenerators[r];if(!a)throw new Error(r?'The FullCalendar view "'+r+'" does not exist. Make sure your plugins are loaded correctly.':"No available FullCalendar view plugins.");o=a.build(t.dateMarker||n,void 0,!0)}return!o||!o.isValid||e&&kr(e,o)?e:o}function Hr(e,t,n){switch(t.type){case"PREV":case"NEXT":return Rt(n.currentRange,e)?e:n.currentRange.start;case"SET_DATE":case"SET_VIEW_TYPE":var r=t.dateMarker||e;return n.activeRange&&!Rt(n.activeRange,r)?n.currentRange.start:r;default:return e}}function xr(e,t,n){switch(t.type){case"SELECT_DATES":return t.selection;case"UNSELECT_DATES":return null;default:return e}}function Nr(e,t){switch(t.type){case"SELECT_EVENT":return t.eventInstanceId;case"UNSELECT_EVENT":return"";default:return e}}function zr(e,t,n,r){switch(t.type){case"SET_EVENT_DRAG":var i=t.state;return{affectedEvents:i.affectedEvents,mutatedEvents:i.mutatedEvents,isEvent:i.isEvent,origSeg:i.origSeg};case"UNSET_EVENT_DRAG":return null;default:return e}}function Ur(e,t,n,r){switch(t.type){case"SET_EVENT_RESIZE":var i=t.state;return{affectedEvents:i.affectedEvents,mutatedEvents:i.mutatedEvents,isEvent:i.isEvent,origSeg:i.origSeg};case"UNSET_EVENT_RESIZE":return null;default:return e}}function Lr(e){var t=0;for(var n in e)e[n].isFetching&&t++;return t}function Ar(e,t,n){var r=Vr(e,t),i=r.range;if(!i.start)return null;if(!i.end){if(null==n)return null;i.end=t.add(i.start,n)}return r}function Vr(e,t){var n={},r=Ge(e,No,{},n),i=r.start?t.createMarkerMeta(r.start):null,o=r.end?t.createMarkerMeta(r.end):null,a=r.allDay;return null==a&&(a=i&&i.isTimeUnspecified&&(!o||o.isTimeUnspecified)),n.range={start:i?i.marker:null,end:o?o.marker:null},n.allDay=a,n}function Br(e,t){return bt(e.range,t.range)&&e.allDay===t.allDay&&Fr(e,t)}function Fr(e,t){for(var n in t)if("range"!==n&&"allDay"!==n&&e[n]!==t[n])return!1;for(var n in e)if(!(n in t))return!1;return!0}function Wr(e,t){return{start:t.toDate(e.range.start),end:t.toDate(e.range.end),startStr:t.formatIso(e.range.start,{omitTime:e.allDay}),endStr:t.formatIso(e.range.end,{omitTime:e.allDay}),allDay:e.allDay}}function Zr(e,t){return{date:t.toDate(e.range.start),dateStr:t.formatIso(e.range.start,{omitTime:e.allDay}),allDay:e.allDay}}function jr(e,t,n){var r=_n({editable:!1},"",e.allDay,!0,n);return{def:r,ui:Qt(r,t),instance:Pn(r.defId,e.range),range:e.range,isStart:!0,isEnd:!0}}function Yr(e,t){var n,r={};for(n in e)qr(n,r,e,t);for(n in t)qr(n,r,e,t);return r}function qr(e,t,n,r){if(t[e])return t[e];var i=Gr(e,t,n,r);return i&&(t[e]=i),i}function Gr(e,t,n,r){var i=n[e],o=r[e],a=function(e){return i&&null!==i[e]?i[e]:o&&null!==o[e]?o[e]:null},s=a("class"),u=a("superType");!u&&s&&(u=Xr(s,r)||Xr(s,n));var l=u?qr(u,t,n,r):null;return!s&&l&&(s=l.class),s?{type:e,class:s,defaults:ki({},l?l.defaults:{},i?i.options:{}),overrides:ki({},l?l.overrides:{},o?o.options:{})}:null}function Xr(e,t){var n=Object.getPrototypeOf(e.prototype);for(var r in t){var i=t[r];if(i.class&&i.class.prototype===n)return r}return""}function Jr(e){return ot(e,Kr)}function Kr(e){"function"==typeof e&&(e={class:e});var t={},n=Ge(e,zo,{},t);return{superType:n.type,class:n.class,options:t}}function Qr(e,t){var n=Jr(e),r=Jr(t.overrides.views);return ot(Yr(n,r),function(e){return $r(e,r,t)})}function $r(e,t,n){var r=e.overrides.duration||e.defaults.duration||n.dynamicOverrides.duration||n.overrides.duration,i=null,o="",a="",s={};if(r&&(i=ue(r))){var u=we(i,!de(r));o=u.unit,1===u.value&&(a=o,s=t[o]?t[o].options:{})}var l=function(t){var n=t.buttonText||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[a]?n[a]:void 0};return{type:e.type,class:e.class,duration:i,durationUnit:o,singleUnit:a,options:ki({},So,e.defaults,n.dirDefaults,n.localeDefaults,n.overrides,s,e.overrides,n.dynamicOverrides),buttonTextOverride:l(n.dynamicOverrides)||l(n.overrides)||e.overrides.buttonText,buttonTextDefault:l(n.localeDefaults)||l(n.dirDefaults)||e.defaults.buttonText||l(So)||e.type}}function ei(e,t){var n;return n=/^(year|month)$/.test(e.currentRangeUnit)?e.currentRange:e.activeRange,this.dateEnv.formatRange(n.start,n.end,Vt(t.titleFormat||ti(e),t.titleRangeSeparator),{isEndExclusive:e.isRangeAllDay})}function ti(e){var t=e.currentRangeUnit;if("year"===t)return{year:"numeric"};if("month"===t)return{year:"numeric",month:"long"};var n=G(e.currentRange.start,e.currentRange.end);return null!==n&&n>1?{year:"numeric",month:"short",day:"numeric"}:{year:"numeric",month:"long",day:"numeric"}}function ni(e){return e.map(function(e){return new e})}function ri(e,t){return{component:e,el:t.el,useEventCenter:null==t.useEventCenter||t.useEventCenter}}function ii(e){var t;return t={},t[e.component.uid]=e,t}function oi(e,t,n,r,i,o,a){return new Oo({calendarSystem:"gregory",timeZone:t,namedTimeZoneImpl:n,locale:e,weekNumberCalculation:i,firstDay:r,weekLabel:o,cmdFormatter:a})}function ai(e){return new(this.pluginSystem.hooks.themeClasses[e.themeSystem]||Wo)(e)}function si(e){var t=this.tryRerender.bind(this);return null!=e&&(t=qe(t,e)),t}function ui(e){return ot(e,function(e){return e.ui})}function li(e,t,n){var r={"":t};for(var i in e){var o=e[i];o.sourceId&&n[o.sourceId]&&(r[i]=n[o.sourceId])}return r}function ci(e){var t=e.eventRange.def,n=e.eventRange.instance.range,r=n.start?n.start.valueOf():0,i=n.end?n.end.valueOf():0;return ki({},t.extendedProps,t,{id:t.publicId,start:r,end:i,duration:i-r,allDay:Number(t.allDay),_seg:e})}function di(e,t){void 0===t&&(t={});var n=pi(t),r=Vt(t),i=n.createMarkerMeta(e);return i?n.format(i.marker,r,{forcedTzo:i.forcedTzo}):""}function fi(e,t,n){var r=pi("object"==typeof n&&n?n:{}),i=Vt(n,So.defaultRangeSeparator),o=r.createMarkerMeta(e),a=r.createMarkerMeta(t);return o&&a?r.formatRange(o.marker,a.marker,i,{forcedStartTzo:o.forcedTzo,forcedEndTzo:a.forcedTzo,isEndExclusive:n.isEndExclusive}):""}function pi(e){var t=dr(e.locale||"en",cr([]).map);return e=ki({timeZone:So.timeZone,calendarSystem:"gregory"},e,{locale:t}),new Oo(e)}function hi(e){var t={},n=Ge(e,Jo,Ko,t);return n.leftoverProps=t,n}function vi(e,t){return!e||t>10?{weekday:"short"}:t>1?{weekday:"short",month:"numeric",day:"numeric",omitCommas:!0}:{weekday:"long"}}function gi(e,t,n,r,i,o,a,s){var u,l=o.view,c=o.dateEnv,d=o.theme,f=o.options,p=Rt(t.activeRange,e),h=["fc-day-header",d.getClass("widgetHeader")];return u="function"==typeof f.columnHeaderHtml?f.columnHeaderHtml(c.toDate(e)):bn("function"==typeof f.columnHeaderText?f.columnHeaderText(c.toDate(e)):c.format(e,i)),n?h=h.concat(Gn(e,t,o,!0)):h.push("fc-"+Ri[e.getUTCDay()]),'<th class="'+h.join(" ")+'"'+(p&&n?' data-date="'+c.formatIso(e,{omitTime:!0})+'"':"")+(a>1?' colspan="'+a+'"':"")+(s?" "+s:"")+">"+(p?Yn(l,{date:e,forceOff:!n||1===r},u):u)+"</th>"}function yi(e,t){var n=e.activeRange;return t?n:{start:V(n.start,e.minTime.milliseconds),end:V(n.end,e.maxTime.milliseconds-864e5)}}var mi={className:!0,colSpan:!0,rowSpan:!0},Ei={"<tr":"tbody","<td":"tr"},Si=Element.prototype.matches||Element.prototype.matchesSelector||Element.prototype.msMatchesSelector,Di=Element.prototype.closest||function(e){var t=this;if(!document.documentElement.contains(t))return null;do{if(f(t,e))return t;t=t.parentElement||t.parentNode}while(null!==t&&1===t.nodeType);return null},bi=/(top|left|right|bottom|width|height)$/i,Ti=null,wi=["webkitTransitionEnd","otransitionend","oTransitionEnd","msTransitionEnd","transitionend"],Ri=["sun","mon","tue","wed","thu","fri","sat"],Ii=["years","months","days","milliseconds"],Ci=/^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/,Mi=function(e,t){return(Mi=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},ki=function(){return ki=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++){t=arguments[n];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e},ki.apply(this,arguments)},Oi={week:3,separator:0,omitZeroMinute:0,meridiem:0,omitCommas:0},_i={timeZoneName:7,era:6,year:5,month:4,day:2,weekday:2,hour:1,minute:1,second:1},Pi=/\s*([ap])\.?m\.?/i,Hi=/,/g,xi=/\s+/g,Ni=/\u200e/g,zi=/UTC|GMT/,Ui=function(){function e(e){var t={},n={},r=0;for(var i in e)i in Oi?(n[i]=e[i],r=Math.max(Oi[i],r)):(t[i]=e[i],i in _i&&(r=Math.max(_i[i],r)));this.standardDateProps=t,this.extendedSettings=n,this.severity=r,this.buildFormattingFunc=kt(_t)}return e.prototype.format=function(e,t){return this.buildFormattingFunc(this.standardDateProps,this.extendedSettings,t)(e)},e.prototype.formatRange=function(e,t,n){var r=this,i=r.standardDateProps,o=r.extendedSettings,a=Ut(e.marker,t.marker,n.calendarSystem);if(!a)return this.format(e,n);var s=a;!(s>1)||"numeric"!==i.year&&"2-digit"!==i.year||"numeric"!==i.month&&"2-digit"!==i.month||"numeric"!==i.day&&"2-digit"!==i.day||(s=1);var u=this.format(e,n),l=this.format(t,n);if(u===l)return u;var c=Lt(i,s),d=_t(c,o,n),f=d(e),p=d(t),h=At(u,f,l,p),v=o.separator||"";return h?h.before+f+v+p+h.after:u+v+l},e.prototype.getLargestUnit=function(){switch(this.severity){case 7:case 6:case 5:return"year";case 4:return"month";case 3:return"week";default:return"day"}},e}(),Li=function(){function e(e,t){this.cmdStr=e,this.separator=t}return e.prototype.format=function(e,t){return t.cmdFormatter(this.cmdStr,Zt(e,null,t,this.separator))},e.prototype.formatRange=function(e,t,n){return n.cmdFormatter(this.cmdStr,Zt(e,t,n,this.separator))},e}(),Ai=function(){function e(e){this.func=e}return e.prototype.format=function(e,t){return this.func(Zt(e,null,t))},e.prototype.formatRange=function(e,t,n){return this.func(Zt(e,t,n))},e}(),Vi=function(){function e(e,t){this.calendar=e,this.internalEventSource=t}return e.prototype.remove=function(){this.calendar.dispatch({type:"REMOVE_EVENT_SOURCE",sourceId:this.internalEventSource.sourceId})},e.prototype.refetch=function(){this.calendar.dispatch({type:"FETCH_EVENT_SOURCES",sourceIds:[this.internalEventSource.sourceId]})},Object.defineProperty(e.prototype,"id",{get:function(){return this.internalEventSource.publicId},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"url",{get:function(){return this.internalEventSource.meta.url},enumerable:!0,configurable:!0}),e}(),Bi=function(){function e(e,t,n){this._calendar=e,this._def=t,this._instance=n||null}return e.prototype.setProp=function(e,t){var n,r;if(e in ji);else if(e in Zi)"function"==typeof Zi[e]&&(t=Zi[e](t)),this.mutate({standardProps:(n={},n[e]=t,n)});else if(e in Fi){var i=void 0;"function"==typeof Fi[e]&&(t=Fi[e](t)),"color"===e?i={backgroundColor:t,borderColor:t}:"editable"===e?i={startEditable:t,durationEditable:t}:(r={},r[e]=t,i=r),this.mutate({standardProps:{ui:i}})}},e.prototype.setExtendedProp=function(e,t){var n;this.mutate({extendedProps:(n={},n[e]=t,n)})},e.prototype.setStart=function(e,t){void 0===t&&(t={});var n=this._calendar.dateEnv,r=n.createMarker(e);if(r&&this._instance){var i=this._instance.range,o=$e(i.start,r,n,t.granularity),a=null;if(t.maintainDuration){a=ve($e(i.start,i.end,n,t.granularity),$e(r,i.end,n,t.granularity))}this.mutate({startDelta:o,endDelta:a})}},e.prototype.setEnd=function(e,t){void 0===t&&(t={});var n,r=this._calendar.dateEnv;if((null==e||(n=r.createMarker(e)))&&this._instance)if(n){var i=$e(this._instance.range.end,n,r,t.granularity);this.mutate({endDelta:i})}else this.mutate({standardProps:{hasEnd:!1}})},e.prototype.setDates=function(e,t,n){void 0===n&&(n={});var r,i=this._calendar.dateEnv,o={allDay:n.allDay},a=i.createMarker(e);if(a&&(null==t||(r=i.createMarker(t)))&&this._instance){var s=this._instance.range;!0===n.allDay&&(s=Je(s));var u=$e(s.start,a,i,n.granularity);if(r){var l=$e(s.end,r,i,n.granularity);this.mutate({startDelta:u,endDelta:l,standardProps:o})}else o.hasEnd=!1,this.mutate({startDelta:u,standardProps:o})}},e.prototype.moveStart=function(e){var t=ue(e);t&&this.mutate({startDelta:t})},e.prototype.moveEnd=function(e){var t=ue(e);t&&this.mutate({endDelta:t})},e.prototype.moveDates=function(e){var t=ue(e);t&&this.mutate({startDelta:t,endDelta:t})},e.prototype.setAllDay=function(e,t){void 0===t&&(t={});var n={allDay:e},r=t.maintainDuration;null==r&&(r=this._calendar.opt("allDayMaintainDuration")),this._def.allDay!==e&&(n.hasEnd=r),this.mutate({standardProps:n})},e.prototype.formatRange=function(e){var t=this._calendar.dateEnv,n=this._instance,r=Vt(e,this._calendar.opt("defaultRangeSeparator"));return this._def.hasEnd?t.formatRange(n.range.start,n.range.end,r,{forcedStartTzo:n.forcedStartTzo,forcedEndTzo:n.forcedEndTzo}):t.format(n.range.start,r,{forcedTzo:n.forcedStartTzo})},e.prototype.mutate=function(e){var t=this._def,n=this._instance;if(n){this._calendar.dispatch({type:"MUTATE_EVENTS",instanceId:n.instanceId,mutation:e,fromApi:!0});var r=this._calendar.state.eventStore;this._def=r.defs[t.defId],this._instance=r.instances[n.instanceId]}},e.prototype.remove=function(){this._calendar.dispatch({type:"REMOVE_EVENT_DEF",defId:this._def.defId})},Object.defineProperty(e.prototype,"source",{get:function(){var e=this._def.sourceId;return e?new Vi(this._calendar,this._calendar.state.eventSources[e]):null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"start",{get:function(){return this._instance?this._calendar.dateEnv.toDate(this._instance.range.start):null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"end",{get:function(){return this._instance&&this._def.hasEnd?this._calendar.dateEnv.toDate(this._instance.range.end):null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"id",{get:function(){return this._def.publicId},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"groupId",{get:function(){return this._def.groupId},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"allDay",{get:function(){return this._def.allDay},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"title",{get:function(){return this._def.title},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"url",{get:function(){return this._def.url},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rendering",{get:function(){return this._def.rendering},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"startEditable",{get:function(){return this._def.ui.startEditable},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"durationEditable",{get:function(){return this._def.ui.durationEditable},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"constraint",{get:function(){return this._def.ui.constraints[0]||null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"overlap",{get:function(){return this._def.ui.overlap},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"allow",{get:function(){return this._def.ui.allows[0]||null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"backgroundColor",{get:function(){return this._def.ui.backgroundColor},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"borderColor",{get:function(){return this._def.ui.borderColor},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"textColor",{get:function(){return this._def.ui.textColor},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"classNames",{get:function(){return this._def.ui.classNames},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"extendedProps",{get:function(){return this._def.extendedProps},enumerable:!0,configurable:!0}),e}(),Fi={editable:Boolean,startEditable:Boolean,durationEditable:Boolean,constraint:null,overlap:null,allow:null,className:Rn,classNames:Rn,color:String,backgroundColor:String,borderColor:String,textColor:String},Wi={startEditable:null,durationEditable:null,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]},Zi={id:String,groupId:String,title:String,url:String,rendering:String,extendedProps:null},ji={start:null,date:null,end:null,allDay:null},Yi=0,qi={startTime:"09:00",endTime:"17:00",daysOfWeek:[1,2,3,4,5],rendering:"inverse-background",classNames:"fc-nonbusiness",groupId:"_businessHours"},Gi=vt(),Xi=function(){function e(){this.getKeysForEventDefs=kt(this._getKeysForEventDefs),this.splitDateSelection=kt(this._splitDateSpan),this.splitEventStore=kt(this._splitEventStore),this.splitIndividualUi=kt(this._splitIndividualUi),this.splitEventDrag=kt(this._splitInteraction),this.splitEventResize=kt(this._splitInteraction),this.eventUiBuilders={}}return e.prototype.splitProps=function(e){var t=this,n=this.getKeyInfo(e),r=this.getKeysForEventDefs(e.eventStore),i=this.splitDateSelection(e.dateSelection),o=this.splitIndividualUi(e.eventUiBases,r),a=this.splitEventStore(e.eventStore,r),s=this.splitEventDrag(e.eventDrag),u=this.splitEventResize(e.eventResize),l={};this.eventUiBuilders=ot(n,function(e,n){return t.eventUiBuilders[n]||kt(jn)});for(var c in n){var d=n[c],f=a[c]||Gi,p=this.eventUiBuilders[c];l[c]={businessHours:d.businessHours||e.businessHours,dateSelection:i[c]||null,eventStore:f,eventUiBases:p(e.eventUiBases[""],d.ui,o[c]),eventSelection:f.instances[e.eventSelection]?e.eventSelection:"",eventDrag:s[c]||null,eventResize:u[c]||null}}return l},e.prototype._splitDateSpan=function(e){var t={};if(e)for(var n=this.getKeysForDateSpan(e),r=0,i=n;r<i.length;r++){var o=i[r];t[o]=e}return t},e.prototype._getKeysForEventDefs=function(e){var t=this;return ot(e.defs,function(e){return t.getKeysForEventDef(e)})},e.prototype._splitEventStore=function(e,t){var n=e.defs,r=e.instances,i={};for(var o in n)for(var a=0,s=t[o];a<s.length;a++){var u=s[a];i[u]||(i[u]=vt()),i[u].defs[o]=n[o]}for(var l in r)for(var c=r[l],d=0,f=t[c.defId];d<f.length;d++){var u=f[d];i[u]&&(i[u].instances[l]=c)}return i},e.prototype._splitIndividualUi=function(e,t){var n={};for(var r in e)if(r)for(var i=0,o=t[r];i<o.length;i++){var a=o[i];n[a]||(n[a]={}),n[a][r]=e[r]}return n},e.prototype._splitInteraction=function(e){var t={};if(e){var n=this._splitEventStore(e.affectedEvents,this._getKeysForEventDefs(e.affectedEvents)),r=this._getKeysForEventDefs(e.mutatedEvents),i=this._splitEventStore(e.mutatedEvents,r),o=function(r){t[r]||(t[r]={affectedEvents:n[r]||Gi,mutatedEvents:i[r]||Gi,isEvent:e.isEvent,origSeg:e.origSeg})};for(var a in n)o(a);for(var a in i)o(a)}return t},e}(),Ji=function(){function e(){}return e.mixInto=function(e){this.mixIntoObj(e.prototype)},e.mixIntoObj=function(e){var t=this;Object.getOwnPropertyNames(this.prototype).forEach(function(n){e[n]||(e[n]=t.prototype[n])})},e.mixOver=function(e){var t=this;Object.getOwnPropertyNames(this.prototype).forEach(function(n){e.prototype[n]=t.prototype[n]})},e}(),Ki=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return et(t,e),t.prototype.on=function(e,t){return Jn(this._handlers||(this._handlers={}),e,t),this},t.prototype.one=function(e,t){return Jn(this._oneHandlers||(this._oneHandlers={}),e,t),this},t.prototype.off=function(e,t){return this._handlers&&Kn(this._handlers,e,t),this._oneHandlers&&Kn(this._oneHandlers,e,t),this},t.prototype.trigger=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];return this.triggerWith(e,this,t),this},t.prototype.triggerWith=function(e,t,n){return this._handlers&&je(this._handlers[e],t,n),this._oneHandlers&&(je(this._oneHandlers[e],t,n),delete this._oneHandlers[e]),this},t.prototype.hasHandlers=function(e){return this._handlers&&this._handlers[e]&&this._handlers[e].length||this._oneHandlers&&this._oneHandlers[e]&&this._oneHandlers[e].length},t}(Ji),Qi=function(){function e(e,t,n,r){this.originEl=e,this.els=t,this.isHorizontal=n,this.isVertical=r}return e.prototype.build=function(){var e=this.originEl,t=this.originClientRect=e.getBoundingClientRect();this.isHorizontal&&this.buildElHorizontals(t.left),this.isVertical&&this.buildElVerticals(t.top)},e.prototype.buildElHorizontals=function(e){for(var t=[],n=[],r=0,i=this.els;r<i.length;r++){var o=i[r],a=o.getBoundingClientRect();t.push(a.left-e),n.push(a.right-e)}this.lefts=t,this.rights=n},e.prototype.buildElVerticals=function(e){for(var t=[],n=[],r=0,i=this.els;r<i.length;r++){var o=i[r],a=o.getBoundingClientRect();t.push(a.top-e),n.push(a.bottom-e)}this.tops=t,this.bottoms=n},e.prototype.leftToIndex=function(e){var t,n=this.lefts,r=this.rights,i=n.length;for(t=0;t<i;t++)if(e>=n[t]&&e<r[t])return t},e.prototype.topToIndex=function(e){var t,n=this.tops,r=this.bottoms,i=n.length;for(t=0;t<i;t++)if(e>=n[t]&&e<r[t])return t},e.prototype.getWidth=function(e){return this.rights[e]-this.lefts[e]},e.prototype.getHeight=function(e){return this.bottoms[e]-this.tops[e]},e}(),$i=function(){function e(){}return e.prototype.getMaxScrollTop=function(){return this.getScrollHeight()-this.getClientHeight()},e.prototype.getMaxScrollLeft=function(){return this.getScrollWidth()-this.getClientWidth()},e.prototype.canScrollVertically=function(){return this.getMaxScrollTop()>0},e.prototype.canScrollHorizontally=function(){return this.getMaxScrollLeft()>0},e.prototype.canScrollUp=function(){return this.getScrollTop()>0},e.prototype.canScrollDown=function(){return this.getScrollTop()<this.getMaxScrollTop()},e.prototype.canScrollLeft=function(){return this.getScrollLeft()>0},e.prototype.canScrollRight=function(){return this.getScrollLeft()<this.getMaxScrollLeft()},e}(),eo=function(e){function t(t){var n=e.call(this)||this;return n.el=t,n}return et(t,e),t.prototype.getScrollTop=function(){return this.el.scrollTop},t.prototype.getScrollLeft=function(){return this.el.scrollLeft},t.prototype.setScrollTop=function(e){this.el.scrollTop=e},t.prototype.setScrollLeft=function(e){this.el.scrollLeft=e},t.prototype.getScrollWidth=function(){return this.el.scrollWidth},t.prototype.getScrollHeight=function(){return this.el.scrollHeight},t.prototype.getClientHeight=function(){return this.el.clientHeight},t.prototype.getClientWidth=function(){return this.el.clientWidth},t}($i),to=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return et(t,e),t.prototype.getScrollTop=function(){return window.pageYOffset},t.prototype.getScrollLeft=function(){return window.pageXOffset},t.prototype.setScrollTop=function(e){
+window.scroll(window.pageXOffset,e)},t.prototype.setScrollLeft=function(e){window.scroll(e,window.pageYOffset)},t.prototype.getScrollWidth=function(){return document.documentElement.scrollWidth},t.prototype.getScrollHeight=function(){return document.documentElement.scrollHeight},t.prototype.getClientHeight=function(){return document.documentElement.clientHeight},t.prototype.getClientWidth=function(){return document.documentElement.clientWidth},t}($i),no=function(e){function n(n,r){var i=e.call(this,t("div",{className:"fc-scroller"}))||this;return i.overflowX=n,i.overflowY=r,i.applyOverflow(),i}return et(n,e),n.prototype.clear=function(){this.setHeight("auto"),this.applyOverflow()},n.prototype.destroy=function(){c(this.el)},n.prototype.applyOverflow=function(){g(this.el,{overflowX:this.overflowX,overflowY:this.overflowY})},n.prototype.lockOverflow=function(e){var t=this.overflowX,n=this.overflowY;e=e||this.getScrollbarWidths(),"auto"===t&&(t=e.bottom||this.canScrollHorizontally()?"scroll":"hidden"),"auto"===n&&(n=e.left||e.right||this.canScrollVertically()?"scroll":"hidden"),g(this.el,{overflowX:t,overflowY:n})},n.prototype.setHeight=function(e){y(this.el,"height",e)},n.prototype.getScrollbarWidths=function(){var e=C(this.el);return{left:e.scrollbarLeft,right:e.scrollbarRight,bottom:e.scrollbarBottom}},n}(eo),ro=function(){function e(e){this.calendarOptions=e,this.processIconOverride()}return e.prototype.processIconOverride=function(){this.iconOverrideOption&&this.setIconOverride(this.calendarOptions[this.iconOverrideOption])},e.prototype.setIconOverride=function(e){var t,n;if("object"==typeof e&&e){t=ki({},this.iconClasses);for(n in e)t[n]=this.applyIconOverridePrefix(e[n]);this.iconClasses=t}else!1===e&&(this.iconClasses={})},e.prototype.applyIconOverridePrefix=function(e){var t=this.iconOverridePrefix;return t&&0!==e.indexOf(t)&&(e=t+e),e},e.prototype.getClass=function(e){return this.classes[e]||""},e.prototype.getIconClass=function(e){var t=this.iconClasses[e];return t?this.baseIconClass+" "+t:""},e.prototype.getCustomButtonIconClass=function(e){var t;return this.iconOverrideCustomButtonOption&&(t=e[this.iconOverrideCustomButtonOption])?this.baseIconClass+" "+this.applyIconOverridePrefix(t):""},e}();ro.prototype.classes={},ro.prototype.iconClasses={},ro.prototype.baseIconClass="",ro.prototype.iconOverridePrefix="";var io=0,oo=function(){function e(e,t){t&&(e.view=this),this.uid=String(io++),this.context=e,this.dateEnv=e.dateEnv,this.theme=e.theme,this.view=e.view,this.calendar=e.calendar,this.isRtl="rtl"===this.opt("dir")}return e.addEqualityFuncs=function(e){this.prototype.equalityFuncs=ki({},this.prototype.equalityFuncs,e)},e.prototype.opt=function(e){return this.context.options[e]},e.prototype.receiveProps=function(e){var t=Qn(this.props||{},e,this.equalityFuncs),n=t.anyChanges,r=t.comboProps;this.props=r,n&&this.render(r)},e.prototype.render=function(e){},e.prototype.destroy=function(){},e}();oo.prototype.equalityFuncs={};var ao=function(e){function t(t,n,r){var i=e.call(this,t,r)||this;return i.el=n,i}return et(t,e),t.prototype.destroy=function(){e.prototype.destroy.call(this),c(this.el)},t.prototype.queryHit=function(e,t,n,r){return null},t.prototype.isInteractionValid=function(e){var t=this.calendar,n=this.props.dateProfile,r=e.mutatedEvents.instances;if(n)for(var i in r)if(!wt(n.validRange,r[i].range))return!1;return dn(e,t)},t.prototype.isDateSelectionValid=function(e){var t=this.props.dateProfile;return!(t&&!wt(t.validRange,e.range))&&fn(e,this.calendar)},t.prototype.publiclyTrigger=function(e,t){return this.calendar.publiclyTrigger(e,t)},t.prototype.publiclyTriggerAfterSizing=function(e,t){return this.calendar.publiclyTriggerAfterSizing(e,t)},t.prototype.hasPublicHandlers=function(e){return this.calendar.hasPublicHandlers(e)},t.prototype.triggerRenderedSegs=function(e,t){var n=this.calendar;if(this.hasPublicHandlers("eventPositioned"))for(var r=0,i=e;r<i.length;r++){var o=i[r];this.publiclyTriggerAfterSizing("eventPositioned",[{event:new Bi(n,o.eventRange.def,o.eventRange.instance),isMirror:t,isStart:o.isStart,isEnd:o.isEnd,el:o.el,view:this}])}n.state.loadingLevel||(n.afterSizingTriggers._eventsPositioned=[null])},t.prototype.triggerWillRemoveSegs=function(e,t){for(var n=this.calendar,r=0,i=e;r<i.length;r++){var o=i[r];n.trigger("eventElRemove",o.el)}if(this.hasPublicHandlers("eventDestroy"))for(var a=0,s=e;a<s.length;a++){var o=s[a];this.publiclyTrigger("eventDestroy",[{event:new Bi(n,o.eventRange.def,o.eventRange.instance),isMirror:t,el:o.el,view:this}])}},t.prototype.isValidSegDownEl=function(e){return!this.props.eventDrag&&!this.props.eventResize&&!d(e,".fc-mirror")&&(this.isPopover()||!this.isInPopover(e))},t.prototype.isValidDateDownEl=function(e){var t=d(e,this.fgSegSelector);return(!t||t.classList.contains("fc-mirror"))&&!d(e,".fc-more")&&!d(e,"a[data-goto]")&&!this.isInPopover(e)},t.prototype.isPopover=function(){return this.el.classList.contains("fc-popover")},t.prototype.isInPopover=function(e){return Boolean(d(e,".fc-popover"))},t}(oo);ao.prototype.fgSegSelector=".fc-event-container > *",ao.prototype.bgSegSelector=".fc-bgevent:not(.fc-nonbusiness)";var so=0,uo=function(){function e(){this.hooks={reducers:[],eventDefParsers:[],eventDragMutationMassagers:[],eventDefMutationAppliers:[],dateSelectionTransformers:[],datePointTransforms:[],dateSpanTransforms:[],views:{},viewPropsTransformers:[],isPropsValid:null,externalDefTransforms:[],eventResizeJoinTransforms:[],viewContainerModifiers:[],eventDropTransformers:[],componentInteractions:[],calendarInteractions:[],themeClasses:{},eventSourceDefs:[],cmdFormatter:null,recurringTypes:[],namedTimeZonedImpl:null,defaultView:"",elementDraggingImpl:null,optionChangeHandlers:{}},this.addedHash={}}return e.prototype.add=function(e){if(!this.addedHash[e.id]){this.addedHash[e.id]=!0;for(var t=0,n=e.deps;t<n.length;t++){var r=n[t];this.add(r)}this.hooks=er(this.hooks,e)}},e}(),lo={ignoreRange:!0,parseMeta:function(e){return Array.isArray(e)?e:Array.isArray(e.events)?e.events:null},fetch:function(e,t){t({rawEvents:e.eventSource.meta})}},co=$n({eventSourceDefs:[lo]}),fo={parseMeta:function(e){return"function"==typeof e?e:"function"==typeof e.events?e.events:null},fetch:function(e,t,n){var r=e.calendar.dateEnv;Xn(e.eventSource.meta.bind(null,{start:r.toDate(e.range.start),end:r.toDate(e.range.end),startStr:r.formatIso(e.range.start),endStr:r.formatIso(e.range.end),timeZone:r.timeZone}),function(e){t({rawEvents:e})},n)}},po=$n({eventSourceDefs:[fo]}),ho={parseMeta:function(e){if("string"==typeof e)e={url:e};else if(!e||"object"!=typeof e||!e.url)return null;return{url:e.url,method:(e.method||"GET").toUpperCase(),extraParams:e.extraParams,startParam:e.startParam,endParam:e.endParam,timeZoneParam:e.timeZoneParam}},fetch:function(e,t,n){var r=e.eventSource.meta,i=ir(r,e.range,e.calendar);tr(r.method,r.url,i,function(e,n){t({rawEvents:e,xhr:n})},function(e,t){n({message:e,xhr:t})})}},vo=$n({eventSourceDefs:[ho]}),go={parse:function(e,t,n){var r=n.createMarker.bind(n),i={daysOfWeek:null,startTime:ue,endTime:ue,startRecur:r,endRecur:r},o=Ge(e,i,{},t),a=!1;for(var s in o)if(null!=o[s]){a=!0;break}return a?{allDayGuess:Boolean(!o.startTime&&!o.endTime),duration:o.startTime&&o.endTime?ve(o.endTime,o.startTime):null,typeData:o}:null},expand:function(e,t,n){var r=Dt(t,{start:e.startRecur,end:e.endRecur});return r?or(e.daysOfWeek,e.startTime,r,n):[]}},yo=$n({recurringTypes:[go]}),mo=$n({optionChangeHandlers:{events:function(e,t){ar([e],t)},eventSources:ar,plugins:sr}}),Eo={},So={defaultRangeSeparator:" - ",titleRangeSeparator:" – ",defaultTimedEventDuration:"01:00:00",defaultAllDayEventDuration:{day:1},forceEventDuration:!1,nextDayThreshold:"00:00:00",columnHeader:!0,defaultView:"",aspectRatio:1.35,header:{left:"title",center:"",right:"today prev,next"},weekends:!0,weekNumbers:!1,weekNumberCalculation:"local",editable:!1,scrollTime:"06:00:00",minTime:"00:00:00",maxTime:"24:00:00",showNonCurrentDates:!0,lazyFetching:!0,startParam:"start",endParam:"end",timeZoneParam:"timeZone",timeZone:"local",locales:[],locale:"",timeGridEventMinHeight:0,themeSystem:"standard",dragRevertDuration:500,dragScroll:!0,allDayMaintainDuration:!1,unselectAuto:!0,dropAccept:"*",eventOrder:"start,-duration,allDay,title",eventLimit:!1,eventLimitClick:"popover",dayPopoverFormat:{month:"long",day:"numeric",year:"numeric"},handleWindowResize:!0,windowResizeDelay:100,longPressDelay:1e3,eventDragMinDistance:5},Do={header:{left:"next,prev today",center:"",right:"title"},buttonIcons:{prev:"fc-icon-chevron-right",next:"fc-icon-chevron-left",prevYear:"fc-icon-chevrons-right",nextYear:"fc-icon-chevrons-left"}},bo=["header","footer","buttonText","buttonIcons"],To=[co,po,vo,yo,mo],wo={code:"en",week:{dow:0,doy:4},dir:"ltr",buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day",list:"list"},weekLabel:"W",allDayText:"all-day",eventLimitText:"more",noEventsMessage:"No events to display"},Ro=function(){function e(e){this.overrides=ki({},e),this.dynamicOverrides={},this.compute()}return e.prototype.add=function(e){ki(this.overrides,e),this.compute()},e.prototype.addDynamic=function(e){ki(this.dynamicOverrides,e),this.compute()},e.prototype.reset=function(e){this.overrides=e,this.compute()},e.prototype.compute=function(){var e=Ye(this.dynamicOverrides.locales,this.overrides.locales,So.locales),t=Ye(this.dynamicOverrides.locale,this.overrides.locale,So.locale),n=cr(e),r=dr(t||n.defaultCode,n.map).options,i=Ye(this.dynamicOverrides.dir,this.overrides.dir,r.dir),o="rtl"===i?Do:{};this.dirDefaults=o,this.localeDefaults=r,this.computed=ur([So,o,r,this.overrides,this.dynamicOverrides])},e}(),Io={},Co=function(){function e(){}return e.prototype.getMarkerYear=function(e){return e.getUTCFullYear()},e.prototype.getMarkerMonth=function(e){return e.getUTCMonth()},e.prototype.getMarkerDay=function(e){return e.getUTCDate()},e.prototype.arrayToMarker=function(e){return oe(e)},e.prototype.markerToArray=function(e){return ie(e)},e}();!function(e,t){Io[e]=t}("gregory",Co);var Mo=/^\s*\d{4}-\d\d-\d\d([T ]\d)?/,ko=/(?:(Z)|([-+])(\d\d)(?::(\d\d))?)$/,Oo=function(){function e(e){var t=this.timeZone=e.timeZone,n="local"!==t&&"UTC"!==t;e.namedTimeZoneImpl&&n&&(this.namedTimeZoneImpl=new e.namedTimeZoneImpl(t)),this.canComputeOffset=Boolean(!n||this.namedTimeZoneImpl),this.calendarSystem=vr(e.calendarSystem),this.locale=e.locale,this.weekDow=e.locale.week.dow,this.weekDoy=e.locale.week.doy,"ISO"===e.weekNumberCalculation?(this.weekDow=1,this.weekDoy=4):"number"==typeof e.firstDay&&(this.weekDow=e.firstDay),"function"==typeof e.weekNumberCalculation&&(this.weekNumberFunc=e.weekNumberCalculation),this.weekLabel=null!=e.weekLabel?e.weekLabel:e.locale.options.weekLabel,this.cmdFormatter=e.cmdFormatter}return e.prototype.createMarker=function(e){var t=this.createMarkerMeta(e);return null===t?null:t.marker},e.prototype.createNowMarker=function(){return this.canComputeOffset?this.timestampToMarker((new Date).valueOf()):oe(ne(new Date))},e.prototype.createMarkerMeta=function(e){if("string"==typeof e)return this.parse(e);var t=null;return"number"==typeof e?t=this.timestampToMarker(e):e instanceof Date?(e=e.valueOf(),isNaN(e)||(t=this.timestampToMarker(e))):Array.isArray(e)&&(t=oe(e)),null!==t&&ae(t)?{marker:t,isTimeUnspecified:!1,forcedTzo:null}:null},e.prototype.parse=function(e){var t=gr(e);if(null===t)return null;var n=t.marker,r=null;return null!==t.timeZoneOffset&&(this.canComputeOffset?n=this.timestampToMarker(n.valueOf()-60*t.timeZoneOffset*1e3):r=t.timeZoneOffset),{marker:n,isTimeUnspecified:t.isTimeUnspecified,forcedTzo:r}},e.prototype.getYear=function(e){return this.calendarSystem.getMarkerYear(e)},e.prototype.getMonth=function(e){return this.calendarSystem.getMarkerMonth(e)},e.prototype.add=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]+=t.years,n[1]+=t.months,n[2]+=t.days,n[6]+=t.milliseconds,this.calendarSystem.arrayToMarker(n)},e.prototype.subtract=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]-=t.years,n[1]-=t.months,n[2]-=t.days,n[6]-=t.milliseconds,this.calendarSystem.arrayToMarker(n)},e.prototype.addYears=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]+=t,this.calendarSystem.arrayToMarker(n)},e.prototype.addMonths=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[1]+=t,this.calendarSystem.arrayToMarker(n)},e.prototype.diffWholeYears=function(e,t){var n=this.calendarSystem;return se(e)===se(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)&&n.getMarkerMonth(e)===n.getMarkerMonth(t)?n.getMarkerYear(t)-n.getMarkerYear(e):null},e.prototype.diffWholeMonths=function(e,t){var n=this.calendarSystem;return se(e)===se(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)?n.getMarkerMonth(t)-n.getMarkerMonth(e)+12*(n.getMarkerYear(t)-n.getMarkerYear(e)):null},e.prototype.greatestWholeUnit=function(e,t){var n=this.diffWholeYears(e,t);return null!==n?{unit:"year",value:n}:null!==(n=this.diffWholeMonths(e,t))?{unit:"month",value:n}:null!==(n=q(e,t))?{unit:"week",value:n}:null!==(n=G(e,t))?{unit:"day",value:n}:(n=W(e,t),Ze(n)?{unit:"hour",value:n}:(n=Z(e,t),Ze(n)?{unit:"minute",value:n}:(n=j(e,t),Ze(n)?{unit:"second",value:n}:{unit:"millisecond",value:t.valueOf()-e.valueOf()})))},e.prototype.countDurationsBetween=function(e,t,n){var r;return n.years&&null!==(r=this.diffWholeYears(e,t))?r/ye(n):n.months&&null!==(r=this.diffWholeMonths(e,t))?r/me(n):n.days&&null!==(r=G(e,t))?r/Ee(n):(t.valueOf()-e.valueOf())/be(n)},e.prototype.startOf=function(e,t){return"year"===t?this.startOfYear(e):"month"===t?this.startOfMonth(e):"week"===t?this.startOfWeek(e):"day"===t?X(e):"hour"===t?J(e):"minute"===t?K(e):"second"===t?Q(e):void 0},e.prototype.startOfYear=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e)])},e.prototype.startOfMonth=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e)])},e.prototype.startOfWeek=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e),e.getUTCDate()-(e.getUTCDay()-this.weekDow+7)%7])},e.prototype.computeWeekNumber=function(e){return this.weekNumberFunc?this.weekNumberFunc(this.toDate(e)):$(e,this.weekDow,this.weekDoy)},e.prototype.format=function(e,t,n){return void 0===n&&(n={}),t.format({marker:e,timeZoneOffset:null!=n.forcedTzo?n.forcedTzo:this.offsetForMarker(e)},this)},e.prototype.formatRange=function(e,t,n,r){return void 0===r&&(r={}),r.isEndExclusive&&(t=V(t,-1)),n.formatRange({marker:e,timeZoneOffset:null!=r.forcedStartTzo?r.forcedStartTzo:this.offsetForMarker(e)},{marker:t,timeZoneOffset:null!=r.forcedEndTzo?r.forcedEndTzo:this.offsetForMarker(t)},this)},e.prototype.formatIso=function(e,t){void 0===t&&(t={});var n=null;return t.omitTimeZoneOffset||(n=null!=t.forcedTzo?t.forcedTzo:this.offsetForMarker(e)),Bt(e,n,t.omitTime)},e.prototype.timestampToMarker=function(e){return"local"===this.timeZone?oe(ne(new Date(e))):"UTC"!==this.timeZone&&this.namedTimeZoneImpl?oe(this.namedTimeZoneImpl.timestampToArray(e)):new Date(e)},e.prototype.offsetForMarker=function(e){return"local"===this.timeZone?-re(ie(e)).getTimezoneOffset():"UTC"===this.timeZone?0:this.namedTimeZoneImpl?this.namedTimeZoneImpl.offsetForArray(ie(e)):null},e.prototype.toDate=function(e,t){return"local"===this.timeZone?re(ie(e)):"UTC"===this.timeZone?new Date(e.valueOf()):this.namedTimeZoneImpl?new Date(e.valueOf()-1e3*this.namedTimeZoneImpl.offsetForArray(ie(e))*60):new Date(e.valueOf()-(t||0))},e}(),_o={id:String,allDayDefault:Boolean,eventDataTransform:Function,success:Function,failure:Function},Po=0,Ho=0,xo=function(){function e(e,t){this.viewSpec=e,this.options=e.options,this.dateEnv=t.dateEnv,this.calendar=t,this.initHiddenDays()}return e.prototype.buildPrev=function(e,t){var n=this.dateEnv,r=n.subtract(n.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(r,-1)},e.prototype.buildNext=function(e,t){var n=this.dateEnv,r=n.add(n.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(r,1)},e.prototype.build=function(e,t,n){void 0===n&&(n=!1);var r,i,o,a,s,u,l=null,c=null;return r=this.buildValidRange(),r=this.trimHiddenDays(r),n&&(e=It(e,r)),i=this.buildCurrentRangeInfo(e,t),o=/^(year|month|week|day)$/.test(i.unit),a=this.buildRenderRange(this.trimHiddenDays(i.range),i.unit,o),a=this.trimHiddenDays(a),s=a,this.options.showNonCurrentDates||(s=Dt(s,i.range)),l=ue(this.options.minTime),c=ue(this.options.maxTime),s=this.adjustActiveRange(s,l,c),s=Dt(s,r),u=Tt(i.range,r),{validRange:r,currentRange:i.range,currentRangeUnit:i.unit,isRangeAllDay:o,activeRange:s,renderRange:a,minTime:l,maxTime:c,isValid:u,dateIncrement:this.buildDateIncrement(i.duration)}},e.prototype.buildValidRange=function(){return this.getRangeOption("validRange",this.calendar.getNow())||{start:null,end:null}},e.prototype.buildCurrentRangeInfo=function(e,t){var n,r=this,i=r.viewSpec,o=r.dateEnv,a=null,s=null,u=null;return i.duration?(a=i.duration,s=i.durationUnit,u=this.buildRangeFromDuration(e,t,a,s)):(n=this.options.dayCount)?(s="day",u=this.buildRangeFromDayCount(e,t,n)):(u=this.buildCustomVisibleRange(e))?s=o.greatestWholeUnit(u.start,u.end).unit:(a=this.getFallbackDuration(),s=we(a).unit,u=this.buildRangeFromDuration(e,t,a,s)),{duration:a,unit:s,range:u}},e.prototype.getFallbackDuration=function(){return ue({day:1})},e.prototype.adjustActiveRange=function(e,t,n){var r=this.dateEnv,i=e.start,o=e.end;return this.viewSpec.class.prototype.usesMinMaxTime&&(Ee(t)<0&&(i=X(i),i=r.add(i,t)),Ee(n)>1&&(o=X(o),o=A(o,-1),o=r.add(o,n))),{start:i,end:o}},e.prototype.buildRangeFromDuration=function(e,t,n,r){function i(){s=c.startOf(e,d),u=c.add(s,n),l={start:s,end:u}}var o,a,s,u,l,c=this.dateEnv,d=this.options.dateAlignment;return d||(o=this.options.dateIncrement,o?(a=ue(o),d=be(a)<be(n)?we(a,!de(o)).unit:r):d=r),Ee(n)<=1&&this.isHiddenDay(s)&&(s=this.skipHiddenDays(s,t),s=X(s)),i(),this.trimHiddenDays(l)||(e=this.skipHiddenDays(e,t),i()),l},e.prototype.buildRangeFromDayCount=function(e,t,n){var r,i=this.dateEnv,o=this.options.dateAlignment,a=0,s=e;o&&(s=i.startOf(s,o)),s=X(s),s=this.skipHiddenDays(s,t),r=s;do{r=A(r,1),this.isHiddenDay(r)||a++}while(a<n);return{start:s,end:r}},e.prototype.buildCustomVisibleRange=function(e){var t=this.dateEnv,n=this.getRangeOption("visibleRange",t.toDate(e));return!n||null!=n.start&&null!=n.end?n:null},e.prototype.buildRenderRange=function(e,t,n){return e},e.prototype.buildDateIncrement=function(e){var t,n=this.options.dateIncrement;return n?ue(n):(t=this.options.dateAlignment)?ue(1,t):e||ue({days:1})},e.prototype.getRangeOption=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];var r=this.options[e];return"function"==typeof r&&(r=r.apply(null,t)),r&&(r=mt(r,this.dateEnv)),r&&(r=Ke(r)),r},e.prototype.initHiddenDays=function(){var e,t=this.options.hiddenDays||[],n=[],r=0;for(!1===this.options.weekends&&t.push(0,6),e=0;e<7;e++)(n[e]=-1!==t.indexOf(e))||r++;if(!r)throw new Error("invalid hiddenDays");this.isHiddenDayHash=n},e.prototype.trimHiddenDays=function(e){var t=e.start,n=e.end;return t&&(t=this.skipHiddenDays(t)),n&&(n=this.skipHiddenDays(n,-1,!0)),null==t||null==n||t<n?{start:t,end:n}:null},e.prototype.isHiddenDay=function(e){return e instanceof Date&&(e=e.getUTCDay()),this.isHiddenDayHash[e]},e.prototype.skipHiddenDays=function(e,t,n){for(void 0===t&&(t=1),void 0===n&&(n=!1);this.isHiddenDayHash[(e.getUTCDay()+(n?t:0)+7)%7];)e=A(e,t);return e},e}(),No={start:null,end:null,allDay:Boolean},zo={type:String,class:null},Uo=function(e){function r(n,r){var i=e.call(this,n)||this;return i._renderLayout=An(i.renderLayout,i.unrenderLayout),i._updateTitle=An(i.updateTitle,null,[i._renderLayout]),i._updateActiveButton=An(i.updateActiveButton,null,[i._renderLayout]),i._updateToday=An(i.updateToday,null,[i._renderLayout]),i._updatePrev=An(i.updatePrev,null,[i._renderLayout]),i._updateNext=An(i.updateNext,null,[i._renderLayout]),i.el=t("div",{className:"fc-toolbar "+r}),i}return et(r,e),r.prototype.destroy=function(){e.prototype.destroy.call(this),this._renderLayout.unrender(),c(this.el)},r.prototype.render=function(e){this._renderLayout(e.layout),this._updateTitle(e.title),this._updateActiveButton(e.activeButton),this._updateToday(e.isTodayEnabled),this._updatePrev(e.isPrevEnabled),this._updateNext(e.isNextEnabled)},r.prototype.renderLayout=function(e){var t=this.el;this.viewsWithButtons=[],a(t,this.renderSection("left",e.left)),a(t,this.renderSection("center",e.center)),a(t,this.renderSection("right",e.right))},r.prototype.unrenderLayout=function(){this.el.innerHTML=""},r.prototype.renderSection=function(e,r){var i=this,o=this,s=o.theme,u=o.calendar,l=u.optionsManager,c=u.viewSpecs,d=t("div",{className:"fc-"+e}),f=l.computed.customButtons||{},p=l.overrides.buttonText||{},h=l.computed.buttonText||{};return r&&r.split(" ").forEach(function(e,t){var r,o=[],l=!0;if(e.split(",").forEach(function(e,t){var r,a,d,v,g,y,m,E,S;"title"===e?(o.push(n("<h2>&nbsp;</h2>")),l=!1):((r=f[e])?(d=function(e){r.click&&r.click.call(E,e)},(v=s.getCustomButtonIconClass(r))||(v=s.getIconClass(e))||(g=r.text)):(a=c[e])?(i.viewsWithButtons.push(e),d=function(){u.changeView(e)},(g=a.buttonTextOverride)||(v=s.getIconClass(e))||(g=a.buttonTextDefault)):u[e]&&(d=function(){u[e]()},(g=p[e])||(v=s.getIconClass(e))||(g=h[e])),d&&(m=["fc-"+e+"-button",s.getClass("button")],g?(y=bn(g),S=""):v&&(y="<span class='"+v+"'></span>",S=' aria-label="'+e+'"'),E=n('<button type="button" class="'+m.join(" ")+'"'+S+">"+y+"</button>"),E.addEventListener("click",d),o.push(E)))}),o.length>1){r=document.createElement("div");var v=s.getClass("buttonGroup");l&&v&&r.classList.add(v),a(r,o),d.appendChild(r)}else a(d,o)}),d},r.prototype.updateToday=function(e){this.toggleButtonEnabled("today",e)},r.prototype.updatePrev=function(e){this.toggleButtonEnabled("prev",e)},r.prototype.updateNext=function(e){this.toggleButtonEnabled("next",e)},r.prototype.updateTitle=function(e){p(this.el,"h2").forEach(function(t){t.innerText=e})},r.prototype.updateActiveButton=function(e){var t=this.theme.getClass("buttonActive");p(this.el,"button").forEach(function(n){e&&n.classList.contains("fc-"+e+"-button")?n.classList.add(t):n.classList.remove(t)})},r.prototype.toggleButtonEnabled=function(e,t){p(this.el,".fc-"+e+"-button").forEach(function(e){e.disabled=!t})},r}(oo),Lo=function(e){function n(n,r){var i=e.call(this,n)||this;i._renderToolbars=An(i.renderToolbars),i.buildViewPropTransformers=kt(ni),i.el=r,s(r,i.contentEl=t("div",{className:"fc-view-container"}));for(var o=i.calendar,a=0,u=o.pluginSystem.hooks.viewContainerModifiers;a<u.length;a++){(0,u[a])(i.contentEl,o)}return i.toggleElClassNames(!0),i.computeTitle=kt(ei),i.parseBusinessHours=kt(function(e){return Un(e,i.calendar)}),i}return et(n,e),n.prototype.destroy=function(){this.header&&this.header.destroy(),this.footer&&this.footer.destroy(),this.view&&this.view.destroy(),c(this.contentEl),this.toggleElClassNames(!1),e.prototype.destroy.call(this)},n.prototype.toggleElClassNames=function(e){var t=this.el.classList,n="fc-"+this.opt("dir"),r=this.theme.getClass("widget");e?(t.add("fc"),t.add(n),t.add(r)):(t.remove("fc"),t.remove(n),t.remove(r))},n.prototype.render=function(e){this.freezeHeight();var t=this.computeTitle(e.dateProfile,e.viewSpec.options);this._renderToolbars(e.viewSpec,e.dateProfile,e.currentDate,e.dateProfileGenerator,t),this.renderView(e,t),this.updateSize(),this.thawHeight()},n.prototype.renderToolbars=function(e,t,n,r,i){var o=this.opt("header"),u=this.opt("footer"),l=this.calendar.getNow(),c=r.build(l),d=r.buildPrev(t,n),f=r.buildNext(t,n),p={title:i,activeButton:e.type,isTodayEnabled:c.isValid&&!Rt(t.currentRange,l),isPrevEnabled:d.isValid,isNextEnabled:f.isValid};o?(this.header||(this.header=new Uo(this.context,"fc-header-toolbar"),s(this.el,this.header.el)),this.header.receiveProps(ki({layout:o},p))):this.header&&(this.header.destroy(),this.header=null),u?(this.footer||(this.footer=new Uo(this.context,"fc-footer-toolbar"),a(this.el,this.footer.el)),this.footer.receiveProps(ki({layout:u},p))):this.footer&&(this.footer.destroy(),this.footer=null)},n.prototype.renderView=function(e,t){var n=this.view,r=e.viewSpec,i=e.dateProfileGenerator;n&&n.viewSpec===r?n.addScroll(n.queryScroll()):(n&&n.destroy(),n=this.view=new r.class({calendar:this.calendar,view:null,dateEnv:this.dateEnv,theme:this.theme,options:r.options},r,i,this.contentEl)),n.title=t;for(var o={dateProfile:e.dateProfile,businessHours:this.parseBusinessHours(r.options.businessHours),eventStore:e.eventStore,eventUiBases:e.eventUiBases,dateSelection:e.dateSelection,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize},a=this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers),s=0,u=a;s<u.length;s++){var l=u[s];ki(o,l.transform(o,r,e,n))}n.receiveProps(o)},n.prototype.updateSize=function(e){void 0===e&&(e=!1);var t=this.view;e&&t.addScroll(t.queryScroll()),(e||null==this.isHeightAuto)&&this.computeHeightVars(),t.updateSize(e,this.viewHeight,this.isHeightAuto),t.updateNowIndicator(),t.popScroll(e)},n.prototype.computeHeightVars=function(){var e=this.calendar,t=e.opt("height"),n=e.opt("contentHeight");this.isHeightAuto="auto"===t||"auto"===n,this.viewHeight="number"==typeof n?n:"function"==typeof n?n():"number"==typeof t?t-this.queryToolbarsHeight():"function"==typeof t?t()-this.queryToolbarsHeight():"parent"===t?this.el.parentNode.offsetHeight-this.queryToolbarsHeight():Math.round(this.contentEl.offsetWidth/Math.max(e.opt("aspectRatio"),.5))},n.prototype.queryToolbarsHeight=function(){var e=0;return this.header&&(e+=_(this.header.el)),this.footer&&(e+=_(this.footer.el)),e},n.prototype.freezeHeight=function(){g(this.el,{height:this.el.offsetHeight,overflow:"hidden"})},n.prototype.thawHeight=function(){g(this.el,{height:"",overflow:""})},n}(oo),Ao=function(){function e(e){this.component=e.component}return e.prototype.destroy=function(){},e}(),Vo={},Bo=function(e){function t(t){var n=e.call(this,t)||this;n.handleSegClick=function(e,t){var r=n.component,i=Jt(t);if(i&&r.isValidSegDownEl(e.target)){var o=d(e.target,".fc-has-url"),a=o?o.querySelector("a[href]").href:"";r.publiclyTrigger("eventClick",[{el:t,event:new Bi(r.calendar,i.eventRange.def,i.eventRange.instance),jsEvent:e,view:r.view}]),a&&!e.defaultPrevented&&(window.location.href=a)}};var r=t.component;return n.destroy=N(r.el,"click",r.fgSegSelector+","+r.bgSegSelector,n.handleSegClick),n}return et(t,e),t}(Ao),Fo=function(e){function t(t){var n=e.call(this,t)||this;n.handleEventElRemove=function(e){e===n.currentSegEl&&n.handleSegLeave(null,n.currentSegEl)},n.handleSegEnter=function(e,t){Jt(t)&&(t.classList.add("fc-allow-mouse-resize"),n.currentSegEl=t,n.triggerEvent("eventMouseEnter",e,t))},n.handleSegLeave=function(e,t){n.currentSegEl&&(t.classList.remove("fc-allow-mouse-resize"),n.currentSegEl=null,n.triggerEvent("eventMouseLeave",e,t))};var r=t.component;return n.removeHoverListeners=z(r.el,r.fgSegSelector+","+r.bgSegSelector,n.handleSegEnter,n.handleSegLeave),r.calendar.on("eventElRemove",n.handleEventElRemove),n}return et(t,e),t.prototype.destroy=function(){this.removeHoverListeners(),this.component.calendar.off("eventElRemove",this.handleEventElRemove)},t.prototype.triggerEvent=function(e,t,n){var r=this.component,i=Jt(n);t&&!r.isValidSegDownEl(t.target)||r.publiclyTrigger(e,[{el:n,event:new Bi(this.component.calendar,i.eventRange.def,i.eventRange.instance),jsEvent:t,view:r.view}])},t}(Ao),Wo=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return et(t,e),t}(ro);Wo.prototype.classes={widget:"fc-unthemed",widgetHeader:"fc-widget-header",widgetContent:"fc-widget-content",buttonGroup:"fc-button-group",button:"fc-button fc-button-primary",buttonActive:"fc-button-active",popoverHeader:"fc-widget-header",popoverContent:"fc-widget-content",headerRow:"fc-widget-header",dayRow:"fc-widget-content",listView:"fc-widget-content"},Wo.prototype.baseIconClass="fc-icon",Wo.prototype.iconClasses={close:"fc-icon-x",prev:"fc-icon-chevron-left",next:"fc-icon-chevron-right",prevYear:"fc-icon-chevrons-left",nextYear:"fc-icon-chevrons-right"},Wo.prototype.iconOverrideOption="buttonIcons",Wo.prototype.iconOverrideCustomButtonOption="icon",Wo.prototype.iconOverridePrefix="fc-icon-";var Zo=function(){function e(e,t){var n=this;this.parseRawLocales=kt(cr),this.buildLocale=kt(dr),this.buildDateEnv=kt(oi),this.buildTheme=kt(ai),this.buildEventUiSingleBase=kt(this._buildEventUiSingleBase),this.buildSelectionConfig=kt(this._buildSelectionConfig),this.buildEventUiBySource=Ot(ui,Fn),this.buildEventUiBases=kt(li),this.interactionsStore={},this.actionQueue=[],this.isReducing=!1,this.needsRerender=!1,this.needsFullRerender=!1,this.isRendering=!1,this.renderingPauseDepth=0,this.buildDelayedRerender=kt(si),this.afterSizingTriggers={},this.isViewUpdated=!1,this.isDatesUpdated=!1,this.isEventsUpdated=!1,this.el=e,this.optionsManager=new Ro(t||{}),this.pluginSystem=new uo,this.addPluginInputs(this.optionsManager.computed.plugins||[]),this.handleOptions(this.optionsManager.computed),this.publiclyTrigger("_init"),this.hydrate(),this.calendarInteractions=this.pluginSystem.hooks.calendarInteractions.map(function(e){return new e(n)})}return e.prototype.addPluginInputs=function(e){for(var t=lr(e),n=0,r=t;n<r.length;n++){var i=r[n];this.pluginSystem.add(i)}},Object.defineProperty(e.prototype,"view",{get:function(){return this.component?this.component.view:null},enumerable:!0,configurable:!0}),e.prototype.render=function(){this.component?this.requestRerender(!0):(this.renderableEventStore=vt(),this.bindHandlers(),this.executeRender())},e.prototype.destroy=function(){if(this.component){this.unbindHandlers(),this.component.destroy(),this.component=null;for(var e=0,t=this.calendarInteractions;e<t.length;e++){t[e].destroy()}this.publiclyTrigger("_destroyed")}},e.prototype.bindHandlers=function(){var e=this;this.removeNavLinkListener=N(this.el,"click","a[data-goto]",function(t,n){var r=n.getAttribute("data-goto");r=r?JSON.parse(r):{};var i=e.dateEnv,o=i.createMarker(r.date),a=r.type,s=e.viewOpt("navLink"+Be(a)+"Click");"function"==typeof s?s(i.toDate(o),t):("string"==typeof s&&(a=s),e.zoomTo(o,a))}),this.opt("handleWindowResize")&&window.addEventListener("resize",this.windowResizeProxy=qe(this.windowResize.bind(this),this.opt("windowResizeDelay")))},e.prototype.unbindHandlers=function(){this.removeNavLinkListener(),this.windowResizeProxy&&(window.removeEventListener("resize",this.windowResizeProxy),this.windowResizeProxy=null)},e.prototype.hydrate=function(){var e=this;this.state=this.buildInitialState();var t=this.opt("eventSources")||[],n=this.opt("events"),r=[];n&&t.unshift(n);for(var i=0,o=t;i<o.length;i++){var a=o[i],s=mr(a,this);s&&r.push(s)}this.batchRendering(function(){e.dispatch({type:"INIT"}),e.dispatch({type:"ADD_EVENT_SOURCES",sources:r}),e.dispatch({type:"SET_VIEW_TYPE",viewType:e.opt("defaultView")||e.pluginSystem.hooks.defaultView})})},e.prototype.buildInitialState=function(){return{viewType:null,loadingLevel:0,eventSourceLoadingLevel:0,currentDate:this.getInitialDate(),dateProfile:null,eventSources:{},eventStore:vt(),dateSelection:null,eventSelection:"",eventDrag:null,eventResize:null}},e.prototype.dispatch=function(e){if(this.actionQueue.push(e),!this.isReducing){this.isReducing=!0;for(var t=this.state;this.actionQueue.length;)this.state=this.reduce(this.state,this.actionQueue.shift(),this);var n=this.state;this.isReducing=!1,!t.loadingLevel&&n.loadingLevel?this.publiclyTrigger("loading",[!0]):t.loadingLevel&&!n.loadingLevel&&this.publiclyTrigger("loading",[!1]);var r=this.component&&this.component.view;(t.eventStore!==n.eventStore||this.needsFullRerender)&&t.eventStore&&(this.isEventsUpdated=!0),
+(t.dateProfile!==n.dateProfile||this.needsFullRerender)&&(t.dateProfile&&r&&this.publiclyTrigger("datesDestroy",[{view:r,el:r.el}]),this.isDatesUpdated=!0),(t.viewType!==n.viewType||this.needsFullRerender)&&(t.viewType&&r&&this.publiclyTrigger("viewSkeletonDestroy",[{view:r,el:r.el}]),this.isViewUpdated=!0),this.requestRerender()}},e.prototype.reduce=function(e,t,n){return Or(e,t,n)},e.prototype.requestRerender=function(e){void 0===e&&(e=!1),this.needsRerender=!0,this.needsFullRerender=this.needsFullRerender||e,this.delayedRerender()},e.prototype.tryRerender=function(){this.component&&this.needsRerender&&!this.renderingPauseDepth&&!this.isRendering&&this.executeRender()},e.prototype.batchRendering=function(e){this.renderingPauseDepth++,e(),this.renderingPauseDepth--,this.needsRerender&&this.requestRerender()},e.prototype.executeRender=function(){var e=this.needsFullRerender;this.needsRerender=!1,this.needsFullRerender=!1,this.isRendering=!0,this.renderComponent(e),this.isRendering=!1,this.needsRerender&&this.delayedRerender()},e.prototype.renderComponent=function(e){var t=this,n=t.state,r=t.component,i=n.viewType,o=this.viewSpecs[i],a=e&&r?r.view.queryScroll():null;if(!o)throw new Error('View type "'+i+'" is not valid');var s=this.renderableEventStore=n.eventSourceLoadingLevel&&!this.opt("progressiveEventRendering")?this.renderableEventStore:n.eventStore,u=this.buildEventUiSingleBase(o.options),l=this.buildEventUiBySource(n.eventSources),c=this.eventUiBases=this.buildEventUiBases(s.defs,u,l);!e&&r||(r&&(r.freezeHeight(),r.destroy()),r=this.component=new Lo({calendar:this,view:null,dateEnv:this.dateEnv,theme:this.theme,options:this.optionsManager.computed},this.el)),r.receiveProps(ki({},n,{viewSpec:o,dateProfile:n.dateProfile,dateProfileGenerator:this.dateProfileGenerators[i],eventStore:s,eventUiBases:c,dateSelection:n.dateSelection,eventSelection:n.eventSelection,eventDrag:n.eventDrag,eventResize:n.eventResize})),a&&r.view.applyScroll(a,!1),this.isViewUpdated&&(this.isViewUpdated=!1,this.publiclyTrigger("viewSkeletonRender",[{view:r.view,el:r.view.el}])),this.isDatesUpdated&&(this.isDatesUpdated=!1,this.publiclyTrigger("datesRender",[{view:r.view,el:r.view.el}])),this.isEventsUpdated&&(this.isEventsUpdated=!1),this.releaseAfterSizingTriggers()},e.prototype.resetOptions=function(e){var t=this,n=this.pluginSystem.hooks.optionChangeHandlers,r=this.optionsManager.overrides,i={},o={},a={};for(var s in r)n[s]||(i[s]=r[s]);for(var u in e)n[u]?a[u]=e[u]:o[u]=e[u];this.batchRendering(function(){Zn(i,o)?t.processOptions(e,"reset"):t.processOptions(Wn(i,o));for(var r in a)n[r](a[r],t)})},e.prototype.setOptions=function(e){var t=this,n=this.pluginSystem.hooks.optionChangeHandlers,r={},i={};for(var o in e)n[o]?i[o]=e[o]:r[o]=e[o];this.batchRendering(function(){t.processOptions(r);for(var e in i)n[e](i[e],t)})},e.prototype.processOptions=function(e,t){var n=this,r=this.dateEnv,i=!1,o=!1,a=!1;for(var s in e)/^(height|contentHeight|aspectRatio)$/.test(s)?o=!0:/^(defaultDate|defaultView)$/.test(s)||(a=!0,"timeZone"===s&&(i=!0));"reset"===t?(a=!0,this.optionsManager.reset(e)):"dynamic"===t?this.optionsManager.addDynamic(e):this.optionsManager.add(e),a&&(this.handleOptions(this.optionsManager.computed),this.needsFullRerender=!0,this.batchRendering(function(){i&&n.dispatch({type:"CHANGE_TIMEZONE",oldDateEnv:r}),n.dispatch({type:"SET_VIEW_TYPE",viewType:n.state.viewType})})),o&&this.updateSize()},e.prototype.setOption=function(e,t){var n;this.processOptions((n={},n[e]=t,n),"dynamic")},e.prototype.getOption=function(e){return this.optionsManager.computed[e]},e.prototype.opt=function(e){return this.optionsManager.computed[e]},e.prototype.viewOpt=function(e){return this.viewOpts()[e]},e.prototype.viewOpts=function(){return this.viewSpecs[this.state.viewType].options},e.prototype.handleOptions=function(e){var t=this,n=this.pluginSystem.hooks;this.defaultAllDayEventDuration=ue(e.defaultAllDayEventDuration),this.defaultTimedEventDuration=ue(e.defaultTimedEventDuration),this.delayedRerender=this.buildDelayedRerender(e.rerenderDelay),this.theme=this.buildTheme(e);var r=this.parseRawLocales(e.locales);this.availableRawLocales=r.map;var i=this.buildLocale(e.locale||r.defaultCode,r.map);this.dateEnv=this.buildDateEnv(i,e.timeZone,n.namedTimeZonedImpl,e.firstDay,e.weekNumberCalculation,e.weekLabel,n.cmdFormatter),this.selectionConfig=this.buildSelectionConfig(e),this.viewSpecs=Qr(n.views,this.optionsManager),this.dateProfileGenerators=ot(this.viewSpecs,function(e){return new e.class.prototype.dateProfileGeneratorClass(e,t)})},e.prototype.getAvailableLocaleCodes=function(){return Object.keys(this.availableRawLocales)},e.prototype._buildSelectionConfig=function(e){return Cn("select",e,this)},e.prototype._buildEventUiSingleBase=function(e){return e.editable&&(e=ki({},e,{eventEditable:!0})),Cn("event",e,this)},e.prototype.hasPublicHandlers=function(e){return this.hasHandlers(e)||this.opt(e)},e.prototype.publiclyTrigger=function(e,t){var n=this.opt(e);if(this.triggerWith(e,this,t),n)return n.apply(this,t)},e.prototype.publiclyTriggerAfterSizing=function(e,t){var n=this.afterSizingTriggers;(n[e]||(n[e]=[])).push(t)},e.prototype.releaseAfterSizingTriggers=function(){var e=this.afterSizingTriggers;for(var t in e)for(var n=0,r=e[t];n<r.length;n++){var i=r[n];this.publiclyTrigger(t,i)}this.afterSizingTriggers={}},e.prototype.isValidViewType=function(e){return Boolean(this.viewSpecs[e])},e.prototype.changeView=function(e,t){var n=null;t&&(t.start&&t.end?(this.optionsManager.addDynamic({visibleRange:t}),this.handleOptions(this.optionsManager.computed)):n=this.dateEnv.createMarker(t)),this.unselect(),this.dispatch({type:"SET_VIEW_TYPE",viewType:e,dateMarker:n})},e.prototype.zoomTo=function(e,t){var n;t=t||"day",n=this.viewSpecs[t]||this.getUnitViewSpec(t),this.unselect(),n?this.dispatch({type:"SET_VIEW_TYPE",viewType:n.type,dateMarker:e}):this.dispatch({type:"SET_DATE",dateMarker:e})},e.prototype.getUnitViewSpec=function(e){var t,n,r;t=this.component.header.viewsWithButtons;for(var i in this.viewSpecs)t.push(i);for(n=0;n<t.length;n++)if((r=this.viewSpecs[t[n]])&&r.singleUnit===e)return r},e.prototype.getInitialDate=function(){var e=this.opt("defaultDate");return null!=e?this.dateEnv.createMarker(e):this.getNow()},e.prototype.prev=function(){this.unselect(),this.dispatch({type:"PREV"})},e.prototype.next=function(){this.unselect(),this.dispatch({type:"NEXT"})},e.prototype.prevYear=function(){this.unselect(),this.dispatch({type:"SET_DATE",dateMarker:this.dateEnv.addYears(this.state.currentDate,-1)})},e.prototype.nextYear=function(){this.unselect(),this.dispatch({type:"SET_DATE",dateMarker:this.dateEnv.addYears(this.state.currentDate,1)})},e.prototype.today=function(){this.unselect(),this.dispatch({type:"SET_DATE",dateMarker:this.getNow()})},e.prototype.gotoDate=function(e){this.unselect(),this.dispatch({type:"SET_DATE",dateMarker:this.dateEnv.createMarker(e)})},e.prototype.incrementDate=function(e){var t=ue(e);t&&(this.unselect(),this.dispatch({type:"SET_DATE",dateMarker:this.dateEnv.add(this.state.currentDate,t)}))},e.prototype.getDate=function(){return this.dateEnv.toDate(this.state.currentDate)},e.prototype.formatDate=function(e,t){var n=this.dateEnv;return n.format(n.createMarker(e),Vt(t))},e.prototype.formatRange=function(e,t,n){var r=this.dateEnv;return r.formatRange(r.createMarker(e),r.createMarker(t),Vt(n,this.opt("defaultRangeSeparator")),n)},e.prototype.formatIso=function(e,t){var n=this.dateEnv;return n.formatIso(n.createMarker(e),{omitTime:t})},e.prototype.windowResize=function(e){!this.isHandlingWindowResize&&this.component&&e.target===window&&(this.isHandlingWindowResize=!0,this.updateSize(),this.publiclyTrigger("windowResize",[this.view]),this.isHandlingWindowResize=!1)},e.prototype.updateSize=function(){this.component&&this.component.updateSize(!0)},e.prototype.registerInteractiveComponent=function(e,t){var n=ri(e,t),r=[Bo,Fo],i=r.concat(this.pluginSystem.hooks.componentInteractions),o=i.map(function(e){return new e(n)});this.interactionsStore[e.uid]=o,Vo[e.uid]=n},e.prototype.unregisterInteractiveComponent=function(e){for(var t=0,n=this.interactionsStore[e.uid];t<n.length;t++){n[t].destroy()}delete this.interactionsStore[e.uid],delete Vo[e.uid]},e.prototype.select=function(e,t){var n;n=null==t?null!=e.start?e:{start:e,end:null}:{start:e,end:t};var r=Ar(n,this.dateEnv,ue({days:1}));r&&(this.dispatch({type:"SELECT_DATES",selection:r}),this.triggerDateSelect(r))},e.prototype.unselect=function(e){this.state.dateSelection&&(this.dispatch({type:"UNSELECT_DATES"}),this.triggerDateUnselect(e))},e.prototype.triggerDateSelect=function(e,t){var n=this.buildDateSpanApi(e);n.jsEvent=t?t.origEvent:null,n.view=this.view,this.publiclyTrigger("select",[n])},e.prototype.triggerDateUnselect=function(e){this.publiclyTrigger("unselect",[{jsEvent:e?e.origEvent:null,view:this.view}])},e.prototype.triggerDateClick=function(e,t,n,r){var i=this.buildDatePointApi(e);i.dayEl=t,i.jsEvent=r,i.view=n,this.publiclyTrigger("dateClick",[i])},e.prototype.buildDatePointApi=function(e){for(var t={},n=0,r=this.pluginSystem.hooks.datePointTransforms;n<r.length;n++){var i=r[n];ki(t,i(e,this))}return ki(t,Zr(e,this.dateEnv)),t},e.prototype.buildDateSpanApi=function(e){for(var t={},n=0,r=this.pluginSystem.hooks.dateSpanTransforms;n<r.length;n++){var i=r[n];ki(t,i(e,this))}return ki(t,Wr(e,this.dateEnv)),t},e.prototype.getNow=function(){var e=this.opt("now");return"function"==typeof e&&(e=e()),null==e?this.dateEnv.createNowMarker():this.dateEnv.createMarker(e)},e.prototype.getDefaultEventEnd=function(e,t){var n=t;return e?(n=X(n),n=this.dateEnv.add(n,this.defaultAllDayEventDuration)):n=this.dateEnv.add(n,this.defaultTimedEventDuration),n},e.prototype.addEvent=function(e,t){if(e instanceof Bi){var n=e._def,r=e._instance;return this.state.eventStore.defs[n.defId]||this.dispatch({type:"ADD_EVENTS",eventStore:lt({def:n,instance:r})}),e}var i;if(t instanceof Vi)i=t.internalEventSource.sourceId;else if(null!=t){var o=this.getEventSourceById(t);if(!o)return console.warn('Could not find an event source with ID "'+t+'"'),null;i=o.internalEventSource.sourceId}var a=On(e,i,this);return a?(this.dispatch({type:"ADD_EVENTS",eventStore:lt(a)}),new Bi(this,a.def,a.def.recurringDef?null:a.instance)):null},e.prototype.getEventById=function(e){var t=this.state.eventStore,n=t.defs,r=t.instances;e=String(e);for(var i in n){var o=n[i];if(o.publicId===e){if(o.recurringDef)return new Bi(this,o,null);for(var a in r){var s=r[a];if(s.defId===o.defId)return new Bi(this,o,s)}}}return null},e.prototype.getEvents=function(){var e=this.state.eventStore,t=e.defs,n=e.instances,r=[];for(var i in n){var o=n[i],a=t[o.defId];r.push(new Bi(this,a,o))}return r},e.prototype.removeAllEvents=function(){this.dispatch({type:"REMOVE_ALL_EVENTS"})},e.prototype.rerenderEvents=function(){this.dispatch({type:"RESET_EVENTS"})},e.prototype.getEventSources=function(){var e=this.state.eventSources,t=[];for(var n in e)t.push(new Vi(this,e[n]));return t},e.prototype.getEventSourceById=function(e){var t=this.state.eventSources;e=String(e);for(var n in t)if(t[n].publicId===e)return new Vi(this,t[n]);return null},e.prototype.addEventSource=function(e){if(e instanceof Vi)return this.state.eventSources[e.internalEventSource.sourceId]||this.dispatch({type:"ADD_EVENT_SOURCES",sources:[e.internalEventSource]}),e;var t=mr(e,this);return t?(this.dispatch({type:"ADD_EVENT_SOURCES",sources:[t]}),new Vi(this,t)):null},e.prototype.removeAllEventSources=function(){this.dispatch({type:"REMOVE_ALL_EVENT_SOURCES"})},e.prototype.refetchEvents=function(){this.dispatch({type:"FETCH_EVENT_SOURCES"})},e}();Ki.mixInto(Zo);var jo=function(e){function n(n,r,i,o){var a=e.call(this,n,t("div",{className:"fc-view fc-"+r.type+"-view"}),!0)||this;return a.renderDatesMem=An(a.renderDatesWrap,a.unrenderDatesWrap),a.renderBusinessHoursMem=An(a.renderBusinessHours,a.unrenderBusinessHours,[a.renderDatesMem]),a.renderDateSelectionMem=An(a.renderDateSelectionWrap,a.unrenderDateSelectionWrap,[a.renderDatesMem]),a.renderEventsMem=An(a.renderEvents,a.unrenderEvents,[a.renderDatesMem]),a.renderEventSelectionMem=An(a.renderEventSelectionWrap,a.unrenderEventSelectionWrap,[a.renderEventsMem]),a.renderEventDragMem=An(a.renderEventDragWrap,a.unrenderEventDragWrap,[a.renderDatesMem]),a.renderEventResizeMem=An(a.renderEventResizeWrap,a.unrenderEventResizeWrap,[a.renderDatesMem]),a.viewSpec=r,a.dateProfileGenerator=i,a.type=r.type,a.eventOrderSpecs=Ue(a.opt("eventOrder")),a.nextDayThreshold=ue(a.opt("nextDayThreshold")),o.appendChild(a.el),a.initialize(),a}return et(n,e),n.prototype.initialize=function(){},Object.defineProperty(n.prototype,"activeStart",{get:function(){return this.dateEnv.toDate(this.props.dateProfile.activeRange.start)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"activeEnd",{get:function(){return this.dateEnv.toDate(this.props.dateProfile.activeRange.end)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"currentStart",{get:function(){return this.dateEnv.toDate(this.props.dateProfile.currentRange.start)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"currentEnd",{get:function(){return this.dateEnv.toDate(this.props.dateProfile.currentRange.end)},enumerable:!0,configurable:!0}),n.prototype.render=function(e){this.renderDatesMem(e.dateProfile),this.renderBusinessHoursMem(e.businessHours),this.renderDateSelectionMem(e.dateSelection),this.renderEventsMem(e.eventStore),this.renderEventSelectionMem(e.eventSelection),this.renderEventDragMem(e.eventDrag),this.renderEventResizeMem(e.eventResize)},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderDatesMem.unrender()},n.prototype.updateSize=function(e,t,n){var r=this.calendar;(e||r.isViewUpdated||r.isDatesUpdated||r.isEventsUpdated)&&this.updateBaseSize(e,t,n)},n.prototype.updateBaseSize=function(e,t,n){},n.prototype.renderDatesWrap=function(e){this.renderDates(e),this.addScroll({isDateInit:!0}),this.startNowIndicator(e)},n.prototype.unrenderDatesWrap=function(){this.stopNowIndicator(),this.unrenderDates()},n.prototype.renderDates=function(e){},n.prototype.unrenderDates=function(){},n.prototype.renderBusinessHours=function(e){},n.prototype.unrenderBusinessHours=function(){},n.prototype.renderDateSelectionWrap=function(e){e&&this.renderDateSelection(e)},n.prototype.unrenderDateSelectionWrap=function(e){e&&this.unrenderDateSelection(e)},n.prototype.renderDateSelection=function(e){},n.prototype.unrenderDateSelection=function(e){},n.prototype.renderEvents=function(e){},n.prototype.unrenderEvents=function(){},n.prototype.sliceEvents=function(e,t){var n=this.props;return Yt(e,n.eventUiBases,n.dateProfile.activeRange,t?this.nextDayThreshold:null).fg},n.prototype.renderEventSelectionWrap=function(e){e&&this.renderEventSelection(e)},n.prototype.unrenderEventSelectionWrap=function(e){e&&this.unrenderEventSelection(e)},n.prototype.renderEventSelection=function(e){},n.prototype.unrenderEventSelection=function(e){},n.prototype.renderEventDragWrap=function(e){e&&this.renderEventDrag(e)},n.prototype.unrenderEventDragWrap=function(e){e&&this.unrenderEventDrag(e)},n.prototype.renderEventDrag=function(e){},n.prototype.unrenderEventDrag=function(e){},n.prototype.renderEventResizeWrap=function(e){e&&this.renderEventResize(e)},n.prototype.unrenderEventResizeWrap=function(e){e&&this.unrenderEventResize(e)},n.prototype.renderEventResize=function(e){},n.prototype.unrenderEventResize=function(e){},n.prototype.startNowIndicator=function(e){var t,n,r,i=this,o=this.dateEnv;this.opt("nowIndicator")&&(t=this.getNowIndicatorUnit(e))&&(n=this.updateNowIndicator.bind(this),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=(new Date).valueOf(),r=o.add(o.startOf(this.initialNowDate,t),ue(1,t)).valueOf()-this.initialNowDate.valueOf(),this.nowIndicatorTimeoutID=setTimeout(function(){i.nowIndicatorTimeoutID=null,n(),r="second"===t?1e3:6e4,i.nowIndicatorIntervalID=setInterval(n,r)},r))},n.prototype.updateNowIndicator=function(){this.props.dateProfile&&this.initialNowDate&&(this.unrenderNowIndicator(),this.renderNowIndicator(V(this.initialNowDate,(new Date).valueOf()-this.initialNowQueriedMs)),this.isNowIndicatorRendered=!0)},n.prototype.stopNowIndicator=function(){this.isNowIndicatorRendered&&(this.nowIndicatorTimeoutID&&(clearTimeout(this.nowIndicatorTimeoutID),this.nowIndicatorTimeoutID=null),this.nowIndicatorIntervalID&&(clearInterval(this.nowIndicatorIntervalID),this.nowIndicatorIntervalID=null),this.unrenderNowIndicator(),this.isNowIndicatorRendered=!1)},n.prototype.getNowIndicatorUnit=function(e){},n.prototype.renderNowIndicator=function(e){},n.prototype.unrenderNowIndicator=function(){},n.prototype.addScroll=function(e){var t=this.queuedScroll||(this.queuedScroll={});ki(t,e)},n.prototype.popScroll=function(e){this.applyQueuedScroll(e),this.queuedScroll=null},n.prototype.applyQueuedScroll=function(e){this.applyScroll(this.queuedScroll||{},e)},n.prototype.queryScroll=function(){var e={};return this.props.dateProfile&&ki(e,this.queryDateScroll()),e},n.prototype.applyScroll=function(e,t){e.isDateInit&&(delete e.isDateInit,this.props.dateProfile&&ki(e,this.computeInitialDateScroll())),this.props.dateProfile&&this.applyDateScroll(e)},n.prototype.computeInitialDateScroll=function(){return{}},n.prototype.queryDateScroll=function(){return{}},n.prototype.applyDateScroll=function(e){},n}(ao);Ki.mixInto(jo),jo.prototype.usesMinMaxTime=!1,jo.prototype.dateProfileGeneratorClass=xo;var Yo=function(){function e(e){this.segs=[],this.isSizeDirty=!1,this.context=e}return e.prototype.renderSegs=function(e,t){this.rangeUpdated(),e=this.renderSegEls(e,t),this.segs=e,this.attachSegs(e,t),this.isSizeDirty=!0,this.context.view.triggerRenderedSegs(this.segs,Boolean(t))},e.prototype.unrender=function(e,t){this.context.view.triggerWillRemoveSegs(this.segs,Boolean(t)),this.detachSegs(this.segs),this.segs=[]},e.prototype.rangeUpdated=function(){var e,t,n=this.context.options;this.eventTimeFormat=Vt(n.eventTimeFormat||this.computeEventTimeFormat(),n.defaultRangeSeparator),e=n.displayEventTime,null==e&&(e=this.computeDisplayEventTime()),t=n.displayEventEnd,null==t&&(t=this.computeDisplayEventEnd()),this.displayEventTime=e,this.displayEventEnd=t},e.prototype.renderSegEls=function(e,t){var n,i="";if(e.length){for(n=0;n<e.length;n++)i+=this.renderSegHtml(e[n],t);r(i).forEach(function(t,n){var r=e[n];t&&(r.el=t)}),e=Gt(this.context.view,e,Boolean(t))}return e},e.prototype.getSegClasses=function(e,t,n,r){var i=["fc-event",e.isStart?"fc-start":"fc-not-start",e.isEnd?"fc-end":"fc-not-end"].concat(e.eventRange.ui.classNames);return t&&i.push("fc-draggable"),n&&i.push("fc-resizable"),r&&(i.push("fc-mirror"),r.isDragging&&i.push("fc-dragging"),r.isResizing&&i.push("fc-resizing")),i},e.prototype.getTimeText=function(e,t,n){var r=e.def,i=e.instance;return this._getTimeText(i.range.start,r.hasEnd?i.range.end:null,r.allDay,t,n,i.forcedStartTzo,i.forcedEndTzo)},e.prototype._getTimeText=function(e,t,n,r,i,o,a){var s=this.context.dateEnv;return null==r&&(r=this.eventTimeFormat),null==i&&(i=this.displayEventEnd),this.displayEventTime&&!n?i&&t?s.formatRange(e,t,r,{forcedStartTzo:o,forcedEndTzo:a}):s.format(e,r,{forcedTzo:o}):""},e.prototype.computeEventTimeFormat=function(){return{hour:"numeric",minute:"2-digit",omitZeroMinute:!0}},e.prototype.computeDisplayEventTime=function(){return!0},e.prototype.computeDisplayEventEnd=function(){return!0},e.prototype.getSkinCss=function(e){return{"background-color":e.backgroundColor,"border-color":e.borderColor,color:e.textColor}},e.prototype.sortEventSegs=function(e){var t=this.context.view.eventOrderSpecs,n=e.map(ci);return n.sort(function(e,n){return Le(e,n,t)}),n.map(function(e){return e._seg})},e.prototype.computeSizes=function(e){(e||this.isSizeDirty)&&this.computeSegSizes(this.segs)},e.prototype.assignSizes=function(e){(e||this.isSizeDirty)&&(this.assignSegSizes(this.segs),this.isSizeDirty=!1)},e.prototype.computeSegSizes=function(e){},e.prototype.assignSegSizes=function(e){},e.prototype.hideByHash=function(e){if(e)for(var t=0,n=this.segs;t<n.length;t++){var r=n[t];e[r.eventRange.instance.instanceId]&&(r.el.style.visibility="hidden")}},e.prototype.showByHash=function(e){if(e)for(var t=0,n=this.segs;t<n.length;t++){var r=n[t];e[r.eventRange.instance.instanceId]&&(r.el.style.visibility="")}},e.prototype.selectByInstanceId=function(e){if(e)for(var t=0,n=this.segs;t<n.length;t++){var r=n[t],i=r.eventRange.instance;i&&i.instanceId===e&&r.el&&r.el.classList.add("fc-selected")}},e.prototype.unselectByInstanceId=function(e){if(e)for(var t=0,n=this.segs;t<n.length;t++){var r=n[t];r.el&&r.el.classList.remove("fc-selected")}},e}(),qo=function(){function e(e){this.fillSegTag="div",this.dirtySizeFlags={},this.context=e,this.containerElsByType={},this.segsByType={}}return e.prototype.getSegsByType=function(e){return this.segsByType[e]||[]},e.prototype.renderSegs=function(e,t){var n,r=this.renderSegEls(e,t),i=this.attachSegs(e,r);i&&(n=this.containerElsByType[e]||(this.containerElsByType[e]=[])).push.apply(n,i),this.segsByType[e]=r,"bgEvent"===e&&this.context.view.triggerRenderedSegs(r,!1),this.dirtySizeFlags[e]=!0},e.prototype.unrender=function(e){var t=this.segsByType[e];t&&("bgEvent"===e&&this.context.view.triggerWillRemoveSegs(t,!1),this.detachSegs(e,t))},e.prototype.renderSegEls=function(e,t){var n,i=this,o="";if(t.length){for(n=0;n<t.length;n++)o+=this.renderSegHtml(e,t[n]);r(o).forEach(function(e,n){var r=t[n];e&&(r.el=e)}),"bgEvent"===e&&(t=Gt(this.context.view,t,!1)),t=t.filter(function(e){return f(e.el,i.fillSegTag)})}return t},e.prototype.renderSegHtml=function(e,t){var n=null,r=[];return"highlight"!==e&&"businessHours"!==e&&(n={"background-color":t.eventRange.ui.backgroundColor}),"highlight"!==e&&(r=r.concat(t.eventRange.ui.classNames)),"businessHours"===e?r.push("fc-bgevent"):r.push("fc-"+e.toLowerCase()),"<"+this.fillSegTag+(r.length?' class="'+r.join(" ")+'"':"")+(n?' style="'+Tn(n)+'"':"")+"></"+this.fillSegTag+">"},e.prototype.detachSegs=function(e,t){var n=this.containerElsByType[e];n&&(n.forEach(c),delete this.containerElsByType[e])},e.prototype.computeSizes=function(e){for(var t in this.segsByType)(e||this.dirtySizeFlags[t])&&this.computeSegSizes(this.segsByType[t])},e.prototype.assignSizes=function(e){for(var t in this.segsByType)(e||this.dirtySizeFlags[t])&&this.assignSegSizes(this.segsByType[t]);this.dirtySizeFlags={}},e.prototype.computeSegSizes=function(e){},e.prototype.assignSegSizes=function(e){},e}(),Go=function(){function e(e){this.timeZoneName=e}return e}(),Xo=function(){function e(e){this.emitter=new Ki}return e.prototype.destroy=function(){},e.prototype.setMirrorIsVisible=function(e){},e.prototype.setMirrorNeedsRevert=function(e){},e.prototype.setAutoScrollEnabled=function(e){},e}(),Jo={startTime:ue,duration:ue,create:Boolean,sourceId:String},Ko={create:!0},Qo=function(e){function t(t,r){var i=e.call(this,t)||this;return r.innerHTML="",r.appendChild(i.el=n('<div class="fc-row '+i.theme.getClass("headerRow")+'"><table class="'+i.theme.getClass("tableGrid")+'"><thead></thead></table></div>')),i.thead=i.el.querySelector("thead"),i}return et(t,e),t.prototype.destroy=function(){c(this.el)},t.prototype.render=function(e){var t=e.dates,n=e.datesRepDistinctDays,r=[];e.renderIntroHtml&&r.push(e.renderIntroHtml());for(var i=Vt(this.opt("columnHeaderFormat")||vi(n,t.length)),o=0,a=t;o<a.length;o++){var s=a[o];r.push(gi(s,e.dateProfile,n,t.length,i,this.context))}this.isRtl&&r.reverse(),this.thead.innerHTML="<tr>"+r.join("")+"</tr>"},t}(oo),$o=function(){function e(e,t){for(var n=e.start,r=e.end,i=[],o=[],a=-1;n<r;)t.isHiddenDay(n)?i.push(a+.5):(a++,i.push(a),o.push(n)),n=A(n,1);this.dates=o,this.indices=i,this.cnt=o.length}return e.prototype.sliceRange=function(e){var t=this.getDateDayIndex(e.start),n=this.getDateDayIndex(A(e.end,-1)),r=Math.max(0,t),i=Math.min(this.cnt-1,n);return r=Math.ceil(r),i=Math.floor(i),r<=i?{firstIndex:r,lastIndex:i,isStart:t===r,isEnd:n===i}:null},e.prototype.getDateDayIndex=function(e){var t=this.indices,n=Math.floor(F(this.dates[0],e));return n<0?t[0]-1:n>=t.length?t[t.length-1]+1:t[n]},e}(),ea=function(){function e(e,t){var n,r,i,o=e.dates;if(t){for(r=o[0].getUTCDay(),n=1;n<o.length&&o[n].getUTCDay()!==r;n++);i=Math.ceil(o.length/n)}else i=1,n=o.length;this.rowCnt=i,this.colCnt=n,this.daySeries=e,this.cells=this.buildCells(),this.headerDates=this.buildHeaderDates()}return e.prototype.buildCells=function(){for(var e=[],t=0;t<this.rowCnt;t++){for(var n=[],r=0;r<this.colCnt;r++)n.push(this.buildCell(t,r));e.push(n)}return e},e.prototype.buildCell=function(e,t){return{date:this.daySeries.dates[e*this.colCnt+t]}},e.prototype.buildHeaderDates=function(){for(var e=[],t=0;t<this.colCnt;t++)e.push(this.cells[0][t].date);return e},e.prototype.sliceRange=function(e){var t=this.colCnt,n=this.daySeries.sliceRange(e),r=[];if(n)for(var i=n.firstIndex,o=n.lastIndex,a=i;a<=o;){var s=Math.floor(a/t),u=Math.min((s+1)*t,o+1);r.push({row:s,firstCol:a%t,lastCol:(u-1)%t,isStart:n.isStart&&a===i,isEnd:n.isEnd&&u-1===o}),a=u}return r},e}(),ta=function(){function e(){this.sliceBusinessHours=kt(this._sliceBusinessHours),this.sliceDateSelection=kt(this._sliceDateSpan),this.sliceEventStore=kt(this._sliceEventStore),this.sliceEventDrag=kt(this._sliceInteraction),this.sliceEventResize=kt(this._sliceInteraction)}return e.prototype.sliceProps=function(e,t,n,r){for(var i=[],o=4;o<arguments.length;o++)i[o-4]=arguments[o];var a=e.eventUiBases,s=this.sliceEventStore.apply(this,[e.eventStore,a,t,n,r].concat(i));return{dateSelectionSegs:this.sliceDateSelection.apply(this,[e.dateSelection,a,r].concat(i)),businessHourSegs:this.sliceBusinessHours.apply(this,[e.businessHours,t,n,r].concat(i)),fgEventSegs:s.fg,bgEventSegs:s.bg,eventDrag:this.sliceEventDrag.apply(this,[e.eventDrag,a,t,n,r].concat(i)),eventResize:this.sliceEventResize.apply(this,[e.eventResize,a,t,n,r].concat(i)),eventSelection:e.eventSelection}},e.prototype.sliceNowDate=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return this._sliceDateSpan.apply(this,[{range:{start:e,end:V(e,1)},allDay:!1},{},t].concat(n))},e.prototype._sliceBusinessHours=function(e,t,n,r){for(var i=[],o=4;o<arguments.length;o++)i[o-4]=arguments[o];return e?this._sliceEventStore.apply(this,[ct(e,yi(t,Boolean(n)),r.calendar),{},t,n,r].concat(i)).bg:[]},e.prototype._sliceEventStore=function(e,t,n,r,i){for(var o=[],a=5;a<arguments.length;a++)o[a-5]=arguments[a];if(e){var s=Yt(e,t,yi(n,Boolean(r)),r);return{bg:this.sliceEventRanges(s.bg,i,o),fg:this.sliceEventRanges(s.fg,i,o)}}return{bg:[],fg:[]}},e.prototype._sliceInteraction=function(e,t,n,r,i){for(var o=[],a=5;a<arguments.length;a++)o[a-5]=arguments[a];if(!e)return null;var s=Yt(e.mutatedEvents,t,yi(n,Boolean(r)),r);return{segs:this.sliceEventRanges(s.fg,i,o),affectedInstances:e.affectedEvents.instances,isEvent:e.isEvent,sourceSeg:e.origSeg}},e.prototype._sliceDateSpan=function(e,t,n){for(var r=[],i=3;i<arguments.length;i++)r[i-3]=arguments[i];if(!e)return[];for(var o=jr(e,t,n.calendar),a=this.sliceRange.apply(this,[e.range].concat(r)),s=0,u=a;s<u.length;s++){var l=u[s];l.component=n,l.eventRange=o}return a},e.prototype.sliceEventRanges=function(e,t,n){for(var r=[],i=0,o=e;i<o.length;i++){var a=o[i];r.push.apply(r,this.sliceEventRange(a,t,n))}return r},e.prototype.sliceEventRange=function(e,t,n){for(var r=this.sliceRange.apply(this,[e.range].concat(n)),i=0,o=r;i<o.length;i++){var a=o[i];a.component=t,a.eventRange=e,a.isStart=e.isStart&&a.isStart,a.isEnd=e.isEnd&&a.isEnd}return r},e}();e.Calendar=Zo,e.Component=oo,e.DateComponent=ao,e.DateEnv=Oo,e.DateProfileGenerator=xo,e.DayHeader=Qo,e.DaySeries=$o,e.DayTable=ea,e.ElementDragging=Xo,e.ElementScrollController=eo,e.EmitterMixin=Ki,e.EventApi=Bi,e.FgEventRenderer=Yo,e.FillRenderer=qo,e.Interaction=Ao,e.Mixin=Ji,e.NamedTimeZoneImpl=Go,e.PositionCache=Qi,e.ScrollComponent=no,e.ScrollController=$i,e.Slicer=ta,e.Splitter=Xi,e.Theme=ro,e.View=jo,e.WindowScrollController=to,e.addDays=A,e.addDurations=he,e.addMs=V,e.addWeeks=L,e.allowContextMenu=ze,e.allowSelection=xe,e.appendToElement=a,e.applyAll=je,e.applyMutationToEventStore=$t,e.applyStyle=g,e.applyStyleProp=y,e.asRoughMinutes=Se,e.asRoughMs=be,e.asRoughSeconds=De,e.buildGotoAnchorHtml=Yn,e.buildSegCompareObj=ci,e.capitaliseFirstLetter=Be,e.combineEventUis=Mn,e.compareByFieldSpec=Ae,e.compareByFieldSpecs=Le,e.compareNumbers=We,e.compensateScroll=Re,e.computeClippingRect=H,e.computeEdges=C,e.computeFallbackHeaderFormat=vi,e.computeHeightAndMargins=_,e.computeInnerRect=M,e.computeRect=k,e.computeVisibleDayRange=Ke,e.config=Eo,e.constrainPoint=D,e.createDuration=ue,e.createElement=t,e.createEmptyEventStore=vt,e.createEventInstance=Pn,e.createFormatter=Vt,e.createPlugin=$n,e.cssToStr=Tn,e.debounce=qe,e.diffDates=$e,e.diffDayAndTime=Y,e.diffDays=F,e.diffPoints=T,e.diffWeeks=B,e.diffWholeDays=G,e.diffWholeWeeks=q,e.disableCursor=Ce,e.distributeHeight=ke,e.elementClosest=d,e.elementMatches=f,e.enableCursor=Me,e.eventTupleToStore=lt,e.filterEventStoreDefs=yt,e.filterHash=it,e.findChildren=h,e.findElements=p,e.flexibleCompare=Ve,e.forceClassName=v,e.formatDate=di,e.formatIsoTimeString=Ft,e.formatRange=fi,e.freezeRaw=Xe,e.getAllDayHtml=qn,e.getClippingParents=P,e.getDayClasses=Gn,e.getElSeg=Jt,e.getRectCenter=b,e.getRelevantEvents=dt,e.globalDefaults=So,e.greatestDurationDenominator=we,e.hasBgRendering=qt,e.htmlEscape=bn,e.htmlToElement=n,e.insertAfterElement=u,e.interactionSettingsStore=Vo,e.interactionSettingsToStore=ii,e.intersectRanges=Dt,e.intersectRects=E,e.isArraysEqual=Mt,e.isDateSpansEqual=Br,e.isInt=Ze,e.isInteractionValid=dn,e.isMultiDayRange=Qe,e.isObjectsSimilar=Fn,e.isPropsValid=hn,e.isSingleDay=pe,e.isValidDate=ae,e.isValuesSimilar=Vn,e.listenBySelector=N,e.mapHash=ot,e.matchCellWidths=_e,e.memoize=kt,e.memoizeOutput=Ot,e.memoizeRendering=An,e.mergeEventStores=gt,e.multiplyDuration=ge,e.padStart=Fe,e.parseBusinessHours=Un,e.parseDragMeta=hi,e.parseEventDef=_n,e.parseFieldSpecs=Ue,e.parseMarker=gr,e.pointInsideRect=m,e.prependToElement=s,e.preventContextMenu=Ne,e.preventDefault=x,e.preventSelection=He,e.processScopedUiProps=Cn,e.rangeContainsMarker=Rt,e.rangeContainsRange=wt,e.rangesEqual=bt,e.rangesIntersect=Tt,e.refineProps=Ge,e.removeElement=c,e.removeExact=Ct,e.renderDateCell=gi,e.requestJson=tr,e.sliceEventStore=Yt,e.startOfDay=X,e.subtractInnerElHeight=Pe,e.translateRect=S,e.uncompensateScroll=Ie,e.undistributeHeight=Oe,e.unpromisify=Xn,e.version="4.0.2",e.whenTransitionDone=U,e.wholeDivideDurations=Te,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/daygrid/main.css b/library/fullcalendar/packages/daygrid/main.css
new file mode 100644
index 000000000..60f489ce2
--- /dev/null
+++ b/library/fullcalendar/packages/daygrid/main.css
@@ -0,0 +1,69 @@
+/*!
+FullCalendar Day Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+/* DayGridView
+--------------------------------------------------------------------------------------------------*/
+/* day row structure */
+.fc-dayGridWeek-view .fc-content-skeleton,
+.fc-dayGridDay-view .fc-content-skeleton {
+ /* there may be week numbers in these views, so no padding-top */
+ padding-bottom: 1em;
+ /* ensure a space at bottom of cell for user selecting/clicking */ }
+
+.fc-dayGrid-view .fc-body .fc-row {
+ min-height: 4em;
+ /* ensure that all rows are at least this tall */ }
+
+/* a "rigid" row will take up a constant amount of height because content-skeleton is absolute */
+.fc-row.fc-rigid {
+ overflow: hidden; }
+
+.fc-row.fc-rigid .fc-content-skeleton {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0; }
+
+/* week and day number styling */
+.fc-day-top.fc-other-month {
+ opacity: 0.3; }
+
+.fc-dayGrid-view .fc-week-number,
+.fc-dayGrid-view .fc-day-number {
+ padding: 2px; }
+
+.fc-dayGrid-view th.fc-week-number,
+.fc-dayGrid-view th.fc-day-number {
+ padding: 0 2px;
+ /* column headers can't have as much v space */ }
+
+.fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number {
+ float: right; }
+
+.fc-rtl .fc-dayGrid-view .fc-day-top .fc-day-number {
+ float: left; }
+
+.fc-ltr .fc-dayGrid-view .fc-day-top .fc-week-number {
+ float: left;
+ border-radius: 0 0 3px 0; }
+
+.fc-rtl .fc-dayGrid-view .fc-day-top .fc-week-number {
+ float: right;
+ border-radius: 0 0 0 3px; }
+
+.fc-dayGrid-view .fc-day-top .fc-week-number {
+ min-width: 1.5em;
+ text-align: center;
+ background-color: #f2f2f2;
+ color: #808080; }
+
+/* when week/day number have own column */
+.fc-dayGrid-view td.fc-week-number {
+ text-align: center; }
+
+.fc-dayGrid-view td.fc-week-number > * {
+ /* work around the way we do column resizing and ensure a minimum width */
+ display: inline-block;
+ min-width: 1.25em; }
diff --git a/library/fullcalendar/packages/daygrid/main.js b/library/fullcalendar/packages/daygrid/main.js
new file mode 100644
index 000000000..e41463eb9
--- /dev/null
+++ b/library/fullcalendar/packages/daygrid/main.js
@@ -0,0 +1,1630 @@
+/*!
+FullCalendar Day Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarDayGrid = {}, global.FullCalendar));
+}(this, function (exports, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ var DayGridDateProfileGenerator = /** @class */ (function (_super) {
+ __extends(DayGridDateProfileGenerator, _super);
+ function DayGridDateProfileGenerator() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ // Computes the date range that will be rendered.
+ DayGridDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
+ var dateEnv = this.dateEnv;
+ var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
+ var start = renderRange.start;
+ var end = renderRange.end;
+ var endOfWeek;
+ // year and month views should be aligned with weeks. this is already done for week
+ if (/^(year|month)$/.test(currentRangeUnit)) {
+ start = dateEnv.startOfWeek(start);
+ // make end-of-week if not already
+ endOfWeek = dateEnv.startOfWeek(end);
+ if (endOfWeek.valueOf() !== end.valueOf()) {
+ end = core.addWeeks(endOfWeek, 1);
+ }
+ }
+ // ensure 6 weeks
+ if (this.options.monthMode &&
+ this.options.fixedWeekCount) {
+ var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
+ core.diffWeeks(start, end));
+ end = core.addWeeks(end, 6 - rowCnt);
+ }
+ return { start: start, end: end };
+ };
+ return DayGridDateProfileGenerator;
+ }(core.DateProfileGenerator));
+
+ /* A rectangular panel that is absolutely positioned over other content
+ ------------------------------------------------------------------------------------------------------------------------
+ Options:
+ - className (string)
+ - content (HTML string, element, or element array)
+ - parentEl
+ - top
+ - left
+ - right (the x coord of where the right edge should be. not a "CSS" right)
+ - autoHide (boolean)
+ - show (callback)
+ - hide (callback)
+ */
+ var Popover = /** @class */ (function () {
+ function Popover(options) {
+ var _this = this;
+ this.isHidden = true;
+ this.margin = 10; // the space required between the popover and the edges of the scroll container
+ // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
+ this.documentMousedown = function (ev) {
+ // only hide the popover if the click happened outside the popover
+ if (_this.el && !_this.el.contains(ev.target)) {
+ _this.hide();
+ }
+ };
+ this.options = options;
+ }
+ // Shows the popover on the specified position. Renders it if not already
+ Popover.prototype.show = function () {
+ if (this.isHidden) {
+ if (!this.el) {
+ this.render();
+ }
+ this.el.style.display = '';
+ this.position();
+ this.isHidden = false;
+ this.trigger('show');
+ }
+ };
+ // Hides the popover, through CSS, but does not remove it from the DOM
+ Popover.prototype.hide = function () {
+ if (!this.isHidden) {
+ this.el.style.display = 'none';
+ this.isHidden = true;
+ this.trigger('hide');
+ }
+ };
+ // Creates `this.el` and renders content inside of it
+ Popover.prototype.render = function () {
+ var _this = this;
+ var options = this.options;
+ var el = this.el = core.createElement('div', {
+ className: 'fc-popover ' + (options.className || ''),
+ style: {
+ top: '0',
+ left: '0'
+ }
+ });
+ if (typeof options.content === 'function') {
+ options.content(el);
+ }
+ options.parentEl.appendChild(el);
+ // when a click happens on anything inside with a 'fc-close' className, hide the popover
+ core.listenBySelector(el, 'click', '.fc-close', function (ev) {
+ _this.hide();
+ });
+ if (options.autoHide) {
+ document.addEventListener('mousedown', this.documentMousedown);
+ }
+ };
+ // Hides and unregisters any handlers
+ Popover.prototype.destroy = function () {
+ this.hide();
+ if (this.el) {
+ core.removeElement(this.el);
+ this.el = null;
+ }
+ document.removeEventListener('mousedown', this.documentMousedown);
+ };
+ // Positions the popover optimally, using the top/left/right options
+ Popover.prototype.position = function () {
+ var options = this.options;
+ var el = this.el;
+ var elDims = el.getBoundingClientRect(); // only used for width,height
+ var origin = core.computeRect(el.offsetParent);
+ var clippingRect = core.computeClippingRect(options.parentEl);
+ var top; // the "position" (not "offset") values for the popover
+ var left; //
+ // compute top and left
+ top = options.top || 0;
+ if (options.left !== undefined) {
+ left = options.left;
+ }
+ else if (options.right !== undefined) {
+ left = options.right - elDims.width; // derive the left value from the right value
+ }
+ else {
+ left = 0;
+ }
+ // constrain to the view port. if constrained by two edges, give precedence to top/left
+ top = Math.min(top, clippingRect.bottom - elDims.height - this.margin);
+ top = Math.max(top, clippingRect.top + this.margin);
+ left = Math.min(left, clippingRect.right - elDims.width - this.margin);
+ left = Math.max(left, clippingRect.left + this.margin);
+ core.applyStyle(el, {
+ top: top - origin.top,
+ left: left - origin.left
+ });
+ };
+ // Triggers a callback. Calls a function in the option hash of the same name.
+ // Arguments beyond the first `name` are forwarded on.
+ // TODO: better code reuse for this. Repeat code
+ // can kill this???
+ Popover.prototype.trigger = function (name) {
+ if (this.options[name]) {
+ this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
+ }
+ };
+ return Popover;
+ }());
+
+ /* Event-rendering methods for the DayGrid class
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // "Simple" is bad a name. has nothing to do with SimpleDayGrid
+ var SimpleDayGridEventRenderer = /** @class */ (function (_super) {
+ __extends(SimpleDayGridEventRenderer, _super);
+ function SimpleDayGridEventRenderer() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ // Builds the HTML to be used for the default element for an individual segment
+ SimpleDayGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
+ var options = this.context.options;
+ var eventRange = seg.eventRange;
+ var eventDef = eventRange.def;
+ var eventUi = eventRange.ui;
+ var allDay = eventDef.allDay;
+ var isDraggable = eventUi.startEditable;
+ var isResizableFromStart = allDay && seg.isStart && eventUi.durationEditable && options.eventResizableFromStart;
+ var isResizableFromEnd = allDay && seg.isEnd && eventUi.durationEditable;
+ var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
+ var skinCss = core.cssToStr(this.getSkinCss(eventUi));
+ var timeHtml = '';
+ var timeText;
+ var titleHtml;
+ classes.unshift('fc-day-grid-event', 'fc-h-event');
+ // Only display a timed events time if it is the starting segment
+ if (seg.isStart) {
+ timeText = this.getTimeText(eventRange);
+ if (timeText) {
+ timeHtml = '<span class="fc-time">' + core.htmlEscape(timeText) + '</span>';
+ }
+ }
+ titleHtml =
+ '<span class="fc-title">' +
+ (core.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
+ '</span>';
+ return '<a class="' + classes.join(' ') + '"' +
+ (eventDef.url ?
+ ' href="' + core.htmlEscape(eventDef.url) + '"' :
+ '') +
+ (skinCss ?
+ ' style="' + skinCss + '"' :
+ '') +
+ '>' +
+ '<div class="fc-content">' +
+ (options.dir === 'rtl' ?
+ titleHtml + ' ' + timeHtml : // put a natural space in between
+ timeHtml + ' ' + titleHtml //
+ ) +
+ '</div>' +
+ (isResizableFromStart ?
+ '<div class="fc-resizer fc-start-resizer"></div>' :
+ '') +
+ (isResizableFromEnd ?
+ '<div class="fc-resizer fc-end-resizer"></div>' :
+ '') +
+ '</a>';
+ };
+ // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
+ SimpleDayGridEventRenderer.prototype.computeEventTimeFormat = function () {
+ return {
+ hour: 'numeric',
+ minute: '2-digit',
+ omitZeroMinute: true,
+ meridiem: 'narrow'
+ };
+ };
+ SimpleDayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
+ return false; // TODO: somehow consider the originating DayGrid's column count
+ };
+ return SimpleDayGridEventRenderer;
+ }(core.FgEventRenderer));
+
+ /* Event-rendering methods for the DayGrid class
+ ----------------------------------------------------------------------------------------------------------------------*/
+ var DayGridEventRenderer = /** @class */ (function (_super) {
+ __extends(DayGridEventRenderer, _super);
+ function DayGridEventRenderer(dayGrid) {
+ var _this = _super.call(this, dayGrid.context) || this;
+ _this.dayGrid = dayGrid;
+ return _this;
+ }
+ // Renders the given foreground event segments onto the grid
+ DayGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
+ var rowStructs = this.rowStructs = this.renderSegRows(segs);
+ // append to each row's content skeleton
+ this.dayGrid.rowEls.forEach(function (rowNode, i) {
+ rowNode.querySelector('.fc-content-skeleton > table').appendChild(rowStructs[i].tbodyEl);
+ });
+ // removes the "more.." events popover
+ if (!mirrorInfo) {
+ this.dayGrid.removeSegPopover();
+ }
+ };
+ // Unrenders all currently rendered foreground event segments
+ DayGridEventRenderer.prototype.detachSegs = function () {
+ var rowStructs = this.rowStructs || [];
+ var rowStruct;
+ while ((rowStruct = rowStructs.pop())) {
+ core.removeElement(rowStruct.tbodyEl);
+ }
+ this.rowStructs = null;
+ };
+ // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
+ // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
+ // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
+ DayGridEventRenderer.prototype.renderSegRows = function (segs) {
+ var rowStructs = [];
+ var segRows;
+ var row;
+ segRows = this.groupSegRows(segs); // group into nested arrays
+ // iterate each row of segment groupings
+ for (row = 0; row < segRows.length; row++) {
+ rowStructs.push(this.renderSegRow(row, segRows[row]));
+ }
+ return rowStructs;
+ };
+ // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
+ // the segments. Returns object with a bunch of internal data about how the render was calculated.
+ // NOTE: modifies rowSegs
+ DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
+ var dayGrid = this.dayGrid;
+ var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
+ var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
+ var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
+ var tbody = document.createElement('tbody');
+ var segMatrix = []; // lookup for which segments are rendered into which level+col cells
+ var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
+ var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
+ var i;
+ var levelSegs;
+ var col;
+ var tr;
+ var j;
+ var seg;
+ var td;
+ // populates empty cells from the current column (`col`) to `endCol`
+ function emptyCellsUntil(endCol) {
+ while (col < endCol) {
+ // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
+ td = (loneCellMatrix[i - 1] || [])[col];
+ if (td) {
+ td.rowSpan = (td.rowSpan || 1) + 1;
+ }
+ else {
+ td = document.createElement('td');
+ tr.appendChild(td);
+ }
+ cellMatrix[i][col] = td;
+ loneCellMatrix[i][col] = td;
+ col++;
+ }
+ }
+ for (i = 0; i < levelCnt; i++) { // iterate through all levels
+ levelSegs = segLevels[i];
+ col = 0;
+ tr = document.createElement('tr');
+ segMatrix.push([]);
+ cellMatrix.push([]);
+ loneCellMatrix.push([]);
+ // levelCnt might be 1 even though there are no actual levels. protect against this.
+ // this single empty row is useful for styling.
+ if (levelSegs) {
+ for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
+ seg = levelSegs[j];
+ var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
+ var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
+ emptyCellsUntil(leftCol);
+ // create a container that occupies or more columns. append the event element.
+ td = core.createElement('td', { className: 'fc-event-container' }, seg.el);
+ if (leftCol !== rightCol) {
+ td.colSpan = rightCol - leftCol + 1;
+ }
+ else { // a single-column segment
+ loneCellMatrix[i][col] = td;
+ }
+ while (col <= rightCol) {
+ cellMatrix[i][col] = td;
+ segMatrix[i][col] = seg;
+ col++;
+ }
+ tr.appendChild(td);
+ }
+ }
+ emptyCellsUntil(colCnt); // finish off the row
+ var introHtml = dayGrid.renderProps.renderIntroHtml();
+ if (introHtml) {
+ if (dayGrid.isRtl) {
+ core.appendToElement(tr, introHtml);
+ }
+ else {
+ core.prependToElement(tr, introHtml);
+ }
+ }
+ tbody.appendChild(tr);
+ }
+ return {
+ row: row,
+ tbodyEl: tbody,
+ cellMatrix: cellMatrix,
+ segMatrix: segMatrix,
+ segLevels: segLevels,
+ segs: rowSegs
+ };
+ };
+ // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
+ // NOTE: modifies segs
+ DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
+ var _a = this.dayGrid, isRtl = _a.isRtl, colCnt = _a.colCnt;
+ var levels = [];
+ var i;
+ var seg;
+ var j;
+ // Give preference to elements with certain criteria, so they have
+ // a chance to be closer to the top.
+ segs = this.sortEventSegs(segs);
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
+ for (j = 0; j < levels.length; j++) {
+ if (!isDaySegCollision(seg, levels[j])) {
+ break;
+ }
+ }
+ // `j` now holds the desired subrow index
+ seg.level = j;
+ seg.leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; // for sorting only
+ seg.rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol // for sorting only
+ ;
+ (levels[j] || (levels[j] = [])).push(seg);
+ }
+ // order segments left-to-right. very important if calendar is RTL
+ for (j = 0; j < levels.length; j++) {
+ levels[j].sort(compareDaySegCols);
+ }
+ return levels;
+ };
+ // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
+ DayGridEventRenderer.prototype.groupSegRows = function (segs) {
+ var segRows = [];
+ var i;
+ for (i = 0; i < this.dayGrid.rowCnt; i++) {
+ segRows.push([]);
+ }
+ for (i = 0; i < segs.length; i++) {
+ segRows[segs[i].row].push(segs[i]);
+ }
+ return segRows;
+ };
+ // Computes a default `displayEventEnd` value if one is not expliclty defined
+ DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
+ return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
+ };
+ return DayGridEventRenderer;
+ }(SimpleDayGridEventRenderer));
+ // Computes whether two segments' columns collide. They are assumed to be in the same row.
+ function isDaySegCollision(seg, otherSegs) {
+ var i;
+ var otherSeg;
+ for (i = 0; i < otherSegs.length; i++) {
+ otherSeg = otherSegs[i];
+ if (otherSeg.firstCol <= seg.lastCol &&
+ otherSeg.lastCol >= seg.firstCol) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // A cmp function for determining the leftmost event
+ function compareDaySegCols(a, b) {
+ return a.leftCol - b.leftCol;
+ }
+
+ var DayGridMirrorRenderer = /** @class */ (function (_super) {
+ __extends(DayGridMirrorRenderer, _super);
+ function DayGridMirrorRenderer() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ DayGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
+ var sourceSeg = mirrorInfo.sourceSeg;
+ var rowStructs = this.rowStructs = this.renderSegRows(segs);
+ // inject each new event skeleton into each associated row
+ this.dayGrid.rowEls.forEach(function (rowNode, row) {
+ var skeletonEl = core.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>'); // will be absolutely positioned
+ var skeletonTopEl;
+ var skeletonTop;
+ // If there is an original segment, match the top position. Otherwise, put it at the row's top level
+ if (sourceSeg && sourceSeg.row === row) {
+ skeletonTopEl = sourceSeg.el;
+ }
+ else {
+ skeletonTopEl = rowNode.querySelector('.fc-content-skeleton tbody');
+ if (!skeletonTopEl) { // when no events
+ skeletonTopEl = rowNode.querySelector('.fc-content-skeleton table');
+ }
+ }
+ skeletonTop = skeletonTopEl.getBoundingClientRect().top -
+ rowNode.getBoundingClientRect().top; // the offsetParent origin
+ skeletonEl.style.top = skeletonTop + 'px';
+ skeletonEl.querySelector('table').appendChild(rowStructs[row].tbodyEl);
+ rowNode.appendChild(skeletonEl);
+ });
+ };
+ return DayGridMirrorRenderer;
+ }(DayGridEventRenderer));
+
+ var DayGridFillRenderer = /** @class */ (function (_super) {
+ __extends(DayGridFillRenderer, _super);
+ function DayGridFillRenderer(dayGrid) {
+ var _this = _super.call(this, dayGrid.context) || this;
+ _this.fillSegTag = 'td'; // override the default tag name
+ _this.dayGrid = dayGrid;
+ return _this;
+ }
+ DayGridFillRenderer.prototype.renderSegs = function (type, segs) {
+ // don't render timed background events
+ if (type === 'bgEvent') {
+ segs = segs.filter(function (seg) {
+ return seg.eventRange.def.allDay;
+ });
+ }
+ _super.prototype.renderSegs.call(this, type, segs);
+ };
+ DayGridFillRenderer.prototype.attachSegs = function (type, segs) {
+ var els = [];
+ var i;
+ var seg;
+ var skeletonEl;
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ skeletonEl = this.renderFillRow(type, seg);
+ this.dayGrid.rowEls[seg.row].appendChild(skeletonEl);
+ els.push(skeletonEl);
+ }
+ return els;
+ };
+ // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
+ DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
+ var dayGrid = this.dayGrid;
+ var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
+ var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
+ var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
+ var startCol = leftCol;
+ var endCol = rightCol + 1;
+ var className;
+ var skeletonEl;
+ var trEl;
+ if (type === 'businessHours') {
+ className = 'bgevent';
+ }
+ else {
+ className = type.toLowerCase();
+ }
+ skeletonEl = core.htmlToElement('<div class="fc-' + className + '-skeleton">' +
+ '<table><tr></tr></table>' +
+ '</div>');
+ trEl = skeletonEl.getElementsByTagName('tr')[0];
+ if (startCol > 0) {
+ core.appendToElement(trEl,
+ // will create (startCol + 1) td's
+ new Array(startCol + 1).join('<td></td>'));
+ }
+ seg.el.colSpan = endCol - startCol;
+ trEl.appendChild(seg.el);
+ if (endCol < colCnt) {
+ core.appendToElement(trEl,
+ // will create (colCnt - endCol) td's
+ new Array(colCnt - endCol + 1).join('<td></td>'));
+ }
+ var introHtml = dayGrid.renderProps.renderIntroHtml();
+ if (introHtml) {
+ if (dayGrid.isRtl) {
+ core.appendToElement(trEl, introHtml);
+ }
+ else {
+ core.prependToElement(trEl, introHtml);
+ }
+ }
+ return skeletonEl;
+ };
+ return DayGridFillRenderer;
+ }(core.FillRenderer));
+
+ var DayTile = /** @class */ (function (_super) {
+ __extends(DayTile, _super);
+ function DayTile(context, el) {
+ var _this = _super.call(this, context, el) || this;
+ var eventRenderer = _this.eventRenderer = new DayTileEventRenderer(_this);
+ var renderFrame = _this.renderFrame = core.memoizeRendering(_this._renderFrame);
+ _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderFrame]);
+ _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
+ _this.renderEventDrag = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
+ _this.renderEventResize = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
+ context.calendar.registerInteractiveComponent(_this, {
+ el: _this.el,
+ useEventCenter: false
+ });
+ return _this;
+ }
+ DayTile.prototype.render = function (props) {
+ this.renderFrame(props.date);
+ this.renderFgEvents(props.fgSegs);
+ this.renderEventSelection(props.eventSelection);
+ this.renderEventDrag(props.eventDragInstances);
+ this.renderEventResize(props.eventResizeInstances);
+ };
+ DayTile.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.renderFrame.unrender(); // should unrender everything else
+ this.calendar.unregisterInteractiveComponent(this);
+ };
+ DayTile.prototype._renderFrame = function (date) {
+ var _a = this, theme = _a.theme, dateEnv = _a.dateEnv;
+ var title = dateEnv.format(date, core.createFormatter(this.opt('dayPopoverFormat')) // TODO: cache
+ );
+ this.el.innerHTML =
+ '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
+ '<span class="fc-title">' +
+ core.htmlEscape(title) +
+ '</span>' +
+ '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
+ '</div>' +
+ '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
+ '<div class="fc-event-container"></div>' +
+ '</div>';
+ this.segContainerEl = this.el.querySelector('.fc-event-container');
+ };
+ DayTile.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
+ var date = this.props.date; // HACK
+ if (positionLeft < elWidth && positionTop < elHeight) {
+ return {
+ component: this,
+ dateSpan: {
+ allDay: true,
+ range: { start: date, end: core.addDays(date, 1) }
+ },
+ dayEl: this.el,
+ rect: {
+ left: 0,
+ top: 0,
+ right: elWidth,
+ bottom: elHeight
+ },
+ layer: 1
+ };
+ }
+ };
+ return DayTile;
+ }(core.DateComponent));
+ var DayTileEventRenderer = /** @class */ (function (_super) {
+ __extends(DayTileEventRenderer, _super);
+ function DayTileEventRenderer(dayTile) {
+ var _this = _super.call(this, dayTile.context) || this;
+ _this.dayTile = dayTile;
+ return _this;
+ }
+ DayTileEventRenderer.prototype.attachSegs = function (segs) {
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+ var seg = segs_1[_i];
+ this.dayTile.segContainerEl.appendChild(seg.el);
+ }
+ };
+ DayTileEventRenderer.prototype.detachSegs = function (segs) {
+ for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
+ var seg = segs_2[_i];
+ core.removeElement(seg.el);
+ }
+ };
+ return DayTileEventRenderer;
+ }(SimpleDayGridEventRenderer));
+
+ var DayBgRow = /** @class */ (function () {
+ function DayBgRow(context) {
+ this.context = context;
+ }
+ DayBgRow.prototype.renderHtml = function (props) {
+ var parts = [];
+ if (props.renderIntroHtml) {
+ parts.push(props.renderIntroHtml());
+ }
+ for (var _i = 0, _a = props.cells; _i < _a.length; _i++) {
+ var cell = _a[_i];
+ parts.push(renderCellHtml(cell.date, props.dateProfile, this.context, cell.htmlAttrs));
+ }
+ if (!props.cells.length) {
+ parts.push('<td class="fc-day ' + this.context.theme.getClass('widgetContent') + '"></td>');
+ }
+ if (this.context.options.dir === 'rtl') {
+ parts.reverse();
+ }
+ return '<tr>' + parts.join('') + '</tr>';
+ };
+ return DayBgRow;
+ }());
+ function renderCellHtml(date, dateProfile, context, otherAttrs) {
+ var dateEnv = context.dateEnv, theme = context.theme;
+ var isDateValid = core.rangeContainsMarker(dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
+ var classes = core.getDayClasses(date, dateProfile, context);
+ classes.unshift('fc-day', theme.getClass('widgetContent'));
+ return '<td class="' + classes.join(' ') + '"' +
+ (isDateValid ?
+ ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
+ '') +
+ (otherAttrs ?
+ ' ' + otherAttrs :
+ '') +
+ '></td>';
+ }
+
+ var DAY_NUM_FORMAT = core.createFormatter({ day: 'numeric' });
+ var WEEK_NUM_FORMAT = core.createFormatter({ week: 'numeric' });
+ var DayGrid = /** @class */ (function (_super) {
+ __extends(DayGrid, _super);
+ function DayGrid(context, el, renderProps) {
+ var _this = _super.call(this, context, el) || this;
+ _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
+ _this.isCellSizesDirty = false;
+ var eventRenderer = _this.eventRenderer = new DayGridEventRenderer(_this);
+ var fillRenderer = _this.fillRenderer = new DayGridFillRenderer(_this);
+ _this.mirrorRenderer = new DayGridMirrorRenderer(_this);
+ var renderCells = _this.renderCells = core.memoizeRendering(_this._renderCells, _this._unrenderCells);
+ _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderCells]);
+ _this.renderDateSelection = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'highlight'), fillRenderer.unrender.bind(fillRenderer, 'highlight'), [renderCells]);
+ _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderCells]);
+ _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderCells]);
+ _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
+ _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderCells]);
+ _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderCells]);
+ _this.renderProps = renderProps;
+ return _this;
+ }
+ DayGrid.prototype.render = function (props) {
+ var cells = props.cells;
+ this.rowCnt = cells.length;
+ this.colCnt = cells[0].length;
+ this.renderCells(cells, props.isRigid);
+ this.renderBusinessHours(props.businessHourSegs);
+ this.renderDateSelection(props.dateSelectionSegs);
+ this.renderBgEvents(props.bgEventSegs);
+ this.renderFgEvents(props.fgEventSegs);
+ this.renderEventSelection(props.eventSelection);
+ this.renderEventDrag(props.eventDrag);
+ this.renderEventResize(props.eventResize);
+ if (this.segPopoverTile) {
+ this.updateSegPopoverTile();
+ }
+ };
+ DayGrid.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.renderCells.unrender(); // will unrender everything else
+ };
+ DayGrid.prototype.getCellRange = function (row, col) {
+ var start = this.props.cells[row][col].date;
+ var end = core.addDays(start, 1);
+ return { start: start, end: end };
+ };
+ DayGrid.prototype.updateSegPopoverTile = function (date, segs) {
+ var ownProps = this.props;
+ this.segPopoverTile.receiveProps({
+ date: date || this.segPopoverTile.props.date,
+ fgSegs: segs || this.segPopoverTile.props.fgSegs,
+ eventSelection: ownProps.eventSelection,
+ eventDragInstances: ownProps.eventDrag ? ownProps.eventDrag.affectedInstances : null,
+ eventResizeInstances: ownProps.eventResize ? ownProps.eventResize.affectedInstances : null
+ });
+ };
+ /* Date Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype._renderCells = function (cells, isRigid) {
+ var _a = this, view = _a.view, dateEnv = _a.dateEnv;
+ var _b = this, rowCnt = _b.rowCnt, colCnt = _b.colCnt;
+ var html = '';
+ var row;
+ var col;
+ for (row = 0; row < rowCnt; row++) {
+ html += this.renderDayRowHtml(row, isRigid);
+ }
+ this.el.innerHTML = html;
+ this.rowEls = core.findElements(this.el, '.fc-row');
+ this.cellEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
+ if (this.isRtl) {
+ this.cellEls.reverse();
+ }
+ this.rowPositions = new core.PositionCache(this.el, this.rowEls, false, true // vertical
+ );
+ this.colPositions = new core.PositionCache(this.el, this.cellEls.slice(0, colCnt), // only the first row
+ true, false // horizontal
+ );
+ // trigger dayRender with each cell's element
+ for (row = 0; row < rowCnt; row++) {
+ for (col = 0; col < colCnt; col++) {
+ this.publiclyTrigger('dayRender', [
+ {
+ date: dateEnv.toDate(cells[row][col].date),
+ el: this.getCellEl(row, col),
+ view: view
+ }
+ ]);
+ }
+ }
+ this.isCellSizesDirty = true;
+ };
+ DayGrid.prototype._unrenderCells = function () {
+ this.removeSegPopover();
+ };
+ // Generates the HTML for a single row, which is a div that wraps a table.
+ // `row` is the row number.
+ DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
+ var theme = this.theme;
+ var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
+ if (isRigid) {
+ classes.push('fc-rigid');
+ }
+ var bgRow = new DayBgRow(this.context);
+ return '' +
+ '<div class="' + classes.join(' ') + '">' +
+ '<div class="fc-bg">' +
+ '<table class="' + theme.getClass('tableGrid') + '">' +
+ bgRow.renderHtml({
+ cells: this.props.cells[row],
+ dateProfile: this.props.dateProfile,
+ renderIntroHtml: this.renderProps.renderBgIntroHtml
+ }) +
+ '</table>' +
+ '</div>' +
+ '<div class="fc-content-skeleton">' +
+ '<table>' +
+ (this.getIsNumbersVisible() ?
+ '<thead>' +
+ this.renderNumberTrHtml(row) +
+ '</thead>' :
+ '') +
+ '</table>' +
+ '</div>' +
+ '</div>';
+ };
+ DayGrid.prototype.getIsNumbersVisible = function () {
+ return this.getIsDayNumbersVisible() ||
+ this.renderProps.cellWeekNumbersVisible ||
+ this.renderProps.colWeekNumbersVisible;
+ };
+ DayGrid.prototype.getIsDayNumbersVisible = function () {
+ return this.rowCnt > 1;
+ };
+ /* Grid Number Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype.renderNumberTrHtml = function (row) {
+ var intro = this.renderProps.renderNumberIntroHtml(row, this);
+ return '' +
+ '<tr>' +
+ (this.isRtl ? '' : intro) +
+ this.renderNumberCellsHtml(row) +
+ (this.isRtl ? intro : '') +
+ '</tr>';
+ };
+ DayGrid.prototype.renderNumberCellsHtml = function (row) {
+ var htmls = [];
+ var col;
+ var date;
+ for (col = 0; col < this.colCnt; col++) {
+ date = this.props.cells[row][col].date;
+ htmls.push(this.renderNumberCellHtml(date));
+ }
+ if (this.isRtl) {
+ htmls.reverse();
+ }
+ return htmls.join('');
+ };
+ // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
+ // The number row will only exist if either day numbers or week numbers are turned on.
+ DayGrid.prototype.renderNumberCellHtml = function (date) {
+ var _a = this, view = _a.view, dateEnv = _a.dateEnv;
+ var html = '';
+ var isDateValid = core.rangeContainsMarker(this.props.dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
+ var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
+ var classes;
+ var weekCalcFirstDow;
+ if (!isDayNumberVisible && !this.renderProps.cellWeekNumbersVisible) {
+ // no numbers in day cell (week number must be along the side)
+ return '<td></td>'; // will create an empty space above events :(
+ }
+ classes = core.getDayClasses(date, this.props.dateProfile, this.context);
+ classes.unshift('fc-day-top');
+ if (this.renderProps.cellWeekNumbersVisible) {
+ weekCalcFirstDow = dateEnv.weekDow;
+ }
+ html += '<td class="' + classes.join(' ') + '"' +
+ (isDateValid ?
+ ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
+ '') +
+ '>';
+ if (this.renderProps.cellWeekNumbersVisible && (date.getUTCDay() === weekCalcFirstDow)) {
+ html += core.buildGotoAnchorHtml(view, { date: date, type: 'week' }, { 'class': 'fc-week-number' }, dateEnv.format(date, WEEK_NUM_FORMAT) // inner HTML
+ );
+ }
+ if (isDayNumberVisible) {
+ html += core.buildGotoAnchorHtml(view, date, { 'class': 'fc-day-number' }, dateEnv.format(date, DAY_NUM_FORMAT) // inner HTML
+ );
+ }
+ html += '</td>';
+ return html;
+ };
+ /* Sizing
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype.updateSize = function (isResize) {
+ var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
+ if (isResize || this.isCellSizesDirty) {
+ this.buildColPositions();
+ this.buildRowPositions();
+ this.isCellSizesDirty = false;
+ }
+ fillRenderer.computeSizes(isResize);
+ eventRenderer.computeSizes(isResize);
+ mirrorRenderer.computeSizes(isResize);
+ fillRenderer.assignSizes(isResize);
+ eventRenderer.assignSizes(isResize);
+ mirrorRenderer.assignSizes(isResize);
+ };
+ DayGrid.prototype.buildColPositions = function () {
+ this.colPositions.build();
+ };
+ DayGrid.prototype.buildRowPositions = function () {
+ this.rowPositions.build();
+ this.rowPositions.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
+ };
+ /* Hit System
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype.positionToHit = function (leftPosition, topPosition) {
+ var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
+ var col = colPositions.leftToIndex(leftPosition);
+ var row = rowPositions.topToIndex(topPosition);
+ if (row != null && col != null) {
+ return {
+ row: row,
+ col: col,
+ dateSpan: {
+ range: this.getCellRange(row, col),
+ allDay: true
+ },
+ dayEl: this.getCellEl(row, col),
+ relativeRect: {
+ left: colPositions.lefts[col],
+ right: colPositions.rights[col],
+ top: rowPositions.tops[row],
+ bottom: rowPositions.bottoms[row]
+ }
+ };
+ }
+ };
+ /* Cell System
+ ------------------------------------------------------------------------------------------------------------------*/
+ // FYI: the first column is the leftmost column, regardless of date
+ DayGrid.prototype.getCellEl = function (row, col) {
+ return this.cellEls[row * this.colCnt + col];
+ };
+ /* Event Drag Visualization
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype._renderEventDrag = function (state) {
+ if (state) {
+ this.eventRenderer.hideByHash(state.affectedInstances);
+ this.fillRenderer.renderSegs('highlight', state.segs);
+ }
+ };
+ DayGrid.prototype._unrenderEventDrag = function (state) {
+ if (state) {
+ this.eventRenderer.showByHash(state.affectedInstances);
+ this.fillRenderer.unrender('highlight');
+ }
+ };
+ /* Event Resize Visualization
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype._renderEventResize = function (state) {
+ if (state) {
+ this.eventRenderer.hideByHash(state.affectedInstances);
+ this.fillRenderer.renderSegs('highlight', state.segs);
+ this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
+ }
+ };
+ DayGrid.prototype._unrenderEventResize = function (state) {
+ if (state) {
+ this.eventRenderer.showByHash(state.affectedInstances);
+ this.fillRenderer.unrender('highlight');
+ this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
+ }
+ };
+ /* More+ Link Popover
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGrid.prototype.removeSegPopover = function () {
+ if (this.segPopover) {
+ this.segPopover.hide(); // in handler, will call segPopover's removeElement
+ }
+ };
+ // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
+ // `levelLimit` can be false (don't limit), a number, or true (should be computed).
+ DayGrid.prototype.limitRows = function (levelLimit) {
+ var rowStructs = this.eventRenderer.rowStructs || [];
+ var row; // row #
+ var rowLevelLimit;
+ for (row = 0; row < rowStructs.length; row++) {
+ this.unlimitRow(row);
+ if (!levelLimit) {
+ rowLevelLimit = false;
+ }
+ else if (typeof levelLimit === 'number') {
+ rowLevelLimit = levelLimit;
+ }
+ else {
+ rowLevelLimit = this.computeRowLevelLimit(row);
+ }
+ if (rowLevelLimit !== false) {
+ this.limitRow(row, rowLevelLimit);
+ }
+ }
+ };
+ // Computes the number of levels a row will accomodate without going outside its bounds.
+ // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
+ // `row` is the row number.
+ DayGrid.prototype.computeRowLevelLimit = function (row) {
+ var rowEl = this.rowEls[row]; // the containing "fake" row div
+ var rowBottom = rowEl.getBoundingClientRect().bottom; // relative to viewport!
+ var trEls = core.findChildren(this.eventRenderer.rowStructs[row].tbodyEl);
+ var i;
+ var trEl;
+ // Reveal one level <tr> at a time and stop when we find one out of bounds
+ for (i = 0; i < trEls.length; i++) {
+ trEl = trEls[i];
+ trEl.classList.remove('fc-limited'); // reset to original state (reveal)
+ if (trEl.getBoundingClientRect().bottom > rowBottom) {
+ return i;
+ }
+ }
+ return false; // should not limit at all
+ };
+ // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
+ // `row` is the row number.
+ // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
+ DayGrid.prototype.limitRow = function (row, levelLimit) {
+ var _this = this;
+ var _a = this, colCnt = _a.colCnt, isRtl = _a.isRtl;
+ var rowStruct = this.eventRenderer.rowStructs[row];
+ var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
+ var col = 0; // col #, left-to-right (not chronologically)
+ var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
+ var cellMatrix; // a matrix (by level, then column) of all <td> elements in the row
+ var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
+ var i;
+ var seg;
+ var segsBelow; // array of segment objects below `seg` in the current `col`
+ var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
+ var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
+ var td;
+ var rowSpan;
+ var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
+ var j;
+ var moreTd;
+ var moreWrap;
+ var moreLink;
+ // Iterates through empty level cells and places "more" links inside if need be
+ var emptyCellsUntil = function (endCol) {
+ while (col < endCol) {
+ segsBelow = _this.getCellSegs(row, col, levelLimit);
+ if (segsBelow.length) {
+ td = cellMatrix[levelLimit - 1][col];
+ moreLink = _this.renderMoreLink(row, col, segsBelow);
+ moreWrap = core.createElement('div', null, moreLink);
+ td.appendChild(moreWrap);
+ moreNodes.push(moreWrap[0]);
+ }
+ col++;
+ }
+ };
+ if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
+ levelSegs = rowStruct.segLevels[levelLimit - 1];
+ cellMatrix = rowStruct.cellMatrix;
+ limitedNodes = core.findChildren(rowStruct.tbodyEl).slice(levelLimit); // get level <tr> elements past the limit
+ limitedNodes.forEach(function (node) {
+ node.classList.add('fc-limited'); // hide elements and get a simple DOM-nodes array
+ });
+ // iterate though segments in the last allowable level
+ for (i = 0; i < levelSegs.length; i++) {
+ seg = levelSegs[i];
+ var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
+ var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
+ emptyCellsUntil(leftCol); // process empty cells before the segment
+ // determine *all* segments below `seg` that occupy the same columns
+ colSegsBelow = [];
+ totalSegsBelow = 0;
+ while (col <= rightCol) {
+ segsBelow = this.getCellSegs(row, col, levelLimit);
+ colSegsBelow.push(segsBelow);
+ totalSegsBelow += segsBelow.length;
+ col++;
+ }
+ if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
+ td = cellMatrix[levelLimit - 1][leftCol]; // the segment's parent cell
+ rowSpan = td.rowSpan || 1;
+ segMoreNodes = [];
+ // make a replacement <td> for each column the segment occupies. will be one for each colspan
+ for (j = 0; j < colSegsBelow.length; j++) {
+ moreTd = core.createElement('td', { className: 'fc-more-cell', rowSpan: rowSpan });
+ segsBelow = colSegsBelow[j];
+ moreLink = this.renderMoreLink(row, leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
+ );
+ moreWrap = core.createElement('div', null, moreLink);
+ moreTd.appendChild(moreWrap);
+ segMoreNodes.push(moreTd);
+ moreNodes.push(moreTd);
+ }
+ td.classList.add('fc-limited');
+ core.insertAfterElement(td, segMoreNodes);
+ limitedNodes.push(td);
+ }
+ }
+ emptyCellsUntil(this.colCnt); // finish off the level
+ rowStruct.moreEls = moreNodes; // for easy undoing later
+ rowStruct.limitedEls = limitedNodes; // for easy undoing later
+ }
+ };
+ // Reveals all levels and removes all "more"-related elements for a grid's row.
+ // `row` is a row number.
+ DayGrid.prototype.unlimitRow = function (row) {
+ var rowStruct = this.eventRenderer.rowStructs[row];
+ if (rowStruct.moreEls) {
+ rowStruct.moreEls.forEach(core.removeElement);
+ rowStruct.moreEls = null;
+ }
+ if (rowStruct.limitedEls) {
+ rowStruct.limitedEls.forEach(function (limitedEl) {
+ limitedEl.classList.remove('fc-limited');
+ });
+ rowStruct.limitedEls = null;
+ }
+ };
+ // Renders an <a> element that represents hidden event element for a cell.
+ // Responsible for attaching click handler as well.
+ DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
+ var _this = this;
+ var _a = this, view = _a.view, dateEnv = _a.dateEnv;
+ var a = core.createElement('a', { className: 'fc-more' });
+ a.innerText = this.getMoreLinkText(hiddenSegs.length);
+ a.addEventListener('click', function (ev) {
+ var clickOption = _this.opt('eventLimitClick');
+ var _col = _this.isRtl ? _this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
+ var date = _this.props.cells[row][_col].date;
+ var moreEl = ev.currentTarget;
+ var dayEl = _this.getCellEl(row, col);
+ var allSegs = _this.getCellSegs(row, col);
+ // rescope the segments to be within the cell's date
+ var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
+ var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
+ if (typeof clickOption === 'function') {
+ // the returned value can be an atomic option
+ clickOption = _this.publiclyTrigger('eventLimitClick', [
+ {
+ date: dateEnv.toDate(date),
+ allDay: true,
+ dayEl: dayEl,
+ moreEl: moreEl,
+ segs: reslicedAllSegs,
+ hiddenSegs: reslicedHiddenSegs,
+ jsEvent: ev,
+ view: view
+ }
+ ]);
+ }
+ if (clickOption === 'popover') {
+ _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
+ }
+ else if (typeof clickOption === 'string') { // a view name
+ view.calendar.zoomTo(date, clickOption);
+ }
+ });
+ return a;
+ };
+ // Reveals the popover that displays all events within a cell
+ DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
+ var _this = this;
+ var _a = this, calendar = _a.calendar, view = _a.view, theme = _a.theme;
+ var _col = this.isRtl ? this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
+ var moreWrap = moreLink.parentNode; // the <div> wrapper around the <a>
+ var topEl; // the element we want to match the top coordinate of
+ var options;
+ if (this.rowCnt === 1) {
+ topEl = view.el; // will cause the popover to cover any sort of header
+ }
+ else {
+ topEl = this.rowEls[row]; // will align with top of row
+ }
+ options = {
+ className: 'fc-more-popover ' + theme.getClass('popover'),
+ parentEl: view.el,
+ top: core.computeRect(topEl).top,
+ autoHide: true,
+ content: function (el) {
+ _this.segPopoverTile = new DayTile(_this.context, el);
+ _this.updateSegPopoverTile(_this.props.cells[row][_col].date, segs);
+ },
+ hide: function () {
+ _this.segPopoverTile.destroy();
+ _this.segPopoverTile = null;
+ _this.segPopover.destroy();
+ _this.segPopover = null;
+ }
+ };
+ // Determine horizontal coordinate.
+ // We use the moreWrap instead of the <td> to avoid border confusion.
+ if (this.isRtl) {
+ options.right = core.computeRect(moreWrap).right + 1; // +1 to be over cell border
+ }
+ else {
+ options.left = core.computeRect(moreWrap).left - 1; // -1 to be over cell border
+ }
+ this.segPopover = new Popover(options);
+ this.segPopover.show();
+ calendar.releaseAfterSizingTriggers(); // hack for eventPositioned
+ };
+ // Given the events within an array of segment objects, reslice them to be in a single day
+ DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
+ var dayStart = dayDate;
+ var dayEnd = core.addDays(dayStart, 1);
+ var dayRange = { start: dayStart, end: dayEnd };
+ var newSegs = [];
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+ var seg = segs_1[_i];
+ var eventRange = seg.eventRange;
+ var origRange = eventRange.range;
+ var slicedRange = core.intersectRanges(origRange, dayRange);
+ if (slicedRange) {
+ newSegs.push(__assign({}, seg, { eventRange: {
+ def: eventRange.def,
+ ui: __assign({}, eventRange.ui, { durationEditable: false }),
+ instance: eventRange.instance,
+ range: slicedRange
+ }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }));
+ }
+ }
+ return newSegs;
+ };
+ // Generates the text that should be inside a "more" link, given the number of events it represents
+ DayGrid.prototype.getMoreLinkText = function (num) {
+ var opt = this.opt('eventLimitText');
+ if (typeof opt === 'function') {
+ return opt(num);
+ }
+ else {
+ return '+' + num + ' ' + opt;
+ }
+ };
+ // Returns segments within a given cell.
+ // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
+ DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
+ var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
+ var level = startLevel || 0;
+ var segs = [];
+ var seg;
+ while (level < segMatrix.length) {
+ seg = segMatrix[level][col];
+ if (seg) {
+ segs.push(seg);
+ }
+ level++;
+ }
+ return segs;
+ };
+ return DayGrid;
+ }(core.DateComponent));
+
+ var WEEK_NUM_FORMAT$1 = core.createFormatter({ week: 'numeric' });
+ /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
+ // It is responsible for managing width/height.
+ var DayGridView = /** @class */ (function (_super) {
+ __extends(DayGridView, _super);
+ function DayGridView(context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
+ /* Header Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Generates the HTML that will go before the day-of week header cells
+ _this.renderHeadIntroHtml = function () {
+ var theme = _this.theme;
+ if (_this.colWeekNumbersVisible) {
+ return '' +
+ '<th class="fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.weekNumberStyleAttr() + '>' +
+ '<span>' + // needed for matchCellWidths
+ core.htmlEscape(_this.opt('weekLabel')) +
+ '</span>' +
+ '</th>';
+ }
+ return '';
+ };
+ /* Day Grid Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
+ _this.renderDayGridNumberIntroHtml = function (row, dayGrid) {
+ var dateEnv = _this.dateEnv;
+ var weekStart = dayGrid.props.cells[row][0].date;
+ if (_this.colWeekNumbersVisible) {
+ return '' +
+ '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '>' +
+ core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
+ _this, { date: weekStart, type: 'week', forceOff: dayGrid.colCnt === 1 }, dateEnv.format(weekStart, WEEK_NUM_FORMAT$1) // inner HTML
+ ) +
+ '</td>';
+ }
+ return '';
+ };
+ // Generates the HTML that goes before the day bg cells for each day-row
+ _this.renderDayGridBgIntroHtml = function () {
+ var theme = _this.theme;
+ if (_this.colWeekNumbersVisible) {
+ return '<td class="fc-week-number ' + theme.getClass('widgetContent') + '" ' + _this.weekNumberStyleAttr() + '></td>';
+ }
+ return '';
+ };
+ // Generates the HTML that goes before every other type of row generated by DayGrid.
+ // Affects mirror-skeleton and highlight-skeleton rows.
+ _this.renderDayGridIntroHtml = function () {
+ if (_this.colWeekNumbersVisible) {
+ return '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '></td>';
+ }
+ return '';
+ };
+ _this.el.classList.add('fc-dayGrid-view');
+ _this.el.innerHTML = _this.renderSkeletonHtml();
+ _this.scroller = new core.ScrollComponent('hidden', // overflow x
+ 'auto' // overflow y
+ );
+ var dayGridContainerEl = _this.scroller.el;
+ _this.el.querySelector('.fc-body > tr > td').appendChild(dayGridContainerEl);
+ dayGridContainerEl.classList.add('fc-day-grid-container');
+ var dayGridEl = core.createElement('div', { className: 'fc-day-grid' });
+ dayGridContainerEl.appendChild(dayGridEl);
+ var cellWeekNumbersVisible;
+ if (_this.opt('weekNumbers')) {
+ if (_this.opt('weekNumbersWithinDays')) {
+ cellWeekNumbersVisible = true;
+ _this.colWeekNumbersVisible = false;
+ }
+ else {
+ cellWeekNumbersVisible = false;
+ _this.colWeekNumbersVisible = true;
+ }
+ }
+ else {
+ _this.colWeekNumbersVisible = false;
+ cellWeekNumbersVisible = false;
+ }
+ _this.dayGrid = new DayGrid(_this.context, dayGridEl, {
+ renderNumberIntroHtml: _this.renderDayGridNumberIntroHtml,
+ renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
+ renderIntroHtml: _this.renderDayGridIntroHtml,
+ colWeekNumbersVisible: _this.colWeekNumbersVisible,
+ cellWeekNumbersVisible: cellWeekNumbersVisible
+ });
+ return _this;
+ }
+ DayGridView.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.dayGrid.destroy();
+ this.scroller.destroy();
+ };
+ // Builds the HTML skeleton for the view.
+ // The day-grid component will render inside of a container defined by this HTML.
+ DayGridView.prototype.renderSkeletonHtml = function () {
+ var theme = this.theme;
+ return '' +
+ '<table class="' + theme.getClass('tableGrid') + '">' +
+ (this.opt('columnHeader') ?
+ '<thead class="fc-head">' +
+ '<tr>' +
+ '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
+ '</tr>' +
+ '</thead>' :
+ '') +
+ '<tbody class="fc-body">' +
+ '<tr>' +
+ '<td class="' + theme.getClass('widgetContent') + '"></td>' +
+ '</tr>' +
+ '</tbody>' +
+ '</table>';
+ };
+ // Generates an HTML attribute string for setting the width of the week number column, if it is known
+ DayGridView.prototype.weekNumberStyleAttr = function () {
+ if (this.weekNumberWidth != null) {
+ return 'style="width:' + this.weekNumberWidth + 'px"';
+ }
+ return '';
+ };
+ // Determines whether each row should have a constant height
+ DayGridView.prototype.hasRigidRows = function () {
+ var eventLimit = this.opt('eventLimit');
+ return eventLimit && typeof eventLimit !== 'number';
+ };
+ /* Dimensions
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
+ _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
+ this.dayGrid.updateSize(isResize);
+ };
+ // Refreshes the horizontal dimensions of the view
+ DayGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
+ var dayGrid = this.dayGrid;
+ var eventLimit = this.opt('eventLimit');
+ var headRowEl = this.header ? this.header.el : null; // HACK
+ var scrollerHeight;
+ var scrollbarWidths;
+ // hack to give the view some height prior to dayGrid's columns being rendered
+ // TODO: separate setting height from scroller VS dayGrid.
+ if (!dayGrid.rowEls) {
+ if (!isAuto) {
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.scroller.setHeight(scrollerHeight);
+ }
+ return;
+ }
+ if (this.colWeekNumbersVisible) {
+ // Make sure all week number cells running down the side have the same width.
+ this.weekNumberWidth = core.matchCellWidths(core.findElements(this.el, '.fc-week-number'));
+ }
+ // reset all heights to be natural
+ this.scroller.clear();
+ if (headRowEl) {
+ core.uncompensateScroll(headRowEl);
+ }
+ dayGrid.removeSegPopover(); // kill the "more" popover if displayed
+ // is the event limit a constant level number?
+ if (eventLimit && typeof eventLimit === 'number') {
+ dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
+ }
+ // distribute the height to the rows
+ // (viewHeight is a "recommended" value if isAuto)
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.setGridHeight(scrollerHeight, isAuto);
+ // is the event limit dynamically calculated?
+ if (eventLimit && typeof eventLimit !== 'number') {
+ dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
+ }
+ if (!isAuto) { // should we force dimensions of the scroll container?
+ this.scroller.setHeight(scrollerHeight);
+ scrollbarWidths = this.scroller.getScrollbarWidths();
+ if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
+ if (headRowEl) {
+ core.compensateScroll(headRowEl, scrollbarWidths);
+ }
+ // doing the scrollbar compensation might have created text overflow which created more height. redo
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.scroller.setHeight(scrollerHeight);
+ }
+ // guarantees the same scrollbar widths
+ this.scroller.lockOverflow(scrollbarWidths);
+ }
+ };
+ // given a desired total height of the view, returns what the height of the scroller should be
+ DayGridView.prototype.computeScrollerHeight = function (viewHeight) {
+ return viewHeight -
+ core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+ };
+ // Sets the height of just the DayGrid component in this view
+ DayGridView.prototype.setGridHeight = function (height, isAuto) {
+ if (this.opt('monthMode')) {
+ // if auto, make the height of each row the height that it would be if there were 6 weeks
+ if (isAuto) {
+ height *= this.dayGrid.rowCnt / 6;
+ }
+ core.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
+ }
+ else {
+ if (isAuto) {
+ core.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
+ }
+ else {
+ core.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
+ }
+ }
+ };
+ /* Scroll
+ ------------------------------------------------------------------------------------------------------------------*/
+ DayGridView.prototype.computeInitialDateScroll = function () {
+ return { top: 0 };
+ };
+ DayGridView.prototype.queryDateScroll = function () {
+ return { top: this.scroller.getScrollTop() };
+ };
+ DayGridView.prototype.applyDateScroll = function (scroll) {
+ if (scroll.top !== undefined) {
+ this.scroller.setScrollTop(scroll.top);
+ }
+ };
+ return DayGridView;
+ }(core.View));
+ DayGridView.prototype.dateProfileGeneratorClass = DayGridDateProfileGenerator;
+
+ var SimpleDayGrid = /** @class */ (function (_super) {
+ __extends(SimpleDayGrid, _super);
+ function SimpleDayGrid(context, dayGrid) {
+ var _this = _super.call(this, context, dayGrid.el) || this;
+ _this.slicer = new DayGridSlicer();
+ _this.dayGrid = dayGrid;
+ context.calendar.registerInteractiveComponent(_this, { el: _this.dayGrid.el });
+ return _this;
+ }
+ SimpleDayGrid.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.calendar.unregisterInteractiveComponent(this);
+ };
+ SimpleDayGrid.prototype.render = function (props) {
+ var dayGrid = this.dayGrid;
+ var dateProfile = props.dateProfile, dayTable = props.dayTable;
+ dayGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable), { dateProfile: dateProfile, cells: dayTable.cells, isRigid: props.isRigid }));
+ };
+ SimpleDayGrid.prototype.queryHit = function (positionLeft, positionTop) {
+ var rawHit = this.dayGrid.positionToHit(positionLeft, positionTop);
+ if (rawHit) {
+ return {
+ component: this.dayGrid,
+ dateSpan: rawHit.dateSpan,
+ dayEl: rawHit.dayEl,
+ rect: {
+ left: rawHit.relativeRect.left,
+ right: rawHit.relativeRect.right,
+ top: rawHit.relativeRect.top,
+ bottom: rawHit.relativeRect.bottom
+ },
+ layer: 0
+ };
+ }
+ };
+ return SimpleDayGrid;
+ }(core.DateComponent));
+ var DayGridSlicer = /** @class */ (function (_super) {
+ __extends(DayGridSlicer, _super);
+ function DayGridSlicer() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ DayGridSlicer.prototype.sliceRange = function (dateRange, dayTable) {
+ return dayTable.sliceRange(dateRange);
+ };
+ return DayGridSlicer;
+ }(core.Slicer));
+
+ var DayGridView$1 = /** @class */ (function (_super) {
+ __extends(DayGridView, _super);
+ function DayGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
+ _this.buildDayTable = core.memoize(buildDayTable);
+ if (_this.opt('columnHeader')) {
+ _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
+ }
+ _this.simpleDayGrid = new SimpleDayGrid(_this.context, _this.dayGrid);
+ return _this;
+ }
+ DayGridView.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ if (this.header) {
+ this.header.destroy();
+ }
+ this.simpleDayGrid.destroy();
+ };
+ DayGridView.prototype.render = function (props) {
+ _super.prototype.render.call(this, props);
+ var dateProfile = this.props.dateProfile;
+ var dayTable = this.dayTable =
+ this.buildDayTable(dateProfile, this.dateProfileGenerator);
+ if (this.header) {
+ this.header.receiveProps({
+ dateProfile: dateProfile,
+ dates: dayTable.headerDates,
+ datesRepDistinctDays: dayTable.rowCnt === 1,
+ renderIntroHtml: this.renderHeadIntroHtml
+ });
+ }
+ this.simpleDayGrid.receiveProps({
+ dateProfile: dateProfile,
+ dayTable: dayTable,
+ businessHours: props.businessHours,
+ dateSelection: props.dateSelection,
+ eventStore: props.eventStore,
+ eventUiBases: props.eventUiBases,
+ eventSelection: props.eventSelection,
+ eventDrag: props.eventDrag,
+ eventResize: props.eventResize,
+ isRigid: this.hasRigidRows(),
+ nextDayThreshold: this.nextDayThreshold
+ });
+ };
+ return DayGridView;
+ }(DayGridView));
+ function buildDayTable(dateProfile, dateProfileGenerator) {
+ var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
+ return new core.DayTable(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
+ }
+
+ var main = core.createPlugin({
+ defaultView: 'dayGridMonth',
+ views: {
+ dayGrid: DayGridView$1,
+ dayGridDay: {
+ type: 'dayGrid',
+ duration: { days: 1 }
+ },
+ dayGridWeek: {
+ type: 'dayGrid',
+ duration: { weeks: 1 }
+ },
+ dayGridMonth: {
+ type: 'dayGrid',
+ duration: { months: 1 },
+ monthMode: true,
+ fixedWeekCount: true
+ }
+ }
+ });
+
+ exports.AbstractDayGridView = DayGridView;
+ exports.DayBgRow = DayBgRow;
+ exports.DayGrid = DayGrid;
+ exports.DayGridSlicer = DayGridSlicer;
+ exports.DayGridView = DayGridView$1;
+ exports.SimpleDayGrid = SimpleDayGrid;
+ exports.buildBasicDayTable = buildDayTable;
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/daygrid/main.min.css b/library/fullcalendar/packages/daygrid/main.min.css
new file mode 100644
index 000000000..75fd5cb88
--- /dev/null
+++ b/library/fullcalendar/packages/daygrid/main.min.css
@@ -0,0 +1,5 @@
+/*!
+FullCalendar Day Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/.fc-dayGridDay-view .fc-content-skeleton,.fc-dayGridWeek-view .fc-content-skeleton{padding-bottom:1em}.fc-dayGrid-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid{overflow:hidden}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-day-top.fc-other-month{opacity:.3}.fc-dayGrid-view .fc-day-number,.fc-dayGrid-view .fc-week-number{padding:2px}.fc-dayGrid-view th.fc-day-number,.fc-dayGrid-view th.fc-week-number{padding:0 2px}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number{float:right}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-day-number{float:left}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-week-number{float:left;border-radius:0 0 3px}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-week-number{float:right;border-radius:0 0 0 3px}.fc-dayGrid-view .fc-day-top .fc-week-number{min-width:1.5em;text-align:center;background-color:#f2f2f2;color:grey}.fc-dayGrid-view td.fc-week-number{text-align:center}.fc-dayGrid-view td.fc-week-number>*{display:inline-block;min-width:1.25em} \ No newline at end of file
diff --git a/library/fullcalendar/packages/daygrid/main.min.js b/library/fullcalendar/packages/daygrid/main.min.js
new file mode 100644
index 000000000..54b390012
--- /dev/null
+++ b/library/fullcalendar/packages/daygrid/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Day Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarDayGrid={},e.FullCalendar))}(this,function(e,t){"use strict";function r(e,t){function r(){this.constructor=e}l(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function n(e,t){var r,n;for(r=0;r<t.length;r++)if(n=t[r],n.firstCol<=e.lastCol&&n.lastCol>=e.firstCol)return!0;return!1}function i(e,t){return e.leftCol-t.leftCol}function o(e,r,n,i){var o=n.dateEnv,s=n.theme,l=t.rangeContainsMarker(r.activeRange,e),a=t.getDayClasses(e,r,n);return a.unshift("fc-day",s.getClass("widgetContent")),'<td class="'+a.join(" ")+'"'+(l?' data-date="'+o.formatIso(e,{omitTime:!0})+'"':"")+(i?" "+i:"")+"></td>"}function s(e,r){var n=new t.DaySeries(e.renderRange,r);return new t.DayTable(n,/year|month|week/.test(e.currentRangeUnit))}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var l=function(e,t){return(l=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)},a=function(){return a=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++){t=arguments[r];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e},a.apply(this,arguments)},d=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.buildRenderRange=function(r,n,i){var o,s=this.dateEnv,l=e.prototype.buildRenderRange.call(this,r,n,i),a=l.start,d=l.end;if(/^(year|month)$/.test(n)&&(a=s.startOfWeek(a),o=s.startOfWeek(d),o.valueOf()!==d.valueOf()&&(d=t.addWeeks(o,1))),this.options.monthMode&&this.options.fixedWeekCount){var c=Math.ceil(t.diffWeeks(a,d));d=t.addWeeks(d,6-c)}return{start:a,end:d}},n}(t.DateProfileGenerator),c=function(){function e(e){var t=this;this.isHidden=!0,this.margin=10,this.documentMousedown=function(e){t.el&&!t.el.contains(e.target)&&t.hide()},this.options=e}return e.prototype.show=function(){this.isHidden&&(this.el||this.render(),this.el.style.display="",this.position(),this.isHidden=!1,this.trigger("show"))},e.prototype.hide=function(){this.isHidden||(this.el.style.display="none",this.isHidden=!0,this.trigger("hide"))},e.prototype.render=function(){var e=this,r=this.options,n=this.el=t.createElement("div",{className:"fc-popover "+(r.className||""),style:{top:"0",left:"0"}});"function"==typeof r.content&&r.content(n),r.parentEl.appendChild(n),t.listenBySelector(n,"click",".fc-close",function(t){e.hide()}),r.autoHide&&document.addEventListener("mousedown",this.documentMousedown)},e.prototype.destroy=function(){this.hide(),this.el&&(t.removeElement(this.el),this.el=null),document.removeEventListener("mousedown",this.documentMousedown)},e.prototype.position=function(){var e,r,n=this.options,i=this.el,o=i.getBoundingClientRect(),s=t.computeRect(i.offsetParent),l=t.computeClippingRect(n.parentEl);e=n.top||0,r=void 0!==n.left?n.left:void 0!==n.right?n.right-o.width:0,e=Math.min(e,l.bottom-o.height-this.margin),e=Math.max(e,l.top+this.margin),r=Math.min(r,l.right-o.width-this.margin),r=Math.max(r,l.left+this.margin),t.applyStyle(i,{top:e-s.top,left:r-s.left})},e.prototype.trigger=function(e){this.options[e]&&this.options[e].apply(this,Array.prototype.slice.call(arguments,1))},e}(),h=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.renderSegHtml=function(e,r){var n,i,o=this.context.options,s=e.eventRange,l=s.def,a=s.ui,d=l.allDay,c=a.startEditable,h=d&&e.isStart&&a.durationEditable&&o.eventResizableFromStart,p=d&&e.isEnd&&a.durationEditable,u=this.getSegClasses(e,c,h||p,r),f=t.cssToStr(this.getSkinCss(a)),g="";return u.unshift("fc-day-grid-event","fc-h-event"),e.isStart&&(n=this.getTimeText(s))&&(g='<span class="fc-time">'+t.htmlEscape(n)+"</span>"),i='<span class="fc-title">'+(t.htmlEscape(l.title||"")||"&nbsp;")+"</span>",'<a class="'+u.join(" ")+'"'+(l.url?' href="'+t.htmlEscape(l.url)+'"':"")+(f?' style="'+f+'"':"")+'><div class="fc-content">'+("rtl"===o.dir?i+" "+g:g+" "+i)+"</div>"+(h?'<div class="fc-resizer fc-start-resizer"></div>':"")+(p?'<div class="fc-resizer fc-end-resizer"></div>':"")+"</a>"},n.prototype.computeEventTimeFormat=function(){return{hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"narrow"}},n.prototype.computeDisplayEventEnd=function(){return!1},n}(t.FgEventRenderer),p=function(e){function o(t){var r=e.call(this,t.context)||this;return r.dayGrid=t,r}return r(o,e),o.prototype.attachSegs=function(e,t){var r=this.rowStructs=this.renderSegRows(e);this.dayGrid.rowEls.forEach(function(e,t){e.querySelector(".fc-content-skeleton > table").appendChild(r[t].tbodyEl)}),t||this.dayGrid.removeSegPopover()},o.prototype.detachSegs=function(){for(var e,r=this.rowStructs||[];e=r.pop();)t.removeElement(e.tbodyEl);this.rowStructs=null},o.prototype.renderSegRows=function(e){var t,r,n=[];for(t=this.groupSegRows(e),r=0;r<t.length;r++)n.push(this.renderSegRow(r,t[r]));return n},o.prototype.renderSegRow=function(e,r){function n(e){for(;s<e;)c=(b[i-1]||[])[s],c?c.rowSpan=(c.rowSpan||1)+1:(c=document.createElement("td"),l.appendChild(c)),v[i][s]=c,b[i][s]=c,s++}var i,o,s,l,a,d,c,h=this.dayGrid,p=h.colCnt,u=h.isRtl,f=this.buildSegLevels(r),g=Math.max(1,f.length),m=document.createElement("tbody"),y=[],v=[],b=[];for(i=0;i<g;i++){if(o=f[i],s=0,l=document.createElement("tr"),y.push([]),v.push([]),b.push([]),o)for(a=0;a<o.length;a++){d=o[a];var w=u?p-1-d.lastCol:d.firstCol,S=u?p-1-d.firstCol:d.lastCol;for(n(w),c=t.createElement("td",{className:"fc-event-container"},d.el),w!==S?c.colSpan=S-w+1:b[i][s]=c;s<=S;)v[i][s]=c,y[i][s]=d,s++;l.appendChild(c)}n(p);var C=h.renderProps.renderIntroHtml();C&&(h.isRtl?t.appendToElement(l,C):t.prependToElement(l,C)),m.appendChild(l)}return{row:e,tbodyEl:m,cellMatrix:v,segMatrix:y,segLevels:f,segs:r}},o.prototype.buildSegLevels=function(e){var t,r,o,s=this.dayGrid,l=s.isRtl,a=s.colCnt,d=[];for(e=this.sortEventSegs(e),t=0;t<e.length;t++){for(r=e[t],o=0;o<d.length&&n(r,d[o]);o++);r.level=o,r.leftCol=l?a-1-r.lastCol:r.firstCol,r.rightCol=l?a-1-r.firstCol:r.lastCol,(d[o]||(d[o]=[])).push(r)}for(o=0;o<d.length;o++)d[o].sort(i);return d},o.prototype.groupSegRows=function(e){var t,r=[];for(t=0;t<this.dayGrid.rowCnt;t++)r.push([]);for(t=0;t<e.length;t++)r[e[t].row].push(e[t]);return r},o.prototype.computeDisplayEventEnd=function(){return 1===this.dayGrid.colCnt},o}(h),u=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.attachSegs=function(e,r){var n=r.sourceSeg,i=this.rowStructs=this.renderSegRows(e);this.dayGrid.rowEls.forEach(function(e,r){var o,s,l=t.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>');n&&n.row===r?o=n.el:(o=e.querySelector(".fc-content-skeleton tbody"))||(o=e.querySelector(".fc-content-skeleton table")),s=o.getBoundingClientRect().top-e.getBoundingClientRect().top,l.style.top=s+"px",l.querySelector("table").appendChild(i[r].tbodyEl),e.appendChild(l)})},n}(p),f=function(e){function n(t){var r=e.call(this,t.context)||this;return r.fillSegTag="td",r.dayGrid=t,r}return r(n,e),n.prototype.renderSegs=function(t,r){"bgEvent"===t&&(r=r.filter(function(e){return e.eventRange.def.allDay})),e.prototype.renderSegs.call(this,t,r)},n.prototype.attachSegs=function(e,t){var r,n,i,o=[];for(r=0;r<t.length;r++)n=t[r],i=this.renderFillRow(e,n),this.dayGrid.rowEls[n.row].appendChild(i),o.push(i);return o},n.prototype.renderFillRow=function(e,r){var n,i,o,s=this.dayGrid,l=s.colCnt,a=s.isRtl,d=a?l-1-r.lastCol:r.firstCol,c=a?l-1-r.firstCol:r.lastCol,h=d,p=c+1;n="businessHours"===e?"bgevent":e.toLowerCase(),i=t.htmlToElement('<div class="fc-'+n+'-skeleton"><table><tr></tr></table></div>'),o=i.getElementsByTagName("tr")[0],h>0&&t.appendToElement(o,new Array(h+1).join("<td></td>")),r.el.colSpan=p-h,o.appendChild(r.el),p<l&&t.appendToElement(o,new Array(l-p+1).join("<td></td>"));var u=s.renderProps.renderIntroHtml();return u&&(s.isRtl?t.appendToElement(o,u):t.prependToElement(o,u)),i},n}(t.FillRenderer),g=function(e){function n(r,n){var i=e.call(this,r,n)||this,o=i.eventRenderer=new m(i),s=i.renderFrame=t.memoizeRendering(i._renderFrame);return i.renderFgEvents=t.memoizeRendering(o.renderSegs.bind(o),o.unrender.bind(o),[s]),i.renderEventSelection=t.memoizeRendering(o.selectByInstanceId.bind(o),o.unselectByInstanceId.bind(o),[i.renderFgEvents]),i.renderEventDrag=t.memoizeRendering(o.hideByHash.bind(o),o.showByHash.bind(o),[s]),i.renderEventResize=t.memoizeRendering(o.hideByHash.bind(o),o.showByHash.bind(o),[s]),r.calendar.registerInteractiveComponent(i,{el:i.el,useEventCenter:!1}),i}return r(n,e),n.prototype.render=function(e){this.renderFrame(e.date),this.renderFgEvents(e.fgSegs),this.renderEventSelection(e.eventSelection),this.renderEventDrag(e.eventDragInstances),this.renderEventResize(e.eventResizeInstances)},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderFrame.unrender(),this.calendar.unregisterInteractiveComponent(this)},n.prototype._renderFrame=function(e){var r=this,n=r.theme,i=r.dateEnv,o=i.format(e,t.createFormatter(this.opt("dayPopoverFormat")));this.el.innerHTML='<div class="fc-header '+n.getClass("popoverHeader")+'"><span class="fc-title">'+t.htmlEscape(o)+'</span><span class="fc-close '+n.getIconClass("close")+'"></span></div><div class="fc-body '+n.getClass("popoverContent")+'"><div class="fc-event-container"></div></div>',this.segContainerEl=this.el.querySelector(".fc-event-container")},n.prototype.queryHit=function(e,r,n,i){var o=this.props.date;if(e<n&&r<i)return{component:this,dateSpan:{allDay:!0,range:{start:o,end:t.addDays(o,1)}},dayEl:this.el,rect:{left:0,top:0,right:n,bottom:i},layer:1}},n}(t.DateComponent),m=function(e){function n(t){var r=e.call(this,t.context)||this;return r.dayTile=t,r}return r(n,e),n.prototype.attachSegs=function(e){for(var t=0,r=e;t<r.length;t++){var n=r[t];this.dayTile.segContainerEl.appendChild(n.el)}},n.prototype.detachSegs=function(e){for(var r=0,n=e;r<n.length;r++){var i=n[r];t.removeElement(i.el)}},n}(h),y=function(){function e(e){this.context=e}return e.prototype.renderHtml=function(e){var t=[];e.renderIntroHtml&&t.push(e.renderIntroHtml());for(var r=0,n=e.cells;r<n.length;r++){var i=n[r];t.push(o(i.date,e.dateProfile,this.context,i.htmlAttrs))}return e.cells.length||t.push('<td class="fc-day '+this.context.theme.getClass("widgetContent")+'"></td>'),"rtl"===this.context.options.dir&&t.reverse(),"<tr>"+t.join("")+"</tr>"},e}(),v=t.createFormatter({day:"numeric"}),b=t.createFormatter({week:"numeric"}),w=function(e){function n(r,n,i){var o=e.call(this,r,n)||this;o.bottomCoordPadding=0,o.isCellSizesDirty=!1;var s=o.eventRenderer=new p(o),l=o.fillRenderer=new f(o);o.mirrorRenderer=new u(o);var a=o.renderCells=t.memoizeRendering(o._renderCells,o._unrenderCells);return o.renderBusinessHours=t.memoizeRendering(l.renderSegs.bind(l,"businessHours"),l.unrender.bind(l,"businessHours"),[a]),o.renderDateSelection=t.memoizeRendering(l.renderSegs.bind(l,"highlight"),l.unrender.bind(l,"highlight"),[a]),o.renderBgEvents=t.memoizeRendering(l.renderSegs.bind(l,"bgEvent"),l.unrender.bind(l,"bgEvent"),[a]),o.renderFgEvents=t.memoizeRendering(s.renderSegs.bind(s),s.unrender.bind(s),[a]),o.renderEventSelection=t.memoizeRendering(s.selectByInstanceId.bind(s),s.unselectByInstanceId.bind(s),[o.renderFgEvents]),o.renderEventDrag=t.memoizeRendering(o._renderEventDrag,o._unrenderEventDrag,[a]),o.renderEventResize=t.memoizeRendering(o._renderEventResize,o._unrenderEventResize,[a]),o.renderProps=i,o}return r(n,e),n.prototype.render=function(e){var t=e.cells;this.rowCnt=t.length,this.colCnt=t[0].length,this.renderCells(t,e.isRigid),this.renderBusinessHours(e.businessHourSegs),this.renderDateSelection(e.dateSelectionSegs),this.renderBgEvents(e.bgEventSegs),this.renderFgEvents(e.fgEventSegs),this.renderEventSelection(e.eventSelection),this.renderEventDrag(e.eventDrag),this.renderEventResize(e.eventResize),this.segPopoverTile&&this.updateSegPopoverTile()},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderCells.unrender()},n.prototype.getCellRange=function(e,r){var n=this.props.cells[e][r].date;return{start:n,end:t.addDays(n,1)}},n.prototype.updateSegPopoverTile=function(e,t){var r=this.props;this.segPopoverTile.receiveProps({date:e||this.segPopoverTile.props.date,fgSegs:t||this.segPopoverTile.props.fgSegs,eventSelection:r.eventSelection,eventDragInstances:r.eventDrag?r.eventDrag.affectedInstances:null,eventResizeInstances:r.eventResize?r.eventResize.affectedInstances:null})},n.prototype._renderCells=function(e,r){var n,i,o=this,s=o.view,l=o.dateEnv,a=this,d=a.rowCnt,c=a.colCnt,h="";for(n=0;n<d;n++)h+=this.renderDayRowHtml(n,r);for(this.el.innerHTML=h,this.rowEls=t.findElements(this.el,".fc-row"),this.cellEls=t.findElements(this.el,".fc-day, .fc-disabled-day"),this.isRtl&&this.cellEls.reverse(),this.rowPositions=new t.PositionCache(this.el,this.rowEls,!1,!0),this.colPositions=new t.PositionCache(this.el,this.cellEls.slice(0,c),!0,!1),n=0;n<d;n++)for(i=0;i<c;i++)this.publiclyTrigger("dayRender",[{date:l.toDate(e[n][i].date),el:this.getCellEl(n,i),view:s}]);this.isCellSizesDirty=!0},n.prototype._unrenderCells=function(){this.removeSegPopover()},n.prototype.renderDayRowHtml=function(e,t){var r=this.theme,n=["fc-row","fc-week",r.getClass("dayRow")];t&&n.push("fc-rigid");var i=new y(this.context);return'<div class="'+n.join(" ")+'"><div class="fc-bg"><table class="'+r.getClass("tableGrid")+'">'+i.renderHtml({cells:this.props.cells[e],dateProfile:this.props.dateProfile,renderIntroHtml:this.renderProps.renderBgIntroHtml})+'</table></div><div class="fc-content-skeleton"><table>'+(this.getIsNumbersVisible()?"<thead>"+this.renderNumberTrHtml(e)+"</thead>":"")+"</table></div></div>"},n.prototype.getIsNumbersVisible=function(){return this.getIsDayNumbersVisible()||this.renderProps.cellWeekNumbersVisible||this.renderProps.colWeekNumbersVisible},n.prototype.getIsDayNumbersVisible=function(){return this.rowCnt>1},n.prototype.renderNumberTrHtml=function(e){var t=this.renderProps.renderNumberIntroHtml(e,this);return"<tr>"+(this.isRtl?"":t)+this.renderNumberCellsHtml(e)+(this.isRtl?t:"")+"</tr>"},n.prototype.renderNumberCellsHtml=function(e){var t,r,n=[];for(t=0;t<this.colCnt;t++)r=this.props.cells[e][t].date,n.push(this.renderNumberCellHtml(r));return this.isRtl&&n.reverse(),n.join("")},n.prototype.renderNumberCellHtml=function(e){var r,n,i=this,o=i.view,s=i.dateEnv,l="",a=t.rangeContainsMarker(this.props.dateProfile.activeRange,e),d=this.getIsDayNumbersVisible()&&a;return d||this.renderProps.cellWeekNumbersVisible?(r=t.getDayClasses(e,this.props.dateProfile,this.context),r.unshift("fc-day-top"),this.renderProps.cellWeekNumbersVisible&&(n=s.weekDow),l+='<td class="'+r.join(" ")+'"'+(a?' data-date="'+s.formatIso(e,{omitTime:!0})+'"':"")+">",this.renderProps.cellWeekNumbersVisible&&e.getUTCDay()===n&&(l+=t.buildGotoAnchorHtml(o,{date:e,type:"week"},{class:"fc-week-number"},s.format(e,b))),d&&(l+=t.buildGotoAnchorHtml(o,e,{class:"fc-day-number"},s.format(e,v))),l+="</td>"):"<td></td>"},n.prototype.updateSize=function(e){var t=this,r=t.fillRenderer,n=t.eventRenderer,i=t.mirrorRenderer;(e||this.isCellSizesDirty)&&(this.buildColPositions(),this.buildRowPositions(),this.isCellSizesDirty=!1),r.computeSizes(e),n.computeSizes(e),i.computeSizes(e),r.assignSizes(e),n.assignSizes(e),i.assignSizes(e)},n.prototype.buildColPositions=function(){this.colPositions.build()},n.prototype.buildRowPositions=function(){this.rowPositions.build(),this.rowPositions.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},n.prototype.positionToHit=function(e,t){var r=this,n=r.colPositions,i=r.rowPositions,o=n.leftToIndex(e),s=i.topToIndex(t);if(null!=s&&null!=o)return{row:s,col:o,dateSpan:{range:this.getCellRange(s,o),allDay:!0},dayEl:this.getCellEl(s,o),relativeRect:{left:n.lefts[o],right:n.rights[o],top:i.tops[s],bottom:i.bottoms[s]}}},n.prototype.getCellEl=function(e,t){return this.cellEls[e*this.colCnt+t]},n.prototype._renderEventDrag=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),this.fillRenderer.renderSegs("highlight",e.segs))},n.prototype._unrenderEventDrag=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.fillRenderer.unrender("highlight"))},n.prototype._renderEventResize=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),this.fillRenderer.renderSegs("highlight",e.segs),this.mirrorRenderer.renderSegs(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype._unrenderEventResize=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.fillRenderer.unrender("highlight"),this.mirrorRenderer.unrender(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype.removeSegPopover=function(){this.segPopover&&this.segPopover.hide()},n.prototype.limitRows=function(e){var t,r,n=this.eventRenderer.rowStructs||[];for(t=0;t<n.length;t++)this.unlimitRow(t),!1!==(r=!!e&&("number"==typeof e?e:this.computeRowLevelLimit(t)))&&this.limitRow(t,r)},n.prototype.computeRowLevelLimit=function(e){var r,n,i=this.rowEls[e],o=i.getBoundingClientRect().bottom,s=t.findChildren(this.eventRenderer.rowStructs[e].tbodyEl);for(r=0;r<s.length;r++)if(n=s[r],n.classList.remove("fc-limited"),n.getBoundingClientRect().bottom>o)return r;return!1},n.prototype.limitRow=function(e,r){var n,i,o,s,l,a,d,c,h,p,u,f,g,m,y,v=this,b=this,w=b.colCnt,S=b.isRtl,C=this.eventRenderer.rowStructs[e],E=[],R=0,H=function(n){for(;R<n;)a=v.getCellSegs(e,R,r),a.length&&(h=i[r-1][R],y=v.renderMoreLink(e,R,a),m=t.createElement("div",null,y),h.appendChild(m),E.push(m[0])),R++};if(r&&r<C.segLevels.length){for(n=C.segLevels[r-1],i=C.cellMatrix,o=t.findChildren(C.tbodyEl).slice(r),o.forEach(function(e){e.classList.add("fc-limited")}),s=0;s<n.length;s++){l=n[s];var D=S?w-1-l.lastCol:l.firstCol,P=S?w-1-l.firstCol:l.lastCol;for(H(D),c=[],d=0;R<=P;)a=this.getCellSegs(e,R,r),c.push(a),d+=a.length,R++;if(d){for(h=i[r-1][D],p=h.rowSpan||1,u=[],f=0;f<c.length;f++)g=t.createElement("td",{className:"fc-more-cell",rowSpan:p}),a=c[f],y=this.renderMoreLink(e,D+f,[l].concat(a)),m=t.createElement("div",null,y),g.appendChild(m),u.push(g),E.push(g);h.classList.add("fc-limited"),t.insertAfterElement(h,u),o.push(h)}}H(this.colCnt),C.moreEls=E,C.limitedEls=o}},n.prototype.unlimitRow=function(e){var r=this.eventRenderer.rowStructs[e];r.moreEls&&(r.moreEls.forEach(t.removeElement),r.moreEls=null),r.limitedEls&&(r.limitedEls.forEach(function(e){e.classList.remove("fc-limited")}),r.limitedEls=null)},n.prototype.renderMoreLink=function(e,r,n){var i=this,o=this,s=o.view,l=o.dateEnv,a=t.createElement("a",{className:"fc-more"});return a.innerText=this.getMoreLinkText(n.length),a.addEventListener("click",function(t){var o=i.opt("eventLimitClick"),a=i.isRtl?i.colCnt-r-1:r,d=i.props.cells[e][a].date,c=t.currentTarget,h=i.getCellEl(e,r),p=i.getCellSegs(e,r),u=i.resliceDaySegs(p,d),f=i.resliceDaySegs(n,d);"function"==typeof o&&(o=i.publiclyTrigger("eventLimitClick",[{date:l.toDate(d),allDay:!0,dayEl:h,moreEl:c,segs:u,hiddenSegs:f,jsEvent:t,view:s}])),"popover"===o?i.showSegPopover(e,r,c,u):"string"==typeof o&&s.calendar.zoomTo(d,o)}),a},n.prototype.showSegPopover=function(e,r,n,i){var o,s,l=this,a=this,d=a.calendar,h=a.view,p=a.theme,u=this.isRtl?this.colCnt-r-1:r,f=n.parentNode;o=1===this.rowCnt?h.el:this.rowEls[e],s={className:"fc-more-popover "+p.getClass("popover"),parentEl:h.el,top:t.computeRect(o).top,autoHide:!0,content:function(t){l.segPopoverTile=new g(l.context,t),l.updateSegPopoverTile(l.props.cells[e][u].date,i)},hide:function(){l.segPopoverTile.destroy(),l.segPopoverTile=null,l.segPopover.destroy(),l.segPopover=null}},this.isRtl?s.right=t.computeRect(f).right+1:s.left=t.computeRect(f).left-1,this.segPopover=new c(s),this.segPopover.show(),d.releaseAfterSizingTriggers()},n.prototype.resliceDaySegs=function(e,r){for(var n=r,i=t.addDays(n,1),o={start:n,end:i},s=[],l=0,d=e;l<d.length;l++){var c=d[l],h=c.eventRange,p=h.range,u=t.intersectRanges(p,o);u&&s.push(a({},c,{eventRange:{def:h.def,ui:a({},h.ui,{durationEditable:!1}),instance:h.instance,range:u},isStart:c.isStart&&u.start.valueOf()===p.start.valueOf(),isEnd:c.isEnd&&u.end.valueOf()===p.end.valueOf()}))}return s},n.prototype.getMoreLinkText=function(e){var t=this.opt("eventLimitText");return"function"==typeof t?t(e):"+"+e+" "+t},n.prototype.getCellSegs=function(e,t,r){for(var n,i=this.eventRenderer.rowStructs[e].segMatrix,o=r||0,s=[];o<i.length;)n=i[o][t],n&&s.push(n),o++;return s},n}(t.DateComponent),S=t.createFormatter({week:"numeric"}),C=function(e){function n(r,n,i,o){var s=e.call(this,r,n,i,o)||this;s.renderHeadIntroHtml=function(){var e=s.theme;return s.colWeekNumbersVisible?'<th class="fc-week-number '+e.getClass("widgetHeader")+'" '+s.weekNumberStyleAttr()+"><span>"+t.htmlEscape(s.opt("weekLabel"))+"</span></th>":""},s.renderDayGridNumberIntroHtml=function(e,r){var n=s.dateEnv,i=r.props.cells[e][0].date;return s.colWeekNumbersVisible?'<td class="fc-week-number" '+s.weekNumberStyleAttr()+">"+t.buildGotoAnchorHtml(s,{date:i,type:"week",forceOff:1===r.colCnt},n.format(i,S))+"</td>":""},s.renderDayGridBgIntroHtml=function(){var e=s.theme;return s.colWeekNumbersVisible?'<td class="fc-week-number '+e.getClass("widgetContent")+'" '+s.weekNumberStyleAttr()+"></td>":""},s.renderDayGridIntroHtml=function(){return s.colWeekNumbersVisible?'<td class="fc-week-number" '+s.weekNumberStyleAttr()+"></td>":""},s.el.classList.add("fc-dayGrid-view"),s.el.innerHTML=s.renderSkeletonHtml(),s.scroller=new t.ScrollComponent("hidden","auto");var l=s.scroller.el;s.el.querySelector(".fc-body > tr > td").appendChild(l),l.classList.add("fc-day-grid-container");var a=t.createElement("div",{className:"fc-day-grid"});l.appendChild(a);var d;return s.opt("weekNumbers")?s.opt("weekNumbersWithinDays")?(d=!0,s.colWeekNumbersVisible=!1):(d=!1,s.colWeekNumbersVisible=!0):(s.colWeekNumbersVisible=!1,d=!1),s.dayGrid=new w(s.context,a,{renderNumberIntroHtml:s.renderDayGridNumberIntroHtml,renderBgIntroHtml:s.renderDayGridBgIntroHtml,renderIntroHtml:s.renderDayGridIntroHtml,colWeekNumbersVisible:s.colWeekNumbersVisible,cellWeekNumbersVisible:d}),s}return r(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.dayGrid.destroy(),this.scroller.destroy()},n.prototype.renderSkeletonHtml=function(){var e=this.theme;return'<table class="'+e.getClass("tableGrid")+'">'+(this.opt("columnHeader")?'<thead class="fc-head"><tr><td class="fc-head-container '+e.getClass("widgetHeader")+'">&nbsp;</td></tr></thead>':"")+'<tbody class="fc-body"><tr><td class="'+e.getClass("widgetContent")+'"></td></tr></tbody></table>'},n.prototype.weekNumberStyleAttr=function(){return null!=this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},n.prototype.hasRigidRows=function(){var e=this.opt("eventLimit");return e&&"number"!=typeof e},n.prototype.updateSize=function(t,r,n){e.prototype.updateSize.call(this,t,r,n),this.dayGrid.updateSize(t)},n.prototype.updateBaseSize=function(e,r,n){var i,o,s=this.dayGrid,l=this.opt("eventLimit"),a=this.header?this.header.el:null;if(!s.rowEls)return void(n||(i=this.computeScrollerHeight(r),this.scroller.setHeight(i)));this.colWeekNumbersVisible&&(this.weekNumberWidth=t.matchCellWidths(t.findElements(this.el,".fc-week-number"))),this.scroller.clear(),a&&t.uncompensateScroll(a),s.removeSegPopover(),l&&"number"==typeof l&&s.limitRows(l),i=this.computeScrollerHeight(r),this.setGridHeight(i,n),l&&"number"!=typeof l&&s.limitRows(l),n||(this.scroller.setHeight(i),o=this.scroller.getScrollbarWidths(),(o.left||o.right)&&(a&&t.compensateScroll(a,o),i=this.computeScrollerHeight(r),this.scroller.setHeight(i)),this.scroller.lockOverflow(o))},n.prototype.computeScrollerHeight=function(e){return e-t.subtractInnerElHeight(this.el,this.scroller.el)},n.prototype.setGridHeight=function(e,r){this.opt("monthMode")?(r&&(e*=this.dayGrid.rowCnt/6),t.distributeHeight(this.dayGrid.rowEls,e,!r)):r?t.undistributeHeight(this.dayGrid.rowEls):t.distributeHeight(this.dayGrid.rowEls,e,!0)},n.prototype.computeInitialDateScroll=function(){return{top:0}},n.prototype.queryDateScroll=function(){return{top:this.scroller.getScrollTop()}},n.prototype.applyDateScroll=function(e){void 0!==e.top&&this.scroller.setScrollTop(e.top)},n}(t.View);C.prototype.dateProfileGeneratorClass=d;var E=function(e){function t(t,r){var n=e.call(this,t,r.el)||this;return n.slicer=new R,n.dayGrid=r,t.calendar.registerInteractiveComponent(n,{el:n.dayGrid.el}),n}return r(t,e),t.prototype.destroy=function(){e.prototype.destroy.call(this),this.calendar.unregisterInteractiveComponent(this)},t.prototype.render=function(e){var t=this.dayGrid,r=e.dateProfile,n=e.dayTable;t.receiveProps(a({},this.slicer.sliceProps(e,r,e.nextDayThreshold,t,n),{dateProfile:r,cells:n.cells,isRigid:e.isRigid}))},t.prototype.queryHit=function(e,t){var r=this.dayGrid.positionToHit(e,t);if(r)return{component:this.dayGrid,dateSpan:r.dateSpan,dayEl:r.dayEl,rect:{left:r.relativeRect.left,right:r.relativeRect.right,top:r.relativeRect.top,bottom:r.relativeRect.bottom},layer:0}},t}(t.DateComponent),R=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r(t,e),t.prototype.sliceRange=function(e,t){return t.sliceRange(e)},t}(t.Slicer),H=function(e){function n(r,n,i,o){var l=e.call(this,r,n,i,o)||this;return l.buildDayTable=t.memoize(s),l.opt("columnHeader")&&(l.header=new t.DayHeader(l.context,l.el.querySelector(".fc-head-container"))),l.simpleDayGrid=new E(l.context,l.dayGrid),l}return r(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.header&&this.header.destroy(),this.simpleDayGrid.destroy()},n.prototype.render=function(t){e.prototype.render.call(this,t);var r=this.props.dateProfile,n=this.dayTable=this.buildDayTable(r,this.dateProfileGenerator);this.header&&this.header.receiveProps({dateProfile:r,dates:n.headerDates,datesRepDistinctDays:1===n.rowCnt,renderIntroHtml:this.renderHeadIntroHtml}),this.simpleDayGrid.receiveProps({dateProfile:r,dayTable:n,businessHours:t.businessHours,dateSelection:t.dateSelection,eventStore:t.eventStore,eventUiBases:t.eventUiBases,eventSelection:t.eventSelection,eventDrag:t.eventDrag,eventResize:t.eventResize,isRigid:this.hasRigidRows(),nextDayThreshold:this.nextDayThreshold})},n}(C),D=t.createPlugin({defaultView:"dayGridMonth",views:{dayGrid:H,dayGridDay:{type:"dayGrid",duration:{days:1}},dayGridWeek:{type:"dayGrid",duration:{weeks:1}},dayGridMonth:{type:"dayGrid",duration:{months:1},monthMode:!0,fixedWeekCount:!0}}});e.AbstractDayGridView=C,e.DayBgRow=y,e.DayGrid=w,e.DayGridSlicer=R,e.DayGridView=H,e.SimpleDayGrid=E,e.buildBasicDayTable=s,e.default=D,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/google-calendar/main.js b/library/fullcalendar/packages/google-calendar/main.js
new file mode 100644
index 000000000..89ce3d7a6
--- /dev/null
+++ b/library/fullcalendar/packages/google-calendar/main.js
@@ -0,0 +1,169 @@
+/*!
+FullCalendar Google Calendar Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar));
+}(this, function (exports, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ // TODO: expose somehow
+ var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
+ var STANDARD_PROPS = {
+ url: String,
+ googleCalendarApiKey: String,
+ googleCalendarId: String,
+ data: null
+ };
+ var eventSourceDef = {
+ parseMeta: function (raw) {
+ if (typeof raw === 'string') {
+ raw = { url: raw };
+ }
+ if (typeof raw === 'object') {
+ var standardProps = core.refineProps(raw, STANDARD_PROPS);
+ if (!standardProps.googleCalendarId && standardProps.url) {
+ standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url);
+ }
+ delete standardProps.url;
+ if (standardProps.googleCalendarId) {
+ return standardProps;
+ }
+ }
+ return null;
+ },
+ fetch: function (arg, onSuccess, onFailure) {
+ var calendar = arg.calendar;
+ var meta = arg.eventSource.meta;
+ var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey');
+ if (!apiKey) {
+ onFailure({
+ message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/'
+ });
+ }
+ else {
+ var url = buildUrl(meta);
+ var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv);
+ core.requestJson('GET', url, requestParams_1, function (body, xhr) {
+ if (body.error) {
+ onFailure({
+ message: 'Google Calendar API: ' + body.error.message,
+ errors: body.error.errors,
+ xhr: xhr
+ });
+ }
+ else {
+ onSuccess({
+ rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
+ xhr: xhr
+ });
+ }
+ }, function (message, xhr) {
+ onFailure({ message: message, xhr: xhr });
+ });
+ }
+ }
+ };
+ function parseGoogleCalendarId(url) {
+ var match;
+ // detect if the ID was specified as a single string.
+ // will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars.
+ if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
+ return url;
+ }
+ else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||
+ (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) {
+ return decodeURIComponent(match[1]);
+ }
+ }
+ function buildUrl(meta) {
+ return API_BASE + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
+ }
+ function buildRequestParams(range, apiKey, extraParams, dateEnv) {
+ var params;
+ var startStr;
+ var endStr;
+ if (dateEnv.canComputeOffset) {
+ // strings will naturally have offsets, which GCal needs
+ startStr = dateEnv.formatIso(range.start);
+ endStr = dateEnv.formatIso(range.end);
+ }
+ else {
+ // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
+ // from the UTC day-start to guarantee we're getting all the events
+ // (start/end will be UTC-coerced dates, so toISOString is okay)
+ startStr = core.addDays(range.start, -1).toISOString();
+ endStr = core.addDays(range.end, 1).toISOString();
+ }
+ params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
+ if (dateEnv.timeZone !== 'local') {
+ params.timeZone = dateEnv.timeZone;
+ }
+ return params;
+ }
+ function gcalItemsToRawEventDefs(items, gcalTimezone) {
+ return items.map(function (item) {
+ return gcalItemToRawEventDef(item, gcalTimezone);
+ });
+ }
+ function gcalItemToRawEventDef(item, gcalTimezone) {
+ var url = item.htmlLink || null;
+ // make the URLs for each event show times in the correct timezone
+ if (url && gcalTimezone) {
+ url = injectQsComponent(url, 'ctz=' + gcalTimezone);
+ }
+ return {
+ id: item.id,
+ title: item.summary,
+ start: item.start.dateTime || item.start.date,
+ end: item.end.dateTime || item.end.date,
+ url: url,
+ location: item.location,
+ description: item.description
+ };
+ }
+ // Injects a string like "arg=value" into the querystring of a URL
+ // TODO: move to a general util file?
+ function injectQsComponent(url, component) {
+ // inject it after the querystring but before the fragment
+ return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) {
+ return (qs ? qs + '&' : '?') + component + hash;
+ });
+ }
+ var main = core.createPlugin({
+ eventSourceDefs: [eventSourceDef]
+ });
+
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/google-calendar/main.min.js b/library/fullcalendar/packages/google-calendar/main.min.js
new file mode 100644
index 000000000..51947e659
--- /dev/null
+++ b/library/fullcalendar/packages/google-calendar/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Google Calendar Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],r):(e=e||self,r(e.FullCalendarGoogleCalendar={},e.FullCalendar))}(this,function(e,r){"use strict";function t(e){var r;return/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(e)?e:(r=/^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(e))||(r=/^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(e))?decodeURIComponent(r[1]):void 0}function n(e){return s+"/"+encodeURIComponent(e.googleCalendarId)+"/events"}function o(e,t,n,o){var a,l,i;return o.canComputeOffset?(l=o.formatIso(e.start),i=o.formatIso(e.end)):(l=r.addDays(e.start,-1).toISOString(),i=r.addDays(e.end,1).toISOString()),a=d({},n||{},{key:t,timeMin:l,timeMax:i,singleEvents:!0,maxResults:9999}),"local"!==o.timeZone&&(a.timeZone=o.timeZone),a}function a(e,r){return e.map(function(e){return l(e,r)})}function l(e,r){var t=e.htmlLink||null;return t&&r&&(t=i(t,"ctz="+r)),{id:e.id,title:e.summary,start:e.start.dateTime||e.start.date,end:e.end.dateTime||e.end.date,url:t,location:e.location,description:e.description}}function i(e,r){return e.replace(/(\?.*?)?(#|$)/,function(e,t,n){return(t?t+"&":"?")+r+n})}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var d=function(){return d=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++){r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},d.apply(this,arguments)},s="https://www.googleapis.com/calendar/v3/calendars",c={url:String,googleCalendarApiKey:String,googleCalendarId:String,data:null},u={parseMeta:function(e){if("string"==typeof e&&(e={url:e}),"object"==typeof e){var n=r.refineProps(e,c);if(!n.googleCalendarId&&n.url&&(n.googleCalendarId=t(n.url)),delete n.url,n.googleCalendarId)return n}return null},fetch:function(e,t,l){var i=e.calendar,d=e.eventSource.meta,s=d.googleCalendarApiKey||i.opt("googleCalendarApiKey");if(s){var c=n(d),u=o(e.range,s,d.data,i.dateEnv);r.requestJson("GET",c,u,function(e,r){e.error?l({message:"Google Calendar API: "+e.error.message,errors:e.error.errors,xhr:r}):t({rawEvents:a(e.items,u.timeZone),xhr:r})},function(e,r){l({message:e,xhr:r})})}else l({message:"Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/"})}},g=r.createPlugin({eventSourceDefs:[u]});e.default=g,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/interaction/main.js b/library/fullcalendar/packages/interaction/main.js
new file mode 100644
index 000000000..8dbb47bde
--- /dev/null
+++ b/library/fullcalendar/packages/interaction/main.js
@@ -0,0 +1,2155 @@
+/*!
+FullCalendar Interaction Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarInteraction = {}, global.FullCalendar));
+}(this, function (exports, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ core.config.touchMouseIgnoreWait = 500;
+ var ignoreMouseDepth = 0;
+ var listenerCnt = 0;
+ var isWindowTouchMoveCancelled = false;
+ /*
+ Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
+ Tracks when the pointer "drags" on a certain element, meaning down+move+up.
+
+ Also, tracks if there was touch-scrolling.
+ Also, can prevent touch-scrolling from happening.
+ Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
+
+ emits:
+ - pointerdown
+ - pointermove
+ - pointerup
+ */
+ var PointerDragging = /** @class */ (function () {
+ function PointerDragging(containerEl) {
+ var _this = this;
+ this.subjectEl = null;
+ this.downEl = null;
+ // options that can be directly assigned by caller
+ this.selector = ''; // will cause subjectEl in all emitted events to be this element
+ this.handleSelector = '';
+ this.shouldIgnoreMove = false;
+ this.shouldWatchScroll = true; // for simulating pointermove on scroll
+ // internal states
+ this.isDragging = false;
+ this.isTouchDragging = false;
+ this.wasTouchScroll = false;
+ // Mouse
+ // ----------------------------------------------------------------------------------------------------
+ this.handleMouseDown = function (ev) {
+ if (!_this.shouldIgnoreMouse() &&
+ isPrimaryMouseButton(ev) &&
+ _this.tryStart(ev)) {
+ var pev = _this.createEventFromMouse(ev, true);
+ _this.emitter.trigger('pointerdown', pev);
+ _this.initScrollWatch(pev);
+ if (!_this.shouldIgnoreMove) {
+ document.addEventListener('mousemove', _this.handleMouseMove);
+ }
+ document.addEventListener('mouseup', _this.handleMouseUp);
+ }
+ };
+ this.handleMouseMove = function (ev) {
+ var pev = _this.createEventFromMouse(ev);
+ _this.recordCoords(pev);
+ _this.emitter.trigger('pointermove', pev);
+ };
+ this.handleMouseUp = function (ev) {
+ document.removeEventListener('mousemove', _this.handleMouseMove);
+ document.removeEventListener('mouseup', _this.handleMouseUp);
+ _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
+ _this.cleanup(); // call last so that pointerup has access to props
+ };
+ // Touch
+ // ----------------------------------------------------------------------------------------------------
+ this.handleTouchStart = function (ev) {
+ if (_this.tryStart(ev)) {
+ _this.isTouchDragging = true;
+ var pev = _this.createEventFromTouch(ev, true);
+ _this.emitter.trigger('pointerdown', pev);
+ _this.initScrollWatch(pev);
+ // unlike mouse, need to attach to target, not document
+ // https://stackoverflow.com/a/45760014
+ var target = ev.target;
+ if (!_this.shouldIgnoreMove) {
+ target.addEventListener('touchmove', _this.handleTouchMove);
+ }
+ target.addEventListener('touchend', _this.handleTouchEnd);
+ target.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
+ // attach a handler to get called when ANY scroll action happens on the page.
+ // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
+ // http://stackoverflow.com/a/32954565/96342
+ window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture
+ );
+ }
+ };
+ this.handleTouchMove = function (ev) {
+ var pev = _this.createEventFromTouch(ev);
+ _this.recordCoords(pev);
+ _this.emitter.trigger('pointermove', pev);
+ };
+ this.handleTouchEnd = function (ev) {
+ if (_this.isDragging) { // done to guard against touchend followed by touchcancel
+ var target = ev.target;
+ target.removeEventListener('touchmove', _this.handleTouchMove);
+ target.removeEventListener('touchend', _this.handleTouchEnd);
+ target.removeEventListener('touchcancel', _this.handleTouchEnd);
+ window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
+ _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
+ _this.cleanup(); // call last so that pointerup has access to props
+ _this.isTouchDragging = false;
+ startIgnoringMouse();
+ }
+ };
+ this.handleTouchScroll = function () {
+ _this.wasTouchScroll = true;
+ };
+ this.handleScroll = function (ev) {
+ if (!_this.shouldIgnoreMove) {
+ var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
+ var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
+ _this.emitter.trigger('pointermove', {
+ origEvent: ev,
+ isTouch: _this.isTouchDragging,
+ subjectEl: _this.subjectEl,
+ pageX: pageX,
+ pageY: pageY,
+ deltaX: pageX - _this.origPageX,
+ deltaY: pageY - _this.origPageY
+ });
+ }
+ };
+ this.containerEl = containerEl;
+ this.emitter = new core.EmitterMixin();
+ containerEl.addEventListener('mousedown', this.handleMouseDown);
+ containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
+ listenerCreated();
+ }
+ PointerDragging.prototype.destroy = function () {
+ this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
+ this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
+ listenerDestroyed();
+ };
+ PointerDragging.prototype.tryStart = function (ev) {
+ var subjectEl = this.querySubjectEl(ev);
+ var downEl = ev.target;
+ if (subjectEl &&
+ (!this.handleSelector || core.elementClosest(downEl, this.handleSelector))) {
+ this.subjectEl = subjectEl;
+ this.downEl = downEl;
+ this.isDragging = true; // do this first so cancelTouchScroll will work
+ this.wasTouchScroll = false;
+ return true;
+ }
+ return false;
+ };
+ PointerDragging.prototype.cleanup = function () {
+ isWindowTouchMoveCancelled = false;
+ this.isDragging = false;
+ this.subjectEl = null;
+ this.downEl = null;
+ // keep wasTouchScroll around for later access
+ this.destroyScrollWatch();
+ };
+ PointerDragging.prototype.querySubjectEl = function (ev) {
+ if (this.selector) {
+ return core.elementClosest(ev.target, this.selector);
+ }
+ else {
+ return this.containerEl;
+ }
+ };
+ PointerDragging.prototype.shouldIgnoreMouse = function () {
+ return ignoreMouseDepth || this.isTouchDragging;
+ };
+ // can be called by user of this class, to cancel touch-based scrolling for the current drag
+ PointerDragging.prototype.cancelTouchScroll = function () {
+ if (this.isDragging) {
+ isWindowTouchMoveCancelled = true;
+ }
+ };
+ // Scrolling that simulates pointermoves
+ // ----------------------------------------------------------------------------------------------------
+ PointerDragging.prototype.initScrollWatch = function (ev) {
+ if (this.shouldWatchScroll) {
+ this.recordCoords(ev);
+ window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
+ }
+ };
+ PointerDragging.prototype.recordCoords = function (ev) {
+ if (this.shouldWatchScroll) {
+ this.prevPageX = ev.pageX;
+ this.prevPageY = ev.pageY;
+ this.prevScrollX = window.pageXOffset;
+ this.prevScrollY = window.pageYOffset;
+ }
+ };
+ PointerDragging.prototype.destroyScrollWatch = function () {
+ if (this.shouldWatchScroll) {
+ window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
+ }
+ };
+ // Event Normalization
+ // ----------------------------------------------------------------------------------------------------
+ PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
+ var deltaX = 0;
+ var deltaY = 0;
+ // TODO: repeat code
+ if (isFirst) {
+ this.origPageX = ev.pageX;
+ this.origPageY = ev.pageY;
+ }
+ else {
+ deltaX = ev.pageX - this.origPageX;
+ deltaY = ev.pageY - this.origPageY;
+ }
+ return {
+ origEvent: ev,
+ isTouch: false,
+ subjectEl: this.subjectEl,
+ pageX: ev.pageX,
+ pageY: ev.pageY,
+ deltaX: deltaX,
+ deltaY: deltaY
+ };
+ };
+ PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
+ var touches = ev.touches;
+ var pageX;
+ var pageY;
+ var deltaX = 0;
+ var deltaY = 0;
+ // if touch coords available, prefer,
+ // because FF would give bad ev.pageX ev.pageY
+ if (touches && touches.length) {
+ pageX = touches[0].pageX;
+ pageY = touches[0].pageY;
+ }
+ else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+ // TODO: repeat code
+ if (isFirst) {
+ this.origPageX = pageX;
+ this.origPageY = pageY;
+ }
+ else {
+ deltaX = pageX - this.origPageX;
+ deltaY = pageY - this.origPageY;
+ }
+ return {
+ origEvent: ev,
+ isTouch: true,
+ subjectEl: this.subjectEl,
+ pageX: pageX,
+ pageY: pageY,
+ deltaX: deltaX,
+ deltaY: deltaY
+ };
+ };
+ return PointerDragging;
+ }());
+ // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
+ function isPrimaryMouseButton(ev) {
+ return ev.button === 0 && !ev.ctrlKey;
+ }
+ // Ignoring fake mouse events generated by touch
+ // ----------------------------------------------------------------------------------------------------
+ function startIgnoringMouse() {
+ ignoreMouseDepth++;
+ setTimeout(function () {
+ ignoreMouseDepth--;
+ }, core.config.touchMouseIgnoreWait);
+ }
+ // We want to attach touchmove as early as possible for Safari
+ // ----------------------------------------------------------------------------------------------------
+ function listenerCreated() {
+ if (!(listenerCnt++)) {
+ window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
+ }
+ }
+ function listenerDestroyed() {
+ if (!(--listenerCnt)) {
+ window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
+ }
+ }
+ function onWindowTouchMove(ev) {
+ if (isWindowTouchMoveCancelled) {
+ ev.preventDefault();
+ }
+ }
+
+ /*
+ An effect in which an element follows the movement of a pointer across the screen.
+ The moving element is a clone of some other element.
+ Must call start + handleMove + stop.
+ */
+ var ElementMirror = /** @class */ (function () {
+ function ElementMirror() {
+ this.isVisible = false; // must be explicitly enabled
+ this.sourceEl = null;
+ this.mirrorEl = null;
+ this.sourceElRect = null; // screen coords relative to viewport
+ // options that can be set directly by caller
+ this.parentNode = document.body;
+ this.zIndex = 9999;
+ this.revertDuration = 0;
+ }
+ ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
+ this.sourceEl = sourceEl;
+ this.sourceElRect = this.sourceEl.getBoundingClientRect();
+ this.origScreenX = pageX - window.pageXOffset;
+ this.origScreenY = pageY - window.pageYOffset;
+ this.deltaX = 0;
+ this.deltaY = 0;
+ this.updateElPosition();
+ };
+ ElementMirror.prototype.handleMove = function (pageX, pageY) {
+ this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
+ this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
+ this.updateElPosition();
+ };
+ // can be called before start
+ ElementMirror.prototype.setIsVisible = function (bool) {
+ if (bool) {
+ if (!this.isVisible) {
+ if (this.mirrorEl) {
+ this.mirrorEl.style.display = '';
+ }
+ this.isVisible = bool; // needs to happen before updateElPosition
+ this.updateElPosition(); // because was not updating the position while invisible
+ }
+ }
+ else {
+ if (this.isVisible) {
+ if (this.mirrorEl) {
+ this.mirrorEl.style.display = 'none';
+ }
+ this.isVisible = bool;
+ }
+ }
+ };
+ // always async
+ ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
+ var _this = this;
+ var done = function () {
+ _this.cleanup();
+ callback();
+ };
+ if (needsRevertAnimation &&
+ this.mirrorEl &&
+ this.isVisible &&
+ this.revertDuration && // if 0, transition won't work
+ (this.deltaX || this.deltaY) // if same coords, transition won't work
+ ) {
+ this.doRevertAnimation(done, this.revertDuration);
+ }
+ else {
+ setTimeout(done, 0);
+ }
+ };
+ ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
+ var mirrorEl = this.mirrorEl;
+ var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
+ mirrorEl.style.transition =
+ 'top ' + revertDuration + 'ms,' +
+ 'left ' + revertDuration + 'ms';
+ core.applyStyle(mirrorEl, {
+ left: finalSourceElRect.left,
+ top: finalSourceElRect.top
+ });
+ core.whenTransitionDone(mirrorEl, function () {
+ mirrorEl.style.transition = '';
+ callback();
+ });
+ };
+ ElementMirror.prototype.cleanup = function () {
+ if (this.mirrorEl) {
+ core.removeElement(this.mirrorEl);
+ this.mirrorEl = null;
+ }
+ this.sourceEl = null;
+ };
+ ElementMirror.prototype.updateElPosition = function () {
+ if (this.sourceEl && this.isVisible) {
+ core.applyStyle(this.getMirrorEl(), {
+ left: this.sourceElRect.left + this.deltaX,
+ top: this.sourceElRect.top + this.deltaY
+ });
+ }
+ };
+ ElementMirror.prototype.getMirrorEl = function () {
+ var sourceElRect = this.sourceElRect;
+ var mirrorEl = this.mirrorEl;
+ if (!mirrorEl) {
+ mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
+ // we don't want long taps or any mouse interaction causing selection/menus.
+ // would use preventSelection(), but that prevents selectstart, causing problems.
+ mirrorEl.classList.add('fc-unselectable');
+ mirrorEl.classList.add('fc-dragging');
+ core.applyStyle(mirrorEl, {
+ position: 'fixed',
+ zIndex: this.zIndex,
+ visibility: '',
+ boxSizing: 'border-box',
+ width: sourceElRect.right - sourceElRect.left,
+ height: sourceElRect.bottom - sourceElRect.top,
+ right: 'auto',
+ bottom: 'auto',
+ margin: 0
+ });
+ this.parentNode.appendChild(mirrorEl);
+ }
+ return mirrorEl;
+ };
+ return ElementMirror;
+ }());
+
+ /*
+ Is a cache for a given element's scroll information (all the info that ScrollController stores)
+ in addition the "client rectangle" of the element.. the area within the scrollbars.
+
+ The cache can be in one of two modes:
+ - doesListening:false - ignores when the container is scrolled by someone else
+ - doesListening:true - watch for scrolling and update the cache
+ */
+ var ScrollGeomCache = /** @class */ (function (_super) {
+ __extends(ScrollGeomCache, _super);
+ function ScrollGeomCache(scrollController, doesListening) {
+ var _this = _super.call(this) || this;
+ _this.handleScroll = function () {
+ _this.scrollTop = _this.scrollController.getScrollTop();
+ _this.scrollLeft = _this.scrollController.getScrollLeft();
+ _this.handleScrollChange();
+ };
+ _this.scrollController = scrollController;
+ _this.doesListening = doesListening;
+ _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
+ _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
+ _this.scrollWidth = scrollController.getScrollWidth();
+ _this.scrollHeight = scrollController.getScrollHeight();
+ _this.clientWidth = scrollController.getClientWidth();
+ _this.clientHeight = scrollController.getClientHeight();
+ _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
+ if (_this.doesListening) {
+ _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
+ }
+ return _this;
+ }
+ ScrollGeomCache.prototype.destroy = function () {
+ if (this.doesListening) {
+ this.getEventTarget().removeEventListener('scroll', this.handleScroll);
+ }
+ };
+ ScrollGeomCache.prototype.getScrollTop = function () {
+ return this.scrollTop;
+ };
+ ScrollGeomCache.prototype.getScrollLeft = function () {
+ return this.scrollLeft;
+ };
+ ScrollGeomCache.prototype.setScrollTop = function (top) {
+ this.scrollController.setScrollTop(top);
+ if (!this.doesListening) {
+ // we are not relying on the element to normalize out-of-bounds scroll values
+ // so we need to sanitize ourselves
+ this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
+ this.handleScrollChange();
+ }
+ };
+ ScrollGeomCache.prototype.setScrollLeft = function (top) {
+ this.scrollController.setScrollLeft(top);
+ if (!this.doesListening) {
+ // we are not relying on the element to normalize out-of-bounds scroll values
+ // so we need to sanitize ourselves
+ this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
+ this.handleScrollChange();
+ }
+ };
+ ScrollGeomCache.prototype.getClientWidth = function () {
+ return this.clientWidth;
+ };
+ ScrollGeomCache.prototype.getClientHeight = function () {
+ return this.clientHeight;
+ };
+ ScrollGeomCache.prototype.getScrollWidth = function () {
+ return this.scrollWidth;
+ };
+ ScrollGeomCache.prototype.getScrollHeight = function () {
+ return this.scrollHeight;
+ };
+ ScrollGeomCache.prototype.handleScrollChange = function () {
+ };
+ return ScrollGeomCache;
+ }(core.ScrollController));
+ var ElementScrollGeomCache = /** @class */ (function (_super) {
+ __extends(ElementScrollGeomCache, _super);
+ function ElementScrollGeomCache(el, doesListening) {
+ return _super.call(this, new core.ElementScrollController(el), doesListening) || this;
+ }
+ ElementScrollGeomCache.prototype.getEventTarget = function () {
+ return this.scrollController.el;
+ };
+ ElementScrollGeomCache.prototype.computeClientRect = function () {
+ return core.computeInnerRect(this.scrollController.el);
+ };
+ return ElementScrollGeomCache;
+ }(ScrollGeomCache));
+ var WindowScrollGeomCache = /** @class */ (function (_super) {
+ __extends(WindowScrollGeomCache, _super);
+ function WindowScrollGeomCache(doesListening) {
+ return _super.call(this, new core.WindowScrollController(), doesListening) || this;
+ }
+ WindowScrollGeomCache.prototype.getEventTarget = function () {
+ return window;
+ };
+ WindowScrollGeomCache.prototype.computeClientRect = function () {
+ return {
+ left: this.scrollLeft,
+ right: this.scrollLeft + this.clientWidth,
+ top: this.scrollTop,
+ bottom: this.scrollTop + this.clientHeight
+ };
+ };
+ // the window is the only scroll object that changes it's rectangle relative
+ // to the document's topleft as it scrolls
+ WindowScrollGeomCache.prototype.handleScrollChange = function () {
+ this.clientRect = this.computeClientRect();
+ };
+ return WindowScrollGeomCache;
+ }(ScrollGeomCache));
+
+ // If available we are using native "performance" API instead of "Date"
+ // Read more about it on MDN:
+ // https://developer.mozilla.org/en-US/docs/Web/API/Performance
+ var getTime = typeof performance === 'function' ? performance.now : Date.now;
+ /*
+ For a pointer interaction, automatically scrolls certain scroll containers when the pointer
+ approaches the edge.
+
+ The caller must call start + handleMove + stop.
+ */
+ var AutoScroller = /** @class */ (function () {
+ function AutoScroller() {
+ var _this = this;
+ // options that can be set by caller
+ this.isEnabled = true;
+ this.scrollQuery = [window, '.fc-scroller'];
+ this.edgeThreshold = 50; // pixels
+ this.maxVelocity = 300; // pixels per second
+ // internal state
+ this.pointerScreenX = null;
+ this.pointerScreenY = null;
+ this.isAnimating = false;
+ this.scrollCaches = null;
+ // protect against the initial pointerdown being too close to an edge and starting the scroll
+ this.everMovedUp = false;
+ this.everMovedDown = false;
+ this.everMovedLeft = false;
+ this.everMovedRight = false;
+ this.animate = function () {
+ if (_this.isAnimating) { // wasn't cancelled between animation calls
+ var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
+ if (edge) {
+ var now = getTime();
+ _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
+ _this.requestAnimation(now);
+ }
+ else {
+ _this.isAnimating = false; // will stop animation
+ }
+ }
+ };
+ }
+ AutoScroller.prototype.start = function (pageX, pageY) {
+ if (this.isEnabled) {
+ this.scrollCaches = this.buildCaches();
+ this.pointerScreenX = null;
+ this.pointerScreenY = null;
+ this.everMovedUp = false;
+ this.everMovedDown = false;
+ this.everMovedLeft = false;
+ this.everMovedRight = false;
+ this.handleMove(pageX, pageY);
+ }
+ };
+ AutoScroller.prototype.handleMove = function (pageX, pageY) {
+ if (this.isEnabled) {
+ var pointerScreenX = pageX - window.pageXOffset;
+ var pointerScreenY = pageY - window.pageYOffset;
+ var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
+ var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
+ if (yDelta < 0) {
+ this.everMovedUp = true;
+ }
+ else if (yDelta > 0) {
+ this.everMovedDown = true;
+ }
+ if (xDelta < 0) {
+ this.everMovedLeft = true;
+ }
+ else if (xDelta > 0) {
+ this.everMovedRight = true;
+ }
+ this.pointerScreenX = pointerScreenX;
+ this.pointerScreenY = pointerScreenY;
+ if (!this.isAnimating) {
+ this.isAnimating = true;
+ this.requestAnimation(getTime());
+ }
+ }
+ };
+ AutoScroller.prototype.stop = function () {
+ if (this.isEnabled) {
+ this.isAnimating = false; // will stop animation
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ scrollCache.destroy();
+ }
+ this.scrollCaches = null;
+ }
+ };
+ AutoScroller.prototype.requestAnimation = function (now) {
+ this.msSinceRequest = now;
+ requestAnimationFrame(this.animate);
+ };
+ AutoScroller.prototype.handleSide = function (edge, seconds) {
+ var scrollCache = edge.scrollCache;
+ var edgeThreshold = this.edgeThreshold;
+ var invDistance = edgeThreshold - edge.distance;
+ var velocity = // the closer to the edge, the faster we scroll
+ (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
+ this.maxVelocity * seconds;
+ var sign = 1;
+ switch (edge.name) {
+ case 'left':
+ sign = -1;
+ // falls through
+ case 'right':
+ scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
+ break;
+ case 'top':
+ sign = -1;
+ // falls through
+ case 'bottom':
+ scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
+ break;
+ }
+ };
+ // left/top are relative to document topleft
+ AutoScroller.prototype.computeBestEdge = function (left, top) {
+ var edgeThreshold = this.edgeThreshold;
+ var bestSide = null;
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ var rect = scrollCache.clientRect;
+ var leftDist = left - rect.left;
+ var rightDist = rect.right - left;
+ var topDist = top - rect.top;
+ var bottomDist = rect.bottom - top;
+ // completely within the rect?
+ if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
+ if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
+ (!bestSide || bestSide.distance > topDist)) {
+ bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
+ }
+ if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
+ (!bestSide || bestSide.distance > bottomDist)) {
+ bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
+ }
+ if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
+ (!bestSide || bestSide.distance > leftDist)) {
+ bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
+ }
+ if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
+ (!bestSide || bestSide.distance > rightDist)) {
+ bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
+ }
+ }
+ }
+ return bestSide;
+ };
+ AutoScroller.prototype.buildCaches = function () {
+ return this.queryScrollEls().map(function (el) {
+ if (el === window) {
+ return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
+ }
+ else {
+ return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
+ }
+ });
+ };
+ AutoScroller.prototype.queryScrollEls = function () {
+ var els = [];
+ for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
+ var query = _a[_i];
+ if (typeof query === 'object') {
+ els.push(query);
+ }
+ else {
+ els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
+ }
+ }
+ return els;
+ };
+ return AutoScroller;
+ }());
+
+ /*
+ Monitors dragging on an element. Has a number of high-level features:
+ - minimum distance required before dragging
+ - minimum wait time ("delay") before dragging
+ - a mirror element that follows the pointer
+ */
+ var FeaturefulElementDragging = /** @class */ (function (_super) {
+ __extends(FeaturefulElementDragging, _super);
+ function FeaturefulElementDragging(containerEl) {
+ var _this = _super.call(this, containerEl) || this;
+ // options that can be directly set by caller
+ // the caller can also set the PointerDragging's options as well
+ _this.delay = null;
+ _this.minDistance = 0;
+ _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
+ _this.mirrorNeedsRevert = false;
+ _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
+ _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
+ _this.isDelayEnded = false;
+ _this.isDistanceSurpassed = false;
+ _this.delayTimeoutId = null;
+ _this.onPointerDown = function (ev) {
+ if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
+ _this.isInteracting = true;
+ _this.isDelayEnded = false;
+ _this.isDistanceSurpassed = false;
+ core.preventSelection(document.body);
+ core.preventContextMenu(document.body);
+ // prevent links from being visited if there's an eventual drag.
+ // also prevents selection in older browsers (maybe?).
+ // not necessary for touch, besides, browser would complain about passiveness.
+ if (!ev.isTouch) {
+ ev.origEvent.preventDefault();
+ }
+ _this.emitter.trigger('pointerdown', ev);
+ if (!_this.pointer.shouldIgnoreMove) {
+ // actions related to initiating dragstart+dragmove+dragend...
+ _this.mirror.setIsVisible(false); // reset. caller must set-visible
+ _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
+ _this.startDelay(ev);
+ if (!_this.minDistance) {
+ _this.handleDistanceSurpassed(ev);
+ }
+ }
+ }
+ };
+ _this.onPointerMove = function (ev) {
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
+ _this.emitter.trigger('pointermove', ev);
+ if (!_this.isDistanceSurpassed) {
+ var minDistance = _this.minDistance;
+ var distanceSq = void 0; // current distance from the origin, squared
+ var deltaX = ev.deltaX, deltaY = ev.deltaY;
+ distanceSq = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
+ _this.handleDistanceSurpassed(ev);
+ }
+ }
+ if (_this.isDragging) {
+ // a real pointer move? (not one simulated by scrolling)
+ if (ev.origEvent.type !== 'scroll') {
+ _this.mirror.handleMove(ev.pageX, ev.pageY);
+ _this.autoScroller.handleMove(ev.pageX, ev.pageY);
+ }
+ _this.emitter.trigger('dragmove', ev);
+ }
+ }
+ };
+ _this.onPointerUp = function (ev) {
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
+ _this.isInteracting = false;
+ core.allowSelection(document.body);
+ core.allowContextMenu(document.body);
+ _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
+ if (_this.isDragging) {
+ _this.autoScroller.stop();
+ _this.tryStopDrag(ev); // which will stop the mirror
+ }
+ if (_this.delayTimeoutId) {
+ clearTimeout(_this.delayTimeoutId);
+ _this.delayTimeoutId = null;
+ }
+ }
+ };
+ var pointer = _this.pointer = new PointerDragging(containerEl);
+ pointer.emitter.on('pointerdown', _this.onPointerDown);
+ pointer.emitter.on('pointermove', _this.onPointerMove);
+ pointer.emitter.on('pointerup', _this.onPointerUp);
+ _this.mirror = new ElementMirror();
+ _this.autoScroller = new AutoScroller();
+ return _this;
+ }
+ FeaturefulElementDragging.prototype.destroy = function () {
+ this.pointer.destroy();
+ };
+ FeaturefulElementDragging.prototype.startDelay = function (ev) {
+ var _this = this;
+ if (typeof this.delay === 'number') {
+ this.delayTimeoutId = setTimeout(function () {
+ _this.delayTimeoutId = null;
+ _this.handleDelayEnd(ev);
+ }, this.delay);
+ }
+ else {
+ this.handleDelayEnd(ev);
+ }
+ };
+ FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
+ this.isDelayEnded = true;
+ this.tryStartDrag(ev);
+ };
+ FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
+ this.isDistanceSurpassed = true;
+ this.tryStartDrag(ev);
+ };
+ FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
+ if (this.isDelayEnded && this.isDistanceSurpassed) {
+ if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
+ this.isDragging = true;
+ this.mirrorNeedsRevert = false;
+ this.autoScroller.start(ev.pageX, ev.pageY);
+ this.emitter.trigger('dragstart', ev);
+ if (this.touchScrollAllowed === false) {
+ this.pointer.cancelTouchScroll();
+ }
+ }
+ }
+ };
+ FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
+ // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
+ // that come from the document to fire beforehand. much more convenient this way.
+ this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args
+ );
+ };
+ FeaturefulElementDragging.prototype.stopDrag = function (ev) {
+ this.isDragging = false;
+ this.emitter.trigger('dragend', ev);
+ };
+ // fill in the implementations...
+ FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
+ this.pointer.shouldIgnoreMove = bool;
+ };
+ FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
+ this.mirror.setIsVisible(bool);
+ };
+ FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
+ this.mirrorNeedsRevert = bool;
+ };
+ FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
+ this.autoScroller.isEnabled = bool;
+ };
+ return FeaturefulElementDragging;
+ }(core.ElementDragging));
+
+ /*
+ When this class is instantiated, it records the offset of an element (relative to the document topleft),
+ and continues to monitor scrolling, updating the cached coordinates if it needs to.
+ Does not access the DOM after instantiation, so highly performant.
+
+ Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
+ and an determine if a given point is inside the combined clipping rectangle.
+ */
+ var OffsetTracker = /** @class */ (function () {
+ function OffsetTracker(el) {
+ this.origRect = core.computeRect(el);
+ // will work fine for divs that have overflow:hidden
+ this.scrollCaches = core.getClippingParents(el).map(function (el) {
+ return new ElementScrollGeomCache(el, true); // listen=true
+ });
+ }
+ OffsetTracker.prototype.destroy = function () {
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ scrollCache.destroy();
+ }
+ };
+ OffsetTracker.prototype.computeLeft = function () {
+ var left = this.origRect.left;
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
+ }
+ return left;
+ };
+ OffsetTracker.prototype.computeTop = function () {
+ var top = this.origRect.top;
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ top += scrollCache.origScrollTop - scrollCache.getScrollTop();
+ }
+ return top;
+ };
+ OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
+ var point = { left: pageX, top: pageY };
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+ var scrollCache = _a[_i];
+ if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
+ !core.pointInsideRect(point, scrollCache.clientRect)) {
+ return false;
+ }
+ }
+ return true;
+ };
+ return OffsetTracker;
+ }());
+ // certain clipping containers should never constrain interactions, like <html> and <body>
+ // https://github.com/fullcalendar/fullcalendar/issues/3615
+ function isIgnoredClipping(node) {
+ var tagName = node.tagName;
+ return tagName === 'HTML' || tagName === 'BODY';
+ }
+
+ /*
+ Tracks movement over multiple droppable areas (aka "hits")
+ that exist in one or more DateComponents.
+ Relies on an existing draggable.
+
+ emits:
+ - pointerdown
+ - dragstart
+ - hitchange - fires initially, even if not over a hit
+ - pointerup
+ - (hitchange - again, to null, if ended over a hit)
+ - dragend
+ */
+ var HitDragging = /** @class */ (function () {
+ function HitDragging(dragging, droppableStore) {
+ var _this = this;
+ // options that can be set by caller
+ this.useSubjectCenter = false;
+ this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
+ this.initialHit = null;
+ this.movingHit = null;
+ this.finalHit = null; // won't ever be populated if shouldIgnoreMove
+ this.handlePointerDown = function (ev) {
+ var dragging = _this.dragging;
+ _this.initialHit = null;
+ _this.movingHit = null;
+ _this.finalHit = null;
+ _this.prepareHits();
+ _this.processFirstCoord(ev);
+ if (_this.initialHit || !_this.requireInitial) {
+ dragging.setIgnoreMove(false);
+ _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
+ }
+ else {
+ dragging.setIgnoreMove(true);
+ }
+ };
+ this.handleDragStart = function (ev) {
+ _this.emitter.trigger('dragstart', ev);
+ _this.handleMove(ev, true); // force = fire even if initially null
+ };
+ this.handleDragMove = function (ev) {
+ _this.emitter.trigger('dragmove', ev);
+ _this.handleMove(ev);
+ };
+ this.handlePointerUp = function (ev) {
+ _this.releaseHits();
+ _this.emitter.trigger('pointerup', ev);
+ };
+ this.handleDragEnd = function (ev) {
+ if (_this.movingHit) {
+ _this.emitter.trigger('hitupdate', null, true, ev);
+ }
+ _this.finalHit = _this.movingHit;
+ _this.movingHit = null;
+ _this.emitter.trigger('dragend', ev);
+ };
+ this.droppableStore = droppableStore;
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
+ dragging.emitter.on('dragstart', this.handleDragStart);
+ dragging.emitter.on('dragmove', this.handleDragMove);
+ dragging.emitter.on('pointerup', this.handlePointerUp);
+ dragging.emitter.on('dragend', this.handleDragEnd);
+ this.dragging = dragging;
+ this.emitter = new core.EmitterMixin();
+ }
+ // sets initialHit
+ // sets coordAdjust
+ HitDragging.prototype.processFirstCoord = function (ev) {
+ var origPoint = { left: ev.pageX, top: ev.pageY };
+ var adjustedPoint = origPoint;
+ var subjectEl = ev.subjectEl;
+ var subjectRect;
+ if (subjectEl !== document) {
+ subjectRect = core.computeRect(subjectEl);
+ adjustedPoint = core.constrainPoint(adjustedPoint, subjectRect);
+ }
+ var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
+ if (initialHit) {
+ if (this.useSubjectCenter && subjectRect) {
+ var slicedSubjectRect = core.intersectRects(subjectRect, initialHit.rect);
+ if (slicedSubjectRect) {
+ adjustedPoint = core.getRectCenter(slicedSubjectRect);
+ }
+ }
+ this.coordAdjust = core.diffPoints(adjustedPoint, origPoint);
+ }
+ else {
+ this.coordAdjust = { left: 0, top: 0 };
+ }
+ };
+ HitDragging.prototype.handleMove = function (ev, forceHandle) {
+ var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
+ if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
+ this.movingHit = hit;
+ this.emitter.trigger('hitupdate', hit, false, ev);
+ }
+ };
+ HitDragging.prototype.prepareHits = function () {
+ this.offsetTrackers = core.mapHash(this.droppableStore, function (interactionSettings) {
+ return new OffsetTracker(interactionSettings.el);
+ });
+ };
+ HitDragging.prototype.releaseHits = function () {
+ var offsetTrackers = this.offsetTrackers;
+ for (var id in offsetTrackers) {
+ offsetTrackers[id].destroy();
+ }
+ this.offsetTrackers = {};
+ };
+ HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
+ var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
+ var bestHit = null;
+ for (var id in droppableStore) {
+ var component = droppableStore[id].component;
+ var offsetTracker = offsetTrackers[id];
+ if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
+ var originLeft = offsetTracker.computeLeft();
+ var originTop = offsetTracker.computeTop();
+ var positionLeft = offsetLeft - originLeft;
+ var positionTop = offsetTop - originTop;
+ var origRect = offsetTracker.origRect;
+ var width = origRect.right - origRect.left;
+ var height = origRect.bottom - origRect.top;
+ if (
+ // must be within the element's bounds
+ positionLeft >= 0 && positionLeft < width &&
+ positionTop >= 0 && positionTop < height) {
+ var hit = component.queryHit(positionLeft, positionTop, width, height);
+ if (hit &&
+ (
+ // make sure the hit is within activeRange, meaning it's not a deal cell
+ !component.props.dateProfile || // hack for DayTile
+ core.rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) &&
+ (!bestHit || hit.layer > bestHit.layer)) {
+ // TODO: better way to re-orient rectangle
+ hit.rect.left += originLeft;
+ hit.rect.right += originLeft;
+ hit.rect.top += originTop;
+ hit.rect.bottom += originTop;
+ bestHit = hit;
+ }
+ }
+ }
+ }
+ return bestHit;
+ };
+ return HitDragging;
+ }());
+ function isHitsEqual(hit0, hit1) {
+ if (!hit0 && !hit1) {
+ return true;
+ }
+ if (Boolean(hit0) !== Boolean(hit1)) {
+ return false;
+ }
+ return core.isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
+ }
+
+ /*
+ Monitors when the user clicks on a specific date/time of a component.
+ A pointerdown+pointerup on the same "hit" constitutes a click.
+ */
+ var DateClicking = /** @class */ (function (_super) {
+ __extends(DateClicking, _super);
+ function DateClicking(settings) {
+ var _this = _super.call(this, settings) || this;
+ _this.handlePointerDown = function (ev) {
+ var dragging = _this.dragging;
+ // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
+ dragging.setIgnoreMove(!_this.component.isValidDateDownEl(dragging.pointer.downEl));
+ };
+ // won't even fire if moving was ignored
+ _this.handleDragEnd = function (ev) {
+ var component = _this.component;
+ var pointer = _this.dragging.pointer;
+ if (!pointer.wasTouchScroll) {
+ var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
+ if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
+ component.calendar.triggerDateClick(initialHit.dateSpan, initialHit.dayEl, component.view, ev.origEvent);
+ }
+ }
+ };
+ var component = settings.component;
+ // we DO want to watch pointer moves because otherwise finalHit won't get populated
+ _this.dragging = new FeaturefulElementDragging(component.el);
+ _this.dragging.autoScroller.isEnabled = false;
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
+ return _this;
+ }
+ DateClicking.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ return DateClicking;
+ }(core.Interaction));
+
+ /*
+ Tracks when the user selects a portion of time of a component,
+ constituted by a drag over date cells, with a possible delay at the beginning of the drag.
+ */
+ var DateSelecting = /** @class */ (function (_super) {
+ __extends(DateSelecting, _super);
+ function DateSelecting(settings) {
+ var _this = _super.call(this, settings) || this;
+ _this.dragSelection = null;
+ _this.handlePointerDown = function (ev) {
+ var _a = _this, component = _a.component, dragging = _a.dragging;
+ var canSelect = component.opt('selectable') &&
+ component.isValidDateDownEl(ev.origEvent.target);
+ // don't bother to watch expensive moves if component won't do selection
+ dragging.setIgnoreMove(!canSelect);
+ // if touch, require user to hold down
+ dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
+ };
+ _this.handleDragStart = function (ev) {
+ _this.component.calendar.unselect(ev); // unselect previous selections
+ };
+ _this.handleHitUpdate = function (hit, isFinal) {
+ var calendar = _this.component.calendar;
+ var dragSelection = null;
+ var isInvalid = false;
+ if (hit) {
+ dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, calendar.pluginSystem.hooks.dateSelectionTransformers);
+ if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
+ isInvalid = true;
+ dragSelection = null;
+ }
+ }
+ if (dragSelection) {
+ calendar.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
+ }
+ else if (!isFinal) { // only unselect if moved away while dragging
+ calendar.dispatch({ type: 'UNSELECT_DATES' });
+ }
+ if (!isInvalid) {
+ core.enableCursor();
+ }
+ else {
+ core.disableCursor();
+ }
+ if (!isFinal) {
+ _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
+ }
+ };
+ _this.handlePointerUp = function (pev) {
+ if (_this.dragSelection) {
+ // selection is already rendered, so just need to report selection
+ _this.component.calendar.triggerDateSelect(_this.dragSelection, pev);
+ _this.dragSelection = null;
+ }
+ };
+ var component = settings.component;
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
+ dragging.touchScrollAllowed = false;
+ dragging.minDistance = component.opt('selectMinDistance') || 0;
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
+ return _this;
+ }
+ DateSelecting.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ return DateSelecting;
+ }(core.Interaction));
+ function getComponentTouchDelay(component) {
+ var delay = component.opt('selectLongPressDelay');
+ if (delay == null) {
+ delay = component.opt('longPressDelay');
+ }
+ return delay;
+ }
+ function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
+ var dateSpan0 = hit0.dateSpan;
+ var dateSpan1 = hit1.dateSpan;
+ var ms = [
+ dateSpan0.range.start,
+ dateSpan0.range.end,
+ dateSpan1.range.start,
+ dateSpan1.range.end
+ ];
+ ms.sort(core.compareNumbers);
+ var props = {};
+ for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
+ var transformer = dateSelectionTransformers_1[_i];
+ var res = transformer(hit0, hit1);
+ if (res === false) {
+ return null;
+ }
+ else if (res) {
+ __assign(props, res);
+ }
+ }
+ props.range = { start: ms[0], end: ms[3] };
+ props.allDay = dateSpan0.allDay;
+ return props;
+ }
+
+ var EventDragging = /** @class */ (function (_super) {
+ __extends(EventDragging, _super);
+ function EventDragging(settings) {
+ var _this = _super.call(this, settings) || this;
+ // internal state
+ _this.subjectSeg = null; // the seg being selected/dragged
+ _this.isDragging = false;
+ _this.eventRange = null;
+ _this.relevantEvents = null; // the events being dragged
+ _this.receivingCalendar = null;
+ _this.validMutation = null;
+ _this.mutatedRelevantEvents = null;
+ _this.handlePointerDown = function (ev) {
+ var origTarget = ev.origEvent.target;
+ var _a = _this, component = _a.component, dragging = _a.dragging;
+ var mirror = dragging.mirror;
+ var initialCalendar = component.calendar;
+ var subjectSeg = _this.subjectSeg = core.getElSeg(ev.subjectEl);
+ var eventRange = _this.eventRange = subjectSeg.eventRange;
+ var eventInstanceId = eventRange.instance.instanceId;
+ _this.relevantEvents = core.getRelevantEvents(initialCalendar.state.eventStore, eventInstanceId);
+ dragging.minDistance = ev.isTouch ? 0 : component.opt('eventDragMinDistance');
+ dragging.delay =
+ // only do a touch delay if touch and this event hasn't been selected yet
+ (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
+ getComponentTouchDelay$1(component) :
+ null;
+ mirror.parentNode = initialCalendar.el;
+ mirror.revertDuration = component.opt('dragRevertDuration');
+ var isValid = component.isValidSegDownEl(origTarget) &&
+ !core.elementClosest(origTarget, '.fc-resizer');
+ dragging.setIgnoreMove(!isValid);
+ // disable dragging for elements that are resizable (ie, selectable)
+ // but are not draggable
+ _this.isDragging = isValid &&
+ ev.subjectEl.classList.contains('fc-draggable');
+ };
+ _this.handleDragStart = function (ev) {
+ var initialCalendar = _this.component.calendar;
+ var eventRange = _this.eventRange;
+ var eventInstanceId = eventRange.instance.instanceId;
+ if (ev.isTouch) {
+ // need to select a different event?
+ if (eventInstanceId !== _this.component.props.eventSelection) {
+ initialCalendar.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
+ }
+ }
+ else {
+ // if now using mouse, but was previous touch interaction, clear selected event
+ initialCalendar.dispatch({ type: 'UNSELECT_EVENT' });
+ }
+ if (_this.isDragging) {
+ initialCalendar.unselect(ev); // unselect *date* selection
+ initialCalendar.publiclyTrigger('eventDragStart', [
+ {
+ el: _this.subjectSeg.el,
+ event: new core.EventApi(initialCalendar, eventRange.def, eventRange.instance),
+ jsEvent: ev.origEvent,
+ view: _this.component.view
+ }
+ ]);
+ }
+ };
+ _this.handleHitUpdate = function (hit, isFinal) {
+ if (!_this.isDragging) {
+ return;
+ }
+ var relevantEvents = _this.relevantEvents;
+ var initialHit = _this.hitDragging.initialHit;
+ var initialCalendar = _this.component.calendar;
+ // states based on new hit
+ var receivingCalendar = null;
+ var mutation = null;
+ var mutatedRelevantEvents = null;
+ var isInvalid = false;
+ var interaction = {
+ affectedEvents: relevantEvents,
+ mutatedEvents: core.createEmptyEventStore(),
+ isEvent: true,
+ origSeg: _this.subjectSeg
+ };
+ if (hit) {
+ var receivingComponent = hit.component;
+ receivingCalendar = receivingComponent.calendar;
+ if (initialCalendar === receivingCalendar ||
+ receivingComponent.opt('editable') && receivingComponent.opt('droppable')) {
+ mutation = computeEventMutation(initialHit, hit, receivingCalendar.pluginSystem.hooks.eventDragMutationMassagers);
+ if (mutation) {
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, receivingCalendar.eventUiBases, mutation, receivingCalendar);
+ interaction.mutatedEvents = mutatedRelevantEvents;
+ if (!receivingComponent.isInteractionValid(interaction)) {
+ isInvalid = true;
+ mutation = null;
+ mutatedRelevantEvents = null;
+ interaction.mutatedEvents = core.createEmptyEventStore();
+ }
+ }
+ }
+ else {
+ receivingCalendar = null;
+ }
+ }
+ _this.displayDrag(receivingCalendar, interaction);
+ if (!isInvalid) {
+ core.enableCursor();
+ }
+ else {
+ core.disableCursor();
+ }
+ if (!isFinal) {
+ if (initialCalendar === receivingCalendar && // TODO: write test for this
+ isHitsEqual(initialHit, hit)) {
+ mutation = null;
+ }
+ _this.dragging.setMirrorNeedsRevert(!mutation);
+ // render the mirror if no already-rendered mirror
+ // TODO: wish we could somehow wait for dispatch to guarantee render
+ _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-mirror'));
+ // assign states based on new hit
+ _this.receivingCalendar = receivingCalendar;
+ _this.validMutation = mutation;
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
+ }
+ };
+ _this.handlePointerUp = function () {
+ if (!_this.isDragging) {
+ _this.cleanup(); // because handleDragEnd won't fire
+ }
+ };
+ _this.handleDragEnd = function (ev) {
+ if (_this.isDragging) {
+ var initialCalendar_1 = _this.component.calendar;
+ var initialView = _this.component.view;
+ var receivingCalendar = _this.receivingCalendar;
+ var eventDef = _this.eventRange.def;
+ var eventInstance = _this.eventRange.instance;
+ var eventApi = new core.EventApi(initialCalendar_1, eventDef, eventInstance);
+ var relevantEvents_1 = _this.relevantEvents;
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
+ var finalHit = _this.hitDragging.finalHit;
+ _this.clearDrag(); // must happen after revert animation
+ initialCalendar_1.publiclyTrigger('eventDragStop', [
+ {
+ el: _this.subjectSeg.el,
+ event: eventApi,
+ jsEvent: ev.origEvent,
+ view: initialView
+ }
+ ]);
+ if (_this.validMutation) {
+ // dropped within same calendar
+ if (receivingCalendar === initialCalendar_1) {
+ initialCalendar_1.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: mutatedRelevantEvents
+ });
+ var eventDropArg = {};
+ for (var _i = 0, _a = initialCalendar_1.pluginSystem.hooks.eventDropTransformers; _i < _a.length; _i++) {
+ var transformer = _a[_i];
+ __assign(eventDropArg, transformer(_this.validMutation, initialCalendar_1));
+ }
+ __assign(eventDropArg, {
+ el: ev.subjectEl,
+ delta: _this.validMutation.startDelta,
+ oldEvent: eventApi,
+ event: new core.EventApi(// the data AFTER the mutation
+ initialCalendar_1, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
+ revert: function () {
+ initialCalendar_1.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: relevantEvents_1
+ });
+ },
+ jsEvent: ev.origEvent,
+ view: initialView
+ });
+ initialCalendar_1.publiclyTrigger('eventDrop', [eventDropArg]);
+ // dropped in different calendar
+ }
+ else if (receivingCalendar) {
+ initialCalendar_1.publiclyTrigger('eventLeave', [
+ {
+ draggedEl: ev.subjectEl,
+ event: eventApi,
+ view: initialView
+ }
+ ]);
+ initialCalendar_1.dispatch({
+ type: 'REMOVE_EVENT_INSTANCES',
+ instances: _this.mutatedRelevantEvents.instances
+ });
+ receivingCalendar.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: _this.mutatedRelevantEvents
+ });
+ if (ev.isTouch) {
+ receivingCalendar.dispatch({
+ type: 'SELECT_EVENT',
+ eventInstanceId: eventInstance.instanceId
+ });
+ }
+ var dropArg = receivingCalendar.buildDatePointApi(finalHit.dateSpan);
+ dropArg.draggedEl = ev.subjectEl;
+ dropArg.jsEvent = ev.origEvent;
+ dropArg.view = finalHit.component; // ?
+ receivingCalendar.publiclyTrigger('drop', [dropArg]);
+ receivingCalendar.publiclyTrigger('eventReceive', [
+ {
+ draggedEl: ev.subjectEl,
+ event: new core.EventApi(// the data AFTER the mutation
+ receivingCalendar, mutatedRelevantEvents.defs[eventDef.defId], mutatedRelevantEvents.instances[eventInstance.instanceId]),
+ view: finalHit.component
+ }
+ ]);
+ }
+ }
+ else {
+ initialCalendar_1.publiclyTrigger('_noEventDrop');
+ }
+ }
+ _this.cleanup();
+ };
+ var component = _this.component;
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
+ dragging.pointer.selector = EventDragging.SELECTOR;
+ dragging.touchScrollAllowed = false;
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsStore);
+ hitDragging.useSubjectCenter = settings.useEventCenter;
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
+ return _this;
+ }
+ EventDragging.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ // render a drag state on the next receivingCalendar
+ EventDragging.prototype.displayDrag = function (nextCalendar, state) {
+ var initialCalendar = this.component.calendar;
+ var prevCalendar = this.receivingCalendar;
+ // does the previous calendar need to be cleared?
+ if (prevCalendar && prevCalendar !== nextCalendar) {
+ // does the initial calendar need to be cleared?
+ // if so, don't clear all the way. we still need to to hide the affectedEvents
+ if (prevCalendar === initialCalendar) {
+ prevCalendar.dispatch({
+ type: 'SET_EVENT_DRAG',
+ state: {
+ affectedEvents: state.affectedEvents,
+ mutatedEvents: core.createEmptyEventStore(),
+ isEvent: true,
+ origSeg: state.origSeg
+ }
+ });
+ // completely clear the old calendar if it wasn't the initial
+ }
+ else {
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+ }
+ }
+ if (nextCalendar) {
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
+ }
+ };
+ EventDragging.prototype.clearDrag = function () {
+ var initialCalendar = this.component.calendar;
+ var receivingCalendar = this.receivingCalendar;
+ if (receivingCalendar) {
+ receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+ }
+ // the initial calendar might have an dummy drag state from displayDrag
+ if (initialCalendar !== receivingCalendar) {
+ initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+ }
+ };
+ EventDragging.prototype.cleanup = function () {
+ this.subjectSeg = null;
+ this.isDragging = false;
+ this.eventRange = null;
+ this.relevantEvents = null;
+ this.receivingCalendar = null;
+ this.validMutation = null;
+ this.mutatedRelevantEvents = null;
+ };
+ EventDragging.SELECTOR = '.fc-draggable, .fc-resizable'; // TODO: test this in IE11
+ return EventDragging;
+ }(core.Interaction));
+ function computeEventMutation(hit0, hit1, massagers) {
+ var dateSpan0 = hit0.dateSpan;
+ var dateSpan1 = hit1.dateSpan;
+ var date0 = dateSpan0.range.start;
+ var date1 = dateSpan1.range.start;
+ var standardProps = {};
+ if (dateSpan0.allDay !== dateSpan1.allDay) {
+ standardProps.allDay = dateSpan1.allDay;
+ standardProps.hasEnd = hit1.component.opt('allDayMaintainDuration');
+ if (dateSpan1.allDay) {
+ // means date1 is already start-of-day,
+ // but date0 needs to be converted
+ date0 = core.startOfDay(date0);
+ }
+ }
+ var delta = core.diffDates(date0, date1, hit0.component.dateEnv, hit0.component === hit1.component ?
+ hit0.component.largeUnit :
+ null);
+ if (delta.milliseconds) { // has hours/minutes/seconds
+ standardProps.allDay = false;
+ }
+ var mutation = {
+ startDelta: delta,
+ endDelta: delta,
+ standardProps: standardProps
+ };
+ for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
+ var massager = massagers_1[_i];
+ massager(mutation, hit0, hit1);
+ }
+ return mutation;
+ }
+ function getComponentTouchDelay$1(component) {
+ var delay = component.opt('eventLongPressDelay');
+ if (delay == null) {
+ delay = component.opt('longPressDelay');
+ }
+ return delay;
+ }
+
+ var EventDragging$1 = /** @class */ (function (_super) {
+ __extends(EventDragging, _super);
+ function EventDragging(settings) {
+ var _this = _super.call(this, settings) || this;
+ // internal state
+ _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
+ _this.eventRange = null;
+ _this.relevantEvents = null;
+ _this.validMutation = null;
+ _this.mutatedRelevantEvents = null;
+ _this.handlePointerDown = function (ev) {
+ var component = _this.component;
+ var seg = _this.querySeg(ev);
+ var eventRange = _this.eventRange = seg.eventRange;
+ _this.dragging.minDistance = component.opt('eventDragMinDistance');
+ // if touch, need to be working with a selected event
+ _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
+ (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
+ };
+ _this.handleDragStart = function (ev) {
+ var calendar = _this.component.calendar;
+ var eventRange = _this.eventRange;
+ _this.relevantEvents = core.getRelevantEvents(calendar.state.eventStore, _this.eventRange.instance.instanceId);
+ _this.draggingSeg = _this.querySeg(ev);
+ calendar.unselect();
+ calendar.publiclyTrigger('eventResizeStart', [
+ {
+ el: _this.draggingSeg.el,
+ event: new core.EventApi(calendar, eventRange.def, eventRange.instance),
+ jsEvent: ev.origEvent,
+ view: _this.component.view
+ }
+ ]);
+ };
+ _this.handleHitUpdate = function (hit, isFinal, ev) {
+ var calendar = _this.component.calendar;
+ var relevantEvents = _this.relevantEvents;
+ var initialHit = _this.hitDragging.initialHit;
+ var eventInstance = _this.eventRange.instance;
+ var mutation = null;
+ var mutatedRelevantEvents = null;
+ var isInvalid = false;
+ var interaction = {
+ affectedEvents: relevantEvents,
+ mutatedEvents: core.createEmptyEventStore(),
+ isEvent: true,
+ origSeg: _this.draggingSeg
+ };
+ if (hit) {
+ mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-start-resizer'), eventInstance.range, calendar.pluginSystem.hooks.eventResizeJoinTransforms);
+ }
+ if (mutation) {
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, calendar.eventUiBases, mutation, calendar);
+ interaction.mutatedEvents = mutatedRelevantEvents;
+ if (!_this.component.isInteractionValid(interaction)) {
+ isInvalid = true;
+ mutation = null;
+ mutatedRelevantEvents = null;
+ interaction.mutatedEvents = null;
+ }
+ }
+ if (mutatedRelevantEvents) {
+ calendar.dispatch({
+ type: 'SET_EVENT_RESIZE',
+ state: interaction
+ });
+ }
+ else {
+ calendar.dispatch({ type: 'UNSET_EVENT_RESIZE' });
+ }
+ if (!isInvalid) {
+ core.enableCursor();
+ }
+ else {
+ core.disableCursor();
+ }
+ if (!isFinal) {
+ if (mutation && isHitsEqual(initialHit, hit)) {
+ mutation = null;
+ }
+ _this.validMutation = mutation;
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
+ }
+ };
+ _this.handleDragEnd = function (ev) {
+ var calendar = _this.component.calendar;
+ var view = _this.component.view;
+ var eventDef = _this.eventRange.def;
+ var eventInstance = _this.eventRange.instance;
+ var eventApi = new core.EventApi(calendar, eventDef, eventInstance);
+ var relevantEvents = _this.relevantEvents;
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
+ calendar.publiclyTrigger('eventResizeStop', [
+ {
+ el: _this.draggingSeg.el,
+ event: eventApi,
+ jsEvent: ev.origEvent,
+ view: view
+ }
+ ]);
+ if (_this.validMutation) {
+ calendar.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: mutatedRelevantEvents
+ });
+ calendar.publiclyTrigger('eventResize', [
+ {
+ el: _this.draggingSeg.el,
+ startDelta: _this.validMutation.startDelta || core.createDuration(0),
+ endDelta: _this.validMutation.endDelta || core.createDuration(0),
+ prevEvent: eventApi,
+ event: new core.EventApi(// the data AFTER the mutation
+ calendar, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
+ revert: function () {
+ calendar.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: relevantEvents
+ });
+ },
+ jsEvent: ev.origEvent,
+ view: view
+ }
+ ]);
+ }
+ else {
+ calendar.publiclyTrigger('_noEventResize');
+ }
+ // reset all internal state
+ _this.draggingSeg = null;
+ _this.relevantEvents = null;
+ _this.validMutation = null;
+ // okay to keep eventInstance around. useful to set it in handlePointerDown
+ };
+ var component = settings.component;
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
+ dragging.pointer.selector = '.fc-resizer';
+ dragging.touchScrollAllowed = false;
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
+ return _this;
+ }
+ EventDragging.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ EventDragging.prototype.querySeg = function (ev) {
+ return core.getElSeg(core.elementClosest(ev.subjectEl, this.component.fgSegSelector));
+ };
+ return EventDragging;
+ }(core.Interaction));
+ function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
+ var dateEnv = hit0.component.dateEnv;
+ var date0 = hit0.dateSpan.range.start;
+ var date1 = hit1.dateSpan.range.start;
+ var delta = core.diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
+ var props = {};
+ for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
+ var transform = transforms_1[_i];
+ var res = transform(hit0, hit1);
+ if (res === false) {
+ return null;
+ }
+ else if (res) {
+ __assign(props, res);
+ }
+ }
+ if (isFromStart) {
+ if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
+ props.startDelta = delta;
+ return props;
+ }
+ }
+ else {
+ if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
+ props.endDelta = delta;
+ return props;
+ }
+ }
+ return null;
+ }
+
+ var UnselectAuto = /** @class */ (function () {
+ function UnselectAuto(calendar) {
+ var _this = this;
+ this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
+ this.onSelect = function (selectInfo) {
+ if (selectInfo.jsEvent) {
+ _this.isRecentPointerDateSelect = true;
+ }
+ };
+ this.onDocumentPointerUp = function (pev) {
+ var _a = _this, calendar = _a.calendar, documentPointer = _a.documentPointer;
+ var state = calendar.state;
+ // touch-scrolling should never unfocus any type of selection
+ if (!documentPointer.wasTouchScroll) {
+ if (state.dateSelection && // an existing date selection?
+ !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
+ ) {
+ var unselectAuto = calendar.viewOpt('unselectAuto');
+ var unselectCancel = calendar.viewOpt('unselectCancel');
+ if (unselectAuto && (!unselectAuto || !core.elementClosest(documentPointer.downEl, unselectCancel))) {
+ calendar.unselect(pev);
+ }
+ }
+ if (state.eventSelection && // an existing event selected?
+ !core.elementClosest(documentPointer.downEl, EventDragging.SELECTOR) // interaction DIDN'T start on an event
+ ) {
+ calendar.dispatch({ type: 'UNSELECT_EVENT' });
+ }
+ }
+ _this.isRecentPointerDateSelect = false;
+ };
+ this.calendar = calendar;
+ var documentPointer = this.documentPointer = new PointerDragging(document);
+ documentPointer.shouldIgnoreMove = true;
+ documentPointer.shouldWatchScroll = false;
+ documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
+ /*
+ TODO: better way to know about whether there was a selection with the pointer
+ */
+ calendar.on('select', this.onSelect);
+ }
+ UnselectAuto.prototype.destroy = function () {
+ this.calendar.off('select', this.onSelect);
+ this.documentPointer.destroy();
+ };
+ return UnselectAuto;
+ }());
+
+ /*
+ Given an already instantiated draggable object for one-or-more elements,
+ Interprets any dragging as an attempt to drag an events that lives outside
+ of a calendar onto a calendar.
+ */
+ var ExternalElementDragging = /** @class */ (function () {
+ function ExternalElementDragging(dragging, suppliedDragMeta) {
+ var _this = this;
+ this.receivingCalendar = null;
+ this.droppableEvent = null; // will exist for all drags, even if create:false
+ this.suppliedDragMeta = null;
+ this.dragMeta = null;
+ this.handleDragStart = function (ev) {
+ _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
+ };
+ this.handleHitUpdate = function (hit, isFinal, ev) {
+ var dragging = _this.hitDragging.dragging;
+ var receivingCalendar = null;
+ var droppableEvent = null;
+ var isInvalid = false;
+ var interaction = {
+ affectedEvents: core.createEmptyEventStore(),
+ mutatedEvents: core.createEmptyEventStore(),
+ isEvent: _this.dragMeta.create,
+ origSeg: null
+ };
+ if (hit) {
+ receivingCalendar = hit.component.calendar;
+ if (_this.canDropElOnCalendar(ev.subjectEl, receivingCalendar)) {
+ droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingCalendar);
+ interaction.mutatedEvents = core.eventTupleToStore(droppableEvent);
+ isInvalid = !core.isInteractionValid(interaction, receivingCalendar);
+ if (isInvalid) {
+ interaction.mutatedEvents = core.createEmptyEventStore();
+ droppableEvent = null;
+ }
+ }
+ }
+ _this.displayDrag(receivingCalendar, interaction);
+ // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
+ // TODO: wish we could somehow wait for dispatch to guarantee render
+ dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-mirror'));
+ if (!isInvalid) {
+ core.enableCursor();
+ }
+ else {
+ core.disableCursor();
+ }
+ if (!isFinal) {
+ dragging.setMirrorNeedsRevert(!droppableEvent);
+ _this.receivingCalendar = receivingCalendar;
+ _this.droppableEvent = droppableEvent;
+ }
+ };
+ this.handleDragEnd = function (pev) {
+ var _a = _this, receivingCalendar = _a.receivingCalendar, droppableEvent = _a.droppableEvent;
+ _this.clearDrag();
+ if (receivingCalendar && droppableEvent) {
+ var finalHit = _this.hitDragging.finalHit;
+ var finalView = finalHit.component.view;
+ var dragMeta = _this.dragMeta;
+ var arg = receivingCalendar.buildDatePointApi(finalHit.dateSpan);
+ arg.draggedEl = pev.subjectEl;
+ arg.jsEvent = pev.origEvent;
+ arg.view = finalView;
+ receivingCalendar.publiclyTrigger('drop', [arg]);
+ if (dragMeta.create) {
+ receivingCalendar.dispatch({
+ type: 'MERGE_EVENTS',
+ eventStore: core.eventTupleToStore(droppableEvent)
+ });
+ if (pev.isTouch) {
+ receivingCalendar.dispatch({
+ type: 'SELECT_EVENT',
+ eventInstanceId: droppableEvent.instance.instanceId
+ });
+ }
+ // signal that an external event landed
+ receivingCalendar.publiclyTrigger('eventReceive', [
+ {
+ draggedEl: pev.subjectEl,
+ event: new core.EventApi(receivingCalendar, droppableEvent.def, droppableEvent.instance),
+ view: finalView
+ }
+ ]);
+ }
+ }
+ _this.receivingCalendar = null;
+ _this.droppableEvent = null;
+ };
+ var hitDragging = this.hitDragging = new HitDragging(dragging, core.interactionSettingsStore);
+ hitDragging.requireInitial = false; // will start outside of a component
+ hitDragging.emitter.on('dragstart', this.handleDragStart);
+ hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
+ hitDragging.emitter.on('dragend', this.handleDragEnd);
+ this.suppliedDragMeta = suppliedDragMeta;
+ }
+ ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
+ if (typeof this.suppliedDragMeta === 'object') {
+ return core.parseDragMeta(this.suppliedDragMeta);
+ }
+ else if (typeof this.suppliedDragMeta === 'function') {
+ return core.parseDragMeta(this.suppliedDragMeta(subjectEl));
+ }
+ else {
+ return getDragMetaFromEl(subjectEl);
+ }
+ };
+ ExternalElementDragging.prototype.displayDrag = function (nextCalendar, state) {
+ var prevCalendar = this.receivingCalendar;
+ if (prevCalendar && prevCalendar !== nextCalendar) {
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+ }
+ if (nextCalendar) {
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
+ }
+ };
+ ExternalElementDragging.prototype.clearDrag = function () {
+ if (this.receivingCalendar) {
+ this.receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+ }
+ };
+ ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingCalendar) {
+ var dropAccept = receivingCalendar.opt('dropAccept');
+ if (typeof dropAccept === 'function') {
+ return dropAccept(el);
+ }
+ else if (typeof dropAccept === 'string' && dropAccept) {
+ return Boolean(core.elementMatches(el, dropAccept));
+ }
+ return true;
+ };
+ return ExternalElementDragging;
+ }());
+ // Utils for computing event store from the DragMeta
+ // ----------------------------------------------------------------------------------------------------
+ function computeEventForDateSpan(dateSpan, dragMeta, calendar) {
+ var defProps = __assign({}, dragMeta.leftoverProps);
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.externalDefTransforms; _i < _a.length; _i++) {
+ var transform = _a[_i];
+ __assign(defProps, transform(dateSpan, dragMeta));
+ }
+ var def = core.parseEventDef(defProps, dragMeta.sourceId, dateSpan.allDay, calendar.opt('forceEventDuration') || Boolean(dragMeta.duration), // hasEnd
+ calendar);
+ var start = dateSpan.range.start;
+ // only rely on time info if drop zone is all-day,
+ // otherwise, we already know the time
+ if (dateSpan.allDay && dragMeta.startTime) {
+ start = calendar.dateEnv.add(start, dragMeta.startTime);
+ }
+ var end = dragMeta.duration ?
+ calendar.dateEnv.add(start, dragMeta.duration) :
+ calendar.getDefaultEventEnd(dateSpan.allDay, start);
+ var instance = core.createEventInstance(def.defId, { start: start, end: end });
+ return { def: def, instance: instance };
+ }
+ // Utils for extracting data from element
+ // ----------------------------------------------------------------------------------------------------
+ function getDragMetaFromEl(el) {
+ var str = getEmbeddedElData(el, 'event');
+ var obj = str ?
+ JSON.parse(str) :
+ { create: false }; // if no embedded data, assume no event creation
+ return core.parseDragMeta(obj);
+ }
+ core.config.dataAttrPrefix = '';
+ function getEmbeddedElData(el, name) {
+ var prefix = core.config.dataAttrPrefix;
+ var prefixedName = (prefix ? prefix + '-' : '') + name;
+ return el.getAttribute('data-' + prefixedName) || '';
+ }
+
+ /*
+ Makes an element (that is *external* to any calendar) draggable.
+ Can pass in data that determines how an event will be created when dropped onto a calendar.
+ Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
+ */
+ var ExternalDraggable = /** @class */ (function () {
+ function ExternalDraggable(el, settings) {
+ var _this = this;
+ if (settings === void 0) { settings = {}; }
+ this.handlePointerDown = function (ev) {
+ var dragging = _this.dragging;
+ var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
+ dragging.minDistance =
+ minDistance != null ?
+ minDistance :
+ (ev.isTouch ? 0 : core.globalDefaults.eventDragMinDistance);
+ dragging.delay =
+ ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
+ (longPressDelay != null ? longPressDelay : core.globalDefaults.longPressDelay) :
+ 0;
+ };
+ this.handleDragStart = function (ev) {
+ if (ev.isTouch &&
+ _this.dragging.delay &&
+ ev.subjectEl.classList.contains('fc-event')) {
+ _this.dragging.mirror.getMirrorEl().classList.add('fc-selected');
+ }
+ };
+ this.settings = settings;
+ var dragging = this.dragging = new FeaturefulElementDragging(el);
+ dragging.touchScrollAllowed = false;
+ if (settings.itemSelector != null) {
+ dragging.pointer.selector = settings.itemSelector;
+ }
+ if (settings.appendTo != null) {
+ dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
+ }
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
+ dragging.emitter.on('dragstart', this.handleDragStart);
+ new ExternalElementDragging(dragging, settings.eventData);
+ }
+ ExternalDraggable.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ return ExternalDraggable;
+ }());
+
+ /*
+ Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
+ The third-party system is responsible for drawing the visuals effects of the drag.
+ This class simply monitors for pointer movements and fires events.
+ It also has the ability to hide the moving element (the "mirror") during the drag.
+ */
+ var InferredElementDragging = /** @class */ (function (_super) {
+ __extends(InferredElementDragging, _super);
+ function InferredElementDragging(containerEl) {
+ var _this = _super.call(this, containerEl) || this;
+ _this.shouldIgnoreMove = false;
+ _this.mirrorSelector = '';
+ _this.currentMirrorEl = null;
+ _this.handlePointerDown = function (ev) {
+ _this.emitter.trigger('pointerdown', ev);
+ if (!_this.shouldIgnoreMove) {
+ // fire dragstart right away. does not support delay or min-distance
+ _this.emitter.trigger('dragstart', ev);
+ }
+ };
+ _this.handlePointerMove = function (ev) {
+ if (!_this.shouldIgnoreMove) {
+ _this.emitter.trigger('dragmove', ev);
+ }
+ };
+ _this.handlePointerUp = function (ev) {
+ _this.emitter.trigger('pointerup', ev);
+ if (!_this.shouldIgnoreMove) {
+ // fire dragend right away. does not support a revert animation
+ _this.emitter.trigger('dragend', ev);
+ }
+ };
+ var pointer = _this.pointer = new PointerDragging(containerEl);
+ pointer.emitter.on('pointerdown', _this.handlePointerDown);
+ pointer.emitter.on('pointermove', _this.handlePointerMove);
+ pointer.emitter.on('pointerup', _this.handlePointerUp);
+ return _this;
+ }
+ InferredElementDragging.prototype.destroy = function () {
+ this.pointer.destroy();
+ };
+ InferredElementDragging.prototype.setIgnoreMove = function (bool) {
+ this.shouldIgnoreMove = bool;
+ };
+ InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
+ if (bool) {
+ // restore a previously hidden element.
+ // use the reference in case the selector class has already been removed.
+ if (this.currentMirrorEl) {
+ this.currentMirrorEl.style.visibility = '';
+ this.currentMirrorEl = null;
+ }
+ }
+ else {
+ var mirrorEl = this.mirrorSelector ?
+ document.querySelector(this.mirrorSelector) :
+ null;
+ if (mirrorEl) {
+ this.currentMirrorEl = mirrorEl;
+ mirrorEl.style.visibility = 'hidden';
+ }
+ }
+ };
+ return InferredElementDragging;
+ }(core.ElementDragging));
+
+ /*
+ Bridges third-party drag-n-drop systems with FullCalendar.
+ Must be instantiated and destroyed by caller.
+ */
+ var ThirdPartyDraggable = /** @class */ (function () {
+ function ThirdPartyDraggable(containerOrSettings, settings) {
+ var containerEl = document;
+ if (
+ // wish we could just test instanceof EventTarget, but doesn't work in IE11
+ containerOrSettings === document ||
+ containerOrSettings instanceof Element) {
+ containerEl = containerOrSettings;
+ settings = settings || {};
+ }
+ else {
+ settings = (containerOrSettings || {});
+ }
+ var dragging = this.dragging = new InferredElementDragging(containerEl);
+ if (typeof settings.itemSelector === 'string') {
+ dragging.pointer.selector = settings.itemSelector;
+ }
+ else if (containerEl === document) {
+ dragging.pointer.selector = '[data-event]';
+ }
+ if (typeof settings.mirrorSelector === 'string') {
+ dragging.mirrorSelector = settings.mirrorSelector;
+ }
+ new ExternalElementDragging(dragging, settings.eventData);
+ }
+ ThirdPartyDraggable.prototype.destroy = function () {
+ this.dragging.destroy();
+ };
+ return ThirdPartyDraggable;
+ }());
+
+ var main = core.createPlugin({
+ componentInteractions: [DateClicking, DateSelecting, EventDragging, EventDragging$1],
+ calendarInteractions: [UnselectAuto],
+ elementDraggingImpl: FeaturefulElementDragging
+ });
+
+ exports.Draggable = ExternalDraggable;
+ exports.FeaturefulElementDragging = FeaturefulElementDragging;
+ exports.PointerDragging = PointerDragging;
+ exports.ThirdPartyDraggable = ThirdPartyDraggable;
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/interaction/main.min.js b/library/fullcalendar/packages/interaction/main.min.js
new file mode 100644
index 000000000..58c189c8a
--- /dev/null
+++ b/library/fullcalendar/packages/interaction/main.min.js
@@ -0,0 +1,21 @@
+/*!
+FullCalendar Interaction Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarInteraction={},e.FullCalendar))}(this,function(e,t){"use strict";function n(e,t){function n(){this.constructor=e}m(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}function r(e){return 0===e.button&&!e.ctrlKey}function i(){y++,setTimeout(function(){y--},t.config.touchMouseIgnoreWait)}function o(){D++||window.addEventListener("touchmove",l,{passive:!1})}function a(){--D||window.removeEventListener("touchmove",l,{passive:!1})}function l(e){w&&e.preventDefault()}function s(e){var t=e.tagName;return"HTML"===t||"BODY"===t}function c(e,n){return!e&&!n||Boolean(e)===Boolean(n)&&t.isDateSpansEqual(e.dateSpan,n.dateSpan)}function d(e){var t=e.opt("selectLongPressDelay");return null==t&&(t=e.opt("longPressDelay")),t}function u(e,n,r){var i=e.dateSpan,o=n.dateSpan,a=[i.range.start,i.range.end,o.range.start,o.range.end];a.sort(t.compareNumbers);for(var l={},s=0,c=r;s<c.length;s++){var d=c[s],u=d(e,n);if(!1===u)return null;u&&S(l,u)}return l.range={start:a[0],end:a[3]},l.allDay=i.allDay,l}function g(e,n,r){var i=e.dateSpan,o=n.dateSpan,a=i.range.start,l=o.range.start,s={};i.allDay!==o.allDay&&(s.allDay=o.allDay,s.hasEnd=n.component.opt("allDayMaintainDuration"),o.allDay&&(a=t.startOfDay(a)));var c=t.diffDates(a,l,e.component.dateEnv,e.component===n.component?e.component.largeUnit:null);c.milliseconds&&(s.allDay=!1);for(var d={startDelta:c,endDelta:c,standardProps:s},u=0,g=r;u<g.length;u++){(0,g[u])(d,e,n)}return d}function h(e){var t=e.opt("eventLongPressDelay");return null==t&&(t=e.opt("longPressDelay")),t}function p(e,n,r,i,o){for(var a=e.component.dateEnv,l=e.dateSpan.range.start,s=n.dateSpan.range.start,c=t.diffDates(l,s,a,e.component.largeUnit),d={},u=0,g=o;u<g.length;u++){var h=g[u],p=h(e,n);if(!1===p)return null;p&&S(d,p)}if(r){if(a.add(i.start,c)<i.end)return d.startDelta=c,d}else if(a.add(i.end,c)>i.start)return d.endDelta=c,d;return null}function v(e,n,r){for(var i=S({},n.leftoverProps),o=0,a=r.pluginSystem.hooks.externalDefTransforms;o<a.length;o++){var l=a[o];S(i,l(e,n))}var s=t.parseEventDef(i,n.sourceId,e.allDay,r.opt("forceEventDuration")||Boolean(n.duration),r),c=e.range.start;e.allDay&&n.startTime&&(c=r.dateEnv.add(c,n.startTime));var d=n.duration?r.dateEnv.add(c,n.duration):r.getDefaultEventEnd(e.allDay,c);return{def:s,instance:t.createEventInstance(s.defId,{start:c,end:d})}}function f(e){var n=E(e,"event"),r=n?JSON.parse(n):{create:!1};return t.parseDragMeta(r)}function E(e,n){var r=t.config.dataAttrPrefix,i=(r?r+"-":"")+n;return e.getAttribute("data-"+i)||""}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var m=function(e,t){return(m=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},S=function(){return S=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++){t=arguments[n];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])}return e},S.apply(this,arguments)};t.config.touchMouseIgnoreWait=500;var y=0,D=0,w=!1,T=function(){function e(e){var n=this;this.subjectEl=null,this.downEl=null,this.selector="",this.handleSelector="",this.shouldIgnoreMove=!1,this.shouldWatchScroll=!0,this.isDragging=!1,this.isTouchDragging=!1,this.wasTouchScroll=!1,this.handleMouseDown=function(e){if(!n.shouldIgnoreMouse()&&r(e)&&n.tryStart(e)){var t=n.createEventFromMouse(e,!0);n.emitter.trigger("pointerdown",t),n.initScrollWatch(t),n.shouldIgnoreMove||document.addEventListener("mousemove",n.handleMouseMove),document.addEventListener("mouseup",n.handleMouseUp)}},this.handleMouseMove=function(e){var t=n.createEventFromMouse(e);n.recordCoords(t),n.emitter.trigger("pointermove",t)},this.handleMouseUp=function(e){document.removeEventListener("mousemove",n.handleMouseMove),document.removeEventListener("mouseup",n.handleMouseUp),n.emitter.trigger("pointerup",n.createEventFromMouse(e)),n.cleanup()},this.handleTouchStart=function(e){if(n.tryStart(e)){n.isTouchDragging=!0;var t=n.createEventFromTouch(e,!0);n.emitter.trigger("pointerdown",t),n.initScrollWatch(t);var r=e.target;n.shouldIgnoreMove||r.addEventListener("touchmove",n.handleTouchMove),r.addEventListener("touchend",n.handleTouchEnd),r.addEventListener("touchcancel",n.handleTouchEnd),window.addEventListener("scroll",n.handleTouchScroll,!0)}},this.handleTouchMove=function(e){var t=n.createEventFromTouch(e);n.recordCoords(t),n.emitter.trigger("pointermove",t)},this.handleTouchEnd=function(e){if(n.isDragging){var t=e.target;t.removeEventListener("touchmove",n.handleTouchMove),t.removeEventListener("touchend",n.handleTouchEnd),t.removeEventListener("touchcancel",n.handleTouchEnd),window.removeEventListener("scroll",n.handleTouchScroll,!0),n.emitter.trigger("pointerup",n.createEventFromTouch(e)),n.cleanup(),n.isTouchDragging=!1,i()}},this.handleTouchScroll=function(){n.wasTouchScroll=!0},this.handleScroll=function(e){if(!n.shouldIgnoreMove){var t=window.pageXOffset-n.prevScrollX+n.prevPageX,r=window.pageYOffset-n.prevScrollY+n.prevPageY;n.emitter.trigger("pointermove",{origEvent:e,isTouch:n.isTouchDragging,subjectEl:n.subjectEl,pageX:t,pageY:r,deltaX:t-n.origPageX,deltaY:r-n.origPageY})}},this.containerEl=e,this.emitter=new t.EmitterMixin,e.addEventListener("mousedown",this.handleMouseDown),e.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),o()}return e.prototype.destroy=function(){this.containerEl.removeEventListener("mousedown",this.handleMouseDown),this.containerEl.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),a()},e.prototype.tryStart=function(e){var n=this.querySubjectEl(e),r=e.target;return!(!n||this.handleSelector&&!t.elementClosest(r,this.handleSelector))&&(this.subjectEl=n,this.downEl=r,this.isDragging=!0,this.wasTouchScroll=!1,!0)},e.prototype.cleanup=function(){w=!1,this.isDragging=!1,this.subjectEl=null,this.downEl=null,this.destroyScrollWatch()},e.prototype.querySubjectEl=function(e){return this.selector?t.elementClosest(e.target,this.selector):this.containerEl},e.prototype.shouldIgnoreMouse=function(){return y||this.isTouchDragging},e.prototype.cancelTouchScroll=function(){this.isDragging&&(w=!0)},e.prototype.initScrollWatch=function(e){this.shouldWatchScroll&&(this.recordCoords(e),window.addEventListener("scroll",this.handleScroll,!0))},e.prototype.recordCoords=function(e){this.shouldWatchScroll&&(this.prevPageX=e.pageX,this.prevPageY=e.pageY,this.prevScrollX=window.pageXOffset,this.prevScrollY=window.pageYOffset)},e.prototype.destroyScrollWatch=function(){this.shouldWatchScroll&&window.removeEventListener("scroll",this.handleScroll,!0)},e.prototype.createEventFromMouse=function(e,t){var n=0,r=0;return t?(this.origPageX=e.pageX,this.origPageY=e.pageY):(n=e.pageX-this.origPageX,r=e.pageY-this.origPageY),{origEvent:e,isTouch:!1,subjectEl:this.subjectEl,pageX:e.pageX,pageY:e.pageY,deltaX:n,deltaY:r}},e.prototype.createEventFromTouch=function(e,t){var n,r,i=e.touches,o=0,a=0;return i&&i.length?(n=i[0].pageX,r=i[0].pageY):(n=e.pageX,r=e.pageY),t?(this.origPageX=n,this.origPageY=r):(o=n-this.origPageX,a=r-this.origPageY),{origEvent:e,isTouch:!0,subjectEl:this.subjectEl,pageX:n,pageY:r,deltaX:o,deltaY:a}},e}(),M=function(){function e(){this.isVisible=!1,this.sourceEl=null,this.mirrorEl=null,this.sourceElRect=null,this.parentNode=document.body,this.zIndex=9999,this.revertDuration=0}return e.prototype.start=function(e,t,n){this.sourceEl=e,this.sourceElRect=this.sourceEl.getBoundingClientRect(),this.origScreenX=t-window.pageXOffset,this.origScreenY=n-window.pageYOffset,this.deltaX=0,this.deltaY=0,this.updateElPosition()},e.prototype.handleMove=function(e,t){this.deltaX=e-window.pageXOffset-this.origScreenX,this.deltaY=t-window.pageYOffset-this.origScreenY,this.updateElPosition()},e.prototype.setIsVisible=function(e){e?this.isVisible||(this.mirrorEl&&(this.mirrorEl.style.display=""),this.isVisible=e,this.updateElPosition()):this.isVisible&&(this.mirrorEl&&(this.mirrorEl.style.display="none"),this.isVisible=e)},e.prototype.stop=function(e,t){var n=this,r=function(){n.cleanup(),t()};e&&this.mirrorEl&&this.isVisible&&this.revertDuration&&(this.deltaX||this.deltaY)?this.doRevertAnimation(r,this.revertDuration):setTimeout(r,0)},e.prototype.doRevertAnimation=function(e,n){var r=this.mirrorEl,i=this.sourceEl.getBoundingClientRect();r.style.transition="top "+n+"ms,left "+n+"ms",t.applyStyle(r,{left:i.left,top:i.top}),t.whenTransitionDone(r,function(){r.style.transition="",e()})},e.prototype.cleanup=function(){this.mirrorEl&&(t.removeElement(this.mirrorEl),this.mirrorEl=null),this.sourceEl=null},e.prototype.updateElPosition=function(){this.sourceEl&&this.isVisible&&t.applyStyle(this.getMirrorEl(),{left:this.sourceElRect.left+this.deltaX,top:this.sourceElRect.top+this.deltaY})},e.prototype.getMirrorEl=function(){var e=this.sourceElRect,n=this.mirrorEl;return n||(n=this.mirrorEl=this.sourceEl.cloneNode(!0),n.classList.add("fc-unselectable"),n.classList.add("fc-dragging"),t.applyStyle(n,{position:"fixed",zIndex:this.zIndex,visibility:"",boxSizing:"border-box",width:e.right-e.left,height:e.bottom-e.top,right:"auto",bottom:"auto",margin:0}),this.parentNode.appendChild(n)),n},e}(),b=function(e){function t(t,n){var r=e.call(this)||this;return r.handleScroll=function(){r.scrollTop=r.scrollController.getScrollTop(),r.scrollLeft=r.scrollController.getScrollLeft(),r.handleScrollChange()},r.scrollController=t,r.doesListening=n,r.scrollTop=r.origScrollTop=t.getScrollTop(),r.scrollLeft=r.origScrollLeft=t.getScrollLeft(),r.scrollWidth=t.getScrollWidth(),r.scrollHeight=t.getScrollHeight(),r.clientWidth=t.getClientWidth(),r.clientHeight=t.getClientHeight(),r.clientRect=r.computeClientRect(),r.doesListening&&r.getEventTarget().addEventListener("scroll",r.handleScroll),r}return n(t,e),t.prototype.destroy=function(){this.doesListening&&this.getEventTarget().removeEventListener("scroll",this.handleScroll)},t.prototype.getScrollTop=function(){return this.scrollTop},t.prototype.getScrollLeft=function(){return this.scrollLeft},t.prototype.setScrollTop=function(e){this.scrollController.setScrollTop(e),this.doesListening||(this.scrollTop=Math.max(Math.min(e,this.getMaxScrollTop()),0),this.handleScrollChange())},t.prototype.setScrollLeft=function(e){this.scrollController.setScrollLeft(e),this.doesListening||(this.scrollLeft=Math.max(Math.min(e,this.getMaxScrollLeft()),0),this.handleScrollChange())},t.prototype.getClientWidth=function(){return this.clientWidth},t.prototype.getClientHeight=function(){return this.clientHeight},t.prototype.getScrollWidth=function(){return this.scrollWidth},t.prototype.getScrollHeight=function(){return this.scrollHeight},t.prototype.handleScrollChange=function(){},t}(t.ScrollController),C=function(e){function r(n,r){return e.call(this,new t.ElementScrollController(n),r)||this}return n(r,e),r.prototype.getEventTarget=function(){return this.scrollController.el},r.prototype.computeClientRect=function(){return t.computeInnerRect(this.scrollController.el)},r}(b),R=function(e){function r(n){return e.call(this,new t.WindowScrollController,n)||this}return n(r,e),r.prototype.getEventTarget=function(){return window},r.prototype.computeClientRect=function(){return{left:this.scrollLeft,right:this.scrollLeft+this.clientWidth,top:this.scrollTop,bottom:this.scrollTop+this.clientHeight}},r.prototype.handleScrollChange=function(){this.clientRect=this.computeClientRect()},r}(b),I="function"==typeof performance?performance.now:Date.now,P=function(){function e(){var e=this;this.isEnabled=!0,this.scrollQuery=[window,".fc-scroller"],this.edgeThreshold=50,this.maxVelocity=300,this.pointerScreenX=null,this.pointerScreenY=null,this.isAnimating=!1,this.scrollCaches=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.animate=function(){if(e.isAnimating){var t=e.computeBestEdge(e.pointerScreenX+window.pageXOffset,e.pointerScreenY+window.pageYOffset);if(t){var n=I();e.handleSide(t,(n-e.msSinceRequest)/1e3),e.requestAnimation(n)}else e.isAnimating=!1}}}return e.prototype.start=function(e,t){this.isEnabled&&(this.scrollCaches=this.buildCaches(),this.pointerScreenX=null,this.pointerScreenY=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.handleMove(e,t))},e.prototype.handleMove=function(e,t){if(this.isEnabled){var n=e-window.pageXOffset,r=t-window.pageYOffset,i=null===this.pointerScreenY?0:r-this.pointerScreenY,o=null===this.pointerScreenX?0:n-this.pointerScreenX;i<0?this.everMovedUp=!0:i>0&&(this.everMovedDown=!0),o<0?this.everMovedLeft=!0:o>0&&(this.everMovedRight=!0),this.pointerScreenX=n,this.pointerScreenY=r,this.isAnimating||(this.isAnimating=!0,this.requestAnimation(I()))}},e.prototype.stop=function(){if(this.isEnabled){this.isAnimating=!1;for(var e=0,t=this.scrollCaches;e<t.length;e++){t[e].destroy()}this.scrollCaches=null}},e.prototype.requestAnimation=function(e){this.msSinceRequest=e,requestAnimationFrame(this.animate)},e.prototype.handleSide=function(e,t){var n=e.scrollCache,r=this.edgeThreshold,i=r-e.distance,o=i*i/(r*r)*this.maxVelocity*t,a=1;switch(e.name){case"left":a=-1;case"right":n.setScrollLeft(n.getScrollLeft()+o*a);break;case"top":a=-1;case"bottom":n.setScrollTop(n.getScrollTop()+o*a)}},e.prototype.computeBestEdge=function(e,t){for(var n=this.edgeThreshold,r=null,i=0,o=this.scrollCaches;i<o.length;i++){var a=o[i],l=a.clientRect,s=e-l.left,c=l.right-e,d=t-l.top,u=l.bottom-t;s>=0&&c>=0&&d>=0&&u>=0&&(d<=n&&this.everMovedUp&&a.canScrollUp()&&(!r||r.distance>d)&&(r={scrollCache:a,name:"top",distance:d}),u<=n&&this.everMovedDown&&a.canScrollDown()&&(!r||r.distance>u)&&(r={scrollCache:a,name:"bottom",distance:u}),s<=n&&this.everMovedLeft&&a.canScrollLeft()&&(!r||r.distance>s)&&(r={scrollCache:a,name:"left",distance:s}),c<=n&&this.everMovedRight&&a.canScrollRight()&&(!r||r.distance>c)&&(r={scrollCache:a,name:"right",distance:c}))}return r},e.prototype.buildCaches=function(){return this.queryScrollEls().map(function(e){return e===window?new R(!1):new C(e,!1)})},e.prototype.queryScrollEls=function(){for(var e=[],t=0,n=this.scrollQuery;t<n.length;t++){var r=n[t];"object"==typeof r?e.push(r):e.push.apply(e,Array.prototype.slice.call(document.querySelectorAll(r)))}return e},e}(),L=function(e){function r(n){var r=e.call(this,n)||this;r.delay=null,r.minDistance=0,r.touchScrollAllowed=!0,r.mirrorNeedsRevert=!1,r.isInteracting=!1,r.isDragging=!1,r.isDelayEnded=!1,r.isDistanceSurpassed=!1,r.delayTimeoutId=null,r.onPointerDown=function(e){r.isDragging||(r.isInteracting=!0,r.isDelayEnded=!1,r.isDistanceSurpassed=!1,t.preventSelection(document.body),t.preventContextMenu(document.body),e.isTouch||e.origEvent.preventDefault(),r.emitter.trigger("pointerdown",e),r.pointer.shouldIgnoreMove||(r.mirror.setIsVisible(!1),r.mirror.start(e.subjectEl,e.pageX,e.pageY),r.startDelay(e),r.minDistance||r.handleDistanceSurpassed(e)))},r.onPointerMove=function(e){if(r.isInteracting){if(r.emitter.trigger("pointermove",e),!r.isDistanceSurpassed){var t=r.minDistance,n=void 0,i=e.deltaX,o=e.deltaY;n=i*i+o*o,n>=t*t&&r.handleDistanceSurpassed(e)}r.isDragging&&("scroll"!==e.origEvent.type&&(r.mirror.handleMove(e.pageX,e.pageY),r.autoScroller.handleMove(e.pageX,e.pageY)),r.emitter.trigger("dragmove",e))}},r.onPointerUp=function(e){r.isInteracting&&(r.isInteracting=!1,t.allowSelection(document.body),t.allowContextMenu(document.body),r.emitter.trigger("pointerup",e),r.isDragging&&(r.autoScroller.stop(),r.tryStopDrag(e)),r.delayTimeoutId&&(clearTimeout(r.delayTimeoutId),r.delayTimeoutId=null))};var i=r.pointer=new T(n);return i.emitter.on("pointerdown",r.onPointerDown),i.emitter.on("pointermove",r.onPointerMove),i.emitter.on("pointerup",r.onPointerUp),r.mirror=new M,r.autoScroller=new P,r}return n(r,e),r.prototype.destroy=function(){this.pointer.destroy()},r.prototype.startDelay=function(e){var t=this;"number"==typeof this.delay?this.delayTimeoutId=setTimeout(function(){t.delayTimeoutId=null,t.handleDelayEnd(e)},this.delay):this.handleDelayEnd(e)},r.prototype.handleDelayEnd=function(e){this.isDelayEnded=!0,this.tryStartDrag(e)},r.prototype.handleDistanceSurpassed=function(e){this.isDistanceSurpassed=!0,this.tryStartDrag(e)},r.prototype.tryStartDrag=function(e){this.isDelayEnded&&this.isDistanceSurpassed&&(this.pointer.wasTouchScroll&&!this.touchScrollAllowed||(this.isDragging=!0,this.mirrorNeedsRevert=!1,this.autoScroller.start(e.pageX,e.pageY),this.emitter.trigger("dragstart",e),!1===this.touchScrollAllowed&&this.pointer.cancelTouchScroll()))},r.prototype.tryStopDrag=function(e){this.mirror.stop(this.mirrorNeedsRevert,this.stopDrag.bind(this,e))},r.prototype.stopDrag=function(e){this.isDragging=!1,this.emitter.trigger("dragend",e)},r.prototype.setIgnoreMove=function(e){this.pointer.shouldIgnoreMove=e},r.prototype.setMirrorIsVisible=function(e){this.mirror.setIsVisible(e)},r.prototype.setMirrorNeedsRevert=function(e){this.mirrorNeedsRevert=e},r.prototype.setAutoScrollEnabled=function(e){this.autoScroller.isEnabled=e},r}(t.ElementDragging),j=function(){function e(e){this.origRect=t.computeRect(e),this.scrollCaches=t.getClippingParents(e).map(function(e){return new C(e,!0)})}return e.prototype.destroy=function(){for(var e=0,t=this.scrollCaches;e<t.length;e++){t[e].destroy()}},e.prototype.computeLeft=function(){for(var e=this.origRect.left,t=0,n=this.scrollCaches;t<n.length;t++){var r=n[t];e+=r.origScrollLeft-r.getScrollLeft()}return e},e.prototype.computeTop=function(){for(var e=this.origRect.top,t=0,n=this.scrollCaches;t<n.length;t++){var r=n[t];e+=r.origScrollTop-r.getScrollTop()}return e},e.prototype.isWithinClipping=function(e,n){for(var r={left:e,top:n},i=0,o=this.scrollCaches;i<o.length;i++){var a=o[i];if(!s(a.getEventTarget())&&!t.pointInsideRect(r,a.clientRect))return!1}return!0},e}(),A=function(){function e(e,n){var r=this;this.useSubjectCenter=!1,this.requireInitial=!0,this.initialHit=null,this.movingHit=null,this.finalHit=null,this.handlePointerDown=function(e){var t=r.dragging;r.initialHit=null,r.movingHit=null,r.finalHit=null,r.prepareHits(),r.processFirstCoord(e),r.initialHit||!r.requireInitial?(t.setIgnoreMove(!1),r.emitter.trigger("pointerdown",e)):t.setIgnoreMove(!0)},this.handleDragStart=function(e){r.emitter.trigger("dragstart",e),r.handleMove(e,!0)},this.handleDragMove=function(e){r.emitter.trigger("dragmove",e),r.handleMove(e)},this.handlePointerUp=function(e){r.releaseHits(),r.emitter.trigger("pointerup",e)},this.handleDragEnd=function(e){r.movingHit&&r.emitter.trigger("hitupdate",null,!0,e),r.finalHit=r.movingHit,r.movingHit=null,r.emitter.trigger("dragend",e)},this.droppableStore=n,e.emitter.on("pointerdown",this.handlePointerDown),e.emitter.on("dragstart",this.handleDragStart),e.emitter.on("dragmove",this.handleDragMove),e.emitter.on("pointerup",this.handlePointerUp),e.emitter.on("dragend",this.handleDragEnd),this.dragging=e,this.emitter=new t.EmitterMixin}return e.prototype.processFirstCoord=function(e){var n,r={left:e.pageX,top:e.pageY},i=r,o=e.subjectEl;o!==document&&(n=t.computeRect(o),i=t.constrainPoint(i,n));var a=this.initialHit=this.queryHitForOffset(i.left,i.top);if(a){if(this.useSubjectCenter&&n){var l=t.intersectRects(n,a.rect);l&&(i=t.getRectCenter(l))}this.coordAdjust=t.diffPoints(i,r)}else this.coordAdjust={left:0,top:0}},e.prototype.handleMove=function(e,t){var n=this.queryHitForOffset(e.pageX+this.coordAdjust.left,e.pageY+this.coordAdjust.top);!t&&c(this.movingHit,n)||(this.movingHit=n,this.emitter.trigger("hitupdate",n,!1,e))},e.prototype.prepareHits=function(){this.offsetTrackers=t.mapHash(this.droppableStore,function(e){return new j(e.el)})},e.prototype.releaseHits=function(){var e=this.offsetTrackers;for(var t in e)e[t].destroy();this.offsetTrackers={}},e.prototype.queryHitForOffset=function(e,n){var r=this,i=r.droppableStore,o=r.offsetTrackers,a=null;for(var l in i){var s=i[l].component,c=o[l];if(c.isWithinClipping(e,n)){var d=c.computeLeft(),u=c.computeTop(),g=e-d,h=n-u,p=c.origRect,v=p.right-p.left,f=p.bottom-p.top;if(g>=0&&g<v&&h>=0&&h<f){var E=s.queryHit(g,h,v,f);!E||s.props.dateProfile&&!t.rangeContainsRange(s.props.dateProfile.activeRange,E.dateSpan.range)||a&&!(E.layer>a.layer)||(E.rect.left+=d,E.rect.right+=d,E.rect.top+=u,E.rect.bottom+=u,a=E)}}}return a},e}(),H=function(e){function r(n){var r=e.call(this,n)||this;r.handlePointerDown=function(e){var t=r.dragging;t.setIgnoreMove(!r.component.isValidDateDownEl(t.pointer.downEl))},r.handleDragEnd=function(e){var t=r.component;if(!r.dragging.pointer.wasTouchScroll){var n=r.hitDragging,i=n.initialHit,o=n.finalHit;i&&o&&c(i,o)&&t.calendar.triggerDateClick(i.dateSpan,i.dayEl,t.view,e.origEvent)}};var i=n.component;r.dragging=new L(i.el),r.dragging.autoScroller.isEnabled=!1;var o=r.hitDragging=new A(r.dragging,t.interactionSettingsToStore(n));return o.emitter.on("pointerdown",r.handlePointerDown),o.emitter.on("dragend",r.handleDragEnd),r}return n(r,e),r.prototype.destroy=function(){this.dragging.destroy()},r}(t.Interaction),N=function(e){function r(n){var r=e.call(this,n)||this;r.dragSelection=null,r.handlePointerDown=function(e){var t=r,n=t.component,i=t.dragging,o=n.opt("selectable")&&n.isValidDateDownEl(e.origEvent.target);i.setIgnoreMove(!o),i.delay=e.isTouch?d(n):null},r.handleDragStart=function(e){r.component.calendar.unselect(e)},r.handleHitUpdate=function(e,n){var i=r.component.calendar,o=null,a=!1;e&&((o=u(r.hitDragging.initialHit,e,i.pluginSystem.hooks.dateSelectionTransformers))&&r.component.isDateSelectionValid(o)||(a=!0,o=null)),o?i.dispatch({type:"SELECT_DATES",selection:o}):n||i.dispatch({type:"UNSELECT_DATES"}),a?t.disableCursor():t.enableCursor(),n||(r.dragSelection=o)},r.handlePointerUp=function(e){r.dragSelection&&(r.component.calendar.triggerDateSelect(r.dragSelection,e),r.dragSelection=null)};var i=n.component,o=r.dragging=new L(i.el);o.touchScrollAllowed=!1,o.minDistance=i.opt("selectMinDistance")||0,o.autoScroller.isEnabled=i.opt("dragScroll");var a=r.hitDragging=new A(r.dragging,t.interactionSettingsToStore(n));return a.emitter.on("pointerdown",r.handlePointerDown),a.emitter.on("dragstart",r.handleDragStart),a.emitter.on("hitupdate",r.handleHitUpdate),a.emitter.on("pointerup",r.handlePointerUp),r}return n(r,e),r.prototype.destroy=function(){this.dragging.destroy()},r}(t.Interaction),V=function(e){function r(n){var i=e.call(this,n)||this;i.subjectSeg=null,i.isDragging=!1,i.eventRange=null,i.relevantEvents=null,i.receivingCalendar=null,i.validMutation=null,i.mutatedRelevantEvents=null,i.handlePointerDown=function(e){var n=e.origEvent.target,r=i,o=r.component,a=r.dragging,l=a.mirror,s=o.calendar,c=i.subjectSeg=t.getElSeg(e.subjectEl),d=i.eventRange=c.eventRange,u=d.instance.instanceId;i.relevantEvents=t.getRelevantEvents(s.state.eventStore,u),a.minDistance=e.isTouch?0:o.opt("eventDragMinDistance"),a.delay=e.isTouch&&u!==o.props.eventSelection?h(o):null,l.parentNode=s.el,l.revertDuration=o.opt("dragRevertDuration");var g=o.isValidSegDownEl(n)&&!t.elementClosest(n,".fc-resizer");a.setIgnoreMove(!g),i.isDragging=g&&e.subjectEl.classList.contains("fc-draggable")},i.handleDragStart=function(e){var n=i.component.calendar,r=i.eventRange,o=r.instance.instanceId;e.isTouch?o!==i.component.props.eventSelection&&n.dispatch({type:"SELECT_EVENT",eventInstanceId:o}):n.dispatch({type:"UNSELECT_EVENT"}),i.isDragging&&(n.unselect(e),n.publiclyTrigger("eventDragStart",[{el:i.subjectSeg.el,event:new t.EventApi(n,r.def,r.instance),jsEvent:e.origEvent,view:i.component.view}]))},i.handleHitUpdate=function(e,n){if(i.isDragging){var r=i.relevantEvents,o=i.hitDragging.initialHit,a=i.component.calendar,l=null,s=null,d=null,u=!1,h={affectedEvents:r,mutatedEvents:t.createEmptyEventStore(),isEvent:!0,origSeg:i.subjectSeg};if(e){var p=e.component;l=p.calendar,a===l||p.opt("editable")&&p.opt("droppable")?(s=g(o,e,l.pluginSystem.hooks.eventDragMutationMassagers))&&(d=t.applyMutationToEventStore(r,l.eventUiBases,s,l),h.mutatedEvents=d,p.isInteractionValid(h)||(u=!0,s=null,d=null,h.mutatedEvents=t.createEmptyEventStore())):l=null}i.displayDrag(l,h),u?t.disableCursor():t.enableCursor(),n||(a===l&&c(o,e)&&(s=null),i.dragging.setMirrorNeedsRevert(!s),i.dragging.setMirrorIsVisible(!e||!document.querySelector(".fc-mirror")),i.receivingCalendar=l,i.validMutation=s,i.mutatedRelevantEvents=d)}},i.handlePointerUp=function(){i.isDragging||i.cleanup()},i.handleDragEnd=function(e){if(i.isDragging){var n=i.component.calendar,r=i.component.view,o=i.receivingCalendar,a=i.eventRange.def,l=i.eventRange.instance,s=new t.EventApi(n,a,l),c=i.relevantEvents,d=i.mutatedRelevantEvents,u=i.hitDragging.finalHit;if(i.clearDrag(),n.publiclyTrigger("eventDragStop",[{el:i.subjectSeg.el,event:s,jsEvent:e.origEvent,view:r}]),i.validMutation){if(o===n){n.dispatch({type:"MERGE_EVENTS",eventStore:d});for(var g={},h=0,p=n.pluginSystem.hooks.eventDropTransformers;h<p.length;h++){var v=p[h];S(g,v(i.validMutation,n))}S(g,{el:e.subjectEl,delta:i.validMutation.startDelta,oldEvent:s,event:new t.EventApi(n,d.defs[a.defId],l?d.instances[l.instanceId]:null),revert:function(){n.dispatch({type:"MERGE_EVENTS",eventStore:c})},jsEvent:e.origEvent,view:r}),n.publiclyTrigger("eventDrop",[g])}else if(o){n.publiclyTrigger("eventLeave",[{draggedEl:e.subjectEl,event:s,view:r}]),n.dispatch({type:"REMOVE_EVENT_INSTANCES",instances:i.mutatedRelevantEvents.instances}),o.dispatch({type:"MERGE_EVENTS",eventStore:i.mutatedRelevantEvents}),e.isTouch&&o.dispatch({type:"SELECT_EVENT",eventInstanceId:l.instanceId});var f=o.buildDatePointApi(u.dateSpan);f.draggedEl=e.subjectEl,f.jsEvent=e.origEvent,f.view=u.component,o.publiclyTrigger("drop",[f]),o.publiclyTrigger("eventReceive",[{draggedEl:e.subjectEl,event:new t.EventApi(o,d.defs[a.defId],d.instances[l.instanceId]),view:u.component}])}}else n.publiclyTrigger("_noEventDrop")}i.cleanup()};var o=i.component,a=i.dragging=new L(o.el);a.pointer.selector=r.SELECTOR,a.touchScrollAllowed=!1,a.autoScroller.isEnabled=o.opt("dragScroll");var l=i.hitDragging=new A(i.dragging,t.interactionSettingsStore);return l.useSubjectCenter=n.useEventCenter,l.emitter.on("pointerdown",i.handlePointerDown),l.emitter.on("dragstart",i.handleDragStart),l.emitter.on("hitupdate",i.handleHitUpdate),l.emitter.on("pointerup",i.handlePointerUp),l.emitter.on("dragend",i.handleDragEnd),i}return n(r,e),r.prototype.destroy=function(){this.dragging.destroy()},r.prototype.displayDrag=function(e,n){var r=this.component.calendar,i=this.receivingCalendar;i&&i!==e&&(i===r?i.dispatch({type:"SET_EVENT_DRAG",state:{affectedEvents:n.affectedEvents,mutatedEvents:t.createEmptyEventStore(),isEvent:!0,origSeg:n.origSeg}}):i.dispatch({type:"UNSET_EVENT_DRAG"})),e&&e.dispatch({type:"SET_EVENT_DRAG",state:n})},r.prototype.clearDrag=function(){var e=this.component.calendar,t=this.receivingCalendar;t&&t.dispatch({type:"UNSET_EVENT_DRAG"}),e!==t&&e.dispatch({type:"UNSET_EVENT_DRAG"})},r.prototype.cleanup=function(){this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingCalendar=null,this.validMutation=null,this.mutatedRelevantEvents=null},r.SELECTOR=".fc-draggable, .fc-resizable",r}(t.Interaction),Y=function(e){function r(n){var r=e.call(this,n)||this;r.draggingSeg=null,r.eventRange=null,r.relevantEvents=null,r.validMutation=null,r.mutatedRelevantEvents=null,r.handlePointerDown=function(e){var t=r.component,n=r.querySeg(e),i=r.eventRange=n.eventRange;r.dragging.minDistance=t.opt("eventDragMinDistance"),r.dragging.setIgnoreMove(!r.component.isValidSegDownEl(e.origEvent.target)||e.isTouch&&r.component.props.eventSelection!==i.instance.instanceId)},r.handleDragStart=function(e){var n=r.component.calendar,i=r.eventRange;r.relevantEvents=t.getRelevantEvents(n.state.eventStore,r.eventRange.instance.instanceId),r.draggingSeg=r.querySeg(e),n.unselect(),n.publiclyTrigger("eventResizeStart",[{el:r.draggingSeg.el,event:new t.EventApi(n,i.def,i.instance),jsEvent:e.origEvent,view:r.component.view}])},r.handleHitUpdate=function(e,n,i){var o=r.component.calendar,a=r.relevantEvents,l=r.hitDragging.initialHit,s=r.eventRange.instance,d=null,u=null,g=!1,h={affectedEvents:a,mutatedEvents:t.createEmptyEventStore(),isEvent:!0,origSeg:r.draggingSeg};e&&(d=p(l,e,i.subjectEl.classList.contains("fc-start-resizer"),s.range,o.pluginSystem.hooks.eventResizeJoinTransforms)),d&&(u=t.applyMutationToEventStore(a,o.eventUiBases,d,o),h.mutatedEvents=u,r.component.isInteractionValid(h)||(g=!0,d=null,u=null,h.mutatedEvents=null)),u?o.dispatch({type:"SET_EVENT_RESIZE",state:h}):o.dispatch({type:"UNSET_EVENT_RESIZE"}),g?t.disableCursor():t.enableCursor(),n||(d&&c(l,e)&&(d=null),r.validMutation=d,r.mutatedRelevantEvents=u)},r.handleDragEnd=function(e){var n=r.component.calendar,i=r.component.view,o=r.eventRange.def,a=r.eventRange.instance,l=new t.EventApi(n,o,a),s=r.relevantEvents,c=r.mutatedRelevantEvents;n.publiclyTrigger("eventResizeStop",[{el:r.draggingSeg.el,event:l,jsEvent:e.origEvent,view:i}]),r.validMutation?(n.dispatch({type:"MERGE_EVENTS",eventStore:c}),n.publiclyTrigger("eventResize",[{el:r.draggingSeg.el,startDelta:r.validMutation.startDelta||t.createDuration(0),endDelta:r.validMutation.endDelta||t.createDuration(0),prevEvent:l,event:new t.EventApi(n,c.defs[o.defId],a?c.instances[a.instanceId]:null),revert:function(){n.dispatch({type:"MERGE_EVENTS",eventStore:s})},jsEvent:e.origEvent,view:i}])):n.publiclyTrigger("_noEventResize"),r.draggingSeg=null,r.relevantEvents=null,r.validMutation=null};var i=n.component,o=r.dragging=new L(i.el);o.pointer.selector=".fc-resizer",o.touchScrollAllowed=!1,o.autoScroller.isEnabled=i.opt("dragScroll");var a=r.hitDragging=new A(r.dragging,t.interactionSettingsToStore(n));return a.emitter.on("pointerdown",r.handlePointerDown),a.emitter.on("dragstart",r.handleDragStart),a.emitter.on("hitupdate",r.handleHitUpdate),a.emitter.on("dragend",r.handleDragEnd),r}return n(r,e),r.prototype.destroy=function(){this.dragging.destroy()},r.prototype.querySeg=function(e){return t.getElSeg(t.elementClosest(e.subjectEl,this.component.fgSegSelector))},r}(t.Interaction),_=function(){function e(e){var n=this;this.isRecentPointerDateSelect=!1,this.onSelect=function(e){e.jsEvent&&(n.isRecentPointerDateSelect=!0)},this.onDocumentPointerUp=function(e){var r=n,i=r.calendar,o=r.documentPointer,a=i.state;if(!o.wasTouchScroll){if(a.dateSelection&&!n.isRecentPointerDateSelect){var l=i.viewOpt("unselectAuto"),s=i.viewOpt("unselectCancel");!l||l&&t.elementClosest(o.downEl,s)||i.unselect(e)}a.eventSelection&&!t.elementClosest(o.downEl,V.SELECTOR)&&i.dispatch({type:"UNSELECT_EVENT"})}n.isRecentPointerDateSelect=!1},this.calendar=e;var r=this.documentPointer=new T(document);r.shouldIgnoreMove=!0,r.shouldWatchScroll=!1,r.emitter.on("pointerup",this.onDocumentPointerUp),e.on("select",this.onSelect)}return e.prototype.destroy=function(){this.calendar.off("select",this.onSelect),this.documentPointer.destroy()},e}(),X=function(){function e(e,n){var r=this;this.receivingCalendar=null,this.droppableEvent=null,this.suppliedDragMeta=null,this.dragMeta=null,this.handleDragStart=function(e){r.dragMeta=r.buildDragMeta(e.subjectEl)},this.handleHitUpdate=function(e,n,i){var o=r.hitDragging.dragging,a=null,l=null,s=!1,c={affectedEvents:t.createEmptyEventStore(),mutatedEvents:t.createEmptyEventStore(),isEvent:r.dragMeta.create,origSeg:null};e&&(a=e.component.calendar,r.canDropElOnCalendar(i.subjectEl,a)&&(l=v(e.dateSpan,r.dragMeta,a),c.mutatedEvents=t.eventTupleToStore(l),(s=!t.isInteractionValid(c,a))&&(c.mutatedEvents=t.createEmptyEventStore(),l=null))),r.displayDrag(a,c),o.setMirrorIsVisible(n||!l||!document.querySelector(".fc-mirror")),s?t.disableCursor():t.enableCursor(),n||(o.setMirrorNeedsRevert(!l),r.receivingCalendar=a,r.droppableEvent=l)},this.handleDragEnd=function(e){var n=r,i=n.receivingCalendar,o=n.droppableEvent;if(r.clearDrag(),i&&o){var a=r.hitDragging.finalHit,l=a.component.view,s=r.dragMeta,c=i.buildDatePointApi(a.dateSpan);c.draggedEl=e.subjectEl,c.jsEvent=e.origEvent,c.view=l,i.publiclyTrigger("drop",[c]),s.create&&(i.dispatch({type:"MERGE_EVENTS",eventStore:t.eventTupleToStore(o)}),e.isTouch&&i.dispatch({type:"SELECT_EVENT",eventInstanceId:o.instance.instanceId}),i.publiclyTrigger("eventReceive",[{draggedEl:e.subjectEl,event:new t.EventApi(i,o.def,o.instance),view:l}]))}r.receivingCalendar=null,r.droppableEvent=null};var i=this.hitDragging=new A(e,t.interactionSettingsStore);i.requireInitial=!1,i.emitter.on("dragstart",this.handleDragStart),i.emitter.on("hitupdate",this.handleHitUpdate),i.emitter.on("dragend",this.handleDragEnd),this.suppliedDragMeta=n}return e.prototype.buildDragMeta=function(e){return"object"==typeof this.suppliedDragMeta?t.parseDragMeta(this.suppliedDragMeta):"function"==typeof this.suppliedDragMeta?t.parseDragMeta(this.suppliedDragMeta(e)):f(e)},e.prototype.displayDrag=function(e,t){var n=this.receivingCalendar;n&&n!==e&&n.dispatch({type:"UNSET_EVENT_DRAG"}),e&&e.dispatch({type:"SET_EVENT_DRAG",state:t})},e.prototype.clearDrag=function(){this.receivingCalendar&&this.receivingCalendar.dispatch({type:"UNSET_EVENT_DRAG"})},e.prototype.canDropElOnCalendar=function(e,n){var r=n.opt("dropAccept");return"function"==typeof r?r(e):"string"!=typeof r||!r||Boolean(t.elementMatches(e,r))},e}();t.config.dataAttrPrefix="";var U=function(){function e(e,n){var r=this;void 0===n&&(n={}),this.handlePointerDown=function(e){var n=r.dragging,i=r.settings,o=i.minDistance,a=i.longPressDelay;n.minDistance=null!=o?o:e.isTouch?0:t.globalDefaults.eventDragMinDistance,n.delay=e.isTouch?null!=a?a:t.globalDefaults.longPressDelay:0},this.handleDragStart=function(e){e.isTouch&&r.dragging.delay&&e.subjectEl.classList.contains("fc-event")&&r.dragging.mirror.getMirrorEl().classList.add("fc-selected")},this.settings=n;var i=this.dragging=new L(e);i.touchScrollAllowed=!1,null!=n.itemSelector&&(i.pointer.selector=n.itemSelector),null!=n.appendTo&&(i.mirror.parentNode=n.appendTo),i.emitter.on("pointerdown",this.handlePointerDown),i.emitter.on("dragstart",this.handleDragStart),new X(i,n.eventData)}return e.prototype.destroy=function(){this.dragging.destroy()},e}(),O=function(e){function t(t){var n=e.call(this,t)||this;n.shouldIgnoreMove=!1,n.mirrorSelector="",n.currentMirrorEl=null,n.handlePointerDown=function(e){n.emitter.trigger("pointerdown",e),n.shouldIgnoreMove||n.emitter.trigger("dragstart",e)},n.handlePointerMove=function(e){n.shouldIgnoreMove||n.emitter.trigger("dragmove",e)},n.handlePointerUp=function(e){n.emitter.trigger("pointerup",e),n.shouldIgnoreMove||n.emitter.trigger("dragend",e)};var r=n.pointer=new T(t)
+;return r.emitter.on("pointerdown",n.handlePointerDown),r.emitter.on("pointermove",n.handlePointerMove),r.emitter.on("pointerup",n.handlePointerUp),n}return n(t,e),t.prototype.destroy=function(){this.pointer.destroy()},t.prototype.setIgnoreMove=function(e){this.shouldIgnoreMove=e},t.prototype.setMirrorIsVisible=function(e){if(e)this.currentMirrorEl&&(this.currentMirrorEl.style.visibility="",this.currentMirrorEl=null);else{var t=this.mirrorSelector?document.querySelector(this.mirrorSelector):null;t&&(this.currentMirrorEl=t,t.style.visibility="hidden")}},t}(t.ElementDragging),q=function(){function e(e,t){var n=document;e===document||e instanceof Element?(n=e,t=t||{}):t=e||{};var r=this.dragging=new O(n);"string"==typeof t.itemSelector?r.pointer.selector=t.itemSelector:n===document&&(r.pointer.selector="[data-event]"),"string"==typeof t.mirrorSelector&&(r.mirrorSelector=t.mirrorSelector),new X(r,t.eventData)}return e.prototype.destroy=function(){this.dragging.destroy()},e}(),W=t.createPlugin({componentInteractions:[H,N,V,Y],calendarInteractions:[_],elementDraggingImpl:L});e.Draggable=U,e.FeaturefulElementDragging=L,e.PointerDragging=T,e.ThirdPartyDraggable=q,e.default=W,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/list/main.css b/library/fullcalendar/packages/list/main.css
new file mode 100644
index 000000000..eac305505
--- /dev/null
+++ b/library/fullcalendar/packages/list/main.css
@@ -0,0 +1,101 @@
+/*!
+FullCalendar List View Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+/* List View
+--------------------------------------------------------------------------------------------------*/
+/* possibly reusable */
+.fc-event-dot {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ border-radius: 5px; }
+
+/* view wrapper */
+.fc-rtl .fc-list-view {
+ direction: rtl;
+ /* unlike core views, leverage browser RTL */ }
+
+.fc-list-view {
+ border-width: 1px;
+ border-style: solid; }
+
+/* table resets */
+.fc .fc-list-table {
+ table-layout: auto;
+ /* for shrinkwrapping cell content */ }
+
+.fc-list-table td {
+ border-width: 1px 0 0;
+ padding: 8px 14px; }
+
+.fc-list-table tr:first-child td {
+ border-top-width: 0; }
+
+/* day headings with the list */
+.fc-list-heading {
+ border-bottom-width: 1px; }
+
+.fc-list-heading td {
+ font-weight: bold; }
+
+.fc-ltr .fc-list-heading-main {
+ float: left; }
+
+.fc-ltr .fc-list-heading-alt {
+ float: right; }
+
+.fc-rtl .fc-list-heading-main {
+ float: right; }
+
+.fc-rtl .fc-list-heading-alt {
+ float: left; }
+
+/* event list items */
+.fc-list-item.fc-has-url {
+ cursor: pointer;
+ /* whole row will be clickable */ }
+
+.fc-list-item-marker,
+.fc-list-item-time {
+ white-space: nowrap;
+ width: 1px; }
+
+/* make the dot closer to the event title */
+.fc-ltr .fc-list-item-marker {
+ padding-right: 0; }
+
+.fc-rtl .fc-list-item-marker {
+ padding-left: 0; }
+
+.fc-list-item-title a {
+ /* every event title cell has an <a> tag */
+ text-decoration: none;
+ color: inherit; }
+
+.fc-list-item-title a[href]:hover {
+ /* hover effect only on titles with hrefs */
+ text-decoration: underline; }
+
+/* message when no events */
+.fc-list-empty-wrap2 {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0; }
+
+.fc-list-empty-wrap1 {
+ width: 100%;
+ height: 100%;
+ display: table; }
+
+.fc-list-empty {
+ display: table-cell;
+ vertical-align: middle;
+ text-align: center; }
+
+.fc-unthemed .fc-list-empty {
+ /* theme will provide own background */
+ background-color: #eee; }
diff --git a/library/fullcalendar/packages/list/main.js b/library/fullcalendar/packages/list/main.js
new file mode 100644
index 000000000..abd7c1192
--- /dev/null
+++ b/library/fullcalendar/packages/list/main.js
@@ -0,0 +1,341 @@
+/*!
+FullCalendar List View Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarList = {}, global.FullCalendar));
+}(this, function (exports, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var ListEventRenderer = /** @class */ (function (_super) {
+ __extends(ListEventRenderer, _super);
+ function ListEventRenderer(listView) {
+ var _this = _super.call(this, listView.context) || this;
+ _this.listView = listView;
+ return _this;
+ }
+ ListEventRenderer.prototype.attachSegs = function (segs) {
+ if (!segs.length) {
+ this.listView.renderEmptyMessage();
+ }
+ else {
+ this.listView.renderSegList(segs);
+ }
+ };
+ ListEventRenderer.prototype.detachSegs = function () {
+ };
+ // generates the HTML for a single event row
+ ListEventRenderer.prototype.renderSegHtml = function (seg) {
+ var _a = this.context, view = _a.view, theme = _a.theme;
+ var eventRange = seg.eventRange;
+ var eventDef = eventRange.def;
+ var eventInstance = eventRange.instance;
+ var eventUi = eventRange.ui;
+ var url = eventDef.url;
+ var classes = ['fc-list-item'].concat(eventUi.classNames);
+ var bgColor = eventUi.backgroundColor;
+ var timeHtml;
+ if (eventDef.allDay) {
+ timeHtml = core.getAllDayHtml(view);
+ }
+ else if (core.isMultiDayRange(eventRange.range)) {
+ if (seg.isStart) {
+ timeHtml = core.htmlEscape(this._getTimeText(eventInstance.range.start, seg.end, false // allDay
+ ));
+ }
+ else if (seg.isEnd) {
+ timeHtml = core.htmlEscape(this._getTimeText(seg.start, eventInstance.range.end, false // allDay
+ ));
+ }
+ else { // inner segment that lasts the whole day
+ timeHtml = core.getAllDayHtml(view);
+ }
+ }
+ else {
+ // Display the normal time text for the *event's* times
+ timeHtml = core.htmlEscape(this.getTimeText(eventRange));
+ }
+ if (url) {
+ classes.push('fc-has-url');
+ }
+ return '<tr class="' + classes.join(' ') + '">' +
+ (this.displayEventTime ?
+ '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' +
+ (timeHtml || '') +
+ '</td>' :
+ '') +
+ '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' +
+ '<span class="fc-event-dot"' +
+ (bgColor ?
+ ' style="background-color:' + bgColor + '"' :
+ '') +
+ '></span>' +
+ '</td>' +
+ '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' +
+ '<a' + (url ? ' href="' + core.htmlEscape(url) + '"' : '') + '>' +
+ core.htmlEscape(eventDef.title || '') +
+ '</a>' +
+ '</td>' +
+ '</tr>';
+ };
+ // like "4:00am"
+ ListEventRenderer.prototype.computeEventTimeFormat = function () {
+ return {
+ hour: 'numeric',
+ minute: '2-digit',
+ meridiem: 'short'
+ };
+ };
+ return ListEventRenderer;
+ }(core.FgEventRenderer));
+
+ /*
+ Responsible for the scroller, and forwarding event-related actions into the "grid".
+ */
+ var ListView = /** @class */ (function (_super) {
+ __extends(ListView, _super);
+ function ListView(context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
+ _this.computeDateVars = core.memoize(computeDateVars);
+ _this.eventStoreToSegs = core.memoize(_this._eventStoreToSegs);
+ var eventRenderer = _this.eventRenderer = new ListEventRenderer(_this);
+ _this.renderContent = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer));
+ _this.el.classList.add('fc-list-view');
+ var listViewClassNames = (_this.theme.getClass('listView') || '').split(' '); // wish we didn't have to do this
+ for (var _i = 0, listViewClassNames_1 = listViewClassNames; _i < listViewClassNames_1.length; _i++) {
+ var listViewClassName = listViewClassNames_1[_i];
+ if (listViewClassName) { // in case input was empty string
+ _this.el.classList.add(listViewClassName);
+ }
+ }
+ _this.scroller = new core.ScrollComponent('hidden', // overflow x
+ 'auto' // overflow y
+ );
+ _this.el.appendChild(_this.scroller.el);
+ _this.contentEl = _this.scroller.el; // shortcut
+ context.calendar.registerInteractiveComponent(_this, {
+ el: _this.el
+ // TODO: make aware that it doesn't do Hits
+ });
+ return _this;
+ }
+ ListView.prototype.render = function (props) {
+ var _a = this.computeDateVars(props.dateProfile), dayDates = _a.dayDates, dayRanges = _a.dayRanges;
+ this.dayDates = dayDates;
+ this.renderContent(this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges));
+ };
+ ListView.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.scroller.destroy(); // will remove the Grid too
+ this.calendar.unregisterInteractiveComponent(this);
+ };
+ ListView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
+ _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto);
+ this.eventRenderer.computeSizes(isResize);
+ this.eventRenderer.assignSizes(isResize);
+ this.scroller.clear(); // sets height to 'auto' and clears overflow
+ if (!isAuto) {
+ this.scroller.setHeight(this.computeScrollerHeight(viewHeight));
+ }
+ };
+ ListView.prototype.computeScrollerHeight = function (viewHeight) {
+ return viewHeight -
+ core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+ };
+ ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
+ return this.eventRangesToSegs(core.sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.nextDayThreshold).fg, dayRanges);
+ };
+ ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
+ var segs = [];
+ for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
+ var eventRange = eventRanges_1[_i];
+ segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
+ }
+ return segs;
+ };
+ ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
+ var _a = this, dateEnv = _a.dateEnv, nextDayThreshold = _a.nextDayThreshold;
+ var range = eventRange.range;
+ var allDay = eventRange.def.allDay;
+ var dayIndex;
+ var segRange;
+ var seg;
+ var segs = [];
+ for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
+ segRange = core.intersectRanges(range, dayRanges[dayIndex]);
+ if (segRange) {
+ seg = {
+ component: this,
+ eventRange: eventRange,
+ start: segRange.start,
+ end: segRange.end,
+ isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
+ isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
+ dayIndex: dayIndex
+ };
+ segs.push(seg);
+ // detect when range won't go fully into the next day,
+ // and mutate the latest seg to the be the end.
+ if (!seg.isEnd && !allDay &&
+ dayIndex + 1 < dayRanges.length &&
+ range.end <
+ dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
+ seg.end = range.end;
+ seg.isEnd = true;
+ break;
+ }
+ }
+ }
+ return segs;
+ };
+ ListView.prototype.renderEmptyMessage = function () {
+ this.contentEl.innerHTML =
+ '<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
+ '<div class="fc-list-empty-wrap1">' +
+ '<div class="fc-list-empty">' +
+ core.htmlEscape(this.opt('noEventsMessage')) +
+ '</div>' +
+ '</div>' +
+ '</div>';
+ };
+ // called by ListEventRenderer
+ ListView.prototype.renderSegList = function (allSegs) {
+ var segsByDay = this.groupSegsByDay(allSegs); // sparse array
+ var dayIndex;
+ var daySegs;
+ var i;
+ var tableEl = core.htmlToElement('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>');
+ var tbodyEl = tableEl.querySelector('tbody');
+ for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
+ daySegs = segsByDay[dayIndex];
+ if (daySegs) { // sparse array, so might be undefined
+ // append a day header
+ tbodyEl.appendChild(this.buildDayHeaderRow(this.dayDates[dayIndex]));
+ daySegs = this.eventRenderer.sortEventSegs(daySegs);
+ for (i = 0; i < daySegs.length; i++) {
+ tbodyEl.appendChild(daySegs[i].el); // append event row
+ }
+ }
+ }
+ this.contentEl.innerHTML = '';
+ this.contentEl.appendChild(tableEl);
+ };
+ // Returns a sparse array of arrays, segs grouped by their dayIndex
+ ListView.prototype.groupSegsByDay = function (segs) {
+ var segsByDay = []; // sparse array
+ var i;
+ var seg;
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
+ .push(seg);
+ }
+ return segsByDay;
+ };
+ // generates the HTML for the day headers that live amongst the event rows
+ ListView.prototype.buildDayHeaderRow = function (dayDate) {
+ var dateEnv = this.dateEnv;
+ var mainFormat = core.createFormatter(this.opt('listDayFormat')); // TODO: cache
+ var altFormat = core.createFormatter(this.opt('listDayAltFormat')); // TODO: cache
+ return core.createElement('tr', {
+ className: 'fc-list-heading',
+ 'data-date': dateEnv.formatIso(dayDate, { omitTime: true })
+ }, '<td class="' + (this.calendar.theme.getClass('tableListHeading') ||
+ this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' +
+ (mainFormat ?
+ core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-main' }, core.htmlEscape(dateEnv.format(dayDate, mainFormat)) // inner HTML
+ ) :
+ '') +
+ (altFormat ?
+ core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-alt' }, core.htmlEscape(dateEnv.format(dayDate, altFormat)) // inner HTML
+ ) :
+ '') +
+ '</td>');
+ };
+ return ListView;
+ }(core.View));
+ ListView.prototype.fgSegSelector = '.fc-list-item'; // which elements accept event actions
+ function computeDateVars(dateProfile) {
+ var dayStart = core.startOfDay(dateProfile.renderRange.start);
+ var viewEnd = dateProfile.renderRange.end;
+ var dayDates = [];
+ var dayRanges = [];
+ while (dayStart < viewEnd) {
+ dayDates.push(dayStart);
+ dayRanges.push({
+ start: dayStart,
+ end: core.addDays(dayStart, 1)
+ });
+ dayStart = core.addDays(dayStart, 1);
+ }
+ return { dayDates: dayDates, dayRanges: dayRanges };
+ }
+
+ var main = core.createPlugin({
+ views: {
+ list: {
+ class: ListView,
+ buttonTextKey: 'list',
+ listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016"
+ },
+ listDay: {
+ type: 'list',
+ duration: { days: 1 },
+ listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in header
+ },
+ listWeek: {
+ type: 'list',
+ duration: { weeks: 1 },
+ listDayFormat: { weekday: 'long' },
+ listDayAltFormat: { month: 'long', day: 'numeric', year: 'numeric' }
+ },
+ listMonth: {
+ type: 'list',
+ duration: { month: 1 },
+ listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
+ },
+ listYear: {
+ type: 'list',
+ duration: { year: 1 },
+ listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
+ }
+ }
+ });
+
+ exports.ListView = ListView;
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/list/main.min.css b/library/fullcalendar/packages/list/main.min.css
new file mode 100644
index 000000000..6a9c9101d
--- /dev/null
+++ b/library/fullcalendar/packages/list/main.min.css
@@ -0,0 +1,5 @@
+/*!
+FullCalendar List View Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/.fc-event-dot{display:inline-block;width:10px;height:10px;border-radius:5px}.fc-rtl .fc-list-view{direction:rtl}.fc-list-view{border-width:1px;border-style:solid}.fc .fc-list-table{table-layout:auto}.fc-list-table td{border-width:1px 0 0;padding:8px 14px}.fc-list-table tr:first-child td{border-top-width:0}.fc-list-heading{border-bottom-width:1px}.fc-list-heading td{font-weight:700}.fc-ltr .fc-list-heading-main{float:left}.fc-ltr .fc-list-heading-alt,.fc-rtl .fc-list-heading-main{float:right}.fc-rtl .fc-list-heading-alt{float:left}.fc-list-item.fc-has-url{cursor:pointer}.fc-list-item-marker,.fc-list-item-time{white-space:nowrap;width:1px}.fc-ltr .fc-list-item-marker{padding-right:0}.fc-rtl .fc-list-item-marker{padding-left:0}.fc-list-item-title a{text-decoration:none;color:inherit}.fc-list-item-title a[href]:hover{text-decoration:underline}.fc-list-empty-wrap2{position:absolute;top:0;left:0;right:0;bottom:0}.fc-list-empty-wrap1{width:100%;height:100%;display:table}.fc-list-empty{display:table-cell;vertical-align:middle;text-align:center}.fc-unthemed .fc-list-empty{background-color:#eee} \ No newline at end of file
diff --git a/library/fullcalendar/packages/list/main.min.js b/library/fullcalendar/packages/list/main.min.js
new file mode 100644
index 000000000..3310229fa
--- /dev/null
+++ b/library/fullcalendar/packages/list/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar List View Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarList={},e.FullCalendar))}(this,function(e,t){"use strict";function n(e,t){function n(){this.constructor=e}s(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}function r(e){for(var n=t.startOfDay(e.renderRange.start),r=e.renderRange.end,s=[],a=[];n<r;)s.push(n),a.push({start:n,end:t.addDays(n,1)}),n=t.addDays(n,1);return{dayDates:s,dayRanges:a}}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var s=function(e,t){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},a=function(e){function r(t){var n=e.call(this,t.context)||this;return n.listView=t,n}return n(r,e),r.prototype.attachSegs=function(e){e.length?this.listView.renderSegList(e):this.listView.renderEmptyMessage()},r.prototype.detachSegs=function(){},r.prototype.renderSegHtml=function(e){var n,r=this.context,s=r.view,a=r.theme,i=e.eventRange,o=i.def,l=i.instance,d=i.ui,c=o.url,p=["fc-list-item"].concat(d.classNames),h=d.backgroundColor;return n=o.allDay?t.getAllDayHtml(s):t.isMultiDayRange(i.range)?e.isStart?t.htmlEscape(this._getTimeText(l.range.start,e.end,!1)):e.isEnd?t.htmlEscape(this._getTimeText(e.start,l.range.end,!1)):t.getAllDayHtml(s):t.htmlEscape(this.getTimeText(i)),c&&p.push("fc-has-url"),'<tr class="'+p.join(" ")+'">'+(this.displayEventTime?'<td class="fc-list-item-time '+a.getClass("widgetContent")+'">'+(n||"")+"</td>":"")+'<td class="fc-list-item-marker '+a.getClass("widgetContent")+'"><span class="fc-event-dot"'+(h?' style="background-color:'+h+'"':"")+'></span></td><td class="fc-list-item-title '+a.getClass("widgetContent")+'"><a'+(c?' href="'+t.htmlEscape(c)+'"':"")+">"+t.htmlEscape(o.title||"")+"</a></td></tr>"},r.prototype.computeEventTimeFormat=function(){return{hour:"numeric",minute:"2-digit",meridiem:"short"}},r}(t.FgEventRenderer),i=function(e){function s(n,s,i,o){var l=e.call(this,n,s,i,o)||this;l.computeDateVars=t.memoize(r),l.eventStoreToSegs=t.memoize(l._eventStoreToSegs);var d=l.eventRenderer=new a(l);l.renderContent=t.memoizeRendering(d.renderSegs.bind(d),d.unrender.bind(d)),l.el.classList.add("fc-list-view");for(var c=(l.theme.getClass("listView")||"").split(" "),p=0,h=c;p<h.length;p++){var u=h[p];u&&l.el.classList.add(u)}return l.scroller=new t.ScrollComponent("hidden","auto"),l.el.appendChild(l.scroller.el),l.contentEl=l.scroller.el,n.calendar.registerInteractiveComponent(l,{el:l.el}),l}return n(s,e),s.prototype.render=function(e){var t=this.computeDateVars(e.dateProfile),n=t.dayDates,r=t.dayRanges;this.dayDates=n,this.renderContent(this.eventStoreToSegs(e.eventStore,e.eventUiBases,r))},s.prototype.destroy=function(){e.prototype.destroy.call(this),this.scroller.destroy(),this.calendar.unregisterInteractiveComponent(this)},s.prototype.updateSize=function(t,n,r){e.prototype.updateSize.call(this,t,n,r),this.eventRenderer.computeSizes(t),this.eventRenderer.assignSizes(t),this.scroller.clear(),r||this.scroller.setHeight(this.computeScrollerHeight(n))},s.prototype.computeScrollerHeight=function(e){return e-t.subtractInnerElHeight(this.el,this.scroller.el)},s.prototype._eventStoreToSegs=function(e,n,r){return this.eventRangesToSegs(t.sliceEventStore(e,n,this.props.dateProfile.activeRange,this.nextDayThreshold).fg,r)},s.prototype.eventRangesToSegs=function(e,t){for(var n=[],r=0,s=e;r<s.length;r++){var a=s[r];n.push.apply(n,this.eventRangeToSegs(a,t))}return n},s.prototype.eventRangeToSegs=function(e,n){var r,s,a,i=this,o=i.dateEnv,l=i.nextDayThreshold,d=e.range,c=e.def.allDay,p=[];for(r=0;r<n.length;r++)if((s=t.intersectRanges(d,n[r]))&&(a={component:this,eventRange:e,start:s.start,end:s.end,isStart:e.isStart&&s.start.valueOf()===d.start.valueOf(),isEnd:e.isEnd&&s.end.valueOf()===d.end.valueOf(),dayIndex:r},p.push(a),!a.isEnd&&!c&&r+1<n.length&&d.end<o.add(n[r+1].start,l))){a.end=d.end,a.isEnd=!0;break}return p},s.prototype.renderEmptyMessage=function(){this.contentEl.innerHTML='<div class="fc-list-empty-wrap2"><div class="fc-list-empty-wrap1"><div class="fc-list-empty">'+t.htmlEscape(this.opt("noEventsMessage"))+"</div></div></div>"},s.prototype.renderSegList=function(e){var n,r,s,a=this.groupSegsByDay(e),i=t.htmlToElement('<table class="fc-list-table '+this.calendar.theme.getClass("tableList")+'"><tbody></tbody></table>'),o=i.querySelector("tbody");for(n=0;n<a.length;n++)if(r=a[n])for(o.appendChild(this.buildDayHeaderRow(this.dayDates[n])),r=this.eventRenderer.sortEventSegs(r),s=0;s<r.length;s++)o.appendChild(r[s].el);this.contentEl.innerHTML="",this.contentEl.appendChild(i)},s.prototype.groupSegsByDay=function(e){var t,n,r=[];for(t=0;t<e.length;t++)n=e[t],(r[n.dayIndex]||(r[n.dayIndex]=[])).push(n);return r},s.prototype.buildDayHeaderRow=function(e){var n=this.dateEnv,r=t.createFormatter(this.opt("listDayFormat")),s=t.createFormatter(this.opt("listDayAltFormat"));return t.createElement("tr",{className:"fc-list-heading","data-date":n.formatIso(e,{omitTime:!0})},'<td class="'+(this.calendar.theme.getClass("tableListHeading")||this.calendar.theme.getClass("widgetHeader"))+'" colspan="3">'+(r?t.buildGotoAnchorHtml(this,e,{class:"fc-list-heading-main"},t.htmlEscape(n.format(e,r))):"")+(s?t.buildGotoAnchorHtml(this,e,{class:"fc-list-heading-alt"},t.htmlEscape(n.format(e,s))):"")+"</td>")},s}(t.View);i.prototype.fgSegSelector=".fc-list-item";var o=t.createPlugin({views:{list:{class:i,buttonTextKey:"list",listDayFormat:{month:"long",day:"numeric",year:"numeric"}},listDay:{type:"list",duration:{days:1},listDayFormat:{weekday:"long"}},listWeek:{type:"list",duration:{weeks:1},listDayFormat:{weekday:"long"},listDayAltFormat:{month:"long",day:"numeric",year:"numeric"}},listMonth:{type:"list",duration:{month:1},listDayAltFormat:{weekday:"long"}},listYear:{type:"list",duration:{year:1},listDayAltFormat:{weekday:"long"}}}});e.ListView=i,e.default=o,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/luxon/main.js b/library/fullcalendar/packages/luxon/main.js
new file mode 100644
index 000000000..ff5fc19a1
--- /dev/null
+++ b/library/fullcalendar/packages/luxon/main.js
@@ -0,0 +1,162 @@
+/*!
+FullCalendar Luxon Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('luxon'), require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', 'luxon', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarLuxon = {}, global.luxon, global.FullCalendar));
+}(this, function (exports, luxon, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ function toDateTime(date, calendar) {
+ if (!(calendar instanceof core.Calendar)) {
+ throw new Error('must supply a Calendar instance');
+ }
+ return luxon.DateTime.fromJSDate(date, {
+ zone: calendar.dateEnv.timeZone,
+ locale: calendar.dateEnv.locale.codes[0]
+ });
+ }
+ function toDuration(duration, calendar) {
+ if (!(calendar instanceof core.Calendar)) {
+ throw new Error('must supply a Calendar instance');
+ }
+ return luxon.Duration.fromObject(__assign({}, duration, { locale: calendar.dateEnv.locale.codes[0] }));
+ }
+ var LuxonNamedTimeZone = /** @class */ (function (_super) {
+ __extends(LuxonNamedTimeZone, _super);
+ function LuxonNamedTimeZone() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ LuxonNamedTimeZone.prototype.offsetForArray = function (a) {
+ return arrayToLuxon(a, this.timeZoneName).offset;
+ };
+ LuxonNamedTimeZone.prototype.timestampToArray = function (ms) {
+ return luxonToArray(luxon.DateTime.fromMillis(ms, {
+ zone: this.timeZoneName
+ }));
+ };
+ return LuxonNamedTimeZone;
+ }(core.NamedTimeZoneImpl));
+ function formatWithCmdStr(cmdStr, arg) {
+ var cmd = parseCmdStr(cmdStr);
+ if (arg.end) {
+ var start = arrayToLuxon(arg.start.array, arg.timeZone, arg.localeCodes[0]);
+ var end = arrayToLuxon(arg.end.array, arg.timeZone, arg.localeCodes[0]);
+ return formatRange(cmd, start.toFormat.bind(start), end.toFormat.bind(end), arg.separator);
+ }
+ return arrayToLuxon(arg.date.array, arg.timeZone, arg.localeCodes[0]).toFormat(cmd.whole);
+ }
+ var main = core.createPlugin({
+ cmdFormatter: formatWithCmdStr,
+ namedTimeZonedImpl: LuxonNamedTimeZone
+ });
+ function luxonToArray(datetime) {
+ return [
+ datetime.year,
+ datetime.month - 1,
+ datetime.day,
+ datetime.hour,
+ datetime.minute,
+ datetime.second,
+ datetime.millisecond
+ ];
+ }
+ function arrayToLuxon(arr, timeZone, locale) {
+ return luxon.DateTime.fromObject({
+ zone: timeZone,
+ locale: locale,
+ year: arr[0],
+ month: arr[1] + 1,
+ day: arr[2],
+ hour: arr[3],
+ minute: arr[4],
+ second: arr[5],
+ millisecond: arr[6]
+ });
+ }
+ function parseCmdStr(cmdStr) {
+ var parts = cmdStr.match(/^(.*?)\{(.*)\}(.*)$/); // TODO: lookbehinds for escape characters
+ if (parts) {
+ var middle = parseCmdStr(parts[2]);
+ return {
+ head: parts[1],
+ middle: middle,
+ tail: parts[3],
+ whole: parts[1] + middle.whole + parts[3]
+ };
+ }
+ else {
+ return {
+ head: null,
+ middle: null,
+ tail: null,
+ whole: cmdStr
+ };
+ }
+ }
+ function formatRange(cmd, formatStart, formatEnd, separator) {
+ if (cmd.middle) {
+ var startHead = formatStart(cmd.head);
+ var startMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
+ var startTail = formatStart(cmd.tail);
+ var endHead = formatEnd(cmd.head);
+ var endMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
+ var endTail = formatEnd(cmd.tail);
+ if (startHead === endHead && startTail === endTail) {
+ return startHead +
+ (startMiddle === endMiddle ? startMiddle : startMiddle + separator + endMiddle) +
+ startTail;
+ }
+ }
+ return formatStart(cmd.whole) + separator + formatEnd(cmd.whole);
+ }
+
+ exports.default = main;
+ exports.toDateTime = toDateTime;
+ exports.toDuration = toDuration;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/luxon/main.min.js b/library/fullcalendar/packages/luxon/main.min.js
new file mode 100644
index 000000000..6267f8bbe
--- /dev/null
+++ b/library/fullcalendar/packages/luxon/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Luxon Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("luxon"),require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","luxon","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarLuxon={},e.luxon,e.FullCalendar))}(this,function(e,t,n){"use strict";function o(e,t){function n(){this.constructor=e}f(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}function r(e,o){if(!(o instanceof n.Calendar))throw new Error("must supply a Calendar instance");return t.DateTime.fromJSDate(e,{zone:o.dateEnv.timeZone,locale:o.dateEnv.locale.codes[0]})}function a(e,o){if(!(o instanceof n.Calendar))throw new Error("must supply a Calendar instance");return t.Duration.fromObject(m({},e,{locale:o.dateEnv.locale.codes[0]}))}function i(e,t){var n=c(e);if(t.end){var o=u(t.start.array,t.timeZone,t.localeCodes[0]),r=u(t.end.array,t.timeZone,t.localeCodes[0]);return d(n,o.toFormat.bind(o),r.toFormat.bind(r),t.separator)}return u(t.date.array,t.timeZone,t.localeCodes[0]).toFormat(n.whole)}function l(e){return[e.year,e.month-1,e.day,e.hour,e.minute,e.second,e.millisecond]}function u(e,n,o){return t.DateTime.fromObject({zone:n,locale:o,year:e[0],month:e[1]+1,day:e[2],hour:e[3],minute:e[4],second:e[5],millisecond:e[6]})}function c(e){var t=e.match(/^(.*?)\{(.*)\}(.*)$/);if(t){var n=c(t[2]);return{head:t[1],middle:n,tail:t[3],whole:t[1]+n.whole+t[3]}}return{head:null,middle:null,tail:null,whole:e}}function d(e,t,n,o){if(e.middle){var r=t(e.head),a=d(e.middle,t,n,o),i=t(e.tail),l=n(e.head),u=d(e.middle,t,n,o),c=n(e.tail);if(r===l&&i===c)return r+(a===u?a:a+o+u)+i}return t(e.whole)+o+n(e.whole)}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var f=function(e,t){return(f=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},m=function(){return m=Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++){t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},m.apply(this,arguments)},s=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return o(n,e),n.prototype.offsetForArray=function(e){return u(e,this.timeZoneName).offset},n.prototype.timestampToArray=function(e){return l(t.DateTime.fromMillis(e,{zone:this.timeZoneName}))},n}(n.NamedTimeZoneImpl),p=n.createPlugin({cmdFormatter:i,namedTimeZonedImpl:s});e.default=p,e.toDateTime=r,e.toDuration=a,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/moment-timezone/main.js b/library/fullcalendar/packages/moment-timezone/main.js
new file mode 100644
index 000000000..9a390b905
--- /dev/null
+++ b/library/fullcalendar/packages/moment-timezone/main.js
@@ -0,0 +1,64 @@
+/*!
+FullCalendar Moment Timezone Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('moment'), require('moment-timezone/builds/moment-timezone-with-data'), require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', 'moment', 'moment-timezone/builds/moment-timezone-with-data', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarMomentTimezone = {}, global.moment, global.moment, global.FullCalendar));
+}(this, function (exports, moment, momentTimezoneWithData, core) { 'use strict';
+
+ moment = moment && moment.hasOwnProperty('default') ? moment['default'] : moment;
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var MomentNamedTimeZone = /** @class */ (function (_super) {
+ __extends(MomentNamedTimeZone, _super);
+ function MomentNamedTimeZone() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ MomentNamedTimeZone.prototype.offsetForArray = function (a) {
+ return moment.tz(a, this.timeZoneName).utcOffset();
+ };
+ MomentNamedTimeZone.prototype.timestampToArray = function (ms) {
+ return moment.tz(ms, this.timeZoneName).toArray();
+ };
+ return MomentNamedTimeZone;
+ }(core.NamedTimeZoneImpl));
+ var main = core.createPlugin({
+ namedTimeZonedImpl: MomentNamedTimeZone
+ });
+
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/moment-timezone/main.min.js b/library/fullcalendar/packages/moment-timezone/main.min.js
new file mode 100644
index 000000000..c2e5ee936
--- /dev/null
+++ b/library/fullcalendar/packages/moment-timezone/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Moment Timezone Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("moment"),require("moment-timezone/builds/moment-timezone-with-data"),require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","moment","moment-timezone/builds/moment-timezone-with-data","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarMomentTimezone={},e.moment,e.moment,e.FullCalendar))}(this,function(e,t,n,o){"use strict";function r(e,t){function n(){this.constructor=e}i(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}t=t&&t.hasOwnProperty("default")?t.default:t;/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var i=function(e,t){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},u=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return r(n,e),n.prototype.offsetForArray=function(e){return t.tz(e,this.timeZoneName).utcOffset()},n.prototype.timestampToArray=function(e){return t.tz(e,this.timeZoneName).toArray()},n}(o.NamedTimeZoneImpl),m=o.createPlugin({namedTimeZonedImpl:u});e.default=m,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/moment/main.js b/library/fullcalendar/packages/moment/main.js
new file mode 100644
index 000000000..ca94518a4
--- /dev/null
+++ b/library/fullcalendar/packages/moment/main.js
@@ -0,0 +1,103 @@
+/*!
+FullCalendar Moment Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('moment'), require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', 'moment', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarMoment = {}, global.moment, global.FullCalendar));
+}(this, function (exports, moment, core) { 'use strict';
+
+ moment = moment && moment.hasOwnProperty('default') ? moment['default'] : moment;
+
+ function toMoment(date, calendar) {
+ if (!(calendar instanceof core.Calendar)) {
+ throw new Error('must supply a Calendar instance');
+ }
+ return convertToMoment(date, calendar.dateEnv.timeZone, null, calendar.dateEnv.locale.codes[0]);
+ }
+ function toDuration(fcDuration) {
+ return moment.duration(fcDuration); // momment accepts all the props that fc.Duration already has!
+ }
+ function formatWithCmdStr(cmdStr, arg) {
+ var cmd = parseCmdStr(cmdStr);
+ if (arg.end) {
+ var startMom = convertToMoment(arg.start.array, arg.timeZone, arg.start.timeZoneOffset, arg.localeCodes[0]);
+ var endMom = convertToMoment(arg.end.array, arg.timeZone, arg.end.timeZoneOffset, arg.localeCodes[0]);
+ return formatRange(cmd, createMomentFormatFunc(startMom), createMomentFormatFunc(endMom), arg.separator);
+ }
+ return convertToMoment(arg.date.array, arg.timeZone, arg.date.timeZoneOffset, arg.localeCodes[0]).format(cmd.whole); // TODO: test for this
+ }
+ var main = core.createPlugin({
+ cmdFormatter: formatWithCmdStr
+ });
+ function createMomentFormatFunc(mom) {
+ return function (cmdStr) {
+ return cmdStr ? mom.format(cmdStr) : ''; // because calling with blank string results in ISO8601 :(
+ };
+ }
+ function convertToMoment(input, timeZone, timeZoneOffset, locale) {
+ var mom;
+ if (timeZone === 'local') {
+ mom = moment(input);
+ }
+ else if (timeZone === 'UTC') {
+ mom = moment.utc(input);
+ }
+ else if (moment.tz) {
+ mom = moment.tz(input, timeZone);
+ }
+ else {
+ mom = moment.utc(input);
+ if (timeZoneOffset != null) {
+ mom.utcOffset(timeZoneOffset);
+ }
+ }
+ mom.locale(locale);
+ return mom;
+ }
+ function parseCmdStr(cmdStr) {
+ var parts = cmdStr.match(/^(.*?)\{(.*)\}(.*)$/); // TODO: lookbehinds for escape characters
+ if (parts) {
+ var middle = parseCmdStr(parts[2]);
+ return {
+ head: parts[1],
+ middle: middle,
+ tail: parts[3],
+ whole: parts[1] + middle.whole + parts[3]
+ };
+ }
+ else {
+ return {
+ head: null,
+ middle: null,
+ tail: null,
+ whole: cmdStr
+ };
+ }
+ }
+ function formatRange(cmd, formatStart, formatEnd, separator) {
+ if (cmd.middle) {
+ var startHead = formatStart(cmd.head);
+ var startMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
+ var startTail = formatStart(cmd.tail);
+ var endHead = formatEnd(cmd.head);
+ var endMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
+ var endTail = formatEnd(cmd.tail);
+ if (startHead === endHead && startTail === endTail) {
+ return startHead +
+ (startMiddle === endMiddle ? startMiddle : startMiddle + separator + endMiddle) +
+ startTail;
+ }
+ }
+ return formatStart(cmd.whole) + separator + formatEnd(cmd.whole);
+ }
+
+ exports.default = main;
+ exports.toDuration = toDuration;
+ exports.toMoment = toMoment;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/moment/main.min.js b/library/fullcalendar/packages/moment/main.min.js
new file mode 100644
index 000000000..9b5b6d84e
--- /dev/null
+++ b/library/fullcalendar/packages/moment/main.min.js
@@ -0,0 +1,6 @@
+/*!
+FullCalendar Moment Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("moment"),require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","moment","@fullcalendar/core"],t):(e=e||self,t(e.FullCalendarMoment={},e.moment,e.FullCalendar))}(this,function(e,t,n){"use strict";function r(e,t){if(!(t instanceof n.Calendar))throw new Error("must supply a Calendar instance");return u(e,t.dateEnv.timeZone,null,t.dateEnv.locale.codes[0])}function a(e){return t.duration(e)}function o(e,t){var n=i(e);if(t.end){var r=u(t.start.array,t.timeZone,t.start.timeZoneOffset,t.localeCodes[0]),a=u(t.end.array,t.timeZone,t.end.timeZoneOffset,t.localeCodes[0]);return d(n,l(r),l(a),t.separator)}return u(t.date.array,t.timeZone,t.date.timeZoneOffset,t.localeCodes[0]).format(n.whole)}function l(e){return function(t){return t?e.format(t):""}}function u(e,n,r,a){var o;return"local"===n?o=t(e):"UTC"===n?o=t.utc(e):t.tz?o=t.tz(e,n):(o=t.utc(e),null!=r&&o.utcOffset(r)),o.locale(a),o}function i(e){var t=e.match(/^(.*?)\{(.*)\}(.*)$/);if(t){var n=i(t[2]);return{head:t[1],middle:n,tail:t[3],whole:t[1]+n.whole+t[3]}}return{head:null,middle:null,tail:null,whole:e}}function d(e,t,n,r){if(e.middle){var a=t(e.head),o=d(e.middle,t,n,r),l=t(e.tail),u=n(e.head),i=d(e.middle,t,n,r),f=n(e.tail);if(a===u&&l===f)return a+(o===i?o:o+r+i)+l}return t(e.whole)+r+n(e.whole)}t=t&&t.hasOwnProperty("default")?t.default:t;var f=n.createPlugin({cmdFormatter:o});e.default=f,e.toDuration=a,e.toMoment=r,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/rrule/main.js b/library/fullcalendar/packages/rrule/main.js
new file mode 100644
index 000000000..43ad6ed2f
--- /dev/null
+++ b/library/fullcalendar/packages/rrule/main.js
@@ -0,0 +1,127 @@
+/*!
+FullCalendar RRule Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rrule'), require('@fullcalendar/core')) :
+ typeof define === 'function' && define.amd ? define(['exports', 'rrule', '@fullcalendar/core'], factory) :
+ (global = global || self, factory(global.FullCalendarRrule = {}, global.rrule, global.FullCalendar));
+}(this, function (exports, rrule, core) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ var EVENT_DEF_PROPS = {
+ rrule: null,
+ duration: core.createDuration
+ };
+ var recurring = {
+ parse: function (rawEvent, leftoverProps, dateEnv) {
+ if (rawEvent.rrule != null) {
+ var props = core.refineProps(rawEvent, EVENT_DEF_PROPS, {}, leftoverProps);
+ var parsed = parseRRule(props.rrule, dateEnv);
+ if (parsed) {
+ return {
+ typeData: parsed.rrule,
+ allDayGuess: parsed.allDayGuess,
+ duration: props.duration
+ };
+ }
+ }
+ return null;
+ },
+ expand: function (rrule, framingRange) {
+ // we WANT an inclusive start and in exclusive end, but the js rrule lib will only do either BOTH
+ // inclusive or BOTH exclusive, which is stupid: https://github.com/jakubroztocil/rrule/issues/84
+ // Workaround: make inclusive, which will generate extra occurences, and then trim.
+ return rrule.between(framingRange.start, framingRange.end, true)
+ .filter(function (date) {
+ return date.valueOf() < framingRange.end.valueOf();
+ });
+ }
+ };
+ var main = core.createPlugin({
+ recurringTypes: [recurring]
+ });
+ function parseRRule(input, dateEnv) {
+ var allDayGuess = null;
+ var rrule$1;
+ if (typeof input === 'string') {
+ rrule$1 = rrule.rrulestr(input);
+ }
+ else if (typeof input === 'object' && input) { // non-null object
+ var refined = __assign({}, input); // copy
+ if (typeof refined.dtstart === 'string') {
+ var dtstartMeta = dateEnv.createMarkerMeta(refined.dtstart);
+ if (dtstartMeta) {
+ refined.dtstart = dtstartMeta.marker;
+ allDayGuess = dtstartMeta.isTimeUnspecified;
+ }
+ else {
+ delete refined.dtstart;
+ }
+ }
+ if (typeof refined.until === 'string') {
+ refined.until = dateEnv.createMarker(refined.until);
+ }
+ if (refined.freq != null) {
+ refined.freq = convertConstant(refined.freq);
+ }
+ if (refined.wkst != null) {
+ refined.wkst = convertConstant(refined.wkst);
+ }
+ else {
+ refined.wkst = (dateEnv.weekDow - 1 + 7) % 7; // convert Sunday-first to Monday-first
+ }
+ if (refined.byweekday != null) {
+ refined.byweekday = convertConstants(refined.byweekday); // the plural version
+ }
+ rrule$1 = new rrule.RRule(refined);
+ }
+ if (rrule$1) {
+ return { rrule: rrule$1, allDayGuess: allDayGuess };
+ }
+ return null;
+ }
+ function convertConstants(input) {
+ if (Array.isArray(input)) {
+ return input.map(convertConstant);
+ }
+ return convertConstant(input);
+ }
+ function convertConstant(input) {
+ if (typeof input === 'string') {
+ return rrule.RRule[input.toUpperCase()];
+ }
+ return input;
+ }
+
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/rrule/main.min.js b/library/fullcalendar/packages/rrule/main.min.js
new file mode 100644
index 000000000..057788f3c
--- /dev/null
+++ b/library/fullcalendar/packages/rrule/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar RRule Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("rrule"),require("@fullcalendar/core")):"function"==typeof define&&define.amd?define(["exports","rrule","@fullcalendar/core"],r):(e=e||self,r(e.FullCalendarRrule={},e.rrule,e.FullCalendar))}(this,function(e,r,t){"use strict";function n(e,t){var n,i=null;if("string"==typeof e)n=r.rrulestr(e);else if("object"==typeof e&&e){var f=a({},e);if("string"==typeof f.dtstart){var o=t.createMarkerMeta(f.dtstart);o?(f.dtstart=o.marker,i=o.isTimeUnspecified):delete f.dtstart}"string"==typeof f.until&&(f.until=t.createMarker(f.until)),null!=f.freq&&(f.freq=l(f.freq)),null!=f.wkst?f.wkst=l(f.wkst):f.wkst=(t.weekDow-1+7)%7,null!=f.byweekday&&(f.byweekday=u(f.byweekday)),n=new r.RRule(f)}return n?{rrule:n,allDayGuess:i}:null}function u(e){return Array.isArray(e)?e.map(l):l(e)}function l(e){return"string"==typeof e?r.RRule[e.toUpperCase()]:e}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var a=function(){return a=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++){r=arguments[t];for(var u in r)Object.prototype.hasOwnProperty.call(r,u)&&(e[u]=r[u])}return e},a.apply(this,arguments)},i={rrule:null,duration:t.createDuration},f={parse:function(e,r,u){if(null!=e.rrule){var l=t.refineProps(e,i,{},r),a=n(l.rrule,u);if(a)return{typeData:a.rrule,allDayGuess:a.allDayGuess,duration:l.duration}}return null},expand:function(e,r){return e.between(r.start,r.end,!0).filter(function(e){return e.valueOf()<r.end.valueOf()})}},o=t.createPlugin({recurringTypes:[f]});e.default=o,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/packages/timegrid/main.css b/library/fullcalendar/packages/timegrid/main.css
new file mode 100644
index 000000000..9dd11b68f
--- /dev/null
+++ b/library/fullcalendar/packages/timegrid/main.css
@@ -0,0 +1,266 @@
+/*!
+FullCalendar Time Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+/* TimeGridView all-day area
+--------------------------------------------------------------------------------------------------*/
+.fc-timeGrid-view .fc-day-grid {
+ position: relative;
+ z-index: 2;
+ /* so the "more.." popover will be over the time grid */ }
+
+.fc-timeGrid-view .fc-day-grid .fc-row {
+ min-height: 3em;
+ /* all-day section will never get shorter than this */ }
+
+.fc-timeGrid-view .fc-day-grid .fc-row .fc-content-skeleton {
+ padding-bottom: 1em;
+ /* give space underneath events for clicking/selecting days */ }
+
+/* TimeGrid axis running down the side (for both the all-day area and the slot area)
+--------------------------------------------------------------------------------------------------*/
+.fc .fc-axis {
+ /* .fc to overcome default cell styles */
+ vertical-align: middle;
+ padding: 0 4px;
+ white-space: nowrap; }
+
+.fc-ltr .fc-axis {
+ text-align: right; }
+
+.fc-rtl .fc-axis {
+ text-align: left; }
+
+/* TimeGrid Structure
+--------------------------------------------------------------------------------------------------*/
+.fc-time-grid-container,
+.fc-time-grid {
+ /* so slats/bg/content/etc positions get scoped within here */
+ position: relative;
+ z-index: 1; }
+
+.fc-time-grid {
+ min-height: 100%;
+ /* so if height setting is 'auto', .fc-bg stretches to fill height */ }
+
+.fc-time-grid table {
+ /* don't put outer borders on slats/bg/content/etc */
+ border: 0 hidden transparent; }
+
+.fc-time-grid > .fc-bg {
+ z-index: 1; }
+
+.fc-time-grid .fc-slats,
+.fc-time-grid > hr {
+ /* the <hr> TimeGridView injects when grid is shorter than scroller */
+ position: relative;
+ z-index: 2; }
+
+.fc-time-grid .fc-content-col {
+ position: relative;
+ /* because now-indicator lives directly inside */ }
+
+.fc-time-grid .fc-content-skeleton {
+ position: absolute;
+ z-index: 3;
+ top: 0;
+ left: 0;
+ right: 0; }
+
+/* divs within a cell within the fc-content-skeleton */
+.fc-time-grid .fc-business-container {
+ position: relative;
+ z-index: 1; }
+
+.fc-time-grid .fc-bgevent-container {
+ position: relative;
+ z-index: 2; }
+
+.fc-time-grid .fc-highlight-container {
+ position: relative;
+ z-index: 3; }
+
+.fc-time-grid .fc-event-container {
+ position: relative;
+ z-index: 4; }
+
+.fc-time-grid .fc-now-indicator-line {
+ z-index: 5; }
+
+.fc-time-grid .fc-mirror-container {
+ /* also is fc-event-container */
+ position: relative;
+ z-index: 6; }
+
+/* TimeGrid Slats (lines that run horizontally)
+--------------------------------------------------------------------------------------------------*/
+.fc-time-grid .fc-slats td {
+ height: 1.5em;
+ border-bottom: 0;
+ /* each cell is responsible for its top border */ }
+
+.fc-time-grid .fc-slats .fc-minor td {
+ border-top-style: dotted; }
+
+/* TimeGrid Highlighting Slots
+--------------------------------------------------------------------------------------------------*/
+.fc-time-grid .fc-highlight-container {
+ /* a div within a cell within the fc-highlight-skeleton */
+ position: relative;
+ /* scopes the left/right of the fc-highlight to be in the column */ }
+
+.fc-time-grid .fc-highlight {
+ position: absolute;
+ left: 0;
+ right: 0;
+ /* top and bottom will be in by JS */ }
+
+/* TimeGrid Event Containment
+--------------------------------------------------------------------------------------------------*/
+.fc-ltr .fc-time-grid .fc-event-container {
+ /* space on the sides of events for LTR (default) */
+ margin: 0 2.5% 0 2px; }
+
+.fc-rtl .fc-time-grid .fc-event-container {
+ /* space on the sides of events for RTL */
+ margin: 0 2px 0 2.5%; }
+
+.fc-time-grid .fc-event,
+.fc-time-grid .fc-bgevent {
+ position: absolute;
+ z-index: 1;
+ /* scope inner z-index's */ }
+
+.fc-time-grid .fc-bgevent {
+ /* background events always span full width */
+ left: 0;
+ right: 0; }
+
+/* TimeGrid Event Styling
+----------------------------------------------------------------------------------------------------
+We use the full "fc-time-grid-event" class instead of using descendants because the event won't
+be a descendant of the grid when it is being dragged.
+*/
+.fc-time-grid-event {
+ margin-bottom: 1px; }
+
+.fc-time-grid-event-inset {
+ -webkit-box-shadow: 0px 0px 0px 1px #fff;
+ box-shadow: 0px 0px 0px 1px #fff; }
+
+.fc-time-grid-event.fc-not-start {
+ /* events that are continuing from another day */
+ /* replace space made by the top border with padding */
+ border-top-width: 0;
+ padding-top: 1px;
+ /* remove top rounded corners */
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.fc-time-grid-event.fc-not-end {
+ /* replace space made by the top border with padding */
+ border-bottom-width: 0;
+ padding-bottom: 1px;
+ /* remove bottom rounded corners */
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.fc-time-grid-event .fc-content {
+ overflow: hidden;
+ max-height: 100%; }
+
+.fc-time-grid-event .fc-time,
+.fc-time-grid-event .fc-title {
+ padding: 0 1px; }
+
+.fc-time-grid-event .fc-time {
+ font-size: .85em;
+ white-space: nowrap; }
+
+/* short mode, where time and title are on the same line */
+.fc-time-grid-event.fc-short .fc-content {
+ /* don't wrap to second line (now that contents will be inline) */
+ white-space: nowrap; }
+
+.fc-time-grid-event.fc-short .fc-time,
+.fc-time-grid-event.fc-short .fc-title {
+ /* put the time and title on the same line */
+ display: inline-block;
+ vertical-align: top; }
+
+.fc-time-grid-event.fc-short .fc-time span {
+ display: none;
+ /* don't display the full time text... */ }
+
+.fc-time-grid-event.fc-short .fc-time:before {
+ content: attr(data-start);
+ /* ...instead, display only the start time */ }
+
+.fc-time-grid-event.fc-short .fc-time:after {
+ content: "\000A0-\000A0";
+ /* seperate with a dash, wrapped in nbsp's */ }
+
+.fc-time-grid-event.fc-short .fc-title {
+ font-size: .85em;
+ /* make the title text the same size as the time */
+ padding: 0;
+ /* undo padding from above */ }
+
+/* resizer (cursor device) */
+.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer {
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 8px;
+ overflow: hidden;
+ line-height: 8px;
+ font-size: 11px;
+ font-family: monospace;
+ text-align: center;
+ cursor: s-resize; }
+
+.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after {
+ content: "="; }
+
+/* resizer (touch device) */
+.fc-time-grid-event.fc-selected .fc-resizer {
+ /* 10x10 dot */
+ border-radius: 5px;
+ border-width: 1px;
+ width: 8px;
+ height: 8px;
+ border-style: solid;
+ border-color: inherit;
+ background: #fff;
+ /* horizontally center */
+ left: 50%;
+ margin-left: -5px;
+ /* center on the bottom edge */
+ bottom: -5px; }
+
+/* Now Indicator
+--------------------------------------------------------------------------------------------------*/
+.fc-time-grid .fc-now-indicator-line {
+ border-top-width: 1px;
+ left: 0;
+ right: 0; }
+
+/* arrow on axis */
+.fc-time-grid .fc-now-indicator-arrow {
+ margin-top: -5px;
+ /* vertically center on top coordinate */ }
+
+.fc-ltr .fc-time-grid .fc-now-indicator-arrow {
+ left: 0;
+ /* triangle pointing right... */
+ border-width: 5px 0 5px 6px;
+ border-top-color: transparent;
+ border-bottom-color: transparent; }
+
+.fc-rtl .fc-time-grid .fc-now-indicator-arrow {
+ right: 0;
+ /* triangle pointing left... */
+ border-width: 5px 6px 5px 0;
+ border-top-color: transparent;
+ border-bottom-color: transparent; }
diff --git a/library/fullcalendar/packages/timegrid/main.js b/library/fullcalendar/packages/timegrid/main.js
new file mode 100644
index 000000000..e96a54b93
--- /dev/null
+++ b/library/fullcalendar/packages/timegrid/main.js
@@ -0,0 +1,1339 @@
+/*!
+FullCalendar Time Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) :
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) :
+ (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid));
+}(this, function (exports, core, daygrid) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ /*
+ Only handles foreground segs.
+ Does not own rendering. Use for low-level util methods by TimeGrid.
+ */
+ var TimeGridEventRenderer = /** @class */ (function (_super) {
+ __extends(TimeGridEventRenderer, _super);
+ function TimeGridEventRenderer(timeGrid) {
+ var _this = _super.call(this, timeGrid.context) || this;
+ _this.timeGrid = timeGrid;
+ _this.fullTimeFormat = core.createFormatter({
+ hour: 'numeric',
+ minute: '2-digit',
+ separator: _this.context.options.defaultRangeSeparator
+ });
+ return _this;
+ }
+ // Given an array of foreground segments, render a DOM element for each, computes position,
+ // and attaches to the column inner-container elements.
+ TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
+ var segsByCol = this.timeGrid.groupSegsByCol(segs);
+ // order the segs within each column
+ // TODO: have groupSegsByCol do this?
+ for (var col = 0; col < segsByCol.length; col++) {
+ segsByCol[col] = this.sortEventSegs(segsByCol[col]);
+ }
+ this.segsByCol = segsByCol;
+ this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls);
+ };
+ TimeGridEventRenderer.prototype.detachSegs = function (segs) {
+ segs.forEach(function (seg) {
+ core.removeElement(seg.el);
+ });
+ this.segsByCol = null;
+ };
+ TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) {
+ var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
+ var colCnt = timeGrid.colCnt;
+ timeGrid.computeSegVerticals(allSegs); // horizontals relies on this
+ if (segsByCol) {
+ for (var col = 0; col < colCnt; col++) {
+ this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array
+ }
+ }
+ };
+ TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) {
+ var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
+ var colCnt = timeGrid.colCnt;
+ timeGrid.assignSegVerticals(allSegs); // horizontals relies on this
+ if (segsByCol) {
+ for (var col = 0; col < colCnt; col++) {
+ this.assignSegCss(segsByCol[col]);
+ }
+ }
+ };
+ // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
+ TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
+ return {
+ hour: 'numeric',
+ minute: '2-digit',
+ meridiem: false
+ };
+ };
+ // Computes a default `displayEventEnd` value if one is not expliclty defined
+ TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
+ return true;
+ };
+ // Renders the HTML for a single event segment's default rendering
+ TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
+ var eventRange = seg.eventRange;
+ var eventDef = eventRange.def;
+ var eventUi = eventRange.ui;
+ var allDay = eventDef.allDay;
+ var isDraggable = eventUi.startEditable;
+ var isResizableFromStart = seg.isStart && eventUi.durationEditable && this.context.options.eventResizableFromStart;
+ var isResizableFromEnd = seg.isEnd && eventUi.durationEditable;
+ var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
+ var skinCss = core.cssToStr(this.getSkinCss(eventUi));
+ var timeText;
+ var fullTimeText; // more verbose time text. for the print stylesheet
+ var startTimeText; // just the start time text
+ classes.unshift('fc-time-grid-event');
+ // if the event appears to span more than one day...
+ if (core.isMultiDayRange(eventRange.range)) {
+ // Don't display time text on segments that run entirely through a day.
+ // That would appear as midnight-midnight and would look dumb.
+ // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
+ if (seg.isStart || seg.isEnd) {
+ var unzonedStart = seg.start;
+ var unzonedEnd = seg.end;
+ timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones
+ fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat);
+ startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false
+ }
+ }
+ else {
+ // Display the normal time text for the *event's* times
+ timeText = this.getTimeText(eventRange);
+ fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat);
+ startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false
+ }
+ return '<a class="' + classes.join(' ') + '"' +
+ (eventDef.url ?
+ ' href="' + core.htmlEscape(eventDef.url) + '"' :
+ '') +
+ (skinCss ?
+ ' style="' + skinCss + '"' :
+ '') +
+ '>' +
+ '<div class="fc-content">' +
+ (timeText ?
+ '<div class="fc-time"' +
+ ' data-start="' + core.htmlEscape(startTimeText) + '"' +
+ ' data-full="' + core.htmlEscape(fullTimeText) + '"' +
+ '>' +
+ '<span>' + core.htmlEscape(timeText) + '</span>' +
+ '</div>' :
+ '') +
+ (eventDef.title ?
+ '<div class="fc-title">' +
+ core.htmlEscape(eventDef.title) +
+ '</div>' :
+ '') +
+ '</div>' +
+ /* TODO: write CSS for this
+ (isResizableFromStart ?
+ '<div class="fc-resizer fc-start-resizer"></div>' :
+ ''
+ ) +
+ */
+ (isResizableFromEnd ?
+ '<div class="fc-resizer fc-end-resizer"></div>' :
+ '') +
+ '</a>';
+ };
+ // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
+ // Assumed the segs are already ordered.
+ // NOTE: Also reorders the given array by date!
+ TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) {
+ var levels;
+ var level0;
+ var i;
+ levels = buildSlotSegLevels(segs);
+ computeForwardSlotSegs(levels);
+ if ((level0 = levels[0])) {
+ for (i = 0; i < level0.length; i++) {
+ computeSlotSegPressures(level0[i]);
+ }
+ for (i = 0; i < level0.length; i++) {
+ this.computeSegForwardBack(level0[i], 0, 0);
+ }
+ }
+ };
+ // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
+ // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
+ // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
+ //
+ // The segment might be part of a "series", which means consecutive segments with the same pressure
+ // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
+ // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
+ // coordinate of the first segment in the series.
+ TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
+ var forwardSegs = seg.forwardSegs;
+ var i;
+ if (seg.forwardCoord === undefined) { // not already computed
+ if (!forwardSegs.length) {
+ // if there are no forward segments, this segment should butt up against the edge
+ seg.forwardCoord = 1;
+ }
+ else {
+ // sort highest pressure first
+ this.sortForwardSegs(forwardSegs);
+ // this segment's forwardCoord will be calculated from the backwardCoord of the
+ // highest-pressure forward segment.
+ this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
+ seg.forwardCoord = forwardSegs[0].backwardCoord;
+ }
+ // calculate the backwardCoord from the forwardCoord. consider the series
+ seg.backwardCoord = seg.forwardCoord -
+ (seg.forwardCoord - seriesBackwardCoord) / // available width for series
+ (seriesBackwardPressure + 1); // # of segments in the series
+ // use this segment's coordinates to computed the coordinates of the less-pressurized
+ // forward segments
+ for (i = 0; i < forwardSegs.length; i++) {
+ this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
+ }
+ }
+ };
+ TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
+ var objs = forwardSegs.map(buildTimeGridSegCompareObj);
+ var specs = [
+ // put higher-pressure first
+ { field: 'forwardPressure', order: -1 },
+ // put segments that are closer to initial edge first (and favor ones with no coords yet)
+ { field: 'backwardCoord', order: 1 }
+ ].concat(this.context.view.eventOrderSpecs);
+ objs.sort(function (obj0, obj1) {
+ return core.compareByFieldSpecs(obj0, obj1, specs);
+ });
+ return objs.map(function (c) {
+ return c._seg;
+ });
+ };
+ // Given foreground event segments that have already had their position coordinates computed,
+ // assigns position-related CSS values to their elements.
+ TimeGridEventRenderer.prototype.assignSegCss = function (segs) {
+ for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+ var seg = segs_1[_i];
+ core.applyStyle(seg.el, this.generateSegCss(seg));
+ if (seg.level > 0) {
+ seg.el.classList.add('fc-time-grid-event-inset');
+ }
+ // if the event is short that the title will be cut off,
+ // attach a className that condenses the title into the time area.
+ if (seg.eventRange.def.title && seg.bottom - seg.top < 30) {
+ seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name
+ }
+ }
+ };
+ // Generates an object with CSS properties/values that should be applied to an event segment element.
+ // Contains important positioning-related properties that should be applied to any event element, customized or not.
+ TimeGridEventRenderer.prototype.generateSegCss = function (seg) {
+ var shouldOverlap = this.context.options.slotEventOverlap;
+ var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
+ var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
+ var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
+ var isRtl = this.timeGrid.isRtl;
+ var left; // amount of space from left edge, a fraction of the total width
+ var right; // amount of space from right edge, a fraction of the total width
+ if (shouldOverlap) {
+ // double the width, but don't go beyond the maximum forward coordinate (1.0)
+ forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
+ }
+ if (isRtl) {
+ left = 1 - forwardCoord;
+ right = backwardCoord;
+ }
+ else {
+ left = backwardCoord;
+ right = 1 - forwardCoord;
+ }
+ props.zIndex = seg.level + 1; // convert from 0-base to 1-based
+ props.left = left * 100 + '%';
+ props.right = right * 100 + '%';
+ if (shouldOverlap && seg.forwardPressure) {
+ // add padding to the edge so that forward stacked events don't cover the resizer's icon
+ props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
+ }
+ return props;
+ };
+ return TimeGridEventRenderer;
+ }(core.FgEventRenderer));
+ // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
+ // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
+ function buildSlotSegLevels(segs) {
+ var levels = [];
+ var i;
+ var seg;
+ var j;
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ // go through all the levels and stop on the first level where there are no collisions
+ for (j = 0; j < levels.length; j++) {
+ if (!computeSlotSegCollisions(seg, levels[j]).length) {
+ break;
+ }
+ }
+ seg.level = j;
+ (levels[j] || (levels[j] = [])).push(seg);
+ }
+ return levels;
+ }
+ // For every segment, figure out the other segments that are in subsequent
+ // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
+ function computeForwardSlotSegs(levels) {
+ var i;
+ var level;
+ var j;
+ var seg;
+ var k;
+ for (i = 0; i < levels.length; i++) {
+ level = levels[i];
+ for (j = 0; j < level.length; j++) {
+ seg = level[j];
+ seg.forwardSegs = [];
+ for (k = i + 1; k < levels.length; k++) {
+ computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
+ }
+ }
+ }
+ }
+ // Figure out which path forward (via seg.forwardSegs) results in the longest path until
+ // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
+ function computeSlotSegPressures(seg) {
+ var forwardSegs = seg.forwardSegs;
+ var forwardPressure = 0;
+ var i;
+ var forwardSeg;
+ if (seg.forwardPressure === undefined) { // not already computed
+ for (i = 0; i < forwardSegs.length; i++) {
+ forwardSeg = forwardSegs[i];
+ // figure out the child's maximum forward path
+ computeSlotSegPressures(forwardSeg);
+ // either use the existing maximum, or use the child's forward pressure
+ // plus one (for the forwardSeg itself)
+ forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
+ }
+ seg.forwardPressure = forwardPressure;
+ }
+ }
+ // Find all the segments in `otherSegs` that vertically collide with `seg`.
+ // Append into an optionally-supplied `results` array and return.
+ function computeSlotSegCollisions(seg, otherSegs, results) {
+ if (results === void 0) { results = []; }
+ for (var i = 0; i < otherSegs.length; i++) {
+ if (isSlotSegCollision(seg, otherSegs[i])) {
+ results.push(otherSegs[i]);
+ }
+ }
+ return results;
+ }
+ // Do these segments occupy the same vertical space?
+ function isSlotSegCollision(seg1, seg2) {
+ return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
+ }
+ function buildTimeGridSegCompareObj(seg) {
+ var obj = core.buildSegCompareObj(seg);
+ obj.forwardPressure = seg.forwardPressure;
+ obj.backwardCoord = seg.backwardCoord;
+ return obj;
+ }
+
+ var TimeGridMirrorRenderer = /** @class */ (function (_super) {
+ __extends(TimeGridMirrorRenderer, _super);
+ function TimeGridMirrorRenderer() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
+ this.segsByCol = this.timeGrid.groupSegsByCol(segs);
+ this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls);
+ this.sourceSeg = mirrorInfo.sourceSeg;
+ };
+ TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) {
+ var props = _super.prototype.generateSegCss.call(this, seg);
+ var sourceSeg = this.sourceSeg;
+ if (sourceSeg && sourceSeg.col === seg.col) {
+ var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg);
+ props.left = sourceSegProps.left;
+ props.right = sourceSegProps.right;
+ props.marginLeft = sourceSegProps.marginLeft;
+ props.marginRight = sourceSegProps.marginRight;
+ }
+ return props;
+ };
+ return TimeGridMirrorRenderer;
+ }(TimeGridEventRenderer));
+
+ var TimeGridFillRenderer = /** @class */ (function (_super) {
+ __extends(TimeGridFillRenderer, _super);
+ function TimeGridFillRenderer(timeGrid) {
+ var _this = _super.call(this, timeGrid.context) || this;
+ _this.timeGrid = timeGrid;
+ return _this;
+ }
+ TimeGridFillRenderer.prototype.attachSegs = function (type, segs) {
+ var timeGrid = this.timeGrid;
+ var containerEls;
+ // TODO: more efficient lookup
+ if (type === 'bgEvent') {
+ containerEls = timeGrid.bgContainerEls;
+ }
+ else if (type === 'businessHours') {
+ containerEls = timeGrid.businessContainerEls;
+ }
+ else if (type === 'highlight') {
+ containerEls = timeGrid.highlightContainerEls;
+ }
+ timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
+ return segs.map(function (seg) {
+ return seg.el;
+ });
+ };
+ TimeGridFillRenderer.prototype.computeSegSizes = function (segs) {
+ this.timeGrid.computeSegVerticals(segs);
+ };
+ TimeGridFillRenderer.prototype.assignSegSizes = function (segs) {
+ this.timeGrid.assignSegVerticals(segs);
+ };
+ return TimeGridFillRenderer;
+ }(core.FillRenderer));
+
+ /* A component that renders one or more columns of vertical time slots
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // potential nice values for the slot-duration and interval-duration
+ // from largest to smallest
+ var AGENDA_STOCK_SUB_DURATIONS = [
+ { hours: 1 },
+ { minutes: 30 },
+ { minutes: 15 },
+ { seconds: 30 },
+ { seconds: 15 }
+ ];
+ var TimeGrid = /** @class */ (function (_super) {
+ __extends(TimeGrid, _super);
+ function TimeGrid(context, el, renderProps) {
+ var _this = _super.call(this, context, el) || this;
+ _this.isSlatSizesDirty = false;
+ _this.isColSizesDirty = false;
+ _this.renderSlats = core.memoizeRendering(_this._renderSlats);
+ var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this);
+ var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this);
+ _this.mirrorRenderer = new TimeGridMirrorRenderer(_this);
+ var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns);
+ _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]);
+ _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]);
+ _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]);
+ _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]);
+ _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
+ _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]);
+ _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]);
+ _this.processOptions();
+ el.innerHTML =
+ '<div class="fc-bg"></div>' +
+ '<div class="fc-slats"></div>' +
+ '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />';
+ _this.rootBgContainerEl = el.querySelector('.fc-bg');
+ _this.slatContainerEl = el.querySelector('.fc-slats');
+ _this.bottomRuleEl = el.querySelector('.fc-divider');
+ _this.renderProps = renderProps;
+ return _this;
+ }
+ /* Options
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Parses various options into properties of this object
+ TimeGrid.prototype.processOptions = function () {
+ var slotDuration = this.opt('slotDuration');
+ var snapDuration = this.opt('snapDuration');
+ var snapsPerSlot;
+ var input;
+ slotDuration = core.createDuration(slotDuration);
+ snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration;
+ snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration);
+ if (snapsPerSlot === null) {
+ snapDuration = slotDuration;
+ snapsPerSlot = 1;
+ // TODO: say warning?
+ }
+ this.slotDuration = slotDuration;
+ this.snapDuration = snapDuration;
+ this.snapsPerSlot = snapsPerSlot;
+ // might be an array value (for TimelineView).
+ // if so, getting the most granular entry (the last one probably).
+ input = this.opt('slotLabelFormat');
+ if (Array.isArray(input)) {
+ input = input[input.length - 1];
+ }
+ this.labelFormat = core.createFormatter(input || {
+ hour: 'numeric',
+ minute: '2-digit',
+ omitZeroMinute: true,
+ meridiem: 'short'
+ });
+ input = this.opt('slotLabelInterval');
+ this.labelInterval = input ?
+ core.createDuration(input) :
+ this.computeLabelInterval(slotDuration);
+ };
+ // Computes an automatic value for slotLabelInterval
+ TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
+ var i;
+ var labelInterval;
+ var slotsPerLabel;
+ // find the smallest stock label interval that results in more than one slots-per-label
+ for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
+ labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
+ slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration);
+ if (slotsPerLabel !== null && slotsPerLabel > 1) {
+ return labelInterval;
+ }
+ }
+ return slotDuration; // fall back
+ };
+ /* Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype.render = function (props) {
+ var cells = props.cells;
+ this.colCnt = cells.length;
+ this.renderSlats(props.dateProfile);
+ this.renderColumns(props.cells, props.dateProfile);
+ this.renderBusinessHours(props.businessHourSegs);
+ this.renderDateSelection(props.dateSelectionSegs);
+ this.renderFgEvents(props.fgEventSegs);
+ this.renderBgEvents(props.bgEventSegs);
+ this.renderEventSelection(props.eventSelection);
+ this.renderEventDrag(props.eventDrag);
+ this.renderEventResize(props.eventResize);
+ };
+ TimeGrid.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ // should unrender everything else too
+ this.renderSlats.unrender();
+ this.renderColumns.unrender();
+ };
+ TimeGrid.prototype.updateSize = function (isResize) {
+ var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
+ if (isResize || this.isSlatSizesDirty) {
+ this.buildSlatPositions();
+ this.isSlatSizesDirty = false;
+ }
+ if (isResize || this.isColSizesDirty) {
+ this.buildColPositions();
+ this.isColSizesDirty = false;
+ }
+ fillRenderer.computeSizes(isResize);
+ eventRenderer.computeSizes(isResize);
+ mirrorRenderer.computeSizes(isResize);
+ fillRenderer.assignSizes(isResize);
+ eventRenderer.assignSizes(isResize);
+ mirrorRenderer.assignSizes(isResize);
+ };
+ TimeGrid.prototype._renderSlats = function (dateProfile) {
+ var theme = this.theme;
+ this.slatContainerEl.innerHTML =
+ '<table class="' + theme.getClass('tableGrid') + '">' +
+ this.renderSlatRowHtml(dateProfile) +
+ '</table>';
+ this.slatEls = core.findElements(this.slatContainerEl, 'tr');
+ this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical
+ );
+ this.isSlatSizesDirty = true;
+ };
+ // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
+ TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) {
+ var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl;
+ var html = '';
+ var dayStart = core.startOfDay(dateProfile.renderRange.start);
+ var slotTime = dateProfile.minTime;
+ var slotIterator = core.createDuration(0);
+ var slotDate; // will be on the view's first day, but we only care about its time
+ var isLabeled;
+ var axisHtml;
+ // Calculate the time for each slot
+ while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) {
+ slotDate = dateEnv.add(dayStart, slotTime);
+ isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null;
+ axisHtml =
+ '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' +
+ (isLabeled ?
+ '<span>' + // for matchCellWidths
+ core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) +
+ '</span>' :
+ '') +
+ '</td>';
+ html +=
+ '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' +
+ (isLabeled ? '' : ' class="fc-minor"') +
+ '>' +
+ (!isRtl ? axisHtml : '') +
+ '<td class="' + theme.getClass('widgetContent') + '"></td>' +
+ (isRtl ? axisHtml : '') +
+ '</tr>';
+ slotTime = core.addDurations(slotTime, this.slotDuration);
+ slotIterator = core.addDurations(slotIterator, this.slotDuration);
+ }
+ return html;
+ };
+ TimeGrid.prototype._renderColumns = function (cells, dateProfile) {
+ var theme = this.theme;
+ var bgRow = new daygrid.DayBgRow(this.context);
+ this.rootBgContainerEl.innerHTML =
+ '<table class="' + theme.getClass('tableGrid') + '">' +
+ bgRow.renderHtml({
+ cells: cells,
+ dateProfile: dateProfile,
+ renderIntroHtml: this.renderProps.renderBgIntroHtml
+ }) +
+ '</table>';
+ this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
+ if (this.isRtl) {
+ this.colEls.reverse();
+ }
+ this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal
+ false);
+ this.renderContentSkeleton();
+ this.isColSizesDirty = true;
+ };
+ TimeGrid.prototype._unrenderColumns = function () {
+ this.unrenderContentSkeleton();
+ };
+ /* Content Skeleton
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Renders the DOM that the view's content will live in
+ TimeGrid.prototype.renderContentSkeleton = function () {
+ var parts = [];
+ var skeletonEl;
+ parts.push(this.renderProps.renderIntroHtml());
+ for (var i = 0; i < this.colCnt; i++) {
+ parts.push('<td>' +
+ '<div class="fc-content-col">' +
+ '<div class="fc-event-container fc-mirror-container"></div>' +
+ '<div class="fc-event-container"></div>' +
+ '<div class="fc-highlight-container"></div>' +
+ '<div class="fc-bgevent-container"></div>' +
+ '<div class="fc-business-container"></div>' +
+ '</div>' +
+ '</td>');
+ }
+ if (this.isRtl) {
+ parts.reverse();
+ }
+ skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' +
+ '<table>' +
+ '<tr>' + parts.join('') + '</tr>' +
+ '</table>' +
+ '</div>');
+ this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col');
+ this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container');
+ this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)');
+ this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container');
+ this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container');
+ this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container');
+ if (this.isRtl) {
+ this.colContainerEls.reverse();
+ this.mirrorContainerEls.reverse();
+ this.fgContainerEls.reverse();
+ this.bgContainerEls.reverse();
+ this.highlightContainerEls.reverse();
+ this.businessContainerEls.reverse();
+ }
+ this.el.appendChild(skeletonEl);
+ };
+ TimeGrid.prototype.unrenderContentSkeleton = function () {
+ core.removeElement(this.contentSkeletonEl);
+ };
+ // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
+ TimeGrid.prototype.groupSegsByCol = function (segs) {
+ var segsByCol = [];
+ var i;
+ for (i = 0; i < this.colCnt; i++) {
+ segsByCol.push([]);
+ }
+ for (i = 0; i < segs.length; i++) {
+ segsByCol[segs[i].col].push(segs[i]);
+ }
+ return segsByCol;
+ };
+ // Given segments grouped by column, insert the segments' elements into a parallel array of container
+ // elements, each living within a column.
+ TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
+ var col;
+ var segs;
+ var i;
+ for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
+ segs = segsByCol[col];
+ for (i = 0; i < segs.length; i++) {
+ containerEls[col].appendChild(segs[i].el);
+ }
+ }
+ };
+ /* Now Indicator
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype.getNowIndicatorUnit = function () {
+ return 'minute'; // will refresh on the minute
+ };
+ TimeGrid.prototype.renderNowIndicator = function (segs, date) {
+ // HACK: if date columns not ready for some reason (scheduler)
+ if (!this.colContainerEls) {
+ return;
+ }
+ var top = this.computeDateTop(date);
+ var nodes = [];
+ var i;
+ // render lines within the columns
+ for (i = 0; i < segs.length; i++) {
+ var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' });
+ lineEl.style.top = top + 'px';
+ this.colContainerEls[segs[i].col].appendChild(lineEl);
+ nodes.push(lineEl);
+ }
+ // render an arrow over the axis
+ if (segs.length > 0) { // is the current time in view?
+ var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' });
+ arrowEl.style.top = top + 'px';
+ this.contentSkeletonEl.appendChild(arrowEl);
+ nodes.push(arrowEl);
+ }
+ this.nowIndicatorEls = nodes;
+ };
+ TimeGrid.prototype.unrenderNowIndicator = function () {
+ if (this.nowIndicatorEls) {
+ this.nowIndicatorEls.forEach(core.removeElement);
+ this.nowIndicatorEls = null;
+ }
+ };
+ /* Coordinates
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype.getTotalSlatHeight = function () {
+ return this.slatContainerEl.offsetHeight;
+ };
+ // Computes the top coordinate, relative to the bounds of the grid, of the given date.
+ // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
+ TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) {
+ if (!startOfDayDate) {
+ startOfDayDate = core.startOfDay(when);
+ }
+ return this.computeTimeTop(when.valueOf() - startOfDayDate.valueOf());
+ };
+ // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
+ TimeGrid.prototype.computeTimeTop = function (timeMs) {
+ var len = this.slatEls.length;
+ var dateProfile = this.props.dateProfile;
+ var slatCoverage = (timeMs - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered
+ var slatIndex;
+ var slatRemainder;
+ // compute a floating-point number for how many slats should be progressed through.
+ // from 0 to number of slats (inclusive)
+ // constrained because minTime/maxTime might be customized.
+ slatCoverage = Math.max(0, slatCoverage);
+ slatCoverage = Math.min(len, slatCoverage);
+ // an integer index of the furthest whole slat
+ // from 0 to number slats (*exclusive*, so len-1)
+ slatIndex = Math.floor(slatCoverage);
+ slatIndex = Math.min(slatIndex, len - 1);
+ // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
+ // could be 1.0 if slatCoverage is covering *all* the slots
+ slatRemainder = slatCoverage - slatIndex;
+ return this.slatPositions.tops[slatIndex] +
+ this.slatPositions.getHeight(slatIndex) * slatRemainder;
+ };
+ // For each segment in an array, computes and assigns its top and bottom properties
+ TimeGrid.prototype.computeSegVerticals = function (segs) {
+ var eventMinHeight = this.opt('timeGridEventMinHeight');
+ var i;
+ var seg;
+ var dayDate;
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ dayDate = this.props.cells[seg.col].date;
+ seg.top = this.computeDateTop(seg.start, dayDate);
+ seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate));
+ }
+ };
+ // Given segments that already have their top/bottom properties computed, applies those values to
+ // the segments' elements.
+ TimeGrid.prototype.assignSegVerticals = function (segs) {
+ var i;
+ var seg;
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ core.applyStyle(seg.el, this.generateSegVerticalCss(seg));
+ }
+ };
+ // Generates an object with CSS properties for the top/bottom coordinates of a segment element
+ TimeGrid.prototype.generateSegVerticalCss = function (seg) {
+ return {
+ top: seg.top,
+ bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
+ };
+ };
+ /* Sizing
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype.buildColPositions = function () {
+ this.colPositions.build();
+ };
+ TimeGrid.prototype.buildSlatPositions = function () {
+ this.slatPositions.build();
+ };
+ /* Hit System
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) {
+ var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions;
+ var colIndex = colPositions.leftToIndex(positionLeft);
+ var slatIndex = slatPositions.topToIndex(positionTop);
+ if (colIndex != null && slatIndex != null) {
+ var slatTop = slatPositions.tops[slatIndex];
+ var slatHeight = slatPositions.getHeight(slatIndex);
+ var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
+ var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
+ var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
+ var dayDate = this.props.cells[colIndex].date;
+ var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex));
+ var start = dateEnv.add(dayDate, time);
+ var end = dateEnv.add(start, this.snapDuration);
+ return {
+ col: colIndex,
+ dateSpan: {
+ range: { start: start, end: end },
+ allDay: false
+ },
+ dayEl: this.colEls[colIndex],
+ relativeRect: {
+ left: colPositions.lefts[colIndex],
+ right: colPositions.rights[colIndex],
+ top: slatTop,
+ bottom: slatTop + slatHeight
+ }
+ };
+ }
+ };
+ /* Event Drag Visualization
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype._renderEventDrag = function (state) {
+ if (state) {
+ this.eventRenderer.hideByHash(state.affectedInstances);
+ if (state.isEvent) {
+ this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
+ }
+ else {
+ this.fillRenderer.renderSegs('highlight', state.segs);
+ }
+ }
+ };
+ TimeGrid.prototype._unrenderEventDrag = function (state) {
+ if (state) {
+ this.eventRenderer.showByHash(state.affectedInstances);
+ this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
+ this.fillRenderer.unrender('highlight');
+ }
+ };
+ /* Event Resize Visualization
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGrid.prototype._renderEventResize = function (state) {
+ if (state) {
+ this.eventRenderer.hideByHash(state.affectedInstances);
+ this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
+ }
+ };
+ TimeGrid.prototype._unrenderEventResize = function (state) {
+ if (state) {
+ this.eventRenderer.showByHash(state.affectedInstances);
+ this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
+ }
+ };
+ /* Selection
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
+ TimeGrid.prototype._renderDateSelection = function (segs) {
+ if (segs) {
+ if (this.opt('selectMirror')) {
+ this.mirrorRenderer.renderSegs(segs, { isSelecting: true });
+ }
+ else {
+ this.fillRenderer.renderSegs('highlight', segs);
+ }
+ }
+ };
+ TimeGrid.prototype._unrenderDateSelection = function (segs) {
+ this.mirrorRenderer.unrender(segs, { isSelecting: true });
+ this.fillRenderer.unrender('highlight');
+ };
+ return TimeGrid;
+ }(core.DateComponent));
+
+ var AllDaySplitter = /** @class */ (function (_super) {
+ __extends(AllDaySplitter, _super);
+ function AllDaySplitter() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ AllDaySplitter.prototype.getKeyInfo = function () {
+ return {
+ allDay: {},
+ timed: {}
+ };
+ };
+ AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
+ if (dateSpan.allDay) {
+ return ['allDay'];
+ }
+ else {
+ return ['timed'];
+ }
+ };
+ AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
+ if (!eventDef.allDay) {
+ return ['timed'];
+ }
+ else if (core.hasBgRendering(eventDef)) {
+ return ['timed', 'allDay'];
+ }
+ else {
+ return ['allDay'];
+ }
+ };
+ return AllDaySplitter;
+ }(core.Splitter));
+
+ var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5;
+ var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' });
+ /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically.
+ ----------------------------------------------------------------------------------------------------------------------*/
+ // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
+ // Responsible for managing width/height.
+ var TimeGridView = /** @class */ (function (_super) {
+ __extends(TimeGridView, _super);
+ function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
+ _this.splitter = new AllDaySplitter();
+ /* Header Render Methods
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Generates the HTML that will go before the day-of week header cells
+ _this.renderHeadIntroHtml = function () {
+ var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv;
+ var range = _this.props.dateProfile.renderRange;
+ var dayCnt = core.diffDays(range.start, range.end);
+ var weekText;
+ if (_this.opt('weekNumbers')) {
+ weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT);
+ return '' +
+ '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' +
+ core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
+ _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML
+ ) +
+ '</th>';
+ }
+ else {
+ return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>';
+ }
+ };
+ /* Time Grid Render Methods
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
+ _this.renderTimeGridBgIntroHtml = function () {
+ var theme = _this.theme;
+ return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>';
+ };
+ // Generates the HTML that goes before all other types of cells.
+ // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
+ _this.renderTimeGridIntroHtml = function () {
+ return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
+ };
+ /* Day Grid Render Methods
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Generates the HTML that goes before the all-day cells
+ _this.renderDayGridBgIntroHtml = function () {
+ var theme = _this.theme;
+ return '' +
+ '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' +
+ '<span>' + // needed for matchCellWidths
+ core.getAllDayHtml(_this) +
+ '</span>' +
+ '</td>';
+ };
+ // Generates the HTML that goes before all other types of cells.
+ // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
+ _this.renderDayGridIntroHtml = function () {
+ return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
+ };
+ _this.el.classList.add('fc-timeGrid-view');
+ _this.el.innerHTML = _this.renderSkeletonHtml();
+ _this.scroller = new core.ScrollComponent('hidden', // overflow x
+ 'auto' // overflow y
+ );
+ var timeGridWrapEl = _this.scroller.el;
+ _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl);
+ timeGridWrapEl.classList.add('fc-time-grid-container');
+ var timeGridEl = core.createElement('div', { className: 'fc-time-grid' });
+ timeGridWrapEl.appendChild(timeGridEl);
+ _this.timeGrid = new TimeGrid(_this.context, timeGridEl, {
+ renderBgIntroHtml: _this.renderTimeGridBgIntroHtml,
+ renderIntroHtml: _this.renderTimeGridIntroHtml
+ });
+ if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
+ _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view
+ _this.context, _this.el.querySelector('.fc-day-grid'), {
+ renderNumberIntroHtml: _this.renderDayGridIntroHtml,
+ renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
+ renderIntroHtml: _this.renderDayGridIntroHtml,
+ colWeekNumbersVisible: false,
+ cellWeekNumbersVisible: false
+ });
+ // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
+ _this.dayGrid.bottomCoordPadding = _this.el.querySelector('.fc-divider').offsetHeight;
+ }
+ return _this;
+ }
+ TimeGridView.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.timeGrid.destroy();
+ if (this.dayGrid) {
+ this.dayGrid.destroy();
+ }
+ this.scroller.destroy();
+ };
+ /* Rendering
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Builds the HTML skeleton for the view.
+ // The day-grid and time-grid components will render inside containers defined by this HTML.
+ TimeGridView.prototype.renderSkeletonHtml = function () {
+ var theme = this.theme;
+ return '' +
+ '<table class="' + theme.getClass('tableGrid') + '">' +
+ (this.opt('columnHeader') ?
+ '<thead class="fc-head">' +
+ '<tr>' +
+ '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
+ '</tr>' +
+ '</thead>' :
+ '') +
+ '<tbody class="fc-body">' +
+ '<tr>' +
+ '<td class="' + theme.getClass('widgetContent') + '">' +
+ (this.opt('allDaySlot') ?
+ '<div class="fc-day-grid"></div>' +
+ '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' :
+ '') +
+ '</td>' +
+ '</tr>' +
+ '</tbody>' +
+ '</table>';
+ };
+ /* Now Indicator
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGridView.prototype.getNowIndicatorUnit = function () {
+ return this.timeGrid.getNowIndicatorUnit();
+ };
+ // subclasses should implement
+ // renderNowIndicator(date: DateMarker) {
+ // }
+ TimeGridView.prototype.unrenderNowIndicator = function () {
+ this.timeGrid.unrenderNowIndicator();
+ };
+ /* Dimensions
+ ------------------------------------------------------------------------------------------------------------------*/
+ TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
+ _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
+ this.timeGrid.updateSize(isResize);
+ if (this.dayGrid) {
+ this.dayGrid.updateSize(isResize);
+ }
+ };
+ // Adjusts the vertical dimensions of the view to the specified values
+ TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
+ var _this = this;
+ var eventLimit;
+ var scrollerHeight;
+ var scrollbarWidths;
+ // make all axis cells line up
+ this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis'));
+ // hack to give the view some height prior to timeGrid's columns being rendered
+ // TODO: separate setting height from scroller VS timeGrid.
+ if (!this.timeGrid.colEls) {
+ if (!isAuto) {
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.scroller.setHeight(scrollerHeight);
+ }
+ return;
+ }
+ // set of fake row elements that must compensate when scroller has scrollbars
+ var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) {
+ return !_this.scroller.el.contains(node);
+ });
+ // reset all dimensions back to the original state
+ this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary
+ this.scroller.clear(); // sets height to 'auto' and clears overflow
+ noScrollRowEls.forEach(core.uncompensateScroll);
+ // limit number of events in the all-day area
+ if (this.dayGrid) {
+ this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
+ eventLimit = this.opt('eventLimit');
+ if (eventLimit && typeof eventLimit !== 'number') {
+ eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
+ }
+ if (eventLimit) {
+ this.dayGrid.limitRows(eventLimit);
+ }
+ }
+ if (!isAuto) { // should we force dimensions of the scroll container?
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.scroller.setHeight(scrollerHeight);
+ scrollbarWidths = this.scroller.getScrollbarWidths();
+ if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
+ // make the all-day and header rows lines up
+ noScrollRowEls.forEach(function (rowEl) {
+ core.compensateScroll(rowEl, scrollbarWidths);
+ });
+ // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
+ // and reapply the desired height to the scroller.
+ scrollerHeight = this.computeScrollerHeight(viewHeight);
+ this.scroller.setHeight(scrollerHeight);
+ }
+ // guarantees the same scrollbar widths
+ this.scroller.lockOverflow(scrollbarWidths);
+ // if there's any space below the slats, show the horizontal rule.
+ // this won't cause any new overflow, because lockOverflow already called.
+ if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
+ this.timeGrid.bottomRuleEl.style.display = '';
+ }
+ }
+ };
+ // given a desired total height of the view, returns what the height of the scroller should be
+ TimeGridView.prototype.computeScrollerHeight = function (viewHeight) {
+ return viewHeight -
+ core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+ };
+ /* Scroll
+ ------------------------------------------------------------------------------------------------------------------*/
+ // Computes the initial pre-configured scroll state prior to allowing the user to change it
+ TimeGridView.prototype.computeInitialDateScroll = function () {
+ var scrollTime = core.createDuration(this.opt('scrollTime'));
+ var top = this.timeGrid.computeTimeTop(scrollTime.milliseconds);
+ // zoom can give weird floating-point values. rather scroll a little bit further
+ top = Math.ceil(top);
+ if (top) {
+ top++; // to overcome top border that slots beyond the first have. looks better
+ }
+ return { top: top };
+ };
+ TimeGridView.prototype.queryDateScroll = function () {
+ return { top: this.scroller.getScrollTop() };
+ };
+ TimeGridView.prototype.applyDateScroll = function (scroll) {
+ if (scroll.top !== undefined) {
+ this.scroller.setScrollTop(scroll.top);
+ }
+ };
+ // Generates an HTML attribute string for setting the width of the axis, if it is known
+ TimeGridView.prototype.axisStyleAttr = function () {
+ if (this.axisWidth != null) {
+ return 'style="width:' + this.axisWidth + 'px"';
+ }
+ return '';
+ };
+ return TimeGridView;
+ }(core.View));
+ TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
+
+ var SimpleTimeGrid = /** @class */ (function (_super) {
+ __extends(SimpleTimeGrid, _super);
+ function SimpleTimeGrid(context, timeGrid) {
+ var _this = _super.call(this, context, timeGrid.el) || this;
+ _this.buildDayRanges = core.memoize(buildDayRanges);
+ _this.slicer = new TimeGridSlicer();
+ _this.timeGrid = timeGrid;
+ context.calendar.registerInteractiveComponent(_this, {
+ el: _this.timeGrid.el
+ });
+ return _this;
+ }
+ SimpleTimeGrid.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ this.calendar.unregisterInteractiveComponent(this);
+ };
+ SimpleTimeGrid.prototype.render = function (props) {
+ var dateProfile = props.dateProfile, dayTable = props.dayTable;
+ var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv);
+ this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] }));
+ };
+ SimpleTimeGrid.prototype.renderNowIndicator = function (date) {
+ this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date);
+ };
+ SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) {
+ var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop);
+ if (rawHit) {
+ return {
+ component: this.timeGrid,
+ dateSpan: rawHit.dateSpan,
+ dayEl: rawHit.dayEl,
+ rect: {
+ left: rawHit.relativeRect.left,
+ right: rawHit.relativeRect.right,
+ top: rawHit.relativeRect.top,
+ bottom: rawHit.relativeRect.bottom
+ },
+ layer: 0
+ };
+ }
+ };
+ return SimpleTimeGrid;
+ }(core.DateComponent));
+ function buildDayRanges(dayTable, dateProfile, dateEnv) {
+ var ranges = [];
+ for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) {
+ var date = _a[_i];
+ ranges.push({
+ start: dateEnv.add(date, dateProfile.minTime),
+ end: dateEnv.add(date, dateProfile.maxTime)
+ });
+ }
+ return ranges;
+ }
+ var TimeGridSlicer = /** @class */ (function (_super) {
+ __extends(TimeGridSlicer, _super);
+ function TimeGridSlicer() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) {
+ var segs = [];
+ for (var col = 0; col < dayRanges.length; col++) {
+ var segRange = core.intersectRanges(range, dayRanges[col]);
+ if (segRange) {
+ segs.push({
+ start: segRange.start,
+ end: segRange.end,
+ isStart: segRange.start.valueOf() === range.start.valueOf(),
+ isEnd: segRange.end.valueOf() === range.end.valueOf(),
+ col: col
+ });
+ }
+ }
+ return segs;
+ };
+ return TimeGridSlicer;
+ }(core.Slicer));
+
+ var TimeGridView$1 = /** @class */ (function (_super) {
+ __extends(TimeGridView, _super);
+ function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
+ var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
+ _this.buildDayTable = core.memoize(buildDayTable);
+ if (_this.opt('columnHeader')) {
+ _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
+ }
+ _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid);
+ if (_this.dayGrid) {
+ _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid);
+ }
+ return _this;
+ }
+ TimeGridView.prototype.destroy = function () {
+ _super.prototype.destroy.call(this);
+ if (this.header) {
+ this.header.destroy();
+ }
+ this.simpleTimeGrid.destroy();
+ if (this.simpleDayGrid) {
+ this.simpleDayGrid.destroy();
+ }
+ };
+ TimeGridView.prototype.render = function (props) {
+ _super.prototype.render.call(this, props); // for flags for updateSize
+ var dateProfile = this.props.dateProfile;
+ var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator);
+ var splitProps = this.splitter.splitProps(props);
+ if (this.header) {
+ this.header.receiveProps({
+ dateProfile: dateProfile,
+ dates: dayTable.headerDates,
+ datesRepDistinctDays: true,
+ renderIntroHtml: this.renderHeadIntroHtml
+ });
+ }
+ this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile,
+ dayTable: dayTable }));
+ if (this.simpleDayGrid) {
+ this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile,
+ dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false }));
+ }
+ };
+ TimeGridView.prototype.renderNowIndicator = function (date) {
+ this.simpleTimeGrid.renderNowIndicator(date);
+ };
+ return TimeGridView;
+ }(TimeGridView));
+ function buildDayTable(dateProfile, dateProfileGenerator) {
+ var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
+ return new core.DayTable(daySeries, false);
+ }
+
+ var main = core.createPlugin({
+ defaultView: 'timeGridWeek',
+ views: {
+ timeGrid: {
+ class: TimeGridView$1,
+ allDaySlot: true,
+ slotDuration: '00:30:00',
+ slotEventOverlap: true // a bad name. confused with overlap/constraint system
+ },
+ timeGridDay: {
+ type: 'timeGrid',
+ duration: { days: 1 }
+ },
+ timeGridWeek: {
+ type: 'timeGrid',
+ duration: { weeks: 1 }
+ }
+ }
+ });
+
+ exports.AbstractTimeGridView = TimeGridView;
+ exports.TimeGrid = TimeGrid;
+ exports.TimeGridSlicer = TimeGridSlicer;
+ exports.TimeGridView = TimeGridView$1;
+ exports.buildDayRanges = buildDayRanges;
+ exports.buildDayTable = buildDayTable;
+ exports.default = main;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/library/fullcalendar/packages/timegrid/main.min.css b/library/fullcalendar/packages/timegrid/main.min.css
new file mode 100644
index 000000000..f603e1eeb
--- /dev/null
+++ b/library/fullcalendar/packages/timegrid/main.min.css
@@ -0,0 +1,5 @@
+/*!
+FullCalendar Time Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/.fc-timeGrid-view .fc-day-grid{position:relative;z-index:2}.fc-timeGrid-view .fc-day-grid .fc-row{min-height:3em}.fc-timeGrid-view .fc-day-grid .fc-row .fc-content-skeleton{padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px;white-space:nowrap}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-mirror-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-time-grid-event{margin-bottom:1px}.fc-time-grid-event-inset{-webkit-box-shadow:0 0 0 1px #fff;box-shadow:0 0 0 1px #fff}.fc-time-grid-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-time-grid-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event .fc-content{overflow:hidden;max-height:100%}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em;white-space:nowrap}.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after{content:"="}.fc-time-grid-event.fc-selected .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent} \ No newline at end of file
diff --git a/library/fullcalendar/packages/timegrid/main.min.js b/library/fullcalendar/packages/timegrid/main.min.js
new file mode 100644
index 000000000..309213ec9
--- /dev/null
+++ b/library/fullcalendar/packages/timegrid/main.min.js
@@ -0,0 +1,20 @@
+/*!
+FullCalendar Time Grid Plugin v4.0.2
+Docs & License: https://fullcalendar.io/
+(c) 2019 Adam Shaw
+*/
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@fullcalendar/core"),require("@fullcalendar/daygrid")):"function"==typeof define&&define.amd?define(["exports","@fullcalendar/core","@fullcalendar/daygrid"],t):(e=e||self,t(e.FullCalendarTimeGrid={},e.FullCalendar,e.FullCalendarDayGrid))}(this,function(e,t,r){"use strict";function i(e,t){function r(){this.constructor=e}u(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function n(e){var t,r,i,n=[];for(t=0;t<e.length;t++){for(r=e[t],i=0;i<n.length&&a(r,n[i]).length;i++);r.level=i,(n[i]||(n[i]=[])).push(r)}return n}function o(e){var t,r,i,n,o;for(t=0;t<e.length;t++)for(r=e[t],i=0;i<r.length;i++)for(n=r[i],n.forwardSegs=[],o=t+1;o<e.length;o++)a(n,e[o],n.forwardSegs)}function s(e){var t,r,i=e.forwardSegs,n=0;if(void 0===e.forwardPressure){for(t=0;t<i.length;t++)r=i[t],s(r),n=Math.max(n,1+r.forwardPressure);e.forwardPressure=n}}function a(e,t,r){void 0===r&&(r=[]);for(var i=0;i<t.length;i++)l(e,t[i])&&r.push(t[i]);return r}function l(e,t){return e.bottom>t.top&&e.top<t.bottom}function d(e){var r=t.buildSegCompareObj(e);return r.forwardPressure=e.forwardPressure,r.backwardCoord=e.backwardCoord,r}function c(e,t,r){for(var i=[],n=0,o=e.headerDates;n<o.length;n++){var s=o[n];i.push({start:r.add(s,t.minTime),end:r.add(s,t.maxTime)})}return i}function h(e,r){var i=new t.DaySeries(e.renderRange,r);return new t.DayTable(i,!1)}/*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+var u=function(e,t){return(u=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)},p=function(){return p=Object.assign||function(e){for(var t,r=1,i=arguments.length;r<i;r++){t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},p.apply(this,arguments)},f=function(e){function r(r){var i=e.call(this,r.context)||this;return i.timeGrid=r,i.fullTimeFormat=t.createFormatter({hour:"numeric",minute:"2-digit",separator:i.context.options.defaultRangeSeparator}),i}return i(r,e),r.prototype.attachSegs=function(e,t){for(var r=this.timeGrid.groupSegsByCol(e),i=0;i<r.length;i++)r[i]=this.sortEventSegs(r[i]);this.segsByCol=r,this.timeGrid.attachSegsByCol(r,this.timeGrid.fgContainerEls)},r.prototype.detachSegs=function(e){e.forEach(function(e){t.removeElement(e.el)}),this.segsByCol=null},r.prototype.computeSegSizes=function(e){var t=this,r=t.timeGrid,i=t.segsByCol,n=r.colCnt;if(r.computeSegVerticals(e),i)for(var o=0;o<n;o++)this.computeSegHorizontals(i[o])},r.prototype.assignSegSizes=function(e){var t=this,r=t.timeGrid,i=t.segsByCol,n=r.colCnt;if(r.assignSegVerticals(e),i)for(var o=0;o<n;o++)this.assignSegCss(i[o])},r.prototype.computeEventTimeFormat=function(){return{hour:"numeric",minute:"2-digit",meridiem:!1}},r.prototype.computeDisplayEventEnd=function(){return!0},r.prototype.renderSegHtml=function(e,r){var i,n,o,s=e.eventRange,a=s.def,l=s.ui,d=a.allDay,c=l.startEditable,h=e.isStart&&l.durationEditable&&this.context.options.eventResizableFromStart,u=e.isEnd&&l.durationEditable,p=this.getSegClasses(e,c,h||u,r),f=t.cssToStr(this.getSkinCss(l));if(p.unshift("fc-time-grid-event"),t.isMultiDayRange(s.range)){if(e.isStart||e.isEnd){var m=e.start,g=e.end;i=this._getTimeText(m,g,d),n=this._getTimeText(m,g,d,this.fullTimeFormat),o=this._getTimeText(m,g,d,null,!1)}}else i=this.getTimeText(s),n=this.getTimeText(s,this.fullTimeFormat),o=this.getTimeText(s,null,!1);return'<a class="'+p.join(" ")+'"'+(a.url?' href="'+t.htmlEscape(a.url)+'"':"")+(f?' style="'+f+'"':"")+'><div class="fc-content">'+(i?'<div class="fc-time" data-start="'+t.htmlEscape(o)+'" data-full="'+t.htmlEscape(n)+'"><span>'+t.htmlEscape(i)+"</span></div>":"")+(a.title?'<div class="fc-title">'+t.htmlEscape(a.title)+"</div>":"")+"</div>"+(u?'<div class="fc-resizer fc-end-resizer"></div>':"")+"</a>"},r.prototype.computeSegHorizontals=function(e){var t,r,i;if(t=n(e),o(t),r=t[0]){for(i=0;i<r.length;i++)s(r[i]);for(i=0;i<r.length;i++)this.computeSegForwardBack(r[i],0,0)}},r.prototype.computeSegForwardBack=function(e,t,r){var i,n=e.forwardSegs;if(void 0===e.forwardCoord)for(n.length?(this.sortForwardSegs(n),this.computeSegForwardBack(n[0],t+1,r),e.forwardCoord=n[0].backwardCoord):e.forwardCoord=1,e.backwardCoord=e.forwardCoord-(e.forwardCoord-r)/(t+1),i=0;i<n.length;i++)this.computeSegForwardBack(n[i],0,e.forwardCoord)},r.prototype.sortForwardSegs=function(e){var r=e.map(d),i=[{field:"forwardPressure",order:-1},{field:"backwardCoord",order:1}].concat(this.context.view.eventOrderSpecs);return r.sort(function(e,r){return t.compareByFieldSpecs(e,r,i)}),r.map(function(e){return e._seg})},r.prototype.assignSegCss=function(e){for(var r=0,i=e;r<i.length;r++){var n=i[r];t.applyStyle(n.el,this.generateSegCss(n)),n.level>0&&n.el.classList.add("fc-time-grid-event-inset"),n.eventRange.def.title&&n.bottom-n.top<30&&n.el.classList.add("fc-short")}},r.prototype.generateSegCss=function(e){var t,r,i=this.context.options.slotEventOverlap,n=e.backwardCoord,o=e.forwardCoord,s=this.timeGrid.generateSegVerticalCss(e),a=this.timeGrid.isRtl;return i&&(o=Math.min(1,n+2*(o-n))),a?(t=1-o,r=n):(t=n,r=1-o),s.zIndex=e.level+1,s.left=100*t+"%",s.right=100*r+"%",i&&e.forwardPressure&&(s[a?"marginLeft":"marginRight"]=20),s},r}(t.FgEventRenderer),m=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return i(t,e),t.prototype.attachSegs=function(e,t){this.segsByCol=this.timeGrid.groupSegsByCol(e),this.timeGrid.attachSegsByCol(this.segsByCol,this.timeGrid.mirrorContainerEls),this.sourceSeg=t.sourceSeg},t.prototype.generateSegCss=function(t){var r=e.prototype.generateSegCss.call(this,t),i=this.sourceSeg;if(i&&i.col===t.col){var n=e.prototype.generateSegCss.call(this,i);r.left=n.left,r.right=n.right,r.marginLeft=n.marginLeft,r.marginRight=n.marginRight}return r},t}(f),g=function(e){function t(t){var r=e.call(this,t.context)||this;return r.timeGrid=t,r}return i(t,e),t.prototype.attachSegs=function(e,t){var r,i=this.timeGrid;return"bgEvent"===e?r=i.bgContainerEls:"businessHours"===e?r=i.businessContainerEls:"highlight"===e&&(r=i.highlightContainerEls),i.attachSegsByCol(i.groupSegsByCol(t),r),t.map(function(e){return e.el})},t.prototype.computeSegSizes=function(e){this.timeGrid.computeSegVerticals(e)},t.prototype.assignSegSizes=function(e){this.timeGrid.assignSegVerticals(e)},t}(t.FillRenderer),y=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}],v=function(e){function n(r,i,n){var o=e.call(this,r,i)||this;o.isSlatSizesDirty=!1,o.isColSizesDirty=!1,o.renderSlats=t.memoizeRendering(o._renderSlats);var s=o.eventRenderer=new f(o),a=o.fillRenderer=new g(o);o.mirrorRenderer=new m(o);var l=o.renderColumns=t.memoizeRendering(o._renderColumns,o._unrenderColumns);return o.renderBusinessHours=t.memoizeRendering(a.renderSegs.bind(a,"businessHours"),a.unrender.bind(a,"businessHours"),[l]),o.renderDateSelection=t.memoizeRendering(o._renderDateSelection,o._unrenderDateSelection,[l]),o.renderFgEvents=t.memoizeRendering(s.renderSegs.bind(s),s.unrender.bind(s),[l]),o.renderBgEvents=t.memoizeRendering(a.renderSegs.bind(a,"bgEvent"),a.unrender.bind(a,"bgEvent"),[l]),o.renderEventSelection=t.memoizeRendering(s.selectByInstanceId.bind(s),s.unselectByInstanceId.bind(s),[o.renderFgEvents]),o.renderEventDrag=t.memoizeRendering(o._renderEventDrag,o._unrenderEventDrag,[l]),o.renderEventResize=t.memoizeRendering(o._renderEventResize,o._unrenderEventResize,[l]),o.processOptions(),i.innerHTML='<div class="fc-bg"></div><div class="fc-slats"></div><hr class="fc-divider '+o.theme.getClass("widgetHeader")+'" style="display:none" />',o.rootBgContainerEl=i.querySelector(".fc-bg"),o.slatContainerEl=i.querySelector(".fc-slats"),o.bottomRuleEl=i.querySelector(".fc-divider"),o.renderProps=n,o}return i(n,e),n.prototype.processOptions=function(){var e,r,i=this.opt("slotDuration"),n=this.opt("snapDuration");i=t.createDuration(i),n=n?t.createDuration(n):i,e=t.wholeDivideDurations(i,n),null===e&&(n=i,e=1),this.slotDuration=i,this.snapDuration=n,this.snapsPerSlot=e,r=this.opt("slotLabelFormat"),Array.isArray(r)&&(r=r[r.length-1]),this.labelFormat=t.createFormatter(r||{hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"short"}),r=this.opt("slotLabelInterval"),this.labelInterval=r?t.createDuration(r):this.computeLabelInterval(i)},n.prototype.computeLabelInterval=function(e){var r,i,n;for(r=y.length-1;r>=0;r--)if(i=t.createDuration(y[r]),null!==(n=t.wholeDivideDurations(i,e))&&n>1)return i;return e},n.prototype.render=function(e){var t=e.cells;this.colCnt=t.length,this.renderSlats(e.dateProfile),this.renderColumns(e.cells,e.dateProfile),this.renderBusinessHours(e.businessHourSegs),this.renderDateSelection(e.dateSelectionSegs),this.renderFgEvents(e.fgEventSegs),this.renderBgEvents(e.bgEventSegs),this.renderEventSelection(e.eventSelection),this.renderEventDrag(e.eventDrag),this.renderEventResize(e.eventResize)},n.prototype.destroy=function(){e.prototype.destroy.call(this),this.renderSlats.unrender(),this.renderColumns.unrender()},n.prototype.updateSize=function(e){var t=this,r=t.fillRenderer,i=t.eventRenderer,n=t.mirrorRenderer;(e||this.isSlatSizesDirty)&&(this.buildSlatPositions(),this.isSlatSizesDirty=!1),(e||this.isColSizesDirty)&&(this.buildColPositions(),this.isColSizesDirty=!1),r.computeSizes(e),i.computeSizes(e),n.computeSizes(e),r.assignSizes(e),i.assignSizes(e),n.assignSizes(e)},n.prototype._renderSlats=function(e){var r=this.theme;this.slatContainerEl.innerHTML='<table class="'+r.getClass("tableGrid")+'">'+this.renderSlatRowHtml(e)+"</table>",this.slatEls=t.findElements(this.slatContainerEl,"tr"),this.slatPositions=new t.PositionCache(this.el,this.slatEls,!1,!0),this.isSlatSizesDirty=!0},n.prototype.renderSlatRowHtml=function(e){for(var r,i,n,o=this,s=o.dateEnv,a=o.theme,l=o.isRtl,d="",c=t.startOfDay(e.renderRange.start),h=e.minTime,u=t.createDuration(0);t.asRoughMs(h)<t.asRoughMs(e.maxTime);)r=s.add(c,h),i=null!==t.wholeDivideDurations(u,this.labelInterval),n='<td class="fc-axis fc-time '+a.getClass("widgetContent")+'">'+(i?"<span>"+t.htmlEscape(s.format(r,this.labelFormat))+"</span>":"")+"</td>",d+='<tr data-time="'+t.formatIsoTimeString(r)+'"'+(i?"":' class="fc-minor"')+">"+(l?"":n)+'<td class="'+a.getClass("widgetContent")+'"></td>'+(l?n:"")+"</tr>",h=t.addDurations(h,this.slotDuration),u=t.addDurations(u,this.slotDuration);return d},n.prototype._renderColumns=function(e,i){var n=this.theme,o=new r.DayBgRow(this.context);this.rootBgContainerEl.innerHTML='<table class="'+n.getClass("tableGrid")+'">'+o.renderHtml({cells:e,dateProfile:i,renderIntroHtml:this.renderProps.renderBgIntroHtml})+"</table>",this.colEls=t.findElements(this.el,".fc-day, .fc-disabled-day"),this.isRtl&&this.colEls.reverse(),this.colPositions=new t.PositionCache(this.el,this.colEls,!0,!1),this.renderContentSkeleton(),this.isColSizesDirty=!0},n.prototype._unrenderColumns=function(){this.unrenderContentSkeleton()},n.prototype.renderContentSkeleton=function(){var e,r=[];r.push(this.renderProps.renderIntroHtml());for(var i=0;i<this.colCnt;i++)r.push('<td><div class="fc-content-col"><div class="fc-event-container fc-mirror-container"></div><div class="fc-event-container"></div><div class="fc-highlight-container"></div><div class="fc-bgevent-container"></div><div class="fc-business-container"></div></div></td>');this.isRtl&&r.reverse(),e=this.contentSkeletonEl=t.htmlToElement('<div class="fc-content-skeleton"><table><tr>'+r.join("")+"</tr></table></div>"),this.colContainerEls=t.findElements(e,".fc-content-col"),this.mirrorContainerEls=t.findElements(e,".fc-mirror-container"),this.fgContainerEls=t.findElements(e,".fc-event-container:not(.fc-mirror-container)"),this.bgContainerEls=t.findElements(e,".fc-bgevent-container"),this.highlightContainerEls=t.findElements(e,".fc-highlight-container"),this.businessContainerEls=t.findElements(e,".fc-business-container"),this.isRtl&&(this.colContainerEls.reverse(),this.mirrorContainerEls.reverse(),this.fgContainerEls.reverse(),this.bgContainerEls.reverse(),this.highlightContainerEls.reverse(),this.businessContainerEls.reverse()),this.el.appendChild(e)},n.prototype.unrenderContentSkeleton=function(){t.removeElement(this.contentSkeletonEl)},n.prototype.groupSegsByCol=function(e){var t,r=[];for(t=0;t<this.colCnt;t++)r.push([]);for(t=0;t<e.length;t++)r[e[t].col].push(e[t]);return r},n.prototype.attachSegsByCol=function(e,t){var r,i,n;for(r=0;r<this.colCnt;r++)for(i=e[r],n=0;n<i.length;n++)t[r].appendChild(i[n].el)},n.prototype.getNowIndicatorUnit=function(){return"minute"},n.prototype.renderNowIndicator=function(e,r){if(this.colContainerEls){var i,n=this.computeDateTop(r),o=[];for(i=0;i<e.length;i++){var s=t.createElement("div",{className:"fc-now-indicator fc-now-indicator-line"});s.style.top=n+"px",this.colContainerEls[e[i].col].appendChild(s),o.push(s)}if(e.length>0){var a=t.createElement("div",{className:"fc-now-indicator fc-now-indicator-arrow"});a.style.top=n+"px",this.contentSkeletonEl.appendChild(a),o.push(a)}this.nowIndicatorEls=o}},n.prototype.unrenderNowIndicator=function(){this.nowIndicatorEls&&(this.nowIndicatorEls.forEach(t.removeElement),this.nowIndicatorEls=null)},n.prototype.getTotalSlatHeight=function(){return this.slatContainerEl.offsetHeight},n.prototype.computeDateTop=function(e,r){return r||(r=t.startOfDay(e)),this.computeTimeTop(e.valueOf()-r.valueOf())},n.prototype.computeTimeTop=function(e){var r,i,n=this.slatEls.length,o=this.props.dateProfile,s=(e-t.asRoughMs(o.minTime))/t.asRoughMs(this.slotDuration);return s=Math.max(0,s),s=Math.min(n,s),r=Math.floor(s),r=Math.min(r,n-1),i=s-r,this.slatPositions.tops[r]+this.slatPositions.getHeight(r)*i},n.prototype.computeSegVerticals=function(e){var t,r,i,n=this.opt("timeGridEventMinHeight");for(t=0;t<e.length;t++)r=e[t],i=this.props.cells[r.col].date,r.top=this.computeDateTop(r.start,i),r.bottom=Math.max(r.top+n,this.computeDateTop(r.end,i))},n.prototype.assignSegVerticals=function(e){var r,i;for(r=0;r<e.length;r++)i=e[r],t.applyStyle(i.el,this.generateSegVerticalCss(i))},n.prototype.generateSegVerticalCss=function(e){return{top:e.top,bottom:-e.bottom}},n.prototype.buildColPositions=function(){this.colPositions.build()},n.prototype.buildSlatPositions=function(){this.slatPositions.build()},n.prototype.positionToHit=function(e,r){var i=this,n=i.dateEnv,o=i.snapsPerSlot,s=i.slatPositions,a=i.colPositions,l=a.leftToIndex(e),d=s.topToIndex(r);if(null!=l&&null!=d){var c=s.tops[d],h=s.getHeight(d),u=(r-c)/h,p=Math.floor(u*o),f=d*o+p,m=this.props.cells[l].date,g=t.addDurations(this.props.dateProfile.minTime,t.multiplyDuration(this.snapDuration,f)),y=n.add(m,g);return{col:l,dateSpan:{range:{start:y,end:n.add(y,this.snapDuration)},allDay:!1},dayEl:this.colEls[l],relativeRect:{left:a.lefts[l],right:a.rights[l],top:c,bottom:c+h}}}},n.prototype._renderEventDrag=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),e.isEvent?this.mirrorRenderer.renderSegs(e.segs,{isDragging:!0,sourceSeg:e.sourceSeg}):this.fillRenderer.renderSegs("highlight",e.segs))},n.prototype._unrenderEventDrag=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.mirrorRenderer.unrender(e.segs,{isDragging:!0,sourceSeg:e.sourceSeg}),this.fillRenderer.unrender("highlight"))},n.prototype._renderEventResize=function(e){e&&(this.eventRenderer.hideByHash(e.affectedInstances),this.mirrorRenderer.renderSegs(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype._unrenderEventResize=function(e){e&&(this.eventRenderer.showByHash(e.affectedInstances),this.mirrorRenderer.unrender(e.segs,{isResizing:!0,sourceSeg:e.sourceSeg}))},n.prototype._renderDateSelection=function(e){e&&(this.opt("selectMirror")?this.mirrorRenderer.renderSegs(e,{isSelecting:!0}):this.fillRenderer.renderSegs("highlight",e))},n.prototype._unrenderDateSelection=function(e){this.mirrorRenderer.unrender(e,{isSelecting:!0}),this.fillRenderer.unrender("highlight")},n}(t.DateComponent),S=function(e){function r(){return null!==e&&e.apply(this,arguments)||this}return i(r,e),r.prototype.getKeyInfo=function(){return{allDay:{},timed:{}}},r.prototype.getKeysForDateSpan=function(e){return e.allDay?["allDay"]:["timed"]},r.prototype.getKeysForEventDef=function(e){return e.allDay?t.hasBgRendering(e)?["timed","allDay"]:["allDay"]:["timed"]},r}(t.Splitter),C=t.createFormatter({week:"short"}),E=function(e){function n(i,n,o,s){var a=e.call(this,i,n,o,s)||this;a.splitter=new S,a.renderHeadIntroHtml=function(){var e,r=a,i=r.theme,n=r.dateEnv,o=a.props.dateProfile.renderRange,s=t.diffDays(o.start,o.end);return a.opt("weekNumbers")?(e=n.format(o.start,C),'<th class="fc-axis fc-week-number '+i.getClass("widgetHeader")+'" '+a.axisStyleAttr()+">"+t.buildGotoAnchorHtml(a,{date:o.start,type:"week",forceOff:s>1},t.htmlEscape(e))+"</th>"):'<th class="fc-axis '+i.getClass("widgetHeader")+'" '+a.axisStyleAttr()+"></th>"},a.renderTimeGridBgIntroHtml=function(){return'<td class="fc-axis '+a.theme.getClass("widgetContent")+'" '+a.axisStyleAttr()+"></td>"},a.renderTimeGridIntroHtml=function(){return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"},a.renderDayGridBgIntroHtml=function(){return'<td class="fc-axis '+a.theme.getClass("widgetContent")+'" '+a.axisStyleAttr()+"><span>"+t.getAllDayHtml(a)+"</span></td>"},a.renderDayGridIntroHtml=function(){return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"},a.el.classList.add("fc-timeGrid-view"),a.el.innerHTML=a.renderSkeletonHtml(),a.scroller=new t.ScrollComponent("hidden","auto");var l=a.scroller.el;a.el.querySelector(".fc-body > tr > td").appendChild(l),l.classList.add("fc-time-grid-container");var d=t.createElement("div",{className:"fc-time-grid"});return l.appendChild(d),a.timeGrid=new v(a.context,d,{renderBgIntroHtml:a.renderTimeGridBgIntroHtml,renderIntroHtml:a.renderTimeGridIntroHtml}),a.opt("allDaySlot")&&(a.dayGrid=new r.DayGrid(a.context,a.el.querySelector(".fc-day-grid"),{renderNumberIntroHtml:a.renderDayGridIntroHtml,renderBgIntroHtml:a.renderDayGridBgIntroHtml,renderIntroHtml:a.renderDayGridIntroHtml,colWeekNumbersVisible:!1,cellWeekNumbersVisible:!1}),a.dayGrid.bottomCoordPadding=a.el.querySelector(".fc-divider").offsetHeight),a}return i(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.timeGrid.destroy(),this.dayGrid&&this.dayGrid.destroy(),this.scroller.destroy()},n.prototype.renderSkeletonHtml=function(){var e=this.theme;return'<table class="'+e.getClass("tableGrid")+'">'+(this.opt("columnHeader")?'<thead class="fc-head"><tr><td class="fc-head-container '+e.getClass("widgetHeader")+'">&nbsp;</td></tr></thead>':"")+'<tbody class="fc-body"><tr><td class="'+e.getClass("widgetContent")+'">'+(this.opt("allDaySlot")?'<div class="fc-day-grid"></div><hr class="fc-divider '+e.getClass("widgetHeader")+'" />':"")+"</td></tr></tbody></table>"},n.prototype.getNowIndicatorUnit=function(){return this.timeGrid.getNowIndicatorUnit()},n.prototype.unrenderNowIndicator=function(){this.timeGrid.unrenderNowIndicator()},n.prototype.updateSize=function(t,r,i){e.prototype.updateSize.call(this,t,r,i),this.timeGrid.updateSize(t),this.dayGrid&&this.dayGrid.updateSize(t)},n.prototype.updateBaseSize=function(e,r,i){var n,o,s,a=this;if(this.axisWidth=t.matchCellWidths(t.findElements(this.el,".fc-axis")),!this.timeGrid.colEls)return void(i||(o=this.computeScrollerHeight(r),this.scroller.setHeight(o)));var l=t.findElements(this.el,".fc-row").filter(function(e){return!a.scroller.el.contains(e)});this.timeGrid.bottomRuleEl.style.display="none",this.scroller.clear(),l.forEach(t.uncompensateScroll),this.dayGrid&&(this.dayGrid.removeSegPopover(),n=this.opt("eventLimit"),n&&"number"!=typeof n&&(n=5),n&&this.dayGrid.limitRows(n)),i||(o=this.computeScrollerHeight(r),this.scroller.setHeight(o),s=this.scroller.getScrollbarWidths(),(s.left||s.right)&&(l.forEach(function(e){t.compensateScroll(e,s)}),o=this.computeScrollerHeight(r),this.scroller.setHeight(o)),this.scroller.lockOverflow(s),this.timeGrid.getTotalSlatHeight()<o&&(this.timeGrid.bottomRuleEl.style.display=""))},n.prototype.computeScrollerHeight=function(e){return e-t.subtractInnerElHeight(this.el,this.scroller.el)},n.prototype.computeInitialDateScroll=function(){var e=t.createDuration(this.opt("scrollTime")),r=this.timeGrid.computeTimeTop(e.milliseconds);return r=Math.ceil(r),r&&r++,{top:r}},n.prototype.queryDateScroll=function(){return{top:this.scroller.getScrollTop()}},n.prototype.applyDateScroll=function(e){void 0!==e.top&&this.scroller.setScrollTop(e.top)},n.prototype.axisStyleAttr=function(){return null!=this.axisWidth?'style="width:'+this.axisWidth+'px"':""},n}(t.View);E.prototype.usesMinMaxTime=!0;var b=function(e){function r(r,i){var n=e.call(this,r,i.el)||this;return n.buildDayRanges=t.memoize(c),n.slicer=new D,n.timeGrid=i,r.calendar.registerInteractiveComponent(n,{el:n.timeGrid.el}),n}return i(r,e),r.prototype.destroy=function(){e.prototype.destroy.call(this),this.calendar.unregisterInteractiveComponent(this)},r.prototype.render=function(e){var t=e.dateProfile,r=e.dayTable,i=this.dayRanges=this.buildDayRanges(r,t,this.dateEnv);this.timeGrid.receiveProps(p({},this.slicer.sliceProps(e,t,null,this.timeGrid,i),{dateProfile:t,cells:r.cells[0]}))},r.prototype.renderNowIndicator=function(e){this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(e,this.timeGrid,this.dayRanges),e)},r.prototype.queryHit=function(e,t){var r=this.timeGrid.positionToHit(e,t);if(r)return{component:this.timeGrid,dateSpan:r.dateSpan,dayEl:r.dayEl,rect:{left:r.relativeRect.left,right:r.relativeRect.right,top:r.relativeRect.top,bottom:r.relativeRect.bottom},layer:0}},r}(t.DateComponent),D=function(e){function r(){return null!==e&&e.apply(this,arguments)||this}return i(r,e),r.prototype.sliceRange=function(e,r){for(var i=[],n=0;n<r.length;n++){var o=t.intersectRanges(e,r[n]);o&&i.push({start:o.start,end:o.end,isStart:o.start.valueOf()===e.start.valueOf(),isEnd:o.end.valueOf()===e.end.valueOf(),col:n})}return i},r}(t.Slicer),w=function(e){function n(i,n,o,s){var a=e.call(this,i,n,o,s)||this;return a.buildDayTable=t.memoize(h),a.opt("columnHeader")&&(a.header=new t.DayHeader(a.context,a.el.querySelector(".fc-head-container"))),a.simpleTimeGrid=new b(a.context,a.timeGrid),a.dayGrid&&(a.simpleDayGrid=new r.SimpleDayGrid(a.context,a.dayGrid)),a}return i(n,e),n.prototype.destroy=function(){e.prototype.destroy.call(this),this.header&&this.header.destroy(),this.simpleTimeGrid.destroy(),this.simpleDayGrid&&this.simpleDayGrid.destroy()},n.prototype.render=function(t){e.prototype.render.call(this,t);var r=this.props.dateProfile,i=this.buildDayTable(r,this.dateProfileGenerator),n=this.splitter.splitProps(t);this.header&&this.header.receiveProps({dateProfile:r,dates:i.headerDates,datesRepDistinctDays:!0,renderIntroHtml:this.renderHeadIntroHtml}),this.simpleTimeGrid.receiveProps(p({},n.timed,{dateProfile:r,dayTable:i})),this.simpleDayGrid&&this.simpleDayGrid.receiveProps(p({},n.allDay,{dateProfile:r,dayTable:i,nextDayThreshold:this.nextDayThreshold,isRigid:!1}))},n.prototype.renderNowIndicator=function(e){this.simpleTimeGrid.renderNowIndicator(e)},n}(E),G=t.createPlugin({defaultView:"timeGridWeek",views:{timeGrid:{class:w,allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0},timeGridDay:{type:"timeGrid",duration:{days:1}},timeGridWeek:{type:"timeGrid",duration:{weeks:1}}}});e.AbstractTimeGridView=E,e.TimeGrid=v,e.TimeGridSlicer=D,e.TimeGridView=w,e.buildDayRanges=c,e.buildDayTable=h,e.default=G,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file
diff --git a/library/fullcalendar/vendor/rrule.js b/library/fullcalendar/vendor/rrule.js
new file mode 100644
index 000000000..08fdb7d70
--- /dev/null
+++ b/library/fullcalendar/vendor/rrule.js
@@ -0,0 +1,3617 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory(require("luxon"));
+ else if(typeof define === 'function' && define.amd)
+ define(["luxon"], factory);
+ else if(typeof exports === 'object')
+ exports["rrule"] = factory(require("luxon"));
+ else
+ root["rrule"] = factory(root["luxon"]);
+})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__2__) {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ }
+/******/ };
+/******/
+/******/ // define __esModule on exports
+/******/ __webpack_require__.r = function(exports) {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/
+/******/ // create a fake namespace object
+/******/ // mode & 1: value is a module id, require it
+/******/ // mode & 2: merge all properties of value into the ns
+/******/ // mode & 4: return value when already ns object
+/******/ // mode & 8|1: behave like require
+/******/ __webpack_require__.t = function(value, mode) {
+/******/ if(mode & 1) value = __webpack_require__(value);
+/******/ if(mode & 8) return value;
+/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ var ns = Object.create(null);
+/******/ __webpack_require__.r(ns);
+/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ return ns;
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+/******/
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = 1);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return isPresent; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return isNumber; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return isArray; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return range; });
+/* unused harmony export clone */
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return repeat; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return toArray; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return padStart; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return split; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return pymod; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return divmod; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return empty; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return notEmpty; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return includes; });
+// =============================================================================
+// Helper functions
+// =============================================================================
+var isPresent = function (value) {
+ return value !== null && value !== undefined;
+};
+var isNumber = function (value) {
+ return typeof value === 'number';
+};
+var isArray = Array.isArray;
+/**
+ * Simplified version of python's range()
+ */
+var range = function (start, end) {
+ if (end === void 0) { end = start; }
+ if (arguments.length === 1) {
+ end = start;
+ start = 0;
+ }
+ var rang = [];
+ for (var i = start; i < end; i++)
+ rang.push(i);
+ return rang;
+};
+var clone = function (array) {
+ return [].concat(array);
+};
+var repeat = function (value, times) {
+ var i = 0;
+ var array = [];
+ if (isArray(value)) {
+ for (; i < times; i++)
+ array[i] = [].concat(value);
+ }
+ else {
+ for (; i < times; i++)
+ array[i] = value;
+ }
+ return array;
+};
+var toArray = function (item) {
+ if (isArray(item)) {
+ return item;
+ }
+ return [item];
+};
+function padStart(item, targetLength, padString) {
+ if (padString === void 0) { padString = ' '; }
+ var str = String(item);
+ targetLength = targetLength >> 0;
+ if (str.length > targetLength) {
+ return String(str);
+ }
+ targetLength = targetLength - str.length;
+ if (targetLength > padString.length) {
+ padString += repeat(padString, targetLength / padString.length);
+ }
+ return padString.slice(0, targetLength) + String(str);
+}
+/**
+ * Python like split
+ */
+var split = function (str, sep, num) {
+ var splits = str.split(sep);
+ return num
+ ? splits.slice(0, num).concat([splits.slice(num).join(sep)])
+ : splits;
+};
+/**
+ * closure/goog/math/math.js:modulo
+ * Copyright 2006 The Closure Library Authors.
+ * The % operator in JavaScript returns the remainder of a / b, but differs from
+ * some other languages in that the result will have the same sign as the
+ * dividend. For example, -1 % 8 == -1, whereas in some other languages
+ * (such as Python) the result would be 7. This function emulates the more
+ * correct modulo behavior, which is useful for certain applications such as
+ * calculating an offset index in a circular list.
+ *
+ * @param {number} a The dividend.
+ * @param {number} b The divisor.
+ * @return {number} a % b where the result is between 0 and b (either 0 <= x < b
+ * or b < x <= 0, depending on the sign of b).
+ */
+var pymod = function (a, b) {
+ var r = a % b;
+ // If r and b differ in sign, add b to wrap the result to the correct sign.
+ return r * b < 0 ? r + b : r;
+};
+/**
+ * @see: <http://docs.python.org/library/functions.html#divmod>
+ */
+var divmod = function (a, b) {
+ return { div: Math.floor(a / b), mod: pymod(a, b) };
+};
+var empty = function (obj) {
+ return !isPresent(obj) || obj.length === 0;
+};
+/**
+ * Python-like boolean
+ * @return {Boolean} value of an object/primitive, taking into account
+ * the fact that in Python an empty list's/tuple's
+ * boolean value is False, whereas in JS it's true
+ */
+var notEmpty = function (obj) {
+ return !empty(obj);
+};
+/**
+ * Return true if a value is in an array
+ */
+var includes = function (arr, val) {
+ return notEmpty(arr) && arr.indexOf(val) !== -1;
+};
+
+
+/***/ }),
+/* 1 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+
+// EXTERNAL MODULE: ./src/helpers.ts
+var helpers = __webpack_require__(0);
+
+// CONCATENATED MODULE: ./src/dateutil.ts
+
+/**
+ * General date-related utilities.
+ * Also handles several incompatibilities between JavaScript and Python
+ *
+ */
+var dateutil_dateutil;
+(function (dateutil) {
+ dateutil.MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ /**
+ * Number of milliseconds of one day
+ */
+ dateutil.ONE_DAY = 1000 * 60 * 60 * 24;
+ /**
+ * @see: <http://docs.python.org/library/datetime.html#datetime.MAXYEAR>
+ */
+ dateutil.MAXYEAR = 9999;
+ /**
+ * Python uses 1-Jan-1 as the base for calculating ordinals but we don't
+ * want to confuse the JS engine with milliseconds > Number.MAX_NUMBER,
+ * therefore we use 1-Jan-1970 instead
+ */
+ dateutil.ORDINAL_BASE = new Date(Date.UTC(1970, 0, 1));
+ /**
+ * Python: MO-SU: 0 - 6
+ * JS: SU-SAT 0 - 6
+ */
+ dateutil.PY_WEEKDAYS = [6, 0, 1, 2, 3, 4, 5];
+ /**
+ * py_date.timetuple()[7]
+ */
+ dateutil.getYearDay = function (date) {
+ var dateNoTime = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
+ return (Math.ceil((dateNoTime.valueOf() -
+ new Date(date.getUTCFullYear(), 0, 1).valueOf()) /
+ dateutil.ONE_DAY) + 1);
+ };
+ dateutil.isLeapYear = function (year) {
+ return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+ };
+ dateutil.isDate = function (value) {
+ return value instanceof Date;
+ };
+ dateutil.isValidDate = function (value) {
+ return dateutil.isDate(value) && !isNaN(value.getTime());
+ };
+ /**
+ * @return {Number} the date's timezone offset in ms
+ */
+ dateutil.tzOffset = function (date) {
+ return date.getTimezoneOffset() * 60 * 1000;
+ };
+ /**
+ * @see: <http://www.mcfedries.com/JavaScript/DaysBetween.asp>
+ */
+ dateutil.daysBetween = function (date1, date2) {
+ // The number of milliseconds in one day
+ // Convert both dates to milliseconds
+ var date1ms = date1.getTime() - dateutil.tzOffset(date1);
+ var date2ms = date2.getTime() - dateutil.tzOffset(date2);
+ // Calculate the difference in milliseconds
+ var differencems = date1ms - date2ms;
+ // Convert back to days and return
+ return Math.round(differencems / dateutil.ONE_DAY);
+ };
+ /**
+ * @see: <http://docs.python.org/library/datetime.html#datetime.date.toordinal>
+ */
+ dateutil.toOrdinal = function (date) {
+ return dateutil.daysBetween(date, dateutil.ORDINAL_BASE);
+ };
+ /**
+ * @see - <http://docs.python.org/library/datetime.html#datetime.date.fromordinal>
+ */
+ dateutil.fromOrdinal = function (ordinal) {
+ return new Date(dateutil.ORDINAL_BASE.getTime() + ordinal * dateutil.ONE_DAY);
+ };
+ dateutil.getMonthDays = function (date) {
+ var month = date.getUTCMonth();
+ return month === 1 && dateutil.isLeapYear(date.getUTCFullYear())
+ ? 29
+ : dateutil.MONTH_DAYS[month];
+ };
+ /**
+ * @return {Number} python-like weekday
+ */
+ dateutil.getWeekday = function (date) {
+ return dateutil.PY_WEEKDAYS[date.getUTCDay()];
+ };
+ /**
+ * @see: <http://docs.python.org/library/calendar.html#calendar.monthrange>
+ */
+ dateutil.monthRange = function (year, month) {
+ var date = new Date(Date.UTC(year, month, 1));
+ return [dateutil.getWeekday(date), dateutil.getMonthDays(date)];
+ };
+ /**
+ * @see: <http://docs.python.org/library/datetime.html#datetime.datetime.combine>
+ */
+ dateutil.combine = function (date, time) {
+ time = time || date;
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()));
+ };
+ dateutil.clone = function (date) {
+ var dolly = new Date(date.getTime());
+ return dolly;
+ };
+ dateutil.cloneDates = function (dates) {
+ var clones = [];
+ for (var i = 0; i < dates.length; i++) {
+ clones.push(dateutil.clone(dates[i]));
+ }
+ return clones;
+ };
+ /**
+ * Sorts an array of Date or dateutil.Time objects
+ */
+ dateutil.sort = function (dates) {
+ dates.sort(function (a, b) {
+ return a.getTime() - b.getTime();
+ });
+ };
+ dateutil.timeToUntilString = function (time, utc) {
+ if (utc === void 0) { utc = true; }
+ var date = new Date(time);
+ return [
+ Object(helpers["h" /* padStart */])(date.getUTCFullYear().toString(), 4, '0'),
+ Object(helpers["h" /* padStart */])(date.getUTCMonth() + 1, 2, '0'),
+ Object(helpers["h" /* padStart */])(date.getUTCDate(), 2, '0'),
+ 'T',
+ Object(helpers["h" /* padStart */])(date.getUTCHours(), 2, '0'),
+ Object(helpers["h" /* padStart */])(date.getUTCMinutes(), 2, '0'),
+ Object(helpers["h" /* padStart */])(date.getUTCSeconds(), 2, '0'),
+ utc ? 'Z' : ''
+ ].join('');
+ };
+ dateutil.untilStringToDate = function (until) {
+ var re = /^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z?)?$/;
+ var bits = re.exec(until);
+ if (!bits)
+ throw new Error("Invalid UNTIL value: " + until);
+ return new Date(Date.UTC(parseInt(bits[1], 10), parseInt(bits[2], 10) - 1, parseInt(bits[3], 10), parseInt(bits[5], 10) || 0, parseInt(bits[6], 10) || 0, parseInt(bits[7], 10) || 0));
+ };
+})(dateutil_dateutil || (dateutil_dateutil = {}));
+/* harmony default export */ var src_dateutil = (dateutil_dateutil);
+
+// CONCATENATED MODULE: ./src/iterresult.ts
+/**
+ * This class helps us to emulate python's generators, sorta.
+ */
+var IterResult = /** @class */ (function () {
+ function IterResult(method, args) {
+ this.minDate = null;
+ this.maxDate = null;
+ this._result = [];
+ this.total = 0;
+ this.method = method;
+ this.args = args;
+ if (method === 'between') {
+ this.maxDate = args.inc
+ ? args.before
+ : new Date(args.before.getTime() - 1);
+ this.minDate = args.inc ? args.after : new Date(args.after.getTime() + 1);
+ }
+ else if (method === 'before') {
+ this.maxDate = args.inc ? args.dt : new Date(args.dt.getTime() - 1);
+ }
+ else if (method === 'after') {
+ this.minDate = args.inc ? args.dt : new Date(args.dt.getTime() + 1);
+ }
+ }
+ /**
+ * Possibly adds a date into the result.
+ *
+ * @param {Date} date - the date isn't necessarly added to the result
+ * list (if it is too late/too early)
+ * @return {Boolean} true if it makes sense to continue the iteration
+ * false if we're done.
+ */
+ IterResult.prototype.accept = function (date) {
+ ++this.total;
+ var tooEarly = this.minDate && date < this.minDate;
+ var tooLate = this.maxDate && date > this.maxDate;
+ if (this.method === 'between') {
+ if (tooEarly)
+ return true;
+ if (tooLate)
+ return false;
+ }
+ else if (this.method === 'before') {
+ if (tooLate)
+ return false;
+ }
+ else if (this.method === 'after') {
+ if (tooEarly)
+ return true;
+ this.add(date);
+ return false;
+ }
+ return this.add(date);
+ };
+ /**
+ *
+ * @param {Date} date that is part of the result.
+ * @return {Boolean} whether we are interested in more values.
+ */
+ IterResult.prototype.add = function (date) {
+ this._result.push(date);
+ return true;
+ };
+ /**
+ * 'before' and 'after' return only one date, whereas 'all'
+ * and 'between' an array.
+ * @return {Date,Array?}
+ */
+ IterResult.prototype.getValue = function () {
+ var res = this._result;
+ switch (this.method) {
+ case 'all':
+ case 'between':
+ return res;
+ case 'before':
+ case 'after':
+ default:
+ return (res.length ? res[res.length - 1] : null);
+ }
+ };
+ IterResult.prototype.clone = function () {
+ return new IterResult(this.method, this.args);
+ };
+ return IterResult;
+}());
+/* harmony default export */ var iterresult = (IterResult);
+
+// CONCATENATED MODULE: ./src/callbackiterresult.ts
+var __extends = (undefined && undefined.__extends) || (function () {
+ var extendStatics = function (d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+
+/**
+ * IterResult subclass that calls a callback function on each add,
+ * and stops iterating when the callback returns false.
+ */
+var CallbackIterResult = /** @class */ (function (_super) {
+ __extends(CallbackIterResult, _super);
+ function CallbackIterResult(method, args, iterator) {
+ var _this = _super.call(this, method, args) || this;
+ _this.iterator = iterator;
+ return _this;
+ }
+ CallbackIterResult.prototype.add = function (date) {
+ if (this.iterator(date, this._result.length)) {
+ this._result.push(date);
+ return true;
+ }
+ return false;
+ };
+ return CallbackIterResult;
+}(iterresult));
+/* harmony default export */ var callbackiterresult = (CallbackIterResult);
+
+// CONCATENATED MODULE: ./src/types.ts
+var Frequency;
+(function (Frequency) {
+ Frequency[Frequency["YEARLY"] = 0] = "YEARLY";
+ Frequency[Frequency["MONTHLY"] = 1] = "MONTHLY";
+ Frequency[Frequency["WEEKLY"] = 2] = "WEEKLY";
+ Frequency[Frequency["DAILY"] = 3] = "DAILY";
+ Frequency[Frequency["HOURLY"] = 4] = "HOURLY";
+ Frequency[Frequency["MINUTELY"] = 5] = "MINUTELY";
+ Frequency[Frequency["SECONDLY"] = 6] = "SECONDLY";
+})(Frequency || (Frequency = {}));
+function freqIsDailyOrGreater(freq) {
+ return freq < Frequency.HOURLY;
+}
+
+// CONCATENATED MODULE: ./src/weekday.ts
+// =============================================================================
+// Weekday
+// =============================================================================
+var WDAYS = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];
+var Weekday = /** @class */ (function () {
+ function Weekday(weekday, n) {
+ if (n === 0)
+ throw new Error("Can't create weekday with n == 0");
+ this.weekday = weekday;
+ this.n = n;
+ }
+ // __call__ - Cannot call the object directly, do it through
+ // e.g. RRule.TH.nth(-1) instead,
+ Weekday.prototype.nth = function (n) {
+ return this.n === n ? this : new Weekday(this.weekday, n);
+ };
+ // __eq__
+ Weekday.prototype.equals = function (other) {
+ return this.weekday === other.weekday && this.n === other.n;
+ };
+ // __repr__
+ Weekday.prototype.toString = function () {
+ var s = WDAYS[this.weekday];
+ if (this.n)
+ s = (this.n > 0 ? '+' : '') + String(this.n) + s;
+ return s;
+ };
+ Weekday.prototype.getJsWeekday = function () {
+ return this.weekday === 6 ? 0 : this.weekday + 1;
+ };
+ return Weekday;
+}());
+
+
+// CONCATENATED MODULE: ./src/datetime.ts
+var datetime_extends = (undefined && undefined.__extends) || (function () {
+ var extendStatics = function (d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+
+
+
+var Time = /** @class */ (function () {
+ function Time(hour, minute, second, millisecond) {
+ this.hour = hour;
+ this.minute = minute;
+ this.second = second;
+ this.millisecond = millisecond || 0;
+ }
+ Time.prototype.getHours = function () {
+ return this.hour;
+ };
+ Time.prototype.getMinutes = function () {
+ return this.minute;
+ };
+ Time.prototype.getSeconds = function () {
+ return this.second;
+ };
+ Time.prototype.getMilliseconds = function () {
+ return this.millisecond;
+ };
+ Time.prototype.getTime = function () {
+ return ((this.hour * 60 * 60 + this.minute * 60 + this.second) * 1000 +
+ this.millisecond);
+ };
+ return Time;
+}());
+
+var datetime_DateTime = /** @class */ (function (_super) {
+ datetime_extends(DateTime, _super);
+ function DateTime(year, month, day, hour, minute, second, millisecond) {
+ var _this = _super.call(this, hour, minute, second, millisecond) || this;
+ _this.year = year;
+ _this.month = month;
+ _this.day = day;
+ return _this;
+ }
+ DateTime.fromDate = function (date) {
+ return new this(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.valueOf() % 1000);
+ };
+ DateTime.prototype.getWeekday = function () {
+ return dateutil_dateutil.getWeekday(new Date(this.getTime()));
+ };
+ DateTime.prototype.getTime = function () {
+ return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)).getTime();
+ };
+ DateTime.prototype.getDay = function () {
+ return this.day;
+ };
+ DateTime.prototype.getMonth = function () {
+ return this.month;
+ };
+ DateTime.prototype.getYear = function () {
+ return this.year;
+ };
+ DateTime.prototype.addYears = function (years) {
+ this.year += years;
+ };
+ DateTime.prototype.addMonths = function (months) {
+ this.month += months;
+ if (this.month > 12) {
+ var yearDiv = Math.floor(this.month / 12);
+ var monthMod = Object(helpers["i" /* pymod */])(this.month, 12);
+ this.month = monthMod;
+ this.year += yearDiv;
+ if (this.month === 0) {
+ this.month = 12;
+ --this.year;
+ }
+ }
+ };
+ DateTime.prototype.addWeekly = function (days, wkst) {
+ if (wkst > this.getWeekday()) {
+ this.day += -(this.getWeekday() + 1 + (6 - wkst)) + days * 7;
+ }
+ else {
+ this.day += -(this.getWeekday() - wkst) + days * 7;
+ }
+ this.fixDay();
+ };
+ DateTime.prototype.addDaily = function (days) {
+ this.day += days;
+ this.fixDay();
+ };
+ DateTime.prototype.addHours = function (hours, filtered, byhour) {
+ if (filtered) {
+ // Jump to one iteration before next day
+ this.hour += Math.floor((23 - this.hour) / hours) * hours;
+ }
+ while (true) {
+ this.hour += hours;
+ var _a = Object(helpers["a" /* divmod */])(this.hour, 24), dayDiv = _a.div, hourMod = _a.mod;
+ if (dayDiv) {
+ this.hour = hourMod;
+ this.addDaily(dayDiv);
+ }
+ if (Object(helpers["b" /* empty */])(byhour) || Object(helpers["c" /* includes */])(byhour, this.hour))
+ break;
+ }
+ };
+ DateTime.prototype.addMinutes = function (minutes, filtered, byhour, byminute) {
+ if (filtered) {
+ // Jump to one iteration before next day
+ this.minute +=
+ Math.floor((1439 - (this.hour * 60 + this.minute)) / minutes) * minutes;
+ }
+ while (true) {
+ this.minute += minutes;
+ var _a = Object(helpers["a" /* divmod */])(this.minute, 60), hourDiv = _a.div, minuteMod = _a.mod;
+ if (hourDiv) {
+ this.minute = minuteMod;
+ this.addHours(hourDiv, false, byhour);
+ }
+ if ((Object(helpers["b" /* empty */])(byhour) || Object(helpers["c" /* includes */])(byhour, this.hour)) &&
+ (Object(helpers["b" /* empty */])(byminute) || Object(helpers["c" /* includes */])(byminute, this.minute))) {
+ break;
+ }
+ }
+ };
+ DateTime.prototype.addSeconds = function (seconds, filtered, byhour, byminute, bysecond) {
+ if (filtered) {
+ // Jump to one iteration before next day
+ this.second +=
+ Math.floor((86399 - (this.hour * 3600 + this.minute * 60 + this.second)) / seconds) * seconds;
+ }
+ while (true) {
+ this.second += seconds;
+ var _a = Object(helpers["a" /* divmod */])(this.second, 60), minuteDiv = _a.div, secondMod = _a.mod;
+ if (minuteDiv) {
+ this.second = secondMod;
+ this.addMinutes(minuteDiv, false, byhour, byminute);
+ }
+ if ((Object(helpers["b" /* empty */])(byhour) || Object(helpers["c" /* includes */])(byhour, this.hour)) &&
+ (Object(helpers["b" /* empty */])(byminute) || Object(helpers["c" /* includes */])(byminute, this.minute)) &&
+ (Object(helpers["b" /* empty */])(bysecond) || Object(helpers["c" /* includes */])(bysecond, this.second))) {
+ break;
+ }
+ }
+ };
+ DateTime.prototype.fixDay = function () {
+ if (this.day <= 28) {
+ return;
+ }
+ var daysinmonth = dateutil_dateutil.monthRange(this.year, this.month - 1)[1];
+ if (this.day <= daysinmonth) {
+ return;
+ }
+ while (this.day > daysinmonth) {
+ this.day -= daysinmonth;
+ ++this.month;
+ if (this.month === 13) {
+ this.month = 1;
+ ++this.year;
+ if (this.year > dateutil_dateutil.MAXYEAR) {
+ return;
+ }
+ }
+ daysinmonth = dateutil_dateutil.monthRange(this.year, this.month - 1)[1];
+ }
+ };
+ DateTime.prototype.add = function (options, filtered) {
+ var freq = options.freq, interval = options.interval, wkst = options.wkst, byhour = options.byhour, byminute = options.byminute, bysecond = options.bysecond;
+ switch (freq) {
+ case Frequency.YEARLY: return this.addYears(interval);
+ case Frequency.MONTHLY: return this.addMonths(interval);
+ case Frequency.WEEKLY: return this.addWeekly(interval, wkst);
+ case Frequency.DAILY: return this.addDaily(interval);
+ case Frequency.HOURLY: return this.addHours(interval, filtered, byhour);
+ case Frequency.MINUTELY: return this.addMinutes(interval, filtered, byhour, byminute);
+ case Frequency.SECONDLY: return this.addSeconds(interval, filtered, byhour, byminute, bysecond);
+ }
+ };
+ return DateTime;
+}(Time));
+
+
+// CONCATENATED MODULE: ./src/parseoptions.ts
+
+
+
+
+
+
+function initializeOptions(options) {
+ var invalid = [];
+ var keys = Object.keys(options);
+ var initializedOptions = {};
+ // Shallow copy for options and origOptions and check for invalid
+ keys.forEach(function (key) {
+ var value = options[key];
+ initializedOptions[key] = value;
+ if (!Object(helpers["c" /* includes */])(rrule_defaultKeys, key))
+ invalid.push(key);
+ if (src_dateutil.isDate(value) && !src_dateutil.isValidDate(value))
+ invalid.push(key);
+ });
+ if (invalid.length) {
+ throw new Error('Invalid options: ' + invalid.join(', '));
+ }
+ return initializedOptions;
+}
+function parseOptions(options) {
+ var opts = initializeOptions(options);
+ var keys = Object.keys(options);
+ // Merge in default options
+ rrule_defaultKeys.forEach(function (key) {
+ if (!Object(helpers["c" /* includes */])(keys, key) || !Object(helpers["f" /* isPresent */])(opts[key]))
+ opts[key] = DEFAULT_OPTIONS[key];
+ });
+ if (Object(helpers["f" /* isPresent */])(opts.byeaster))
+ opts.freq = src_rrule.YEARLY;
+ if (!(Object(helpers["f" /* isPresent */])(opts.freq) && src_rrule.FREQUENCIES[opts.freq])) {
+ throw new Error("Invalid frequency: " + opts.freq + " " + options.freq);
+ }
+ if (!opts.dtstart)
+ opts.dtstart = new Date(new Date().setMilliseconds(0));
+ if (!Object(helpers["f" /* isPresent */])(opts.wkst)) {
+ opts.wkst = src_rrule.MO.weekday;
+ }
+ else if (Object(helpers["e" /* isNumber */])(opts.wkst)) {
+ // cool, just keep it like that
+ }
+ else {
+ opts.wkst = opts.wkst.weekday;
+ }
+ if (Object(helpers["f" /* isPresent */])(opts.bysetpos)) {
+ if (Object(helpers["e" /* isNumber */])(opts.bysetpos))
+ opts.bysetpos = [opts.bysetpos];
+ for (var i = 0; i < opts.bysetpos.length; i++) {
+ var v = opts.bysetpos[i];
+ if (v === 0 || !(v >= -366 && v <= 366)) {
+ throw new Error('bysetpos must be between 1 and 366,' + ' or between -366 and -1');
+ }
+ }
+ }
+ if (!(Boolean(opts.byweekno) ||
+ Object(helpers["g" /* notEmpty */])(opts.byweekno) ||
+ Object(helpers["g" /* notEmpty */])(opts.byyearday) ||
+ Boolean(opts.bymonthday) ||
+ Object(helpers["g" /* notEmpty */])(opts.bymonthday) ||
+ Object(helpers["f" /* isPresent */])(opts.byweekday) ||
+ Object(helpers["f" /* isPresent */])(opts.byeaster))) {
+ switch (opts.freq) {
+ case src_rrule.YEARLY:
+ if (!opts.bymonth)
+ opts.bymonth = opts.dtstart.getUTCMonth() + 1;
+ opts.bymonthday = opts.dtstart.getUTCDate();
+ break;
+ case src_rrule.MONTHLY:
+ opts.bymonthday = opts.dtstart.getUTCDate();
+ break;
+ case src_rrule.WEEKLY:
+ opts.byweekday = [src_dateutil.getWeekday(opts.dtstart)];
+ break;
+ }
+ }
+ // bymonth
+ if (Object(helpers["f" /* isPresent */])(opts.bymonth) && !Object(helpers["d" /* isArray */])(opts.bymonth)) {
+ opts.bymonth = [opts.bymonth];
+ }
+ // byyearday
+ if (Object(helpers["f" /* isPresent */])(opts.byyearday) &&
+ !Object(helpers["d" /* isArray */])(opts.byyearday) &&
+ Object(helpers["e" /* isNumber */])(opts.byyearday)) {
+ opts.byyearday = [opts.byyearday];
+ }
+ // bymonthday
+ if (!Object(helpers["f" /* isPresent */])(opts.bymonthday)) {
+ opts.bymonthday = [];
+ opts.bynmonthday = [];
+ }
+ else if (Object(helpers["d" /* isArray */])(opts.bymonthday)) {
+ var bymonthday = [];
+ var bynmonthday = [];
+ for (var i = 0; i < opts.bymonthday.length; i++) {
+ var v = opts.bymonthday[i];
+ if (v > 0) {
+ bymonthday.push(v);
+ }
+ else if (v < 0) {
+ bynmonthday.push(v);
+ }
+ }
+ opts.bymonthday = bymonthday;
+ opts.bynmonthday = bynmonthday;
+ }
+ else if (opts.bymonthday < 0) {
+ opts.bynmonthday = [opts.bymonthday];
+ opts.bymonthday = [];
+ }
+ else {
+ opts.bynmonthday = [];
+ opts.bymonthday = [opts.bymonthday];
+ }
+ // byweekno
+ if (Object(helpers["f" /* isPresent */])(opts.byweekno) && !Object(helpers["d" /* isArray */])(opts.byweekno)) {
+ opts.byweekno = [opts.byweekno];
+ }
+ // byweekday / bynweekday
+ if (!Object(helpers["f" /* isPresent */])(opts.byweekday)) {
+ opts.bynweekday = null;
+ }
+ else if (Object(helpers["e" /* isNumber */])(opts.byweekday)) {
+ opts.byweekday = [opts.byweekday];
+ opts.bynweekday = null;
+ }
+ else if (opts.byweekday instanceof Weekday) {
+ if (!opts.byweekday.n || opts.freq > src_rrule.MONTHLY) {
+ opts.byweekday = [opts.byweekday.weekday];
+ opts.bynweekday = null;
+ }
+ else {
+ opts.bynweekday = [[opts.byweekday.weekday, opts.byweekday.n]];
+ opts.byweekday = null;
+ }
+ }
+ else {
+ var byweekday = [];
+ var bynweekday = [];
+ for (var i = 0; i < opts.byweekday.length; i++) {
+ var wday = opts.byweekday[i];
+ if (Object(helpers["e" /* isNumber */])(wday)) {
+ byweekday.push(wday);
+ continue;
+ }
+ var wd = wday;
+ if (!wd.n || opts.freq > src_rrule.MONTHLY) {
+ byweekday.push(wd.weekday);
+ }
+ else {
+ bynweekday.push([wd.weekday, wd.n]);
+ }
+ }
+ opts.byweekday = Object(helpers["g" /* notEmpty */])(byweekday) ? byweekday : null;
+ opts.bynweekday = Object(helpers["g" /* notEmpty */])(bynweekday) ? bynweekday : null;
+ }
+ // byhour
+ if (!Object(helpers["f" /* isPresent */])(opts.byhour)) {
+ opts.byhour =
+ opts.freq < src_rrule.HOURLY ? [opts.dtstart.getUTCHours()] : null;
+ }
+ else if (Object(helpers["e" /* isNumber */])(opts.byhour)) {
+ opts.byhour = [opts.byhour];
+ }
+ // byminute
+ if (!Object(helpers["f" /* isPresent */])(opts.byminute)) {
+ opts.byminute =
+ opts.freq < src_rrule.MINUTELY ? [opts.dtstart.getUTCMinutes()] : null;
+ }
+ else if (Object(helpers["e" /* isNumber */])(opts.byminute)) {
+ opts.byminute = [opts.byminute];
+ }
+ // bysecond
+ if (!Object(helpers["f" /* isPresent */])(opts.bysecond)) {
+ opts.bysecond =
+ opts.freq < src_rrule.SECONDLY ? [opts.dtstart.getUTCSeconds()] : null;
+ }
+ else if (Object(helpers["e" /* isNumber */])(opts.bysecond)) {
+ opts.bysecond = [opts.bysecond];
+ }
+ return { parsedOptions: opts };
+}
+function buildTimeset(opts) {
+ var millisecondModulo = opts.dtstart.getTime() % 1000;
+ if (!freqIsDailyOrGreater(opts.freq)) {
+ return [];
+ }
+ var timeset = [];
+ opts.byhour.forEach(function (hour) {
+ opts.byminute.forEach(function (minute) {
+ opts.bysecond.forEach(function (second) {
+ timeset.push(new Time(hour, minute, second, millisecondModulo));
+ });
+ });
+ });
+ return timeset;
+}
+
+// CONCATENATED MODULE: ./src/parsestring.ts
+var __assign = (undefined && undefined.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+};
+
+
+
+
+function parseString(rfcString) {
+ var options = rfcString.split('\n').map(parseLine).filter(function (x) { return x !== null; });
+ return __assign({}, options[0], options[1]);
+}
+function parseDtstart(line) {
+ var options = {};
+ var dtstartWithZone = /DTSTART(?:;TZID=([^:=]+?))?(?::|=)([^;\s]+)/i.exec(line);
+ if (!dtstartWithZone) {
+ return options;
+ }
+ var _ = dtstartWithZone[0], tzid = dtstartWithZone[1], dtstart = dtstartWithZone[2];
+ if (tzid) {
+ options.tzid = tzid;
+ }
+ options.dtstart = src_dateutil.untilStringToDate(dtstart);
+ return options;
+}
+function parseLine(rfcString) {
+ rfcString = rfcString.replace(/^\s+|\s+$/, '');
+ if (!rfcString.length)
+ return null;
+ var header = /^([A-Z]+?)[:;]/.exec(rfcString.toUpperCase());
+ if (!header) {
+ return parseRrule(rfcString);
+ }
+ var _ = header[0], key = header[1];
+ switch (key.toUpperCase()) {
+ case 'RRULE':
+ case 'EXRULE':
+ return parseRrule(rfcString);
+ case 'DTSTART':
+ return parseDtstart(rfcString);
+ default:
+ throw new Error("Unsupported RFC prop " + key + " in " + rfcString);
+ }
+}
+function parseRrule(line) {
+ var strippedLine = line.replace(/^RRULE:/i, '');
+ var options = parseDtstart(strippedLine);
+ var attrs = line.replace(/^(?:RRULE|EXRULE):/i, '').split(';');
+ attrs.forEach(function (attr) {
+ var _a = attr.split('='), key = _a[0], value = _a[1];
+ switch (key.toUpperCase()) {
+ case 'FREQ':
+ options.freq = Frequency[value.toUpperCase()];
+ break;
+ case 'WKST':
+ options.wkst = Days[value.toUpperCase()];
+ break;
+ case 'COUNT':
+ case 'INTERVAL':
+ case 'BYSETPOS':
+ case 'BYMONTH':
+ case 'BYMONTHDAY':
+ case 'BYYEARDAY':
+ case 'BYWEEKNO':
+ case 'BYHOUR':
+ case 'BYMINUTE':
+ case 'BYSECOND':
+ var num = parseNumber(value);
+ var optionKey = key.toLowerCase();
+ // @ts-ignore
+ options[optionKey] = num;
+ break;
+ case 'BYWEEKDAY':
+ case 'BYDAY':
+ options.byweekday = parseWeekday(value);
+ break;
+ case 'DTSTART':
+ case 'TZID':
+ // for backwards compatibility
+ var dtstart = parseDtstart(line);
+ options.tzid = dtstart.tzid;
+ options.dtstart = dtstart.dtstart;
+ break;
+ case 'UNTIL':
+ options.until = src_dateutil.untilStringToDate(value);
+ break;
+ case 'BYEASTER':
+ options.byeaster = Number(value);
+ break;
+ default:
+ throw new Error("Unknown RRULE property '" + key + "'");
+ }
+ });
+ return options;
+}
+function parseNumber(value) {
+ if (value.indexOf(',') !== -1) {
+ var values = value.split(',');
+ return values.map(parseIndividualNumber);
+ }
+ return parseIndividualNumber(value);
+}
+function parseIndividualNumber(value) {
+ if (/^[+-]?\d+$/.test(value)) {
+ return Number(value);
+ }
+ return value;
+}
+function parseWeekday(value) {
+ var days = value.split(',');
+ return days.map(function (day) {
+ if (day.length === 2) {
+ // MO, TU, ...
+ return Days[day]; // wday instanceof Weekday
+ }
+ // -1MO, +3FR, 1SO, ...
+ var parts = day.match(/^([+-]?\d)([A-Z]{2})$/);
+ var n = Number(parts[1]);
+ var wdaypart = parts[2];
+ var wday = Days[wdaypart].weekday;
+ return new Weekday(wday, n);
+ });
+}
+
+// EXTERNAL MODULE: external "luxon"
+var external_luxon_ = __webpack_require__(2);
+
+// CONCATENATED MODULE: ./src/datewithzone.ts
+
+
+var datewithzone_DateWithZone = /** @class */ (function () {
+ function DateWithZone(date, tzid) {
+ this.date = date;
+ this.tzid = tzid;
+ }
+ Object.defineProperty(DateWithZone.prototype, "isUTC", {
+ get: function () {
+ return !this.tzid || this.tzid.toUpperCase() === 'UTC';
+ },
+ enumerable: true,
+ configurable: true
+ });
+ DateWithZone.prototype.toString = function () {
+ var datestr = src_dateutil.timeToUntilString(this.date.getTime(), this.isUTC);
+ if (!this.isUTC) {
+ return ";TZID=" + this.tzid + ":" + datestr;
+ }
+ return ":" + datestr;
+ };
+ DateWithZone.prototype.getTime = function () {
+ return this.date.getTime();
+ };
+ DateWithZone.prototype.rezonedDate = function () {
+ if (this.isUTC) {
+ return this.date;
+ }
+ try {
+ var datetime = external_luxon_["DateTime"]
+ .fromJSDate(this.date);
+ var rezoned = datetime.setZone(this.tzid, { keepLocalTime: true });
+ return rezoned.toJSDate();
+ }
+ catch (e) {
+ if (e instanceof TypeError) {
+ console.error('Using TZID without Luxon available is unsupported. Returned times are in UTC, not the requested time zone');
+ }
+ return this.date;
+ }
+ };
+ return DateWithZone;
+}());
+
+
+// CONCATENATED MODULE: ./src/optionstostring.ts
+
+
+
+
+
+function optionsToString(options) {
+ var rrule = [];
+ var dtstart = '';
+ var keys = Object.keys(options);
+ var defaultKeys = Object.keys(DEFAULT_OPTIONS);
+ for (var i = 0; i < keys.length; i++) {
+ if (keys[i] === 'tzid')
+ continue;
+ if (!Object(helpers["c" /* includes */])(defaultKeys, keys[i]))
+ continue;
+ var key = keys[i].toUpperCase();
+ var value = options[keys[i]];
+ var outValue = '';
+ if (!Object(helpers["f" /* isPresent */])(value) || (Object(helpers["d" /* isArray */])(value) && !value.length))
+ continue;
+ switch (key) {
+ case 'FREQ':
+ outValue = src_rrule.FREQUENCIES[options.freq];
+ break;
+ case 'WKST':
+ if (Object(helpers["e" /* isNumber */])(value)) {
+ outValue = new Weekday(value).toString();
+ }
+ else {
+ outValue = value.toString();
+ }
+ break;
+ case 'BYWEEKDAY':
+ /*
+ NOTE: BYWEEKDAY is a special case.
+ RRule() deconstructs the rule.options.byweekday array
+ into an array of Weekday arguments.
+ On the other hand, rule.origOptions is an array of Weekdays.
+ We need to handle both cases here.
+ It might be worth change RRule to keep the Weekdays.
+
+ Also, BYWEEKDAY (used by RRule) vs. BYDAY (RFC)
+
+ */
+ key = 'BYDAY';
+ outValue = Object(helpers["m" /* toArray */])(value).map(function (wday) {
+ if (wday instanceof Weekday) {
+ return wday;
+ }
+ if (Object(helpers["d" /* isArray */])(wday)) {
+ return new Weekday(wday[0], wday[1]);
+ }
+ return new Weekday(wday);
+ }).toString();
+ break;
+ case 'DTSTART':
+ dtstart = buildDtstart(value, options.tzid);
+ break;
+ case 'UNTIL':
+ outValue = src_dateutil.timeToUntilString(value, !options.tzid);
+ break;
+ default:
+ if (Object(helpers["d" /* isArray */])(value)) {
+ var strValues = [];
+ for (var j = 0; j < value.length; j++) {
+ strValues[j] = String(value[j]);
+ }
+ outValue = strValues.toString();
+ }
+ else {
+ outValue = String(value);
+ }
+ }
+ if (outValue) {
+ rrule.push([key, outValue]);
+ }
+ }
+ var rules = rrule.map(function (_a) {
+ var key = _a[0], value = _a[1];
+ return key + "=" + value.toString();
+ }).join(';');
+ var ruleString = '';
+ if (rules !== '') {
+ ruleString = "RRULE:" + rules;
+ }
+ return [dtstart, ruleString].filter(function (x) { return !!x; }).join('\n');
+}
+function buildDtstart(dtstart, tzid) {
+ if (!dtstart) {
+ return '';
+ }
+ return 'DTSTART' + new datewithzone_DateWithZone(new Date(dtstart), tzid).toString();
+}
+
+// CONCATENATED MODULE: ./src/cache.ts
+
+
+
+var cache_Cache = /** @class */ (function () {
+ function Cache() {
+ this.all = false;
+ this.before = [];
+ this.after = [];
+ this.between = [];
+ }
+ /**
+ * @param {String} what - all/before/after/between
+ * @param {Array,Date} value - an array of dates, one date, or null
+ * @param {Object?} args - _iter arguments
+ */
+ Cache.prototype._cacheAdd = function (what, value, args) {
+ if (value) {
+ value =
+ value instanceof Date
+ ? src_dateutil.clone(value)
+ : src_dateutil.cloneDates(value);
+ }
+ if (what === 'all') {
+ this.all = value;
+ }
+ else {
+ args._value = value;
+ this[what].push(args);
+ }
+ };
+ /**
+ * @return false - not in the cache
+ * null - cached, but zero occurrences (before/after)
+ * Date - cached (before/after)
+ * [] - cached, but zero occurrences (all/between)
+ * [Date1, DateN] - cached (all/between)
+ */
+ Cache.prototype._cacheGet = function (what, args) {
+ var cached = false;
+ var argsKeys = args ? Object.keys(args) : [];
+ var findCacheDiff = function (item) {
+ for (var i = 0; i < argsKeys.length; i++) {
+ var key = argsKeys[i];
+ if (String(args[key]) !== String(item[key])) {
+ return true;
+ }
+ }
+ return false;
+ };
+ var cachedObject = this[what];
+ if (what === 'all') {
+ cached = this.all;
+ }
+ else if (Object(helpers["d" /* isArray */])(cachedObject)) {
+ // Let's see whether we've already called the
+ // 'what' method with the same 'args'
+ for (var i = 0; i < cachedObject.length; i++) {
+ var item = cachedObject[i];
+ if (argsKeys.length && findCacheDiff(item))
+ continue;
+ cached = item._value;
+ break;
+ }
+ }
+ if (!cached && this.all) {
+ // Not in the cache, but we already know all the occurrences,
+ // so we can find the correct dates from the cached ones.
+ var iterResult = new iterresult(what, args);
+ for (var i = 0; i < this.all.length; i++) {
+ if (!iterResult.accept(this.all[i]))
+ break;
+ }
+ cached = iterResult.getValue();
+ this._cacheAdd(what, cached, args);
+ }
+ return Object(helpers["d" /* isArray */])(cached)
+ ? src_dateutil.cloneDates(cached)
+ : cached instanceof Date
+ ? src_dateutil.clone(cached)
+ : cached;
+ };
+ return Cache;
+}());
+
+
+// CONCATENATED MODULE: ./src/masks.ts
+
+// =============================================================================
+// Date masks
+// =============================================================================
+// Every mask is 7 days longer to handle cross-year weekly periods.
+var M365MASK = Object(helpers["k" /* repeat */])(1, 31).concat(Object(helpers["k" /* repeat */])(2, 28), Object(helpers["k" /* repeat */])(3, 31), Object(helpers["k" /* repeat */])(4, 30), Object(helpers["k" /* repeat */])(5, 31), Object(helpers["k" /* repeat */])(6, 30), Object(helpers["k" /* repeat */])(7, 31), Object(helpers["k" /* repeat */])(8, 31), Object(helpers["k" /* repeat */])(9, 30), Object(helpers["k" /* repeat */])(10, 31), Object(helpers["k" /* repeat */])(11, 30), Object(helpers["k" /* repeat */])(12, 31), Object(helpers["k" /* repeat */])(1, 7));
+var M366MASK = Object(helpers["k" /* repeat */])(1, 31).concat(Object(helpers["k" /* repeat */])(2, 29), Object(helpers["k" /* repeat */])(3, 31), Object(helpers["k" /* repeat */])(4, 30), Object(helpers["k" /* repeat */])(5, 31), Object(helpers["k" /* repeat */])(6, 30), Object(helpers["k" /* repeat */])(7, 31), Object(helpers["k" /* repeat */])(8, 31), Object(helpers["k" /* repeat */])(9, 30), Object(helpers["k" /* repeat */])(10, 31), Object(helpers["k" /* repeat */])(11, 30), Object(helpers["k" /* repeat */])(12, 31), Object(helpers["k" /* repeat */])(1, 7));
+var M28 = Object(helpers["j" /* range */])(1, 29);
+var M29 = Object(helpers["j" /* range */])(1, 30);
+var M30 = Object(helpers["j" /* range */])(1, 31);
+var M31 = Object(helpers["j" /* range */])(1, 32);
+var MDAY366MASK = M31.concat(M29, M31, M30, M31, M30, M31, M31, M30, M31, M30, M31, M31.slice(0, 7));
+var MDAY365MASK = M31.concat(M28, M31, M30, M31, M30, M31, M31, M30, M31, M30, M31, M31.slice(0, 7));
+var NM28 = Object(helpers["j" /* range */])(-28, 0);
+var NM29 = Object(helpers["j" /* range */])(-29, 0);
+var NM30 = Object(helpers["j" /* range */])(-30, 0);
+var NM31 = Object(helpers["j" /* range */])(-31, 0);
+var NMDAY366MASK = NM31.concat(NM29, NM31, NM30, NM31, NM30, NM31, NM31, NM30, NM31, NM30, NM31, NM31.slice(0, 7));
+var NMDAY365MASK = NM31.concat(NM28, NM31, NM30, NM31, NM30, NM31, NM31, NM30, NM31, NM30, NM31, NM31.slice(0, 7));
+var M366RANGE = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
+var M365RANGE = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
+var WDAYMASK = (function () {
+ var wdaymask = [];
+ for (var i = 0; i < 55; i++)
+ wdaymask = wdaymask.concat(Object(helpers["j" /* range */])(7));
+ return wdaymask;
+})();
+
+
+// CONCATENATED MODULE: ./src/iterinfo/yearinfo.ts
+var yearinfo_assign = (undefined && undefined.__assign) || function () {
+ yearinfo_assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return yearinfo_assign.apply(this, arguments);
+};
+
+
+
+function rebuildYear(year, options) {
+ var firstyday = new Date(Date.UTC(year, 0, 1));
+ var yearlen = src_dateutil.isLeapYear(year) ? 366 : 365;
+ var nextyearlen = src_dateutil.isLeapYear(year + 1) ? 366 : 365;
+ var yearordinal = src_dateutil.toOrdinal(firstyday);
+ var yearweekday = src_dateutil.getWeekday(firstyday);
+ var result = yearinfo_assign({ yearlen: yearlen,
+ nextyearlen: nextyearlen,
+ yearordinal: yearordinal,
+ yearweekday: yearweekday }, baseYearMasks(year), { wnomask: null });
+ if (Object(helpers["b" /* empty */])(options.byweekno)) {
+ return result;
+ }
+ result.wnomask = Object(helpers["k" /* repeat */])(0, yearlen + 7);
+ var firstwkst;
+ var wyearlen;
+ var no1wkst = firstwkst = Object(helpers["i" /* pymod */])(7 - yearweekday + options.wkst, 7);
+ if (no1wkst >= 4) {
+ no1wkst = 0;
+ // Number of days in the year, plus the days we got
+ // from last year.
+ wyearlen =
+ result.yearlen + Object(helpers["i" /* pymod */])(yearweekday - options.wkst, 7);
+ }
+ else {
+ // Number of days in the year, minus the days we
+ // left in last year.
+ wyearlen = yearlen - no1wkst;
+ }
+ var div = Math.floor(wyearlen / 7);
+ var mod = Object(helpers["i" /* pymod */])(wyearlen, 7);
+ var numweeks = Math.floor(div + mod / 4);
+ for (var j = 0; j < options.byweekno.length; j++) {
+ var n = options.byweekno[j];
+ if (n < 0) {
+ n += numweeks + 1;
+ }
+ if (!(n > 0 && n <= numweeks)) {
+ continue;
+ }
+ var i = void 0;
+ if (n > 1) {
+ i = no1wkst + (n - 1) * 7;
+ if (no1wkst !== firstwkst) {
+ i -= 7 - firstwkst;
+ }
+ }
+ else {
+ i = no1wkst;
+ }
+ for (var k = 0; k < 7; k++) {
+ result.wnomask[i] = 1;
+ i++;
+ if (result.wdaymask[i] === options.wkst)
+ break;
+ }
+ }
+ if (Object(helpers["c" /* includes */])(options.byweekno, 1)) {
+ // Check week number 1 of next year as well
+ // orig-TODO : Check -numweeks for next year.
+ var i = no1wkst + numweeks * 7;
+ if (no1wkst !== firstwkst)
+ i -= 7 - firstwkst;
+ if (i < yearlen) {
+ // If week starts in next year, we
+ // don't care about it.
+ for (var j = 0; j < 7; j++) {
+ result.wnomask[i] = 1;
+ i += 1;
+ if (result.wdaymask[i] === options.wkst)
+ break;
+ }
+ }
+ }
+ if (no1wkst) {
+ // Check last week number of last year as
+ // well. If no1wkst is 0, either the year
+ // started on week start, or week number 1
+ // got days from last year, so there are no
+ // days from last year's last week number in
+ // this year.
+ var lnumweeks = void 0;
+ if (!Object(helpers["c" /* includes */])(options.byweekno, -1)) {
+ var lyearweekday = src_dateutil.getWeekday(new Date(Date.UTC(year - 1, 0, 1)));
+ var lno1wkst = Object(helpers["i" /* pymod */])(7 - lyearweekday.valueOf() + options.wkst, 7);
+ var lyearlen = src_dateutil.isLeapYear(year - 1) ? 366 : 365;
+ var weekst = void 0;
+ if (lno1wkst >= 4) {
+ lno1wkst = 0;
+ weekst = lyearlen + Object(helpers["i" /* pymod */])(lyearweekday - options.wkst, 7);
+ }
+ else {
+ weekst = yearlen - no1wkst;
+ }
+ lnumweeks = Math.floor(52 + Object(helpers["i" /* pymod */])(weekst, 7) / 4);
+ }
+ else {
+ lnumweeks = -1;
+ }
+ if (Object(helpers["c" /* includes */])(options.byweekno, lnumweeks)) {
+ for (var i = 0; i < no1wkst; i++)
+ result.wnomask[i] = 1;
+ }
+ }
+ return result;
+}
+function baseYearMasks(year) {
+ var yearlen = src_dateutil.isLeapYear(year) ? 366 : 365;
+ var firstyday = new Date(Date.UTC(year, 0, 1));
+ var wday = src_dateutil.getWeekday(firstyday);
+ if (yearlen === 365) {
+ return {
+ mmask: M365MASK,
+ mdaymask: MDAY365MASK,
+ nmdaymask: NMDAY365MASK,
+ wdaymask: WDAYMASK.slice(wday),
+ mrange: M365RANGE
+ };
+ }
+ return {
+ mmask: M366MASK,
+ mdaymask: MDAY366MASK,
+ nmdaymask: NMDAY366MASK,
+ wdaymask: WDAYMASK.slice(wday),
+ mrange: M366RANGE
+ };
+}
+
+// CONCATENATED MODULE: ./src/iterinfo/monthinfo.ts
+
+
+function rebuildMonth(year, month, yearlen, mrange, wdaymask, options) {
+ var result = {
+ lastyear: year,
+ lastmonth: month,
+ nwdaymask: []
+ };
+ var ranges = [];
+ if (options.freq === src_rrule.YEARLY) {
+ if (Object(helpers["b" /* empty */])(options.bymonth)) {
+ ranges = [[0, yearlen]];
+ }
+ else {
+ for (var j = 0; j < options.bymonth.length; j++) {
+ month = options.bymonth[j];
+ ranges.push(mrange.slice(month - 1, month + 1));
+ }
+ }
+ }
+ else if (options.freq === src_rrule.MONTHLY) {
+ ranges = [mrange.slice(month - 1, month + 1)];
+ }
+ if (Object(helpers["b" /* empty */])(ranges)) {
+ return result;
+ }
+ // Weekly frequency won't get here, so we may not
+ // care about cross-year weekly periods.
+ result.nwdaymask = Object(helpers["k" /* repeat */])(0, yearlen);
+ for (var j = 0; j < ranges.length; j++) {
+ var rang = ranges[j];
+ var first = rang[0];
+ var last = rang[1] - 1;
+ for (var k = 0; k < options.bynweekday.length; k++) {
+ var i = void 0;
+ var _a = options.bynweekday[k], wday = _a[0], n = _a[1];
+ if (n < 0) {
+ i = last + (n + 1) * 7;
+ i -= Object(helpers["i" /* pymod */])(wdaymask[i] - wday, 7);
+ }
+ else {
+ i = first + (n - 1) * 7;
+ i += Object(helpers["i" /* pymod */])(7 - wdaymask[i] + wday, 7);
+ }
+ if (first <= i && i <= last)
+ result.nwdaymask[i] = 1;
+ }
+ }
+ return result;
+}
+
+// CONCATENATED MODULE: ./src/iterinfo/easter.ts
+function easter(y, offset) {
+ if (offset === void 0) { offset = 0; }
+ var a = y % 19;
+ var b = Math.floor(y / 100);
+ var c = y % 100;
+ var d = Math.floor(b / 4);
+ var e = b % 4;
+ var f = Math.floor((b + 8) / 25);
+ var g = Math.floor((b - f + 1) / 3);
+ var h = Math.floor(19 * a + b - d - g + 15) % 30;
+ var i = Math.floor(c / 4);
+ var k = c % 4;
+ var l = Math.floor(32 + 2 * e + 2 * i - h - k) % 7;
+ var m = Math.floor((a + 11 * h + 22 * l) / 451);
+ var month = Math.floor((h + l - 7 * m + 114) / 31);
+ var day = ((h + l - 7 * m + 114) % 31) + 1;
+ var date = Date.UTC(y, month - 1, day + offset);
+ var yearStart = Date.UTC(y, 0, 1);
+ return [Math.ceil((date - yearStart) / (1000 * 60 * 60 * 24))];
+}
+
+// CONCATENATED MODULE: ./src/iterinfo/index.ts
+
+
+
+
+
+
+
+// =============================================================================
+// Iterinfo
+// =============================================================================
+var iterinfo_Iterinfo = /** @class */ (function () {
+ function Iterinfo(options) {
+ this.options = options;
+ }
+ Iterinfo.prototype.rebuild = function (year, month) {
+ var options = this.options;
+ if (year !== this.lastyear) {
+ this.yearinfo = rebuildYear(year, options);
+ }
+ if (Object(helpers["g" /* notEmpty */])(options.bynweekday) &&
+ (month !== this.lastmonth || year !== this.lastyear)) {
+ var _a = this.yearinfo, yearlen = _a.yearlen, mrange = _a.mrange, wdaymask = _a.wdaymask;
+ this.monthinfo = rebuildMonth(year, month, yearlen, mrange, wdaymask, options);
+ }
+ if (Object(helpers["f" /* isPresent */])(options.byeaster)) {
+ this.eastermask = easter(year, options.byeaster);
+ }
+ };
+ Object.defineProperty(Iterinfo.prototype, "lastyear", {
+ get: function () {
+ return this.monthinfo ? this.monthinfo.lastyear : null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "lastmonth", {
+ get: function () {
+ return this.monthinfo ? this.monthinfo.lastmonth : null;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "yearlen", {
+ get: function () {
+ return this.yearinfo.yearlen;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "yearordinal", {
+ get: function () {
+ return this.yearinfo.yearordinal;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "mrange", {
+ get: function () {
+ return this.yearinfo.mrange;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "wdaymask", {
+ get: function () {
+ return this.yearinfo.wdaymask;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "mmask", {
+ get: function () {
+ return this.yearinfo.mmask;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "wnomask", {
+ get: function () {
+ return this.yearinfo.wnomask;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "nwdaymask", {
+ get: function () {
+ return this.monthinfo ? this.monthinfo.nwdaymask : [];
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "nextyearlen", {
+ get: function () {
+ return this.yearinfo.nextyearlen;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "mdaymask", {
+ get: function () {
+ return this.yearinfo.mdaymask;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty(Iterinfo.prototype, "nmdaymask", {
+ get: function () {
+ return this.yearinfo.nmdaymask;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Iterinfo.prototype.ydayset = function () {
+ return [Object(helpers["j" /* range */])(this.yearlen), 0, this.yearlen];
+ };
+ Iterinfo.prototype.mdayset = function (_, month, __) {
+ var start = this.mrange[month - 1];
+ var end = this.mrange[month];
+ var set = Object(helpers["k" /* repeat */])(null, this.yearlen);
+ for (var i = start; i < end; i++)
+ set[i] = i;
+ return [set, start, end];
+ };
+ Iterinfo.prototype.wdayset = function (year, month, day) {
+ // We need to handle cross-year weeks here.
+ var set = Object(helpers["k" /* repeat */])(null, this.yearlen + 7);
+ var i = src_dateutil.toOrdinal(new Date(Date.UTC(year, month - 1, day))) -
+ this.yearordinal;
+ var start = i;
+ for (var j = 0; j < 7; j++) {
+ set[i] = i;
+ ++i;
+ if (this.wdaymask[i] === this.options.wkst)
+ break;
+ }
+ return [set, start, i];
+ };
+ Iterinfo.prototype.ddayset = function (year, month, day) {
+ var set = Object(helpers["k" /* repeat */])(null, this.yearlen);
+ var i = src_dateutil.toOrdinal(new Date(Date.UTC(year, month - 1, day))) -
+ this.yearordinal;
+ set[i] = i;
+ return [set, i, i + 1];
+ };
+ Iterinfo.prototype.htimeset = function (hour, _, second, millisecond) {
+ var _this = this;
+ var set = [];
+ this.options.byminute.forEach(function (minute) {
+ set = set.concat(_this.mtimeset(hour, minute, second, millisecond));
+ });
+ src_dateutil.sort(set);
+ return set;
+ };
+ Iterinfo.prototype.mtimeset = function (hour, minute, _, millisecond) {
+ var set = this.options.bysecond.map(function (second) {
+ return new Time(hour, minute, second, millisecond);
+ });
+ src_dateutil.sort(set);
+ return set;
+ };
+ Iterinfo.prototype.stimeset = function (hour, minute, second, millisecond) {
+ return [new Time(hour, minute, second, millisecond)];
+ };
+ Iterinfo.prototype.getdayset = function (freq) {
+ switch (freq) {
+ case Frequency.YEARLY: return this.ydayset.bind(this);
+ case Frequency.MONTHLY: return this.mdayset.bind(this);
+ case Frequency.WEEKLY: return this.wdayset.bind(this);
+ case Frequency.DAILY: return this.ddayset.bind(this);
+ default: return this.ddayset.bind(this);
+ }
+ };
+ Iterinfo.prototype.gettimeset = function (freq) {
+ switch (freq) {
+ case Frequency.HOURLY: return this.htimeset.bind(this);
+ case Frequency.MINUTELY: return this.mtimeset.bind(this);
+ case Frequency.SECONDLY: return this.stimeset.bind(this);
+ }
+ };
+ return Iterinfo;
+}());
+/* harmony default export */ var iterinfo = (iterinfo_Iterinfo);
+
+// CONCATENATED MODULE: ./src/iter/poslist.ts
+
+
+function buildPoslist(bysetpos, timeset, start, end, ii, dayset) {
+ var poslist = [];
+ for (var j = 0; j < bysetpos.length; j++) {
+ var daypos = void 0;
+ var timepos = void 0;
+ var pos = bysetpos[j];
+ if (pos < 0) {
+ daypos = Math.floor(pos / timeset.length);
+ timepos = Object(helpers["i" /* pymod */])(pos, timeset.length);
+ }
+ else {
+ daypos = Math.floor((pos - 1) / timeset.length);
+ timepos = Object(helpers["i" /* pymod */])(pos - 1, timeset.length);
+ }
+ var tmp = [];
+ for (var k = start; k < end; k++) {
+ var val = dayset[k];
+ if (!Object(helpers["f" /* isPresent */])(val))
+ continue;
+ tmp.push(val);
+ }
+ var i = void 0;
+ if (daypos < 0) {
+ i = tmp.slice(daypos)[0];
+ }
+ else {
+ i = tmp[daypos];
+ }
+ var time = timeset[timepos];
+ var date = src_dateutil.fromOrdinal(ii.yearordinal + i);
+ var res = src_dateutil.combine(date, time);
+ // XXX: can this ever be in the array?
+ // - compare the actual date instead?
+ if (!Object(helpers["c" /* includes */])(poslist, res))
+ poslist.push(res);
+ }
+ src_dateutil.sort(poslist);
+ return poslist;
+}
+
+// CONCATENATED MODULE: ./src/iter/index.ts
+
+
+
+
+
+
+
+
+
+function iter(iterResult, options) {
+ var dtstart = options.dtstart, freq = options.freq, interval = options.interval, until = options.until, bysetpos = options.bysetpos;
+ var count = options.count;
+ if (count === 0 || interval === 0) {
+ return emitResult(iterResult);
+ }
+ var counterDate = datetime_DateTime.fromDate(dtstart);
+ var ii = new iterinfo(options);
+ ii.rebuild(counterDate.year, counterDate.month);
+ var timeset = makeTimeset(ii, counterDate, options);
+ while (true) {
+ var _a = ii.getdayset(freq)(counterDate.year, counterDate.month, counterDate.day), dayset = _a[0], start = _a[1], end = _a[2];
+ var filtered = removeFilteredDays(dayset, start, end, ii, options);
+ if (Object(helpers["g" /* notEmpty */])(bysetpos)) {
+ var poslist = buildPoslist(bysetpos, timeset, start, end, ii, dayset);
+ for (var j = 0; j < poslist.length; j++) {
+ var res = poslist[j];
+ if (until && res > until) {
+ return emitResult(iterResult);
+ }
+ if (res >= dtstart) {
+ var rezonedDate = rezoneIfNeeded(res, options);
+ if (!iterResult.accept(rezonedDate)) {
+ return emitResult(iterResult);
+ }
+ if (count) {
+ --count;
+ if (!count) {
+ return emitResult(iterResult);
+ }
+ }
+ }
+ }
+ }
+ else {
+ for (var j = start; j < end; j++) {
+ var currentDay = dayset[j];
+ if (!Object(helpers["f" /* isPresent */])(currentDay)) {
+ continue;
+ }
+ var date = src_dateutil.fromOrdinal(ii.yearordinal + currentDay);
+ for (var k = 0; k < timeset.length; k++) {
+ var time = timeset[k];
+ var res = src_dateutil.combine(date, time);
+ if (until && res > until) {
+ return emitResult(iterResult);
+ }
+ if (res >= dtstart) {
+ var rezonedDate = rezoneIfNeeded(res, options);
+ if (!iterResult.accept(rezonedDate)) {
+ return emitResult(iterResult);
+ }
+ if (count) {
+ --count;
+ if (!count) {
+ return emitResult(iterResult);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (options.interval === 0) {
+ return emitResult(iterResult);
+ }
+ // Handle frequency and interval
+ counterDate.add(options, filtered);
+ if (counterDate.year > src_dateutil.MAXYEAR) {
+ return emitResult(iterResult);
+ }
+ if (!freqIsDailyOrGreater(freq)) {
+ timeset = ii.gettimeset(freq)(counterDate.hour, counterDate.minute, counterDate.second, 0);
+ }
+ ii.rebuild(counterDate.year, counterDate.month);
+ }
+}
+function isFiltered(ii, currentDay, options) {
+ var bymonth = options.bymonth, byweekno = options.byweekno, byweekday = options.byweekday, byeaster = options.byeaster, bymonthday = options.bymonthday, bynmonthday = options.bynmonthday, byyearday = options.byyearday;
+ return ((Object(helpers["g" /* notEmpty */])(bymonth) && !Object(helpers["c" /* includes */])(bymonth, ii.mmask[currentDay])) ||
+ (Object(helpers["g" /* notEmpty */])(byweekno) && !ii.wnomask[currentDay]) ||
+ (Object(helpers["g" /* notEmpty */])(byweekday) && !Object(helpers["c" /* includes */])(byweekday, ii.wdaymask[currentDay])) ||
+ (Object(helpers["g" /* notEmpty */])(ii.nwdaymask) && !ii.nwdaymask[currentDay]) ||
+ (byeaster !== null && !Object(helpers["c" /* includes */])(ii.eastermask, currentDay)) ||
+ ((Object(helpers["g" /* notEmpty */])(bymonthday) || Object(helpers["g" /* notEmpty */])(bynmonthday)) &&
+ !Object(helpers["c" /* includes */])(bymonthday, ii.mdaymask[currentDay]) &&
+ !Object(helpers["c" /* includes */])(bynmonthday, ii.nmdaymask[currentDay])) ||
+ (Object(helpers["g" /* notEmpty */])(byyearday) &&
+ ((currentDay < ii.yearlen &&
+ !Object(helpers["c" /* includes */])(byyearday, currentDay + 1) &&
+ !Object(helpers["c" /* includes */])(byyearday, -ii.yearlen + currentDay)) ||
+ (currentDay >= ii.yearlen &&
+ !Object(helpers["c" /* includes */])(byyearday, currentDay + 1 - ii.yearlen) &&
+ !Object(helpers["c" /* includes */])(byyearday, -ii.nextyearlen + currentDay - ii.yearlen)))));
+}
+function rezoneIfNeeded(date, options) {
+ return new datewithzone_DateWithZone(date, options.tzid).rezonedDate();
+}
+function emitResult(iterResult) {
+ return iterResult.getValue();
+}
+function removeFilteredDays(dayset, start, end, ii, options) {
+ var filtered = false;
+ for (var dayCounter = start; dayCounter < end; dayCounter++) {
+ var currentDay = dayset[dayCounter];
+ filtered = isFiltered(ii, currentDay, options);
+ if (filtered)
+ dayset[currentDay] = null;
+ }
+ return filtered;
+}
+function makeTimeset(ii, counterDate, options) {
+ var freq = options.freq, byhour = options.byhour, byminute = options.byminute, bysecond = options.bysecond;
+ if (freqIsDailyOrGreater(freq)) {
+ return buildTimeset(options);
+ }
+ if ((freq >= src_rrule.HOURLY &&
+ Object(helpers["g" /* notEmpty */])(byhour) &&
+ !Object(helpers["c" /* includes */])(byhour, counterDate.hour)) ||
+ (freq >= src_rrule.MINUTELY &&
+ Object(helpers["g" /* notEmpty */])(byminute) &&
+ !Object(helpers["c" /* includes */])(byminute, counterDate.minute)) ||
+ (freq >= src_rrule.SECONDLY &&
+ Object(helpers["g" /* notEmpty */])(bysecond) &&
+ !Object(helpers["c" /* includes */])(bysecond, counterDate.second))) {
+ return [];
+ }
+ return ii.gettimeset(freq)(counterDate.hour, counterDate.minute, counterDate.second, counterDate.millisecond);
+}
+
+// CONCATENATED MODULE: ./src/rrule.ts
+
+
+
+
+
+
+
+
+
+
+var getnlp = function () {
+ // Lazy, runtime import to avoid circular refs.
+ if (!getnlp._nlp) {
+ getnlp._nlp = __webpack_require__(3);
+ }
+ return getnlp._nlp;
+};
+// =============================================================================
+// RRule
+// =============================================================================
+var Days = {
+ MO: new Weekday(0),
+ TU: new Weekday(1),
+ WE: new Weekday(2),
+ TH: new Weekday(3),
+ FR: new Weekday(4),
+ SA: new Weekday(5),
+ SU: new Weekday(6)
+};
+var DEFAULT_OPTIONS = {
+ freq: Frequency.YEARLY,
+ dtstart: null,
+ interval: 1,
+ wkst: Days.MO,
+ count: null,
+ until: null,
+ tzid: null,
+ bysetpos: null,
+ bymonth: null,
+ bymonthday: null,
+ bynmonthday: null,
+ byyearday: null,
+ byweekno: null,
+ byweekday: null,
+ bynweekday: null,
+ byhour: null,
+ byminute: null,
+ bysecond: null,
+ byeaster: null
+};
+var rrule_defaultKeys = Object.keys(DEFAULT_OPTIONS);
+/**
+ *
+ * @param {Options?} options - see <http://labix.org/python-dateutil/#head-cf004ee9a75592797e076752b2a889c10f445418>
+ * The only required option is `freq`, one of RRule.YEARLY, RRule.MONTHLY, ...
+ * @constructor
+ */
+var rrule_RRule = /** @class */ (function () {
+ function RRule(options, noCache) {
+ if (options === void 0) { options = {}; }
+ if (noCache === void 0) { noCache = false; }
+ // RFC string
+ this._cache = noCache ? null : new cache_Cache();
+ // used by toString()
+ this.origOptions = initializeOptions(options);
+ var parsedOptions = parseOptions(options).parsedOptions;
+ this.options = parsedOptions;
+ }
+ RRule.parseText = function (text, language) {
+ return getnlp().parseText(text, language);
+ };
+ RRule.fromText = function (text, language) {
+ return getnlp().fromText(text, language);
+ };
+ RRule.fromString = function (str) {
+ return new RRule(RRule.parseString(str) || undefined);
+ };
+ RRule.prototype._iter = function (iterResult) {
+ return iter(iterResult, this.options);
+ };
+ RRule.prototype._cacheGet = function (what, args) {
+ if (!this._cache)
+ return false;
+ return this._cache._cacheGet(what, args);
+ };
+ RRule.prototype._cacheAdd = function (what, value, args) {
+ if (!this._cache)
+ return;
+ return this._cache._cacheAdd(what, value, args);
+ };
+ /**
+ * @param {Function} iterator - optional function that will be called
+ * on each date that is added. It can return false
+ * to stop the iteration.
+ * @return Array containing all recurrences.
+ */
+ RRule.prototype.all = function (iterator) {
+ if (iterator) {
+ return this._iter(new callbackiterresult('all', {}, iterator));
+ }
+ var result = this._cacheGet('all');
+ if (result === false) {
+ result = this._iter(new iterresult('all', {}));
+ this._cacheAdd('all', result);
+ }
+ return result;
+ };
+ /**
+ * Returns all the occurrences of the rrule between after and before.
+ * The inc keyword defines what happens if after and/or before are
+ * themselves occurrences. With inc == True, they will be included in the
+ * list, if they are found in the recurrence set.
+ * @return Array
+ */
+ RRule.prototype.between = function (after, before, inc, iterator) {
+ if (inc === void 0) { inc = false; }
+ if (!src_dateutil.isValidDate(after) || !src_dateutil.isValidDate(before))
+ throw new Error('Invalid date passed in to RRule.between');
+ var args = {
+ before: before,
+ after: after,
+ inc: inc
+ };
+ if (iterator) {
+ return this._iter(new callbackiterresult('between', args, iterator));
+ }
+ var result = this._cacheGet('between', args);
+ if (result === false) {
+ result = this._iter(new iterresult('between', args));
+ this._cacheAdd('between', result, args);
+ }
+ return result;
+ };
+ /**
+ * Returns the last recurrence before the given datetime instance.
+ * The inc keyword defines what happens if dt is an occurrence.
+ * With inc == True, if dt itself is an occurrence, it will be returned.
+ * @return Date or null
+ */
+ RRule.prototype.before = function (dt, inc) {
+ if (inc === void 0) { inc = false; }
+ if (!src_dateutil.isValidDate(dt))
+ throw new Error('Invalid date passed in to RRule.before');
+ var args = { dt: dt, inc: inc };
+ var result = this._cacheGet('before', args);
+ if (result === false) {
+ result = this._iter(new iterresult('before', args));
+ this._cacheAdd('before', result, args);
+ }
+ return result;
+ };
+ /**
+ * Returns the first recurrence after the given datetime instance.
+ * The inc keyword defines what happens if dt is an occurrence.
+ * With inc == True, if dt itself is an occurrence, it will be returned.
+ * @return Date or null
+ */
+ RRule.prototype.after = function (dt, inc) {
+ if (inc === void 0) { inc = false; }
+ if (!src_dateutil.isValidDate(dt))
+ throw new Error('Invalid date passed in to RRule.after');
+ var args = { dt: dt, inc: inc };
+ var result = this._cacheGet('after', args);
+ if (result === false) {
+ result = this._iter(new iterresult('after', args));
+ this._cacheAdd('after', result, args);
+ }
+ return result;
+ };
+ /**
+ * Returns the number of recurrences in this set. It will have go trough
+ * the whole recurrence, if this hasn't been done before.
+ */
+ RRule.prototype.count = function () {
+ return this.all().length;
+ };
+ /**
+ * Converts the rrule into its string representation
+ * @see <http://www.ietf.org/rfc/rfc2445.txt>
+ * @return String
+ */
+ RRule.prototype.toString = function () {
+ return optionsToString(this.origOptions);
+ };
+ /**
+ * Will convert all rules described in nlp:ToText
+ * to text.
+ */
+ RRule.prototype.toText = function (gettext, language) {
+ return getnlp().toText(this, gettext, language);
+ };
+ RRule.prototype.isFullyConvertibleToText = function () {
+ return getnlp().isFullyConvertible(this);
+ };
+ /**
+ * @return a RRule instance with the same freq and options
+ * as this one (cache is not cloned)
+ */
+ RRule.prototype.clone = function () {
+ return new RRule(this.origOptions);
+ };
+ // RRule class 'constants'
+ RRule.FREQUENCIES = [
+ 'YEARLY',
+ 'MONTHLY',
+ 'WEEKLY',
+ 'DAILY',
+ 'HOURLY',
+ 'MINUTELY',
+ 'SECONDLY'
+ ];
+ RRule.YEARLY = Frequency.YEARLY;
+ RRule.MONTHLY = Frequency.MONTHLY;
+ RRule.WEEKLY = Frequency.WEEKLY;
+ RRule.DAILY = Frequency.DAILY;
+ RRule.HOURLY = Frequency.HOURLY;
+ RRule.MINUTELY = Frequency.MINUTELY;
+ RRule.SECONDLY = Frequency.SECONDLY;
+ RRule.MO = Days.MO;
+ RRule.TU = Days.TU;
+ RRule.WE = Days.WE;
+ RRule.TH = Days.TH;
+ RRule.FR = Days.FR;
+ RRule.SA = Days.SA;
+ RRule.SU = Days.SU;
+ RRule.parseString = parseString;
+ RRule.optionsToString = optionsToString;
+ return RRule;
+}());
+/* harmony default export */ var src_rrule = (rrule_RRule);
+
+// CONCATENATED MODULE: ./src/iterset.ts
+
+
+
+function iterSet(iterResult, _rrule, _exrule, _rdate, _exdate, tzid) {
+ var _exdateHash = {};
+ var _accept = iterResult.accept;
+ function evalExdate(after, before) {
+ _exrule.forEach(function (rrule) {
+ rrule.between(after, before, true).forEach(function (date) {
+ _exdateHash[Number(date)] = true;
+ });
+ });
+ }
+ _exdate.forEach(function (date) {
+ var zonedDate = new datewithzone_DateWithZone(date, tzid).rezonedDate();
+ _exdateHash[Number(zonedDate)] = true;
+ });
+ iterResult.accept = function (date) {
+ var dt = Number(date);
+ if (!_exdateHash[dt]) {
+ evalExdate(new Date(dt - 1), new Date(dt + 1));
+ if (!_exdateHash[dt]) {
+ _exdateHash[dt] = true;
+ return _accept.call(this, date);
+ }
+ }
+ return true;
+ };
+ if (iterResult.method === 'between') {
+ evalExdate(iterResult.args.after, iterResult.args.before);
+ iterResult.accept = function (date) {
+ var dt = Number(date);
+ if (!_exdateHash[dt]) {
+ _exdateHash[dt] = true;
+ return _accept.call(this, date);
+ }
+ return true;
+ };
+ }
+ for (var i = 0; i < _rdate.length; i++) {
+ var zonedDate = new datewithzone_DateWithZone(_rdate[i], tzid).rezonedDate();
+ if (!iterResult.accept(new Date(zonedDate.getTime())))
+ break;
+ }
+ _rrule.forEach(function (rrule) {
+ iter(iterResult, rrule.options);
+ });
+ var res = iterResult._result;
+ src_dateutil.sort(res);
+ switch (iterResult.method) {
+ case 'all':
+ case 'between':
+ return res;
+ case 'before':
+ return ((res.length && res[res.length - 1]) || null);
+ case 'after':
+ default:
+ return ((res.length && res[0]) || null);
+ }
+}
+
+// CONCATENATED MODULE: ./src/rruleset.ts
+var rruleset_extends = (undefined && undefined.__extends) || (function () {
+ var extendStatics = function (d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ }
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+
+
+
+
+var rruleset_RRuleSet = /** @class */ (function (_super) {
+ rruleset_extends(RRuleSet, _super);
+ /**
+ *
+ * @param {Boolean?} noCache
+ * The same stratagy as RRule on cache, default to false
+ * @constructor
+ */
+ function RRuleSet(noCache) {
+ if (noCache === void 0) { noCache = false; }
+ var _this = _super.call(this, {}, noCache) || this;
+ _this._rrule = [];
+ _this._rdate = [];
+ _this._exrule = [];
+ _this._exdate = [];
+ return _this;
+ }
+ RRuleSet.prototype.tzid = function (tzid) {
+ if (tzid !== undefined) {
+ this._tzid = tzid;
+ }
+ if (this._tzid !== undefined) {
+ return this._tzid;
+ }
+ for (var i = 0; i < this._rrule.length; i++) {
+ var tzid_1 = this._rrule[i].origOptions.tzid;
+ if (tzid_1) {
+ return tzid_1;
+ }
+ }
+ return undefined;
+ };
+ RRuleSet.prototype._iter = function (iterResult) {
+ return iterSet(iterResult, this._rrule, this._exrule, this._rdate, this._exdate, this.tzid());
+ };
+ /**
+ * Adds an RRule to the set
+ *
+ * @param {RRule}
+ */
+ RRuleSet.prototype.rrule = function (rrule) {
+ _addRule(rrule, this._rrule);
+ };
+ /**
+ * Adds an EXRULE to the set
+ *
+ * @param {RRule}
+ */
+ RRuleSet.prototype.exrule = function (rrule) {
+ _addRule(rrule, this._exrule);
+ };
+ /**
+ * Adds an RDate to the set
+ *
+ * @param {Date}
+ */
+ RRuleSet.prototype.rdate = function (date) {
+ _addDate(date, this._rdate);
+ };
+ /**
+ * Adds an EXDATE to the set
+ *
+ * @param {Date}
+ */
+ RRuleSet.prototype.exdate = function (date) {
+ _addDate(date, this._exdate);
+ };
+ RRuleSet.prototype.valueOf = function () {
+ var result = [];
+ this._rrule.forEach(function (rrule) {
+ result = result.concat(rrule.toString().split('\n'));
+ });
+ this._exrule.forEach(function (exrule) {
+ result = result.concat(exrule.toString().split('\n')
+ .map(function (line) { return line.replace(/^RRULE:/, 'EXRULE:'); })
+ .filter(function (line) { return !/^DTSTART/.test(line); }));
+ });
+ if (this._rdate.length) {
+ result.push(rdatesToString('RDATE', this._rdate, this.tzid()));
+ }
+ if (this._exdate.length) {
+ result.push(rdatesToString('EXDATE', this._exdate, this.tzid()));
+ }
+ return result;
+ };
+ /**
+ * to generate recurrence field such as:
+ * DTSTART:19970902T010000Z
+ * RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU
+ * RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH
+ */
+ RRuleSet.prototype.toString = function () {
+ return this.valueOf().join('\n');
+ };
+ /**
+ * Create a new RRuleSet Object completely base on current instance
+ */
+ RRuleSet.prototype.clone = function () {
+ var rrs = new RRuleSet(!!this._cache);
+ this._rrule.forEach(function (rule) { return rrs.rrule(rule.clone()); });
+ this._exrule.forEach(function (rule) { return rrs.exrule(rule.clone()); });
+ this._rdate.forEach(function (date) { return rrs.rdate(new Date(date.getTime())); });
+ this._exdate.forEach(function (date) { return rrs.exdate(new Date(date.getTime())); });
+ return rrs;
+ };
+ return RRuleSet;
+}(src_rrule));
+/* harmony default export */ var rruleset = (rruleset_RRuleSet);
+function _addRule(rrule, collection) {
+ if (!(rrule instanceof src_rrule)) {
+ throw new TypeError(String(rrule) + ' is not RRule instance');
+ }
+ if (!Object(helpers["c" /* includes */])(collection.map(String), String(rrule))) {
+ collection.push(rrule);
+ }
+}
+function _addDate(date, collection) {
+ if (!(date instanceof Date)) {
+ throw new TypeError(String(date) + ' is not Date instance');
+ }
+ if (!Object(helpers["c" /* includes */])(collection.map(Number), Number(date))) {
+ collection.push(date);
+ src_dateutil.sort(collection);
+ }
+}
+function rdatesToString(param, rdates, tzid) {
+ var isUTC = !tzid || tzid.toUpperCase() === 'UTC';
+ var header = isUTC ? param + ":" : param + ";TZID=" + tzid + ":";
+ var dateString = rdates
+ .map(function (rdate) { return src_dateutil.timeToUntilString(rdate.valueOf(), isUTC); })
+ .join(',');
+ return "" + header + dateString;
+}
+
+// CONCATENATED MODULE: ./src/rrulestr.ts
+var rrulestr_assign = (undefined && undefined.__assign) || function () {
+ rrulestr_assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ return rrulestr_assign.apply(this, arguments);
+};
+
+
+
+
+
+/**
+ * RRuleStr
+ * To parse a set of rrule strings
+ */
+var rrulestr_DEFAULT_OPTIONS = {
+ dtstart: null,
+ cache: false,
+ unfold: false,
+ forceset: false,
+ compatible: false,
+ tzid: null
+};
+function parseInput(s, options) {
+ var rrulevals = [];
+ var rdatevals = [];
+ var exrulevals = [];
+ var exdatevals = [];
+ var _a = parseDtstart(s), dtstart = _a.dtstart, tzid = _a.tzid;
+ var lines = splitIntoLines(s, options.unfold);
+ lines.forEach(function (line) {
+ if (!line)
+ return;
+ var _a = breakDownLine(line), name = _a.name, parms = _a.parms, value = _a.value;
+ switch (name.toUpperCase()) {
+ case 'RRULE':
+ if (parms.length) {
+ throw new Error("unsupported RRULE parm: " + parms.join(','));
+ }
+ rrulevals.push(parseString(line));
+ break;
+ case 'RDATE':
+ var _b = /RDATE(?:;TZID=([^:=]+))?/i.exec(line), _ = _b[0], rdateTzid = _b[1];
+ if (rdateTzid && !tzid) {
+ tzid = rdateTzid;
+ }
+ rdatevals = rdatevals.concat(parseRDate(value, parms));
+ break;
+ case 'EXRULE':
+ if (parms.length) {
+ throw new Error("unsupported EXRULE parm: " + parms.join(','));
+ }
+ exrulevals.push(parseString(value));
+ break;
+ case 'EXDATE':
+ exdatevals = exdatevals.concat(parseRDate(value, parms));
+ break;
+ case 'DTSTART':
+ break;
+ default:
+ throw new Error('unsupported property: ' + name);
+ }
+ });
+ return {
+ dtstart: dtstart,
+ tzid: tzid,
+ rrulevals: rrulevals,
+ rdatevals: rdatevals,
+ exrulevals: exrulevals,
+ exdatevals: exdatevals
+ };
+}
+function buildRule(s, options) {
+ var _a = parseInput(s, options), rrulevals = _a.rrulevals, rdatevals = _a.rdatevals, exrulevals = _a.exrulevals, exdatevals = _a.exdatevals, dtstart = _a.dtstart, tzid = _a.tzid;
+ var noCache = options.cache === false;
+ if (options.compatible) {
+ options.forceset = true;
+ options.unfold = true;
+ }
+ if (options.forceset ||
+ rrulevals.length > 1 ||
+ rdatevals.length ||
+ exrulevals.length ||
+ exdatevals.length) {
+ var rset_1 = new rruleset(noCache);
+ rset_1.tzid(tzid || undefined);
+ rrulevals.forEach(function (val) {
+ rset_1.rrule(new src_rrule(groomRruleOptions(val, dtstart, tzid), noCache));
+ });
+ rdatevals.forEach(function (date) {
+ rset_1.rdate(date);
+ });
+ exrulevals.forEach(function (val) {
+ rset_1.exrule(new src_rrule(groomRruleOptions(val, dtstart, tzid), noCache));
+ });
+ exdatevals.forEach(function (date) {
+ rset_1.exdate(date);
+ });
+ if (options.compatible && options.dtstart)
+ rset_1.rdate(dtstart);
+ return rset_1;
+ }
+ var val = rrulevals[0];
+ return new src_rrule(groomRruleOptions(val, val.dtstart || options.dtstart || dtstart, val.tzid || options.tzid || tzid), noCache);
+}
+function rrulestr(s, options) {
+ if (options === void 0) { options = {}; }
+ return buildRule(s, rrulestr_initializeOptions(options));
+}
+function groomRruleOptions(val, dtstart, tzid) {
+ return rrulestr_assign({}, val, { dtstart: dtstart,
+ tzid: tzid });
+}
+function rrulestr_initializeOptions(options) {
+ var invalid = [];
+ var keys = Object.keys(options);
+ var defaultKeys = Object.keys(rrulestr_DEFAULT_OPTIONS);
+ keys.forEach(function (key) {
+ if (!Object(helpers["c" /* includes */])(defaultKeys, key))
+ invalid.push(key);
+ });
+ if (invalid.length) {
+ throw new Error('Invalid options: ' + invalid.join(', '));
+ }
+ var initializedOptions = rrulestr_assign({}, options);
+ // Merge in default options
+ defaultKeys.forEach(function (key) {
+ if (!Object(helpers["c" /* includes */])(keys, key))
+ initializedOptions[key] = rrulestr_DEFAULT_OPTIONS[key];
+ });
+ return initializedOptions;
+}
+function extractName(line) {
+ if (line.indexOf(':') === -1) {
+ return {
+ name: 'RRULE',
+ value: line
+ };
+ }
+ var _a = Object(helpers["l" /* split */])(line, ':', 1), name = _a[0], value = _a[1];
+ return {
+ name: name,
+ value: value
+ };
+}
+function breakDownLine(line) {
+ var _a = extractName(line), name = _a.name, value = _a.value;
+ var parms = name.split(';');
+ if (!parms)
+ throw new Error('empty property name');
+ return {
+ name: parms[0].toUpperCase(),
+ parms: parms.slice(1),
+ value: value
+ };
+}
+function splitIntoLines(s, unfold) {
+ if (unfold === void 0) { unfold = false; }
+ s = s && s.trim();
+ if (!s)
+ throw new Error('Invalid empty string');
+ // More info about 'unfold' option
+ // Go head to http://www.ietf.org/rfc/rfc2445.txt
+ if (!unfold) {
+ return s.split(/\s/);
+ }
+ var lines = s.split('\n');
+ var i = 0;
+ while (i < lines.length) {
+ // TODO
+ var line = (lines[i] = lines[i].replace(/\s+$/g, ''));
+ if (!line) {
+ lines.splice(i, 1);
+ }
+ else if (i > 0 && line[0] === ' ') {
+ lines[i - 1] += line.slice(1);
+ lines.splice(i, 1);
+ }
+ else {
+ i += 1;
+ }
+ }
+ return lines;
+}
+function validateDateParm(parms) {
+ parms.forEach(function (parm) {
+ if (!/(VALUE=DATE(-TIME)?)|(TZID=)/.test(parm)) {
+ throw new Error('unsupported RDATE/EXDATE parm: ' + parm);
+ }
+ });
+}
+function parseRDate(rdateval, parms) {
+ validateDateParm(parms);
+ return rdateval
+ .split(',')
+ .map(function (datestr) { return src_dateutil.untilStringToDate(datestr); });
+}
+
+// CONCATENATED MODULE: ./src/index.ts
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "Frequency", function() { return Frequency; });
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "Weekday", function() { return Weekday; });
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "RRule", function() { return src_rrule; });
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "RRuleSet", function() { return rruleset; });
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "rrulestr", function() { return rrulestr; });
+/*!
+ * rrule.js - Library for working with recurrence rules for calendar dates.
+ * https://github.com/jakubroztocil/rrule
+ *
+ * Copyright 2010, Jakub Roztocil and Lars Schoning
+ * Licenced under the BSD licence.
+ * https://github.com/jakubroztocil/rrule/blob/master/LICENCE
+ *
+ * Based on:
+ * python-dateutil - Extensions to the standard Python datetime module.
+ * Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
+ * Copyright (c) 2012 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
+ * https://github.com/jakubroztocil/rrule/blob/master/LICENCE
+ *
+ */
+
+
+
+
+
+// =============================================================================
+// Export
+// =============================================================================
+
+/* harmony default export */ var src = __webpack_exports__["default"] = (src_rrule);
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE__2__;
+
+/***/ }),
+/* 3 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+
+// CONCATENATED MODULE: ./src/nlp/i18n.ts
+// =============================================================================
+// i18n
+// =============================================================================
+var ENGLISH = {
+ dayNames: [
+ 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
+ 'Thursday', 'Friday', 'Saturday'
+ ],
+ monthNames: [
+ 'January', 'February', 'March', 'April', 'May',
+ 'June', 'July', 'August', 'September', 'October',
+ 'November', 'December'
+ ],
+ tokens: {
+ 'SKIP': /^[ \r\n\t]+|^\.$/,
+ 'number': /^[1-9][0-9]*/,
+ 'numberAsText': /^(one|two|three)/i,
+ 'every': /^every/i,
+ 'day(s)': /^days?/i,
+ 'weekday(s)': /^weekdays?/i,
+ 'week(s)': /^weeks?/i,
+ 'hour(s)': /^hours?/i,
+ 'minute(s)': /^minutes?/i,
+ 'month(s)': /^months?/i,
+ 'year(s)': /^years?/i,
+ 'on': /^(on|in)/i,
+ 'at': /^(at)/i,
+ 'the': /^the/i,
+ 'first': /^first/i,
+ 'second': /^second/i,
+ 'third': /^third/i,
+ 'nth': /^([1-9][0-9]*)(\.|th|nd|rd|st)/i,
+ 'last': /^last/i,
+ 'for': /^for/i,
+ 'time(s)': /^times?/i,
+ 'until': /^(un)?til/i,
+ 'monday': /^mo(n(day)?)?/i,
+ 'tuesday': /^tu(e(s(day)?)?)?/i,
+ 'wednesday': /^we(d(n(esday)?)?)?/i,
+ 'thursday': /^th(u(r(sday)?)?)?/i,
+ 'friday': /^fr(i(day)?)?/i,
+ 'saturday': /^sa(t(urday)?)?/i,
+ 'sunday': /^su(n(day)?)?/i,
+ 'january': /^jan(uary)?/i,
+ 'february': /^feb(ruary)?/i,
+ 'march': /^mar(ch)?/i,
+ 'april': /^apr(il)?/i,
+ 'may': /^may/i,
+ 'june': /^june?/i,
+ 'july': /^july?/i,
+ 'august': /^aug(ust)?/i,
+ 'september': /^sep(t(ember)?)?/i,
+ 'october': /^oct(ober)?/i,
+ 'november': /^nov(ember)?/i,
+ 'december': /^dec(ember)?/i,
+ 'comma': /^(,\s*|(and|or)\s*)+/i
+ }
+};
+/* harmony default export */ var i18n = (ENGLISH);
+
+// EXTERNAL MODULE: ./src/index.ts + 22 modules
+var src = __webpack_require__(1);
+
+// EXTERNAL MODULE: ./src/helpers.ts
+var helpers = __webpack_require__(0);
+
+// CONCATENATED MODULE: ./src/nlp/totext.ts
+
+
+
+// =============================================================================
+// Helper functions
+// =============================================================================
+/**
+ * Return true if a value is in an array
+ */
+var contains = function (arr, val) {
+ return arr.indexOf(val) !== -1;
+};
+var defaultGetText = function (id) { return id.toString(); };
+/**
+ *
+ * @param {RRule} rrule
+ * Optional:
+ * @param {Function} gettext function
+ * @param {Object} language definition
+ * @constructor
+ */
+var totext_ToText = /** @class */ (function () {
+ function ToText(rrule, gettext, language) {
+ if (gettext === void 0) { gettext = defaultGetText; }
+ if (language === void 0) { language = i18n; }
+ this.text = [];
+ this.language = language || i18n;
+ this.gettext = gettext;
+ this.rrule = rrule;
+ this.options = rrule.options;
+ this.origOptions = rrule.origOptions;
+ if (this.origOptions.bymonthday) {
+ var bymonthday = [].concat(this.options.bymonthday);
+ var bynmonthday = [].concat(this.options.bynmonthday);
+ bymonthday.sort(function (a, b) { return a - b; });
+ bynmonthday.sort(function (a, b) { return b - a; });
+ // 1, 2, 3, .., -5, -4, -3, ..
+ this.bymonthday = bymonthday.concat(bynmonthday);
+ if (!this.bymonthday.length)
+ this.bymonthday = null;
+ }
+ if (Object(helpers["f" /* isPresent */])(this.origOptions.byweekday)) {
+ var byweekday = !Object(helpers["d" /* isArray */])(this.origOptions.byweekday)
+ ? [this.origOptions.byweekday]
+ : this.origOptions.byweekday;
+ var days = String(byweekday);
+ this.byweekday = {
+ allWeeks: byweekday.filter(function (weekday) {
+ return !weekday.n;
+ }),
+ someWeeks: byweekday.filter(function (weekday) {
+ return Boolean(weekday.n);
+ }),
+ isWeekdays: days.indexOf('MO') !== -1 &&
+ days.indexOf('TU') !== -1 &&
+ days.indexOf('WE') !== -1 &&
+ days.indexOf('TH') !== -1 &&
+ days.indexOf('FR') !== -1 &&
+ days.indexOf('SA') === -1 &&
+ days.indexOf('SU') === -1,
+ isEveryDay: days.indexOf('MO') !== -1 &&
+ days.indexOf('TU') !== -1 &&
+ days.indexOf('WE') !== -1 &&
+ days.indexOf('TH') !== -1 &&
+ days.indexOf('FR') !== -1 &&
+ days.indexOf('SA') !== -1 &&
+ days.indexOf('SU') !== -1
+ };
+ var sortWeekDays = function (a, b) {
+ return a.weekday - b.weekday;
+ };
+ this.byweekday.allWeeks.sort(sortWeekDays);
+ this.byweekday.someWeeks.sort(sortWeekDays);
+ if (!this.byweekday.allWeeks.length)
+ this.byweekday.allWeeks = null;
+ if (!this.byweekday.someWeeks.length)
+ this.byweekday.someWeeks = null;
+ }
+ else {
+ this.byweekday = null;
+ }
+ }
+ /**
+ * Test whether the rrule can be fully converted to text.
+ * @param {RRule} rrule
+ * @return {Boolean}
+ */
+ ToText.isFullyConvertible = function (rrule) {
+ var canConvert = true;
+ if (!(rrule.options.freq in ToText.IMPLEMENTED))
+ return false;
+ if (rrule.origOptions.until && rrule.origOptions.count)
+ return false;
+ for (var key in rrule.origOptions) {
+ if (contains(['dtstart', 'wkst', 'freq'], key))
+ return true;
+ if (!contains(ToText.IMPLEMENTED[rrule.options.freq], key))
+ return false;
+ }
+ return canConvert;
+ };
+ ToText.prototype.isFullyConvertible = function () {
+ return ToText.isFullyConvertible(this.rrule);
+ };
+ /**
+ * Perform the conversion. Only some of the frequencies are supported.
+ * If some of the rrule's options aren't supported, they'll
+ * be omitted from the output an "(~ approximate)" will be appended.
+ * @return {*}
+ */
+ ToText.prototype.toString = function () {
+ var gettext = this.gettext;
+ if (!(this.options.freq in ToText.IMPLEMENTED)) {
+ return gettext('RRule error: Unable to fully convert this rrule to text');
+ }
+ this.text = [gettext('every')];
+ // @ts-ignore
+ this[src["default"].FREQUENCIES[this.options.freq]]();
+ if (this.options.until) {
+ this.add(gettext('until'));
+ var until = this.options.until;
+ this.add(this.language.monthNames[until.getUTCMonth()])
+ .add(until.getUTCDate() + ',')
+ .add(until.getUTCFullYear().toString());
+ }
+ else if (this.options.count) {
+ this.add(gettext('for'))
+ .add(this.options.count.toString())
+ .add(this.plural(this.options.count) ? gettext('times') : gettext('time'));
+ }
+ if (!this.isFullyConvertible())
+ this.add(gettext('(~ approximate)'));
+ return this.text.join('');
+ };
+ ToText.prototype.HOURLY = function () {
+ var gettext = this.gettext;
+ if (this.options.interval !== 1)
+ this.add(this.options.interval.toString());
+ this.add(this.plural(this.options.interval) ? gettext('hours') : gettext('hour'));
+ };
+ ToText.prototype.MINUTELY = function () {
+ var gettext = this.gettext;
+ if (this.options.interval !== 1)
+ this.add(this.options.interval.toString());
+ this.add(this.plural(this.options.interval)
+ ? gettext('minutes')
+ : gettext('minutes'));
+ };
+ ToText.prototype.DAILY = function () {
+ var gettext = this.gettext;
+ if (this.options.interval !== 1)
+ this.add(this.options.interval.toString());
+ if (this.byweekday && this.byweekday.isWeekdays) {
+ this.add(this.plural(this.options.interval)
+ ? gettext('weekdays')
+ : gettext('weekday'));
+ }
+ else {
+ this.add(this.plural(this.options.interval) ? gettext('days') : gettext('day'));
+ }
+ if (this.origOptions.bymonth) {
+ this.add(gettext('in'));
+ this._bymonth();
+ }
+ if (this.bymonthday) {
+ this._bymonthday();
+ }
+ else if (this.byweekday) {
+ this._byweekday();
+ }
+ else if (this.origOptions.byhour) {
+ this._byhour();
+ }
+ };
+ ToText.prototype.WEEKLY = function () {
+ var gettext = this.gettext;
+ if (this.options.interval !== 1) {
+ this.add(this.options.interval.toString()).add(this.plural(this.options.interval) ? gettext('weeks') : gettext('week'));
+ }
+ if (this.byweekday && this.byweekday.isWeekdays) {
+ if (this.options.interval === 1) {
+ this.add(this.plural(this.options.interval)
+ ? gettext('weekdays')
+ : gettext('weekday'));
+ }
+ else {
+ this.add(gettext('on')).add(gettext('weekdays'));
+ }
+ }
+ else if (this.byweekday && this.byweekday.isEveryDay) {
+ this.add(this.plural(this.options.interval) ? gettext('days') : gettext('day'));
+ }
+ else {
+ if (this.options.interval === 1)
+ this.add(gettext('week'));
+ if (this.origOptions.bymonth) {
+ this.add(gettext('in'));
+ this._bymonth();
+ }
+ if (this.bymonthday) {
+ this._bymonthday();
+ }
+ else if (this.byweekday) {
+ this._byweekday();
+ }
+ }
+ };
+ ToText.prototype.MONTHLY = function () {
+ var gettext = this.gettext;
+ if (this.origOptions.bymonth) {
+ if (this.options.interval !== 1) {
+ this.add(this.options.interval.toString()).add(gettext('months'));
+ if (this.plural(this.options.interval))
+ this.add(gettext('in'));
+ }
+ else {
+ // this.add(gettext('MONTH'))
+ }
+ this._bymonth();
+ }
+ else {
+ if (this.options.interval !== 1)
+ this.add(this.options.interval.toString());
+ this.add(this.plural(this.options.interval)
+ ? gettext('months')
+ : gettext('month'));
+ }
+ if (this.bymonthday) {
+ this._bymonthday();
+ }
+ else if (this.byweekday && this.byweekday.isWeekdays) {
+ this.add(gettext('on')).add(gettext('weekdays'));
+ }
+ else if (this.byweekday) {
+ this._byweekday();
+ }
+ };
+ ToText.prototype.YEARLY = function () {
+ var gettext = this.gettext;
+ if (this.origOptions.bymonth) {
+ if (this.options.interval !== 1) {
+ this.add(this.options.interval.toString());
+ this.add(gettext('years'));
+ }
+ else {
+ // this.add(gettext('YEAR'))
+ }
+ this._bymonth();
+ }
+ else {
+ if (this.options.interval !== 1)
+ this.add(this.options.interval.toString());
+ this.add(this.plural(this.options.interval) ? gettext('years') : gettext('year'));
+ }
+ if (this.bymonthday) {
+ this._bymonthday();
+ }
+ else if (this.byweekday) {
+ this._byweekday();
+ }
+ if (this.options.byyearday) {
+ this.add(gettext('on the'))
+ .add(this.list(this.options.byyearday, this.nth, gettext('and')))
+ .add(gettext('day'));
+ }
+ if (this.options.byweekno) {
+ this.add(gettext('in'))
+ .add(this.plural(this.options.byweekno.length)
+ ? gettext('weeks')
+ : gettext('week'))
+ .add(this.list(this.options.byweekno, undefined, gettext('and')));
+ }
+ };
+ ToText.prototype._bymonthday = function () {
+ var gettext = this.gettext;
+ if (this.byweekday && this.byweekday.allWeeks) {
+ this.add(gettext('on'))
+ .add(this.list(this.byweekday.allWeeks, this.weekdaytext, gettext('or')))
+ .add(gettext('the'))
+ .add(this.list(this.bymonthday, this.nth, gettext('or')));
+ }
+ else {
+ this.add(gettext('on the')).add(this.list(this.bymonthday, this.nth, gettext('and')));
+ }
+ // this.add(gettext('DAY'))
+ };
+ ToText.prototype._byweekday = function () {
+ var gettext = this.gettext;
+ if (this.byweekday.allWeeks && !this.byweekday.isWeekdays) {
+ this.add(gettext('on')).add(this.list(this.byweekday.allWeeks, this.weekdaytext));
+ }
+ if (this.byweekday.someWeeks) {
+ if (this.byweekday.allWeeks)
+ this.add(gettext('and'));
+ this.add(gettext('on the')).add(this.list(this.byweekday.someWeeks, this.weekdaytext, gettext('and')));
+ }
+ };
+ ToText.prototype._byhour = function () {
+ var gettext = this.gettext;
+ this.add(gettext('at')).add(this.list(this.origOptions.byhour, undefined, gettext('and')));
+ };
+ ToText.prototype._bymonth = function () {
+ this.add(this.list(this.options.bymonth, this.monthtext, this.gettext('and')));
+ };
+ ToText.prototype.nth = function (n) {
+ n = parseInt(n.toString(), 10);
+ var nth;
+ var npos;
+ var gettext = this.gettext;
+ if (n === -1)
+ return gettext('last');
+ npos = Math.abs(n);
+ switch (npos) {
+ case 1:
+ case 21:
+ case 31:
+ nth = npos + gettext('st');
+ break;
+ case 2:
+ case 22:
+ nth = npos + gettext('nd');
+ break;
+ case 3:
+ case 23:
+ nth = npos + gettext('rd');
+ break;
+ default:
+ nth = npos + gettext('th');
+ }
+ return n < 0 ? nth + ' ' + gettext('last') : nth;
+ };
+ ToText.prototype.monthtext = function (m) {
+ return this.language.monthNames[m - 1];
+ };
+ ToText.prototype.weekdaytext = function (wday) {
+ var weekday = Object(helpers["e" /* isNumber */])(wday) ? (wday + 1) % 7 : wday.getJsWeekday();
+ return ((wday.n ? this.nth(wday.n) + ' ' : '') + this.language.dayNames[weekday]);
+ };
+ ToText.prototype.plural = function (n) {
+ return n % 100 !== 1;
+ };
+ ToText.prototype.add = function (s) {
+ this.text.push(' ');
+ this.text.push(s);
+ return this;
+ };
+ ToText.prototype.list = function (arr, callback, finalDelim, delim) {
+ if (delim === void 0) { delim = ','; }
+ if (!Object(helpers["d" /* isArray */])(arr)) {
+ arr = [arr];
+ }
+ var delimJoin = function (array, delimiter, finalDelimiter) {
+ var list = '';
+ for (var i = 0; i < array.length; i++) {
+ if (i !== 0) {
+ if (i === array.length - 1) {
+ list += ' ' + finalDelimiter + ' ';
+ }
+ else {
+ list += delimiter + ' ';
+ }
+ }
+ list += array[i];
+ }
+ return list;
+ };
+ callback =
+ callback ||
+ function (o) {
+ return o.toString();
+ };
+ var self = this;
+ var realCallback = function (arg) {
+ return callback && callback.call(self, arg);
+ };
+ if (finalDelim) {
+ return delimJoin(arr.map(realCallback), delim, finalDelim);
+ }
+ else {
+ return arr.map(realCallback).join(delim + ' ');
+ }
+ };
+ return ToText;
+}());
+/* harmony default export */ var totext = (totext_ToText);
+
+// CONCATENATED MODULE: ./src/nlp/parsetext.ts
+
+
+// =============================================================================
+// Parser
+// =============================================================================
+var Parser = /** @class */ (function () {
+ function Parser(rules) {
+ this.done = true;
+ this.rules = rules;
+ }
+ Parser.prototype.start = function (text) {
+ this.text = text;
+ this.done = false;
+ return this.nextSymbol();
+ };
+ Parser.prototype.isDone = function () {
+ return this.done && this.symbol === null;
+ };
+ Parser.prototype.nextSymbol = function () {
+ var best;
+ var bestSymbol;
+ var p = this;
+ this.symbol = null;
+ this.value = null;
+ do {
+ if (this.done)
+ return false;
+ var rule = void 0;
+ best = null;
+ for (var name_1 in this.rules) {
+ rule = this.rules[name_1];
+ var match = rule.exec(p.text);
+ if (match) {
+ if (best === null || match[0].length > best[0].length) {
+ best = match;
+ bestSymbol = name_1;
+ }
+ }
+ }
+ if (best != null) {
+ this.text = this.text.substr(best[0].length);
+ if (this.text === '')
+ this.done = true;
+ }
+ if (best == null) {
+ this.done = true;
+ this.symbol = null;
+ this.value = null;
+ return;
+ }
+ // @ts-ignore
+ } while (bestSymbol === 'SKIP');
+ // @ts-ignore
+ this.symbol = bestSymbol;
+ this.value = best;
+ return true;
+ };
+ Parser.prototype.accept = function (name) {
+ if (this.symbol === name) {
+ if (this.value) {
+ var v = this.value;
+ this.nextSymbol();
+ return v;
+ }
+ this.nextSymbol();
+ return true;
+ }
+ return false;
+ };
+ Parser.prototype.acceptNumber = function () {
+ return this.accept('number');
+ };
+ Parser.prototype.expect = function (name) {
+ if (this.accept(name))
+ return true;
+ throw new Error('expected ' + name + ' but found ' + this.symbol);
+ };
+ return Parser;
+}());
+function parseText(text, language) {
+ if (language === void 0) { language = i18n; }
+ var options = {};
+ var ttr = new Parser(language.tokens);
+ if (!ttr.start(text))
+ return null;
+ S();
+ return options;
+ function S() {
+ // every [n]
+ ttr.expect('every');
+ var n = ttr.acceptNumber();
+ if (n)
+ options.interval = parseInt(n[0], 10);
+ if (ttr.isDone())
+ throw new Error('Unexpected end');
+ switch (ttr.symbol) {
+ case 'day(s)':
+ options.freq = src["default"].DAILY;
+ if (ttr.nextSymbol()) {
+ AT();
+ F();
+ }
+ break;
+ // FIXME Note: every 2 weekdays != every two weeks on weekdays.
+ // DAILY on weekdays is not a valid rule
+ case 'weekday(s)':
+ options.freq = src["default"].WEEKLY;
+ options.byweekday = [
+ src["default"].MO,
+ src["default"].TU,
+ src["default"].WE,
+ src["default"].TH,
+ src["default"].FR
+ ];
+ ttr.nextSymbol();
+ F();
+ break;
+ case 'week(s)':
+ options.freq = src["default"].WEEKLY;
+ if (ttr.nextSymbol()) {
+ ON();
+ F();
+ }
+ break;
+ case 'hour(s)':
+ options.freq = src["default"].HOURLY;
+ if (ttr.nextSymbol()) {
+ ON();
+ F();
+ }
+ break;
+ case 'minute(s)':
+ options.freq = src["default"].MINUTELY;
+ if (ttr.nextSymbol()) {
+ ON();
+ F();
+ }
+ break;
+ case 'month(s)':
+ options.freq = src["default"].MONTHLY;
+ if (ttr.nextSymbol()) {
+ ON();
+ F();
+ }
+ break;
+ case 'year(s)':
+ options.freq = src["default"].YEARLY;
+ if (ttr.nextSymbol()) {
+ ON();
+ F();
+ }
+ break;
+ case 'monday':
+ case 'tuesday':
+ case 'wednesday':
+ case 'thursday':
+ case 'friday':
+ case 'saturday':
+ case 'sunday':
+ options.freq = src["default"].WEEKLY;
+ var key = ttr.symbol.substr(0, 2).toUpperCase();
+ options.byweekday = [src["default"][key]];
+ if (!ttr.nextSymbol())
+ return;
+ // TODO check for duplicates
+ while (ttr.accept('comma')) {
+ if (ttr.isDone())
+ throw new Error('Unexpected end');
+ var wkd = decodeWKD();
+ if (!wkd) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + ', expected weekday');
+ }
+ // @ts-ignore
+ options.byweekday.push(src["default"][wkd]);
+ ttr.nextSymbol();
+ }
+ MDAYs();
+ F();
+ break;
+ case 'january':
+ case 'february':
+ case 'march':
+ case 'april':
+ case 'may':
+ case 'june':
+ case 'july':
+ case 'august':
+ case 'september':
+ case 'october':
+ case 'november':
+ case 'december':
+ options.freq = src["default"].YEARLY;
+ options.bymonth = [decodeM()];
+ if (!ttr.nextSymbol())
+ return;
+ // TODO check for duplicates
+ while (ttr.accept('comma')) {
+ if (ttr.isDone())
+ throw new Error('Unexpected end');
+ var m = decodeM();
+ if (!m) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + ', expected month');
+ }
+ options.bymonth.push(m);
+ ttr.nextSymbol();
+ }
+ ON();
+ F();
+ break;
+ default:
+ throw new Error('Unknown symbol');
+ }
+ }
+ function ON() {
+ var on = ttr.accept('on');
+ var the = ttr.accept('the');
+ if (!(on || the))
+ return;
+ do {
+ var nth = decodeNTH();
+ var wkd = decodeWKD();
+ var m = decodeM();
+ // nth <weekday> | <weekday>
+ if (nth) {
+ // ttr.nextSymbol()
+ if (wkd) {
+ ttr.nextSymbol();
+ if (!options.byweekday)
+ options.byweekday = [];
+ // @ts-ignore
+ options.byweekday.push(src["default"][wkd].nth(nth));
+ }
+ else {
+ if (!options.bymonthday)
+ options.bymonthday = [];
+ // @ts-ignore
+ options.bymonthday.push(nth);
+ ttr.accept('day(s)');
+ }
+ // <weekday>
+ }
+ else if (wkd) {
+ ttr.nextSymbol();
+ if (!options.byweekday)
+ options.byweekday = [];
+ // @ts-ignore
+ options.byweekday.push(src["default"][wkd]);
+ }
+ else if (ttr.symbol === 'weekday(s)') {
+ ttr.nextSymbol();
+ if (!options.byweekday) {
+ options.byweekday = [
+ src["default"].MO,
+ src["default"].TU,
+ src["default"].WE,
+ src["default"].TH,
+ src["default"].FR
+ ];
+ }
+ }
+ else if (ttr.symbol === 'week(s)') {
+ ttr.nextSymbol();
+ var n = ttr.acceptNumber();
+ if (!n) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + ', expected week number');
+ }
+ options.byweekno = [parseInt(n[0], 10)];
+ while (ttr.accept('comma')) {
+ n = ttr.acceptNumber();
+ if (!n) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + '; expected monthday');
+ }
+ options.byweekno.push(parseInt(n[0], 10));
+ }
+ }
+ else if (m) {
+ ttr.nextSymbol();
+ if (!options.bymonth)
+ options.bymonth = [];
+ // @ts-ignore
+ options.bymonth.push(m);
+ }
+ else {
+ return;
+ }
+ } while (ttr.accept('comma') || ttr.accept('the') || ttr.accept('on'));
+ }
+ function AT() {
+ var at = ttr.accept('at');
+ if (!at)
+ return;
+ do {
+ var n = ttr.acceptNumber();
+ if (!n) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + ', expected hour');
+ }
+ options.byhour = [parseInt(n[0], 10)];
+ while (ttr.accept('comma')) {
+ n = ttr.acceptNumber();
+ if (!n) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + '; expected hour');
+ }
+ options.byhour.push(parseInt(n[0], 10));
+ }
+ } while (ttr.accept('comma') || ttr.accept('at'));
+ }
+ function decodeM() {
+ switch (ttr.symbol) {
+ case 'january':
+ return 1;
+ case 'february':
+ return 2;
+ case 'march':
+ return 3;
+ case 'april':
+ return 4;
+ case 'may':
+ return 5;
+ case 'june':
+ return 6;
+ case 'july':
+ return 7;
+ case 'august':
+ return 8;
+ case 'september':
+ return 9;
+ case 'october':
+ return 10;
+ case 'november':
+ return 11;
+ case 'december':
+ return 12;
+ default:
+ return false;
+ }
+ }
+ function decodeWKD() {
+ switch (ttr.symbol) {
+ case 'monday':
+ case 'tuesday':
+ case 'wednesday':
+ case 'thursday':
+ case 'friday':
+ case 'saturday':
+ case 'sunday':
+ return ttr.symbol.substr(0, 2).toUpperCase();
+ default:
+ return false;
+ }
+ }
+ function decodeNTH() {
+ switch (ttr.symbol) {
+ case 'last':
+ ttr.nextSymbol();
+ return -1;
+ case 'first':
+ ttr.nextSymbol();
+ return 1;
+ case 'second':
+ ttr.nextSymbol();
+ return ttr.accept('last') ? -2 : 2;
+ case 'third':
+ ttr.nextSymbol();
+ return ttr.accept('last') ? -3 : 3;
+ case 'nth':
+ var v = parseInt(ttr.value[1], 10);
+ if (v < -366 || v > 366)
+ throw new Error('Nth out of range: ' + v);
+ ttr.nextSymbol();
+ return ttr.accept('last') ? -v : v;
+ default:
+ return false;
+ }
+ }
+ function MDAYs() {
+ ttr.accept('on');
+ ttr.accept('the');
+ var nth = decodeNTH();
+ if (!nth)
+ return;
+ options.bymonthday = [nth];
+ ttr.nextSymbol();
+ while (ttr.accept('comma')) {
+ nth = decodeNTH();
+ if (!nth) {
+ throw new Error('Unexpected symbol ' + ttr.symbol + '; expected monthday');
+ }
+ options.bymonthday.push(nth);
+ ttr.nextSymbol();
+ }
+ }
+ function F() {
+ if (ttr.symbol === 'until') {
+ var date = Date.parse(ttr.text);
+ if (!date)
+ throw new Error('Cannot parse until date:' + ttr.text);
+ options.until = new Date(date);
+ }
+ else if (ttr.accept('for')) {
+ options.count = parseInt(ttr.value[0], 10);
+ ttr.expect('number');
+ // ttr.expect('times')
+ }
+ }
+}
+
+// CONCATENATED MODULE: ./src/nlp/index.ts
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromText", function() { return fromText; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFullyConvertible", function() { return isFullyConvertible; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toText", function() { return toText; });
+/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "parseText", function() { return parseText; });
+
+
+
+
+/*!
+* rrule.js - Library for working with recurrence rules for calendar dates.
+* https://github.com/jakubroztocil/rrule
+*
+* Copyright 2010, Jakub Roztocil and Lars Schoning
+* Licenced under the BSD licence.
+* https://github.com/jakubroztocil/rrule/blob/master/LICENCE
+*
+*/
+/**
+ *
+ * Implementation of RRule.fromText() and RRule::toText().
+ *
+ *
+ * On the client side, this file needs to be included
+ * when those functions are used.
+ *
+ */
+// =============================================================================
+// fromText
+// =============================================================================
+/**
+ * Will be able to convert some of the below described rules from
+ * text format to a rule object.
+ *
+ *
+ * RULES
+ *
+ * Every ([n])
+ * day(s)
+ * | [weekday], ..., (and) [weekday]
+ * | weekday(s)
+ * | week(s)
+ * | month(s)
+ * | [month], ..., (and) [month]
+ * | year(s)
+ *
+ *
+ * Plus 0, 1, or multiple of these:
+ *
+ * on [weekday], ..., (or) [weekday] the [monthday], [monthday], ... (or) [monthday]
+ *
+ * on [weekday], ..., (and) [weekday]
+ *
+ * on the [monthday], [monthday], ... (and) [monthday] (day of the month)
+ *
+ * on the [nth-weekday], ..., (and) [nth-weekday] (of the month/year)
+ *
+ *
+ * Plus 0 or 1 of these:
+ *
+ * for [n] time(s)
+ *
+ * until [date]
+ *
+ * Plus (.)
+ *
+ *
+ * Definitely no supported for parsing:
+ *
+ * (for year):
+ * in week(s) [n], ..., (and) [n]
+ *
+ * on the [yearday], ..., (and) [n] day of the year
+ * on day [yearday], ..., (and) [n]
+ *
+ *
+ * NON-TERMINALS
+ *
+ * [n]: 1, 2 ..., one, two, three ..
+ * [month]: January, February, March, April, May, ... December
+ * [weekday]: Monday, ... Sunday
+ * [nth-weekday]: first [weekday], 2nd [weekday], ... last [weekday], ...
+ * [monthday]: first, 1., 2., 1st, 2nd, second, ... 31st, last day, 2nd last day, ..
+ * [date]:
+ * [month] (0-31(,) ([year])),
+ * (the) 0-31.(1-12.([year])),
+ * (the) 0-31/(1-12/([year])),
+ * [weekday]
+ *
+ * [year]: 0000, 0001, ... 01, 02, ..
+ *
+ * Definitely not supported for parsing:
+ *
+ * [yearday]: first, 1., 2., 1st, 2nd, second, ... 366th, last day, 2nd last day, ..
+ *
+ * @param {String} text
+ * @return {Object, Boolean} the rule, or null.
+ */
+var fromText = function (text, language) {
+ if (language === void 0) { language = i18n; }
+ return new src["default"](parseText(text, language) || undefined);
+};
+var common = [
+ 'count',
+ 'until',
+ 'interval',
+ 'byweekday',
+ 'bymonthday',
+ 'bymonth'
+];
+totext.IMPLEMENTED = [];
+totext.IMPLEMENTED[src["default"].HOURLY] = common;
+totext.IMPLEMENTED[src["default"].MINUTELY] = common;
+totext.IMPLEMENTED[src["default"].DAILY] = ['byhour'].concat(common);
+totext.IMPLEMENTED[src["default"].WEEKLY] = common;
+totext.IMPLEMENTED[src["default"].MONTHLY] = common;
+totext.IMPLEMENTED[src["default"].YEARLY] = ['byweekno', 'byyearday'].concat(common);
+// =============================================================================
+// Export
+// =============================================================================
+var toText = function (rrule, gettext, language) {
+ return new totext(rrule, gettext, language).toString();
+};
+var isFullyConvertible = totext.isFullyConvertible;
+
+
+
+/***/ })
+/******/ ]);
+});
+//# sourceMappingURL=rrule.js.map \ No newline at end of file
diff --git a/util/po2php.php b/util/po2php.php
index 9ffcb64c4..73d9b454e 100644
--- a/util/po2php.php
+++ b/util/po2php.php
@@ -52,7 +52,7 @@ function po2php_run($argc,$argv) {
if ($l[0]=="#") $l="";
if (substr($l,0,15)=='"Plural-Forms: '){
$match=Array();
- preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);
+ preg_match("|nplurals=([0-9]*);\s*plural=(.*)[;\\\\]|", $l, $match);
$cond = str_replace('n','$n',$match[2]);
$out .= 'if(! function_exists("' . 'string_plural_select_' . $lang .'")) {' . "\n";
$out .= 'function string_plural_select_' . $lang . '($n){'."\n";
diff --git a/util/storageconv b/util/storageconv
new file mode 100755
index 000000000..594ec14fb
--- /dev/null
+++ b/util/storageconv
@@ -0,0 +1,137 @@
+#!/usr/bin/env php
+<?php
+
+// Hubzilla thumbnails storage convertor
+function usage() {
+ echo <<< EOT
+Hubzilla thumbnails storage convertor
+
+Usage:
+ util/storageconv stats # show current stats
+ util/storageconv fs # move thumbnails from SQL to filesystem
+ util/storageconv db # move thumbnails from filesystem to SQL
+
+EOT;
+}
+
+require_once('include/cli_startup.php');
+
+cli_startup();
+
+if($argc == 1) {
+ usage();
+ killme();
+}
+
+if($argc == 2) {
+
+ $storage = (intval(get_config('system','filesystem_storage_thumbnails', 0)) > 0 ? 1 : 0);
+ echo 'Current storage set to: ' . ($storage ? 'filesystem' : 'SQL database') . PHP_EOL;
+ switch($argv[1]) {
+ case 'stats':
+ $x = q("SELECT COUNT(resource_id) AS qty FROM photo WHERE photo_usage = 0 and os_storage = 1");
+ echo 'Local images: ' . $x[0]['qty'] . PHP_EOL;
+ $x = q("SELECT COUNT(id) AS qty FROM photo WHERE resource_id IN (SELECT DISTINCT resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1) AND imgscale > 0");
+ echo 'Thumbnails total: ' . $x[0]['qty'] . PHP_EOL;
+ $x = q("SELECT COUNT(id) AS qty FROM photo WHERE resource_id IN (SELECT DISTINCT resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1) AND os_storage != %d AND imgscale > 0",
+ $storage
+ );
+ echo 'Thumbnails to convert: ' . $x[0]['qty'] . PHP_EOL;
+ break;
+
+ case 'fs':
+ if($storage == 0) {
+ echo 'Please set system.filesystem_storage_thumbnails to 1 before move thumbnails to filesystem storage' . PHP_EOL;
+ break;
+ }
+
+ $x = q("SELECT DISTINCT uid, resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1");
+
+ if($x) {
+ foreach($x as $xx) {
+
+ $r = q("SELECT channel_address FROM channel WHERE channel_id = %d",
+ intval($xx['uid'])
+ );
+
+ $n = q("SELECT id, imgscale, content, os_path FROM photo WHERE resource_id = '%s' AND os_storage != %d AND imgscale > 0",
+ dbesc($xx['resource_id']),
+ $storage
+ );
+
+ echo count($n) . PHP_EOL;
+ foreach($n as $nn) {
+
+ echo '.';
+
+ $filename = 'store/' . $r[0]['channel_address'] . '/' . $nn['os_path'] . '-' . $nn['imgscale'];
+ if(! file_put_contents($filename, dbunescbin($nn['content']))) {
+ echo 'Failed to save file ' . $filename . PHP_EOL;
+ continue;
+ }
+
+ $z = q("UPDATE photo SET content = '%s', os_storage = 1 WHERE id = %d",
+ dbescbin($filename),
+ intval($nn['id'])
+ );
+ if(! $z) {
+ @unlink($filename);
+ echo 'Failed to update metadata for saved file ' . $filename . PHP_EOL;
+ }
+
+ }
+ }
+ }
+ break;
+
+ case 'db':
+ if($storage == 1) {
+ echo 'Please set system.filesystem_storage_thumbnails to 0 before move thumbnails to SQL database storage' . PHP_EOL;
+ break;
+ }
+
+ $x = q("SELECT DISTINCT resource_id FROM photo WHERE photo_usage = 0 and os_storage = 1");
+
+ if($x) {
+ foreach($x as $xx) {
+
+ $n = q("SELECT id, content FROM photo WHERE resource_id = '%s' AND os_storage != %d AND imgscale > 0",
+ dbesc($xx['resource_id']),
+ $storage
+ );
+
+ foreach($n as $nn) {
+
+ echo '.';
+
+ $filename = dbunescbin($nn['content']);
+ $content = file_get_contents($filename);
+ if($content) {
+
+ $z = q("UPDATE photo SET content = '%s', os_storage = 0 WHERE id = %d",
+ dbescbin($content),
+ intval($nn['id'])
+ );
+ if(! $z) {
+ echo 'Failed to update stored file metadata ' . $filename . PHP_EOL;
+ continue;
+ }
+
+ @unlink($filename);
+ }
+ else
+ echo 'Can not read file contents ' . $filename . PHP_EOL;
+ }
+ }
+ }
+ break;
+
+ default:
+ usage();
+ return;
+
+ }
+
+ echo PHP_EOL;
+}
+
diff --git a/view/css/cdav_calendar.css b/view/css/cdav_calendar.css
index d68278a63..2deff683c 100644
--- a/view/css/cdav_calendar.css
+++ b/view/css/cdav_calendar.css
@@ -2,13 +2,18 @@
.fc th:first-child,
.fc td:first-child {
- border-left-width: 0px;
+ border-left-width: 0px;
}
.fc th:last-child,
.fc td:last-child {
- border-right-width: 0px;
- border-bottom-width: 0px;
+ border-right-width: 0px;
+ border-bottom-width: 0px;
+}
+
+main.fullscreen .fc th:last-child,
+main.fullscreen .fc td:last-child {
+ border-bottom-width: 1px;
}
.fc-unthemed th,
@@ -20,3 +25,7 @@
.fc-unthemed .fc-popover {
border-color: #ccc !important;
}
+
+.fc-list-view {
+ border-width: 0px;
+}
diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po
index 2c394e84c..e5f69ab8d 100644
--- a/view/ru/hmessages.po
+++ b/view/ru/hmessages.po
@@ -1,7 +1,7 @@
-# hubzilla
-# Copyright (C) 2012-2016 hubzilla
-# This file is distributed under the same license as the hubzilla package.
-# Mike Macgirvin, 2012
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Alex <info@pixelbits.de>, 2016-2017
@@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: hubzilla\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-02-19 15:46+0200\n"
-"PO-Revision-Date: 2019-02-19 15:58+0200\n"
+"POT-Creation-Date: 2019-04-15 12:05+0200\n"
+"PO-Revision-Date: 2019-04-15 12:14+0200\n"
"Last-Translator: Max Kostikov <max@kostikov.co>\n"
"Language-Team: Russian (http://www.transifex.com/Friendica/hubzilla/language/ru/)\n"
"MIME-Version: 1.0\n"
@@ -21,1413 +21,5852 @@ msgstr ""
"Language: ru\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))\n"
-#: ../../Zotlabs/Access/Permissions.php:56
-msgid "Can view my channel stream and posts"
-msgstr "Может просматривать мой поток и сообщения"
+#: ../../util/nconfig.php:34
+msgid "Source channel not found."
+msgstr "Канал-источник не найден."
-#: ../../Zotlabs/Access/Permissions.php:57
-msgid "Can send me their channel stream and posts"
-msgstr "Может присылать мне свои потоки и сообщения"
+#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3200
+#: ../../Zotlabs/Module/Admin/Site.php:187
+msgid "Default"
+msgstr "По умолчанию"
-#: ../../Zotlabs/Access/Permissions.php:58
-msgid "Can view my default channel profile"
-msgstr "Может просматривать мой стандартный профиль канала"
+#: ../../view/theme/redbasic/php/config.php:16
+#: ../../view/theme/redbasic/php/config.php:19
+msgid "Focus (Hubzilla default)"
+msgstr "Фокус (по умолчанию Hubzilla)"
-#: ../../Zotlabs/Access/Permissions.php:59
-msgid "Can view my connections"
-msgstr "Может просматривать мои контакты"
+#: ../../view/theme/redbasic/php/config.php:94 ../../include/js_strings.php:22
+#: ../../Zotlabs/Module/Mail.php:431 ../../Zotlabs/Module/Pconfig.php:116
+#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Permcats.php:128
+#: ../../Zotlabs/Module/Xchan.php:15
+#: ../../Zotlabs/Module/Email_validation.php:40
+#: ../../Zotlabs/Module/Poke.php:217 ../../Zotlabs/Module/Appman.php:155
+#: ../../Zotlabs/Module/Profiles.php:723 ../../Zotlabs/Module/Photos.php:1097
+#: ../../Zotlabs/Module/Photos.php:1138 ../../Zotlabs/Module/Photos.php:1257
+#: ../../Zotlabs/Module/Oauth.php:111 ../../Zotlabs/Module/Events.php:495
+#: ../../Zotlabs/Module/Rate.php:166 ../../Zotlabs/Module/Locs.php:121
+#: ../../Zotlabs/Module/Sources.php:125 ../../Zotlabs/Module/Sources.php:162
+#: ../../Zotlabs/Module/Chat.php:211 ../../Zotlabs/Module/Chat.php:250
+#: ../../Zotlabs/Module/Oauth2.php:116
+#: ../../Zotlabs/Module/Settings/Manage.php:41
+#: ../../Zotlabs/Module/Settings/Calendar.php:41
+#: ../../Zotlabs/Module/Settings/Account.php:103
+#: ../../Zotlabs/Module/Settings/Conversation.php:48
+#: ../../Zotlabs/Module/Settings/Editor.php:41
+#: ../../Zotlabs/Module/Settings/Display.php:189
+#: ../../Zotlabs/Module/Settings/Features.php:46
+#: ../../Zotlabs/Module/Settings/Network.php:61
+#: ../../Zotlabs/Module/Settings/Events.php:41
+#: ../../Zotlabs/Module/Settings/Channel_home.php:89
+#: ../../Zotlabs/Module/Settings/Directory.php:41
+#: ../../Zotlabs/Module/Settings/Photos.php:41
+#: ../../Zotlabs/Module/Settings/Profiles.php:50
+#: ../../Zotlabs/Module/Settings/Connections.php:41
+#: ../../Zotlabs/Module/Settings/Channel.php:493
+#: ../../Zotlabs/Module/Filestorage.php:203 ../../Zotlabs/Module/Cal.php:344
+#: ../../Zotlabs/Module/Setup.php:304 ../../Zotlabs/Module/Setup.php:344
+#: ../../Zotlabs/Module/Mitem.php:259
+#: ../../Zotlabs/Module/Admin/Features.php:66
+#: ../../Zotlabs/Module/Admin/Logs.php:84
+#: ../../Zotlabs/Module/Admin/Channels.php:147
+#: ../../Zotlabs/Module/Admin/Security.php:112
+#: ../../Zotlabs/Module/Admin/Addons.php:441
+#: ../../Zotlabs/Module/Admin/Site.php:289
+#: ../../Zotlabs/Module/Admin/Profs.php:178
+#: ../../Zotlabs/Module/Admin/Themes.php:158
+#: ../../Zotlabs/Module/Admin/Accounts.php:168
+#: ../../Zotlabs/Module/Admin/Account_edit.php:73
+#: ../../Zotlabs/Module/Tokens.php:188 ../../Zotlabs/Module/Thing.php:326
+#: ../../Zotlabs/Module/Thing.php:379 ../../Zotlabs/Module/Editpost.php:85
+#: ../../Zotlabs/Module/Connedit.php:904 ../../Zotlabs/Module/Group.php:150
+#: ../../Zotlabs/Module/Group.php:166 ../../Zotlabs/Module/Mood.php:158
+#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Connect.php:124
+#: ../../Zotlabs/Module/Pdledit.php:107 ../../Zotlabs/Module/Affinity.php:87
+#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Import.php:611
+#: ../../Zotlabs/Module/Import_items.php:129
+#: ../../Zotlabs/Widget/Wiki_pages.php:42
+#: ../../Zotlabs/Widget/Wiki_pages.php:99
+#: ../../Zotlabs/Widget/Eventstools.php:16 ../../Zotlabs/Lib/ThreadItem.php:795
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:71
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:56
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:136
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:72
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:72
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:124
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:184
+#: ../../extend/addon/hzaddons/logrot/logrot.php:35
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:57
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:169
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:67
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:261
+#: ../../extend/addon/hzaddons/piwik/piwik.php:95
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:115
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:100
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:53
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:86
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:73
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:193
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:251
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:306
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:602
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:142
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:73
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:114
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:410
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:640
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:248
+#: ../../extend/addon/hzaddons/cart/cart.php:1264
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:53
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:142
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:54
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:95
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:55
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:97
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:92
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:70
+#: ../../extend/addon/hzaddons/irc/irc.php:45
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:60
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:70
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:90
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:65
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:99
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:97
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:61
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:51
+msgid "Submit"
+msgstr "Отправить"
-#: ../../Zotlabs/Access/Permissions.php:60
-msgid "Can view my file storage and photos"
-msgstr "Может просматривать мое хранилище файлов"
+#: ../../view/theme/redbasic/php/config.php:98
+msgid "Theme settings"
+msgstr "Настройки темы"
-#: ../../Zotlabs/Access/Permissions.php:61
-msgid "Can upload/modify my file storage and photos"
-msgstr "Может загружать/изменять мои файлы и фотографии в хранилище"
+#: ../../view/theme/redbasic/php/config.php:99
+msgid "Narrow navbar"
+msgstr "Узкая панель навигации"
-#: ../../Zotlabs/Access/Permissions.php:62
-msgid "Can view my channel webpages"
-msgstr "Может просматривать мои веб-страницы"
+#: ../../view/theme/redbasic/php/config.php:99
+#: ../../view/theme/redbasic/php/config.php:116 ../../include/dir_fns.php:143
+#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
+#: ../../boot.php:1634 ../../Zotlabs/Storage/Browser.php:411
+#: ../../Zotlabs/Module/Defperms.php:197 ../../Zotlabs/Module/Profiles.php:681
+#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Api.php:99
+#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
+#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
+#: ../../Zotlabs/Module/Settings/Display.php:89
+#: ../../Zotlabs/Module/Settings/Channel.php:309
+#: ../../Zotlabs/Module/Filestorage.php:198
+#: ../../Zotlabs/Module/Filestorage.php:206
+#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Menu.php:162
+#: ../../Zotlabs/Module/Menu.php:221 ../../Zotlabs/Module/Mitem.php:176
+#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256
+#: ../../Zotlabs/Module/Mitem.php:257 ../../Zotlabs/Module/Admin/Site.php:255
+#: ../../Zotlabs/Module/Connedit.php:406 ../../Zotlabs/Module/Connedit.php:796
+#: ../../Zotlabs/Module/Wiki.php:227 ../../Zotlabs/Module/Wiki.php:228
+#: ../../Zotlabs/Module/Import.php:600 ../../Zotlabs/Module/Import.php:604
+#: ../../Zotlabs/Module/Import.php:605 ../../Zotlabs/Lib/Libzotdir.php:162
+#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../Zotlabs/Lib/Libzotdir.php:165
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:60
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:161
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:191
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:199
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:203
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:207
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:62
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:110
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:59
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:71
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:64
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:646
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:650
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258
+#: ../../extend/addon/hzaddons/cart/cart.php:1258
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86
+msgid "No"
+msgstr "Нет"
-#: ../../Zotlabs/Access/Permissions.php:63
-msgid "Can view my wiki pages"
-msgstr "Может просматривать мои вики-страницы"
+#: ../../view/theme/redbasic/php/config.php:99
+#: ../../view/theme/redbasic/php/config.php:116 ../../include/dir_fns.php:143
+#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
+#: ../../boot.php:1634 ../../Zotlabs/Storage/Browser.php:411
+#: ../../Zotlabs/Module/Defperms.php:197 ../../Zotlabs/Module/Profiles.php:681
+#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Api.php:98
+#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
+#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
+#: ../../Zotlabs/Module/Settings/Display.php:89
+#: ../../Zotlabs/Module/Settings/Channel.php:309
+#: ../../Zotlabs/Module/Filestorage.php:198
+#: ../../Zotlabs/Module/Filestorage.php:206
+#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Menu.php:162
+#: ../../Zotlabs/Module/Menu.php:221 ../../Zotlabs/Module/Mitem.php:176
+#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256
+#: ../../Zotlabs/Module/Mitem.php:257 ../../Zotlabs/Module/Admin/Site.php:257
+#: ../../Zotlabs/Module/Connedit.php:406 ../../Zotlabs/Module/Wiki.php:227
+#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Import.php:600
+#: ../../Zotlabs/Module/Import.php:604 ../../Zotlabs/Module/Import.php:605
+#: ../../Zotlabs/Lib/Libzotdir.php:162 ../../Zotlabs/Lib/Libzotdir.php:163
+#: ../../Zotlabs/Lib/Libzotdir.php:165
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:60
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:161
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:191
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:199
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:203
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:207
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:62
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:110
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:59
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:71
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:153
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:425
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:64
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:646
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:650
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:87
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:95
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:63
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:254
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:258
+#: ../../extend/addon/hzaddons/cart/cart.php:1258
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:45
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86
+msgid "Yes"
+msgstr "Да"
-#: ../../Zotlabs/Access/Permissions.php:64
-msgid "Can create/edit my channel webpages"
-msgstr "Может редактировать мои веб-страницы"
+#: ../../view/theme/redbasic/php/config.php:100
+msgid "Navigation bar background color"
+msgstr "Панель навигации, цвет фона"
-#: ../../Zotlabs/Access/Permissions.php:65
-msgid "Can write to my wiki pages"
-msgstr "Может редактировать мои вики-страницы"
+#: ../../view/theme/redbasic/php/config.php:101
+msgid "Navigation bar icon color "
+msgstr "Панель навигации, цвет значков"
-#: ../../Zotlabs/Access/Permissions.php:66
-msgid "Can post on my channel (wall) page"
-msgstr "Может публиковать на моей странице канала"
+#: ../../view/theme/redbasic/php/config.php:102
+msgid "Navigation bar active icon color "
+msgstr "Панель навигации, цвет активного значка"
-#: ../../Zotlabs/Access/Permissions.php:67
-msgid "Can comment on or like my posts"
-msgstr "Может прокомментировать или отмечать как понравившиеся мои публикации"
+#: ../../view/theme/redbasic/php/config.php:103
+msgid "Link color"
+msgstr "Цвет ссылок"
-#: ../../Zotlabs/Access/Permissions.php:68
-msgid "Can send me private mail messages"
-msgstr "Может отправлять мне личные сообщения по эл. почте"
+#: ../../view/theme/redbasic/php/config.php:104
+msgid "Set font-color for banner"
+msgstr "Цвет текста в шапке"
-#: ../../Zotlabs/Access/Permissions.php:69
-msgid "Can like/dislike profiles and profile things"
-msgstr "Может комментировать или отмечать как нравится/ненравится мой профиль"
+#: ../../view/theme/redbasic/php/config.php:105
+msgid "Set the background color"
+msgstr "Цвет фона"
-#: ../../Zotlabs/Access/Permissions.php:70
-msgid "Can forward to all my channel connections via ! mentions in posts"
-msgstr "Может пересылать всем подписчикам моего канала используя ! в публикациях"
+#: ../../view/theme/redbasic/php/config.php:106
+msgid "Set the background image"
+msgstr "Фоновое изображение"
-#: ../../Zotlabs/Access/Permissions.php:71
-msgid "Can chat with me"
-msgstr "Может общаться со мной в чате"
+#: ../../view/theme/redbasic/php/config.php:107
+msgid "Set the background color of items"
+msgstr "Цвет фона элементов"
-#: ../../Zotlabs/Access/Permissions.php:72
-msgid "Can source my public posts in derived channels"
-msgstr "Может использовать мои публичные сообщения в клонированных лентах сообщений"
+#: ../../view/theme/redbasic/php/config.php:108
+msgid "Set the background color of comments"
+msgstr "Цвет фона комментариев"
-#: ../../Zotlabs/Access/Permissions.php:73
-msgid "Can administer my channel"
-msgstr "Может администрировать мой канал"
+#: ../../view/theme/redbasic/php/config.php:109
+msgid "Set font-size for the entire application"
+msgstr "Установить системный размер шрифта"
-#: ../../Zotlabs/Access/PermissionRoles.php:283
-msgid "Social Networking"
-msgstr "Социальная Сеть"
+#: ../../view/theme/redbasic/php/config.php:109
+msgid "Examples: 1rem, 100%, 16px"
+msgstr "Например: 1rem, 100%, 16px"
-#: ../../Zotlabs/Access/PermissionRoles.php:284
-msgid "Social - Federation"
-msgstr "Социальная - Федерация"
+#: ../../view/theme/redbasic/php/config.php:110
+msgid "Set font-color for posts and comments"
+msgstr "Цвет шрифта для публикаций и комментариев"
-#: ../../Zotlabs/Access/PermissionRoles.php:285
-msgid "Social - Mostly Public"
-msgstr "Социальная - В основном общественный"
+#: ../../view/theme/redbasic/php/config.php:111
+msgid "Set radius of corners"
+msgstr "Радиус скруглений"
-#: ../../Zotlabs/Access/PermissionRoles.php:286
-msgid "Social - Restricted"
-msgstr "Социальная - Ограниченный"
+#: ../../view/theme/redbasic/php/config.php:111
+msgid "Example: 4px"
+msgstr "Например: 4px"
-#: ../../Zotlabs/Access/PermissionRoles.php:287
-msgid "Social - Private"
-msgstr "Социальная - Частный"
+#: ../../view/theme/redbasic/php/config.php:112
+msgid "Set shadow depth of photos"
+msgstr "Глубина теней фотографий"
-#: ../../Zotlabs/Access/PermissionRoles.php:290
-msgid "Community Forum"
-msgstr "Форум сообщества"
+#: ../../view/theme/redbasic/php/config.php:113
+msgid "Set maximum width of content region in pixel"
+msgstr "Максимальная ширина содержания региона (в пикселях)"
-#: ../../Zotlabs/Access/PermissionRoles.php:291
-msgid "Forum - Mostly Public"
-msgstr "Форум - В основном общественный"
+#: ../../view/theme/redbasic/php/config.php:113
+msgid "Leave empty for default width"
+msgstr "Оставьте пустым для ширины по умолчанию"
-#: ../../Zotlabs/Access/PermissionRoles.php:292
-msgid "Forum - Restricted"
-msgstr "Форум - Ограниченный"
+#: ../../view/theme/redbasic/php/config.php:114
+msgid "Set size of conversation author photo"
+msgstr "Размер фотографии автора беседы"
-#: ../../Zotlabs/Access/PermissionRoles.php:293
-msgid "Forum - Private"
-msgstr "Форум - Частный"
+#: ../../view/theme/redbasic/php/config.php:115
+msgid "Set size of followup author photos"
+msgstr "Размер фотографий подписчиков"
-#: ../../Zotlabs/Access/PermissionRoles.php:296
-msgid "Feed Republish"
-msgstr "Публиковать ленты новостей"
+#: ../../view/theme/redbasic/php/config.php:116
+msgid "Show advanced settings"
+msgstr "Показать расширенные настройки"
-#: ../../Zotlabs/Access/PermissionRoles.php:297
-msgid "Feed - Mostly Public"
-msgstr "Ленты новостей - В основном общественный"
+#: ../../include/selectors.php:18
+msgid "Profile to assign new connections"
+msgstr "Назначить профиль для новых контактов"
-#: ../../Zotlabs/Access/PermissionRoles.php:298
-msgid "Feed - Restricted"
-msgstr "Ленты новостей - Ограниченный"
+#: ../../include/selectors.php:41
+msgid "Frequently"
+msgstr "Часто"
-#: ../../Zotlabs/Access/PermissionRoles.php:301
-msgid "Special Purpose"
-msgstr "Спец. назначение"
+#: ../../include/selectors.php:42
+msgid "Hourly"
+msgstr "Ежечасно"
-#: ../../Zotlabs/Access/PermissionRoles.php:302
-msgid "Special - Celebrity/Soapbox"
-msgstr "Спец. назначение - Знаменитость/Soapbox"
+#: ../../include/selectors.php:43
+msgid "Twice daily"
+msgstr "Дважды в день"
-#: ../../Zotlabs/Access/PermissionRoles.php:303
-msgid "Special - Group Repository"
-msgstr "Спец. назначение - Групповой репозиторий"
+#: ../../include/selectors.php:44
+msgid "Daily"
+msgstr "Ежедневно"
+
+#: ../../include/selectors.php:45
+msgid "Weekly"
+msgstr "Еженедельно"
+
+#: ../../include/selectors.php:46
+msgid "Monthly"
+msgstr "Ежемесячно"
+
+#: ../../include/selectors.php:60 ../../include/selectors.php:77
+#: ../../include/channel.php:1595
+#: ../../extend/addon/hzaddons/openid/Mod_Id.php:85
+msgid "Male"
+msgstr "Мужчина"
+
+#: ../../include/selectors.php:60 ../../include/selectors.php:77
+#: ../../include/channel.php:1593
+#: ../../extend/addon/hzaddons/openid/Mod_Id.php:87
+msgid "Female"
+msgstr "Женщина"
+
+#: ../../include/selectors.php:60
+msgid "Currently Male"
+msgstr "В настоящее время мужской"
+
+#: ../../include/selectors.php:60
+msgid "Currently Female"
+msgstr "В настоящее время женский"
+
+#: ../../include/selectors.php:60
+msgid "Mostly Male"
+msgstr "В основном мужской"
+
+#: ../../include/selectors.php:60
+msgid "Mostly Female"
+msgstr "В основном женский"
+
+#: ../../include/selectors.php:60
+msgid "Transgender"
+msgstr "Трансгендер"
+
+#: ../../include/selectors.php:60
+msgid "Intersex"
+msgstr "Интерсексуал"
+
+#: ../../include/selectors.php:60
+msgid "Transsexual"
+msgstr "Транссексуал"
+
+#: ../../include/selectors.php:60
+msgid "Hermaphrodite"
+msgstr "Гермафродит"
+
+#: ../../include/selectors.php:60 ../../include/channel.php:1599
+msgid "Neuter"
+msgstr "Среднего рода"
+#: ../../include/selectors.php:60 ../../include/channel.php:1601
+msgid "Non-specific"
+msgstr "Неспецифический"
+
+#: ../../include/selectors.php:60 ../../include/selectors.php:77
+#: ../../include/selectors.php:115 ../../include/selectors.php:151
+#: ../../include/connections.php:703 ../../include/connections.php:710
+#: ../../include/event.php:1327 ../../include/event.php:1334
+#: ../../Zotlabs/Module/Cdav.php:1254 ../../Zotlabs/Module/Profiles.php:795
+#: ../../Zotlabs/Module/Connedit.php:935
#: ../../Zotlabs/Access/PermissionRoles.php:306
-#: ../../Zotlabs/Module/Cdav.php:1227 ../../Zotlabs/Module/Connedit.php:935
-#: ../../Zotlabs/Module/Profiles.php:795 ../../include/selectors.php:60
-#: ../../include/selectors.php:77 ../../include/selectors.php:115
-#: ../../include/selectors.php:151 ../../include/event.php:1327
-#: ../../include/event.php:1334 ../../include/connections.php:703
-#: ../../include/connections.php:710
msgid "Other"
msgstr "Другой"
-#: ../../Zotlabs/Access/PermissionRoles.php:307
-msgid "Custom/Expert Mode"
-msgstr "Экспертный режим"
+#: ../../include/selectors.php:60
+msgid "Undecided"
+msgstr "Не решил"
-#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Articles.php:42
-#: ../../Zotlabs/Module/Editlayout.php:31 ../../Zotlabs/Module/Connect.php:17
-#: ../../Zotlabs/Module/Achievements.php:15 ../../Zotlabs/Module/Hcard.php:12
-#: ../../Zotlabs/Module/Editblock.php:31 ../../Zotlabs/Module/Profile.php:20
-#: ../../Zotlabs/Module/Menu.php:91 ../../Zotlabs/Module/Layouts.php:31
-#: ../../Zotlabs/Module/Editwebpage.php:32 ../../Zotlabs/Module/Cards.php:42
-#: ../../Zotlabs/Module/Webpages.php:39 ../../Zotlabs/Module/Filestorage.php:51
-#: ../../addon/gallery/Mod_Gallery.php:49 ../../include/channel.php:1253
-msgid "Requested profile is not available."
-msgstr "Запрашиваемый профиль не доступен."
+#: ../../include/selectors.php:96 ../../include/selectors.php:115
+msgid "Males"
+msgstr "Мужчины"
-#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80
-#: ../../Zotlabs/Module/Invite.php:21 ../../Zotlabs/Module/Invite.php:102
-#: ../../Zotlabs/Module/Articles.php:88 ../../Zotlabs/Module/Editlayout.php:67
-#: ../../Zotlabs/Module/Editlayout.php:90 ../../Zotlabs/Module/Channel.php:168
-#: ../../Zotlabs/Module/Channel.php:335 ../../Zotlabs/Module/Channel.php:374
-#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Locs.php:87
-#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Events.php:271
-#: ../../Zotlabs/Module/Appman.php:87 ../../Zotlabs/Module/Regmod.php:20
-#: ../../Zotlabs/Module/Article_edit.php:51
-#: ../../Zotlabs/Module/New_channel.php:105
-#: ../../Zotlabs/Module/New_channel.php:130
-#: ../../Zotlabs/Module/Sharedwithme.php:16 ../../Zotlabs/Module/Setup.php:209
-#: ../../Zotlabs/Module/Moderate.php:13
-#: ../../Zotlabs/Module/Achievements.php:34 ../../Zotlabs/Module/Thing.php:280
-#: ../../Zotlabs/Module/Thing.php:300 ../../Zotlabs/Module/Thing.php:341
-#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Editblock.php:67
+#: ../../include/selectors.php:96 ../../include/selectors.php:115
+msgid "Females"
+msgstr "Женщины"
+
+#: ../../include/selectors.php:96
+msgid "Gay"
+msgstr "Гей"
+
+#: ../../include/selectors.php:96
+msgid "Lesbian"
+msgstr "Лесбиянка"
+
+#: ../../include/selectors.php:96
+msgid "No Preference"
+msgstr "Без предпочтений"
+
+#: ../../include/selectors.php:96
+msgid "Bisexual"
+msgstr "Бисексуал"
+
+#: ../../include/selectors.php:96
+msgid "Autosexual"
+msgstr "Автосексуал"
+
+#: ../../include/selectors.php:96
+msgid "Abstinent"
+msgstr "Воздержание"
+
+#: ../../include/selectors.php:96
+msgid "Virgin"
+msgstr "Девственник"
+
+#: ../../include/selectors.php:96
+msgid "Deviant"
+msgstr "Отклоняющийся от нормы"
+
+#: ../../include/selectors.php:96
+msgid "Fetish"
+msgstr "Фетишист"
+
+#: ../../include/selectors.php:96
+msgid "Oodles"
+msgstr "Множественный"
+
+#: ../../include/selectors.php:96
+msgid "Nonsexual"
+msgstr "Асексуал"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Single"
+msgstr "Одиночка"
+
+#: ../../include/selectors.php:134
+msgid "Lonely"
+msgstr "Одинокий"
+
+#: ../../include/selectors.php:134
+msgid "Available"
+msgstr "Свободен"
+
+#: ../../include/selectors.php:134
+msgid "Unavailable"
+msgstr "Занят"
+
+#: ../../include/selectors.php:134
+msgid "Has crush"
+msgstr "Влюблён"
+
+#: ../../include/selectors.php:134
+msgid "Infatuated"
+msgstr "без ума"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Dating"
+msgstr "Встречаюсь"
+
+#: ../../include/selectors.php:134
+msgid "Unfaithful"
+msgstr "Неверный"
+
+#: ../../include/selectors.php:134
+msgid "Sex Addict"
+msgstr "Эротоман"
+
+#: ../../include/selectors.php:134 ../../include/channel.php:493
+#: ../../include/channel.php:494 ../../include/channel.php:501
+#: ../../Zotlabs/Module/Settings/Channel.php:70
+#: ../../Zotlabs/Module/Settings/Channel.php:74
+#: ../../Zotlabs/Module/Settings/Channel.php:75
+#: ../../Zotlabs/Module/Settings/Channel.php:78
+#: ../../Zotlabs/Module/Settings/Channel.php:89
+#: ../../Zotlabs/Module/Connedit.php:725 ../../Zotlabs/Widget/Affinity.php:32
+msgid "Friends"
+msgstr "Друзья"
+
+#: ../../include/selectors.php:134
+msgid "Friends/Benefits"
+msgstr "Друзья / Выгоды"
+
+#: ../../include/selectors.php:134
+msgid "Casual"
+msgstr "Легкомысленный"
+
+#: ../../include/selectors.php:134
+msgid "Engaged"
+msgstr "Помолвлен"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Married"
+msgstr "В браке"
+
+#: ../../include/selectors.php:134
+msgid "Imaginarily married"
+msgstr "В воображаемом браке"
+
+#: ../../include/selectors.php:134
+msgid "Partners"
+msgstr "Партнёрство"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Cohabiting"
+msgstr "Сожительствующие"
+
+#: ../../include/selectors.php:134
+msgid "Common law"
+msgstr "Гражданский брак"
+
+#: ../../include/selectors.php:134
+msgid "Happy"
+msgstr "Счастлив"
+
+#: ../../include/selectors.php:134
+msgid "Not looking"
+msgstr "Не нуждаюсь"
+
+#: ../../include/selectors.php:134
+msgid "Swinger"
+msgstr "Свингер"
+
+#: ../../include/selectors.php:134
+msgid "Betrayed"
+msgstr "Предан"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Separated"
+msgstr "Разделён"
+
+#: ../../include/selectors.php:134
+msgid "Unstable"
+msgstr "Нестабильно"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Divorced"
+msgstr "В разводе"
+
+#: ../../include/selectors.php:134
+msgid "Imaginarily divorced"
+msgstr "В воображаемом разводе"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "Widowed"
+msgstr "Вдовец / вдова"
+
+#: ../../include/selectors.php:134
+msgid "Uncertain"
+msgstr "Неопределенный"
+
+#: ../../include/selectors.php:134 ../../include/selectors.php:151
+msgid "It's complicated"
+msgstr "Это сложно"
+
+#: ../../include/selectors.php:134
+msgid "Don't care"
+msgstr "Всё равно"
+
+#: ../../include/selectors.php:134
+msgid "Ask me"
+msgstr "Спроси меня"
+
+#: ../../include/photos.php:27 ../../include/items.php:3801
+#: ../../include/attach.php:150 ../../include/attach.php:199
+#: ../../include/attach.php:272 ../../include/attach.php:380
+#: ../../include/attach.php:394 ../../include/attach.php:401
+#: ../../include/attach.php:483 ../../include/attach.php:1043
+#: ../../include/attach.php:1117 ../../include/attach.php:1280
+#: ../../Zotlabs/Module/Mail.php:146 ../../Zotlabs/Module/Defperms.php:181
+#: ../../Zotlabs/Module/Network.php:19 ../../Zotlabs/Module/Common.php:38
+#: ../../Zotlabs/Module/Item.php:397 ../../Zotlabs/Module/Item.php:416
+#: ../../Zotlabs/Module/Item.php:426 ../../Zotlabs/Module/Item.php:1302
+#: ../../Zotlabs/Module/Achievements.php:34
+#: ../../Zotlabs/Module/Display.php:451 ../../Zotlabs/Module/Poke.php:157
#: ../../Zotlabs/Module/Profile.php:85 ../../Zotlabs/Module/Profile.php:101
-#: ../../Zotlabs/Module/Mood.php:126 ../../Zotlabs/Module/Connections.php:32
-#: ../../Zotlabs/Module/Viewsrc.php:19 ../../Zotlabs/Module/Bookmarks.php:70
-#: ../../Zotlabs/Module/Photos.php:69 ../../Zotlabs/Module/Wiki.php:59
-#: ../../Zotlabs/Module/Wiki.php:285 ../../Zotlabs/Module/Wiki.php:428
-#: ../../Zotlabs/Module/Pdledit.php:34 ../../Zotlabs/Module/Poke.php:157
-#: ../../Zotlabs/Module/Profile_photo.php:302
-#: ../../Zotlabs/Module/Profile_photo.php:315
-#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Item.php:376
-#: ../../Zotlabs/Module/Item.php:395 ../../Zotlabs/Module/Item.php:405
-#: ../../Zotlabs/Module/Item.php:1281 ../../Zotlabs/Module/Page.php:34
-#: ../../Zotlabs/Module/Page.php:133 ../../Zotlabs/Module/Connedit.php:399
-#: ../../Zotlabs/Module/Chat.php:115 ../../Zotlabs/Module/Chat.php:120
-#: ../../Zotlabs/Module/Menu.php:129 ../../Zotlabs/Module/Menu.php:140
-#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78
-#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Cloud.php:40
-#: ../../Zotlabs/Module/Defperms.php:181 ../../Zotlabs/Module/Group.php:14
-#: ../../Zotlabs/Module/Group.php:30 ../../Zotlabs/Module/Profiles.php:198
-#: ../../Zotlabs/Module/Profiles.php:635
-#: ../../Zotlabs/Module/Editwebpage.php:68
-#: ../../Zotlabs/Module/Editwebpage.php:89
-#: ../../Zotlabs/Module/Editwebpage.php:107
-#: ../../Zotlabs/Module/Editwebpage.php:121 ../../Zotlabs/Module/Manage.php:10
-#: ../../Zotlabs/Module/Cards.php:86 ../../Zotlabs/Module/Webpages.php:133
-#: ../../Zotlabs/Module/Block.php:24 ../../Zotlabs/Module/Block.php:74
-#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Sources.php:80
-#: ../../Zotlabs/Module/Like.php:187 ../../Zotlabs/Module/Suggest.php:32
-#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Mail.php:146
+#: ../../Zotlabs/Module/Appman.php:87 ../../Zotlabs/Module/Profiles.php:198
+#: ../../Zotlabs/Module/Profiles.php:635 ../../Zotlabs/Module/Photos.php:69
+#: ../../Zotlabs/Module/Page.php:34 ../../Zotlabs/Module/Page.php:133
+#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Events.php:271
+#: ../../Zotlabs/Module/New_channel.php:105
+#: ../../Zotlabs/Module/New_channel.php:130 ../../Zotlabs/Module/Block.php:24
+#: ../../Zotlabs/Module/Block.php:74 ../../Zotlabs/Module/Cover_photo.php:342
+#: ../../Zotlabs/Module/Cover_photo.php:355
+#: ../../Zotlabs/Module/Sharedwithme.php:16
#: ../../Zotlabs/Module/Register.php:77
-#: ../../Zotlabs/Module/Cover_photo.php:313
-#: ../../Zotlabs/Module/Cover_photo.php:326
-#: ../../Zotlabs/Module/Display.php:446 ../../Zotlabs/Module/Network.php:19
-#: ../../Zotlabs/Module/Filestorage.php:15
-#: ../../Zotlabs/Module/Filestorage.php:70
-#: ../../Zotlabs/Module/Filestorage.php:96
-#: ../../Zotlabs/Module/Filestorage.php:140 ../../Zotlabs/Module/Common.php:38
#: ../../Zotlabs/Module/Viewconnections.php:28
#: ../../Zotlabs/Module/Viewconnections.php:33
-#: ../../Zotlabs/Module/Service_limits.php:11 ../../Zotlabs/Module/Rate.php:113
+#: ../../Zotlabs/Module/Rate.php:113 ../../Zotlabs/Module/Regmod.php:20
+#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Locs.php:87
+#: ../../Zotlabs/Module/Sources.php:80 ../../Zotlabs/Module/Chat.php:115
+#: ../../Zotlabs/Module/Chat.php:120 ../../Zotlabs/Module/Editlayout.php:67
+#: ../../Zotlabs/Module/Editlayout.php:90
+#: ../../Zotlabs/Module/Filestorage.php:17
+#: ../../Zotlabs/Module/Filestorage.php:72
+#: ../../Zotlabs/Module/Filestorage.php:90
+#: ../../Zotlabs/Module/Filestorage.php:113
+#: ../../Zotlabs/Module/Filestorage.php:160
+#: ../../Zotlabs/Module/Editblock.php:67
+#: ../../Zotlabs/Module/Service_limits.php:11
+#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Channel.php:168
+#: ../../Zotlabs/Module/Channel.php:335 ../../Zotlabs/Module/Channel.php:374
+#: ../../Zotlabs/Module/Like.php:187 ../../Zotlabs/Module/Bookmarks.php:70
+#: ../../Zotlabs/Module/Viewsrc.php:19 ../../Zotlabs/Module/Menu.php:129
+#: ../../Zotlabs/Module/Menu.php:140 ../../Zotlabs/Module/Setup.php:206
+#: ../../Zotlabs/Module/Mitem.php:129 ../../Zotlabs/Module/Notifications.php:11
+#: ../../Zotlabs/Module/Editwebpage.php:68
+#: ../../Zotlabs/Module/Editwebpage.php:89
+#: ../../Zotlabs/Module/Editwebpage.php:107
+#: ../../Zotlabs/Module/Editwebpage.php:121
+#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Thing.php:280
+#: ../../Zotlabs/Module/Thing.php:300 ../../Zotlabs/Module/Thing.php:341
+#: ../../Zotlabs/Module/Moderate.php:13 ../../Zotlabs/Module/Webpages.php:133
+#: ../../Zotlabs/Module/Profile_photo.php:313
+#: ../../Zotlabs/Module/Profile_photo.php:326
+#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Connedit.php:399
+#: ../../Zotlabs/Module/Group.php:14 ../../Zotlabs/Module/Group.php:30
+#: ../../Zotlabs/Module/Connections.php:32 ../../Zotlabs/Module/Mood.php:126
#: ../../Zotlabs/Module/Card_edit.php:51
-#: ../../Zotlabs/Module/Notifications.php:11 ../../Zotlabs/Lib/Chatroom.php:133
-#: ../../Zotlabs/Web/WebServer.php:123 ../../addon/keepout/keepout.php:36
-#: ../../addon/flashcards/Mod_Flashcards.php:167
-#: ../../addon/openid/Mod_Id.php:53 ../../addon/pumpio/pumpio.php:44
-#: ../../include/attach.php:150 ../../include/attach.php:199
-#: ../../include/attach.php:272 ../../include/attach.php:381
-#: ../../include/attach.php:395 ../../include/attach.php:402
-#: ../../include/attach.php:484 ../../include/attach.php:1044
-#: ../../include/attach.php:1118 ../../include/attach.php:1283
-#: ../../include/items.php:3781 ../../include/photos.php:27
+#: ../../Zotlabs/Module/Article_edit.php:51 ../../Zotlabs/Module/Blocks.php:73
+#: ../../Zotlabs/Module/Blocks.php:80 ../../Zotlabs/Module/Invite.php:21
+#: ../../Zotlabs/Module/Invite.php:102 ../../Zotlabs/Module/Articles.php:88
+#: ../../Zotlabs/Module/Cloud.php:40 ../../Zotlabs/Module/Pdledit.php:34
+#: ../../Zotlabs/Module/Wiki.php:59 ../../Zotlabs/Module/Wiki.php:285
+#: ../../Zotlabs/Module/Wiki.php:428 ../../Zotlabs/Module/Manage.php:10
+#: ../../Zotlabs/Module/Suggest.php:32 ../../Zotlabs/Module/Cards.php:86
+#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78
+#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Web/WebServer.php:123
+#: ../../Zotlabs/Lib/Chatroom.php:133
+#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:167
+#: ../../extend/addon/hzaddons/pumpio/pumpio.php:44
+#: ../../extend/addon/hzaddons/openid/Mod_Id.php:53
+#: ../../extend/addon/hzaddons/keepout/keepout.php:36
msgid "Permission denied."
msgstr "Доступ запрещен."
-#: ../../Zotlabs/Module/Blocks.php:97 ../../Zotlabs/Module/Blocks.php:155
-#: ../../Zotlabs/Module/Editblock.php:113
-msgid "Block Name"
-msgstr "Название блока"
+#: ../../include/photos.php:151
+#, php-format
+msgid "Image exceeds website size limit of %lu bytes"
+msgstr "Файл превышает предельный размер для сайта в %lu байт"
-#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2534
-msgid "Blocks"
-msgstr "Блокировки"
+#: ../../include/photos.php:162
+msgid "Image file is empty."
+msgstr "Файл изображения пуст."
-#: ../../Zotlabs/Module/Blocks.php:156
-msgid "Block Title"
-msgstr "Заблокировать заголовок"
+#: ../../include/photos.php:196 ../../Zotlabs/Module/Cover_photo.php:234
+#: ../../Zotlabs/Module/Profile_photo.php:236
+msgid "Unable to process image"
+msgstr "Не удается обработать изображение"
-#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Menu.php:177
-#: ../../Zotlabs/Module/Layouts.php:191 ../../Zotlabs/Module/Webpages.php:266
-msgid "Created"
-msgstr "Создано"
+#: ../../include/photos.php:324
+msgid "Photo storage failed."
+msgstr "Ошибка хранилища фотографий."
-#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Menu.php:178
-#: ../../Zotlabs/Module/Layouts.php:192 ../../Zotlabs/Module/Webpages.php:267
-msgid "Edited"
-msgstr "Отредактировано"
+#: ../../include/photos.php:373
+msgid "a new photo"
+msgstr "новая фотография"
-#: ../../Zotlabs/Module/Blocks.php:159 ../../Zotlabs/Module/Articles.php:116
-#: ../../Zotlabs/Module/Cdav.php:1230 ../../Zotlabs/Module/New_channel.php:189
-#: ../../Zotlabs/Module/Connedit.php:938 ../../Zotlabs/Module/Menu.php:181
-#: ../../Zotlabs/Module/Layouts.php:185 ../../Zotlabs/Module/Profiles.php:798
-#: ../../Zotlabs/Module/Cards.php:113 ../../Zotlabs/Module/Webpages.php:254
-#: ../../Zotlabs/Storage/Browser.php:276 ../../Zotlabs/Storage/Browser.php:390
-#: ../../Zotlabs/Widget/Cdav.php:128 ../../Zotlabs/Widget/Cdav.php:165
-msgid "Create"
-msgstr "Создать"
+#: ../../include/photos.php:377
+#, php-format
+msgctxt "photo_upload"
+msgid "%1$s posted %2$s to %3$s"
+msgstr "%1$s опубликовал %2$s в %3$s"
-#: ../../Zotlabs/Module/Blocks.php:160 ../../Zotlabs/Module/Editlayout.php:114
-#: ../../Zotlabs/Module/Article_edit.php:99
-#: ../../Zotlabs/Module/Admin/Profs.php:175 ../../Zotlabs/Module/Thing.php:266
-#: ../../Zotlabs/Module/Oauth2.php:194 ../../Zotlabs/Module/Editblock.php:114
-#: ../../Zotlabs/Module/Connections.php:284
-#: ../../Zotlabs/Module/Connections.php:322
-#: ../../Zotlabs/Module/Connections.php:342 ../../Zotlabs/Module/Wiki.php:211
-#: ../../Zotlabs/Module/Wiki.php:384 ../../Zotlabs/Module/Menu.php:175
-#: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Module/Group.php:252
-#: ../../Zotlabs/Module/Editwebpage.php:142
-#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Card_edit.php:99
-#: ../../Zotlabs/Module/Oauth.php:173 ../../Zotlabs/Lib/Apps.php:556
-#: ../../Zotlabs/Lib/ThreadItem.php:147 ../../Zotlabs/Storage/Browser.php:290
-#: ../../Zotlabs/Widget/Cdav.php:126 ../../Zotlabs/Widget/Cdav.php:162
-#: ../../include/channel.php:1352 ../../include/channel.php:1356
-#: ../../include/menu.php:118
+#: ../../include/photos.php:666 ../../include/nav.php:449
+msgid "Photo Albums"
+msgstr "Фотоальбомы"
+
+#: ../../include/photos.php:667 ../../Zotlabs/Module/Photos.php:1389
+#: ../../Zotlabs/Module/Photos.php:1402 ../../Zotlabs/Module/Photos.php:1403
+msgid "Recent Photos"
+msgstr "Последние фотографии"
+
+#: ../../include/photos.php:671
+msgid "Upload New Photos"
+msgstr "Загрузить новые фотографии"
+
+#: ../../include/oembed.php:226
+msgid "View PDF"
+msgstr "Просмотреть PDF"
+
+#: ../../include/oembed.php:356
+msgid " by "
+msgstr " из "
+
+#: ../../include/oembed.php:357
+msgid " on "
+msgstr " на "
+
+#: ../../include/oembed.php:386
+msgid "Embedded content"
+msgstr "Встроенное содержимое"
+
+#: ../../include/oembed.php:395
+msgid "Embedding disabled"
+msgstr "Встраивание отключено"
+
+#: ../../include/security.php:607
+msgid ""
+"The form security token was not correct. This probably happened because the "
+"form has been opened for too long (>3 hours) before submitting it."
+msgstr "Не верный токен безопасности для формы. Вероятно, это произошло потому, что форма была открыта слишком долго (> 3-х часов) перед его отправкой."
+
+#: ../../include/contact_widgets.php:11
+#, php-format
+msgid "%d invitation available"
+msgid_plural "%d invitations available"
+msgstr[0] "доступно %d приглашение"
+msgstr[1] "доступны %d приглашения"
+msgstr[2] "доступны %d приглашений"
+
+#: ../../include/contact_widgets.php:16 ../../Zotlabs/Module/Admin/Site.php:293
+msgid "Advanced"
+msgstr "Дополнительно"
+
+#: ../../include/contact_widgets.php:19
+msgid "Find Channels"
+msgstr "Поиск каналов"
+
+#: ../../include/contact_widgets.php:20
+msgid "Enter name or interest"
+msgstr "Впишите имя или интерес"
+
+#: ../../include/contact_widgets.php:21
+msgid "Connect/Follow"
+msgstr "Подключить / отслеживать"
+
+#: ../../include/contact_widgets.php:22
+msgid "Examples: Robert Morgenstein, Fishing"
+msgstr "Примеры: Владимир Ильич, Революционер"
+
+#: ../../include/contact_widgets.php:23 ../../Zotlabs/Module/Directory.php:405
+#: ../../Zotlabs/Module/Directory.php:410
+#: ../../Zotlabs/Module/Connections.php:355
+msgid "Find"
+msgstr "Поиск"
+
+#: ../../include/contact_widgets.php:24 ../../Zotlabs/Module/Directory.php:409
+#: ../../Zotlabs/Module/Suggest.php:79
+msgid "Channel Suggestions"
+msgstr "Рекомендации каналов"
+
+#: ../../include/contact_widgets.php:26
+msgid "Random Profile"
+msgstr "Случайный профиль"
+
+#: ../../include/contact_widgets.php:27
+msgid "Invite Friends"
+msgstr "Пригласить друзей"
+
+#: ../../include/contact_widgets.php:29
+msgid "Advanced example: name=fred and country=iceland"
+msgstr "Расширенный пример: name=ivan and country=russia"
+
+#: ../../include/contact_widgets.php:53 ../../include/features.php:325
+#: ../../Zotlabs/Widget/Filer.php:28
+#: ../../Zotlabs/Widget/Activity_filter.php:137
+msgid "Saved Folders"
+msgstr "Сохранённые каталоги"
+
+#: ../../include/contact_widgets.php:56 ../../include/contact_widgets.php:99
+#: ../../include/contact_widgets.php:142 ../../include/contact_widgets.php:187
+#: ../../Zotlabs/Widget/Filer.php:31 ../../Zotlabs/Widget/Appcategories.php:46
+msgid "Everything"
+msgstr "Всё"
+
+#: ../../include/contact_widgets.php:96 ../../include/contact_widgets.php:139
+#: ../../include/contact_widgets.php:184 ../../include/taxonomy.php:409
+#: ../../include/taxonomy.php:491 ../../include/taxonomy.php:511
+#: ../../include/taxonomy.php:532 ../../Zotlabs/Widget/Appcategories.php:43
+msgid "Categories"
+msgstr "Категории"
+
+#: ../../include/contact_widgets.php:218
+msgid "Common Connections"
+msgstr "Общие контакты"
+
+#: ../../include/contact_widgets.php:222
+#, php-format
+msgid "View all %d common connections"
+msgstr "Просмотреть все %d общих контактов"
+
+#: ../../include/menu.php:118 ../../include/channel.php:1411
+#: ../../include/channel.php:1415 ../../Zotlabs/Storage/Browser.php:296
+#: ../../Zotlabs/Module/Oauth.php:173 ../../Zotlabs/Module/Oauth2.php:194
+#: ../../Zotlabs/Module/Editlayout.php:114
+#: ../../Zotlabs/Module/Editblock.php:114 ../../Zotlabs/Module/Menu.php:175
+#: ../../Zotlabs/Module/Admin/Profs.php:175
+#: ../../Zotlabs/Module/Editwebpage.php:142 ../../Zotlabs/Module/Thing.php:266
+#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Group.php:252
+#: ../../Zotlabs/Module/Connections.php:298
+#: ../../Zotlabs/Module/Connections.php:336
+#: ../../Zotlabs/Module/Connections.php:356
+#: ../../Zotlabs/Module/Card_edit.php:99
+#: ../../Zotlabs/Module/Article_edit.php:99 ../../Zotlabs/Module/Blocks.php:160
+#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384
+#: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Widget/Cdav.php:126
+#: ../../Zotlabs/Widget/Cdav.php:162 ../../Zotlabs/Lib/Apps.php:558
+#: ../../Zotlabs/Lib/ThreadItem.php:147
msgid "Edit"
msgstr "Изменить"
-#: ../../Zotlabs/Module/Blocks.php:161 ../../Zotlabs/Module/Photos.php:1117
-#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Layouts.php:194
-#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Widget/Cdav.php:124
-#: ../../addon/hsse/hsse.php:186 ../../include/conversation.php:1392
-msgid "Share"
-msgstr "Поделиться"
+#: ../../include/channel.php:43
+msgid "Unable to obtain identity information from database"
+msgstr "Невозможно получить идентификационную информацию из базы данных"
+
+#: ../../include/channel.php:76
+msgid "Empty name"
+msgstr "Пустое имя"
+
+#: ../../include/channel.php:79
+msgid "Name too long"
+msgstr "Слишком длинное имя"
+
+#: ../../include/channel.php:196
+msgid "No account identifier"
+msgstr "Идентификатор аккаунта отсутствует"
+
+#: ../../include/channel.php:208
+msgid "Nickname is required."
+msgstr "Требуется псевдоним."
+
+#: ../../include/channel.php:222 ../../include/channel.php:655
+#: ../../Zotlabs/Module/Changeaddr.php:46
+msgid "Reserved nickname. Please choose another."
+msgstr "Зарезервированый псевдоним. Пожалуйста, выберите другой."
+
+#: ../../include/channel.php:227 ../../include/channel.php:660
+#: ../../Zotlabs/Module/Changeaddr.php:51
+msgid ""
+"Nickname has unsupported characters or is already being used on this site."
+msgstr "Псевдоним имеет недопустимые символы или уже используется на этом сайте."
+
+#: ../../include/channel.php:287
+msgid "Unable to retrieve created identity"
+msgstr "Не удается получить созданный идентификатор"
+
+#: ../../include/channel.php:429
+msgid "Default Profile"
+msgstr "Профиль по умолчанию"
+
+#: ../../include/channel.php:588 ../../include/channel.php:677
+msgid "Unable to retrieve modified identity"
+msgstr "Не удается найти изменённый идентификатор"
+
+#: ../../include/channel.php:1266
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:306
+msgid "Requested channel is not available."
+msgstr "Запрошенный канал не доступен."
+
+#: ../../include/channel.php:1312 ../../Zotlabs/Module/Achievements.php:15
+#: ../../Zotlabs/Module/Profile.php:20 ../../Zotlabs/Module/Editlayout.php:31
+#: ../../Zotlabs/Module/Filestorage.php:53
+#: ../../Zotlabs/Module/Editblock.php:31 ../../Zotlabs/Module/Menu.php:91
+#: ../../Zotlabs/Module/Hcard.php:12 ../../Zotlabs/Module/Editwebpage.php:32
+#: ../../Zotlabs/Module/Webpages.php:39 ../../Zotlabs/Module/Blocks.php:33
+#: ../../Zotlabs/Module/Articles.php:42 ../../Zotlabs/Module/Connect.php:17
+#: ../../Zotlabs/Module/Cards.php:42 ../../Zotlabs/Module/Layouts.php:31
+#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:49
+msgid "Requested profile is not available."
+msgstr "Запрашиваемый профиль не доступен."
+
+#: ../../include/channel.php:1404 ../../Zotlabs/Module/Profiles.php:728
+msgid "Change profile photo"
+msgstr "Изменить фотографию профиля"
+
+#: ../../include/channel.php:1411 ../../include/nav.php:113
+#: ../../Zotlabs/Module/Profiles.php:830
+msgid "Edit Profiles"
+msgstr "Редактирование профилей"
+
+#: ../../include/channel.php:1412
+msgid "Create New Profile"
+msgstr "Создать новый профиль"
+
+#: ../../include/channel.php:1415 ../../include/nav.php:115
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:58
+msgid "Edit Profile"
+msgstr "Редактировать профиль"
+
+#: ../../include/channel.php:1430 ../../Zotlabs/Module/Profiles.php:820
+msgid "Profile Image"
+msgstr "Изображение профиля"
+
+#: ../../include/channel.php:1433
+msgid "Visible to everybody"
+msgstr "Видно всем"
+
+#: ../../include/channel.php:1434 ../../Zotlabs/Module/Profiles.php:725
+#: ../../Zotlabs/Module/Profiles.php:824
+msgid "Edit visibility"
+msgstr "Редактировать видимость"
+
+#: ../../include/channel.php:1491 ../../include/conversation.php:1058
+#: ../../include/connections.php:110 ../../Zotlabs/Module/Directory.php:342
+#: ../../Zotlabs/Module/Suggest.php:71 ../../Zotlabs/Widget/Suggestions.php:46
+#: ../../Zotlabs/Widget/Follow.php:32
+msgid "Connect"
+msgstr "Подключить"
+
+#: ../../include/channel.php:1506 ../../include/event.php:58
+#: ../../include/event.php:90 ../../Zotlabs/Module/Directory.php:328
+msgid "Location:"
+msgstr "Местоположение:"
+
+#: ../../include/channel.php:1510 ../../include/channel.php:1638
+msgid "Gender:"
+msgstr "Пол:"
+
+#: ../../include/channel.php:1511 ../../include/channel.php:1682
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:157
+msgid "Status:"
+msgstr "Статус:"
+
+#: ../../include/channel.php:1512 ../../include/channel.php:1706
+msgid "Homepage:"
+msgstr "Домашняя страница:"
+
+#: ../../include/channel.php:1513
+msgid "Online Now"
+msgstr "Сейчас в сети"
+
+#: ../../include/channel.php:1566
+msgid "Change your profile photo"
+msgstr "Изменить фотографию вашего профиля"
+
+#: ../../include/channel.php:1597
+msgid "Trans"
+msgstr "Трансексуал"
+
+#: ../../include/channel.php:1636 ../../Zotlabs/Module/Settings/Channel.php:499
+msgid "Full Name:"
+msgstr "Полное имя:"
+
+#: ../../include/channel.php:1643
+msgid "Like this channel"
+msgstr "нравится этот канал"
+
+#: ../../include/channel.php:1654 ../../include/conversation.php:1702
+#: ../../include/taxonomy.php:659 ../../Zotlabs/Module/Photos.php:1177
+#: ../../Zotlabs/Lib/ThreadItem.php:235
+msgctxt "noun"
+msgid "Like"
+msgid_plural "Likes"
+msgstr[0] "Нравится"
+msgstr[1] "Нравится"
+msgstr[2] "Нравится"
+
+#: ../../include/channel.php:1667
+msgid "j F, Y"
+msgstr ""
+
+#: ../../include/channel.php:1668
+msgid "j F"
+msgstr ""
+
+#: ../../include/channel.php:1675
+msgid "Birthday:"
+msgstr "День рождения:"
+
+#: ../../include/channel.php:1679 ../../Zotlabs/Module/Directory.php:323
+msgid "Age:"
+msgstr "Возраст:"
+
+#: ../../include/channel.php:1688
+#, php-format
+msgid "for %1$d %2$s"
+msgstr "для %1$d %2$s"
+
+#: ../../include/channel.php:1700
+msgid "Tags:"
+msgstr "Теги:"
+
+#: ../../include/channel.php:1704
+msgid "Sexual Preference:"
+msgstr "Сексуальные предпочтения:"
+
+#: ../../include/channel.php:1708 ../../Zotlabs/Module/Directory.php:339
+msgid "Hometown:"
+msgstr "Родной город:"
+
+#: ../../include/channel.php:1710
+msgid "Political Views:"
+msgstr "Политические взгляды:"
+
+#: ../../include/channel.php:1712
+msgid "Religion:"
+msgstr "Религия:"
+
+#: ../../include/channel.php:1714 ../../Zotlabs/Module/Directory.php:341
+msgid "About:"
+msgstr "О себе:"
+
+#: ../../include/channel.php:1716
+msgid "Hobbies/Interests:"
+msgstr "Хобби / интересы:"
+
+#: ../../include/channel.php:1718
+msgid "Likes:"
+msgstr "Что вам нравится:"
+
+#: ../../include/channel.php:1720
+msgid "Dislikes:"
+msgstr "Что вам не нравится:"
+
+#: ../../include/channel.php:1722
+msgid "Contact information and Social Networks:"
+msgstr "Контактная информация и социальные сети:"
+
+#: ../../include/channel.php:1724
+msgid "My other channels:"
+msgstr "Мои другие каналы:"
+
+#: ../../include/channel.php:1726
+msgid "Musical interests:"
+msgstr "Музыкальные интересы:"
+
+#: ../../include/channel.php:1728
+msgid "Books, literature:"
+msgstr "Книги, литература:"
+
+#: ../../include/channel.php:1730
+msgid "Television:"
+msgstr "Телевидение:"
+
+#: ../../include/channel.php:1732
+msgid "Film/dance/culture/entertainment:"
+msgstr "Кино / танцы / культура / развлечения:"
+
+#: ../../include/channel.php:1734
+msgid "Love/Romance:"
+msgstr "Любовь / романтика:"
+
+#: ../../include/channel.php:1736
+msgid "Work/employment:"
+msgstr "Работа / занятость:"
+
+#: ../../include/channel.php:1738
+msgid "School/education:"
+msgstr "Школа / образование:"
+
+#: ../../include/channel.php:1759 ../../Zotlabs/Module/Profperm.php:113
+#: ../../Zotlabs/Lib/Apps.php:361
+msgid "Profile"
+msgstr "Профиль"
+
+#: ../../include/channel.php:1761
+msgid "Like this thing"
+msgstr "нравится этo"
+
+#: ../../include/channel.php:1762 ../../Zotlabs/Module/Events.php:692
+#: ../../Zotlabs/Module/Cal.php:340
+msgid "Export"
+msgstr "Экспорт"
+
+#: ../../include/channel.php:2197 ../../Zotlabs/Module/Cover_photo.php:305
+msgid "cover photo"
+msgstr "фотография обложки"
+
+#: ../../include/channel.php:2465 ../../boot.php:1630
+#: ../../Zotlabs/Module/Rmagic.php:93
+msgid "Remote Authentication"
+msgstr "Удаленная аутентификация"
+
+#: ../../include/channel.php:2466 ../../Zotlabs/Module/Rmagic.php:94
+msgid "Enter your channel address (e.g. channel@example.com)"
+msgstr "Введите адрес вашего канала (например: channel@example.com)"
+
+#: ../../include/channel.php:2467 ../../Zotlabs/Module/Rmagic.php:95
+msgid "Authenticate"
+msgstr "Проверка подлинности"
+
+#: ../../include/channel.php:2622 ../../Zotlabs/Module/Admin/Accounts.php:91
+#, php-format
+msgid "Account '%s' deleted"
+msgstr "Аккаунт '%s' удален"
+
+#: ../../include/message.php:13 ../../include/text.php:1770
+msgid "Download binary/encrypted content"
+msgstr "Загрузить двоичное / зашифрованное содержимое"
+
+#: ../../include/message.php:41
+msgid "Unable to determine sender."
+msgstr "Невозможно определить отправителя."
+
+#: ../../include/message.php:80
+msgid "No recipient provided."
+msgstr "Получатель не предоставлен."
+
+#: ../../include/message.php:85
+msgid "[no subject]"
+msgstr "[без темы]"
+
+#: ../../include/message.php:215
+msgid "Stored post could not be verified."
+msgstr "Сохранённая публикация не может быть проверена."
+
+#: ../../include/markdown.php:198 ../../include/bbcode.php:367
+#, php-format
+msgid "%1$s wrote the following %2$s %3$s"
+msgstr "%1$s была создана %2$s %3$s"
+
+#: ../../include/markdown.php:200 ../../include/bbcode.php:363
+#: ../../Zotlabs/Module/Tagger.php:77
+msgid "post"
+msgstr "публикация"
+
+#: ../../include/items.php:416 ../../Zotlabs/Module/Dreport.php:10
+#: ../../Zotlabs/Module/Dreport.php:82 ../../Zotlabs/Module/Share.php:71
+#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Like.php:301
+#: ../../Zotlabs/Module/Subthread.php:86 ../../Zotlabs/Module/Group.php:98
+#: ../../Zotlabs/Module/Cloud.php:126 ../../Zotlabs/Module/Import_items.php:120
+#: ../../Zotlabs/Web/WebServer.php:122
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:119
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:109
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:75
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:82
+msgid "Permission denied"
+msgstr "Доступ запрещен"
+
+#: ../../include/items.php:965 ../../include/items.php:1025
+msgid "(Unknown)"
+msgstr "(Неизвестный)"
+
+#: ../../include/items.php:1213
+msgid "Visible to anybody on the internet."
+msgstr "Виден всем в интернете."
+
+#: ../../include/items.php:1215
+msgid "Visible to you only."
+msgstr "Видно только вам."
+
+#: ../../include/items.php:1217
+msgid "Visible to anybody in this network."
+msgstr "Видно всем в этой сети."
+
+#: ../../include/items.php:1219
+msgid "Visible to anybody authenticated."
+msgstr "Видно всем аутентифицированным."
+
+#: ../../include/items.php:1221
+#, php-format
+msgid "Visible to anybody on %s."
+msgstr "Видно всем в %s."
+
+#: ../../include/items.php:1223
+msgid "Visible to all connections."
+msgstr "Видно всем контактам."
+
+#: ../../include/items.php:1225
+msgid "Visible to approved connections."
+msgstr "Видно только одобренным контактам."
+
+#: ../../include/items.php:1227
+msgid "Visible to specific connections."
+msgstr "Видно указанным контактам."
+
+#: ../../include/items.php:3713 ../../Zotlabs/Module/Display.php:45
+#: ../../Zotlabs/Module/Display.php:455 ../../Zotlabs/Module/Admin.php:62
+#: ../../Zotlabs/Module/Filestorage.php:26 ../../Zotlabs/Module/Viewsrc.php:25
+#: ../../Zotlabs/Module/Admin/Addons.php:259
+#: ../../Zotlabs/Module/Admin/Themes.php:72 ../../Zotlabs/Module/Thing.php:94
+msgid "Item not found."
+msgstr "Элемент не найден."
+
+#: ../../include/items.php:4295 ../../Zotlabs/Module/Group.php:61
+#: ../../Zotlabs/Module/Group.php:213
+msgid "Privacy group not found."
+msgstr "Группа безопасности не найдена."
+
+#: ../../include/items.php:4311
+msgid "Privacy group is empty."
+msgstr "Группа безопасности пуста"
+
+#: ../../include/items.php:4318
+#, php-format
+msgid "Privacy group: %s"
+msgstr "Группа безопасности: %s"
+
+#: ../../include/items.php:4328 ../../Zotlabs/Module/Connedit.php:867
+#, php-format
+msgid "Connection: %s"
+msgstr "Контакт: %s"
+
+#: ../../include/items.php:4330
+msgid "Connection not found."
+msgstr "Контакт не найден."
+
+#: ../../include/items.php:4672 ../../Zotlabs/Module/Cover_photo.php:298
+msgid "female"
+msgstr "женщина"
+
+#: ../../include/items.php:4673 ../../Zotlabs/Module/Cover_photo.php:299
+#, php-format
+msgid "%1$s updated her %2$s"
+msgstr "%1$s обновила её %2$s"
+
+#: ../../include/items.php:4674 ../../Zotlabs/Module/Cover_photo.php:300
+msgid "male"
+msgstr "мужчина"
+
+#: ../../include/items.php:4675 ../../Zotlabs/Module/Cover_photo.php:301
+#, php-format
+msgid "%1$s updated his %2$s"
+msgstr "%1$s обновил его %2$s"
+
+#: ../../include/items.php:4677 ../../Zotlabs/Module/Cover_photo.php:303
+#, php-format
+msgid "%1$s updated their %2$s"
+msgstr "%2$s %1$s обновлена"
+
+#: ../../include/items.php:4679
+msgid "profile photo"
+msgstr "Фотография профиля"
+
+#: ../../include/items.php:4871
+#, php-format
+msgid "[Edited %s]"
+msgstr "[Отредактировано %s]"
+
+#: ../../include/items.php:4871
+msgctxt "edit_activity"
+msgid "Post"
+msgstr "Публикация"
+
+#: ../../include/items.php:4871
+msgctxt "edit_activity"
+msgid "Comment"
+msgstr "Комментарий"
+
+#: ../../include/activities.php:42
+msgid " and "
+msgstr " и "
+
+#: ../../include/activities.php:50
+msgid "public profile"
+msgstr "общедоступный профиль"
+
+#: ../../include/activities.php:59
+#, php-format
+msgid "%1$s changed %2$s to &ldquo;%3$s&rdquo;"
+msgstr "%1$s изменил %2$s на &ldquo;%3$s&rdquo;"
+
+#: ../../include/activities.php:60
+#, php-format
+msgid "Visit %1$s's %2$s"
+msgstr "Посетить %1$s %2$s"
+
+#: ../../include/activities.php:63
+#, php-format
+msgid "%1$s has an updated %2$s, changing %3$s."
+msgstr "%1$s обновлено %2$s, изменено %3$s."
+
+#: ../../include/features.php:55 ../../Zotlabs/Module/Settings/Features.php:36
+#: ../../Zotlabs/Module/Admin/Features.php:55
+#: ../../Zotlabs/Module/Admin/Features.php:56
+msgid "Off"
+msgstr "Выкл."
+
+#: ../../include/features.php:55 ../../Zotlabs/Module/Settings/Features.php:36
+#: ../../Zotlabs/Module/Admin/Features.php:55
+#: ../../Zotlabs/Module/Admin/Features.php:56
+msgid "On"
+msgstr "Вкл."
+
+#: ../../include/features.php:82 ../../Zotlabs/Lib/Apps.php:366
+msgid "CalDAV"
+msgstr ""
+
+#: ../../include/features.php:86 ../../include/features.php:273
+msgid "Start calendar week on Monday"
+msgstr "Начинать календарную неделю с понедельника"
+
+#: ../../include/features.php:87 ../../include/features.php:274
+msgid "Default is Sunday"
+msgstr "По умолчанию - воскресенье"
+
+#: ../../include/features.php:96 ../../Zotlabs/Lib/Apps.php:342
+msgid "Channel Home"
+msgstr "Главная канала"
+
+#: ../../include/features.php:100
+msgid "Search by Date"
+msgstr "Поиск по дате"
+
+#: ../../include/features.php:101
+msgid "Ability to select posts by date ranges"
+msgstr "Возможность выбора сообщений по диапазонам дат"
+
+#: ../../include/features.php:108
+msgid "Tag Cloud"
+msgstr "Облако тегов"
+
+#: ../../include/features.php:109
+msgid "Provide a personal tag cloud on your channel page"
+msgstr "Показывает личное облако тегов на странице канала"
+
+#: ../../include/features.php:116 ../../include/features.php:365
+msgid "Use blog/list mode"
+msgstr "Использовать режим блога / списка"
+
+#: ../../include/features.php:117 ../../include/features.php:366
+msgid "Comments will be displayed separately"
+msgstr "Комментарии будут отображаться отдельно"
+
+#: ../../include/features.php:125 ../../include/text.php:991
+#: ../../Zotlabs/Module/Connections.php:348 ../../Zotlabs/Lib/Apps.php:332
+msgid "Connections"
+msgstr "Контакты"
+
+#: ../../include/features.php:129
+msgid "Connection Filtering"
+msgstr "Фильтрация контактов"
+
+#: ../../include/features.php:130
+msgid "Filter incoming posts from connections based on keywords/content"
+msgstr "Фильтр входящих сообщений от контактов на основе ключевых слов / контента"
+
+#: ../../include/features.php:138
+msgid "Conversation"
+msgstr "Диалоги"
+
+#: ../../include/features.php:142
+msgid "Community Tagging"
+msgstr "Отметки сообщества"
+
+#: ../../include/features.php:143
+msgid "Ability to tag existing posts"
+msgstr "Возможность помечать тегами существующие публикации"
+
+#: ../../include/features.php:150
+msgid "Emoji Reactions"
+msgstr "Реакции Emoji"
+
+#: ../../include/features.php:151
+msgid "Add emoji reaction ability to posts"
+msgstr "Возможность добавлять реакции Emoji к публикациям"
+
+#: ../../include/features.php:158
+msgid "Dislike Posts"
+msgstr "Не нравящиеся публикации"
+
+#: ../../include/features.php:159
+msgid "Ability to dislike posts/comments"
+msgstr "Возможность отмечать не нравящиеся публикации / комментарии"
+
+#: ../../include/features.php:166
+msgid "Star Posts"
+msgstr "Помечать сообщения"
+
+#: ../../include/features.php:167
+msgid "Ability to mark special posts with a star indicator"
+msgstr "Возможность отметить специальные сообщения индикатором-звёздочкой"
+
+#: ../../include/features.php:176 ../../Zotlabs/Lib/Apps.php:346
+msgid "Directory"
+msgstr "Каталог"
+
+#: ../../include/features.php:180
+msgid "Advanced Directory Search"
+msgstr "Расширенный поиск в каталоге"
+
+#: ../../include/features.php:181
+msgid "Allows creation of complex directory search queries"
+msgstr "Позволяет создание сложных поисковых запросов в каталоге"
+
+#: ../../include/features.php:190
+msgid "Editor"
+msgstr "Редактор"
+
+#: ../../include/features.php:194
+msgid "Post Categories"
+msgstr "Категории публикаций"
+
+#: ../../include/features.php:195
+msgid "Add categories to your posts"
+msgstr "Добавить категории для ваших публикаций"
+
+#: ../../include/features.php:203
+msgid "Large Photos"
+msgstr "Большие фотографии"
+
+#: ../../include/features.php:204
+msgid ""
+"Include large (1024px) photo thumbnails in posts. If not enabled, use small "
+"(640px) photo thumbnails"
+msgstr "Включить большие (1024px) миниатюры изображений в публикациях. Если не включено, использовать маленькие (640px) миниатюры."
+
+#: ../../include/features.php:211
+msgid "Even More Encryption"
+msgstr "Еще больше шифрования"
+
+#: ../../include/features.php:212
+msgid ""
+"Allow optional encryption of content end-to-end with a shared secret key"
+msgstr "Разрешить дополнительное end-to-end шифрование содержимого с общим секретным ключом"
+
+#: ../../include/features.php:219
+msgid "Enable Voting Tools"
+msgstr "Включить инструменты голосования"
+
+#: ../../include/features.php:220
+msgid "Provide a class of post which others can vote on"
+msgstr "Предоставь класс публикаций с возможностью голосования"
+
+#: ../../include/features.php:227
+msgid "Disable Comments"
+msgstr "Отключить комментарии"
+
+#: ../../include/features.php:228
+msgid "Provide the option to disable comments for a post"
+msgstr "Предоставить возможность отключать комментарии для публикаций"
+
+#: ../../include/features.php:235
+msgid "Delayed Posting"
+msgstr "Задержанная публикация"
+
+#: ../../include/features.php:236
+msgid "Allow posts to be published at a later date"
+msgstr "Разрешить размешать публикации следующими датами"
+
+#: ../../include/features.php:243
+msgid "Content Expiration"
+msgstr "Истечение срока действия содержимого"
+
+#: ../../include/features.php:244
+msgid "Remove posts/comments and/or private messages at a future time"
+msgstr "Удалять публикации / комментарии и / или личные сообщения"
+
+#: ../../include/features.php:251
+msgid "Suppress Duplicate Posts/Comments"
+msgstr "Подавлять дублирующие публикации / комментарии"
+
+#: ../../include/features.php:252
+msgid ""
+"Prevent posts with identical content to be published with less than two "
+"minutes in between submissions."
+msgstr "Предотвращает появление публикаций с одинаковым содержимым если интервал между ними менее 2 минут"
+
+#: ../../include/features.php:259
+msgid "Auto-save drafts of posts and comments"
+msgstr "Автоматически сохранять черновики публикаций и комментариев"
+
+#: ../../include/features.php:260
+msgid ""
+"Automatically saves post and comment drafts in local browser storage to help "
+"prevent accidental loss of compositions"
+msgstr "Автоматически сохраняет черновики публикаций и комментариев в локальном хранилище браузера для предотвращения их случайной утраты"
+
+#: ../../include/features.php:269 ../../Zotlabs/Lib/Apps.php:345
+msgid "Events"
+msgstr "События"
+
+#: ../../include/features.php:281
+msgid "Smart Birthdays"
+msgstr "\"Умные\" Дни рождений"
+
+#: ../../include/features.php:282
+msgid ""
+"Make birthday events timezone aware in case your friends are scattered "
+"across the planet."
+msgstr "Сделать уведомления о днях рождения зависимыми от часового пояса в том случае, если ваши друзья разбросаны по планете."
+
+#: ../../include/features.php:289
+msgid "Event Timezone Selection"
+msgstr "Выбор часового пояса события"
+
+#: ../../include/features.php:290
+msgid "Allow event creation in timezones other than your own."
+msgstr "Разрешить создание события в часовой зоне отличной от вашей"
+
+#: ../../include/features.php:299
+msgid "Manage"
+msgstr "Управление"
+
+#: ../../include/features.php:303
+msgid "Navigation Channel Select"
+msgstr "Выбор канала навигации"
+
+#: ../../include/features.php:304
+msgid "Change channels directly from within the navigation dropdown menu"
+msgstr "Изменить канал напрямую из выпадающего меню"
+
+#: ../../include/features.php:313 ../../Zotlabs/Module/Connections.php:310
+msgid "Network"
+msgstr "Сеть"
+
+#: ../../include/features.php:317 ../../Zotlabs/Widget/Savedsearch.php:83
+msgid "Saved Searches"
+msgstr "Сохранённые поиски"
+
+#: ../../include/features.php:318
+msgid "Save search terms for re-use"
+msgstr "Сохранять результаты поиска для повторного использования"
+
+#: ../../include/features.php:326
+msgid "Ability to file posts under folders"
+msgstr "Возможность размещать публикации в каталогах"
+
+#: ../../include/features.php:333
+msgid "Alternate Stream Order"
+msgstr "Отображение потока"
+
+#: ../../include/features.php:334
+msgid ""
+"Ability to order the stream by last post date, last comment date or "
+"unthreaded activities"
+msgstr "Возможность показывать поток по дате последнего сообщения, последнего комментария или в порядке поступления"
+
+#: ../../include/features.php:341
+msgid "Contact Filter"
+msgstr "Фильтр контактов"
+
+#: ../../include/features.php:342
+msgid "Ability to display only posts of a selected contact"
+msgstr "Возможность показа публикаций только от выбранных контактов"
+
+#: ../../include/features.php:349
+msgid "Forum Filter"
+msgstr "Фильтр по форумам"
+
+#: ../../include/features.php:350
+msgid "Ability to display only posts of a specific forum"
+msgstr "Возможность показа публикаций только определённого форума"
+
+#: ../../include/features.php:357
+msgid "Personal Posts Filter"
+msgstr "Персональный фильтр публикаций"
+
+#: ../../include/features.php:358
+msgid "Ability to display only posts that you've interacted on"
+msgstr "Возможность показа только тех публикаций с которыми вы взаимодействовали"
+
+#: ../../include/features.php:375 ../../include/nav.php:446
+#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:344
+msgid "Photos"
+msgstr "Фотографии"
+
+#: ../../include/features.php:379
+msgid "Photo Location"
+msgstr "Местоположение фотографии"
+
+#: ../../include/features.php:380
+msgid "If location data is available on uploaded photos, link this to a map."
+msgstr "Если данные о местоположении доступны на загруженных фотографий, связать их с картой."
+
+#: ../../include/features.php:389 ../../Zotlabs/Lib/Apps.php:362
+msgid "Profiles"
+msgstr "Редактировать профиль"
+
+#: ../../include/features.php:393
+msgid "Advanced Profiles"
+msgstr "Расширенные профили"
+
+#: ../../include/features.php:394
+msgid "Additional profile sections and selections"
+msgstr "Дополнительные секции и выборы профиля"
+
+#: ../../include/features.php:401
+msgid "Profile Import/Export"
+msgstr "Импорт / экспорт профиля"
+
+#: ../../include/features.php:402
+msgid "Save and load profile details across sites/channels"
+msgstr "Сохранение и загрузка настроек профиля на всех сайтах / каналах"
+
+#: ../../include/features.php:409
+msgid "Multiple Profiles"
+msgstr "Несколько профилей"
+
+#: ../../include/features.php:410
+msgid "Ability to create multiple profiles"
+msgstr "Возможность создания нескольких профилей"
+
+#: ../../include/text.php:501
+msgid "prev"
+msgstr "предыдущий"
+
+#: ../../include/text.php:503
+msgid "first"
+msgstr "первый"
+
+#: ../../include/text.php:532
+msgid "last"
+msgstr "последний"
+
+#: ../../include/text.php:535
+msgid "next"
+msgstr "следующий"
+
+#: ../../include/text.php:553
+msgid "older"
+msgstr "старше"
+
+#: ../../include/text.php:555
+msgid "newer"
+msgstr "новее"
+
+#: ../../include/text.php:979
+msgid "No connections"
+msgstr "Нет контактов"
+
+#: ../../include/text.php:1011
+#, php-format
+msgid "View all %s connections"
+msgstr "Просмотреть все %s контактов"
+
+#: ../../include/text.php:1073
+#, php-format
+msgid "Network: %s"
+msgstr "Сеть: %s"
+
+#: ../../include/text.php:1084 ../../include/text.php:1096
+#: ../../include/acl_selectors.php:118 ../../include/nav.php:186
+#: ../../Zotlabs/Module/Search.php:44 ../../Zotlabs/Module/Connections.php:352
+#: ../../Zotlabs/Widget/Sitesearch.php:31
+#: ../../Zotlabs/Widget/Activity_filter.php:151 ../../Zotlabs/Lib/Apps.php:352
+msgid "Search"
+msgstr "Поиск"
+
+#: ../../include/text.php:1085 ../../include/text.php:1097
+#: ../../Zotlabs/Module/Admin/Profs.php:94
+#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Rbmark.php:32
+#: ../../Zotlabs/Module/Rbmark.php:104 ../../Zotlabs/Module/Filer.php:53
+#: ../../Zotlabs/Widget/Notes.php:23
+#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:102
+msgid "Save"
+msgstr "Запомнить"
+
+#: ../../include/text.php:1176 ../../include/text.php:1180
+msgid "poke"
+msgstr "Ткнуть"
+
+#: ../../include/text.php:1176 ../../include/text.php:1180
+#: ../../include/conversation.php:251
+msgid "poked"
+msgstr "ткнут"
+
+#: ../../include/text.php:1181
+msgid "ping"
+msgstr "Пингануть"
+
+#: ../../include/text.php:1181
+msgid "pinged"
+msgstr "Отпингован"
+
+#: ../../include/text.php:1182
+msgid "prod"
+msgstr "Подтолкнуть"
+
+#: ../../include/text.php:1182
+msgid "prodded"
+msgstr "Подтолкнут"
+
+#: ../../include/text.php:1183
+msgid "slap"
+msgstr "Шлёпнуть"
+
+#: ../../include/text.php:1183
+msgid "slapped"
+msgstr "Шлёпнут"
+
+#: ../../include/text.php:1184
+msgid "finger"
+msgstr "Указать"
+
+#: ../../include/text.php:1184
+msgid "fingered"
+msgstr "Указан"
+
+#: ../../include/text.php:1185
+msgid "rebuff"
+msgstr "Дать отпор"
+
+#: ../../include/text.php:1185
+msgid "rebuffed"
+msgstr "Дан отпор"
+
+#: ../../include/text.php:1208
+msgid "happy"
+msgstr "счастливый"
+
+#: ../../include/text.php:1209
+msgid "sad"
+msgstr "грустный"
+
+#: ../../include/text.php:1210
+msgid "mellow"
+msgstr "спокойный"
+
+#: ../../include/text.php:1211
+msgid "tired"
+msgstr "усталый"
+
+#: ../../include/text.php:1212
+msgid "perky"
+msgstr "весёлый"
+
+#: ../../include/text.php:1213
+msgid "angry"
+msgstr "сердитый"
+
+#: ../../include/text.php:1214
+msgid "stupefied"
+msgstr "отупевший"
+
+#: ../../include/text.php:1215
+msgid "puzzled"
+msgstr "недоумевающий"
+
+#: ../../include/text.php:1216
+msgid "interested"
+msgstr "заинтересованный"
+
+#: ../../include/text.php:1217
+msgid "bitter"
+msgstr "едкий"
+
+#: ../../include/text.php:1218
+msgid "cheerful"
+msgstr "бодрый"
+
+#: ../../include/text.php:1219
+msgid "alive"
+msgstr "энергичный"
+
+#: ../../include/text.php:1220
+msgid "annoyed"
+msgstr "раздражённый"
+
+#: ../../include/text.php:1221
+msgid "anxious"
+msgstr "обеспокоенный"
+
+#: ../../include/text.php:1222
+msgid "cranky"
+msgstr "капризный"
+
+#: ../../include/text.php:1223
+msgid "disturbed"
+msgstr "встревоженный"
+
+#: ../../include/text.php:1224
+msgid "frustrated"
+msgstr "разочарованный"
+
+#: ../../include/text.php:1225
+msgid "depressed"
+msgstr "подавленный"
+
+#: ../../include/text.php:1226
+msgid "motivated"
+msgstr "мотивированный"
+
+#: ../../include/text.php:1227
+msgid "relaxed"
+msgstr "расслабленный"
+
+#: ../../include/text.php:1228
+msgid "surprised"
+msgstr "удивленный"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:95
+msgid "Monday"
+msgstr "Понедельник"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:96
+msgid "Tuesday"
+msgstr "Вторник"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:97
+msgid "Wednesday"
+msgstr "Среда"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:98
+msgid "Thursday"
+msgstr "Четверг"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:99
+msgid "Friday"
+msgstr "Пятница"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:100
+msgid "Saturday"
+msgstr "Суббота"
+
+#: ../../include/text.php:1416 ../../include/js_strings.php:94
+msgid "Sunday"
+msgstr "Воскресенье"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:70
+msgid "January"
+msgstr "Январь"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:71
+msgid "February"
+msgstr "Февраль"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:72
+msgid "March"
+msgstr "Март"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:73
+msgid "April"
+msgstr "Апрель"
+
+#: ../../include/text.php:1420
+msgid "May"
+msgstr "Май"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:75
+msgid "June"
+msgstr "Июнь"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:76
+msgid "July"
+msgstr "Июль"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:77
+msgid "August"
+msgstr "Август"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:78
+msgid "September"
+msgstr "Сентябрь"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:79
+msgid "October"
+msgstr "Октябрь"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:80
+msgid "November"
+msgstr "Ноябрь"
+
+#: ../../include/text.php:1420 ../../include/js_strings.php:81
+msgid "December"
+msgstr "Декабрь"
+
+#: ../../include/text.php:1494
+msgid "Unknown Attachment"
+msgstr "Неизвестное вложение"
+
+#: ../../include/text.php:1496 ../../Zotlabs/Storage/Browser.php:293
+#: ../../Zotlabs/Module/Sharedwithme.php:106
+msgid "Size"
+msgstr "Размер"
+
+#: ../../include/text.php:1496 ../../include/feedutils.php:858
+msgid "unknown"
+msgstr "неизвестный"
+
+#: ../../include/text.php:1532
+msgid "remove category"
+msgstr "удалить категорию"
+
+#: ../../include/text.php:1606
+msgid "remove from file"
+msgstr "удалить из файла"
+
+#: ../../include/text.php:1918 ../../Zotlabs/Module/Events.php:663
+#: ../../Zotlabs/Module/Cal.php:314
+msgid "Link to Source"
+msgstr "Ссылка на источник"
+
+#: ../../include/text.php:1940 ../../include/language.php:423
+msgid "default"
+msgstr "по умолчанию"
+
+#: ../../include/text.php:1948
+msgid "Page layout"
+msgstr "Шаблон страницы"
+
+#: ../../include/text.php:1948
+msgid "You can create your own with the layouts tool"
+msgstr "Вы можете создать свой собственный с помощью инструмента шаблонов"
+
+#: ../../include/text.php:1958 ../../Zotlabs/Module/Wiki.php:217
+#: ../../Zotlabs/Module/Wiki.php:371 ../../Zotlabs/Widget/Wiki_pages.php:38
+#: ../../Zotlabs/Widget/Wiki_pages.php:95
+msgid "BBcode"
+msgstr ""
+
+#: ../../include/text.php:1959
+msgid "HTML"
+msgstr ""
+
+#: ../../include/text.php:1960 ../../Zotlabs/Module/Wiki.php:217
+#: ../../Zotlabs/Module/Wiki.php:371 ../../Zotlabs/Widget/Wiki_pages.php:38
+#: ../../Zotlabs/Widget/Wiki_pages.php:95
+#: ../../extend/addon/hzaddons/mdpost/mdpost.php:41
+msgid "Markdown"
+msgstr "Разметка Markdown"
+
+#: ../../include/text.php:1961 ../../Zotlabs/Module/Wiki.php:217
+#: ../../Zotlabs/Widget/Wiki_pages.php:38
+#: ../../Zotlabs/Widget/Wiki_pages.php:95
+msgid "Text"
+msgstr "Текст"
+
+#: ../../include/text.php:1962
+msgid "Comanche Layout"
+msgstr "Шаблон Comanche"
+
+#: ../../include/text.php:1967
+msgid "PHP"
+msgstr ""
+
+#: ../../include/text.php:1976
+msgid "Page content type"
+msgstr "Тип содержимого страницы"
+
+#: ../../include/text.php:2096 ../../include/conversation.php:116
+#: ../../Zotlabs/Module/Tagger.php:69 ../../Zotlabs/Module/Like.php:392
+#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Lib/Activity.php:2008
+#: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1508
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1565
+msgid "photo"
+msgstr "фото"
+
+#: ../../include/text.php:2099 ../../include/conversation.php:119
+#: ../../include/event.php:1165 ../../Zotlabs/Module/Tagger.php:73
+#: ../../Zotlabs/Module/Events.php:260 ../../Zotlabs/Module/Like.php:394
+msgid "event"
+msgstr "событие"
+
+#: ../../include/text.php:2102 ../../include/conversation.php:144
+#: ../../Zotlabs/Module/Like.php:392 ../../Zotlabs/Module/Subthread.php:112
+#: ../../Zotlabs/Lib/Activity.php:2008
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1508
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1565
+msgid "status"
+msgstr "статус"
+
+#: ../../include/text.php:2104 ../../include/conversation.php:146
+#: ../../Zotlabs/Module/Tagger.php:79
+msgid "comment"
+msgstr "комментарий"
+
+#: ../../include/text.php:2109
+msgid "activity"
+msgstr "активность"
+
+#: ../../include/text.php:2210
+msgid "a-z, 0-9, -, and _ only"
+msgstr "Только a-z, 0-9, -, и _"
+
+#: ../../include/text.php:2536
+msgid "Design Tools"
+msgstr "Инструменты дизайна"
+
+#: ../../include/text.php:2539 ../../Zotlabs/Module/Blocks.php:154
+msgid "Blocks"
+msgstr "Блокировки"
+
+#: ../../include/text.php:2540 ../../Zotlabs/Module/Menu.php:170
+msgid "Menus"
+msgstr "Меню"
+
+#: ../../include/text.php:2541 ../../Zotlabs/Module/Layouts.php:184
+msgid "Layouts"
+msgstr "Шаблоны"
+
+#: ../../include/text.php:2542
+msgid "Pages"
+msgstr "Страницы"
+
+#: ../../include/text.php:2554 ../../Zotlabs/Module/Cal.php:343
+msgid "Import"
+msgstr "Импортировать"
+
+#: ../../include/text.php:2555
+msgid "Import website..."
+msgstr "Импорт веб-сайта..."
+
+#: ../../include/text.php:2556
+msgid "Select folder to import"
+msgstr "Выбрать каталог для импорта"
+
+#: ../../include/text.php:2557
+msgid "Import from a zipped folder:"
+msgstr "Импортировать из каталога в zip-архиве:"
+
+#: ../../include/text.php:2558
+msgid "Import from cloud files:"
+msgstr "Импортировать из сетевых файлов:"
+
+#: ../../include/text.php:2559
+msgid "/cloud/channel/path/to/folder"
+msgstr ""
+
+#: ../../include/text.php:2560
+msgid "Enter path to website files"
+msgstr "Введите путь к файлам веб-сайта"
+
+#: ../../include/text.php:2561
+msgid "Select folder"
+msgstr "Выбрать каталог"
+
+#: ../../include/text.php:2562
+msgid "Export website..."
+msgstr "Экспорт веб-сайта..."
+
+#: ../../include/text.php:2563
+msgid "Export to a zip file"
+msgstr "Экспортировать в ZIP файл."
+
+#: ../../include/text.php:2564
+msgid "website.zip"
+msgstr ""
+
+#: ../../include/text.php:2565
+msgid "Enter a name for the zip file."
+msgstr "Введите имя для ZIP файла."
+
+#: ../../include/text.php:2566
+msgid "Export to cloud files"
+msgstr "Эскпортировать в сетевые файлы:"
+
+#: ../../include/text.php:2567
+msgid "/path/to/export/folder"
+msgstr ""
+
+#: ../../include/text.php:2568
+msgid "Enter a path to a cloud files destination."
+msgstr "Введите путь к расположению сетевых файлов."
+
+#: ../../include/text.php:2569
+msgid "Specify folder"
+msgstr "Указать каталог"
+
+#: ../../include/text.php:2931 ../../Zotlabs/Storage/Browser.php:131
+msgid "Collection"
+msgstr "Коллекция"
+
+#: ../../include/import.php:26
+msgid "Unable to import a removed channel."
+msgstr "Невозможно импортировать удалённый канал."
+
+#: ../../include/import.php:52
+msgid ""
+"Cannot create a duplicate channel identifier on this system. Import failed."
+msgstr "Не удалось создать дублирующийся идентификатор канала. Импорт невозможен."
+
+#: ../../include/import.php:73
+#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:43
+msgid "Unable to create a unique channel address. Import failed."
+msgstr "Не удалось создать уникальный адрес канала. Импорт не завершен."
+
+#: ../../include/import.php:117
+msgid "Cloned channel not found. Import failed."
+msgstr "Клон канала не найден. Импорт невозможен."
+
+#: ../../include/group.php:22 ../../Zotlabs/Lib/Group.php:28
+msgid ""
+"A deleted group with this name was revived. Existing item permissions "
+"<strong>may</strong> apply to this group and any future members. If this is "
+"not what you intended, please create another group with a different name."
+msgstr "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт <strong>могут</strong> применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем."
+
+#: ../../include/group.php:264 ../../Zotlabs/Lib/Group.php:270
+msgid "Add new connections to this privacy group"
+msgstr "Добавить новые контакты в группу безопасности"
+
+#: ../../include/group.php:298 ../../Zotlabs/Lib/Group.php:302
+msgid "edit"
+msgstr "редактировать"
+
+#: ../../include/group.php:320 ../../include/nav.php:99
+#: ../../Zotlabs/Module/Group.php:141 ../../Zotlabs/Module/Group.php:153
+#: ../../Zotlabs/Widget/Activity_filter.php:41 ../../Zotlabs/Lib/Group.php:324
+#: ../../Zotlabs/Lib/Apps.php:363
+msgid "Privacy Groups"
+msgstr "Группы безопасности"
+
+#: ../../include/group.php:321 ../../Zotlabs/Lib/Group.php:325
+msgid "Edit group"
+msgstr "Редактировать группу"
+
+#: ../../include/group.php:322 ../../Zotlabs/Lib/Group.php:326
+msgid "Add privacy group"
+msgstr "Добавить группу безопасности"
+
+#: ../../include/group.php:323 ../../Zotlabs/Lib/Group.php:327
+msgid "Channels not in any privacy group"
+msgstr "Каналы не включены ни в одну группу безопасности"
+
+#: ../../include/group.php:325 ../../Zotlabs/Widget/Savedsearch.php:84
+#: ../../Zotlabs/Lib/Group.php:329
+msgid "add"
+msgstr "добавить"
+
+#: ../../include/account.php:36
+msgid "Not a valid email address"
+msgstr "Недействительный адрес электронной почты"
+
+#: ../../include/account.php:38
+msgid "Your email domain is not among those allowed on this site"
+msgstr "Домен электронной почты не входит в число тех, которые разрешены на этом сайте"
+
+#: ../../include/account.php:44
+msgid "Your email address is already registered at this site."
+msgstr "Ваш адрес электронной почты уже зарегистрирован на этом сайте."
+
+#: ../../include/account.php:76
+msgid "An invitation is required."
+msgstr "Требуется приглашение."
+
+#: ../../include/account.php:80
+msgid "Invitation could not be verified."
+msgstr "Не удалось проверить приглашение."
+
+#: ../../include/account.php:156
+msgid "Please enter the required information."
+msgstr "Пожалуйста, введите необходимую информацию."
+
+#: ../../include/account.php:223
+msgid "Failed to store account information."
+msgstr "Не удалось сохранить информацию аккаунта."
+
+#: ../../include/account.php:311
+#, php-format
+msgid "Registration confirmation for %s"
+msgstr "Подтверждение регистрации на %s"
+
+#: ../../include/account.php:380
+#, php-format
+msgid "Registration request at %s"
+msgstr "Запрос регистрации на %s"
+
+#: ../../include/account.php:402
+msgid "your registration password"
+msgstr "ваш пароль регистрации"
+
+#: ../../include/account.php:408 ../../include/account.php:471
+#, php-format
+msgid "Registration details for %s"
+msgstr "Регистрационные данные для %s"
+
+#: ../../include/account.php:482
+msgid "Account approved."
+msgstr "Аккаунт утвержден."
+
+#: ../../include/account.php:522
+#, php-format
+msgid "Registration revoked for %s"
+msgstr "Регистрация отозвана для %s"
+
+#: ../../include/account.php:803 ../../include/account.php:805
+msgid "Click here to upgrade."
+msgstr "Нажмите здесь для обновления."
+
+#: ../../include/account.php:811
+msgid "This action exceeds the limits set by your subscription plan."
+msgstr "Это действие превышает ограничения, установленные в вашем плане."
+
+#: ../../include/account.php:816
+msgid "This action is not available under your subscription plan."
+msgstr "Это действие невозможно из-за ограничений в вашем плане."
+
+#: ../../include/zot.php:775
+msgid "Invalid data packet"
+msgstr "Неверный пакет данных"
+
+#: ../../include/zot.php:802 ../../Zotlabs/Lib/Libzot.php:652
+msgid "Unable to verify channel signature"
+msgstr "Невозможно проверить подпись канала"
+
+#: ../../include/zot.php:2611 ../../Zotlabs/Lib/Libsync.php:733
+#, php-format
+msgid "Unable to verify site signature for %s"
+msgstr "Невозможно проверить подпись сайта %s"
+
+#: ../../include/zot.php:4308
+msgid "invalid target signature"
+msgstr "недопустимая целевая подпись"
+
+#: ../../include/follow.php:37
+msgid "Channel is blocked on this site."
+msgstr "Канал блокируется на этом сайте."
+
+#: ../../include/follow.php:42
+msgid "Channel location missing."
+msgstr "Местоположение канала отсутствует."
+
+#: ../../include/follow.php:84
+msgid "Response from remote channel was incomplete."
+msgstr "Ответ удаленного канала неполный."
+
+#: ../../include/follow.php:96
+msgid "Premium channel - please visit:"
+msgstr "Премимум-канал - пожалуйста посетите:"
+
+#: ../../include/follow.php:110
+msgid "Channel was deleted and no longer exists."
+msgstr "Канал удален и больше не существует."
+
+#: ../../include/follow.php:166
+msgid "Remote channel or protocol unavailable."
+msgstr "Удалённый канал или протокол недоступен."
+
+#: ../../include/follow.php:189
+msgid "Channel discovery failed."
+msgstr "Не удалось обнаружить канал."
+
+#: ../../include/follow.php:201
+msgid "Protocol disabled."
+msgstr "Протокол отключен."
+
+#: ../../include/follow.php:212
+msgid "Cannot connect to yourself."
+msgstr "Нельзя подключиться к самому себе."
+
+#: ../../include/help.php:80
+msgid "Help:"
+msgstr "Помощь:"
+
+#: ../../include/help.php:117 ../../include/help.php:125
+#: ../../include/nav.php:172 ../../include/nav.php:322
+#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:347
+msgid "Help"
+msgstr "Помощь"
+
+#: ../../include/help.php:129
+msgid "Not Found"
+msgstr "Не найдено"
+
+#: ../../include/help.php:132 ../../Zotlabs/Module/Display.php:140
+#: ../../Zotlabs/Module/Display.php:157 ../../Zotlabs/Module/Display.php:174
+#: ../../Zotlabs/Module/Display.php:180 ../../Zotlabs/Module/Page.php:136
+#: ../../Zotlabs/Module/Block.php:77 ../../Zotlabs/Web/Router.php:185
+#: ../../Zotlabs/Lib/NativeWikiPage.php:521
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:447
+msgid "Page not found."
+msgstr "Страница не найдена."
+
+#: ../../include/bbcode.php:220 ../../include/bbcode.php:1210
+#: ../../include/bbcode.php:1213 ../../include/bbcode.php:1218
+#: ../../include/bbcode.php:1221 ../../include/bbcode.php:1224
+#: ../../include/bbcode.php:1227 ../../include/bbcode.php:1232
+#: ../../include/bbcode.php:1235 ../../include/bbcode.php:1240
+#: ../../include/bbcode.php:1243 ../../include/bbcode.php:1246
+#: ../../include/bbcode.php:1249
+msgid "Image/photo"
+msgstr "Изображение / фотография"
+
+#: ../../include/bbcode.php:259 ../../include/bbcode.php:1260
+msgid "Encrypted content"
+msgstr "Зашифрованное содержание"
+
+#: ../../include/bbcode.php:275
+#, php-format
+msgid "Install %1$s element %2$s"
+msgstr "Установить %1$s элемент %2$s"
+
+#: ../../include/bbcode.php:279
+#, php-format
+msgid ""
+"This post contains an installable %s element, however you lack permissions "
+"to install it on this site."
+msgstr "Эта публикация содержит устанавливаемый %s элемент, однако у вас нет разрешений для его установки на этом сайте."
+
+#: ../../include/bbcode.php:289 ../../Zotlabs/Module/Impel.php:43
+msgid "webpage"
+msgstr "веб-страница"
+
+#: ../../include/bbcode.php:292 ../../Zotlabs/Module/Impel.php:53
+msgid "layout"
+msgstr "шаблон"
+
+#: ../../include/bbcode.php:295 ../../Zotlabs/Module/Impel.php:48
+msgid "block"
+msgstr "заблокировать"
+
+#: ../../include/bbcode.php:298 ../../Zotlabs/Module/Impel.php:60
+msgid "menu"
+msgstr "меню"
+
+#: ../../include/bbcode.php:359
+msgid "card"
+msgstr "карточка"
+
+#: ../../include/bbcode.php:361
+msgid "article"
+msgstr "статья"
+
+#: ../../include/bbcode.php:444 ../../include/bbcode.php:452
+msgid "Click to open/close"
+msgstr "Нажмите, чтобы открыть/закрыть"
+
+#: ../../include/bbcode.php:452
+msgid "spoiler"
+msgstr "спойлер"
+
+#: ../../include/bbcode.php:465
+msgid "View article"
+msgstr "Просмотр статьи"
+
+#: ../../include/bbcode.php:465
+msgid "View summary"
+msgstr "Просмотр резюме"
+
+#: ../../include/bbcode.php:755 ../../include/bbcode.php:925
+#: ../../Zotlabs/Lib/NativeWikiPage.php:603
+msgid "Different viewers will see this text differently"
+msgstr "Различные зрители увидят этот текст по-разному"
+
+#: ../../include/bbcode.php:1198
+msgid "$1 wrote:"
+msgstr "$1 писал:"
+
+#: ../../include/conversation.php:122 ../../Zotlabs/Module/Like.php:123
+msgid "channel"
+msgstr "канал"
+
+#: ../../include/conversation.php:160 ../../Zotlabs/Module/Like.php:447
+#: ../../Zotlabs/Lib/Activity.php:2043
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1544
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1505
+#, php-format
+msgid "%1$s likes %2$s's %3$s"
+msgstr "%1$s нравится %3$s %2$s"
+
+#: ../../include/conversation.php:163 ../../Zotlabs/Module/Like.php:449
+#: ../../Zotlabs/Lib/Activity.php:2045
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1546
+#, php-format
+msgid "%1$s doesn't like %2$s's %3$s"
+msgstr "%1$s не нравится %2$s %3$s"
+
+#: ../../include/conversation.php:169
+#, php-format
+msgid "likes %1$s's %2$s"
+msgstr "Нравится %1$s %2$s"
+
+#: ../../include/conversation.php:172
+#, php-format
+msgid "doesn't like %1$s's %2$s"
+msgstr "Не нравится %1$s %2$s"
+
+#: ../../include/conversation.php:212
+#, php-format
+msgid "%1$s is now connected with %2$s"
+msgstr "%1$s теперь в контакте с %2$s"
+
+#: ../../include/conversation.php:247
+#, php-format
+msgid "%1$s poked %2$s"
+msgstr "%1$s ткнул %2$s"
+
+#: ../../include/conversation.php:268 ../../Zotlabs/Module/Mood.php:76
+#, php-format
+msgctxt "mood"
+msgid "%1$s is %2$s"
+msgstr "%1$s %2$s"
+
+#: ../../include/conversation.php:483 ../../Zotlabs/Lib/ThreadItem.php:468
+msgid "This is an unsaved preview"
+msgstr "Это несохранённый просмотр"
+
+#: ../../include/conversation.php:619 ../../Zotlabs/Module/Photos.php:1154
+msgctxt "title"
+msgid "Likes"
+msgstr "Нравится"
+
+#: ../../include/conversation.php:619 ../../Zotlabs/Module/Photos.php:1154
+msgctxt "title"
+msgid "Dislikes"
+msgstr "Не нравится"
+
+#: ../../include/conversation.php:620 ../../Zotlabs/Module/Photos.php:1155
+msgctxt "title"
+msgid "Agree"
+msgstr "Согласен"
+
+#: ../../include/conversation.php:620 ../../Zotlabs/Module/Photos.php:1155
+msgctxt "title"
+msgid "Disagree"
+msgstr "Не согласен"
+
+#: ../../include/conversation.php:620 ../../Zotlabs/Module/Photos.php:1155
+msgctxt "title"
+msgid "Abstain"
+msgstr "Воздержался"
+
+#: ../../include/conversation.php:621 ../../Zotlabs/Module/Photos.php:1156
+msgctxt "title"
+msgid "Attending"
+msgstr "Посещаю"
+
+#: ../../include/conversation.php:621 ../../Zotlabs/Module/Photos.php:1156
+msgctxt "title"
+msgid "Not attending"
+msgstr "Не посещаю"
+
+#: ../../include/conversation.php:621 ../../Zotlabs/Module/Photos.php:1156
+msgctxt "title"
+msgid "Might attend"
+msgstr "Возможно посещу"
+
+#: ../../include/conversation.php:690 ../../Zotlabs/Lib/ThreadItem.php:177
+msgid "Select"
+msgstr "Выбрать"
-#: ../../Zotlabs/Module/Blocks.php:162 ../../Zotlabs/Module/Editlayout.php:138
-#: ../../Zotlabs/Module/Cdav.php:942 ../../Zotlabs/Module/Cdav.php:1232
-#: ../../Zotlabs/Module/Article_edit.php:129
-#: ../../Zotlabs/Module/Admin/Accounts.php:175
-#: ../../Zotlabs/Module/Admin/Channels.php:149
-#: ../../Zotlabs/Module/Admin/Profs.php:176 ../../Zotlabs/Module/Thing.php:267
-#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Editblock.php:139
-#: ../../Zotlabs/Module/Connections.php:292
-#: ../../Zotlabs/Module/Photos.php:1220 ../../Zotlabs/Module/Connedit.php:668
-#: ../../Zotlabs/Module/Connedit.php:940 ../../Zotlabs/Module/Profiles.php:800
-#: ../../Zotlabs/Module/Editwebpage.php:167
-#: ../../Zotlabs/Module/Webpages.php:257 ../../Zotlabs/Module/Card_edit.php:129
-#: ../../Zotlabs/Module/Oauth.php:174 ../../Zotlabs/Lib/Apps.php:557
-#: ../../Zotlabs/Lib/ThreadItem.php:167 ../../Zotlabs/Storage/Browser.php:291
#: ../../include/conversation.php:691 ../../include/conversation.php:736
+#: ../../Zotlabs/Storage/Browser.php:297 ../../Zotlabs/Module/Cdav.php:966
+#: ../../Zotlabs/Module/Cdav.php:1259 ../../Zotlabs/Module/Profiles.php:800
+#: ../../Zotlabs/Module/Photos.php:1220 ../../Zotlabs/Module/Oauth.php:174
+#: ../../Zotlabs/Module/Oauth2.php:195 ../../Zotlabs/Module/Editlayout.php:138
+#: ../../Zotlabs/Module/Editblock.php:139
+#: ../../Zotlabs/Module/Admin/Channels.php:149
+#: ../../Zotlabs/Module/Admin/Profs.php:176
+#: ../../Zotlabs/Module/Admin/Accounts.php:175
+#: ../../Zotlabs/Module/Editwebpage.php:167 ../../Zotlabs/Module/Thing.php:267
+#: ../../Zotlabs/Module/Webpages.php:257 ../../Zotlabs/Module/Connedit.php:668
+#: ../../Zotlabs/Module/Connedit.php:940
+#: ../../Zotlabs/Module/Connections.php:306
+#: ../../Zotlabs/Module/Card_edit.php:129
+#: ../../Zotlabs/Module/Article_edit.php:129
+#: ../../Zotlabs/Module/Blocks.php:162 ../../Zotlabs/Lib/Apps.php:559
+#: ../../Zotlabs/Lib/ThreadItem.php:167
msgid "Delete"
msgstr "Удалить"
-#: ../../Zotlabs/Module/Blocks.php:166 ../../Zotlabs/Module/Events.php:695
-#: ../../Zotlabs/Module/Wiki.php:213 ../../Zotlabs/Module/Wiki.php:409
-#: ../../Zotlabs/Module/Layouts.php:198 ../../Zotlabs/Module/Webpages.php:261
-#: ../../Zotlabs/Module/Pubsites.php:60
-msgid "View"
-msgstr "Просмотр"
+#: ../../include/conversation.php:695 ../../Zotlabs/Lib/ThreadItem.php:266
+msgid "Toggle Star Status"
+msgstr "Переключить статус пометки"
-#: ../../Zotlabs/Module/Invite.php:37
-msgid "Total invitation limit exceeded."
-msgstr "Превышено общее количество приглашений."
+#: ../../include/conversation.php:700 ../../Zotlabs/Lib/ThreadItem.php:102
+msgid "Private Message"
+msgstr "Личное сообщение"
-#: ../../Zotlabs/Module/Invite.php:61
+#: ../../include/conversation.php:707 ../../Zotlabs/Lib/ThreadItem.php:277
+msgid "Message signature validated"
+msgstr "Подпись сообщения проверена"
+
+#: ../../include/conversation.php:708 ../../Zotlabs/Lib/ThreadItem.php:278
+msgid "Message signature incorrect"
+msgstr "Подпись сообщения неверная"
+
+#: ../../include/conversation.php:735
+#: ../../Zotlabs/Module/Admin/Accounts.php:173
+#: ../../Zotlabs/Module/Connections.php:320
+msgid "Approve"
+msgstr "Утвердить"
+
+#: ../../include/conversation.php:739
#, php-format
-msgid "%s : Not a valid email address."
-msgstr "%s : Недействительный адрес электронной почты."
+msgid "View %s's profile @ %s"
+msgstr "Просмотреть профиль %s @ %s"
-#: ../../Zotlabs/Module/Invite.php:75
-msgid "Please join us on $Projectname"
-msgstr "Присоединятесь к $Projectname !"
+#: ../../include/conversation.php:759
+msgid "Categories:"
+msgstr "Категории:"
-#: ../../Zotlabs/Module/Invite.php:85
-msgid "Invitation limit exceeded. Please contact your site administrator."
-msgstr "Превышен лимит приглашений. Пожалуйста, свяжитесь с администрацией сайта."
+#: ../../include/conversation.php:760
+msgid "Filed under:"
+msgstr "Хранить под:"
-#: ../../Zotlabs/Module/Invite.php:90
-#: ../../addon/notifyadmin/notifyadmin.php:40
+#: ../../include/conversation.php:766 ../../Zotlabs/Lib/ThreadItem.php:402
#, php-format
-msgid "%s : Message delivery failed."
-msgstr "%s : Доставка сообщения не удалась."
+msgid "from %s"
+msgstr "от %s"
-#: ../../Zotlabs/Module/Invite.php:94
+#: ../../include/conversation.php:769 ../../Zotlabs/Lib/ThreadItem.php:405
#, php-format
-msgid "%d message sent."
-msgid_plural "%d messages sent."
-msgstr[0] "%d сообщение отправлено."
-msgstr[1] "%d сообщения отправлено."
-msgstr[2] "%d сообщений отправлено."
+msgid "last edited: %s"
+msgstr "последнее редактирование: %s"
-#: ../../Zotlabs/Module/Invite.php:110
-msgid "Invite App"
-msgstr "Приложение \"Пригласить\""
+#: ../../include/conversation.php:770 ../../Zotlabs/Lib/ThreadItem.php:406
+#, php-format
+msgid "Expires: %s"
+msgstr "Срок действия: %s"
-#: ../../Zotlabs/Module/Invite.php:110 ../../Zotlabs/Module/Articles.php:51
-#: ../../Zotlabs/Module/Cdav.php:839 ../../Zotlabs/Module/Cdav.php:848
-#: ../../Zotlabs/Module/Permcats.php:62 ../../Zotlabs/Module/Lang.php:17
-#: ../../Zotlabs/Module/Uexport.php:61 ../../Zotlabs/Module/Pubstream.php:20
-#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Tokens.php:99
-#: ../../Zotlabs/Module/Oauth2.php:106 ../../Zotlabs/Module/Randprof.php:29
-#: ../../Zotlabs/Module/Mood.php:134 ../../Zotlabs/Module/Bookmarks.php:78
-#: ../../Zotlabs/Module/Wiki.php:52 ../../Zotlabs/Module/Pdledit.php:42
-#: ../../Zotlabs/Module/Poke.php:165 ../../Zotlabs/Module/Chat.php:102
-#: ../../Zotlabs/Module/Notes.php:56 ../../Zotlabs/Module/Affinity.php:52
-#: ../../Zotlabs/Module/Defperms.php:189 ../../Zotlabs/Module/Group.php:106
-#: ../../Zotlabs/Module/Cards.php:51 ../../Zotlabs/Module/Webpages.php:48
-#: ../../Zotlabs/Module/Sources.php:88 ../../Zotlabs/Module/Suggest.php:40
-#: ../../Zotlabs/Module/Probe.php:18 ../../Zotlabs/Module/Oauth.php:100
-#: ../../addon/skeleton/Mod_Skeleton.php:32
-#: ../../addon/gnusoc/Mod_Gnusoc.php:22 ../../addon/planets/Mod_Planets.php:20
-#: ../../addon/wppost/Mod_Wppost.php:41 ../../addon/nsfw/Mod_Nsfw.php:33
-#: ../../addon/ijpost/Mod_Ijpost.php:35 ../../addon/dwpost/Mod_Dwpost.php:36
-#: ../../addon/gallery/Mod_Gallery.php:58 ../../addon/ljpost/Mod_Ljpost.php:36
-#: ../../addon/startpage/Mod_Startpage.php:50
-#: ../../addon/diaspora/Mod_Diaspora.php:55
-#: ../../addon/photocache/Mod_Photocache.php:42
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:21
-#: ../../addon/nsabait/Mod_Nsabait.php:20
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:34 ../../addon/rtof/Mod_Rtof.php:36
-#: ../../addon/jappixmini/Mod_Jappixmini.php:96
-#: ../../addon/superblock/Mod_Superblock.php:20
-#: ../../addon/nofed/Mod_Nofed.php:33 ../../addon/redred/Mod_Redred.php:50
-#: ../../addon/hsse/Mod_Hsse.php:21 ../../addon/pubcrawl/Mod_Pubcrawl.php:40
-#: ../../addon/libertree/Mod_Libertree.php:35
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:53
-#: ../../addon/statusnet/Mod_Statusnet.php:146
-#: ../../addon/twitter/Mod_Twitter.php:78
-#: ../../addon/smileybutton/Mod_Smileybutton.php:35
-#: ../../addon/sendzid/Mod_Sendzid.php:20
-#: ../../addon/pageheader/Mod_Pageheader.php:34
-#: ../../addon/authchoose/Mod_Authchoose.php:28
-#: ../../addon/xmpp/Mod_Xmpp.php:35 ../../addon/pumpio/Mod_Pumpio.php:53
-msgid "Not Installed"
-msgstr "не установлено"
+#: ../../include/conversation.php:785
+msgid "View in context"
+msgstr "Показать в контексте"
-#: ../../Zotlabs/Module/Invite.php:111
-msgid "Send email invitations to join this network"
-msgstr "Отправить приглашение присоединиться к этой сети по электронной почте"
+#: ../../include/conversation.php:787 ../../Zotlabs/Module/Photos.php:1118
+#: ../../Zotlabs/Lib/ThreadItem.php:469
+msgid "Please wait"
+msgstr "Подождите пожалуйста"
-#: ../../Zotlabs/Module/Invite.php:124
-msgid "You have no more invitations available"
-msgstr "У вас больше нет приглашений"
+#: ../../include/conversation.php:886
+msgid "remove"
+msgstr "удалить"
-#: ../../Zotlabs/Module/Invite.php:155
-msgid "Send invitations"
-msgstr "Отправить приглашение"
+#: ../../include/conversation.php:890
+msgid "Loading..."
+msgstr "Загрузка..."
-#: ../../Zotlabs/Module/Invite.php:156
-msgid "Enter email addresses, one per line:"
-msgstr "Введите адреса электронной почты, по одному в строке:"
+#: ../../include/conversation.php:891 ../../Zotlabs/Lib/ThreadItem.php:290
+msgid "Conversation Tools"
+msgstr "Инструменты общения"
-#: ../../Zotlabs/Module/Invite.php:157 ../../Zotlabs/Module/Mail.php:285
-msgid "Your message:"
-msgstr "Сообщение:"
+#: ../../include/conversation.php:892
+msgid "Delete Selected Items"
+msgstr "Удалить выбранные элементы"
-#: ../../Zotlabs/Module/Invite.php:158
-msgid "Please join my community on $Projectname."
-msgstr "Присоединятесь к нашему сообществу $Projectname !"
+#: ../../include/conversation.php:935
+msgid "View Source"
+msgstr "Просмотреть источник"
-#: ../../Zotlabs/Module/Invite.php:160
-msgid "You will need to supply this invitation code:"
-msgstr "Вам нужно предоставит этот код приглашения:"
+#: ../../include/conversation.php:945
+msgid "Follow Thread"
+msgstr "Следить за темой"
-#: ../../Zotlabs/Module/Invite.php:161
-msgid "1. Register at any $Projectname location (they are all inter-connected)"
-msgstr "1. Зарегистрируйтесь на любом из серверов $Projectname"
+#: ../../include/conversation.php:954
+msgid "Unfollow Thread"
+msgstr "Прекратить отслеживать тему"
-#: ../../Zotlabs/Module/Invite.php:163
-msgid "2. Enter my $Projectname network address into the site searchbar."
-msgstr "2. Введите сетевой адрес $Projectname в поисковой строке сайта"
+#: ../../include/conversation.php:1038 ../../include/nav.php:110
+#: ../../Zotlabs/Module/Connedit.php:608 ../../Zotlabs/Lib/Apps.php:343
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:57
+msgid "View Profile"
+msgstr "Просмотреть профиль"
-#: ../../Zotlabs/Module/Invite.php:164
-msgid "or visit"
-msgstr "или посетите"
+#: ../../include/conversation.php:1048 ../../Zotlabs/Module/Connedit.php:629
+msgid "Recent Activity"
+msgstr "Последние действия"
-#: ../../Zotlabs/Module/Invite.php:166
-msgid "3. Click [Connect]"
-msgstr "Нажать [Подключиться]"
+#: ../../include/conversation.php:1068
+msgid "Edit Connection"
+msgstr "Редактировать контакт"
-#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Permcats.php:128
-#: ../../Zotlabs/Module/Locs.php:121 ../../Zotlabs/Module/Mitem.php:259
-#: ../../Zotlabs/Module/Events.php:495 ../../Zotlabs/Module/Appman.php:155
-#: ../../Zotlabs/Module/Import_items.php:129 ../../Zotlabs/Module/Setup.php:308
-#: ../../Zotlabs/Module/Setup.php:349 ../../Zotlabs/Module/Connect.php:124
-#: ../../Zotlabs/Module/Admin/Features.php:66
-#: ../../Zotlabs/Module/Admin/Accounts.php:168
-#: ../../Zotlabs/Module/Admin/Logs.php:84
-#: ../../Zotlabs/Module/Admin/Channels.php:147
-#: ../../Zotlabs/Module/Admin/Themes.php:158
-#: ../../Zotlabs/Module/Admin/Site.php:289
-#: ../../Zotlabs/Module/Admin/Addons.php:441
-#: ../../Zotlabs/Module/Admin/Profs.php:178
-#: ../../Zotlabs/Module/Admin/Account_edit.php:73
-#: ../../Zotlabs/Module/Admin/Security.php:112
-#: ../../Zotlabs/Module/Settings/Channel.php:493
-#: ../../Zotlabs/Module/Settings/Features.php:46
-#: ../../Zotlabs/Module/Settings/Events.php:41
-#: ../../Zotlabs/Module/Settings/Calendar.php:41
-#: ../../Zotlabs/Module/Settings/Conversation.php:48
-#: ../../Zotlabs/Module/Settings/Connections.php:41
-#: ../../Zotlabs/Module/Settings/Photos.php:41
-#: ../../Zotlabs/Module/Settings/Account.php:103
-#: ../../Zotlabs/Module/Settings/Profiles.php:50
-#: ../../Zotlabs/Module/Settings/Manage.php:41
-#: ../../Zotlabs/Module/Settings/Channel_home.php:89
-#: ../../Zotlabs/Module/Settings/Directory.php:41
-#: ../../Zotlabs/Module/Settings/Editor.php:41
-#: ../../Zotlabs/Module/Settings/Display.php:189
-#: ../../Zotlabs/Module/Settings/Network.php:61
-#: ../../Zotlabs/Module/Tokens.php:188 ../../Zotlabs/Module/Thing.php:326
-#: ../../Zotlabs/Module/Thing.php:379 ../../Zotlabs/Module/Import.php:574
-#: ../../Zotlabs/Module/Oauth2.php:116 ../../Zotlabs/Module/Cal.php:344
-#: ../../Zotlabs/Module/Mood.php:158 ../../Zotlabs/Module/Photos.php:1097
-#: ../../Zotlabs/Module/Photos.php:1138 ../../Zotlabs/Module/Photos.php:1257
-#: ../../Zotlabs/Module/Wiki.php:215 ../../Zotlabs/Module/Pdledit.php:107
-#: ../../Zotlabs/Module/Poke.php:217 ../../Zotlabs/Module/Connedit.php:904
-#: ../../Zotlabs/Module/Chat.php:211 ../../Zotlabs/Module/Chat.php:250
-#: ../../Zotlabs/Module/Email_validation.php:40
-#: ../../Zotlabs/Module/Pconfig.php:116 ../../Zotlabs/Module/Affinity.php:87
-#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Group.php:150
-#: ../../Zotlabs/Module/Group.php:166 ../../Zotlabs/Module/Profiles.php:723
-#: ../../Zotlabs/Module/Editpost.php:85 ../../Zotlabs/Module/Sources.php:125
-#: ../../Zotlabs/Module/Sources.php:162 ../../Zotlabs/Module/Xchan.php:15
-#: ../../Zotlabs/Module/Mail.php:431 ../../Zotlabs/Module/Filestorage.php:183
-#: ../../Zotlabs/Module/Rate.php:166 ../../Zotlabs/Module/Oauth.php:111
-#: ../../Zotlabs/Lib/ThreadItem.php:795 ../../Zotlabs/Widget/Eventstools.php:16
-#: ../../Zotlabs/Widget/Wiki_pages.php:42
-#: ../../Zotlabs/Widget/Wiki_pages.php:99
-#: ../../view/theme/redbasic_c/php/config.php:95
-#: ../../view/theme/redbasic/php/config.php:94
-#: ../../addon/skeleton/Mod_Skeleton.php:51
-#: ../../addon/openclipatar/openclipatar.php:53
-#: ../../addon/wppost/Mod_Wppost.php:97 ../../addon/nsfw/Mod_Nsfw.php:61
-#: ../../addon/ijpost/Mod_Ijpost.php:72 ../../addon/dwpost/Mod_Dwpost.php:71
-#: ../../addon/likebanner/likebanner.php:57
-#: ../../addon/redphotos/redphotos.php:136 ../../addon/irc/irc.php:45
-#: ../../addon/ljpost/Mod_Ljpost.php:73
-#: ../../addon/startpage/Mod_Startpage.php:73
-#: ../../addon/diaspora/Mod_Diaspora.php:99
-#: ../../addon/photocache/Mod_Photocache.php:67
-#: ../../addon/hzfiles/hzfiles.php:84 ../../addon/mailtest/mailtest.php:100
-#: ../../addon/openstreetmap/openstreetmap.php:169
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:56 ../../addon/rtof/Mod_Rtof.php:72
-#: ../../addon/jappixmini/Mod_Jappixmini.php:261
-#: ../../addon/channelreputation/channelreputation.php:140
-#: ../../addon/nofed/Mod_Nofed.php:53 ../../addon/redred/Mod_Redred.php:90
-#: ../../addon/logrot/logrot.php:35 ../../addon/frphotos/frphotos.php:97
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:63
-#: ../../addon/chords/Mod_Chords.php:60
-#: ../../addon/libertree/Mod_Libertree.php:70
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:92
-#: ../../addon/statusnet/Mod_Statusnet.php:193
-#: ../../addon/statusnet/Mod_Statusnet.php:251
-#: ../../addon/statusnet/Mod_Statusnet.php:306
-#: ../../addon/statusnet/statusnet.php:602
-#: ../../addon/twitter/Mod_Twitter.php:184
-#: ../../addon/smileybutton/Mod_Smileybutton.php:55
-#: ../../addon/cart/Settings/Cart.php:114 ../../addon/cart/cart.php:1264
-#: ../../addon/cart/submodules/manualcat.php:248
-#: ../../addon/cart/submodules/hzservices.php:640
-#: ../../addon/cart/submodules/subscriptions.php:410
-#: ../../addon/piwik/piwik.php:95 ../../addon/pageheader/Mod_Pageheader.php:54
-#: ../../addon/xmpp/Mod_Xmpp.php:70 ../../addon/pumpio/Mod_Pumpio.php:115
-#: ../../addon/redfiles/redfiles.php:124 ../../addon/hubwall/hubwall.php:95
-#: ../../include/js_strings.php:22
-msgid "Submit"
-msgstr "Отправить"
+#: ../../include/conversation.php:1078
+msgid "Message"
+msgstr "Сообщение"
-#: ../../Zotlabs/Module/Articles.php:51
-msgid "Articles App"
-msgstr "Приложение \"Статьи\""
+#: ../../include/conversation.php:1088 ../../Zotlabs/Module/Ratings.php:97
+#: ../../Zotlabs/Module/Pubsites.php:35
+msgid "Ratings"
+msgstr "Оценки"
-#: ../../Zotlabs/Module/Articles.php:52
-msgid "Create interactive articles"
-msgstr "Создать интерактивные статьи"
+#: ../../include/conversation.php:1098 ../../Zotlabs/Module/Poke.php:199
+#: ../../Zotlabs/Lib/Apps.php:350
+msgid "Poke"
+msgstr "Ткнуть"
-#: ../../Zotlabs/Module/Articles.php:115
-msgid "Add Article"
-msgstr "Добавить статью"
+#: ../../include/conversation.php:1166 ../../Zotlabs/Storage/Browser.php:164
+#: ../../Zotlabs/Module/Cdav.php:826 ../../Zotlabs/Module/Cdav.php:827
+#: ../../Zotlabs/Module/Cdav.php:834 ../../Zotlabs/Module/Photos.php:832
+#: ../../Zotlabs/Module/Photos.php:1296
+#: ../../Zotlabs/Module/Embedphotos.php:174
+#: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Album.php:84
+#: ../../Zotlabs/Lib/Apps.php:1115 ../../Zotlabs/Lib/Apps.php:1199
+#: ../../Zotlabs/Lib/Activity.php:1059
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:959
+msgid "Unknown"
+msgstr "Неизвестный"
-#: ../../Zotlabs/Module/Articles.php:222 ../../Zotlabs/Lib/Apps.php:324
-#: ../../include/nav.php:512
-msgid "Articles"
-msgstr "Статьи"
+#: ../../include/conversation.php:1212
+#, php-format
+msgid "%s likes this."
+msgstr "%s нравится это."
-#: ../../Zotlabs/Module/Editlayout.php:79
-#: ../../Zotlabs/Module/Article_edit.php:17
-#: ../../Zotlabs/Module/Article_edit.php:33
-#: ../../Zotlabs/Module/Editblock.php:79 ../../Zotlabs/Module/Editblock.php:95
-#: ../../Zotlabs/Module/Editwebpage.php:80 ../../Zotlabs/Module/Editpost.php:24
-#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33
-msgid "Item not found"
-msgstr "Элемент не найден"
+#: ../../include/conversation.php:1212
+#, php-format
+msgid "%s doesn't like this."
+msgstr "%s не нравится это."
-#: ../../Zotlabs/Module/Editlayout.php:128 ../../Zotlabs/Module/Layouts.php:129
-#: ../../Zotlabs/Module/Layouts.php:189
-msgid "Layout Name"
-msgstr "Название шаблона"
+#: ../../include/conversation.php:1216
+#, php-format
+msgid "<span %1$s>%2$d people</span> like this."
+msgid_plural "<span %1$s>%2$d people</span> like this."
+msgstr[0] "<span %1$s>%2$d человеку</span> это нравится."
+msgstr[1] "<span %1$s>%2$d человекам</span> это нравится."
+msgstr[2] "<span %1$s>%2$d человекам</span> это нравится."
-#: ../../Zotlabs/Module/Editlayout.php:129 ../../Zotlabs/Module/Layouts.php:132
-msgid "Layout Description (Optional)"
-msgstr "Описание шаблона (необязательно)"
+#: ../../include/conversation.php:1218
+#, php-format
+msgid "<span %1$s>%2$d people</span> don't like this."
+msgid_plural "<span %1$s>%2$d people</span> don't like this."
+msgstr[0] "<span %1$s>%2$d человеку</span> это не нравится."
+msgstr[1] "<span %1$s>%2$d человекам</span> это не нравится."
+msgstr[2] "<span %1$s>%2$d человекам</span> это не нравится."
-#: ../../Zotlabs/Module/Editlayout.php:137
-msgid "Edit Layout"
-msgstr "Редактировать шаблон"
+#: ../../include/conversation.php:1224
+msgid "and"
+msgstr "и"
-#: ../../Zotlabs/Module/Editlayout.php:140 ../../Zotlabs/Module/Cdav.php:944
-#: ../../Zotlabs/Module/Cdav.php:1233 ../../Zotlabs/Module/Article_edit.php:131
-#: ../../Zotlabs/Module/Admin/Addons.php:426
+#: ../../include/conversation.php:1227
+#, php-format
+msgid ", and %d other people"
+msgid_plural ", and %d other people"
+msgstr[0] ", и ещё %d человеку"
+msgstr[1] ", и ещё %d человекам"
+msgstr[2] ", и ещё %d человекам"
+
+#: ../../include/conversation.php:1228
+#, php-format
+msgid "%s like this."
+msgstr "%s нравится это."
+
+#: ../../include/conversation.php:1228
+#, php-format
+msgid "%s don't like this."
+msgstr "%s не нравится это."
+
+#: ../../include/conversation.php:1285
+#: ../../extend/addon/hzaddons/hsse/hsse.php:82
+msgid "Set your location"
+msgstr "Задать своё местоположение"
+
+#: ../../include/conversation.php:1286
+#: ../../extend/addon/hzaddons/hsse/hsse.php:83
+msgid "Clear browser location"
+msgstr "Очистить местоположение из браузера"
+
+#: ../../include/conversation.php:1298 ../../Zotlabs/Module/Mail.php:288
+#: ../../Zotlabs/Module/Mail.php:430 ../../Zotlabs/Module/Chat.php:222
+#: ../../Zotlabs/Module/Editblock.php:116
+#: ../../Zotlabs/Module/Editwebpage.php:143
+#: ../../Zotlabs/Module/Card_edit.php:101
+#: ../../Zotlabs/Module/Article_edit.php:101
+#: ../../extend/addon/hzaddons/hsse/hsse.php:95
+msgid "Insert web link"
+msgstr "Вставить веб-ссылку"
+
+#: ../../include/conversation.php:1302
+#: ../../extend/addon/hzaddons/hsse/hsse.php:99
+msgid "Embed (existing) photo from your photo albums"
+msgstr "Встроить (существующее) фото из вашего фотоальбома"
+
+#: ../../include/conversation.php:1337 ../../Zotlabs/Module/Mail.php:241
+#: ../../Zotlabs/Module/Mail.php:362 ../../Zotlabs/Module/Chat.php:220
+#: ../../extend/addon/hzaddons/hsse/hsse.php:134
+msgid "Please enter a link URL:"
+msgstr "Пожалуйста введите URL ссылки:"
+
+#: ../../include/conversation.php:1338
+#: ../../extend/addon/hzaddons/hsse/hsse.php:135
+msgid "Tag term:"
+msgstr "Теги:"
+
+#: ../../include/conversation.php:1339
+#: ../../extend/addon/hzaddons/hsse/hsse.php:136
+msgid "Where are you right now?"
+msgstr "Где вы сейчас?"
+
+#: ../../include/conversation.php:1342 ../../Zotlabs/Module/Cover_photo.php:431
+#: ../../Zotlabs/Module/Profile_photo.php:481 ../../Zotlabs/Module/Wiki.php:403
+#: ../../extend/addon/hzaddons/hsse/hsse.php:139
+msgid "Choose images to embed"
+msgstr "Выбрать изображения для встраивания"
+
+#: ../../include/conversation.php:1343 ../../Zotlabs/Module/Cover_photo.php:432
+#: ../../Zotlabs/Module/Profile_photo.php:482 ../../Zotlabs/Module/Wiki.php:404
+#: ../../extend/addon/hzaddons/hsse/hsse.php:140
+msgid "Choose an album"
+msgstr "Выбрать альбом"
+
+#: ../../include/conversation.php:1344
+#: ../../extend/addon/hzaddons/hsse/hsse.php:141
+msgid "Choose a different album..."
+msgstr "Выбрать другой альбом..."
+
+#: ../../include/conversation.php:1345 ../../Zotlabs/Module/Cover_photo.php:434
+#: ../../Zotlabs/Module/Profile_photo.php:484 ../../Zotlabs/Module/Wiki.php:406
+#: ../../extend/addon/hzaddons/hsse/hsse.php:142
+msgid "Error getting album list"
+msgstr "Ошибка получения списка альбомов"
+
+#: ../../include/conversation.php:1346 ../../Zotlabs/Module/Cover_photo.php:435
+#: ../../Zotlabs/Module/Profile_photo.php:485 ../../Zotlabs/Module/Wiki.php:407
+#: ../../extend/addon/hzaddons/hsse/hsse.php:143
+msgid "Error getting photo link"
+msgstr "Ошибка получения ссылки на фотографию"
+
+#: ../../include/conversation.php:1347 ../../Zotlabs/Module/Cover_photo.php:436
+#: ../../Zotlabs/Module/Profile_photo.php:486 ../../Zotlabs/Module/Wiki.php:408
+#: ../../extend/addon/hzaddons/hsse/hsse.php:144
+msgid "Error getting album"
+msgstr "Ошибка получения альбома"
+
+#: ../../include/conversation.php:1348
+#: ../../extend/addon/hzaddons/hsse/hsse.php:145
+msgid "Comments enabled"
+msgstr "Комментарии включены"
+
+#: ../../include/conversation.php:1349
+#: ../../extend/addon/hzaddons/hsse/hsse.php:146
+msgid "Comments disabled"
+msgstr "Комментарии отключены"
+
+#: ../../include/conversation.php:1359 ../../Zotlabs/Module/Photos.php:1139
+#: ../../Zotlabs/Module/Events.php:480 ../../Zotlabs/Module/Webpages.php:262
+#: ../../Zotlabs/Lib/ThreadItem.php:805
+#: ../../extend/addon/hzaddons/hsse/hsse.php:153
+msgid "Preview"
+msgstr "Предварительный просмотр"
+
+#: ../../include/conversation.php:1392 ../../Zotlabs/Module/Photos.php:1117
+#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Module/Blocks.php:161
+#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Layouts.php:194
+#: ../../Zotlabs/Widget/Cdav.php:124
+#: ../../extend/addon/hzaddons/hsse/hsse.php:186
+msgid "Share"
+msgstr "Поделиться"
+
+#: ../../include/conversation.php:1401
+#: ../../extend/addon/hzaddons/hsse/hsse.php:195
+msgid "Page link name"
+msgstr "Название ссылки на страницу "
+
+#: ../../include/conversation.php:1404
+#: ../../extend/addon/hzaddons/hsse/hsse.php:198
+msgid "Post as"
+msgstr "Опубликовать как"
+
+#: ../../include/conversation.php:1406 ../../Zotlabs/Lib/ThreadItem.php:796
+#: ../../extend/addon/hzaddons/hsse/hsse.php:200
+msgid "Bold"
+msgstr "Жирный"
+
+#: ../../include/conversation.php:1407 ../../Zotlabs/Lib/ThreadItem.php:797
+#: ../../extend/addon/hzaddons/hsse/hsse.php:201
+msgid "Italic"
+msgstr "Курсив"
+
+#: ../../include/conversation.php:1408 ../../Zotlabs/Lib/ThreadItem.php:798
+#: ../../extend/addon/hzaddons/hsse/hsse.php:202
+msgid "Underline"
+msgstr "Подчеркнутый"
+
+#: ../../include/conversation.php:1409 ../../Zotlabs/Lib/ThreadItem.php:799
+#: ../../extend/addon/hzaddons/hsse/hsse.php:203
+msgid "Quote"
+msgstr "Цитата"
+
+#: ../../include/conversation.php:1410 ../../Zotlabs/Lib/ThreadItem.php:800
+#: ../../extend/addon/hzaddons/hsse/hsse.php:204
+msgid "Code"
+msgstr "Код"
+
+#: ../../include/conversation.php:1411 ../../Zotlabs/Lib/ThreadItem.php:802
+#: ../../extend/addon/hzaddons/hsse/hsse.php:205
+msgid "Attach/Upload file"
+msgstr "Прикрепить/загрузить файл"
+
+#: ../../include/conversation.php:1414 ../../Zotlabs/Module/Wiki.php:400
+#: ../../extend/addon/hzaddons/hsse/hsse.php:208
+msgid "Embed an image from your albums"
+msgstr "Встроить изображение из ваших альбомов"
+
+#: ../../include/conversation.php:1415 ../../include/conversation.php:1464
+#: ../../Zotlabs/Module/Cdav.php:968 ../../Zotlabs/Module/Cdav.php:1260
+#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Tagrm.php:15
+#: ../../Zotlabs/Module/Tagrm.php:138 ../../Zotlabs/Module/Oauth.php:112
+#: ../../Zotlabs/Module/Oauth.php:138 ../../Zotlabs/Module/Cover_photo.php:429
#: ../../Zotlabs/Module/Oauth2.php:117 ../../Zotlabs/Module/Oauth2.php:145
-#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Wiki.php:368
-#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Profile_photo.php:465
-#: ../../Zotlabs/Module/Connedit.php:941 ../../Zotlabs/Module/Fbrowser.php:66
-#: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Profiles.php:801
+#: ../../Zotlabs/Module/Editlayout.php:140
+#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Fbrowser.php:66
+#: ../../Zotlabs/Module/Fbrowser.php:88
+#: ../../Zotlabs/Module/Admin/Addons.php:426
#: ../../Zotlabs/Module/Editwebpage.php:169
-#: ../../Zotlabs/Module/Editpost.php:109 ../../Zotlabs/Module/Filer.php:55
-#: ../../Zotlabs/Module/Cover_photo.php:399 ../../Zotlabs/Module/Tagrm.php:15
-#: ../../Zotlabs/Module/Tagrm.php:138 ../../Zotlabs/Module/Card_edit.php:131
-#: ../../Zotlabs/Module/Oauth.php:112 ../../Zotlabs/Module/Oauth.php:138
-#: ../../addon/hsse/hsse.php:209 ../../addon/hsse/hsse.php:258
-#: ../../include/conversation.php:1415 ../../include/conversation.php:1464
+#: ../../Zotlabs/Module/Profile_photo.php:479
+#: ../../Zotlabs/Module/Editpost.php:109 ../../Zotlabs/Module/Connedit.php:941
+#: ../../Zotlabs/Module/Card_edit.php:131
+#: ../../Zotlabs/Module/Article_edit.php:131 ../../Zotlabs/Module/Wiki.php:368
+#: ../../Zotlabs/Module/Wiki.php:401 ../../Zotlabs/Module/Filer.php:55
+#: ../../extend/addon/hzaddons/hsse/hsse.php:209
+#: ../../extend/addon/hzaddons/hsse/hsse.php:258
msgid "Cancel"
msgstr "Отменить"
-#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Subthread.php:86
-#: ../../Zotlabs/Module/Import_items.php:120 ../../Zotlabs/Module/Share.php:71
-#: ../../Zotlabs/Module/Cloud.php:126 ../../Zotlabs/Module/Group.php:98
-#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:79
-#: ../../Zotlabs/Module/Like.php:301 ../../Zotlabs/Web/WebServer.php:122
-#: ../../addon/redphotos/redphotos.php:119 ../../addon/hzfiles/hzfiles.php:73
-#: ../../addon/frphotos/frphotos.php:82 ../../addon/redfiles/redfiles.php:109
-#: ../../include/items.php:416
-msgid "Permission denied"
-msgstr "Доступ запрещен"
+#: ../../include/conversation.php:1416 ../../include/conversation.php:1463
+#: ../../Zotlabs/Module/Cover_photo.php:430
+#: ../../Zotlabs/Module/Profile_photo.php:480 ../../Zotlabs/Module/Wiki.php:402
+#: ../../extend/addon/hzaddons/hsse/hsse.php:210
+#: ../../extend/addon/hzaddons/hsse/hsse.php:257
+msgid "OK"
+msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63
-msgid "Invalid profile identifier."
-msgstr "Неверный идентификатор профиля"
+#: ../../include/conversation.php:1418
+#: ../../extend/addon/hzaddons/hsse/hsse.php:212
+msgid "Toggle voting"
+msgstr "Подключить голосование"
-#: ../../Zotlabs/Module/Profperm.php:111
-msgid "Profile Visibility Editor"
-msgstr "Редактор видимости профиля"
+#: ../../include/conversation.php:1421
+#: ../../extend/addon/hzaddons/hsse/hsse.php:215
+msgid "Disable comments"
+msgstr "Отключить комментарии"
-#: ../../Zotlabs/Module/Profperm.php:113 ../../Zotlabs/Lib/Apps.php:359
-#: ../../include/channel.php:1700
+#: ../../include/conversation.php:1422
+#: ../../extend/addon/hzaddons/hsse/hsse.php:216
+msgid "Toggle comments"
+msgstr "Переключить комментарии"
+
+#: ../../include/conversation.php:1427 ../../Zotlabs/Module/Photos.php:713
+#: ../../Zotlabs/Module/Photos.php:1083 ../../Zotlabs/Module/Editblock.php:129
+#: ../../Zotlabs/Module/Card_edit.php:117
+#: ../../Zotlabs/Module/Article_edit.php:117
+#: ../../extend/addon/hzaddons/hsse/hsse.php:221
+msgid "Title (optional)"
+msgstr "Заголовок (необязательно)"
+
+#: ../../include/conversation.php:1430
+#: ../../extend/addon/hzaddons/hsse/hsse.php:224
+msgid "Categories (optional, comma-separated list)"
+msgstr "Категории (необязательно, список через запятую)"
+
+#: ../../include/conversation.php:1431 ../../Zotlabs/Module/Events.php:481
+#: ../../extend/addon/hzaddons/hsse/hsse.php:225
+msgid "Permission settings"
+msgstr "Настройки разрешений"
+
+#: ../../include/conversation.php:1453
+#: ../../extend/addon/hzaddons/hsse/hsse.php:247
+msgid "Other networks and post services"
+msgstr "Другие сети и службы публикаций"
+
+#: ../../include/conversation.php:1456 ../../Zotlabs/Module/Mail.php:292
+#: ../../Zotlabs/Module/Mail.php:434
+#: ../../extend/addon/hzaddons/hsse/hsse.php:250
+msgid "Set expiration date"
+msgstr "Установить срок действия"
+
+#: ../../include/conversation.php:1459
+#: ../../extend/addon/hzaddons/hsse/hsse.php:253
+msgid "Set publish date"
+msgstr "Установить дату публикации"
+
+#: ../../include/conversation.php:1461 ../../Zotlabs/Module/Mail.php:294
+#: ../../Zotlabs/Module/Mail.php:436 ../../Zotlabs/Module/Chat.php:221
+#: ../../Zotlabs/Lib/ThreadItem.php:809
+#: ../../extend/addon/hzaddons/hsse/hsse.php:255
+msgid "Encrypt text"
+msgstr "Зашифровать текст"
+
+#: ../../include/conversation.php:1705 ../../Zotlabs/Module/Photos.php:1182
+#: ../../Zotlabs/Lib/ThreadItem.php:240
+msgctxt "noun"
+msgid "Dislike"
+msgid_plural "Dislikes"
+msgstr[0] "Не нравится"
+msgstr[1] "Не нравится"
+msgstr[2] "Не нравится"
+
+#: ../../include/conversation.php:1708
+msgctxt "noun"
+msgid "Attending"
+msgid_plural "Attending"
+msgstr[0] "Посетит"
+msgstr[1] "Посетят"
+msgstr[2] "Посетят"
+
+#: ../../include/conversation.php:1711
+msgctxt "noun"
+msgid "Not Attending"
+msgid_plural "Not Attending"
+msgstr[0] "Не посетит"
+msgstr[1] "Не посетят"
+msgstr[2] "Не посетят"
+
+#: ../../include/conversation.php:1714
+msgctxt "noun"
+msgid "Undecided"
+msgid_plural "Undecided"
+msgstr "Не решил"
+
+#: ../../include/conversation.php:1717
+msgctxt "noun"
+msgid "Agree"
+msgid_plural "Agrees"
+msgstr[0] "Согласен"
+msgstr[1] "Согласны"
+msgstr[2] "Согласны"
+
+#: ../../include/conversation.php:1720
+msgctxt "noun"
+msgid "Disagree"
+msgid_plural "Disagrees"
+msgstr[0] "Не согласен"
+msgstr[1] "Не согласны"
+msgstr[2] "Не согласны"
+
+#: ../../include/conversation.php:1723
+msgctxt "noun"
+msgid "Abstain"
+msgid_plural "Abstains"
+msgstr[0] "Воздержался"
+msgstr[1] "Воздержались"
+msgstr[2] "Воздержались"
+
+#: ../../include/taxonomy.php:320
+msgid "Trending"
+msgstr "В тренде"
+
+#: ../../include/taxonomy.php:320 ../../include/taxonomy.php:449
+#: ../../include/taxonomy.php:470 ../../Zotlabs/Widget/Tagcloud.php:22
+msgid "Tags"
+msgstr "Теги"
+
+#: ../../include/taxonomy.php:550
+msgid "Keywords"
+msgstr "Ключевые слова"
+
+#: ../../include/taxonomy.php:571
+msgid "have"
+msgstr "иметь"
+
+#: ../../include/taxonomy.php:571
+msgid "has"
+msgstr "есть"
+
+#: ../../include/taxonomy.php:572
+msgid "want"
+msgstr "хотеть"
+
+#: ../../include/taxonomy.php:572
+msgid "wants"
+msgstr "хотеть"
+
+#: ../../include/taxonomy.php:573 ../../Zotlabs/Lib/ThreadItem.php:306
+msgid "like"
+msgstr "нравится"
+
+#: ../../include/taxonomy.php:573
+msgid "likes"
+msgstr "нравится"
+
+#: ../../include/taxonomy.php:574 ../../Zotlabs/Lib/ThreadItem.php:307
+msgid "dislike"
+msgstr "не нравится"
+
+#: ../../include/taxonomy.php:574
+msgid "dislikes"
+msgstr "не нравится"
+
+#: ../../include/language.php:436
+msgid "Select an alternate language"
+msgstr "Выбор дополнительного языка"
+
+#: ../../include/js_strings.php:5
+msgid "Delete this item?"
+msgstr "Удалить этот элемент?"
+
+#: ../../include/js_strings.php:6 ../../Zotlabs/Module/Photos.php:1137
+#: ../../Zotlabs/Module/Photos.php:1256 ../../Zotlabs/Lib/ThreadItem.php:794
+msgid "Comment"
+msgstr "Комментарий"
+
+#: ../../include/js_strings.php:7 ../../Zotlabs/Lib/ThreadItem.php:501
+#, php-format
+msgid "%s show all"
+msgstr "%s показать всё"
+
+#: ../../include/js_strings.php:8
+#, php-format
+msgid "%s show less"
+msgstr "%s показать меньше"
+
+#: ../../include/js_strings.php:9
+#, php-format
+msgid "%s expand"
+msgstr "%s развернуть"
+
+#: ../../include/js_strings.php:10
+#, php-format
+msgid "%s collapse"
+msgstr "%s свернуть"
+
+#: ../../include/js_strings.php:11
+msgid "Password too short"
+msgstr "Пароль слишком короткий"
+
+#: ../../include/js_strings.php:12
+msgid "Passwords do not match"
+msgstr "Пароли не совпадают"
+
+#: ../../include/js_strings.php:13
+msgid "everybody"
+msgstr "все"
+
+#: ../../include/js_strings.php:14
+msgid "Secret Passphrase"
+msgstr "Тайный пароль"
+
+#: ../../include/js_strings.php:15
+msgid "Passphrase hint"
+msgstr "Подсказка для пароля"
+
+#: ../../include/js_strings.php:16
+msgid "Notice: Permissions have changed but have not yet been submitted."
+msgstr "Уведомление: Права доступа изменились, но до сих пор не сохранены."
+
+#: ../../include/js_strings.php:17
+msgid "close all"
+msgstr "закрыть все"
+
+#: ../../include/js_strings.php:18
+msgid "Nothing new here"
+msgstr "Здесь нет ничего нового"
+
+#: ../../include/js_strings.php:19
+msgid "Rate This Channel (this is public)"
+msgstr "Оценкa этoго канала (общедоступно)"
+
+#: ../../include/js_strings.php:20 ../../Zotlabs/Module/Rate.php:155
+#: ../../Zotlabs/Module/Connedit.php:887
+msgid "Rating"
+msgstr "Оценка"
+
+#: ../../include/js_strings.php:21
+msgid "Describe (optional)"
+msgstr "Охарактеризовать (необязательно)"
+
+#: ../../include/js_strings.php:23
+msgid "Please enter a link URL"
+msgstr "Пожалуйста, введите URL ссылки"
+
+#: ../../include/js_strings.php:24
+msgid "Unsaved changes. Are you sure you wish to leave this page?"
+msgstr "Есть несохраненные изменения. Вы уверены, что хотите покинуть эту страницу?"
+
+#: ../../include/js_strings.php:25 ../../Zotlabs/Module/Cdav.php:940
+#: ../../Zotlabs/Module/Profiles.php:509 ../../Zotlabs/Module/Profiles.php:734
+#: ../../Zotlabs/Module/Events.php:477 ../../Zotlabs/Module/Locs.php:117
+#: ../../Zotlabs/Module/Pubsites.php:52
+msgid "Location"
+msgstr "Место"
+
+#: ../../include/js_strings.php:26
+msgid "lovely"
+msgstr "прекрасно"
+
+#: ../../include/js_strings.php:27
+msgid "wonderful"
+msgstr "замечательно"
+
+#: ../../include/js_strings.php:28
+msgid "fantastic"
+msgstr "фантастично"
+
+#: ../../include/js_strings.php:29
+msgid "great"
+msgstr "отлично"
+
+#: ../../include/js_strings.php:30
+msgid ""
+"Your chosen nickname was either already taken or not valid. Please use our "
+"suggestion ("
+msgstr "Выбранный вами псевдоним уже используется или недействителен. Попробуйте использовать наше предложение ("
+
+#: ../../include/js_strings.php:31
+msgid ") or enter a new one."
+msgstr ") или введите новый."
+
+#: ../../include/js_strings.php:32
+msgid "Thank you, this nickname is valid."
+msgstr "Спасибо, этот псевдоним может быть использован."
+
+#: ../../include/js_strings.php:33
+msgid "A channel name is required."
+msgstr "Требуется название канала."
+
+#: ../../include/js_strings.php:34
+msgid "This is a "
+msgstr "Это "
+
+#: ../../include/js_strings.php:35
+msgid " channel name"
+msgstr " название канала"
+
+#: ../../include/js_strings.php:41
+#, php-format
+msgid "%d minutes"
+msgid_plural "%d minutes"
+msgstr[0] "%d минуту"
+msgstr[1] "%d минуты"
+msgstr[2] "%d минут"
+
+#: ../../include/js_strings.php:42
+#, php-format
+msgid "about %d hours"
+msgid_plural "about %d hours"
+msgstr[0] "около %d часa"
+msgstr[1] "около %d часов"
+msgstr[2] "около %d часов"
+
+#: ../../include/js_strings.php:43
+#, php-format
+msgid "%d days"
+msgid_plural "%d days"
+msgstr[0] "%d день"
+msgstr[1] "%d дня"
+msgstr[2] "%d дней"
+
+#: ../../include/js_strings.php:44
+#, php-format
+msgid "%d months"
+msgid_plural "%d months"
+msgstr[0] "%d месяц"
+msgstr[1] "%d месяца"
+msgstr[2] "%d месяцев"
+
+#: ../../include/js_strings.php:45
+#, php-format
+msgid "%d years"
+msgid_plural "%d years"
+msgstr[0] "%d год"
+msgstr[1] "%d года"
+msgstr[2] "%d лет"
+
+#: ../../include/js_strings.php:50
+msgid "timeago.prefixAgo"
+msgstr ""
+
+#: ../../include/js_strings.php:51
+msgid "timeago.prefixFromNow"
+msgstr "через"
+
+#: ../../include/js_strings.php:52
+msgid "timeago.suffixAgo"
+msgstr "назад"
+
+#: ../../include/js_strings.php:53
+msgid "timeago.suffixFromNow"
+msgstr ""
+
+#: ../../include/js_strings.php:56
+msgid "less than a minute"
+msgstr "менее чем одну минуту"
+
+#: ../../include/js_strings.php:57
+msgid "about a minute"
+msgstr "около минуты"
+
+#: ../../include/js_strings.php:59
+msgid "about an hour"
+msgstr "около часа"
+
+#: ../../include/js_strings.php:61
+msgid "a day"
+msgstr "день"
+
+#: ../../include/js_strings.php:63
+msgid "about a month"
+msgstr "около месяца"
+
+#: ../../include/js_strings.php:65
+msgid "about a year"
+msgstr "около года"
+
+#: ../../include/js_strings.php:67
+msgid " "
+msgstr " "
+
+#: ../../include/js_strings.php:68
+msgid "timeago.numbers"
+msgstr ""
+
+#: ../../include/js_strings.php:74
+msgctxt "long"
+msgid "May"
+msgstr "Май"
+
+#: ../../include/js_strings.php:82
+msgid "Jan"
+msgstr "Янв"
+
+#: ../../include/js_strings.php:83
+msgid "Feb"
+msgstr "Фев"
+
+#: ../../include/js_strings.php:84
+msgid "Mar"
+msgstr "Мар"
+
+#: ../../include/js_strings.php:85
+msgid "Apr"
+msgstr "Апр"
+
+#: ../../include/js_strings.php:86
+msgctxt "short"
+msgid "May"
+msgstr "Май"
+
+#: ../../include/js_strings.php:87
+msgid "Jun"
+msgstr "Июн"
+
+#: ../../include/js_strings.php:88
+msgid "Jul"
+msgstr "Июл"
+
+#: ../../include/js_strings.php:89
+msgid "Aug"
+msgstr "Авг"
+
+#: ../../include/js_strings.php:90
+msgid "Sep"
+msgstr "Сен"
+
+#: ../../include/js_strings.php:91
+msgid "Oct"
+msgstr "Окт"
+
+#: ../../include/js_strings.php:92
+msgid "Nov"
+msgstr "Ноя"
+
+#: ../../include/js_strings.php:93
+msgid "Dec"
+msgstr "Дек"
+
+#: ../../include/js_strings.php:101
+msgid "Sun"
+msgstr "Вск"
+
+#: ../../include/js_strings.php:102
+msgid "Mon"
+msgstr "Пон"
+
+#: ../../include/js_strings.php:103
+msgid "Tue"
+msgstr "Вт"
+
+#: ../../include/js_strings.php:104
+msgid "Wed"
+msgstr "Ср"
+
+#: ../../include/js_strings.php:105
+msgid "Thu"
+msgstr "Чет"
+
+#: ../../include/js_strings.php:106
+msgid "Fri"
+msgstr "Пят"
+
+#: ../../include/js_strings.php:107
+msgid "Sat"
+msgstr "Суб"
+
+#: ../../include/js_strings.php:108
+msgctxt "calendar"
+msgid "today"
+msgstr "сегодня"
+
+#: ../../include/js_strings.php:109
+msgctxt "calendar"
+msgid "month"
+msgstr "месяц"
+
+#: ../../include/js_strings.php:110
+msgctxt "calendar"
+msgid "week"
+msgstr "неделя"
+
+#: ../../include/js_strings.php:111
+msgctxt "calendar"
+msgid "day"
+msgstr "день"
+
+#: ../../include/js_strings.php:112
+msgctxt "calendar"
+msgid "All day"
+msgstr "Весь день"
+
+#: ../../include/dir_fns.php:141 ../../Zotlabs/Lib/Libzotdir.php:160
+msgid "Directory Options"
+msgstr "Параметры каталога"
+
+#: ../../include/dir_fns.php:143 ../../Zotlabs/Lib/Libzotdir.php:162
+msgid "Safe Mode"
+msgstr "Безопасный режим"
+
+#: ../../include/dir_fns.php:144 ../../Zotlabs/Lib/Libzotdir.php:163
+msgid "Public Forums Only"
+msgstr "Только публичные форумы"
+
+#: ../../include/dir_fns.php:145 ../../Zotlabs/Lib/Libzotdir.php:165
+msgid "This Website Only"
+msgstr "Только этот веб-сайт"
+
+#: ../../include/network.php:1725 ../../include/network.php:1726
+msgid "Friendica"
+msgstr ""
+
+#: ../../include/network.php:1727
+msgid "OStatus"
+msgstr ""
+
+#: ../../include/network.php:1728
+msgid "GNU-Social"
+msgstr ""
+
+#: ../../include/network.php:1729
+msgid "RSS/Atom"
+msgstr ""
+
+#: ../../include/network.php:1730 ../../Zotlabs/Lib/Activity.php:1854
+#: ../../Zotlabs/Lib/Activity.php:2052
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1218
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1373
+#: ../../extend/addon/hzaddons/pubcrawl/as.php:1553
+msgid "ActivityPub"
+msgstr ""
+
+#: ../../include/network.php:1731 ../../Zotlabs/Module/Cdav.php:1246
+#: ../../Zotlabs/Module/Profiles.php:787
+#: ../../Zotlabs/Module/Admin/Accounts.php:171
+#: ../../Zotlabs/Module/Admin/Accounts.php:183
+#: ../../Zotlabs/Module/Connedit.php:927
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:57
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71
+msgid "Email"
+msgstr "Электронная почта"
+
+#: ../../include/network.php:1732
+msgid "Diaspora"
+msgstr ""
+
+#: ../../include/network.php:1733
+msgid "Facebook"
+msgstr ""
+
+#: ../../include/network.php:1734
+msgid "Zot"
+msgstr ""
+
+#: ../../include/network.php:1735
+msgid "LinkedIn"
+msgstr ""
+
+#: ../../include/network.php:1736
+msgid "XMPP/IM"
+msgstr ""
+
+#: ../../include/network.php:1737
+msgid "MySpace"
+msgstr ""
+
+#: ../../include/datetime.php:58 ../../Zotlabs/Module/Profiles.php:736
+#: ../../Zotlabs/Widget/Newmember.php:51
+msgid "Miscellaneous"
+msgstr "Прочее"
+
+#: ../../include/datetime.php:140
+msgid "Birthday"
+msgstr "День рождения"
+
+#: ../../include/datetime.php:140
+msgid "Age: "
+msgstr "Возраст:"
+
+#: ../../include/datetime.php:140
+msgid "YYYY-MM-DD or MM-DD"
+msgstr "YYYY-MM-DD или MM-DD"
+
+#: ../../include/datetime.php:211 ../../Zotlabs/Module/Appman.php:143
+#: ../../Zotlabs/Module/Appman.php:144 ../../Zotlabs/Module/Profiles.php:745
+#: ../../Zotlabs/Module/Profiles.php:749 ../../Zotlabs/Module/Events.php:462
+#: ../../Zotlabs/Module/Events.php:467
+msgid "Required"
+msgstr "Требуется"
+
+#: ../../include/datetime.php:238 ../../boot.php:2560
+msgid "never"
+msgstr "никогда"
+
+#: ../../include/datetime.php:244
+msgid "less than a second ago"
+msgstr "менее чем одну секунду"
+
+#: ../../include/datetime.php:262
+#, php-format
+msgctxt "e.g. 22 hours ago, 1 minute ago"
+msgid "%1$d %2$s ago"
+msgstr "%1$d %2$s назад"
+
+#: ../../include/datetime.php:273
+msgctxt "relative_date"
+msgid "year"
+msgid_plural "years"
+msgstr[0] "год"
+msgstr[1] "года"
+msgstr[2] "лет"
+
+#: ../../include/datetime.php:276
+msgctxt "relative_date"
+msgid "month"
+msgid_plural "months"
+msgstr[0] "месяц"
+msgstr[1] "месяца"
+msgstr[2] "месяцев"
+
+#: ../../include/datetime.php:279
+msgctxt "relative_date"
+msgid "week"
+msgid_plural "weeks"
+msgstr[0] "неделю"
+msgstr[1] "недели"
+msgstr[2] "недель"
+
+#: ../../include/datetime.php:282
+msgctxt "relative_date"
+msgid "day"
+msgid_plural "days"
+msgstr[0] "день"
+msgstr[1] "дня"
+msgstr[2] "дней"
+
+#: ../../include/datetime.php:285
+msgctxt "relative_date"
+msgid "hour"
+msgid_plural "hours"
+msgstr[0] "час"
+msgstr[1] "часа"
+msgstr[2] "часов"
+
+#: ../../include/datetime.php:288
+msgctxt "relative_date"
+msgid "minute"
+msgid_plural "minutes"
+msgstr[0] "минуту"
+msgstr[1] "минуты"
+msgstr[2] "минут"
+
+#: ../../include/datetime.php:291
+msgctxt "relative_date"
+msgid "second"
+msgid_plural "seconds"
+msgstr[0] "секунду"
+msgstr[1] "секунды"
+msgstr[2] "секунд"
+
+#: ../../include/datetime.php:520
+#, php-format
+msgid "%1$s's birthday"
+msgstr "У %1$s День рождения"
+
+#: ../../include/datetime.php:521
+#, php-format
+msgid "Happy Birthday %1$s"
+msgstr "С Днем рождения %1$s !"
+
+#: ../../include/acl_selectors.php:33
+#: ../../Zotlabs/Lib/PermissionDescription.php:34
+msgid "Visible to your default audience"
+msgstr "Видно вашей аудитории по умолчанию."
+
+#: ../../include/acl_selectors.php:88 ../../Zotlabs/Module/Acl.php:121
+#: ../../Zotlabs/Module/Lockview.php:117 ../../Zotlabs/Module/Lockview.php:153
+msgctxt "acl"
msgid "Profile"
msgstr "Профиль"
-#: ../../Zotlabs/Module/Profperm.php:115
-msgid "Click on a contact to add or remove."
-msgstr "Нажмите на контакт, чтобы добавить или удалить."
+#: ../../include/acl_selectors.php:106
+#: ../../Zotlabs/Lib/PermissionDescription.php:107
+msgid "Only me"
+msgstr "Только мне"
-#: ../../Zotlabs/Module/Profperm.php:124
-msgid "Visible To"
-msgstr "Видно"
+#: ../../include/acl_selectors.php:113
+msgid "Who can see this?"
+msgstr "Кто может это видеть?"
-#: ../../Zotlabs/Module/Profperm.php:140
-#: ../../Zotlabs/Module/Connections.php:203
-msgid "All Connections"
-msgstr "Все контакты"
+#: ../../include/acl_selectors.php:114
+msgid "Custom selection"
+msgstr "Настраиваемый выбор"
+
+#: ../../include/acl_selectors.php:115
+msgid ""
+"Select \"Show\" to allow viewing. \"Don't show\" lets you override and limit "
+"the scope of \"Show\"."
+msgstr "Нажмите \"Показать\" чтобы разрешить просмотр. \"Не показывать\" позволит вам переопределить и ограничить область показа."
+
+#: ../../include/acl_selectors.php:116
+msgid "Show"
+msgstr "Показать"
+
+#: ../../include/acl_selectors.php:117
+msgid "Don't show"
+msgstr "Не показывать"
+
+#: ../../include/acl_selectors.php:123 ../../Zotlabs/Module/Photos.php:717
+#: ../../Zotlabs/Module/Photos.php:1086 ../../Zotlabs/Module/Chat.php:243
+#: ../../Zotlabs/Module/Filestorage.php:190 ../../Zotlabs/Module/Thing.php:319
+#: ../../Zotlabs/Module/Thing.php:372 ../../Zotlabs/Module/Connedit.php:690
+msgid "Permissions"
+msgstr "Разрешения"
+
+#: ../../include/acl_selectors.php:125 ../../Zotlabs/Module/Photos.php:1316
+#: ../../Zotlabs/Lib/ThreadItem.php:463
+msgid "Close"
+msgstr "Закрыть"
+
+#: ../../include/acl_selectors.php:150
+#, php-format
+msgid ""
+"Post permissions %s cannot be changed %s after a post is shared.</br />These "
+"permissions set who is allowed to view the post."
+msgstr "Разрешения публикации %s не могут быть изменены %s после того, как ею поделились. Эти разрешения устанавливают кому разрешено просматривать эту публикацию."
+
+#: ../../include/zid.php:351
+#, php-format
+msgid "OpenWebAuth: %1$s welcomes %2$s"
+msgstr "OpenWebAuth: %1$s приветствует %2$s"
+
+#: ../../include/connections.php:133
+msgid "New window"
+msgstr "Новое окно"
+
+#: ../../include/connections.php:134
+msgid "Open the selected location in a different window or browser tab"
+msgstr "Открыть выбранное местоположение в другом окне или вкладке браузера"
+
+#: ../../include/connections.php:696 ../../include/event.php:1320
+#: ../../Zotlabs/Module/Cdav.php:1251 ../../Zotlabs/Module/Profiles.php:792
+#: ../../Zotlabs/Module/Connedit.php:932
+msgid "Mobile"
+msgstr "Мобильный"
+
+#: ../../include/connections.php:697 ../../include/event.php:1321
+#: ../../Zotlabs/Module/Cdav.php:1252 ../../Zotlabs/Module/Profiles.php:793
+#: ../../Zotlabs/Module/Connedit.php:933
+msgid "Home"
+msgstr "Домашний"
+
+#: ../../include/connections.php:698 ../../include/event.php:1322
+msgid "Home, Voice"
+msgstr "Дом, голос"
+
+#: ../../include/connections.php:699 ../../include/event.php:1323
+msgid "Home, Fax"
+msgstr "Дом, факс"
+
+#: ../../include/connections.php:700 ../../include/event.php:1324
+#: ../../Zotlabs/Module/Cdav.php:1253 ../../Zotlabs/Module/Profiles.php:794
+#: ../../Zotlabs/Module/Connedit.php:934
+msgid "Work"
+msgstr "Рабочий"
+
+#: ../../include/connections.php:701 ../../include/event.php:1325
+msgid "Work, Voice"
+msgstr "Работа, голос"
+
+#: ../../include/connections.php:702 ../../include/event.php:1326
+msgid "Work, Fax"
+msgstr "Работа, факс"
+
+#: ../../include/event.php:28 ../../include/event.php:75
+msgid "l F d, Y \\@ g:i A"
+msgstr ""
+
+#: ../../include/event.php:36 ../../include/event.php:79
+msgid "Starts:"
+msgstr "Начало:"
+
+#: ../../include/event.php:46 ../../include/event.php:83
+msgid "Finishes:"
+msgstr "Окончание:"
+
+#: ../../include/event.php:1020
+msgid "This event has been added to your calendar."
+msgstr "Это событие было добавлено в ваш календарь."
+
+#: ../../include/event.php:1239
+msgid "Not specified"
+msgstr "Не указано"
+
+#: ../../include/event.php:1240
+msgid "Needs Action"
+msgstr "Требует действия"
+
+#: ../../include/event.php:1241
+msgid "Completed"
+msgstr "Завершено"
+
+#: ../../include/event.php:1242
+msgid "In Process"
+msgstr "В процессе"
+
+#: ../../include/event.php:1243
+msgid "Cancelled"
+msgstr "Отменено"
+
+#: ../../include/auth.php:192
+msgid "Delegation session ended."
+msgstr "Делегированная сессия завершена."
+
+#: ../../include/auth.php:196
+msgid "Logged out."
+msgstr "Вышел из системы."
+
+#: ../../include/auth.php:291
+msgid "Email validation is incomplete. Please check your email."
+msgstr "Проверка email не завершена. Пожалуйста, проверьте вашу почту."
+
+#: ../../include/auth.php:307
+msgid "Failed authentication"
+msgstr "Ошибка аутентификации"
+
+#: ../../include/auth.php:317
+#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188
+msgid "Login failed."
+msgstr "Не удалось войти."
+
+#: ../../include/nav.php:90
+msgid "Remote authentication"
+msgstr "Удаленная аутентификация"
+
+#: ../../include/nav.php:90
+msgid "Click to authenticate to your home hub"
+msgstr "Нажмите, чтобы аутентифицировать себя на домашнем узле"
+
+#: ../../include/nav.php:96 ../../Zotlabs/Module/Manage.php:170
+#: ../../Zotlabs/Lib/Apps.php:336
+msgid "Channel Manager"
+msgstr "Менеджер каналов"
+
+#: ../../include/nav.php:96
+msgid "Manage your channels"
+msgstr "Управление вашими каналами"
+
+#: ../../include/nav.php:99
+msgid "Manage your privacy groups"
+msgstr "Управление вашим группами безопасности"
-#: ../../Zotlabs/Module/Cdav.php:810
+#: ../../include/nav.php:101 ../../Zotlabs/Module/Admin/Addons.php:344
+#: ../../Zotlabs/Module/Admin/Themes.php:125
+#: ../../Zotlabs/Widget/Newmember.php:53
+#: ../../Zotlabs/Widget/Settings_menu.php:61 ../../Zotlabs/Lib/Apps.php:338
+msgid "Settings"
+msgstr "Настройки"
+
+#: ../../include/nav.php:101
+msgid "Account/Channel Settings"
+msgstr "Настройки аккаунта / канала"
+
+#: ../../include/nav.php:107 ../../include/nav.php:136
+#: ../../include/nav.php:155 ../../boot.php:1628
+msgid "Logout"
+msgstr "Выход"
+
+#: ../../include/nav.php:107 ../../include/nav.php:136
+msgid "End this session"
+msgstr "Закончить эту сессию"
+
+#: ../../include/nav.php:110
+msgid "Your profile page"
+msgstr "Страницa вашего профиля"
+
+#: ../../include/nav.php:113
+msgid "Manage/Edit profiles"
+msgstr "Управление / редактирование профилей"
+
+#: ../../include/nav.php:115 ../../Zotlabs/Widget/Newmember.php:35
+msgid "Edit your profile"
+msgstr "Редактировать профиль"
+
+#: ../../include/nav.php:122 ../../include/nav.php:126 ../../boot.php:1629
+#: ../../Zotlabs/Lib/Apps.php:335
+msgid "Login"
+msgstr "Войти"
+
+#: ../../include/nav.php:122 ../../include/nav.php:126
+msgid "Sign in"
+msgstr "Войти"
+
+#: ../../include/nav.php:153
+msgid "Take me home"
+msgstr "Домой"
+
+#: ../../include/nav.php:155
+msgid "Log me out of this site"
+msgstr "Выйти с этого сайта"
+
+#: ../../include/nav.php:160 ../../boot.php:1609
+#: ../../Zotlabs/Module/Register.php:289
+msgid "Register"
+msgstr "Регистрация"
+
+#: ../../include/nav.php:160
+msgid "Create an account"
+msgstr "Создать аккаунт"
+
+#: ../../include/nav.php:172
+msgid "Help and documentation"
+msgstr "Справочная информация и документация"
+
+#: ../../include/nav.php:186
+msgid "Search site @name, !forum, #tag, ?docs, content"
+msgstr "Искать на сайте @имя, !форум, #тег, ?документ, содержимое"
+
+#: ../../include/nav.php:192 ../../Zotlabs/Widget/Admin.php:55
+msgid "Admin"
+msgstr "Администрирование"
+
+#: ../../include/nav.php:192
+msgid "Site Setup and Configuration"
+msgstr "Установка и конфигурация сайта"
+
+#: ../../include/nav.php:326 ../../Zotlabs/Module/Defperms.php:256
+#: ../../Zotlabs/Module/New_channel.php:157
+#: ../../Zotlabs/Module/New_channel.php:164
+#: ../../Zotlabs/Module/Connedit.php:869
+#: ../../Zotlabs/Widget/Notifications.php:162
+msgid "Loading"
+msgstr "Загрузка"
+
+#: ../../include/nav.php:332
+msgid "@name, !forum, #tag, ?doc, content"
+msgstr "@имя, !форум, #тег, ?документ, содержимое"
+
+#: ../../include/nav.php:333
+msgid "Please wait..."
+msgstr "Подождите пожалуйста ..."
+
+#: ../../include/nav.php:339
+msgid "Add Apps"
+msgstr "Добавить приложения"
+
+#: ../../include/nav.php:340
+msgid "Arrange Apps"
+msgstr "Упорядочить приложения"
+
+#: ../../include/nav.php:341
+msgid "Toggle System Apps"
+msgstr "Показать системные приложения"
+
+#: ../../include/nav.php:423 ../../Zotlabs/Module/Admin/Channels.php:154
+msgid "Channel"
+msgstr "Канал"
+
+#: ../../include/nav.php:426
+msgid "Status Messages and Posts"
+msgstr "Статусы и публикации"
+
+#: ../../include/nav.php:436 ../../Zotlabs/Module/Help.php:80
+msgid "About"
+msgstr "О себе"
+
+#: ../../include/nav.php:439
+msgid "Profile Details"
+msgstr "Информация о профиле"
+
+#: ../../include/nav.php:454 ../../Zotlabs/Storage/Browser.php:278
+#: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Lib/Apps.php:339
+msgid "Files"
+msgstr "Файлы"
+
+#: ../../include/nav.php:457
+msgid "Files and Storage"
+msgstr "Файлы и хранилище"
+
+#: ../../include/nav.php:465 ../../include/nav.php:468
+#: ../../Zotlabs/Storage/Browser.php:140
+msgid "Calendar"
+msgstr "Календарь"
+
+#: ../../include/nav.php:479 ../../include/nav.php:482
+#: ../../Zotlabs/Widget/Chatroom_list.php:16 ../../Zotlabs/Lib/Apps.php:329
+msgid "Chatrooms"
+msgstr "Чаты"
+
+#: ../../include/nav.php:492 ../../Zotlabs/Lib/Apps.php:328
+msgid "Bookmarks"
+msgstr "Закладки"
+
+#: ../../include/nav.php:495
+msgid "Saved Bookmarks"
+msgstr "Сохранённые закладки"
+
+#: ../../include/nav.php:503 ../../Zotlabs/Module/Cards.php:207
+#: ../../Zotlabs/Lib/Apps.php:325
+msgid "Cards"
+msgstr "Карточки"
+
+#: ../../include/nav.php:506
+msgid "View Cards"
+msgstr "Просмотреть карточки"
+
+#: ../../include/nav.php:514 ../../Zotlabs/Module/Articles.php:222
+#: ../../Zotlabs/Lib/Apps.php:324
+msgid "Articles"
+msgstr "Статьи"
+
+#: ../../include/nav.php:517
+msgid "View Articles"
+msgstr "Просмотр статей"
+
+#: ../../include/nav.php:526 ../../Zotlabs/Module/Webpages.php:252
+#: ../../Zotlabs/Lib/Apps.php:340
+msgid "Webpages"
+msgstr "Веб-страницы"
+
+#: ../../include/nav.php:529
+msgid "View Webpages"
+msgstr "Просмотр веб-страниц"
+
+#: ../../include/nav.php:538 ../../Zotlabs/Module/Wiki.php:206
+#: ../../Zotlabs/Widget/Wiki_list.php:15
+msgid "Wikis"
+msgstr ""
+
+#: ../../include/nav.php:541 ../../Zotlabs/Lib/Apps.php:341
+msgid "Wiki"
+msgstr ""
+
+#: ../../include/bookmarks.php:34
+#, php-format
+msgid "%1$s's bookmarks"
+msgstr "Закладки пользователя %1$s"
+
+#: ../../include/attach.php:267 ../../include/attach.php:375
+msgid "Item was not found."
+msgstr "Элемент не найден."
+
+#: ../../include/attach.php:284
+msgid "Unknown error."
+msgstr "Неизвестная ошибка."
+
+#: ../../include/attach.php:568
+msgid "No source file."
+msgstr "Нет исходного файла."
+
+#: ../../include/attach.php:590
+msgid "Cannot locate file to replace"
+msgstr "Не удается найти файл для замены"
+
+#: ../../include/attach.php:609
+msgid "Cannot locate file to revise/update"
+msgstr "Не удается найти файл для пересмотра / обновления"
+
+#: ../../include/attach.php:751
+#, php-format
+msgid "File exceeds size limit of %d"
+msgstr "Файл превышает предельный размер %d"
+
+#: ../../include/attach.php:772
+#, php-format
+msgid "You have reached your limit of %1$.0f Mbytes attachment storage."
+msgstr "Вы достигли предела %1$.0f Мбайт для хранения вложений."
+
+#: ../../include/attach.php:954
+msgid "File upload failed. Possible system limit or action terminated."
+msgstr "Загрузка файла не удалась. Возможно система перегружена или попытка прекращена."
+
+#: ../../include/attach.php:983
+msgid "Stored file could not be verified. Upload failed."
+msgstr "Файл для сохранения не может быть проверен. Загрузка не удалась."
+
+#: ../../include/attach.php:1057 ../../include/attach.php:1073
+msgid "Path not available."
+msgstr "Путь недоступен."
+
+#: ../../include/attach.php:1122 ../../include/attach.php:1285
+msgid "Empty pathname"
+msgstr "Пустое имя пути"
+
+#: ../../include/attach.php:1148
+msgid "duplicate filename or path"
+msgstr "дублирующееся имя файла или пути"
+
+#: ../../include/attach.php:1173
+msgid "Path not found."
+msgstr "Путь не найден."
+
+#: ../../include/attach.php:1241
+msgid "mkdir failed."
+msgstr "mkdir не удался"
+
+#: ../../include/attach.php:1245
+msgid "database storage failed."
+msgstr "ошибка при записи базы данных."
+
+#: ../../include/attach.php:1291
+msgid "Empty path"
+msgstr "Пустое имя пути"
+
+#: ../../include/photo/photo_driver.php:367
+#: ../../Zotlabs/Module/Profile_photo.php:120
+#: ../../Zotlabs/Module/Profile_photo.php:259
+msgid "Profile Photos"
+msgstr "Фотографии профиля"
+
+#: ../../boot.php:1608
+msgid "Create an account to access services and applications"
+msgstr "Создайте аккаунт для доступа к службам и приложениям"
+
+#: ../../boot.php:1632
+msgid "Login/Email"
+msgstr "Пользователь / email"
+
+#: ../../boot.php:1633
+msgid "Password"
+msgstr "Пароль"
+
+#: ../../boot.php:1634
+msgid "Remember me"
+msgstr "Запомнить меня"
+
+#: ../../boot.php:1637
+msgid "Forgot your password?"
+msgstr "Забыли пароль или логин?"
+
+#: ../../boot.php:1638 ../../Zotlabs/Module/Lostpass.php:91
+msgid "Password Reset"
+msgstr "Сбросить пароль"
+
+#: ../../boot.php:2433
+#, php-format
+msgid "[$Projectname] Website SSL error for %s"
+msgstr "[$Projectname] Ошибка SSL/TLS веб-сайта для %s"
+
+#: ../../boot.php:2438
+msgid "Website SSL certificate is not valid. Please correct."
+msgstr "SSL/TLS сертификат веб-сайт недействителен. Исправьте это."
+
+#: ../../boot.php:2554
+#, php-format
+msgid "[$Projectname] Cron tasks not running on %s"
+msgstr "[$Projectname] Задания Cron не запущены на %s"
+
+#: ../../boot.php:2559
+msgid "Cron/Scheduled tasks not running."
+msgstr "Задания Cron / планировщика не запущены."
+
+#: ../../Zotlabs/Storage/Browser.php:107 ../../Zotlabs/Storage/Browser.php:295
+msgid "parent"
+msgstr "источник"
+
+#: ../../Zotlabs/Storage/Browser.php:134
+msgid "Principal"
+msgstr "Субъект"
+
+#: ../../Zotlabs/Storage/Browser.php:137
+msgid "Addressbook"
+msgstr "Адресная книга"
+
+#: ../../Zotlabs/Storage/Browser.php:143
+msgid "Schedule Inbox"
+msgstr "План занятий входящий"
+
+#: ../../Zotlabs/Storage/Browser.php:146
+msgid "Schedule Outbox"
+msgstr "План занятий исходящий"
+
+#: ../../Zotlabs/Storage/Browser.php:279
+msgid "Total"
+msgstr "Всего"
+
+#: ../../Zotlabs/Storage/Browser.php:281
+msgid "Shared"
+msgstr "Общие"
+
+#: ../../Zotlabs/Storage/Browser.php:282 ../../Zotlabs/Storage/Browser.php:396
+#: ../../Zotlabs/Module/Cdav.php:1257 ../../Zotlabs/Module/Profiles.php:798
+#: ../../Zotlabs/Module/New_channel.php:189 ../../Zotlabs/Module/Menu.php:181
+#: ../../Zotlabs/Module/Webpages.php:254 ../../Zotlabs/Module/Connedit.php:938
+#: ../../Zotlabs/Module/Blocks.php:159 ../../Zotlabs/Module/Articles.php:116
+#: ../../Zotlabs/Module/Cards.php:113 ../../Zotlabs/Module/Layouts.php:185
+#: ../../Zotlabs/Widget/Cdav.php:128 ../../Zotlabs/Widget/Cdav.php:165
+msgid "Create"
+msgstr "Создать"
+
+#: ../../Zotlabs/Storage/Browser.php:283
+msgid "Add Files"
+msgstr "Добавить файлы"
+
+#: ../../Zotlabs/Storage/Browser.php:286 ../../Zotlabs/Lib/ThreadItem.php:171
+msgid "Admin Delete"
+msgstr "Удалено администратором"
+
+#: ../../Zotlabs/Storage/Browser.php:291 ../../Zotlabs/Module/Cdav.php:1242
+#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139
+#: ../../Zotlabs/Module/Sharedwithme.php:104 ../../Zotlabs/Module/Chat.php:259
+#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146
+#: ../../Zotlabs/Module/Admin/Channels.php:159
+#: ../../Zotlabs/Module/Connedit.php:923 ../../Zotlabs/Module/Group.php:154
+#: ../../Zotlabs/Module/Wiki.php:218
+#: ../../Zotlabs/Widget/Wiki_page_history.php:22
+#: ../../Zotlabs/Lib/NativeWikiPage.php:561
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:172
+msgid "Name"
+msgstr "Имя"
+
+#: ../../Zotlabs/Storage/Browser.php:292 ../../Zotlabs/Module/Wiki.php:219
+msgid "Type"
+msgstr "Тип"
+
+#: ../../Zotlabs/Storage/Browser.php:294
+#: ../../Zotlabs/Module/Sharedwithme.php:107
+msgid "Last Modified"
+msgstr "Последнее изменение"
+
+#: ../../Zotlabs/Storage/Browser.php:367
+#, php-format
+msgid "You are using %1$s of your available file storage."
+msgstr "Вы используете %1$s из доступного вам хранилища файлов."
+
+#: ../../Zotlabs/Storage/Browser.php:372
+#, php-format
+msgid "You are using %1$s of %2$s available file storage. (%3$s&#37;)"
+msgstr "Вы используете %1$s из %2$s доступного хранилища файлов (%3$s&#37;)."
+
+#: ../../Zotlabs/Storage/Browser.php:383
+msgid "WARNING:"
+msgstr "Предупреждение:"
+
+#: ../../Zotlabs/Storage/Browser.php:395
+msgid "Create new folder"
+msgstr "Создать новую папку"
+
+#: ../../Zotlabs/Storage/Browser.php:397
+msgid "Upload file"
+msgstr "Загрузить файл"
+
+#: ../../Zotlabs/Storage/Browser.php:398 ../../Zotlabs/Module/Photos.php:727
+#: ../../Zotlabs/Module/Cover_photo.php:424
+#: ../../Zotlabs/Module/Embedphotos.php:186
+#: ../../Zotlabs/Module/Profile_photo.php:473
+#: ../../Zotlabs/Widget/Portfolio.php:110 ../../Zotlabs/Widget/Cdav.php:133
+#: ../../Zotlabs/Widget/Cdav.php:169 ../../Zotlabs/Widget/Album.php:97
+msgid "Upload"
+msgstr "Загрузка"
+
+#: ../../Zotlabs/Storage/Browser.php:410
+msgid "Drop files here to immediately upload"
+msgstr "Поместите файлы сюда для немедленной загрузки"
+
+#: ../../Zotlabs/Storage/Browser.php:411
+#: ../../Zotlabs/Module/Filestorage.php:206
+msgid "Show in your contacts shared folder"
+msgstr "Показать общий каталог в ваших контактах"
+
+#: ../../Zotlabs/Zot/Auth.php:152
+msgid ""
+"Remote authentication blocked. You are logged into this site locally. Please "
+"logout and retry."
+msgstr "Удалённая аутентификация заблокирована. Вы вошли на этот сайт локально. Пожалуйста, выйдите и попробуйте ещё раз."
+
+#: ../../Zotlabs/Zot/Auth.php:264
+#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:76
+#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:178
+#, php-format
+msgid "Welcome %s. Remote authentication successful."
+msgstr "Добро пожаловать %s. Удаленная аутентификация успешно завершена."
+
+#: ../../Zotlabs/Module/Regdir.php:49 ../../Zotlabs/Module/Dirsearch.php:25
+msgid "This site is not a directory server"
+msgstr "Этот сайт не является сервером каталога"
+
+#: ../../Zotlabs/Module/Mail.php:73
+msgid "Unable to lookup recipient."
+msgstr "Не удалось найти получателя."
+
+#: ../../Zotlabs/Module/Mail.php:80
+msgid "Unable to communicate with requested channel."
+msgstr "Не удалось установить связь с запрашиваемым каналом."
+
+#: ../../Zotlabs/Module/Mail.php:87
+msgid "Cannot verify requested channel."
+msgstr "Не удалось установить подлинность требуемого канала."
+
+#: ../../Zotlabs/Module/Mail.php:105
+msgid "Selected channel has private message restrictions. Send failed."
+msgstr "Выбранный канал ограничивает частные сообщения. Отправка не удалась."
+
+#: ../../Zotlabs/Module/Mail.php:160
+msgid "Messages"
+msgstr "Сообщения"
+
+#: ../../Zotlabs/Module/Mail.php:173
+msgid "message"
+msgstr "сообщение"
+
+#: ../../Zotlabs/Module/Mail.php:214
+msgid "Message recalled."
+msgstr "Сообщение отозванно."
+
+#: ../../Zotlabs/Module/Mail.php:227
+msgid "Conversation removed."
+msgstr "Беседа удалена."
+
+#: ../../Zotlabs/Module/Mail.php:242 ../../Zotlabs/Module/Mail.php:363
+msgid "Expires YYYY-MM-DD HH:MM"
+msgstr "Истекает YYYY-MM-DD HH:MM"
+
+#: ../../Zotlabs/Module/Mail.php:270
+msgid "Requested channel is not in this network"
+msgstr "Запрашиваемый канал не доступен."
+
+#: ../../Zotlabs/Module/Mail.php:278
+msgid "Send Private Message"
+msgstr "Отправить личное сообщение"
+
+#: ../../Zotlabs/Module/Mail.php:279 ../../Zotlabs/Module/Mail.php:421
+msgid "To:"
+msgstr "Кому:"
+
+#: ../../Zotlabs/Module/Mail.php:282 ../../Zotlabs/Module/Mail.php:423
+msgid "Subject:"
+msgstr "Тема:"
+
+#: ../../Zotlabs/Module/Mail.php:285 ../../Zotlabs/Module/Invite.php:157
+msgid "Your message:"
+msgstr "Сообщение:"
+
+#: ../../Zotlabs/Module/Mail.php:287 ../../Zotlabs/Module/Mail.php:429
+msgid "Attach file"
+msgstr "Прикрепить файл"
+
+#: ../../Zotlabs/Module/Mail.php:289
+msgid "Send"
+msgstr "Отправить"
+
+#: ../../Zotlabs/Module/Mail.php:393
+msgid "Delete message"
+msgstr "Удалить сообщение"
+
+#: ../../Zotlabs/Module/Mail.php:394
+msgid "Delivery report"
+msgstr "Отчёт о доставке"
+
+#: ../../Zotlabs/Module/Mail.php:395
+msgid "Recall message"
+msgstr "Отозвать сообщение"
+
+#: ../../Zotlabs/Module/Mail.php:397
+msgid "Message has been recalled."
+msgstr "Сообщение отозванно"
+
+#: ../../Zotlabs/Module/Mail.php:414
+msgid "Delete Conversation"
+msgstr "Удалить беседу"
+
+#: ../../Zotlabs/Module/Mail.php:416
+msgid ""
+"No secure communications available. You <strong>may</strong> be able to "
+"respond from the sender's profile page."
+msgstr "Безопасная связь недоступна. Вы <strong>можете</strong> попытаться ответить со страницы профиля отправителя."
+
+#: ../../Zotlabs/Module/Mail.php:420
+msgid "Send Reply"
+msgstr "Отправить ответ"
+
+#: ../../Zotlabs/Module/Mail.php:425
+#, php-format
+msgid "Your message for %s (%s):"
+msgstr "Ваше сообщение для %s (%s):"
+
+#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68
+msgid "This setting requires special processing and editing has been blocked."
+msgstr "Этот параметр требует специальной обработки и редактирования и был заблокирован."
+
+#: ../../Zotlabs/Module/Pconfig.php:57
+msgid "Configuration Editor"
+msgstr "Редактор конфигурации"
+
+#: ../../Zotlabs/Module/Pconfig.php:58
+msgid ""
+"Warning: Changing some settings could render your channel inoperable. Please "
+"leave this page unless you are comfortable with and knowledgeable about how "
+"to correctly use this feature."
+msgstr "Предупреждение. Изменение некоторых настроек может привести к неработоспособности вашего канала. Пожалуйста, покиньте эту страницу, если вы точно не значете, как правильно использовать эту функцию."
+
+#: ../../Zotlabs/Module/Defperms.php:67 ../../Zotlabs/Module/Connedit.php:81
+msgid "Could not access contact record."
+msgstr "Не удалось получить доступ к записи контакта."
+
+#: ../../Zotlabs/Module/Defperms.php:111
+#: ../../Zotlabs/Module/Settings/Channel.php:266
+#: ../../extend/addon/hzaddons/twitter/twitter.php:605
+#: ../../extend/addon/hzaddons/logrot/logrot.php:54
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:185
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82
+#: ../../extend/addon/hzaddons/piwik/piwik.php:116
+#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:54
+#: ../../extend/addon/hzaddons/xmpp/xmpp.php:54
+msgid "Settings updated."
+msgstr "Настройки обновлены."
+
+#: ../../Zotlabs/Module/Defperms.php:189
+msgid "Default Permissions App"
+msgstr "Приложение \"Разрешения по умолчанию\""
+
+#: ../../Zotlabs/Module/Defperms.php:189 ../../Zotlabs/Module/Permcats.php:62
+#: ../../Zotlabs/Module/Poke.php:165 ../../Zotlabs/Module/Cdav.php:854
+#: ../../Zotlabs/Module/Cdav.php:863 ../../Zotlabs/Module/Oauth.php:100
+#: ../../Zotlabs/Module/Pubstream.php:20 ../../Zotlabs/Module/Sources.php:88
+#: ../../Zotlabs/Module/Chat.php:102 ../../Zotlabs/Module/Oauth2.php:106
+#: ../../Zotlabs/Module/Uexport.php:61 ../../Zotlabs/Module/Bookmarks.php:78
+#: ../../Zotlabs/Module/Probe.php:18 ../../Zotlabs/Module/Tokens.php:99
+#: ../../Zotlabs/Module/Notes.php:56 ../../Zotlabs/Module/Webpages.php:48
+#: ../../Zotlabs/Module/Group.php:106 ../../Zotlabs/Module/Mood.php:134
+#: ../../Zotlabs/Module/Lang.php:17 ../../Zotlabs/Module/Randprof.php:29
+#: ../../Zotlabs/Module/Invite.php:110 ../../Zotlabs/Module/Articles.php:51
+#: ../../Zotlabs/Module/Connect.php:104 ../../Zotlabs/Module/Pdledit.php:42
+#: ../../Zotlabs/Module/Affinity.php:52 ../../Zotlabs/Module/Wiki.php:52
+#: ../../Zotlabs/Module/Suggest.php:40 ../../Zotlabs/Module/Cards.php:51
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:36
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28
+#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:96
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53
+#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:36
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21
+#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21
+#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:53
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35
+#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:57
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:41
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32
+msgid "Not Installed"
+msgstr "не установлено"
+
+#: ../../Zotlabs/Module/Defperms.php:190
+msgid "Set custom default permissions for new connections"
+msgstr "Настройка пользовательских разрешений по умолчанию для новых подключений "
+
+#: ../../Zotlabs/Module/Defperms.php:254 ../../Zotlabs/Module/Connedit.php:867
+msgid "Connection Default Permissions"
+msgstr "Разрешения по умолчанию для контакта"
+
+#: ../../Zotlabs/Module/Defperms.php:255 ../../Zotlabs/Module/Connedit.php:868
+msgid "Apply these permissions automatically"
+msgstr "Применить эти разрешения автоматически"
+
+#: ../../Zotlabs/Module/Defperms.php:255
+#: ../../Zotlabs/Module/Settings/Channel.php:470
+msgid ""
+"If enabled, connection requests will be approved without your interaction"
+msgstr "Если включено, запросы контактов будут одобрены без вашего участия"
+
+#: ../../Zotlabs/Module/Defperms.php:256 ../../Zotlabs/Module/Connedit.php:869
+msgid "Permission role"
+msgstr "Роль разрешения"
+
+#: ../../Zotlabs/Module/Defperms.php:257 ../../Zotlabs/Module/Connedit.php:870
+msgid "Add permission role"
+msgstr "Добавить роль разрешения"
+
+#: ../../Zotlabs/Module/Defperms.php:261 ../../Zotlabs/Module/Connedit.php:883
+msgid ""
+"The permissions indicated on this page will be applied to all new "
+"connections."
+msgstr "Разрешения, указанные на этой странице, будут применяться ко всем новым соединениям."
+
+#: ../../Zotlabs/Module/Defperms.php:262
+msgid "Automatic approval settings"
+msgstr "Настройки автоматического одобрения"
+
+#: ../../Zotlabs/Module/Defperms.php:264 ../../Zotlabs/Module/Permcats.php:123
+#: ../../Zotlabs/Module/Tokens.php:183 ../../Zotlabs/Module/Connedit.php:903
+msgid "inherited"
+msgstr "наследуется"
+
+#: ../../Zotlabs/Module/Defperms.php:266 ../../Zotlabs/Module/Permcats.php:121
+#: ../../Zotlabs/Module/Tokens.php:181 ../../Zotlabs/Module/Connedit.php:908
+msgid "My Settings"
+msgstr "Мои настройки"
+
+#: ../../Zotlabs/Module/Defperms.php:269 ../../Zotlabs/Module/Permcats.php:126
+#: ../../Zotlabs/Module/Tokens.php:186 ../../Zotlabs/Module/Connedit.php:910
+msgid "Individual Permissions"
+msgstr "Индивидуальные разрешения"
+
+#: ../../Zotlabs/Module/Defperms.php:270
+msgid ""
+"Some individual permissions may have been preset or locked based on your "
+"channel type and privacy settings."
+msgstr "Некоторые индивидуальные разрешения могут быть предустановлены или заблокированы на основании типа вашего канала и настроек приватности."
+
+#: ../../Zotlabs/Module/Permcats.php:28
+msgid "Permission category name is required."
+msgstr "Требуется категория разрешений."
+
+#: ../../Zotlabs/Module/Permcats.php:47
+msgid "Permission category saved."
+msgstr "Категория разрешения сохранена."
+
+#: ../../Zotlabs/Module/Permcats.php:62
+msgid "Permission Categories App"
+msgstr "Приложение \"Категории разрешений\""
+
+#: ../../Zotlabs/Module/Permcats.php:63
+msgid "Create custom connection permission limits"
+msgstr "Создать пользовательские ограничения на доступ к подключению"
+
+#: ../../Zotlabs/Module/Permcats.php:79
+msgid ""
+"Use this form to create permission rules for various classes of people or "
+"connections."
+msgstr "Используйте эту форму для создания правил разрешений для различных групп людей и контактов."
+
+#: ../../Zotlabs/Module/Permcats.php:112 ../../Zotlabs/Lib/Apps.php:374
+msgid "Permission Categories"
+msgstr "Категории разрешений"
+
+#: ../../Zotlabs/Module/Permcats.php:120
+msgid "Permission category name"
+msgstr "Наименование категории разрешений"
+
+#: ../../Zotlabs/Module/Permcats.php:127 ../../Zotlabs/Module/Tokens.php:187
+#: ../../Zotlabs/Module/Connedit.php:911
+msgid ""
+"Some permissions may be inherited from your channel's <a href=\"settings"
+"\"><strong>privacy settings</strong></a>, which have higher priority than "
+"individual settings. You can <strong>not</strong> change those settings here."
+msgstr "Некоторые разрешения могут наследовать из <a href=\"settings\"><strong>настроек приватности</strong></a> ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы <strong>не можете</strong> менять эти настройки здесь."
+
+#: ../../Zotlabs/Module/Xchan.php:10
+msgid "Xchan Lookup"
+msgstr "Поиск Xchan"
+
+#: ../../Zotlabs/Module/Xchan.php:13
+msgid "Lookup xchan beginning with (or webbie): "
+msgstr "Запрос Xchan начинается с (или webbie):"
+
+#: ../../Zotlabs/Module/Xchan.php:41 ../../Zotlabs/Module/Menu.php:231
+#: ../../Zotlabs/Module/Mitem.php:134
+msgid "Not found."
+msgstr "Не найдено."
+
+#: ../../Zotlabs/Module/Dreport.php:59
+msgid "Invalid message"
+msgstr "Неверное сообщение"
+
+#: ../../Zotlabs/Module/Dreport.php:93
+msgid "no results"
+msgstr "Ничего не найдено."
+
+#: ../../Zotlabs/Module/Dreport.php:107
+msgid "channel sync processed"
+msgstr "синхронизация канала завершена"
+
+#: ../../Zotlabs/Module/Dreport.php:111
+msgid "queued"
+msgstr "в очереди"
+
+#: ../../Zotlabs/Module/Dreport.php:115
+msgid "posted"
+msgstr "опубликовано"
+
+#: ../../Zotlabs/Module/Dreport.php:119
+msgid "accepted for delivery"
+msgstr "принято к доставке"
+
+#: ../../Zotlabs/Module/Dreport.php:123
+msgid "updated"
+msgstr "обновлено"
+
+#: ../../Zotlabs/Module/Dreport.php:126
+msgid "update ignored"
+msgstr "обновление игнорируется"
+
+#: ../../Zotlabs/Module/Dreport.php:129
+msgid "permission denied"
+msgstr "доступ запрещен"
+
+#: ../../Zotlabs/Module/Dreport.php:133
+msgid "recipient not found"
+msgstr "получатель не найден"
+
+#: ../../Zotlabs/Module/Dreport.php:136
+msgid "mail recalled"
+msgstr "почта отозвана"
+
+#: ../../Zotlabs/Module/Dreport.php:139
+msgid "duplicate mail received"
+msgstr "получено дублирующее сообщение"
+
+#: ../../Zotlabs/Module/Dreport.php:142
+msgid "mail delivered"
+msgstr "почта доставлен"
+
+#: ../../Zotlabs/Module/Dreport.php:162
+#, php-format
+msgid "Delivery report for %1$s"
+msgstr "Отчёт о доставке для %1$s"
+
+#: ../../Zotlabs/Module/Dreport.php:166 ../../Zotlabs/Widget/Wiki_pages.php:41
+#: ../../Zotlabs/Widget/Wiki_pages.php:98
+msgid "Options"
+msgstr "Параметры"
+
+#: ../../Zotlabs/Module/Dreport.php:167
+msgid "Redeliver"
+msgstr "Доставить повторно"
+
+#: ../../Zotlabs/Module/Network.php:109
+msgid "No such group"
+msgstr "Нет такой группы"
+
+#: ../../Zotlabs/Module/Network.php:158
+msgid "No such channel"
+msgstr "Нет такого канала"
+
+#: ../../Zotlabs/Module/Network.php:173 ../../Zotlabs/Module/Channel.php:182
+msgid "Search Results For:"
+msgstr "Результаты поиска для:"
+
+#: ../../Zotlabs/Module/Network.php:203 ../../Zotlabs/Module/Display.php:80
+#: ../../Zotlabs/Module/Pubstream.php:94 ../../Zotlabs/Module/Channel.php:217
+#: ../../Zotlabs/Module/Hq.php:134
+msgid "Reset form"
+msgstr "Очистить форму"
+
+#: ../../Zotlabs/Module/Network.php:242
+msgid "Privacy group is empty"
+msgstr "Группа безопасности пуста"
+
+#: ../../Zotlabs/Module/Network.php:252
+msgid "Privacy group: "
+msgstr "Группа безопасности: "
+
+#: ../../Zotlabs/Module/Network.php:325
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29
+msgid "Invalid channel."
+msgstr "Недействительный канал."
+
+#: ../../Zotlabs/Module/Email_validation.php:24
+#: ../../Zotlabs/Module/Email_resend.php:12
+msgid "Token verification failed."
+msgstr "Не удалось выполнить проверку токена."
+
+#: ../../Zotlabs/Module/Email_validation.php:36
+msgid "Email Verification Required"
+msgstr "Требуется проверка адреса email"
+
+#: ../../Zotlabs/Module/Email_validation.php:37
+#, php-format
+msgid ""
+"A verification token was sent to your email address [%s]. Enter that token "
+"here to complete the account verification step. Please allow a few minutes "
+"for delivery, and check your spam folder if you do not see the message."
+msgstr "Проверочный токен был отправлен на ваш адрес электронной почты [%s]. Введите этот токен здесь для завершения этапа проверки учётной записи. Пожалуйста, подождите несколько минут для завершения доставки и проверьте вашу папку \"Спам\" если вы не видите письма."
+
+#: ../../Zotlabs/Module/Email_validation.php:38
+msgid "Resend Email"
+msgstr "Выслать повторно"
+
+#: ../../Zotlabs/Module/Email_validation.php:41
+msgid "Validation token"
+msgstr "Проверочный токен"
+
+#: ../../Zotlabs/Module/Common.php:14
+msgid "No channel."
+msgstr "Канала нет."
+
+#: ../../Zotlabs/Module/Common.php:45
+msgid "No connections in common."
+msgstr "Общих контактов нет."
+
+#: ../../Zotlabs/Module/Common.php:65
+msgid "View Common Connections"
+msgstr "Просмотр общий контактов"
+
+#: ../../Zotlabs/Module/Acl.php:360
+msgid "network"
+msgstr "сеть"
+
+#: ../../Zotlabs/Module/Item.php:362
+msgid "Unable to locate original post."
+msgstr "Не удалось найти оригинальную публикацию."
+
+#: ../../Zotlabs/Module/Item.php:649
+msgid "Empty post discarded."
+msgstr "Пустая публикация отклонена."
+
+#: ../../Zotlabs/Module/Item.php:1058
+msgid "Duplicate post suppressed."
+msgstr "Подавлена дублирующаяся публикация."
+
+#: ../../Zotlabs/Module/Item.php:1203
+msgid "System error. Post not saved."
+msgstr "Системная ошибка. Публикация не сохранена."
+
+#: ../../Zotlabs/Module/Item.php:1239
+msgid "Your comment is awaiting approval."
+msgstr "Ваш комментарий ожидает одобрения."
+
+#: ../../Zotlabs/Module/Item.php:1356
+msgid "Unable to obtain post information from database."
+msgstr "Невозможно получить информацию о публикации из базы данных"
+
+#: ../../Zotlabs/Module/Item.php:1363
+#, php-format
+msgid "You have reached your limit of %1$.0f top level posts."
+msgstr "Вы достигли вашего ограничения в %1$.0f публикаций высокого уровня."
+
+#: ../../Zotlabs/Module/Item.php:1370
+#, php-format
+msgid "You have reached your limit of %1$.0f webpages."
+msgstr "Вы достигли вашего ограничения в %1$.0f страниц."
+
+#: ../../Zotlabs/Module/Achievements.php:38
+msgid "Some blurb about what to do when you're new here"
+msgstr "Некоторые предложения о том, что делать, если вы здесь новичок "
+
+#: ../../Zotlabs/Module/Display.php:29 ../../Zotlabs/Module/Directory.php:67
+#: ../../Zotlabs/Module/Directory.php:72 ../../Zotlabs/Module/Photos.php:558
+#: ../../Zotlabs/Module/Viewconnections.php:23
+#: ../../Zotlabs/Module/Ratings.php:83 ../../Zotlabs/Module/Search.php:17
+msgid "Public access denied."
+msgstr "Публичный доступ запрещен."
+
+#: ../../Zotlabs/Module/Display.php:378 ../../Zotlabs/Module/Channel.php:476
+msgid ""
+"You must enable javascript for your browser to be able to view this content."
+msgstr "Для просмотра этого содержимого в вашем браузере должен быть включён JavaScript"
+
+#: ../../Zotlabs/Module/Display.php:396
+msgid "Article"
+msgstr "Статья"
+
+#: ../../Zotlabs/Module/Display.php:448
+msgid "Item has been removed."
+msgstr "Элемент был удалён."
+
+#: ../../Zotlabs/Module/Ping.php:338
+msgid "sent you a private message"
+msgstr "отправил вам личное сообщение"
+
+#: ../../Zotlabs/Module/Ping.php:394
+msgid "added your channel"
+msgstr "добавил ваш канал"
+
+#: ../../Zotlabs/Module/Ping.php:419
+msgid "requires approval"
+msgstr "Требуется подтверждение"
+
+#: ../../Zotlabs/Module/Ping.php:429
+msgid "g A l F d"
+msgstr "g A l F d"
+
+#: ../../Zotlabs/Module/Ping.php:447
+msgid "[today]"
+msgstr "[сегодня]"
+
+#: ../../Zotlabs/Module/Ping.php:457
+msgid "posted an event"
+msgstr "событие опубликовано"
+
+#: ../../Zotlabs/Module/Ping.php:491
+msgid "shared a file with you"
+msgstr "с вами поделились файлом"
+
+#: ../../Zotlabs/Module/Ping.php:673
+msgid "Private forum"
+msgstr "Частный форум"
+
+#: ../../Zotlabs/Module/Ping.php:673
+msgid "Public forum"
+msgstr "Публичный форум"
+
+#: ../../Zotlabs/Module/Poke.php:165
+msgid "Poke App"
+msgstr "Приложение \"Ткнуть\""
+
+#: ../../Zotlabs/Module/Poke.php:166
+msgid "Poke somebody in your addressbook"
+msgstr "Ткнуть кого-нибудь в вашей адресной книге"
+
+#: ../../Zotlabs/Module/Poke.php:200
+msgid "Poke somebody"
+msgstr "Ткнуть кого-нибудь"
+
+#: ../../Zotlabs/Module/Poke.php:203
+msgid "Poke/Prod"
+msgstr "Толкнуть / подтолкнуть"
+
+#: ../../Zotlabs/Module/Poke.php:204
+msgid "Poke, prod or do other things to somebody"
+msgstr "Толкнуть, подтолкнуть или сделать что-то ещё с кем-то"
+
+#: ../../Zotlabs/Module/Poke.php:211
+msgid "Recipient"
+msgstr "Получатель"
+
+#: ../../Zotlabs/Module/Poke.php:212
+msgid "Choose what you wish to do to recipient"
+msgstr "Выбрать что вы хотите сделать с получателем"
+
+#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216
+msgid "Make this post private"
+msgstr "Сделать эту публикацию приватной"
+
+#: ../../Zotlabs/Module/Lockview.php:75
+msgid "Remote privacy information not available."
+msgstr "Удаленная информация о конфиденциальности недоступна."
+
+#: ../../Zotlabs/Module/Lockview.php:96
+msgid "Visible to:"
+msgstr "Видимо для:"
+
+#: ../../Zotlabs/Module/Tagger.php:48
+msgid "Post not found."
+msgstr "Публикация не найдена"
+
+#: ../../Zotlabs/Module/Tagger.php:119
+#, php-format
+msgid "%1$s tagged %2$s's %3$s with %4$s"
+msgstr "%1$s отметил тегом %2$s %3$s с %4$s"
+
+#: ../../Zotlabs/Module/Directory.php:110
+msgid "No default suggestions were found."
+msgstr "Предложений по умолчанию не найдено."
+
+#: ../../Zotlabs/Module/Directory.php:259
+#, php-format
+msgid "%d rating"
+msgid_plural "%d ratings"
+msgstr[0] "%d оценка"
+msgstr[1] "%d оценки"
+msgstr[2] "%d оценок"
+
+#: ../../Zotlabs/Module/Directory.php:270
+msgid "Gender: "
+msgstr "Пол:"
+
+#: ../../Zotlabs/Module/Directory.php:272
+msgid "Status: "
+msgstr "Статус:"
+
+#: ../../Zotlabs/Module/Directory.php:274
+msgid "Homepage: "
+msgstr "Домашняя страница:"
+
+#: ../../Zotlabs/Module/Directory.php:334
+msgid "Description:"
+msgstr "Описание:"
+
+#: ../../Zotlabs/Module/Directory.php:343
+msgid "Public Forum:"
+msgstr "Публичный форум:"
+
+#: ../../Zotlabs/Module/Directory.php:346
+msgid "Keywords: "
+msgstr "Ключевые слова:"
+
+#: ../../Zotlabs/Module/Directory.php:349
+msgid "Don't suggest"
+msgstr "Не предлагать"
+
+#: ../../Zotlabs/Module/Directory.php:351
+msgid "Common connections (estimated):"
+msgstr "Общие контакты (оценочно):"
+
+#: ../../Zotlabs/Module/Directory.php:400
+msgid "Global Directory"
+msgstr "Глобальный каталог"
+
+#: ../../Zotlabs/Module/Directory.php:400
+msgid "Local Directory"
+msgstr "Локальный каталог"
+
+#: ../../Zotlabs/Module/Directory.php:406
+msgid "Finding:"
+msgstr "Поиск:"
+
+#: ../../Zotlabs/Module/Directory.php:411
+msgid "next page"
+msgstr "следующая страница"
+
+#: ../../Zotlabs/Module/Directory.php:411
+msgid "previous page"
+msgstr "предыдущая страница"
+
+#: ../../Zotlabs/Module/Directory.php:412
+msgid "Sort options"
+msgstr "Параметры сортировки"
+
+#: ../../Zotlabs/Module/Directory.php:413
+msgid "Alphabetic"
+msgstr "По алфавиту"
+
+#: ../../Zotlabs/Module/Directory.php:414
+msgid "Reverse Alphabetic"
+msgstr "Против алфавита"
+
+#: ../../Zotlabs/Module/Directory.php:415
+msgid "Newest to Oldest"
+msgstr "От новых к старым"
+
+#: ../../Zotlabs/Module/Directory.php:416
+msgid "Oldest to Newest"
+msgstr "От старых к новым"
+
+#: ../../Zotlabs/Module/Directory.php:433
+msgid "No entries (some entries may be hidden)."
+msgstr "Нет записей (некоторые записи могут быть скрыты)."
+
+#: ../../Zotlabs/Module/Cdav.php:825
msgid "INVALID EVENT DISMISSED!"
msgstr "НЕДЕЙСТВИТЕЛЬНОЕ СОБЫТИЕ ОТКЛОНЕНО!"
-#: ../../Zotlabs/Module/Cdav.php:811
+#: ../../Zotlabs/Module/Cdav.php:826
msgid "Summary: "
msgstr "Резюме: "
-#: ../../Zotlabs/Module/Cdav.php:811 ../../Zotlabs/Module/Cdav.php:812
-#: ../../Zotlabs/Module/Cdav.php:819 ../../Zotlabs/Module/Embedphotos.php:154
-#: ../../Zotlabs/Module/Photos.php:832 ../../Zotlabs/Module/Photos.php:1296
-#: ../../Zotlabs/Lib/Activity.php:1011 ../../Zotlabs/Lib/Apps.php:1113
-#: ../../Zotlabs/Lib/Apps.php:1197 ../../Zotlabs/Storage/Browser.php:164
-#: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Album.php:84
-#: ../../addon/pubcrawl/as.php:959 ../../include/conversation.php:1166
-msgid "Unknown"
-msgstr "Неизвестный"
-
-#: ../../Zotlabs/Module/Cdav.php:812
+#: ../../Zotlabs/Module/Cdav.php:827
msgid "Date: "
msgstr "Дата: "
-#: ../../Zotlabs/Module/Cdav.php:813 ../../Zotlabs/Module/Cdav.php:820
+#: ../../Zotlabs/Module/Cdav.php:828 ../../Zotlabs/Module/Cdav.php:835
msgid "Reason: "
msgstr "Причина: "
-#: ../../Zotlabs/Module/Cdav.php:818
+#: ../../Zotlabs/Module/Cdav.php:833
msgid "INVALID CARD DISMISSED!"
msgstr "НЕДЕЙСТВИТЕЛЬНАЯ КАРТОЧКА ОТКЛОНЕНА!"
-#: ../../Zotlabs/Module/Cdav.php:819
+#: ../../Zotlabs/Module/Cdav.php:834
msgid "Name: "
msgstr "Имя: "
-#: ../../Zotlabs/Module/Cdav.php:839
+#: ../../Zotlabs/Module/Cdav.php:854
msgid "CalDAV App"
msgstr "Приложение CalDAV"
-#: ../../Zotlabs/Module/Cdav.php:840
+#: ../../Zotlabs/Module/Cdav.php:855
msgid "CalDAV capable calendar"
msgstr "Календарь с поддержкой CalDAV"
-#: ../../Zotlabs/Module/Cdav.php:848
+#: ../../Zotlabs/Module/Cdav.php:863
msgid "CardDAV App"
msgstr "Приложение CardDAV"
-#: ../../Zotlabs/Module/Cdav.php:849
+#: ../../Zotlabs/Module/Cdav.php:864
msgid "CalDAV capable addressbook"
msgstr "Адресная книга с поддержкой CalDAV"
-#: ../../Zotlabs/Module/Cdav.php:913 ../../Zotlabs/Module/Events.php:462
+#: ../../Zotlabs/Module/Cdav.php:936 ../../Zotlabs/Module/Events.php:462
msgid "Event title"
msgstr "Наименование события"
-#: ../../Zotlabs/Module/Cdav.php:914 ../../Zotlabs/Module/Events.php:468
+#: ../../Zotlabs/Module/Cdav.php:937 ../../Zotlabs/Module/Events.php:468
msgid "Start date and time"
msgstr "Дата и время начала"
-#: ../../Zotlabs/Module/Cdav.php:914 ../../Zotlabs/Module/Cdav.php:915
-msgid "Example: YYYY-MM-DD HH:mm"
-msgstr "Пример: YYYY-MM-DD HH:mm"
-
-#: ../../Zotlabs/Module/Cdav.php:915
+#: ../../Zotlabs/Module/Cdav.php:938
msgid "End date and time"
msgstr "Дата и время окончания"
-#: ../../Zotlabs/Module/Cdav.php:916 ../../Zotlabs/Module/Events.php:475
-#: ../../Zotlabs/Module/Appman.php:145 ../../Zotlabs/Module/Rbmark.php:101
-#: ../../addon/rendezvous/rendezvous.php:173
-#: ../../addon/cart/submodules/manualcat.php:260
-#: ../../addon/cart/submodules/hzservices.php:652
+#: ../../Zotlabs/Module/Cdav.php:939 ../../Zotlabs/Module/Appman.php:145
+#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Rbmark.php:101
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:173
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:652
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:260
msgid "Description"
msgstr "Описание"
-#: ../../Zotlabs/Module/Cdav.php:917 ../../Zotlabs/Module/Locs.php:117
-#: ../../Zotlabs/Module/Events.php:477 ../../Zotlabs/Module/Profiles.php:509
-#: ../../Zotlabs/Module/Profiles.php:734 ../../Zotlabs/Module/Pubsites.php:52
-#: ../../include/js_strings.php:25
-msgid "Location"
-msgstr "Место"
-
-#: ../../Zotlabs/Module/Cdav.php:924 ../../Zotlabs/Module/Events.php:690
-#: ../../Zotlabs/Module/Events.php:699 ../../Zotlabs/Module/Cal.php:338
-#: ../../Zotlabs/Module/Cal.php:345 ../../Zotlabs/Module/Photos.php:986
+#: ../../Zotlabs/Module/Cdav.php:948 ../../Zotlabs/Module/Photos.php:986
+#: ../../Zotlabs/Module/Events.php:690 ../../Zotlabs/Module/Events.php:699
+#: ../../Zotlabs/Module/Cal.php:338 ../../Zotlabs/Module/Cal.php:345
msgid "Previous"
msgstr "Предыдущая"
-#: ../../Zotlabs/Module/Cdav.php:925 ../../Zotlabs/Module/Events.php:691
-#: ../../Zotlabs/Module/Events.php:700 ../../Zotlabs/Module/Setup.php:263
+#: ../../Zotlabs/Module/Cdav.php:949 ../../Zotlabs/Module/Photos.php:995
+#: ../../Zotlabs/Module/Events.php:691 ../../Zotlabs/Module/Events.php:700
#: ../../Zotlabs/Module/Cal.php:339 ../../Zotlabs/Module/Cal.php:346
-#: ../../Zotlabs/Module/Photos.php:995
+#: ../../Zotlabs/Module/Setup.php:260
msgid "Next"
msgstr "Следующая"
-#: ../../Zotlabs/Module/Cdav.php:926 ../../Zotlabs/Module/Events.php:701
+#: ../../Zotlabs/Module/Cdav.php:950 ../../Zotlabs/Module/Events.php:701
#: ../../Zotlabs/Module/Cal.php:347
msgid "Today"
msgstr "Сегодня"
-#: ../../Zotlabs/Module/Cdav.php:927 ../../Zotlabs/Module/Events.php:696
+#: ../../Zotlabs/Module/Cdav.php:951 ../../Zotlabs/Module/Events.php:696
msgid "Month"
msgstr "Месяц"
-#: ../../Zotlabs/Module/Cdav.php:928 ../../Zotlabs/Module/Events.php:697
+#: ../../Zotlabs/Module/Cdav.php:952 ../../Zotlabs/Module/Events.php:697
msgid "Week"
msgstr "Неделя"
-#: ../../Zotlabs/Module/Cdav.php:929 ../../Zotlabs/Module/Events.php:698
+#: ../../Zotlabs/Module/Cdav.php:953 ../../Zotlabs/Module/Events.php:698
msgid "Day"
msgstr "День"
-#: ../../Zotlabs/Module/Cdav.php:930
+#: ../../Zotlabs/Module/Cdav.php:954
msgid "List month"
msgstr "Просмотреть месяц"
-#: ../../Zotlabs/Module/Cdav.php:931
+#: ../../Zotlabs/Module/Cdav.php:955
msgid "List week"
msgstr "Просмотреть неделю"
-#: ../../Zotlabs/Module/Cdav.php:932
+#: ../../Zotlabs/Module/Cdav.php:956
msgid "List day"
msgstr "Просмотреть день"
-#: ../../Zotlabs/Module/Cdav.php:939
+#: ../../Zotlabs/Module/Cdav.php:963
msgid "More"
msgstr "Больше"
-#: ../../Zotlabs/Module/Cdav.php:940
+#: ../../Zotlabs/Module/Cdav.php:964
msgid "Less"
msgstr "Меньше"
-#: ../../Zotlabs/Module/Cdav.php:941
+#: ../../Zotlabs/Module/Cdav.php:965
msgid "Select calendar"
msgstr "Выбрать календарь"
-#: ../../Zotlabs/Module/Cdav.php:943
+#: ../../Zotlabs/Module/Cdav.php:967
msgid "Delete all"
msgstr "Удалить всё"
-#: ../../Zotlabs/Module/Cdav.php:945
+#: ../../Zotlabs/Module/Cdav.php:969
msgid "Sorry! Editing of recurrent events is not yet implemented."
msgstr "Простите, но редактирование повторяющихся событий пока не реализовано."
-#: ../../Zotlabs/Module/Cdav.php:1215 ../../Zotlabs/Module/Sharedwithme.php:104
-#: ../../Zotlabs/Module/Admin/Channels.php:159
-#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146
-#: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:923
-#: ../../Zotlabs/Module/Chat.php:259 ../../Zotlabs/Module/Group.php:154
-#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139
-#: ../../Zotlabs/Lib/NativeWikiPage.php:561
-#: ../../Zotlabs/Storage/Browser.php:285
-#: ../../Zotlabs/Widget/Wiki_page_history.php:22
-#: ../../addon/rendezvous/rendezvous.php:172
-msgid "Name"
-msgstr "Имя"
-
-#: ../../Zotlabs/Module/Cdav.php:1216 ../../Zotlabs/Module/Connedit.php:924
+#: ../../Zotlabs/Module/Cdav.php:1243 ../../Zotlabs/Module/Connedit.php:924
msgid "Organisation"
msgstr "Организация"
-#: ../../Zotlabs/Module/Cdav.php:1217 ../../Zotlabs/Module/Connedit.php:925
+#: ../../Zotlabs/Module/Cdav.php:1244 ../../Zotlabs/Module/Connedit.php:925
msgid "Title"
msgstr "Наименование"
-#: ../../Zotlabs/Module/Cdav.php:1218 ../../Zotlabs/Module/Connedit.php:926
-#: ../../Zotlabs/Module/Profiles.php:786
+#: ../../Zotlabs/Module/Cdav.php:1245 ../../Zotlabs/Module/Profiles.php:786
+#: ../../Zotlabs/Module/Connedit.php:926
msgid "Phone"
msgstr "Телефон"
-#: ../../Zotlabs/Module/Cdav.php:1219
-#: ../../Zotlabs/Module/Admin/Accounts.php:171
-#: ../../Zotlabs/Module/Admin/Accounts.php:183
-#: ../../Zotlabs/Module/Connedit.php:927 ../../Zotlabs/Module/Profiles.php:787
-#: ../../addon/openid/MysqlProvider.php:56
-#: ../../addon/openid/MysqlProvider.php:57 ../../addon/rtof/Mod_Rtof.php:57
-#: ../../addon/redred/Mod_Redred.php:71 ../../include/network.php:1721
-msgid "Email"
-msgstr "Электронная почта"
-
-#: ../../Zotlabs/Module/Cdav.php:1220 ../../Zotlabs/Module/Connedit.php:928
-#: ../../Zotlabs/Module/Profiles.php:788
+#: ../../Zotlabs/Module/Cdav.php:1247 ../../Zotlabs/Module/Profiles.php:788
+#: ../../Zotlabs/Module/Connedit.php:928
msgid "Instant messenger"
msgstr "Мессенджер"
-#: ../../Zotlabs/Module/Cdav.php:1221 ../../Zotlabs/Module/Connedit.php:929
-#: ../../Zotlabs/Module/Profiles.php:789
+#: ../../Zotlabs/Module/Cdav.php:1248 ../../Zotlabs/Module/Profiles.php:789
+#: ../../Zotlabs/Module/Connedit.php:929
msgid "Website"
msgstr "Веб-сайт"
-#: ../../Zotlabs/Module/Cdav.php:1222 ../../Zotlabs/Module/Locs.php:118
+#: ../../Zotlabs/Module/Cdav.php:1249 ../../Zotlabs/Module/Profiles.php:502
+#: ../../Zotlabs/Module/Profiles.php:790 ../../Zotlabs/Module/Locs.php:118
#: ../../Zotlabs/Module/Admin/Channels.php:160
-#: ../../Zotlabs/Module/Connedit.php:930 ../../Zotlabs/Module/Profiles.php:502
-#: ../../Zotlabs/Module/Profiles.php:790
+#: ../../Zotlabs/Module/Connedit.php:930
msgid "Address"
msgstr "Адрес"
-#: ../../Zotlabs/Module/Cdav.php:1223 ../../Zotlabs/Module/Connedit.php:931
-#: ../../Zotlabs/Module/Profiles.php:791
+#: ../../Zotlabs/Module/Cdav.php:1250 ../../Zotlabs/Module/Profiles.php:791
+#: ../../Zotlabs/Module/Connedit.php:931
msgid "Note"
msgstr "Заметка"
-#: ../../Zotlabs/Module/Cdav.php:1224 ../../Zotlabs/Module/Connedit.php:932
-#: ../../Zotlabs/Module/Profiles.php:792 ../../include/event.php:1320
-#: ../../include/connections.php:696
-msgid "Mobile"
-msgstr "Мобильный"
-
-#: ../../Zotlabs/Module/Cdav.php:1225 ../../Zotlabs/Module/Connedit.php:933
-#: ../../Zotlabs/Module/Profiles.php:793 ../../include/event.php:1321
-#: ../../include/connections.php:697
-msgid "Home"
-msgstr "Домашний"
-
-#: ../../Zotlabs/Module/Cdav.php:1226 ../../Zotlabs/Module/Connedit.php:934
-#: ../../Zotlabs/Module/Profiles.php:794 ../../include/event.php:1324
-#: ../../include/connections.php:700
-msgid "Work"
-msgstr "Рабочий"
-
-#: ../../Zotlabs/Module/Cdav.php:1228 ../../Zotlabs/Module/Connedit.php:936
-#: ../../Zotlabs/Module/Profiles.php:796
-#: ../../addon/jappixmini/Mod_Jappixmini.php:216
+#: ../../Zotlabs/Module/Cdav.php:1255 ../../Zotlabs/Module/Profiles.php:796
+#: ../../Zotlabs/Module/Connedit.php:936
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:216
msgid "Add Contact"
msgstr "Добавить контакт"
-#: ../../Zotlabs/Module/Cdav.php:1229 ../../Zotlabs/Module/Connedit.php:937
-#: ../../Zotlabs/Module/Profiles.php:797
+#: ../../Zotlabs/Module/Cdav.php:1256 ../../Zotlabs/Module/Profiles.php:797
+#: ../../Zotlabs/Module/Connedit.php:937
msgid "Add Field"
msgstr "Добавить поле"
-#: ../../Zotlabs/Module/Cdav.php:1231 ../../Zotlabs/Module/Admin/Addons.php:456
-#: ../../Zotlabs/Module/Oauth2.php:58 ../../Zotlabs/Module/Oauth2.php:144
-#: ../../Zotlabs/Module/Connedit.php:939 ../../Zotlabs/Module/Profiles.php:799
+#: ../../Zotlabs/Module/Cdav.php:1258 ../../Zotlabs/Module/Profiles.php:799
#: ../../Zotlabs/Module/Oauth.php:53 ../../Zotlabs/Module/Oauth.php:137
-#: ../../Zotlabs/Lib/Apps.php:535
+#: ../../Zotlabs/Module/Oauth2.php:58 ../../Zotlabs/Module/Oauth2.php:144
+#: ../../Zotlabs/Module/Admin/Addons.php:456
+#: ../../Zotlabs/Module/Connedit.php:939 ../../Zotlabs/Lib/Apps.php:537
msgid "Update"
msgstr "Обновить"
-#: ../../Zotlabs/Module/Cdav.php:1234 ../../Zotlabs/Module/Connedit.php:942
+#: ../../Zotlabs/Module/Cdav.php:1261 ../../Zotlabs/Module/Connedit.php:942
msgid "P.O. Box"
msgstr "абонентский ящик"
-#: ../../Zotlabs/Module/Cdav.php:1235 ../../Zotlabs/Module/Connedit.php:943
+#: ../../Zotlabs/Module/Cdav.php:1262 ../../Zotlabs/Module/Connedit.php:943
msgid "Additional"
msgstr "Дополнительно"
-#: ../../Zotlabs/Module/Cdav.php:1236 ../../Zotlabs/Module/Connedit.php:944
+#: ../../Zotlabs/Module/Cdav.php:1263 ../../Zotlabs/Module/Connedit.php:944
msgid "Street"
msgstr "Улица"
-#: ../../Zotlabs/Module/Cdav.php:1237 ../../Zotlabs/Module/Connedit.php:945
+#: ../../Zotlabs/Module/Cdav.php:1264 ../../Zotlabs/Module/Connedit.php:945
msgid "Locality"
msgstr "Населённый пункт"
-#: ../../Zotlabs/Module/Cdav.php:1238 ../../Zotlabs/Module/Connedit.php:946
+#: ../../Zotlabs/Module/Cdav.php:1265 ../../Zotlabs/Module/Connedit.php:946
msgid "Region"
msgstr "Регион"
-#: ../../Zotlabs/Module/Cdav.php:1239 ../../Zotlabs/Module/Connedit.php:947
+#: ../../Zotlabs/Module/Cdav.php:1266 ../../Zotlabs/Module/Connedit.php:947
msgid "ZIP Code"
msgstr "Индекс"
-#: ../../Zotlabs/Module/Cdav.php:1240 ../../Zotlabs/Module/Connedit.php:948
-#: ../../Zotlabs/Module/Profiles.php:757
+#: ../../Zotlabs/Module/Cdav.php:1267 ../../Zotlabs/Module/Profiles.php:757
+#: ../../Zotlabs/Module/Connedit.php:948
msgid "Country"
msgstr "Страна"
-#: ../../Zotlabs/Module/Cdav.php:1287
+#: ../../Zotlabs/Module/Cdav.php:1314
msgid "Default Calendar"
msgstr "Календарь по умолчанию"
-#: ../../Zotlabs/Module/Cdav.php:1297
+#: ../../Zotlabs/Module/Cdav.php:1324
msgid "Default Addressbook"
msgstr "Адресная книга по умолчанию"
-#: ../../Zotlabs/Module/Regdir.php:49 ../../Zotlabs/Module/Dirsearch.php:25
-msgid "This site is not a directory server"
-msgstr "Этот сайт не является сервером каталога"
+#: ../../Zotlabs/Module/Profile.php:45 ../../Zotlabs/Module/Channel.php:98
+#: ../../Zotlabs/Module/Hcard.php:37
+msgid "Posts and comments"
+msgstr "Публикации и комментарии"
-#: ../../Zotlabs/Module/Permcats.php:28
-msgid "Permission category name is required."
-msgstr "Требуется категория разрешений."
+#: ../../Zotlabs/Module/Profile.php:52 ../../Zotlabs/Module/Channel.php:105
+#: ../../Zotlabs/Module/Hcard.php:44
+msgid "Only posts"
+msgstr "Только публикации"
-#: ../../Zotlabs/Module/Permcats.php:47
-msgid "Permission category saved."
-msgstr "Категория разрешения сохранена."
+#: ../../Zotlabs/Module/Profile.php:93
+msgid "vcard"
+msgstr "vCard"
-#: ../../Zotlabs/Module/Permcats.php:62
-msgid "Permission Categories App"
-msgstr "Приложение \"Категории разрешений\""
+#: ../../Zotlabs/Module/Ochannel.php:32 ../../Zotlabs/Module/Chat.php:31
+#: ../../Zotlabs/Module/Channel.php:41
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:343
+msgid "You must be logged in to see this page."
+msgstr "Вы должны авторизоваться, чтобы увидеть эту страницу."
-#: ../../Zotlabs/Module/Permcats.php:63
-msgid "Create custom connection permission limits"
-msgstr "Создать пользовательские ограничения на доступ к подключению"
+#: ../../Zotlabs/Module/Share.php:103 ../../Zotlabs/Lib/Activity.php:1521
+#, php-format
+msgid "&#x1f501; Repeated %1$s's %2$s"
+msgstr "&#x1f501; Повторил %1$s %2$s"
-#: ../../Zotlabs/Module/Permcats.php:79
-msgid ""
-"Use this form to create permission rules for various classes of people or "
-"connections."
-msgstr "Используйте эту форму для создания правил разрешений для различных групп людей и контактов."
+#: ../../Zotlabs/Module/Share.php:119
+msgid "Post repeated"
+msgstr "Публикация повторяется"
-#: ../../Zotlabs/Module/Permcats.php:112 ../../Zotlabs/Lib/Apps.php:372
-msgid "Permission Categories"
-msgstr "Категории разрешений"
+#: ../../Zotlabs/Module/Notify.php:61 ../../Zotlabs/Module/Notifications.php:55
+msgid "No more system notifications."
+msgstr "Нет новых оповещений системы."
-#: ../../Zotlabs/Module/Permcats.php:120
-msgid "Permission category name"
-msgstr "Наименование категории разрешений"
+#: ../../Zotlabs/Module/Notify.php:65 ../../Zotlabs/Module/Notifications.php:59
+msgid "System Notifications"
+msgstr "Системные оповещения "
-#: ../../Zotlabs/Module/Permcats.php:121 ../../Zotlabs/Module/Tokens.php:181
-#: ../../Zotlabs/Module/Connedit.php:908 ../../Zotlabs/Module/Defperms.php:266
-msgid "My Settings"
-msgstr "Мои настройки"
+#: ../../Zotlabs/Module/Impel.php:185
+#, php-format
+msgid "%s element installed"
+msgstr "%s элемент установлен"
-#: ../../Zotlabs/Module/Permcats.php:123 ../../Zotlabs/Module/Tokens.php:183
-#: ../../Zotlabs/Module/Connedit.php:903 ../../Zotlabs/Module/Defperms.php:264
-msgid "inherited"
-msgstr "наследуется"
+#: ../../Zotlabs/Module/Impel.php:188
+#, php-format
+msgid "%s element installation failed"
+msgstr "%sустановка элемента неудачна."
-#: ../../Zotlabs/Module/Permcats.php:126 ../../Zotlabs/Module/Tokens.php:186
-#: ../../Zotlabs/Module/Connedit.php:910 ../../Zotlabs/Module/Defperms.php:269
-msgid "Individual Permissions"
-msgstr "Индивидуальные разрешения"
+#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56
+msgid "App installed."
+msgstr "Приложение установлено."
-#: ../../Zotlabs/Module/Permcats.php:127 ../../Zotlabs/Module/Tokens.php:187
-#: ../../Zotlabs/Module/Connedit.php:911
-msgid ""
-"Some permissions may be inherited from your channel's <a href=\"settings"
-"\"><strong>privacy settings</strong></a>, which have higher priority than "
-"individual settings. You can <strong>not</strong> change those settings here."
-msgstr "Некоторые разрешения могут наследовать из <a href=\"settings\"><strong>настроек приватности</strong></a> ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы <strong>не можете</strong> менять эти настройки здесь."
+#: ../../Zotlabs/Module/Appman.php:49
+msgid "Malformed app."
+msgstr "Неработающее приложение."
-#: ../../Zotlabs/Module/Channel.php:41 ../../Zotlabs/Module/Ochannel.php:32
-#: ../../Zotlabs/Module/Chat.php:31 ../../addon/chess/Mod_Chess.php:343
-msgid "You must be logged in to see this page."
-msgstr "Вы должны авторизоваться, чтобы увидеть эту страницу."
+#: ../../Zotlabs/Module/Appman.php:132
+msgid "Embed code"
+msgstr "Встроить код"
-#: ../../Zotlabs/Module/Channel.php:98 ../../Zotlabs/Module/Hcard.php:37
-#: ../../Zotlabs/Module/Profile.php:45
-msgid "Posts and comments"
-msgstr "Публикации и комментарии"
+#: ../../Zotlabs/Module/Appman.php:138
+msgid "Edit App"
+msgstr "Редактировать приложение"
-#: ../../Zotlabs/Module/Channel.php:105 ../../Zotlabs/Module/Hcard.php:44
-#: ../../Zotlabs/Module/Profile.php:52
-msgid "Only posts"
-msgstr "Только публикации"
+#: ../../Zotlabs/Module/Appman.php:138
+msgid "Create App"
+msgstr "Создать приложение"
-#: ../../Zotlabs/Module/Channel.php:165
-msgid "Insufficient permissions. Request redirected to profile page."
-msgstr "Недостаточно прав. Запрос перенаправлен на страницу профиля."
+#: ../../Zotlabs/Module/Appman.php:143
+msgid "Name of app"
+msgstr "Наименование приложения"
-#: ../../Zotlabs/Module/Channel.php:182 ../../Zotlabs/Module/Network.php:173
-msgid "Search Results For:"
-msgstr "Результаты поиска для:"
+#: ../../Zotlabs/Module/Appman.php:144
+msgid "Location (URL) of app"
+msgstr "Местоположение (URL) приложения"
-#: ../../Zotlabs/Module/Channel.php:217 ../../Zotlabs/Module/Hq.php:134
-#: ../../Zotlabs/Module/Pubstream.php:94 ../../Zotlabs/Module/Display.php:80
-#: ../../Zotlabs/Module/Network.php:203
-msgid "Reset form"
-msgstr "Очистить форму"
+#: ../../Zotlabs/Module/Appman.php:146
+msgid "Photo icon URL"
+msgstr "URL пиктограммы"
-#: ../../Zotlabs/Module/Channel.php:476 ../../Zotlabs/Module/Display.php:373
-msgid ""
-"You must enable javascript for your browser to be able to view this content."
-msgstr "Для просмотра этого содержимого в вашем браузере должен быть включён JavaScript"
+#: ../../Zotlabs/Module/Appman.php:146
+msgid "80 x 80 pixels - optional"
+msgstr "80 x 80 пикселей - необязательно"
-#: ../../Zotlabs/Module/Lang.php:17
-msgid "Language App"
-msgstr "Приложение \"Язык\""
+#: ../../Zotlabs/Module/Appman.php:147
+msgid "Categories (optional, comma separated list)"
+msgstr "Категории (необязательно, список через запятую)"
-#: ../../Zotlabs/Module/Lang.php:18
-msgid "Change UI language"
-msgstr "Изменить язык интерфейса"
+#: ../../Zotlabs/Module/Appman.php:148
+msgid "Version ID"
+msgstr "ID версии"
-#: ../../Zotlabs/Module/Uexport.php:61
-msgid "Channel Export App"
-msgstr "Приложение \"Экспорт канала\""
+#: ../../Zotlabs/Module/Appman.php:149
+msgid "Price of app"
+msgstr "Цена приложения"
-#: ../../Zotlabs/Module/Uexport.php:62
-msgid "Export your channel"
-msgstr "Экспортировать ваш канал"
+#: ../../Zotlabs/Module/Appman.php:150
+msgid "Location (URL) to purchase app"
+msgstr "Ссылка (URL) для покупки приложения"
-#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73
-msgid "Export Channel"
-msgstr "Экспорт канала"
+#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63
+msgid "Invalid profile identifier."
+msgstr "Неверный идентификатор профиля"
-#: ../../Zotlabs/Module/Uexport.php:74
-msgid ""
-"Export your basic channel information to a file. This acts as a backup of "
-"your connections, permissions, profile and basic data, which can be used to "
-"import your data to a new server hub, but does not contain your content."
-msgstr "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер."
+#: ../../Zotlabs/Module/Profperm.php:111
+msgid "Profile Visibility Editor"
+msgstr "Редактор видимости профиля"
-#: ../../Zotlabs/Module/Uexport.php:75
-msgid "Export Content"
-msgstr "Экспортировать содержимое"
+#: ../../Zotlabs/Module/Profperm.php:115
+msgid "Click on a contact to add or remove."
+msgstr "Нажмите на контакт, чтобы добавить или удалить."
-#: ../../Zotlabs/Module/Uexport.php:76
-msgid ""
-"Export your channel information and recent content to a JSON backup that can "
-"be restored or imported to another server hub. This backs up all of your "
-"connections, permissions, profile data and several months of posts. This "
-"file may be VERY large. Please be patient - it may take several minutes for "
-"this download to begin."
-msgstr "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка."
+#: ../../Zotlabs/Module/Profperm.php:124
+msgid "Visible To"
+msgstr "Видно"
-#: ../../Zotlabs/Module/Uexport.php:78
-msgid "Export your posts from a given year."
-msgstr "Экспортировать ваши публикации за данный год."
+#: ../../Zotlabs/Module/Profperm.php:140
+#: ../../Zotlabs/Module/Connections.php:217
+msgid "All Connections"
+msgstr "Все контакты"
-#: ../../Zotlabs/Module/Uexport.php:80
+#: ../../Zotlabs/Module/Changeaddr.php:35
msgid ""
-"You may also export your posts and conversations for a particular year or "
-"month. Adjust the date in your browser location bar to select other dates. "
-"If the export fails (possibly due to memory exhaustion on your server hub), "
-"please try again selecting a more limited date range."
-msgstr "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат."
+"Channel name changes are not allowed within 48 hours of changing the account "
+"password."
+msgstr "Изменение названия канала не разрешается в течении 48 часов после смены пароля у аккаунта."
-#: ../../Zotlabs/Module/Uexport.php:81
-#, php-format
-msgid ""
-"To select all posts for a given year, such as this year, visit <a href=\"%1$s"
-"\">%2$s</a>"
-msgstr "Для выбора всех публикаций заданного года, например текущего, посетите <a href=\"%1$s\">%2$s</a>"
+#: ../../Zotlabs/Module/Changeaddr.php:77
+msgid "Change channel nickname/address"
+msgstr "Изменить псевдоним / адрес канала"
-#: ../../Zotlabs/Module/Uexport.php:82
-#, php-format
-msgid ""
-"To select all posts for a given month, such as January of this year, visit "
-"<a href=\"%1$s\">%2$s</a>"
-msgstr "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите <a href=\"%1$s\">%2$s</a>"
+#: ../../Zotlabs/Module/Changeaddr.php:78 ../../Zotlabs/Module/Removeme.php:61
+#: ../../Zotlabs/Module/Removeaccount.php:58
+msgid "WARNING: "
+msgstr "ПРЕДУПРЕЖДЕНИЕ: "
-#: ../../Zotlabs/Module/Uexport.php:83
-#, php-format
-msgid ""
-"These content files may be imported or restored by visiting <a href=\"%1$s\">"
-"%2$s</a> on any site containing your channel. For best results please import "
-"or restore these in date order (oldest first)."
-msgstr "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите <a href=\"%1$s\">%2$s</a>. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала)."
+#: ../../Zotlabs/Module/Changeaddr.php:78
+msgid "Any/all connections on other networks will be lost!"
+msgstr "Любые / все контакты в других сетях будут утеряны!"
-#: ../../Zotlabs/Module/Hq.php:140
-msgid "Welcome to Hubzilla!"
-msgstr "Добро пожаловать в Hubzilla!"
+#: ../../Zotlabs/Module/Changeaddr.php:79 ../../Zotlabs/Module/Removeme.php:62
+#: ../../Zotlabs/Module/Removeaccount.php:59
+msgid "Please enter your password for verification:"
+msgstr "Пожалуйста, введите ваш пароль для проверки:"
-#: ../../Zotlabs/Module/Hq.php:140
-msgid "You have got no unseen posts..."
-msgstr "У вас нет видимых публикаций..."
+#: ../../Zotlabs/Module/Changeaddr.php:80
+msgid "New channel address"
+msgstr "Новый адрес канала"
-#: ../../Zotlabs/Module/Search.php:17 ../../Zotlabs/Module/Photos.php:558
-#: ../../Zotlabs/Module/Ratings.php:83 ../../Zotlabs/Module/Directory.php:67
-#: ../../Zotlabs/Module/Directory.php:72 ../../Zotlabs/Module/Display.php:29
-#: ../../Zotlabs/Module/Viewconnections.php:23
-msgid "Public access denied."
-msgstr "Публичный доступ запрещен."
+#: ../../Zotlabs/Module/Changeaddr.php:81
+msgid "Rename Channel"
+msgstr "Переименовать канал"
-#: ../../Zotlabs/Module/Search.php:44 ../../Zotlabs/Module/Connections.php:338
-#: ../../Zotlabs/Lib/Apps.php:350 ../../Zotlabs/Widget/Sitesearch.php:31
-#: ../../Zotlabs/Widget/Activity_filter.php:151 ../../include/text.php:1084
-#: ../../include/text.php:1096 ../../include/acl_selectors.php:118
-#: ../../include/nav.php:183
-msgid "Search"
-msgstr "Поиск"
+#: ../../Zotlabs/Module/Admin.php:96
+#: ../../Zotlabs/Module/Admin/Accounts.php:167
+#: ../../Zotlabs/Module/Admin/Accounts.php:180
+#: ../../Zotlabs/Widget/Admin.php:23
+msgid "Accounts"
+msgstr "Учётные записи"
-#: ../../Zotlabs/Module/Search.php:230
+#: ../../Zotlabs/Module/Admin.php:97
+msgid "Blocked accounts"
+msgstr "Заблокированные аккаунты"
+
+#: ../../Zotlabs/Module/Admin.php:98
+msgid "Expired accounts"
+msgstr "Просроченные аккаунты"
+
+#: ../../Zotlabs/Module/Admin.php:99
+msgid "Expiring accounts"
+msgstr "Близкие к просрочке аккаунты"
+
+#: ../../Zotlabs/Module/Admin.php:114
+#: ../../Zotlabs/Module/Admin/Channels.php:146
+#: ../../Zotlabs/Widget/Admin.php:24
+msgid "Channels"
+msgstr "Каналы"
+
+#: ../../Zotlabs/Module/Admin.php:120
+msgid "Message queues"
+msgstr "Очередь сообщений"
+
+#: ../../Zotlabs/Module/Admin.php:134
+msgid "Your software should be updated"
+msgstr "Ваше программное обеспечение должно быть обновлено"
+
+#: ../../Zotlabs/Module/Admin.php:138 ../../Zotlabs/Module/Admin/Logs.php:82
+#: ../../Zotlabs/Module/Admin/Channels.php:145
+#: ../../Zotlabs/Module/Admin/Security.php:92
+#: ../../Zotlabs/Module/Admin/Addons.php:341
+#: ../../Zotlabs/Module/Admin/Addons.php:439
+#: ../../Zotlabs/Module/Admin/Site.php:287
+#: ../../Zotlabs/Module/Admin/Themes.php:122
+#: ../../Zotlabs/Module/Admin/Themes.php:156
+#: ../../Zotlabs/Module/Admin/Accounts.php:166
+msgid "Administration"
+msgstr "Администрирование"
+
+#: ../../Zotlabs/Module/Admin.php:139
+msgid "Summary"
+msgstr "Резюме"
+
+#: ../../Zotlabs/Module/Admin.php:142
+msgid "Registered accounts"
+msgstr "Зарегистрированные аккаунты"
+
+#: ../../Zotlabs/Module/Admin.php:143
+msgid "Pending registrations"
+msgstr "Ждут утверждения"
+
+#: ../../Zotlabs/Module/Admin.php:144
+msgid "Registered channels"
+msgstr "Зарегистрированные каналы"
+
+#: ../../Zotlabs/Module/Admin.php:145
+msgid "Active addons"
+msgstr "Активные расширения"
+
+#: ../../Zotlabs/Module/Admin.php:146
+msgid "Version"
+msgstr "Версия системы"
+
+#: ../../Zotlabs/Module/Admin.php:147
+msgid "Repository version (master)"
+msgstr "Версия репозитория (master)"
+
+#: ../../Zotlabs/Module/Admin.php:148
+msgid "Repository version (dev)"
+msgstr "Версия репозитория (dev)"
+
+#: ../../Zotlabs/Module/Profiles.php:24 ../../Zotlabs/Module/Profiles.php:184
+#: ../../Zotlabs/Module/Profiles.php:241 ../../Zotlabs/Module/Profiles.php:659
+msgid "Profile not found."
+msgstr "Профиль не найден."
+
+#: ../../Zotlabs/Module/Profiles.php:44
+msgid "Profile deleted."
+msgstr "Профиль удален."
+
+#: ../../Zotlabs/Module/Profiles.php:68 ../../Zotlabs/Module/Profiles.php:105
+msgid "Profile-"
+msgstr "Профиль -"
+
+#: ../../Zotlabs/Module/Profiles.php:90 ../../Zotlabs/Module/Profiles.php:127
+msgid "New profile created."
+msgstr "Новый профиль создан."
+
+#: ../../Zotlabs/Module/Profiles.php:111
+msgid "Profile unavailable to clone."
+msgstr "Профиль недоступен для клонирования."
+
+#: ../../Zotlabs/Module/Profiles.php:146
+msgid "Profile unavailable to export."
+msgstr "Профиль недоступен для экспорта."
+
+#: ../../Zotlabs/Module/Profiles.php:252
+msgid "Profile Name is required."
+msgstr "Требуется имя профиля."
+
+#: ../../Zotlabs/Module/Profiles.php:459
+msgid "Marital Status"
+msgstr "Семейное положение"
+
+#: ../../Zotlabs/Module/Profiles.php:463
+msgid "Romantic Partner"
+msgstr "Романтический партнер"
+
+#: ../../Zotlabs/Module/Profiles.php:467 ../../Zotlabs/Module/Profiles.php:772
+msgid "Likes"
+msgstr "Нравится"
+
+#: ../../Zotlabs/Module/Profiles.php:471 ../../Zotlabs/Module/Profiles.php:773
+msgid "Dislikes"
+msgstr "Не нравится"
+
+#: ../../Zotlabs/Module/Profiles.php:475 ../../Zotlabs/Module/Profiles.php:780
+msgid "Work/Employment"
+msgstr "Работа / Занятость"
+
+#: ../../Zotlabs/Module/Profiles.php:478
+msgid "Religion"
+msgstr "Религия"
+
+#: ../../Zotlabs/Module/Profiles.php:482
+msgid "Political Views"
+msgstr "Политические взгляды"
+
+#: ../../Zotlabs/Module/Profiles.php:486
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:74
+msgid "Gender"
+msgstr "Гендер"
+
+#: ../../Zotlabs/Module/Profiles.php:490
+msgid "Sexual Preference"
+msgstr "Сексуальная ориентация"
+
+#: ../../Zotlabs/Module/Profiles.php:494
+msgid "Homepage"
+msgstr "Домашняя страница"
+
+#: ../../Zotlabs/Module/Profiles.php:498
+msgid "Interests"
+msgstr "Интересы"
+
+#: ../../Zotlabs/Module/Profiles.php:594
+msgid "Profile updated."
+msgstr "Профиль обновлен."
+
+#: ../../Zotlabs/Module/Profiles.php:678
+msgid "Hide your connections list from viewers of this profile"
+msgstr "Скрывать от просмотра ваш список контактов в этом профиле"
+
+#: ../../Zotlabs/Module/Profiles.php:722
+msgid "Edit Profile Details"
+msgstr "Редактирование профиля"
+
+#: ../../Zotlabs/Module/Profiles.php:724
+msgid "View this profile"
+msgstr "Посмотреть этот профиль"
+
+#: ../../Zotlabs/Module/Profiles.php:726
+msgid "Profile Tools"
+msgstr "Инструменты профиля"
+
+#: ../../Zotlabs/Module/Profiles.php:727
+msgid "Change cover photo"
+msgstr "Изменить фотографию обложки"
+
+#: ../../Zotlabs/Module/Profiles.php:729
+msgid "Create a new profile using these settings"
+msgstr "Создать новый профиль с теми же настройками"
+
+#: ../../Zotlabs/Module/Profiles.php:730
+msgid "Clone this profile"
+msgstr "Клонировать этот профиль"
+
+#: ../../Zotlabs/Module/Profiles.php:731
+msgid "Delete this profile"
+msgstr "Удалить этот профиль"
+
+#: ../../Zotlabs/Module/Profiles.php:732
+msgid "Add profile things"
+msgstr "Добавить в профиль"
+
+#: ../../Zotlabs/Module/Profiles.php:733
+msgid "Personal"
+msgstr "Личное"
+
+#: ../../Zotlabs/Module/Profiles.php:735
+msgid "Relationship"
+msgstr "Отношения"
+
+#: ../../Zotlabs/Module/Profiles.php:738
+msgid "Import profile from file"
+msgstr "Импортировать профиль из файла"
+
+#: ../../Zotlabs/Module/Profiles.php:739
+msgid "Export profile to file"
+msgstr "Экспортировать профиль в файл"
+
+#: ../../Zotlabs/Module/Profiles.php:740
+msgid "Your gender"
+msgstr "Ваш пол"
+
+#: ../../Zotlabs/Module/Profiles.php:741
+msgid "Marital status"
+msgstr "Семейное положение"
+
+#: ../../Zotlabs/Module/Profiles.php:742
+msgid "Sexual preference"
+msgstr "Сексуальная ориентация"
+
+#: ../../Zotlabs/Module/Profiles.php:745
+msgid "Profile name"
+msgstr "Имя профиля"
+
+#: ../../Zotlabs/Module/Profiles.php:747
+msgid "This is your default profile."
+msgstr "Это ваш профиль по умолчанию."
+
+#: ../../Zotlabs/Module/Profiles.php:749
+msgid "Your full name"
+msgstr "Ваше полное имя"
+
+#: ../../Zotlabs/Module/Profiles.php:750
+msgid "Title/Description"
+msgstr "Заголовок / описание"
+
+#: ../../Zotlabs/Module/Profiles.php:753
+msgid "Street address"
+msgstr "Улица, дом, квартира"
+
+#: ../../Zotlabs/Module/Profiles.php:754
+msgid "Locality/City"
+msgstr "Населенный пункт / город"
+
+#: ../../Zotlabs/Module/Profiles.php:755
+msgid "Region/State"
+msgstr "Регион / Область"
+
+#: ../../Zotlabs/Module/Profiles.php:756
+msgid "Postal/Zip code"
+msgstr "Почтовый индекс"
+
+#: ../../Zotlabs/Module/Profiles.php:762
+msgid "Who (if applicable)"
+msgstr "Кто (если применимо)"
+
+#: ../../Zotlabs/Module/Profiles.php:762
+msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
+msgstr "Примеры: ivan1990, Ivan Petrov, ivan@example.com"
+
+#: ../../Zotlabs/Module/Profiles.php:763
+msgid "Since (date)"
+msgstr "С (дата)"
+
+#: ../../Zotlabs/Module/Profiles.php:766
+msgid "Tell us about yourself"
+msgstr "Расскажите нам о себе"
+
+#: ../../Zotlabs/Module/Profiles.php:767
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:68
+msgid "Homepage URL"
+msgstr "URL домашней страницы"
+
+#: ../../Zotlabs/Module/Profiles.php:768
+msgid "Hometown"
+msgstr "Родной город"
+
+#: ../../Zotlabs/Module/Profiles.php:769
+msgid "Political views"
+msgstr "Политические взгляды"
+
+#: ../../Zotlabs/Module/Profiles.php:770
+msgid "Religious views"
+msgstr "Религиозные взгляды"
+
+#: ../../Zotlabs/Module/Profiles.php:771
+msgid "Keywords used in directory listings"
+msgstr "Ключевые слова для участия в каталоге"
+
+#: ../../Zotlabs/Module/Profiles.php:771
+msgid "Example: fishing photography software"
+msgstr "Например: fishing photography software"
+
+#: ../../Zotlabs/Module/Profiles.php:774
+msgid "Musical interests"
+msgstr "Музыкальные интересы"
+
+#: ../../Zotlabs/Module/Profiles.php:775
+msgid "Books, literature"
+msgstr "Книги, литература"
+
+#: ../../Zotlabs/Module/Profiles.php:776
+msgid "Television"
+msgstr "Телевидение"
+
+#: ../../Zotlabs/Module/Profiles.php:777
+msgid "Film/Dance/Culture/Entertainment"
+msgstr "Кино / танцы / культура / развлечения"
+
+#: ../../Zotlabs/Module/Profiles.php:778
+msgid "Hobbies/Interests"
+msgstr "Хобби / интересы"
+
+#: ../../Zotlabs/Module/Profiles.php:779
+msgid "Love/Romance"
+msgstr "Любовь / романтические отношения"
+
+#: ../../Zotlabs/Module/Profiles.php:781
+msgid "School/Education"
+msgstr "Школа / образование"
+
+#: ../../Zotlabs/Module/Profiles.php:782
+msgid "Contact information and social networks"
+msgstr "Информация и социальные сети для связи"
+
+#: ../../Zotlabs/Module/Profiles.php:783
+msgid "My other channels"
+msgstr "Мои другие контакты"
+
+#: ../../Zotlabs/Module/Profiles.php:785
+msgid "Communications"
+msgstr "Связи"
+
+#: ../../Zotlabs/Module/Profiles.php:831 ../../Zotlabs/Module/Chat.php:264
+#: ../../Zotlabs/Module/Wiki.php:214 ../../Zotlabs/Module/Manage.php:145
+msgid "Create New"
+msgstr "Создать новый"
+
+#: ../../Zotlabs/Module/Photos.php:78
+msgid "Page owner information could not be retrieved."
+msgstr "Информация о владельце страницы не может быть получена."
+
+#: ../../Zotlabs/Module/Photos.php:94 ../../Zotlabs/Module/Photos.php:113
+msgid "Album not found."
+msgstr "Альбом не найден."
+
+#: ../../Zotlabs/Module/Photos.php:103
+msgid "Delete Album"
+msgstr "Удалить альбом"
+
+#: ../../Zotlabs/Module/Photos.php:174 ../../Zotlabs/Module/Photos.php:1098
+msgid "Delete Photo"
+msgstr "Удалить фотографию"
+
+#: ../../Zotlabs/Module/Photos.php:569
+msgid "No photos selected"
+msgstr "Никакие фотографии не выбраны"
+
+#: ../../Zotlabs/Module/Photos.php:618
+msgid "Access to this item is restricted."
+msgstr "Доступ к этому элементу ограничен."
+
+#: ../../Zotlabs/Module/Photos.php:661
#, php-format
-msgid "Items tagged with: %s"
-msgstr "Объекты помечены как: %s"
+msgid "%1$.2f MB of %2$.2f MB photo storage used."
+msgstr "Вы использовали %1$.2f мегабайт из %2$.2f для хранения фото."
-#: ../../Zotlabs/Module/Search.php:232
+#: ../../Zotlabs/Module/Photos.php:664
#, php-format
-msgid "Search results for: %s"
-msgstr "Результаты поиска для: %s"
+msgid "%1$.2f MB photo storage used."
+msgstr "Вы использовали %1$.2f мегабайт для хранения фото."
-#: ../../Zotlabs/Module/Pubstream.php:20
-msgid "Public Stream App"
-msgstr "Приложение \"Публичный поток\""
+#: ../../Zotlabs/Module/Photos.php:706
+msgid "Upload Photos"
+msgstr "Загрузить фотографии"
-#: ../../Zotlabs/Module/Pubstream.php:21
-msgid "The unmoderated public stream of this hub"
-msgstr "Немодерируемый публичный поток с этого хаба"
+#: ../../Zotlabs/Module/Photos.php:710
+msgid "Enter an album name"
+msgstr "Введите название альбома"
-#: ../../Zotlabs/Module/Pubstream.php:109 ../../Zotlabs/Lib/Apps.php:374
-#: ../../Zotlabs/Widget/Notifications.php:142
-msgid "Public Stream"
-msgstr "Публичный поток"
+#: ../../Zotlabs/Module/Photos.php:711
+msgid "or select an existing album (doubleclick)"
+msgstr "или выберите существующий альбом (двойной щелчок)"
-#: ../../Zotlabs/Module/Locs.php:25 ../../Zotlabs/Module/Locs.php:54
-msgid "Location not found."
-msgstr "Местоположение не найдено"
+#: ../../Zotlabs/Module/Photos.php:712
+msgid "Create a status post for this upload"
+msgstr "Сделать публикацию о статусе для этой загрузки"
-#: ../../Zotlabs/Module/Locs.php:62
-msgid "Location lookup failed."
-msgstr "Поиск местоположения не удался"
+#: ../../Zotlabs/Module/Photos.php:714
+msgid "Description (optional)"
+msgstr "Описание (необязательно)"
-#: ../../Zotlabs/Module/Locs.php:66
-msgid ""
-"Please select another location to become primary before removing the primary "
-"location."
-msgstr "Пожалуйста, выберите другое местоположение в качестве основного прежде чем удалить предыдущее"
+#: ../../Zotlabs/Module/Photos.php:800
+msgid "Show Newest First"
+msgstr "Показать новые первыми"
-#: ../../Zotlabs/Module/Locs.php:95
-msgid "Syncing locations"
-msgstr "Синхронизировать местоположение"
+#: ../../Zotlabs/Module/Photos.php:802
+msgid "Show Oldest First"
+msgstr "Показать старые первыми"
-#: ../../Zotlabs/Module/Locs.php:105
-msgid "No locations found."
-msgstr "Местоположений не найдено"
+#: ../../Zotlabs/Module/Photos.php:826 ../../Zotlabs/Module/Photos.php:1374
+#: ../../Zotlabs/Module/Embedphotos.php:168
+#: ../../Zotlabs/Widget/Portfolio.php:87 ../../Zotlabs/Widget/Album.php:78
+msgid "View Photo"
+msgstr "Посмотреть фотографию"
-#: ../../Zotlabs/Module/Locs.php:116
-msgid "Manage Channel Locations"
-msgstr "Управление местоположением канала"
+#: ../../Zotlabs/Module/Photos.php:857 ../../Zotlabs/Module/Embedphotos.php:184
+#: ../../Zotlabs/Widget/Portfolio.php:108 ../../Zotlabs/Widget/Album.php:95
+msgid "Edit Album"
+msgstr "Редактировать Фотоальбом"
-#: ../../Zotlabs/Module/Locs.php:119
-msgid "Primary"
-msgstr "Основной"
+#: ../../Zotlabs/Module/Photos.php:859 ../../Zotlabs/Module/Photos.php:1405
+msgid "Add Photos"
+msgstr "Добавить фотографии"
-#: ../../Zotlabs/Module/Locs.php:120 ../../Zotlabs/Module/Menu.php:176
-msgid "Drop"
+#: ../../Zotlabs/Module/Photos.php:907
+msgid "Permission denied. Access to this item may be restricted."
+msgstr "Доступ запрещен. Доступ к этому элементу может быть ограничен."
+
+#: ../../Zotlabs/Module/Photos.php:909
+msgid "Photo not available"
+msgstr "Фотография не доступна"
+
+#: ../../Zotlabs/Module/Photos.php:967
+msgid "Use as profile photo"
+msgstr "Использовать в качестве фотографии профиля"
+
+#: ../../Zotlabs/Module/Photos.php:968
+msgid "Use as cover photo"
+msgstr "Использовать в качестве фотографии обложки"
+
+#: ../../Zotlabs/Module/Photos.php:975
+msgid "Private Photo"
+msgstr "Личная фотография"
+
+#: ../../Zotlabs/Module/Photos.php:990
+msgid "View Full Size"
+msgstr "Посмотреть в полный размер"
+
+#: ../../Zotlabs/Module/Photos.php:1035 ../../Zotlabs/Module/Tagrm.php:137
+#: ../../Zotlabs/Module/Cover_photo.php:425
+#: ../../Zotlabs/Module/Admin/Addons.php:458
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:91
+msgid "Remove"
msgstr "Удалить"
-#: ../../Zotlabs/Module/Locs.php:122
-msgid "Sync Now"
-msgstr "Синхронизировать"
+#: ../../Zotlabs/Module/Photos.php:1072
+msgid "Edit photo"
+msgstr "Редактировать фотографию"
-#: ../../Zotlabs/Module/Locs.php:123
-msgid "Please wait several minutes between consecutive operations."
-msgstr "Пожалуйста, подождите несколько минут между последовательными операциями."
+#: ../../Zotlabs/Module/Photos.php:1074
+msgid "Rotate CW (right)"
+msgstr "Повернуть CW (направо)"
-#: ../../Zotlabs/Module/Locs.php:124
-msgid ""
-"When possible, drop a location by logging into that website/hub and removing "
-"your channel."
-msgstr "По возможности, очистите местоположение, войдя на этот веб-сайт / хаб и удалив свой канал."
+#: ../../Zotlabs/Module/Photos.php:1075
+msgid "Rotate CCW (left)"
+msgstr "Повернуть CCW (налево)"
-#: ../../Zotlabs/Module/Locs.php:125
-msgid "Use this form to drop the location if the hub is no longer operating."
-msgstr "Используйте эту форму, чтобы удалить местоположение, если хаб больше не функционирует."
+#: ../../Zotlabs/Module/Photos.php:1078
+msgid "Move photo to album"
+msgstr "Переместить фотографию в альбом"
-#: ../../Zotlabs/Module/Apporder.php:47
-msgid "Change Order of Pinned Navbar Apps"
-msgstr "Изменить порядок приложений на панели навигации"
+#: ../../Zotlabs/Module/Photos.php:1079
+msgid "Enter a new album name"
+msgstr "Введите новое название альбома"
-#: ../../Zotlabs/Module/Apporder.php:47
-msgid "Change Order of App Tray Apps"
-msgstr "Изменить порядок приложений в лотке"
+#: ../../Zotlabs/Module/Photos.php:1080
+msgid "or select an existing one (doubleclick)"
+msgstr "или выбрать существующую (двойной щелчок)"
-#: ../../Zotlabs/Module/Apporder.php:48
+#: ../../Zotlabs/Module/Photos.php:1085
+msgid "Add a Tag"
+msgstr "Добавить тег"
+
+#: ../../Zotlabs/Module/Photos.php:1093
+msgid "Example: @bob, @Barbara_Jensen, @jim@example.com"
+msgstr "Пример: @bob, @Barbara_Jensen, @jim@example.com"
+
+#: ../../Zotlabs/Module/Photos.php:1096
+msgid "Flag as adult in album view"
+msgstr "Пометить как альбом \"для взрослых\""
+
+#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Lib/ThreadItem.php:306
+msgid "I like this (toggle)"
+msgstr "мне это нравится (переключение)"
+
+#: ../../Zotlabs/Module/Photos.php:1116 ../../Zotlabs/Lib/ThreadItem.php:307
+msgid "I don't like this (toggle)"
+msgstr "мне это не нравится (переключение)"
+
+#: ../../Zotlabs/Module/Photos.php:1135 ../../Zotlabs/Module/Photos.php:1254
+#: ../../Zotlabs/Lib/ThreadItem.php:792
+msgid "This is you"
+msgstr "Это вы"
+
+#: ../../Zotlabs/Module/Photos.php:1173 ../../Zotlabs/Module/Photos.php:1185
+#: ../../Zotlabs/Lib/ThreadItem.php:231 ../../Zotlabs/Lib/ThreadItem.php:243
+msgid "View all"
+msgstr "Просмотреть все"
+
+#: ../../Zotlabs/Module/Photos.php:1288
+msgid "Photo Tools"
+msgstr "Фото-Инструменты"
+
+#: ../../Zotlabs/Module/Photos.php:1297
+msgid "In This Photo:"
+msgstr "На этой фотографии:"
+
+#: ../../Zotlabs/Module/Photos.php:1302
+msgid "Map"
+msgstr "Карта"
+
+#: ../../Zotlabs/Module/Photos.php:1310 ../../Zotlabs/Lib/ThreadItem.php:457
+msgctxt "noun"
+msgid "Likes"
+msgstr "Нравится"
+
+#: ../../Zotlabs/Module/Photos.php:1311 ../../Zotlabs/Lib/ThreadItem.php:458
+msgctxt "noun"
+msgid "Dislikes"
+msgstr "Не нравится"
+
+#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98
+msgid "Tag removed"
+msgstr "Тег удалён"
+
+#: ../../Zotlabs/Module/Tagrm.php:123
+msgid "Remove Item Tag"
+msgstr "Удалить тег элемента"
+
+#: ../../Zotlabs/Module/Tagrm.php:125
+msgid "Select a tag to remove: "
+msgstr "Выбрать тег для удаления:"
+
+#: ../../Zotlabs/Module/Chanview.php:96 ../../Zotlabs/Module/Page.php:75
+#: ../../Zotlabs/Module/Wall_upload.php:31 ../../Zotlabs/Module/Block.php:41
+#: ../../Zotlabs/Module/Cal.php:63 ../../Zotlabs/Module/Card_edit.php:44
+#: ../../Zotlabs/Module/Article_edit.php:44
+msgid "Channel not found."
+msgstr "Канал не найден."
+
+#: ../../Zotlabs/Module/Chanview.php:139
+msgid "toggle full screen mode"
+msgstr "переключение полноэкранного режима"
+
+#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29
+msgid "Invalid item."
+msgstr "Недействительный элемент."
+
+#: ../../Zotlabs/Module/Page.php:173
msgid ""
-"Use arrows to move the corresponding app left (top) or right (bottom) in the "
-"navbar"
-msgstr "Используйте стрелки для перемещения приложения влево (вверх) или вправо (вниз) в панели навигации"
+"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
+"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
+"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo "
+"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
+"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
+"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
+msgstr ""
-#: ../../Zotlabs/Module/Apporder.php:48
-msgid "Use arrows to move the corresponding app up or down in the app tray"
-msgstr "Используйте стрелки для перемещения приложения вверх или вниз в лотке"
+#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95
+msgid "Authorize application connection"
+msgstr "Авторизовать подключение приложения"
-#: ../../Zotlabs/Module/Mitem.php:31 ../../Zotlabs/Module/Menu.php:208
-msgid "Menu not found."
-msgstr "Меню не найдено"
+#: ../../Zotlabs/Module/Api.php:75
+msgid "Return to your app and insert this Security Code:"
+msgstr "Вернитесь к своему приложению и вставьте этот код безопасности:"
-#: ../../Zotlabs/Module/Mitem.php:63
-msgid "Unable to create element."
-msgstr "Невозможно создать элемент."
+#: ../../Zotlabs/Module/Api.php:85
+msgid "Please login to continue."
+msgstr "Пожалуйста, войдите, чтобы продолжить."
-#: ../../Zotlabs/Module/Mitem.php:87
-msgid "Unable to update menu element."
-msgstr "Невозможно обновить элемент меню."
+#: ../../Zotlabs/Module/Api.php:97
+msgid ""
+"Do you want to authorize this application to access your posts and contacts, "
+"and/or create new posts for you?"
+msgstr "Вы хотите авторизовать это приложение для доступа к вашим публикациям и контактам и / или созданию новых публикаций?"
-#: ../../Zotlabs/Module/Mitem.php:103
-msgid "Unable to add menu element."
-msgstr "Невозможно добавить элемент меню."
+#: ../../Zotlabs/Module/Lostpass.php:19
+msgid "No valid account found."
+msgstr "Действительный аккаунт не найден."
-#: ../../Zotlabs/Module/Mitem.php:134 ../../Zotlabs/Module/Menu.php:231
-#: ../../Zotlabs/Module/Xchan.php:41
-msgid "Not found."
-msgstr "Не найдено."
+#: ../../Zotlabs/Module/Lostpass.php:33
+msgid "Password reset request issued. Check your email."
+msgstr "Запрос на сброс пароля отправлен. Проверьте вашу электронную почту."
-#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246
-msgid "Menu Item Permissions"
-msgstr "Разрешения на пункт меню"
+#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108
+#, php-format
+msgid "Site Member (%s)"
+msgstr "Участник сайта (%s)"
-#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247
-#: ../../Zotlabs/Module/Settings/Channel.php:526
-msgid "(click to open/close)"
-msgstr "(нажмите чтобы открыть/закрыть)"
+#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49
+#, php-format
+msgid "Password reset requested at %s"
+msgstr "Запрошен сброс пароля на %s"
-#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191
-msgid "Link Name"
-msgstr "Имя ссылки"
+#: ../../Zotlabs/Module/Lostpass.php:68
+msgid ""
+"Request could not be verified. (You may have previously submitted it.) "
+"Password reset failed."
+msgstr "Запрос не может быть проверен. (Вы могли отправить его раньше). Сброс пароля не возможен."
-#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255
-msgid "Link or Submenu Target"
-msgstr "Ссылка или цель подменю"
+#: ../../Zotlabs/Module/Lostpass.php:92
+msgid "Your password has been reset as requested."
+msgstr "Ваш пароль в соответствии с просьбой сброшен."
-#: ../../Zotlabs/Module/Mitem.php:175
-msgid "Enter URL of the link or select a menu name to create a submenu"
-msgstr "Введите URL ссылки или выберите имя меню для создания подменю"
+#: ../../Zotlabs/Module/Lostpass.php:93
+msgid "Your new password is"
+msgstr "Ваш новый пароль"
-#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256
-msgid "Use magic-auth if available"
-msgstr "Использовать magic-auth если возможно"
+#: ../../Zotlabs/Module/Lostpass.php:94
+msgid "Save or copy your new password - and then"
+msgstr "Сохраните ваш новый пароль и затем"
-#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177
-#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257
-#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
-#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Admin/Site.php:255
-#: ../../Zotlabs/Module/Settings/Channel.php:309
-#: ../../Zotlabs/Module/Settings/Display.php:89
-#: ../../Zotlabs/Module/Import.php:563 ../../Zotlabs/Module/Import.php:567
-#: ../../Zotlabs/Module/Import.php:568 ../../Zotlabs/Module/Api.php:99
-#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Wiki.php:227
-#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:406
-#: ../../Zotlabs/Module/Connedit.php:796 ../../Zotlabs/Module/Menu.php:162
-#: ../../Zotlabs/Module/Menu.php:221 ../../Zotlabs/Module/Defperms.php:197
-#: ../../Zotlabs/Module/Profiles.php:681 ../../Zotlabs/Module/Sources.php:124
-#: ../../Zotlabs/Module/Sources.php:159
-#: ../../Zotlabs/Module/Filestorage.php:178
-#: ../../Zotlabs/Module/Filestorage.php:186 ../../Zotlabs/Lib/Libzotdir.php:162
-#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../Zotlabs/Lib/Libzotdir.php:165
-#: ../../Zotlabs/Storage/Browser.php:405 ../../boot.php:1634
-#: ../../view/theme/redbasic_c/php/config.php:100
-#: ../../view/theme/redbasic_c/php/config.php:115
-#: ../../view/theme/redbasic/php/config.php:99
-#: ../../view/theme/redbasic/php/config.php:116
-#: ../../addon/wppost/Mod_Wppost.php:82 ../../addon/wppost/Mod_Wppost.php:86
-#: ../../addon/ijpost/Mod_Ijpost.php:61 ../../addon/dwpost/Mod_Dwpost.php:60
-#: ../../addon/ljpost/Mod_Ljpost.php:62 ../../addon/rtof/Mod_Rtof.php:49
-#: ../../addon/jappixmini/Mod_Jappixmini.php:161
-#: ../../addon/jappixmini/Mod_Jappixmini.php:191
-#: ../../addon/jappixmini/Mod_Jappixmini.php:199
-#: ../../addon/jappixmini/Mod_Jappixmini.php:203
-#: ../../addon/jappixmini/Mod_Jappixmini.php:207
-#: ../../addon/channelreputation/channelreputation.php:108
-#: ../../addon/nofed/Mod_Nofed.php:42 ../../addon/redred/Mod_Redred.php:63
-#: ../../addon/libertree/Mod_Libertree.php:59
-#: ../../addon/statusnet/Mod_Statusnet.php:260
-#: ../../addon/statusnet/Mod_Statusnet.php:282
-#: ../../addon/statusnet/Mod_Statusnet.php:291
-#: ../../addon/twitter/Mod_Twitter.php:162
-#: ../../addon/twitter/Mod_Twitter.php:171
-#: ../../addon/smileybutton/Mod_Smileybutton.php:44
-#: ../../addon/cart/Settings/Cart.php:59 ../../addon/cart/Settings/Cart.php:71
-#: ../../addon/cart/cart.php:1258
-#: ../../addon/cart/submodules/paypalbutton.php:87
-#: ../../addon/cart/submodules/paypalbutton.php:95
-#: ../../addon/cart/submodules/manualcat.php:63
-#: ../../addon/cart/submodules/manualcat.php:254
-#: ../../addon/cart/submodules/manualcat.php:258
-#: ../../addon/cart/submodules/hzservices.php:64
-#: ../../addon/cart/submodules/hzservices.php:646
-#: ../../addon/cart/submodules/hzservices.php:650
-#: ../../addon/cart/submodules/subscriptions.php:153
-#: ../../addon/cart/submodules/subscriptions.php:425
-#: ../../addon/pumpio/Mod_Pumpio.php:94 ../../addon/pumpio/Mod_Pumpio.php:98
-#: ../../addon/pumpio/Mod_Pumpio.php:102 ../../include/dir_fns.php:143
-#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
-msgid "No"
-msgstr "Нет"
+#: ../../Zotlabs/Module/Lostpass.php:95
+msgid "click here to login"
+msgstr "нажмите здесь чтобы войти"
-#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:177
-#: ../../Zotlabs/Module/Mitem.php:256 ../../Zotlabs/Module/Mitem.php:257
-#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
-#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Admin/Site.php:257
-#: ../../Zotlabs/Module/Settings/Channel.php:309
-#: ../../Zotlabs/Module/Settings/Display.php:89
-#: ../../Zotlabs/Module/Import.php:563 ../../Zotlabs/Module/Import.php:567
-#: ../../Zotlabs/Module/Import.php:568 ../../Zotlabs/Module/Api.php:98
-#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Wiki.php:227
-#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Connedit.php:406
-#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:221
-#: ../../Zotlabs/Module/Defperms.php:197 ../../Zotlabs/Module/Profiles.php:681
-#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
-#: ../../Zotlabs/Module/Filestorage.php:178
-#: ../../Zotlabs/Module/Filestorage.php:186 ../../Zotlabs/Lib/Libzotdir.php:162
-#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../Zotlabs/Lib/Libzotdir.php:165
-#: ../../Zotlabs/Storage/Browser.php:405 ../../boot.php:1634
-#: ../../view/theme/redbasic_c/php/config.php:100
-#: ../../view/theme/redbasic_c/php/config.php:115
-#: ../../view/theme/redbasic/php/config.php:99
-#: ../../view/theme/redbasic/php/config.php:116
-#: ../../addon/wppost/Mod_Wppost.php:82 ../../addon/wppost/Mod_Wppost.php:86
-#: ../../addon/ijpost/Mod_Ijpost.php:61 ../../addon/dwpost/Mod_Dwpost.php:60
-#: ../../addon/ljpost/Mod_Ljpost.php:62 ../../addon/rtof/Mod_Rtof.php:49
-#: ../../addon/jappixmini/Mod_Jappixmini.php:161
-#: ../../addon/jappixmini/Mod_Jappixmini.php:191
-#: ../../addon/jappixmini/Mod_Jappixmini.php:199
-#: ../../addon/jappixmini/Mod_Jappixmini.php:203
-#: ../../addon/jappixmini/Mod_Jappixmini.php:207
-#: ../../addon/channelreputation/channelreputation.php:108
-#: ../../addon/nofed/Mod_Nofed.php:42 ../../addon/redred/Mod_Redred.php:63
-#: ../../addon/libertree/Mod_Libertree.php:59
-#: ../../addon/statusnet/Mod_Statusnet.php:260
-#: ../../addon/statusnet/Mod_Statusnet.php:282
-#: ../../addon/statusnet/Mod_Statusnet.php:291
-#: ../../addon/twitter/Mod_Twitter.php:162
-#: ../../addon/twitter/Mod_Twitter.php:171
-#: ../../addon/smileybutton/Mod_Smileybutton.php:44
-#: ../../addon/cart/Settings/Cart.php:59 ../../addon/cart/Settings/Cart.php:71
-#: ../../addon/cart/cart.php:1258
-#: ../../addon/cart/submodules/paypalbutton.php:87
-#: ../../addon/cart/submodules/paypalbutton.php:95
-#: ../../addon/cart/submodules/manualcat.php:63
-#: ../../addon/cart/submodules/manualcat.php:254
-#: ../../addon/cart/submodules/manualcat.php:258
-#: ../../addon/cart/submodules/hzservices.php:64
-#: ../../addon/cart/submodules/hzservices.php:646
-#: ../../addon/cart/submodules/hzservices.php:650
-#: ../../addon/cart/submodules/subscriptions.php:153
-#: ../../addon/cart/submodules/subscriptions.php:425
-#: ../../addon/pumpio/Mod_Pumpio.php:94 ../../addon/pumpio/Mod_Pumpio.php:98
-#: ../../addon/pumpio/Mod_Pumpio.php:102 ../../include/dir_fns.php:143
-#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
-msgid "Yes"
-msgstr "Да"
+#: ../../Zotlabs/Module/Lostpass.php:96
+msgid ""
+"Your password may be changed from the <em>Settings</em> page after "
+"successful login."
+msgstr "Ваш пароль может быть изменён на странице <em>Настройки</em> после успешного входа."
-#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257
-msgid "Open link in new window"
-msgstr "Открыть ссылку в новом окне"
+#: ../../Zotlabs/Module/Lostpass.php:117
+#, php-format
+msgid "Your password has changed at %s"
+msgstr "Пароль был изменен на %s"
-#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258
-msgid "Order in list"
-msgstr "Порядок в списке"
+#: ../../Zotlabs/Module/Lostpass.php:130
+msgid "Forgot your Password?"
+msgstr "Забыли ваш пароль?"
-#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258
-msgid "Higher numbers will sink to bottom of listing"
-msgstr "Большие значения в конце списка"
+#: ../../Zotlabs/Module/Lostpass.php:131
+msgid ""
+"Enter your email address and submit to have your password reset. Then check "
+"your email for further instructions."
+msgstr "Введите ваш адрес электронной почты и нажмите отправить чтобы сбросить пароль. Затем проверьте ваш почтовый ящик для дальнейших инструкций. "
-#: ../../Zotlabs/Module/Mitem.php:179
-msgid "Submit and finish"
-msgstr "Отправить и завершить"
+#: ../../Zotlabs/Module/Lostpass.php:132
+msgid "Email Address"
+msgstr "Адрес электронной почты"
-#: ../../Zotlabs/Module/Mitem.php:180
-msgid "Submit and continue"
-msgstr "Отправить и продолжить"
+#: ../../Zotlabs/Module/Lostpass.php:133 ../../Zotlabs/Module/Pdledit.php:77
+msgid "Reset"
+msgstr "Сбросить"
-#: ../../Zotlabs/Module/Mitem.php:189
-msgid "Menu:"
-msgstr "Меню:"
+#: ../../Zotlabs/Module/Oauth.php:45
+msgid "Name is required"
+msgstr "Необходимо имя"
-#: ../../Zotlabs/Module/Mitem.php:192
-msgid "Link Target"
-msgstr "Цель ссылки"
+#: ../../Zotlabs/Module/Oauth.php:49
+msgid "Key and Secret are required"
+msgstr "Требуются ключ и код"
-#: ../../Zotlabs/Module/Mitem.php:195
-msgid "Edit menu"
-msgstr "Редактировать меню"
+#: ../../Zotlabs/Module/Oauth.php:100
+msgid "OAuth Apps Manager App"
+msgstr "Приложение \"Менеджер Oauth\""
-#: ../../Zotlabs/Module/Mitem.php:198
-msgid "Edit element"
-msgstr "Редактировать элемент"
+#: ../../Zotlabs/Module/Oauth.php:101
+msgid "OAuth authentication tokens for mobile and remote apps"
+msgstr "Токены аутентификации OAuth для мобильный и удалённых приложений"
-#: ../../Zotlabs/Module/Mitem.php:199
-msgid "Drop element"
-msgstr "Удалить элемент"
+#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136
+#: ../../Zotlabs/Module/Oauth.php:172 ../../Zotlabs/Module/Oauth2.php:143
+#: ../../Zotlabs/Module/Oauth2.php:193
+msgid "Add application"
+msgstr "Добавить приложение"
-#: ../../Zotlabs/Module/Mitem.php:200
-msgid "New element"
-msgstr "Новый элемент"
+#: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth2.php:118
+#: ../../Zotlabs/Module/Oauth2.php:146
+msgid "Name of application"
+msgstr "Название приложения"
-#: ../../Zotlabs/Module/Mitem.php:201
-msgid "Edit this menu container"
-msgstr "Редактировать контейнер меню"
+#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140
+#: ../../extend/addon/hzaddons/twitter/twitter.php:614
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:596
+msgid "Consumer Key"
+msgstr "Ключ клиента"
-#: ../../Zotlabs/Module/Mitem.php:202
-msgid "Add menu element"
-msgstr "Добавить элемент меню"
+#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115
+#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147
+msgid "Automatically generated - change if desired. Max length 20"
+msgstr "Сгенерирован автоматические - измените если требуется. Макс. длина 20"
-#: ../../Zotlabs/Module/Mitem.php:203
-msgid "Delete this menu item"
-msgstr "Удалить этот элемент меню"
+#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141
+#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147
+#: ../../extend/addon/hzaddons/twitter/twitter.php:615
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:595
+msgid "Consumer Secret"
+msgstr "Код клиента"
-#: ../../Zotlabs/Module/Mitem.php:204
-msgid "Edit this menu item"
-msgstr "Редактировать этот элемент меню"
+#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142
+#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148
+msgid "Redirect"
+msgstr "Перенаправление"
-#: ../../Zotlabs/Module/Mitem.php:222
-msgid "Menu item not found."
-msgstr "Элемент меню не найден."
+#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth2.php:120
+#: ../../Zotlabs/Module/Oauth2.php:148
+msgid ""
+"Redirect URI - leave blank unless your application specifically requires this"
+msgstr "URI перенаправления - оставьте пустыми до тех пока ваше приложение не требует этого"
-#: ../../Zotlabs/Module/Mitem.php:235
-msgid "Menu item deleted."
-msgstr "Элемент меню удалён."
+#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143
+msgid "Icon url"
+msgstr "URL значка"
-#: ../../Zotlabs/Module/Mitem.php:237
-msgid "Menu item could not be deleted."
-msgstr "Невозможно удалить элемент меню."
+#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Sources.php:123
+#: ../../Zotlabs/Module/Sources.php:158
+msgid "Optional"
+msgstr "Необязательно"
-#: ../../Zotlabs/Module/Mitem.php:244
-msgid "Edit Menu Element"
-msgstr "Редактировать элемент меню"
+#: ../../Zotlabs/Module/Oauth.php:128
+msgid "Application not found."
+msgstr "Приложение не найдено."
-#: ../../Zotlabs/Module/Mitem.php:254
-msgid "Link text"
-msgstr "Текст ссылки"
+#: ../../Zotlabs/Module/Oauth.php:171
+msgid "Connected OAuth Apps"
+msgstr "Подключенные приложения OAuth"
+
+#: ../../Zotlabs/Module/Oauth.php:175 ../../Zotlabs/Module/Oauth2.php:196
+msgid "Client key starts with"
+msgstr "Ключ клиента начинается с"
+
+#: ../../Zotlabs/Module/Oauth.php:176 ../../Zotlabs/Module/Oauth2.php:197
+msgid "No name"
+msgstr "Без названия"
+
+#: ../../Zotlabs/Module/Oauth.php:177 ../../Zotlabs/Module/Oauth2.php:198
+msgid "Remove authorization"
+msgstr "Удалить разрешение"
#: ../../Zotlabs/Module/Events.php:25
msgid "Calendar entries imported."
@@ -1454,23 +5893,10 @@ msgstr "Требуются наименование события и время
msgid "Event not found."
msgstr "Событие не найдено."
-#: ../../Zotlabs/Module/Events.php:260 ../../Zotlabs/Module/Tagger.php:73
-#: ../../Zotlabs/Module/Like.php:394 ../../include/conversation.php:119
-#: ../../include/text.php:2094 ../../include/event.php:1165
-msgid "event"
-msgstr "событие"
-
#: ../../Zotlabs/Module/Events.php:462
msgid "Edit event title"
msgstr "Редактировать наименование события"
-#: ../../Zotlabs/Module/Events.php:462 ../../Zotlabs/Module/Events.php:467
-#: ../../Zotlabs/Module/Appman.php:143 ../../Zotlabs/Module/Appman.php:144
-#: ../../Zotlabs/Module/Profiles.php:745 ../../Zotlabs/Module/Profiles.php:749
-#: ../../include/datetime.php:211
-msgid "Required"
-msgstr "Требуется"
-
#: ../../Zotlabs/Module/Events.php:464
msgid "Categories (comma-separated list)"
msgstr "Категории (список через запятую)"
@@ -1517,17 +5943,6 @@ msgstr "Редактировать описание"
msgid "Edit Location"
msgstr "Редактировать местоположение"
-#: ../../Zotlabs/Module/Events.php:480 ../../Zotlabs/Module/Photos.php:1139
-#: ../../Zotlabs/Module/Webpages.php:262 ../../Zotlabs/Lib/ThreadItem.php:805
-#: ../../addon/hsse/hsse.php:153 ../../include/conversation.php:1359
-msgid "Preview"
-msgstr "Предварительный просмотр"
-
-#: ../../Zotlabs/Module/Events.php:481 ../../addon/hsse/hsse.php:225
-#: ../../include/conversation.php:1431
-msgid "Permission settings"
-msgstr "Настройки разрешений"
-
#: ../../Zotlabs/Module/Events.php:491
msgid "Timezone:"
msgstr "Часовой пояс:"
@@ -1548,11 +5963,6 @@ msgstr "Редактировать событие"
msgid "Delete event"
msgstr "Удалить событие"
-#: ../../Zotlabs/Module/Events.php:663 ../../Zotlabs/Module/Cal.php:314
-#: ../../include/text.php:1913
-msgid "Link to Source"
-msgstr "Ссылка на источник"
-
#: ../../Zotlabs/Module/Events.php:670
msgid "calendar"
msgstr "календарь"
@@ -1565,10 +5975,12 @@ msgstr "Редактировать событие"
msgid "Create Event"
msgstr "Создать событие"
-#: ../../Zotlabs/Module/Events.php:692 ../../Zotlabs/Module/Cal.php:340
-#: ../../include/channel.php:1703
-msgid "Export"
-msgstr "Экспорт"
+#: ../../Zotlabs/Module/Events.php:695 ../../Zotlabs/Module/Pubsites.php:60
+#: ../../Zotlabs/Module/Webpages.php:261 ../../Zotlabs/Module/Blocks.php:166
+#: ../../Zotlabs/Module/Wiki.php:213 ../../Zotlabs/Module/Wiki.php:409
+#: ../../Zotlabs/Module/Layouts.php:198
+msgid "View"
+msgstr "Просмотр"
#: ../../Zotlabs/Module/Events.php:732
msgid "Event removed"
@@ -1578,164 +5990,46 @@ msgstr "Событие удалено"
msgid "Failed to remove event"
msgstr "Не удалось удалить событие"
-#: ../../Zotlabs/Module/Appman.php:39 ../../Zotlabs/Module/Appman.php:56
-msgid "App installed."
-msgstr "Приложение установлено."
-
-#: ../../Zotlabs/Module/Appman.php:49
-msgid "Malformed app."
-msgstr "Неработающее приложение."
-
-#: ../../Zotlabs/Module/Appman.php:132
-msgid "Embed code"
-msgstr "Встроить код"
-
-#: ../../Zotlabs/Module/Appman.php:138
-msgid "Edit App"
-msgstr "Редактировать приложение"
-
-#: ../../Zotlabs/Module/Appman.php:138
-msgid "Create App"
-msgstr "Создать приложение"
-
-#: ../../Zotlabs/Module/Appman.php:143
-msgid "Name of app"
-msgstr "Наименование приложения"
-
-#: ../../Zotlabs/Module/Appman.php:144
-msgid "Location (URL) of app"
-msgstr "Местоположение (URL) приложения"
-
-#: ../../Zotlabs/Module/Appman.php:146
-msgid "Photo icon URL"
-msgstr "URL пиктограммы"
-
-#: ../../Zotlabs/Module/Appman.php:146
-msgid "80 x 80 pixels - optional"
-msgstr "80 x 80 пикселей - необязательно"
-
-#: ../../Zotlabs/Module/Appman.php:147
-msgid "Categories (optional, comma separated list)"
-msgstr "Категории (необязательно, список через запятую)"
-
-#: ../../Zotlabs/Module/Appman.php:148
-msgid "Version ID"
-msgstr "ID версии"
-
-#: ../../Zotlabs/Module/Appman.php:149
-msgid "Price of app"
-msgstr "Цена приложения"
-
-#: ../../Zotlabs/Module/Appman.php:150
-msgid "Location (URL) to purchase app"
-msgstr "Ссылка (URL) для покупки приложения"
-
-#: ../../Zotlabs/Module/Regmod.php:15
-msgid "Please login."
-msgstr "Пожалуйста, войдите."
-
-#: ../../Zotlabs/Module/Magic.php:76
-msgid "Hub not found."
-msgstr "Узел не найден."
-
-#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Module/Tagger.php:69
-#: ../../Zotlabs/Module/Like.php:392 ../../Zotlabs/Lib/Activity.php:1959
-#: ../../addon/redphotos/redphotohelper.php:71
-#: ../../addon/diaspora/Receiver.php:1551 ../../addon/pubcrawl/as.php:1504
-#: ../../include/conversation.php:116 ../../include/text.php:2091
-msgid "photo"
-msgstr "фото"
-
-#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Module/Like.php:392
-#: ../../Zotlabs/Lib/Activity.php:1959 ../../addon/diaspora/Receiver.php:1551
-#: ../../addon/pubcrawl/as.php:1504 ../../include/conversation.php:144
-#: ../../include/text.php:2097
-msgid "status"
-msgstr "статус"
+#: ../../Zotlabs/Module/Authorize.php:17
+msgid "Unknown App"
+msgstr "Неизвестное приложение"
-#: ../../Zotlabs/Module/Subthread.php:143
-#, php-format
-msgid "%1$s is following %2$s's %3$s"
-msgstr "%1$s отслеживает %2$s's %3$s"
+#: ../../Zotlabs/Module/Authorize.php:29
+msgid "Authorize"
+msgstr "Авторизовать"
-#: ../../Zotlabs/Module/Subthread.php:145
+#: ../../Zotlabs/Module/Authorize.php:30
#, php-format
-msgid "%1$s stopped following %2$s's %3$s"
-msgstr "%1$s прекратил отслеживать %2$s's %3$s"
-
-#: ../../Zotlabs/Module/Article_edit.php:44 ../../Zotlabs/Module/Cal.php:63
-#: ../../Zotlabs/Module/Chanview.php:96 ../../Zotlabs/Module/Page.php:75
-#: ../../Zotlabs/Module/Wall_upload.php:31 ../../Zotlabs/Module/Block.php:41
-#: ../../Zotlabs/Module/Card_edit.php:44
-msgid "Channel not found."
-msgstr "Канал не найден."
-
-#: ../../Zotlabs/Module/Article_edit.php:101
-#: ../../Zotlabs/Module/Editblock.php:116 ../../Zotlabs/Module/Chat.php:222
-#: ../../Zotlabs/Module/Editwebpage.php:143 ../../Zotlabs/Module/Mail.php:288
-#: ../../Zotlabs/Module/Mail.php:430 ../../Zotlabs/Module/Card_edit.php:101
-#: ../../addon/hsse/hsse.php:95 ../../include/conversation.php:1298
-msgid "Insert web link"
-msgstr "Вставить веб-ссылку"
-
-#: ../../Zotlabs/Module/Article_edit.php:117
-#: ../../Zotlabs/Module/Editblock.php:129 ../../Zotlabs/Module/Photos.php:713
-#: ../../Zotlabs/Module/Photos.php:1083 ../../Zotlabs/Module/Card_edit.php:117
-#: ../../addon/hsse/hsse.php:221 ../../include/conversation.php:1427
-msgid "Title (optional)"
-msgstr "Заголовок (необязательно)"
-
-#: ../../Zotlabs/Module/Article_edit.php:128
-msgid "Edit Article"
-msgstr "Редактировать статью"
-
-#: ../../Zotlabs/Module/Import_items.php:48 ../../Zotlabs/Module/Import.php:66
-msgid "Nothing to import."
-msgstr "Ничего импортировать."
-
-#: ../../Zotlabs/Module/Import_items.php:72 ../../Zotlabs/Module/Import.php:81
-#: ../../Zotlabs/Module/Import.php:97
-msgid "Unable to download data from old server"
-msgstr "Невозможно загрузить данные со старого сервера"
-
-#: ../../Zotlabs/Module/Import_items.php:77 ../../Zotlabs/Module/Import.php:104
-msgid "Imported file is empty."
-msgstr "Импортированный файл пуст."
+msgid "Do you authorize the app %s to access your channel data?"
+msgstr "Авторизуете ли вы приложение %s для доступа к данным вашего канала?"
-#: ../../Zotlabs/Module/Import_items.php:93
-#, php-format
-msgid "Warning: Database versions differ by %1$d updates."
-msgstr "Предупреждение: Версия базы данных отличается от %1$d обновления."
+#: ../../Zotlabs/Module/Authorize.php:32
+msgid "Allow"
+msgstr "Разрешить"
-#: ../../Zotlabs/Module/Import_items.php:108
-msgid "Import completed"
-msgstr "Импорт завершён."
+#: ../../Zotlabs/Module/Authorize.php:33
+#: ../../Zotlabs/Module/Admin/Accounts.php:174
+msgid "Deny"
+msgstr "Запретить"
-#: ../../Zotlabs/Module/Import_items.php:125
-msgid "Import Items"
-msgstr "Импортировать объекты"
+#: ../../Zotlabs/Module/Pubstream.php:20
+msgid "Public Stream App"
+msgstr "Приложение \"Публичный поток\""
-#: ../../Zotlabs/Module/Import_items.php:126
-msgid "Use this form to import existing posts and content from an export file."
-msgstr "Используйте эту форму для импорта существующих публикаций и содержимого из файла."
+#: ../../Zotlabs/Module/Pubstream.php:21
+msgid "The unmoderated public stream of this hub"
+msgstr "Немодерируемый публичный поток с этого хаба"
-#: ../../Zotlabs/Module/Import_items.php:127
-#: ../../Zotlabs/Module/Import.php:557
-msgid "File to Upload"
-msgstr "Файл для загрузки"
+#: ../../Zotlabs/Module/Pubstream.php:109
+#: ../../Zotlabs/Widget/Notifications.php:142 ../../Zotlabs/Lib/Apps.php:376
+msgid "Public Stream"
+msgstr "Публичный поток"
#: ../../Zotlabs/Module/New_channel.php:147 ../../Zotlabs/Module/Manage.php:138
#, php-format
msgid "You have created %1$.0f of %2$.0f allowed channels."
msgstr "Вы создали %1$.0f из %2$.0f возможных каналов."
-#: ../../Zotlabs/Module/New_channel.php:157
-#: ../../Zotlabs/Module/New_channel.php:164
-#: ../../Zotlabs/Module/Connedit.php:869 ../../Zotlabs/Module/Defperms.php:256
-#: ../../Zotlabs/Widget/Notifications.php:162 ../../include/nav.php:323
-msgid "Loading"
-msgstr "Загрузка"
-
#: ../../Zotlabs/Module/New_channel.php:159
msgid "Your real name is recommended."
msgstr "Рекомендуется использовать ваше настоящее имя."
@@ -1765,8 +6059,8 @@ msgid "Choose a short nickname"
msgstr "Выберите короткий псевдоним"
#: ../../Zotlabs/Module/New_channel.php:178
-#: ../../Zotlabs/Module/Settings/Channel.php:535
#: ../../Zotlabs/Module/Register.php:261
+#: ../../Zotlabs/Module/Settings/Channel.php:535
msgid "Channel role and privacy"
msgstr "Роль и конфиденциальность канала"
@@ -1801,6 +6095,1468 @@ msgstr "или <a href=\"import\">импортировать существую
msgid "Validate"
msgstr "Проверить"
+#: ../../Zotlabs/Module/Cover_photo.php:80
+#: ../../Zotlabs/Module/Profile_photo.php:66
+msgid "Image uploaded but image cropping failed."
+msgstr "Изображение загружено но обрезка не удалась."
+
+#: ../../Zotlabs/Module/Cover_photo.php:191
+#: ../../Zotlabs/Module/Cover_photo.php:247
+msgid "Cover Photos"
+msgstr "Фотографии обложки"
+
+#: ../../Zotlabs/Module/Cover_photo.php:207
+#: ../../Zotlabs/Module/Profile_photo.php:139
+msgid "Image resize failed."
+msgstr "Не удалось изменить размер изображения."
+
+#: ../../Zotlabs/Module/Cover_photo.php:258
+#: ../../Zotlabs/Module/Profile_photo.php:271
+msgid "Image upload failed."
+msgstr "Загрузка изображения не удалась."
+
+#: ../../Zotlabs/Module/Cover_photo.php:275
+#: ../../Zotlabs/Module/Profile_photo.php:290
+msgid "Unable to process image."
+msgstr "Невозможно обработать изображение."
+
+#: ../../Zotlabs/Module/Cover_photo.php:368
+#: ../../Zotlabs/Module/Cover_photo.php:383
+#: ../../Zotlabs/Module/Profile_photo.php:354
+#: ../../Zotlabs/Module/Profile_photo.php:404
+msgid "Photo not available."
+msgstr "Фотография недоступна."
+
+#: ../../Zotlabs/Module/Cover_photo.php:419
+msgid "Your cover photo may be visible to anybody on the internet"
+msgstr "Фотография вашей обложки может быть видна всем в Интернете"
+
+#: ../../Zotlabs/Module/Cover_photo.php:421
+#: ../../Zotlabs/Module/Profile_photo.php:470
+msgid "Upload File:"
+msgstr "Загрузить файл:"
+
+#: ../../Zotlabs/Module/Cover_photo.php:422
+#: ../../Zotlabs/Module/Profile_photo.php:471
+msgid "Select a profile:"
+msgstr "Выбрать профиль:"
+
+#: ../../Zotlabs/Module/Cover_photo.php:423
+msgid "Change Cover Photo"
+msgstr "Изменить фотографию обложки"
+
+#: ../../Zotlabs/Module/Cover_photo.php:427
+#: ../../Zotlabs/Module/Cover_photo.php:428
+#: ../../Zotlabs/Module/Profile_photo.php:477
+#: ../../Zotlabs/Module/Profile_photo.php:478
+msgid "Use a photo from your albums"
+msgstr "Использовать фотографию из ваших альбомов"
+
+#: ../../Zotlabs/Module/Cover_photo.php:433
+#: ../../Zotlabs/Module/Profile_photo.php:483 ../../Zotlabs/Module/Wiki.php:405
+msgid "Choose a different album"
+msgstr "Выбрать другой альбом"
+
+#: ../../Zotlabs/Module/Cover_photo.php:439
+#: ../../Zotlabs/Module/Profile_photo.php:488
+msgid "Select existing photo"
+msgstr "Выбрать существующую фотографию"
+
+#: ../../Zotlabs/Module/Cover_photo.php:456
+#: ../../Zotlabs/Module/Profile_photo.php:507
+msgid "Crop Image"
+msgstr "Обрезать изображение"
+
+#: ../../Zotlabs/Module/Cover_photo.php:457
+#: ../../Zotlabs/Module/Profile_photo.php:508
+msgid "Please adjust the image cropping for optimum viewing."
+msgstr "Пожалуйста настройте обрезку изображения для оптимального просмотра."
+
+#: ../../Zotlabs/Module/Cover_photo.php:459
+#: ../../Zotlabs/Module/Profile_photo.php:510
+msgid "Done Editing"
+msgstr "Закончить редактирование"
+
+#: ../../Zotlabs/Module/Sharedwithme.php:103
+msgid "Files: shared with me"
+msgstr "Файлы: поделились со мной"
+
+#: ../../Zotlabs/Module/Sharedwithme.php:105
+msgid "NEW"
+msgstr "НОВОЕ"
+
+#: ../../Zotlabs/Module/Sharedwithme.php:108
+msgid "Remove all files"
+msgstr "Удалить все файлы"
+
+#: ../../Zotlabs/Module/Sharedwithme.php:109
+msgid "Remove this file"
+msgstr "Удалить этот файл"
+
+#: ../../Zotlabs/Module/Register.php:49
+msgid "Maximum daily site registrations exceeded. Please try again tomorrow."
+msgstr "Превышено максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра."
+
+#: ../../Zotlabs/Module/Register.php:55
+msgid ""
+"Please indicate acceptance of the Terms of Service. Registration failed."
+msgstr "Пожалуйста, подтвердите согласие с \"Условиями обслуживания\". Регистрация не удалась."
+
+#: ../../Zotlabs/Module/Register.php:89
+msgid "Passwords do not match."
+msgstr "Пароли не совпадают."
+
+#: ../../Zotlabs/Module/Register.php:132
+msgid "Registration successful. Continue to create your first channel..."
+msgstr "Регистрация завершена успешно. Для продолжения создайте свой первый канал..."
+
+#: ../../Zotlabs/Module/Register.php:135
+msgid ""
+"Registration successful. Please check your email for validation instructions."
+msgstr "Регистрация завершена успешно. Пожалуйста проверьте вашу электронную почту для подтверждения."
+
+#: ../../Zotlabs/Module/Register.php:142
+msgid "Your registration is pending approval by the site owner."
+msgstr "Ваша регистрация ожидает одобрения администрации сайта."
+
+#: ../../Zotlabs/Module/Register.php:145
+msgid "Your registration can not be processed."
+msgstr "Ваша регистрация не может быть обработана."
+
+#: ../../Zotlabs/Module/Register.php:192
+msgid "Registration on this hub is disabled."
+msgstr "Регистрация на этом хабе отключена."
+
+#: ../../Zotlabs/Module/Register.php:201
+msgid "Registration on this hub is by approval only."
+msgstr "Регистрация на этом хабе только по утверждению."
+
+#: ../../Zotlabs/Module/Register.php:202 ../../Zotlabs/Module/Register.php:211
+msgid "<a href=\"pubsites\">Register at another affiliated hub.</a>"
+msgstr "<a href=\"pubsites\">Зарегистрироваться на другом хабе.</a>"
+
+#: ../../Zotlabs/Module/Register.php:210
+msgid "Registration on this hub is by invitation only."
+msgstr "Регистрация на этом хабе доступна только по приглашениям."
+
+#: ../../Zotlabs/Module/Register.php:221
+msgid ""
+"This site has exceeded the number of allowed daily account registrations. "
+"Please try again tomorrow."
+msgstr "Этот сайт превысил максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра. "
+
+#: ../../Zotlabs/Module/Register.php:236 ../../Zotlabs/Module/Siteinfo.php:28
+msgid "Terms of Service"
+msgstr "Условия предоставления услуг"
+
+#: ../../Zotlabs/Module/Register.php:242
+#, php-format
+msgid "I accept the %s for this website"
+msgstr "Я принимаю %s для этого веб-сайта."
+
+#: ../../Zotlabs/Module/Register.php:249
+#, php-format
+msgid "I am over %s years of age and accept the %s for this website"
+msgstr "Мой возраст превышает %s лет и я принимаю %s для этого веб-сайта."
+
+#: ../../Zotlabs/Module/Register.php:254
+msgid "Your email address"
+msgstr "Ваш адрес электронной почты"
+
+#: ../../Zotlabs/Module/Register.php:255
+msgid "Choose a password"
+msgstr "Выберите пароль"
+
+#: ../../Zotlabs/Module/Register.php:256
+msgid "Please re-enter your password"
+msgstr "Пожалуйста, введите пароль еще раз"
+
+#: ../../Zotlabs/Module/Register.php:257
+msgid "Please enter your invitation code"
+msgstr "Пожалуйста, введите Ваш код приглашения"
+
+#: ../../Zotlabs/Module/Register.php:258
+msgid "Your Name"
+msgstr "Ваше имя"
+
+#: ../../Zotlabs/Module/Register.php:258
+msgid "Real names are preferred."
+msgstr "Предпочтительны реальные имена."
+
+#: ../../Zotlabs/Module/Register.php:260
+#, php-format
+msgid ""
+"Your nickname will be used to create an easy to remember channel address e."
+"g. nickname%s"
+msgstr "Ваш псевдоним будет использован для создания легко запоминаемого адреса канала, напр. nickname %s"
+
+#: ../../Zotlabs/Module/Register.php:261
+msgid ""
+"Select a channel permission role for your usage needs and privacy "
+"requirements."
+msgstr "Выберите разрешения для канала в зависимости от ваших потребностей и требований приватности."
+
+#: ../../Zotlabs/Module/Register.php:262
+msgid "no"
+msgstr "нет"
+
+#: ../../Zotlabs/Module/Register.php:262
+msgid "yes"
+msgstr "да"
+
+#: ../../Zotlabs/Module/Register.php:273
+#: ../../Zotlabs/Module/Admin/Site.php:290
+msgid "Registration"
+msgstr "Регистрация"
+
+#: ../../Zotlabs/Module/Register.php:290
+msgid ""
+"This site requires email verification. After completing this form, please "
+"check your email for further instructions."
+msgstr "Этот сайт требует проверку адреса электронной почты. После заполнения этой формы, пожалуйста, проверьте ваш почтовый ящик для дальнейших инструкций."
+
+#: ../../Zotlabs/Module/Apporder.php:47
+msgid "Change Order of Pinned Navbar Apps"
+msgstr "Изменить порядок приложений на панели навигации"
+
+#: ../../Zotlabs/Module/Apporder.php:47
+msgid "Change Order of App Tray Apps"
+msgstr "Изменить порядок приложений в лотке"
+
+#: ../../Zotlabs/Module/Apporder.php:48
+msgid ""
+"Use arrows to move the corresponding app left (top) or right (bottom) in the "
+"navbar"
+msgstr "Используйте стрелки для перемещения приложения влево (вверх) или вправо (вниз) в панели навигации"
+
+#: ../../Zotlabs/Module/Apporder.php:48
+msgid "Use arrows to move the corresponding app up or down in the app tray"
+msgstr "Используйте стрелки для перемещения приложения вверх или вниз в лотке"
+
+#: ../../Zotlabs/Module/Help.php:23
+msgid "Documentation Search"
+msgstr "Поиск документации"
+
+#: ../../Zotlabs/Module/Help.php:81 ../../Zotlabs/Module/Group.php:155
+msgid "Members"
+msgstr "Участники"
+
+#: ../../Zotlabs/Module/Help.php:82
+msgid "Administrators"
+msgstr "Администраторы"
+
+#: ../../Zotlabs/Module/Help.php:83
+msgid "Developers"
+msgstr "Разработчики"
+
+#: ../../Zotlabs/Module/Help.php:84
+msgid "Tutorials"
+msgstr "Руководства"
+
+#: ../../Zotlabs/Module/Help.php:95
+msgid "$Projectname Documentation"
+msgstr "$Projectname Документация"
+
+#: ../../Zotlabs/Module/Help.php:96
+msgid "Contents"
+msgstr "Содержимое"
+
+#: ../../Zotlabs/Module/Viewconnections.php:65
+msgid "No connections."
+msgstr "Контактов нет."
+
+#: ../../Zotlabs/Module/Viewconnections.php:83
+#, php-format
+msgid "Visit %s's profile [%s]"
+msgstr "Посетить %s ​​профиль [%s]"
+
+#: ../../Zotlabs/Module/Viewconnections.php:113
+msgid "View Connections"
+msgstr "Просмотр контактов"
+
+#: ../../Zotlabs/Module/Rate.php:156
+msgid "Website:"
+msgstr "Веб-сайт:"
+
+#: ../../Zotlabs/Module/Rate.php:159
+#, php-format
+msgid "Remote Channel [%s] (not yet known on this site)"
+msgstr "Удалённый канал [%s] (пока неизвестен на этом сайте)"
+
+#: ../../Zotlabs/Module/Rate.php:160
+msgid "Rating (this information is public)"
+msgstr "Оценка (эта информация общедоступна)"
+
+#: ../../Zotlabs/Module/Rate.php:161
+msgid "Optionally explain your rating (this information is public)"
+msgstr "Объясните свою оценку (необязательно; эта информация общедоступна)"
+
+#: ../../Zotlabs/Module/Regmod.php:15
+msgid "Please login."
+msgstr "Пожалуйста, войдите."
+
+#: ../../Zotlabs/Module/Locs.php:25 ../../Zotlabs/Module/Locs.php:54
+msgid "Location not found."
+msgstr "Местоположение не найдено"
+
+#: ../../Zotlabs/Module/Locs.php:62
+msgid "Location lookup failed."
+msgstr "Поиск местоположения не удался"
+
+#: ../../Zotlabs/Module/Locs.php:66
+msgid ""
+"Please select another location to become primary before removing the primary "
+"location."
+msgstr "Пожалуйста, выберите другое местоположение в качестве основного прежде чем удалить предыдущее"
+
+#: ../../Zotlabs/Module/Locs.php:95
+msgid "Syncing locations"
+msgstr "Синхронизировать местоположение"
+
+#: ../../Zotlabs/Module/Locs.php:105
+msgid "No locations found."
+msgstr "Местоположений не найдено"
+
+#: ../../Zotlabs/Module/Locs.php:116
+msgid "Manage Channel Locations"
+msgstr "Управление местоположением канала"
+
+#: ../../Zotlabs/Module/Locs.php:119
+msgid "Primary"
+msgstr "Основной"
+
+#: ../../Zotlabs/Module/Locs.php:120 ../../Zotlabs/Module/Menu.php:176
+msgid "Drop"
+msgstr "Удалить"
+
+#: ../../Zotlabs/Module/Locs.php:122
+msgid "Sync Now"
+msgstr "Синхронизировать"
+
+#: ../../Zotlabs/Module/Locs.php:123
+msgid "Please wait several minutes between consecutive operations."
+msgstr "Пожалуйста, подождите несколько минут между последовательными операциями."
+
+#: ../../Zotlabs/Module/Locs.php:124
+msgid ""
+"When possible, drop a location by logging into that website/hub and removing "
+"your channel."
+msgstr "По возможности, очистите местоположение, войдя на этот веб-сайт / хаб и удалив свой канал."
+
+#: ../../Zotlabs/Module/Locs.php:125
+msgid "Use this form to drop the location if the hub is no longer operating."
+msgstr "Используйте эту форму, чтобы удалить местоположение, если хаб больше не функционирует."
+
+#: ../../Zotlabs/Module/Sources.php:41
+msgid "Failed to create source. No channel selected."
+msgstr "Не удалось создать источник. Канал не выбран."
+
+#: ../../Zotlabs/Module/Sources.php:57
+msgid "Source created."
+msgstr "Источник создан."
+
+#: ../../Zotlabs/Module/Sources.php:70
+msgid "Source updated."
+msgstr "Источник обновлен."
+
+#: ../../Zotlabs/Module/Sources.php:88
+msgid "Sources App"
+msgstr "Приложение \"Источники канала\""
+
+#: ../../Zotlabs/Module/Sources.php:89
+msgid "Automatically import channel content from other channels or feeds"
+msgstr "Автоматический импорт контента из других каналов или лент"
+
+#: ../../Zotlabs/Module/Sources.php:101
+msgid "*"
+msgstr ""
+
+#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:368
+msgid "Channel Sources"
+msgstr "Источники канала"
+
+#: ../../Zotlabs/Module/Sources.php:108
+msgid "Manage remote sources of content for your channel."
+msgstr "Управление удалённым источниками содержимого для вашего канала"
+
+#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119
+msgid "New Source"
+msgstr "Новый источник"
+
+#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154
+msgid ""
+"Import all or selected content from the following channel into this channel "
+"and distribute it according to your channel settings."
+msgstr "Импортировать всё или выбранное содержимое из следующего канала в этот канал и распределить его в соответствии с вашими настройками."
+
+#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155
+msgid "Only import content with these words (one per line)"
+msgstr "Импортировать содержимое только с этим текстом (построчно)"
+
+#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155
+msgid "Leave blank to import all public content"
+msgstr "Оставьте пустым для импорта всего общедоступного содержимого"
+
+#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161
+msgid "Channel Name"
+msgstr "Название канала"
+
+#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158
+msgid ""
+"Add the following categories to posts imported from this source (comma "
+"separated)"
+msgstr "Добавить следующие категории к импортированным публикациям из этого источника (через запятые)"
+
+#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
+msgid "Resend posts with this channel as author"
+msgstr "Отправить публикации в этот канал повторно как автор"
+
+#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
+msgid "Copyrights may apply"
+msgstr "Могут применяться авторские права"
+
+#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174
+msgid "Source not found."
+msgstr "Источник не найден."
+
+#: ../../Zotlabs/Module/Sources.php:151
+msgid "Edit Source"
+msgstr "Редактировать источник"
+
+#: ../../Zotlabs/Module/Sources.php:152
+msgid "Delete Source"
+msgstr "Удалить источник"
+
+#: ../../Zotlabs/Module/Sources.php:182
+msgid "Source removed"
+msgstr "Источник удален"
+
+#: ../../Zotlabs/Module/Sources.php:184
+msgid "Unable to remove source."
+msgstr "Невозможно удалить источник."
+
+#: ../../Zotlabs/Module/Chat.php:102
+msgid "Chatrooms App"
+msgstr "Приложение \"Мои чаты\""
+
+#: ../../Zotlabs/Module/Chat.php:103
+msgid "Access Controlled Chatrooms"
+msgstr "Получить доступ к контролируемым чатам"
+
+#: ../../Zotlabs/Module/Chat.php:196
+msgid "Room not found"
+msgstr "Комната не найдена"
+
+#: ../../Zotlabs/Module/Chat.php:212
+msgid "Leave Room"
+msgstr "Покинуть комнату"
+
+#: ../../Zotlabs/Module/Chat.php:213
+msgid "Delete Room"
+msgstr "Удалить комнату"
+
+#: ../../Zotlabs/Module/Chat.php:214
+msgid "I am away right now"
+msgstr "Я сейчас отошёл"
+
+#: ../../Zotlabs/Module/Chat.php:215
+msgid "I am online"
+msgstr "Я на связи"
+
+#: ../../Zotlabs/Module/Chat.php:217
+msgid "Bookmark this room"
+msgstr "Запомнить эту комнату"
+
+#: ../../Zotlabs/Module/Chat.php:240
+msgid "New Chatroom"
+msgstr "Новый чат"
+
+#: ../../Zotlabs/Module/Chat.php:241
+msgid "Chatroom name"
+msgstr "Название чата"
+
+#: ../../Zotlabs/Module/Chat.php:242
+msgid "Expiration of chats (minutes)"
+msgstr "Завершение чатов (минут)"
+
+#: ../../Zotlabs/Module/Chat.php:258
+#, php-format
+msgid "%1$s's Chatrooms"
+msgstr "Чаты пользователя %1$s"
+
+#: ../../Zotlabs/Module/Chat.php:263
+msgid "No chatrooms available"
+msgstr "Нет доступных чатов"
+
+#: ../../Zotlabs/Module/Chat.php:267
+msgid "Expiration"
+msgstr "Срок действия"
+
+#: ../../Zotlabs/Module/Chat.php:268
+msgid "min"
+msgstr "мин."
+
+#: ../../Zotlabs/Module/Oauth2.php:54
+msgid "Name and Secret are required"
+msgstr "Требуются имя и код"
+
+#: ../../Zotlabs/Module/Oauth2.php:106
+msgid "OAuth2 Apps Manager App"
+msgstr "Приложение \"Менеджер Oauth2\""
+
+#: ../../Zotlabs/Module/Oauth2.php:107
+msgid "OAuth2 authenticatication tokens for mobile and remote apps"
+msgstr "Аутентификация OAuth2 для мобильных и удаленных приложений"
+
+#: ../../Zotlabs/Module/Oauth2.php:115
+msgid "Add OAuth2 application"
+msgstr "Добавить приложение OAuth2"
+
+#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149
+msgid "Grant Types"
+msgstr "Разрешить типы"
+
+#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122
+msgid "leave blank unless your application sepcifically requires this"
+msgstr "оставьте пустыми до тех пока ваше приложение не требует этого"
+
+#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150
+msgid "Authorization scope"
+msgstr "Область полномочий"
+
+#: ../../Zotlabs/Module/Oauth2.php:134
+msgid "OAuth2 Application not found."
+msgstr "Приложение OAuth2 не найдено."
+
+#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150
+msgid "leave blank unless your application specifically requires this"
+msgstr "оставьте поле пустым, если ваше приложение не требует этого"
+
+#: ../../Zotlabs/Module/Oauth2.php:192
+msgid "Connected OAuth2 Apps"
+msgstr "Подключённые приложения OAuth2"
+
+#: ../../Zotlabs/Module/Settings/Manage.php:39
+msgid "Channel Manager Settings"
+msgstr "Настройки менеджера канала"
+
+#: ../../Zotlabs/Module/Settings/Calendar.php:39
+msgid "CalDAV Settings"
+msgstr "Настройки CalDAV"
+
+#: ../../Zotlabs/Module/Settings/Account.php:19
+msgid "Not valid email."
+msgstr "Не действительный адрес email."
+
+#: ../../Zotlabs/Module/Settings/Account.php:22
+msgid "Protected email address. Cannot change to that email."
+msgstr "Защищенный адрес электронной почты. Нельзя изменить."
+
+#: ../../Zotlabs/Module/Settings/Account.php:31
+msgid "System failure storing new email. Please try again."
+msgstr "Системная ошибка сохранения email. Пожалуйста попробуйте ещё раз."
+
+#: ../../Zotlabs/Module/Settings/Account.php:48
+msgid "Password verification failed."
+msgstr "Не удалось выполнить проверку пароля."
+
+#: ../../Zotlabs/Module/Settings/Account.php:55
+msgid "Passwords do not match. Password unchanged."
+msgstr "Пароли не совпадают. Пароль не изменён."
+
+#: ../../Zotlabs/Module/Settings/Account.php:59
+msgid "Empty passwords are not allowed. Password unchanged."
+msgstr "Пустые пароли не допускаются. Пароль не изменён."
+
+#: ../../Zotlabs/Module/Settings/Account.php:73
+msgid "Password changed."
+msgstr "Пароль изменен."
+
+#: ../../Zotlabs/Module/Settings/Account.php:75
+msgid "Password update failed. Please try again."
+msgstr "Изменение пароля не удалось. Пожалуйста, попробуйте ещё раз."
+
+#: ../../Zotlabs/Module/Settings/Account.php:99
+msgid "Account Settings"
+msgstr "Настройки аккаунта"
+
+#: ../../Zotlabs/Module/Settings/Account.php:100
+msgid "Current Password"
+msgstr "Текущий пароль"
+
+#: ../../Zotlabs/Module/Settings/Account.php:101
+msgid "Enter New Password"
+msgstr "Введите новый пароль:"
+
+#: ../../Zotlabs/Module/Settings/Account.php:102
+msgid "Confirm New Password"
+msgstr "Подтвердите новый пароль:"
+
+#: ../../Zotlabs/Module/Settings/Account.php:102
+msgid "Leave password fields blank unless changing"
+msgstr "Оставьте поля пустыми до измнения"
+
+#: ../../Zotlabs/Module/Settings/Account.php:104
+#: ../../Zotlabs/Module/Settings/Channel.php:500
+msgid "Email Address:"
+msgstr "Адрес email:"
+
+#: ../../Zotlabs/Module/Settings/Account.php:105
+#: ../../Zotlabs/Module/Removeaccount.php:61
+msgid "Remove Account"
+msgstr "Удалить аккаунт"
+
+#: ../../Zotlabs/Module/Settings/Account.php:106
+msgid "Remove this account including all its channels"
+msgstr "Удалить этот аккаунт включая все каналы"
+
+#: ../../Zotlabs/Module/Settings/Conversation.php:22
+msgid "Settings saved."
+msgstr "Настройки сохранены."
+
+#: ../../Zotlabs/Module/Settings/Conversation.php:24
+msgid "Settings saved. Reload page please."
+msgstr "Настройки сохранены. Пожалуйста, перезагрузите страницу."
+
+#: ../../Zotlabs/Module/Settings/Conversation.php:46
+msgid "Conversation Settings"
+msgstr "Настройки бесед"
+
+#: ../../Zotlabs/Module/Settings/Editor.php:39
+msgid "Editor Settings"
+msgstr "Настройки редактора"
+
+#: ../../Zotlabs/Module/Settings/Display.php:119
+#: ../../Zotlabs/Module/Admin/Site.php:198
+#, php-format
+msgid "%s - (Incompatible)"
+msgstr "%s - (несовместимо)"
+
+#: ../../Zotlabs/Module/Settings/Display.php:128
+#, php-format
+msgid "%s - (Experimental)"
+msgstr "%s - (экспериментальный)"
+
+#: ../../Zotlabs/Module/Settings/Display.php:184
+msgid "Display Settings"
+msgstr "Настройки отображения"
+
+#: ../../Zotlabs/Module/Settings/Display.php:185
+msgid "Theme Settings"
+msgstr "Настройки темы"
+
+#: ../../Zotlabs/Module/Settings/Display.php:186
+msgid "Custom Theme Settings"
+msgstr "Дополнительные настройки темы"
+
+#: ../../Zotlabs/Module/Settings/Display.php:187
+msgid "Content Settings"
+msgstr "Настройки содержимого"
+
+#: ../../Zotlabs/Module/Settings/Display.php:193
+msgid "Display Theme:"
+msgstr "Тема отображения:"
+
+#: ../../Zotlabs/Module/Settings/Display.php:194
+msgid "Select scheme"
+msgstr "Выбрать схему"
+
+#: ../../Zotlabs/Module/Settings/Display.php:196
+msgid "Preload images before rendering the page"
+msgstr "Предзагрузка изображений перед обработкой страницы"
+
+#: ../../Zotlabs/Module/Settings/Display.php:196
+msgid ""
+"The subjective page load time will be longer but the page will be ready when "
+"displayed"
+msgstr "Субъективное время загрузки страницы будет длиннее, но страница будет готова при отображении"
+
+#: ../../Zotlabs/Module/Settings/Display.php:197
+msgid "Enable user zoom on mobile devices"
+msgstr "Включить масштабирование на мобильных устройствах"
+
+#: ../../Zotlabs/Module/Settings/Display.php:198
+msgid "Update browser every xx seconds"
+msgstr "Обновление браузера каждые N секунд"
+
+#: ../../Zotlabs/Module/Settings/Display.php:198
+msgid "Minimum of 10 seconds, no maximum"
+msgstr "Минимум 10 секунд, без максимума"
+
+#: ../../Zotlabs/Module/Settings/Display.php:199
+msgid "Maximum number of conversations to load at any time:"
+msgstr "Максимальное количество бесед для загрузки одновременно:"
+
+#: ../../Zotlabs/Module/Settings/Display.php:199
+msgid "Maximum of 100 items"
+msgstr "Максимум 100 элементов"
+
+#: ../../Zotlabs/Module/Settings/Display.php:200
+msgid "Show emoticons (smilies) as images"
+msgstr "Показывать эмотиконы (смайлики) как изображения"
+
+#: ../../Zotlabs/Module/Settings/Display.php:201
+msgid "Provide channel menu in navigation bar"
+msgstr "Показывать меню канала в панели навигации"
+
+#: ../../Zotlabs/Module/Settings/Display.php:201
+msgid "Default: channel menu located in app menu"
+msgstr "По умолчанию каналы расположены в меню приложения"
+
+#: ../../Zotlabs/Module/Settings/Display.php:202
+msgid "Manual conversation updates"
+msgstr "Обновление бесед вручную"
+
+#: ../../Zotlabs/Module/Settings/Display.php:202
+msgid "Default is on, turning this off may increase screen jumping"
+msgstr "Включено по умолчанию, выключение может привести к рывкам в отображении"
+
+#: ../../Zotlabs/Module/Settings/Display.php:203
+msgid "Link post titles to source"
+msgstr "Ссылки на источник заголовков публикаций"
+
+#: ../../Zotlabs/Module/Settings/Display.php:205
+#: ../../Zotlabs/Widget/Newmember.php:75
+msgid "New Member Links"
+msgstr "Ссылки для новичков"
+
+#: ../../Zotlabs/Module/Settings/Display.php:205
+msgid "Display new member quick links menu"
+msgstr "Показать меню быстрых ссылок для новых участников"
+
+#: ../../Zotlabs/Module/Settings/Features.php:43
+msgid "Additional Features"
+msgstr "Дополнительные функции"
+
+#: ../../Zotlabs/Module/Settings/Network.php:41
+#: ../../Zotlabs/Module/Settings/Channel_home.php:44
+msgid "Max height of content (in pixels)"
+msgstr "Максимальная высота содержимого (в пикселях)"
+
+#: ../../Zotlabs/Module/Settings/Network.php:43
+#: ../../Zotlabs/Module/Settings/Channel_home.php:46
+msgid "Click to expand content exceeding this height"
+msgstr "Нажмите чтобы развернуть содержимое превышающее эту высоту"
+
+#: ../../Zotlabs/Module/Settings/Network.php:58
+msgid "Stream Settings"
+msgstr "Настройки потока"
+
+#: ../../Zotlabs/Module/Settings/Events.php:39
+msgid "Events Settings"
+msgstr "Настройки событий"
+
+#: ../../Zotlabs/Module/Settings/Channel_home.php:59
+msgid "Personal menu to display in your channel pages"
+msgstr "Персональное меню для отображения на странице вашего канала"
+
+#: ../../Zotlabs/Module/Settings/Channel_home.php:86
+msgid "Channel Home Settings"
+msgstr "Настройки главной страницы канала"
+
+#: ../../Zotlabs/Module/Settings/Directory.php:39
+msgid "Directory Settings"
+msgstr "Настройки каталога"
+
+#: ../../Zotlabs/Module/Settings/Photos.php:39
+msgid "Photos Settings"
+msgstr "Настройки фотографий"
+
+#: ../../Zotlabs/Module/Settings/Profiles.php:47
+msgid "Profiles Settings"
+msgstr "Настройки профилей"
+
+#: ../../Zotlabs/Module/Settings/Featured.php:24
+msgid "No feature settings configured"
+msgstr "Параметры функций не настроены"
+
+#: ../../Zotlabs/Module/Settings/Featured.php:33
+msgid "Addon Settings"
+msgstr "Настройки расширений"
+
+#: ../../Zotlabs/Module/Settings/Featured.php:34
+msgid "Please save/submit changes to any panel before opening another."
+msgstr "Пожалуйста сохраните / отправьте изменения на панели прежде чем открывать другую."
+
+#: ../../Zotlabs/Module/Settings/Connections.php:39
+msgid "Connections Settings"
+msgstr "Настройки контактов"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:327
+msgid "Nobody except yourself"
+msgstr "Никто кроме вас"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:328
+msgid "Only those you specifically allow"
+msgstr "Только персонально разрешённые"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:329
+msgid "Approved connections"
+msgstr "Одобренные контакты"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:330
+msgid "Any connections"
+msgstr "Любые контакты"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:331
+msgid "Anybody on this website"
+msgstr "Любой на этом сайте"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:332
+msgid "Anybody in this network"
+msgstr "Любой в этой сети"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:333
+msgid "Anybody authenticated"
+msgstr "Любой аутентифицированный"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:334
+msgid "Anybody on the internet"
+msgstr "Любой в интернете"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:409
+msgid "Publish your default profile in the network directory"
+msgstr "Публиковать ваш профиль по умолчанию в сетевом каталоге"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:414
+msgid "Allow us to suggest you as a potential friend to new members?"
+msgstr "Разрешить предлагать вас как потенциального друга для новых пользователей?"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:418
+msgid "or"
+msgstr "или"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:427
+msgid "Your channel address is"
+msgstr "Адрес вашего канала"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:430
+msgid "Your files/photos are accessible via WebDAV at"
+msgstr "Ваши файлы / фотографии доступны через WebDAV по"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:470
+msgid "Automatic membership approval"
+msgstr "Членство одобрено автоматически"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:491
+msgid "Channel Settings"
+msgstr "Настройки канала"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:498
+msgid "Basic Settings"
+msgstr "Основные настройки"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:501
+msgid "Your Timezone:"
+msgstr "Часовой пояс:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:502
+msgid "Default Post Location:"
+msgstr "Расположение по умолчанию:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:502
+msgid "Geographical location to display on your posts"
+msgstr "Показывать географическое положение в ваших публикациях"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:503
+msgid "Use Browser Location:"
+msgstr "Определять расположение из браузера"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:505
+msgid "Adult Content"
+msgstr "Содержимое для взрослых"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:505
+msgid ""
+"This channel frequently or regularly publishes adult content. (Please tag "
+"any adult material and/or nudity with #NSFW)"
+msgstr "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:507
+msgid "Security and Privacy Settings"
+msgstr "Безопасность и настройки приватности"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:509
+msgid "Your permissions are already configured. Click to view/adjust"
+msgstr "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:511
+msgid "Hide my online presence"
+msgstr "Скрывать моё присутствие онлайн"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:511
+msgid "Prevents displaying in your profile that you are online"
+msgstr "Предотвращает отображения статуса \"в сети\" в вашем профиле"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:513
+msgid "Simple Privacy Settings:"
+msgstr "Простые настройки безопасности:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:514
+msgid ""
+"Very Public - <em>extremely permissive (should be used with caution)</em>"
+msgstr "Полностью открытый - <em>сверхлиберальный (должен использоваться с осторожностью)</em>"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:515
+msgid ""
+"Typical - <em>default public, privacy when desired (similar to social "
+"network permissions but with improved privacy)</em>"
+msgstr "Обычный - <em>открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)</em>"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:516
+msgid "Private - <em>default private, never open or public</em>"
+msgstr "Частный - <em>частный по умочанию, не открытый и не публичный</em>"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:517
+msgid "Blocked - <em>default blocked to/from everybody</em>"
+msgstr "Закрытый - <em>заблокированный по умолчанию от / для всех</em>"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:519
+msgid "Allow others to tag your posts"
+msgstr "Разрешить другим отмечать ваши публикации"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:519
+msgid ""
+"Often used by the community to retro-actively flag inappropriate content"
+msgstr "Часто используется сообществом для маркировки неподобающего содержания"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:521
+msgid "Channel Permission Limits"
+msgstr "Ограничения разрешений канала"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:523
+msgid "Expire other channel content after this many days"
+msgstr "Храненить содержимое других каналов, дней"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:523
+msgid "0 or blank to use the website limit."
+msgstr "0 или пусто - использовать настройки сайта."
+
+#: ../../Zotlabs/Module/Settings/Channel.php:523
+#, php-format
+msgid "This website expires after %d days."
+msgstr "Срок хранения содержимого этого сайта истекает через %d дней"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:523
+msgid "This website does not expire imported content."
+msgstr "Срок хранения импортированного содержимого этого сайта не ограничен."
+
+#: ../../Zotlabs/Module/Settings/Channel.php:523
+msgid "The website limit takes precedence if lower than your limit."
+msgstr "Ограничение сайта имеет приоритет если ниже вашего значения."
+
+#: ../../Zotlabs/Module/Settings/Channel.php:524
+msgid "Maximum Friend Requests/Day:"
+msgstr "Запросов в друзья в день:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:524
+msgid "May reduce spam activity"
+msgstr "Может ограничить спам активность"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:525
+msgid "Default Privacy Group"
+msgstr "Группа конфиденциальности по умолчанию"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:526
+#: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247
+msgid "(click to open/close)"
+msgstr "(нажмите чтобы открыть/закрыть)"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:527
+msgid "Use my default audience setting for the type of object published"
+msgstr "Использовать настройки аудитории по умолчанию для типа опубликованного объекта"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:536
+msgid "Default permissions category"
+msgstr "Категория разрешений по умолчанию"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:542
+msgid "Maximum private messages per day from unknown people:"
+msgstr "Максимально количество сообщений от незнакомых людей, в день:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:542
+msgid "Useful to reduce spamming"
+msgstr "Полезно для сокращения количества спама"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:545
+#: ../../Zotlabs/Lib/Enotify.php:68
+msgid "Notification Settings"
+msgstr "Настройки уведомлений"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:546
+msgid "By default post a status message when:"
+msgstr "По умолчанию публиковать новый статус при:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:547
+msgid "accepting a friend request"
+msgstr "одобрении запроса в друзья"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:548
+msgid "joining a forum/community"
+msgstr "вступлении в сообщество / форум"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:549
+msgid "making an <em>interesting</em> profile change"
+msgstr "<em>интересном</em> изменении профиля"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:550
+msgid "Send a notification email when:"
+msgstr "Отправить уведомление по email когда:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:551
+msgid "You receive a connection request"
+msgstr "вы получили новый запрос контакта"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:552
+msgid "Your connections are confirmed"
+msgstr "Ваш запрос контакта был одобрен"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:553
+msgid "Someone writes on your profile wall"
+msgstr "Кто-то написал на стене вашего профиля"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:554
+msgid "Someone writes a followup comment"
+msgstr "Кто-то пишет комментарий"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:555
+msgid "You receive a private message"
+msgstr "Вы получили личное сообщение"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:556
+msgid "You receive a friend suggestion"
+msgstr "Вы получили предложение друзей"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:557
+msgid "You are tagged in a post"
+msgstr "Вы были отмечены в публикации"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:558
+msgid "You are poked/prodded/etc. in a post"
+msgstr "Вас толкнули, подтолкнули и т.п. в публикации"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:560
+msgid "Someone likes your post/comment"
+msgstr "Кому-то нравится ваша публикация / комментарий"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:563
+msgid "Show visual notifications including:"
+msgstr "Показывать визуальные оповещения включая:"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:565
+msgid "Unseen stream activity"
+msgstr "Невидимая активность в потоке"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:566
+msgid "Unseen channel activity"
+msgstr "Невидимая активность в канале"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:567
+msgid "Unseen private messages"
+msgstr "Невидимые личные сообщения"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:567
+#: ../../Zotlabs/Module/Settings/Channel.php:572
+#: ../../Zotlabs/Module/Settings/Channel.php:573
+#: ../../Zotlabs/Module/Settings/Channel.php:574
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:191
+msgid "Recommended"
+msgstr "Рекомендовано"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:568
+msgid "Upcoming events"
+msgstr "Грядущие события"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:569
+msgid "Events today"
+msgstr "События сегодня"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:570
+msgid "Upcoming birthdays"
+msgstr "Грядущие дни рождения"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:570
+msgid "Not available in all themes"
+msgstr "Не доступно во всех темах"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:571
+msgid "System (personal) notifications"
+msgstr "Системные (личные) уведомления"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:572
+msgid "System info messages"
+msgstr "Сообщения с системной информацией"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:573
+msgid "System critical alerts"
+msgstr "Критические уведомления системы"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:574
+msgid "New connections"
+msgstr "Новые контакты"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:575
+msgid "System Registrations"
+msgstr "Системные регистрации"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:576
+msgid "Unseen shared files"
+msgstr "Невидимые общие файлы"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:577
+msgid "Unseen public stream activity"
+msgstr "Невидимая активность в публичном потоке"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:578
+msgid "Unseen likes and dislikes"
+msgstr "Невидимые лайки и дислайки"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:579
+msgid "Unseen forum posts"
+msgstr "Невидимые публикации на форуме"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:580
+msgid "Email notification hub (hostname)"
+msgstr "Центр уведомлений по email (имя хоста)"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:580
+#, php-format
+msgid ""
+"If your channel is mirrored to multiple hubs, set this to your preferred "
+"location. This will prevent duplicate email notifications. Example: %s"
+msgstr "Если ваш канал зеркалируется в нескольких местах, это ваше предпочтительное местоположение. Это должно предотвратить дублировать уведомлений по email. Например: %s"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:581
+msgid "Show new wall posts, private messages and connections under Notices"
+msgstr "Показать новые сообщения на стене, личные сообщения и контакты в \"Уведомлениях\""
+
+#: ../../Zotlabs/Module/Settings/Channel.php:583
+msgid "Notify me of events this many days in advance"
+msgstr "Уведомлять меня о событиях заранее, дней"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:583
+msgid "Must be greater than 0"
+msgstr "Должно быть больше 0"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:588
+msgid "Advanced Account/Page Type Settings"
+msgstr "Дополнительные настройки учётной записи / страницы"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:589
+msgid "Change the behaviour of this account for special situations"
+msgstr "Изменить поведение этого аккаунта в особых ситуациях"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:591
+msgid "Miscellaneous Settings"
+msgstr "Дополнительные настройки"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:592
+msgid "Default photo upload folder"
+msgstr "Каталог загрузки фотографий по умолчанию"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:592
+#: ../../Zotlabs/Module/Settings/Channel.php:593
+msgid "%Y - current year, %m - current month"
+msgstr "%Y - текущий год, %y - текущий месяц"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:593
+msgid "Default file upload folder"
+msgstr "Каталог загрузки файлов по умолчанию"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:594
+#: ../../Zotlabs/Module/Removeme.php:64
+msgid "Remove Channel"
+msgstr "Удаление канала"
+
+#: ../../Zotlabs/Module/Settings/Channel.php:595
+msgid "Remove this channel."
+msgstr "Удалить этот канал."
+
+#: ../../Zotlabs/Module/Dirsearch.php:33
+msgid "This directory server requires an access token"
+msgstr "Для доступа к этому серверу каталогов требуется токен"
+
+#: ../../Zotlabs/Module/Editlayout.php:79 ../../Zotlabs/Module/Editblock.php:79
+#: ../../Zotlabs/Module/Editblock.php:95
+#: ../../Zotlabs/Module/Editwebpage.php:80 ../../Zotlabs/Module/Editpost.php:24
+#: ../../Zotlabs/Module/Card_edit.php:17 ../../Zotlabs/Module/Card_edit.php:33
+#: ../../Zotlabs/Module/Article_edit.php:17
+#: ../../Zotlabs/Module/Article_edit.php:33
+msgid "Item not found"
+msgstr "Элемент не найден"
+
+#: ../../Zotlabs/Module/Editlayout.php:128 ../../Zotlabs/Module/Layouts.php:129
+#: ../../Zotlabs/Module/Layouts.php:189
+msgid "Layout Name"
+msgstr "Название шаблона"
+
+#: ../../Zotlabs/Module/Editlayout.php:129 ../../Zotlabs/Module/Layouts.php:132
+msgid "Layout Description (Optional)"
+msgstr "Описание шаблона (необязательно)"
+
+#: ../../Zotlabs/Module/Editlayout.php:137
+msgid "Edit Layout"
+msgstr "Редактировать шаблон"
+
+#: ../../Zotlabs/Module/Apps.php:50 ../../Zotlabs/Widget/Appstore.php:14
+msgid "Available Apps"
+msgstr "Доступные приложения"
+
+#: ../../Zotlabs/Module/Apps.php:50
+msgid "Installed Apps"
+msgstr "Установленные приложения"
+
+#: ../../Zotlabs/Module/Apps.php:53
+msgid "Manage Apps"
+msgstr "Управление приложениями"
+
+#: ../../Zotlabs/Module/Apps.php:54
+msgid "Create Custom App"
+msgstr "Создать пользовательское приложение"
+
+#: ../../Zotlabs/Module/Filestorage.php:103
+msgid "File not found."
+msgstr "Файл не найден."
+
+#: ../../Zotlabs/Module/Filestorage.php:152
+msgid "Permission Denied."
+msgstr "Доступ запрещен."
+
+#: ../../Zotlabs/Module/Filestorage.php:185
+msgid "Edit file permissions"
+msgstr "Редактировать разрешения файла"
+
+#: ../../Zotlabs/Module/Filestorage.php:197
+msgid "Set/edit permissions"
+msgstr "Редактировать разрешения"
+
+#: ../../Zotlabs/Module/Filestorage.php:198
+msgid "Include all files and sub folders"
+msgstr "Включить все файлы и подкаталоги"
+
+#: ../../Zotlabs/Module/Filestorage.php:199
+msgid "Return to file list"
+msgstr "Вернутся к списку файлов"
+
+#: ../../Zotlabs/Module/Filestorage.php:201
+msgid "Copy/paste this code to attach file to a post"
+msgstr "Копировать / вставить этот код для прикрепления файла к публикации"
+
+#: ../../Zotlabs/Module/Filestorage.php:202
+msgid "Copy/paste this URL to link file from a web page"
+msgstr "Копировать / вставить эту URL для ссылки на файл со страницы"
+
+#: ../../Zotlabs/Module/Filestorage.php:204
+msgid "Share this file"
+msgstr "Поделиться этим файлом"
+
+#: ../../Zotlabs/Module/Filestorage.php:205
+msgid "Show URL to this file"
+msgstr "Показать URL этого файла"
+
+#: ../../Zotlabs/Module/Editblock.php:113 ../../Zotlabs/Module/Blocks.php:97
+#: ../../Zotlabs/Module/Blocks.php:155
+msgid "Block Name"
+msgstr "Название блока"
+
+#: ../../Zotlabs/Module/Editblock.php:138
+msgid "Edit Block"
+msgstr "Редактировать блок"
+
+#: ../../Zotlabs/Module/Service_limits.php:23
+msgid "No service class restrictions found."
+msgstr "Ограничений класса обслуживание не найдено."
+
+#: ../../Zotlabs/Module/Channel.php:165
+msgid "Insufficient permissions. Request redirected to profile page."
+msgstr "Недостаточно прав. Запрос перенаправлен на страницу профиля."
+
+#: ../../Zotlabs/Module/Uexport.php:61
+msgid "Channel Export App"
+msgstr "Приложение \"Экспорт канала\""
+
+#: ../../Zotlabs/Module/Uexport.php:62
+msgid "Export your channel"
+msgstr "Экспортировать ваш канал"
+
+#: ../../Zotlabs/Module/Uexport.php:72 ../../Zotlabs/Module/Uexport.php:73
+msgid "Export Channel"
+msgstr "Экспорт канала"
+
+#: ../../Zotlabs/Module/Uexport.php:74
+msgid ""
+"Export your basic channel information to a file. This acts as a backup of "
+"your connections, permissions, profile and basic data, which can be used to "
+"import your data to a new server hub, but does not contain your content."
+msgstr "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер."
+
+#: ../../Zotlabs/Module/Uexport.php:75
+msgid "Export Content"
+msgstr "Экспортировать содержимое"
+
+#: ../../Zotlabs/Module/Uexport.php:76
+msgid ""
+"Export your channel information and recent content to a JSON backup that can "
+"be restored or imported to another server hub. This backs up all of your "
+"connections, permissions, profile data and several months of posts. This "
+"file may be VERY large. Please be patient - it may take several minutes for "
+"this download to begin."
+msgstr "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка."
+
+#: ../../Zotlabs/Module/Uexport.php:78
+msgid "Export your posts from a given year."
+msgstr "Экспортировать ваши публикации за данный год."
+
+#: ../../Zotlabs/Module/Uexport.php:80
+msgid ""
+"You may also export your posts and conversations for a particular year or "
+"month. Adjust the date in your browser location bar to select other dates. "
+"If the export fails (possibly due to memory exhaustion on your server hub), "
+"please try again selecting a more limited date range."
+msgstr "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат."
+
+#: ../../Zotlabs/Module/Uexport.php:81
+#, php-format
+msgid ""
+"To select all posts for a given year, such as this year, visit <a href=\"%1$s"
+"\">%2$s</a>"
+msgstr "Для выбора всех публикаций заданного года, например текущего, посетите <a href=\"%1$s\">%2$s</a>"
+
+#: ../../Zotlabs/Module/Uexport.php:82
+#, php-format
+msgid ""
+"To select all posts for a given month, such as January of this year, visit "
+"<a href=\"%1$s\">%2$s</a>"
+msgstr "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите <a href=\"%1$s\">%2$s</a>"
+
+#: ../../Zotlabs/Module/Uexport.php:83
+#, php-format
+msgid ""
+"These content files may be imported or restored by visiting <a href=\"%1$s\">"
+"%2$s</a> on any site containing your channel. For best results please import "
+"or restore these in date order (oldest first)."
+msgstr "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите <a href=\"%1$s\">%2$s</a>. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала)."
+
+#: ../../Zotlabs/Module/Chatsvc.php:131
+msgid "Away"
+msgstr "Нет на месте"
+
+#: ../../Zotlabs/Module/Chatsvc.php:136
+msgid "Online"
+msgstr "В сети"
+
+#: ../../Zotlabs/Module/Like.php:56
+msgid "Like/Dislike"
+msgstr "Нравится / не нравится"
+
+#: ../../Zotlabs/Module/Like.php:61
+msgid "This action is restricted to members."
+msgstr "Это действие доступно только участникам."
+
+#: ../../Zotlabs/Module/Like.php:62
+msgid ""
+"Please <a href=\"rmagic\">login with your $Projectname ID</a> or <a href="
+"\"register\">register as a new $Projectname member</a> to continue."
+msgstr "Пожалуйста, для продолжения <a href=\"rmagic\"> войдите с вашим $Projectname ID</a> или <a href=\"register\">зарегистрируйтесь как новый участник $Projectname</a>."
+
+#: ../../Zotlabs/Module/Like.php:111 ../../Zotlabs/Module/Like.php:137
+#: ../../Zotlabs/Module/Like.php:175
+msgid "Invalid request."
+msgstr "Неверный запрос."
+
+#: ../../Zotlabs/Module/Like.php:152
+msgid "thing"
+msgstr "предмет"
+
+#: ../../Zotlabs/Module/Like.php:198
+msgid "Channel unavailable."
+msgstr "Канал недоступен."
+
+#: ../../Zotlabs/Module/Like.php:246
+msgid "Previous action reversed."
+msgstr "Предыдущее действие отменено."
+
+#: ../../Zotlabs/Module/Like.php:451
+#, php-format
+msgid "%1$s agrees with %2$s's %3$s"
+msgstr "%1$s согласен с %2$s %3$s"
+
+#: ../../Zotlabs/Module/Like.php:453
+#, php-format
+msgid "%1$s doesn't agree with %2$s's %3$s"
+msgstr "%1$s не согласен с %2$s %3$s"
+
+#: ../../Zotlabs/Module/Like.php:455
+#, php-format
+msgid "%1$s abstains from a decision on %2$s's %3$s"
+msgstr "%1$s воздерживается от решения по %2$s%3$s"
+
+#: ../../Zotlabs/Module/Like.php:457
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2151
+#, php-format
+msgid "%1$s is attending %2$s's %3$s"
+msgstr "%1$s посещает %2$s%3$s"
+
+#: ../../Zotlabs/Module/Like.php:459
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2153
+#, php-format
+msgid "%1$s is not attending %2$s's %3$s"
+msgstr "%1$s не посещает %2$s%3$s"
+
+#: ../../Zotlabs/Module/Like.php:461
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:2155
+#, php-format
+msgid "%1$s may attend %2$s's %3$s"
+msgstr "%1$s может посетить %2$s%3$s"
+
+#: ../../Zotlabs/Module/Like.php:572
+msgid "Action completed."
+msgstr "Действие завершено."
+
+#: ../../Zotlabs/Module/Like.php:573
+msgid "Thank you."
+msgstr "Спасибо."
+
+#: ../../Zotlabs/Module/Bookmarks.php:62
+msgid "Bookmark added"
+msgstr "Закладка добавлена"
+
+#: ../../Zotlabs/Module/Bookmarks.php:78
+msgid "Bookmarks App"
+msgstr "Приложение \"Закладки\""
+
+#: ../../Zotlabs/Module/Bookmarks.php:79
+msgid "Bookmark links from posts and manage them"
+msgstr "Поместить ссылки из публикации в закладки и управлять ими"
+
+#: ../../Zotlabs/Module/Bookmarks.php:92
+msgid "My Bookmarks"
+msgstr "Мои закладки"
+
+#: ../../Zotlabs/Module/Bookmarks.php:103
+msgid "My Connections Bookmarks"
+msgstr "Закладки моих контактов"
+
+#: ../../Zotlabs/Module/Attach.php:13
+msgid "Item not available."
+msgstr "Элемент недоступен."
+
+#: ../../Zotlabs/Module/Probe.php:18
+msgid "Remote Diagnostics App"
+msgstr "Приложение \"Удалённая диагностика\""
+
+#: ../../Zotlabs/Module/Probe.php:19
+msgid "Perform diagnostics on remote channels"
+msgstr "Производит диагностику удалённых каналов"
+
+#: ../../Zotlabs/Module/Viewsrc.php:43
+msgid "item"
+msgstr "пункт"
+
+#: ../../Zotlabs/Module/Cal.php:70
+msgid "Permissions denied."
+msgstr "Доступ запрещен."
+
#: ../../Zotlabs/Module/Removeme.php:35
msgid ""
"Channel removals are not allowed within 48 hours of changing the account "
@@ -1812,12 +7568,6 @@ msgid "Remove This Channel"
msgstr "Удалить этот канал"
#: ../../Zotlabs/Module/Removeme.php:61
-#: ../../Zotlabs/Module/Removeaccount.php:58
-#: ../../Zotlabs/Module/Changeaddr.php:78
-msgid "WARNING: "
-msgstr "ПРЕДУПРЕЖДЕНИЕ: "
-
-#: ../../Zotlabs/Module/Removeme.php:61
msgid "This channel will be completely removed from the network. "
msgstr "Этот канал будет полностью удалён из сети. "
@@ -1826,12 +7576,6 @@ msgstr "Этот канал будет полностью удалён из се
msgid "This action is permanent and can not be undone!"
msgstr "Это действие необратимо и не может быть отменено!"
-#: ../../Zotlabs/Module/Removeme.php:62
-#: ../../Zotlabs/Module/Removeaccount.php:59
-#: ../../Zotlabs/Module/Changeaddr.php:79
-msgid "Please enter your password for verification:"
-msgstr "Пожалуйста, введите ваш пароль для проверки:"
-
#: ../../Zotlabs/Module/Removeme.php:63
msgid "Remove this channel and all its clones from the network"
msgstr "Удалить этот канал и все его клоны из сети"
@@ -1842,439 +7586,565 @@ msgid ""
"removed from the network"
msgstr "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети"
-#: ../../Zotlabs/Module/Removeme.php:64
-#: ../../Zotlabs/Module/Settings/Channel.php:594
-msgid "Remove Channel"
-msgstr "Удаление канала"
+#: ../../Zotlabs/Module/Menu.php:67
+msgid "Unable to update menu."
+msgstr "Невозможно обновить меню."
-#: ../../Zotlabs/Module/Sharedwithme.php:103
-msgid "Files: shared with me"
-msgstr "Файлы: поделились со мной"
+#: ../../Zotlabs/Module/Menu.php:78
+msgid "Unable to create menu."
+msgstr "Невозможно создать меню."
-#: ../../Zotlabs/Module/Sharedwithme.php:105
-msgid "NEW"
-msgstr "НОВОЕ"
+#: ../../Zotlabs/Module/Menu.php:160 ../../Zotlabs/Module/Menu.php:173
+msgid "Menu Name"
+msgstr "Название меню"
-#: ../../Zotlabs/Module/Sharedwithme.php:106
-#: ../../Zotlabs/Storage/Browser.php:287 ../../include/text.php:1496
-msgid "Size"
-msgstr "Размер"
+#: ../../Zotlabs/Module/Menu.php:160
+msgid "Unique name (not visible on webpage) - required"
+msgstr "Уникальное название (не видимо на странице) - требуется"
-#: ../../Zotlabs/Module/Sharedwithme.php:107
-#: ../../Zotlabs/Storage/Browser.php:288
-msgid "Last Modified"
-msgstr "Последнее изменение"
+#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174
+msgid "Menu Title"
+msgstr "Заголовок меню"
-#: ../../Zotlabs/Module/Sharedwithme.php:108
-msgid "Remove all files"
-msgstr "Удалить все файлы"
+#: ../../Zotlabs/Module/Menu.php:161
+msgid "Visible on webpage - leave empty for no title"
+msgstr "Видимость на странице - оставьте пустым если не хотите иметь заголовок"
-#: ../../Zotlabs/Module/Sharedwithme.php:109
-msgid "Remove this file"
-msgstr "Удалить этот файл"
+#: ../../Zotlabs/Module/Menu.php:162
+msgid "Allow Bookmarks"
+msgstr "Разрешить закладки"
+
+#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:221
+msgid "Menu may be used to store saved bookmarks"
+msgstr "Меню может использоваться, чтобы сохранить закладки"
+
+#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:224
+msgid "Submit and proceed"
+msgstr "Отправить и обработать"
+
+#: ../../Zotlabs/Module/Menu.php:177 ../../Zotlabs/Module/Webpages.php:266
+#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Layouts.php:191
+msgid "Created"
+msgstr "Создано"
+
+#: ../../Zotlabs/Module/Menu.php:178 ../../Zotlabs/Module/Webpages.php:267
+#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Layouts.php:192
+msgid "Edited"
+msgstr "Отредактировано"
+
+#: ../../Zotlabs/Module/Menu.php:179 ../../Zotlabs/Module/Notifications.php:50
+#: ../../Zotlabs/Module/Connections.php:83
+#: ../../Zotlabs/Module/Connections.php:92
+msgid "New"
+msgstr "Новые"
+
+#: ../../Zotlabs/Module/Menu.php:180
+msgid "Bookmarks allowed"
+msgstr "Закладки разрешены"
+
+#: ../../Zotlabs/Module/Menu.php:182
+msgid "Delete this menu"
+msgstr "Удалить это меню"
+
+#: ../../Zotlabs/Module/Menu.php:183 ../../Zotlabs/Module/Menu.php:218
+msgid "Edit menu contents"
+msgstr "Редактировать содержание меню"
+
+#: ../../Zotlabs/Module/Menu.php:184
+msgid "Edit this menu"
+msgstr "Редактировать это меню"
-#: ../../Zotlabs/Module/Setup.php:170
+#: ../../Zotlabs/Module/Menu.php:200
+msgid "Menu could not be deleted."
+msgstr "Меню не может быть удалено."
+
+#: ../../Zotlabs/Module/Menu.php:208 ../../Zotlabs/Module/Mitem.php:31
+msgid "Menu not found."
+msgstr "Меню не найдено"
+
+#: ../../Zotlabs/Module/Menu.php:213
+msgid "Edit Menu"
+msgstr "Редактировать меню"
+
+#: ../../Zotlabs/Module/Menu.php:217
+msgid "Add or remove entries to this menu"
+msgstr "Добавить или удалить пункты этого меню"
+
+#: ../../Zotlabs/Module/Menu.php:219
+msgid "Menu name"
+msgstr "Название меню"
+
+#: ../../Zotlabs/Module/Menu.php:219
+msgid "Must be unique, only seen by you"
+msgstr "Должно быть уникальным (видно только вам)"
+
+#: ../../Zotlabs/Module/Menu.php:220
+msgid "Menu title"
+msgstr "Заголовок меню"
+
+#: ../../Zotlabs/Module/Menu.php:220
+msgid "Menu title as seen by others"
+msgstr "Видимый другими заголовок меню"
+
+#: ../../Zotlabs/Module/Menu.php:221
+msgid "Allow bookmarks"
+msgstr "Разрешить закладки"
+
+#: ../../Zotlabs/Module/Ratings.php:70
+msgid "No ratings"
+msgstr "Оценок нет"
+
+#: ../../Zotlabs/Module/Ratings.php:98
+msgid "Rating: "
+msgstr "Оценкa:"
+
+#: ../../Zotlabs/Module/Ratings.php:99
+msgid "Website: "
+msgstr "Веб-сайт:"
+
+#: ../../Zotlabs/Module/Ratings.php:101
+msgid "Description: "
+msgstr "Описание:"
+
+#: ../../Zotlabs/Module/Pubsites.php:24 ../../Zotlabs/Widget/Pubsites.php:12
+msgid "Public Hubs"
+msgstr "Публичные хабы"
+
+#: ../../Zotlabs/Module/Pubsites.php:27
+msgid ""
+"The listed hubs allow public registration for the $Projectname network. All "
+"hubs in the network are interlinked so membership on any of them conveys "
+"membership in the network as a whole. Some hubs may require subscription or "
+"provide tiered service plans. The hub itself <strong>may</strong> provide "
+"additional details."
+msgstr "Указанные хабы разрешают публичную регистрацию для сети $Projectname. Все хабы в сети взаимосвязаны, поэтому членство в любом из них передает членство во всю сеть. Некоторым хабам может потребоваться подписка или предоставление многоуровневых планов обслуживания. Сам хаб <strong>может</strong> предоставить дополнительные сведения."
+
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Hub URL"
+msgstr "URL сервера"
+
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Access Type"
+msgstr "Тип доступа"
+
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Registration Policy"
+msgstr "Политика регистрации"
+
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Stats"
+msgstr "Статистика"
+
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Software"
+msgstr "Программное обеспечение"
+
+#: ../../Zotlabs/Module/Pubsites.php:49
+msgid "Rate"
+msgstr "Оценка"
+
+#: ../../Zotlabs/Module/Setup.php:167
msgid "$Projectname Server - Setup"
msgstr "$Projectname сервер - Установка"
-#: ../../Zotlabs/Module/Setup.php:174
+#: ../../Zotlabs/Module/Setup.php:171
msgid "Could not connect to database."
msgstr "Не удалось подключиться к серверу баз данных."
-#: ../../Zotlabs/Module/Setup.php:178
+#: ../../Zotlabs/Module/Setup.php:175
msgid ""
"Could not connect to specified site URL. Possible SSL certificate or DNS "
"issue."
msgstr "Не удалось подключиться к указанному URL. Вероятно проблема с SSL сертификатом или DNS."
-#: ../../Zotlabs/Module/Setup.php:185
+#: ../../Zotlabs/Module/Setup.php:182
msgid "Could not create table."
msgstr "Не удалось создать таблицу."
-#: ../../Zotlabs/Module/Setup.php:191
+#: ../../Zotlabs/Module/Setup.php:188
msgid "Your site database has been installed."
msgstr "Ваша база данных установлена."
-#: ../../Zotlabs/Module/Setup.php:197
+#: ../../Zotlabs/Module/Setup.php:194
msgid ""
"You may need to import the file \"install/schema_xxx.sql\" manually using a "
"database client."
msgstr "Вам может понадобится импортировать файл \"install/schema_xxx.sql\" вручную используя клиент базы данных."
-#: ../../Zotlabs/Module/Setup.php:198 ../../Zotlabs/Module/Setup.php:262
-#: ../../Zotlabs/Module/Setup.php:761
+#: ../../Zotlabs/Module/Setup.php:195 ../../Zotlabs/Module/Setup.php:259
+#: ../../Zotlabs/Module/Setup.php:766
msgid "Please see the file \"install/INSTALL.txt\"."
msgstr "Пожалуйста, обратитесь к файлу \"install/INSTALL.txt\"."
-#: ../../Zotlabs/Module/Setup.php:259
+#: ../../Zotlabs/Module/Setup.php:256
msgid "System check"
msgstr "Проверка системы"
-#: ../../Zotlabs/Module/Setup.php:264
+#: ../../Zotlabs/Module/Setup.php:261
msgid "Check again"
msgstr "Перепроверить"
-#: ../../Zotlabs/Module/Setup.php:286
+#: ../../Zotlabs/Module/Setup.php:282
msgid "Database connection"
msgstr "Подключение к базе данных"
-#: ../../Zotlabs/Module/Setup.php:287
+#: ../../Zotlabs/Module/Setup.php:283
msgid ""
"In order to install $Projectname we need to know how to connect to your "
"database."
msgstr "Для установки $Projectname необходимо знать как подключиться к ваше базе данных."
-#: ../../Zotlabs/Module/Setup.php:288
+#: ../../Zotlabs/Module/Setup.php:284
msgid ""
"Please contact your hosting provider or site administrator if you have "
"questions about these settings."
msgstr "Пожалуйста, свяжитесь с вашим хостинг провайдером или администрацией сайта если у вас есть вопросы об этих настройках."
-#: ../../Zotlabs/Module/Setup.php:289
+#: ../../Zotlabs/Module/Setup.php:285
msgid ""
"The database you specify below should already exist. If it does not, please "
"create it before continuing."
msgstr "Указанная ниже база данных должна существовать. Если это не так, пожалуйста, создайте её перед тем, как продолжить."
-#: ../../Zotlabs/Module/Setup.php:293
+#: ../../Zotlabs/Module/Setup.php:289
msgid "Database Server Name"
msgstr "Имя сервера баз данных"
-#: ../../Zotlabs/Module/Setup.php:293
+#: ../../Zotlabs/Module/Setup.php:289
msgid "Default is 127.0.0.1"
msgstr "По умолчанию 127.0.0.1"
-#: ../../Zotlabs/Module/Setup.php:294
+#: ../../Zotlabs/Module/Setup.php:290
msgid "Database Port"
msgstr "Порт сервера баз данных"
-#: ../../Zotlabs/Module/Setup.php:294
+#: ../../Zotlabs/Module/Setup.php:290
msgid "Communication port number - use 0 for default"
msgstr "Порт коммуникации - используйте 0 по умолчанию"
-#: ../../Zotlabs/Module/Setup.php:295
+#: ../../Zotlabs/Module/Setup.php:291
msgid "Database Login Name"
msgstr "Имя для подключения к базе данных"
-#: ../../Zotlabs/Module/Setup.php:296
+#: ../../Zotlabs/Module/Setup.php:292
msgid "Database Login Password"
msgstr "Пароль для подключения к базе данных"
-#: ../../Zotlabs/Module/Setup.php:297
+#: ../../Zotlabs/Module/Setup.php:293
msgid "Database Name"
msgstr "Имя базы данных"
-#: ../../Zotlabs/Module/Setup.php:298
+#: ../../Zotlabs/Module/Setup.php:294
msgid "Database Type"
msgstr "Тип базы данных"
-#: ../../Zotlabs/Module/Setup.php:300 ../../Zotlabs/Module/Setup.php:341
+#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336
msgid "Site administrator email address"
msgstr "Адрес электронной почты администратора сайта"
-#: ../../Zotlabs/Module/Setup.php:300 ../../Zotlabs/Module/Setup.php:341
+#: ../../Zotlabs/Module/Setup.php:296 ../../Zotlabs/Module/Setup.php:336
msgid ""
"Your account email address must match this in order to use the web admin "
"panel."
msgstr "Ваш адрес электронной почты должен соответствовать этому для использования веб-панели администратора."
-#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:343
+#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338
msgid "Website URL"
msgstr "URL веб-сайта"
-#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:343
+#: ../../Zotlabs/Module/Setup.php:297 ../../Zotlabs/Module/Setup.php:338
msgid "Please use SSL (https) URL if available."
msgstr "Пожалуйста, используйте SSL (https) URL если возможно."
-#: ../../Zotlabs/Module/Setup.php:302 ../../Zotlabs/Module/Setup.php:345
+#: ../../Zotlabs/Module/Setup.php:298 ../../Zotlabs/Module/Setup.php:340
msgid "Please select a default timezone for your website"
msgstr "Пожалуйста, выберите часовой пояс по умолчанию для вашего сайта"
-#: ../../Zotlabs/Module/Setup.php:330
+#: ../../Zotlabs/Module/Setup.php:325
msgid "Site settings"
msgstr "Настройки сайта"
-#: ../../Zotlabs/Module/Setup.php:384
-msgid "PHP version 5.5 or greater is required."
-msgstr "Требуется PHP версии 5.5 или выше"
+#: ../../Zotlabs/Module/Setup.php:379
+msgid "PHP version 7.1 or greater is required."
+msgstr "Требуется PHP версии 7.1 или старше."
-#: ../../Zotlabs/Module/Setup.php:385
+#: ../../Zotlabs/Module/Setup.php:380
msgid "PHP version"
msgstr "Версия PHP"
-#: ../../Zotlabs/Module/Setup.php:401
+#: ../../Zotlabs/Module/Setup.php:396
msgid "Could not find a command line version of PHP in the web server PATH."
msgstr "Не удалось найти консольную версию PHP в путях переменной PATH веб-сервера."
-#: ../../Zotlabs/Module/Setup.php:402
+#: ../../Zotlabs/Module/Setup.php:397
msgid ""
"If you don't have a command line version of PHP installed on server, you "
"will not be able to run background polling via cron."
msgstr "Если у вас на сервере не установлена консольная версия PHP вы не сможете запустить фоновый опрос через cron. "
-#: ../../Zotlabs/Module/Setup.php:406
+#: ../../Zotlabs/Module/Setup.php:401
msgid "PHP executable path"
msgstr "Пусть к исполняемому модулю PHP"
-#: ../../Zotlabs/Module/Setup.php:406
+#: ../../Zotlabs/Module/Setup.php:401
msgid ""
"Enter full path to php executable. You can leave this blank to continue the "
"installation."
msgstr "Введите полный путь к исполняемому модулю PHP. Вы можете оставить его пустым для продолжения установки."
-#: ../../Zotlabs/Module/Setup.php:411
+#: ../../Zotlabs/Module/Setup.php:406
msgid "Command line PHP"
msgstr "Командная строка PHP"
-#: ../../Zotlabs/Module/Setup.php:421
+#: ../../Zotlabs/Module/Setup.php:416
msgid ""
"Unable to check command line PHP, as shell_exec() is disabled. This is "
"required."
msgstr "Невозможно проверить командную строку PHP поскольку требуемая функция shell_exec() отключена."
-#: ../../Zotlabs/Module/Setup.php:424
+#: ../../Zotlabs/Module/Setup.php:420
msgid ""
"The command line version of PHP on your system does not have "
"\"register_argc_argv\" enabled."
msgstr "В консольной версии PHP в вашей системе отключена опция \"register_argc_argv\"."
-#: ../../Zotlabs/Module/Setup.php:425
+#: ../../Zotlabs/Module/Setup.php:421
msgid "This is required for message delivery to work."
msgstr "Это необходимо для функционирования доставки сообщений."
-#: ../../Zotlabs/Module/Setup.php:428
+#: ../../Zotlabs/Module/Setup.php:424
msgid "PHP register_argc_argv"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:448
+#: ../../Zotlabs/Module/Setup.php:444
msgid ""
"This is not sufficient to upload larger images or files. You should be able "
"to upload at least 4 MB at once."
msgstr "Этого недостаточно для загрузки больших изображений или файлов. Вы должны иметь возможность загрузить как минимум 4 Мб за раз."
-#: ../../Zotlabs/Module/Setup.php:450
+#: ../../Zotlabs/Module/Setup.php:446
#, php-format
msgid ""
"Your max allowed total upload size is set to %s. Maximum size of one file to "
"upload is set to %s. You are allowed to upload up to %d files at once."
msgstr "Максимально разрешённый общий размер загрузок установлен в %s. Максимальный размер одной загрузки установлен в %s. Вам разрешено загружать до %d файлов за один приём."
-#: ../../Zotlabs/Module/Setup.php:456
+#: ../../Zotlabs/Module/Setup.php:452
msgid "You can adjust these settings in the server php.ini file."
msgstr "Вы можете изменить эти настройки в файле php.ini на сервере."
-#: ../../Zotlabs/Module/Setup.php:458
+#: ../../Zotlabs/Module/Setup.php:454
msgid "PHP upload limits"
msgstr "Максимальный размер загрузки в PHP"
-#: ../../Zotlabs/Module/Setup.php:481
+#: ../../Zotlabs/Module/Setup.php:477
msgid ""
"Error: the \"openssl_pkey_new\" function on this system is not able to "
"generate encryption keys"
msgstr "Ошибка: функция \"openssl_pkey_new\" не может сгенерировать ключи шифрования"
-#: ../../Zotlabs/Module/Setup.php:482
+#: ../../Zotlabs/Module/Setup.php:478
msgid ""
"If running under Windows, please see \"http://www.php.net/manual/en/openssl."
"installation.php\"."
msgstr "Если работаете под Windows, см. \"http://www.php.net/manual/en/openssl.installation.php\"."
-#: ../../Zotlabs/Module/Setup.php:485
+#: ../../Zotlabs/Module/Setup.php:481
msgid "Generate encryption keys"
msgstr "Генерация ключей шифрования"
-#: ../../Zotlabs/Module/Setup.php:502
+#: ../../Zotlabs/Module/Setup.php:498
msgid "libCurl PHP module"
msgstr "модуль PHP libcURL"
-#: ../../Zotlabs/Module/Setup.php:503
+#: ../../Zotlabs/Module/Setup.php:499
msgid "GD graphics PHP module"
msgstr "модуль графики PHP GD"
-#: ../../Zotlabs/Module/Setup.php:504
+#: ../../Zotlabs/Module/Setup.php:500
msgid "OpenSSL PHP module"
msgstr "модуль PHP OpenSSL"
-#: ../../Zotlabs/Module/Setup.php:505
+#: ../../Zotlabs/Module/Setup.php:501
msgid "PDO database PHP module"
msgstr "модуль баз данных PHP PDO"
-#: ../../Zotlabs/Module/Setup.php:506
+#: ../../Zotlabs/Module/Setup.php:502
msgid "mb_string PHP module"
msgstr "модуль PHP mb_string"
-#: ../../Zotlabs/Module/Setup.php:507
+#: ../../Zotlabs/Module/Setup.php:503
msgid "xml PHP module"
msgstr "модуль PHP xml"
-#: ../../Zotlabs/Module/Setup.php:508
+#: ../../Zotlabs/Module/Setup.php:504
msgid "zip PHP module"
msgstr "модуль PHP zip"
-#: ../../Zotlabs/Module/Setup.php:512 ../../Zotlabs/Module/Setup.php:514
+#: ../../Zotlabs/Module/Setup.php:508 ../../Zotlabs/Module/Setup.php:510
msgid "Apache mod_rewrite module"
msgstr "модуль Apache mod_rewrite"
-#: ../../Zotlabs/Module/Setup.php:512
+#: ../../Zotlabs/Module/Setup.php:508
msgid ""
"Error: Apache webserver mod-rewrite module is required but not installed."
msgstr "Ошибка: требуемый модуль mod_rewrite веб-сервера Apache не установлен."
-#: ../../Zotlabs/Module/Setup.php:518 ../../Zotlabs/Module/Setup.php:521
+#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:517
msgid "exec"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:518
+#: ../../Zotlabs/Module/Setup.php:514
msgid ""
"Error: exec is required but is either not installed or has been disabled in "
"php.ini"
msgstr "Ошибка: exec требуется, однако не установлен или был отключён в php.ini"
-#: ../../Zotlabs/Module/Setup.php:524 ../../Zotlabs/Module/Setup.php:527
+#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523
msgid "shell_exec"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:524
+#: ../../Zotlabs/Module/Setup.php:520
msgid ""
"Error: shell_exec is required but is either not installed or has been "
"disabled in php.ini"
msgstr "Ошибка: shell_exec требуется, однако не установлен или был отключён в php.ini"
-#: ../../Zotlabs/Module/Setup.php:532
+#: ../../Zotlabs/Module/Setup.php:528
msgid "Error: libCURL PHP module required but not installed."
msgstr "Ошибка: модуль PHP libсURL требуется, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:536
+#: ../../Zotlabs/Module/Setup.php:532
msgid ""
"Error: GD PHP module with JPEG support or ImageMagick graphics library "
"required but not installed."
msgstr "Ошибка: модуль PHP GD с поддержкой JPEG или графическая библиотека ImageMagick требуется, однако не установлена"
-#: ../../Zotlabs/Module/Setup.php:540
+#: ../../Zotlabs/Module/Setup.php:536
msgid "Error: openssl PHP module required but not installed."
msgstr "Ошибка: модуль PHP OpenSSL требуется, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:546
+#: ../../Zotlabs/Module/Setup.php:542
msgid ""
"Error: PDO database PHP module missing a driver for either mysql or pgsql."
msgstr "Ошибка: отсутствует драйвер MySQL или PgSQL в модуле баз данных PHP PDO"
-#: ../../Zotlabs/Module/Setup.php:551
+#: ../../Zotlabs/Module/Setup.php:547
msgid "Error: PDO database PHP module required but not installed."
msgstr "Ошибка: модуль баз данных PHP PDO требуется, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:555
+#: ../../Zotlabs/Module/Setup.php:551
msgid "Error: mb_string PHP module required but not installed."
msgstr "Ошибка: модуль PHP mb_string требуется, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:559
+#: ../../Zotlabs/Module/Setup.php:555
msgid "Error: xml PHP module required for DAV but not installed."
msgstr "Ошибка: модуль PHP xml требуется для DAV, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:563
+#: ../../Zotlabs/Module/Setup.php:559
msgid "Error: zip PHP module required but not installed."
msgstr "Ошибка: модуль PHP zip требуется, однако не установлен"
-#: ../../Zotlabs/Module/Setup.php:582 ../../Zotlabs/Module/Setup.php:591
+#: ../../Zotlabs/Module/Setup.php:578 ../../Zotlabs/Module/Setup.php:587
msgid ".htconfig.php is writable"
msgstr ".htconfig.php доступен для записи"
-#: ../../Zotlabs/Module/Setup.php:587
+#: ../../Zotlabs/Module/Setup.php:583
msgid ""
"The web installer needs to be able to create a file called \".htconfig.php\" "
"in the top folder of your web server and it is unable to do so."
msgstr "Инсталлятор требует возможности создать файл с именем \".htconfig.php\" в корневом каталоге вашего веб-сервера но не может этого сделать."
-#: ../../Zotlabs/Module/Setup.php:588
+#: ../../Zotlabs/Module/Setup.php:584
msgid ""
"This is most often a permission setting, as the web server may not be able "
"to write files in your folder - even if you can."
msgstr "В большинстве случаев это проблема прав доступа. Веб-сервер может не иметь возможности записывать файлы в этот каталог даже если вы можете это делать."
-#: ../../Zotlabs/Module/Setup.php:589
+#: ../../Zotlabs/Module/Setup.php:585
msgid "Please see install/INSTALL.txt for additional information."
msgstr "Пожалуйста, ознакомьтесь с install/INSTALL.txt для дополнительных сведений."
-#: ../../Zotlabs/Module/Setup.php:605
+#: ../../Zotlabs/Module/Setup.php:601
msgid ""
"This software uses the Smarty3 template engine to render its web views. "
"Smarty3 compiles templates to PHP to speed up rendering."
msgstr "Это программное обеспечение использует шаблонизатор Smarty3 для отображения своих веб-страниц. Smarty3 компилирует шаблоны для PHP для ускорения рендеринга."
-#: ../../Zotlabs/Module/Setup.php:606
+#: ../../Zotlabs/Module/Setup.php:602
#, php-format
msgid ""
"In order to store these compiled templates, the web server needs to have "
"write access to the directory %s under the top level web folder."
msgstr "Для хранения этих скомпилированных шаблонов веб-сервер должен иметь доступ на запись к каталогу %s в каталоге верхнего уровня."
-#: ../../Zotlabs/Module/Setup.php:607 ../../Zotlabs/Module/Setup.php:628
+#: ../../Zotlabs/Module/Setup.php:603 ../../Zotlabs/Module/Setup.php:624
msgid ""
"Please ensure that the user that your web server runs as (e.g. www-data) has "
"write access to this folder."
msgstr "Убедитесь, что пользователь от имени которого работает ваш веб-сервер (например, www-data), имеет доступ на запись в этот каталог."
-#: ../../Zotlabs/Module/Setup.php:608
+#: ../../Zotlabs/Module/Setup.php:604
#, php-format
msgid ""
"Note: as a security measure, you should give the web server write access to "
"%s only--not the template files (.tpl) that it contains."
msgstr "Примечание. В качестве меры безопасности вы должны предоставить доступ веб-серверу для записи только к %s но не к содержащимися в нём файлами шаблонов (.tpl)."
-#: ../../Zotlabs/Module/Setup.php:611
+#: ../../Zotlabs/Module/Setup.php:607
#, php-format
msgid "%s is writable"
msgstr "%s доступен для записи"
-#: ../../Zotlabs/Module/Setup.php:627
+#: ../../Zotlabs/Module/Setup.php:623
msgid ""
"This software uses the store directory to save uploaded files. The web "
"server needs to have write access to the store directory under the top level "
"web folder"
msgstr "Эта программа использует каталог хранения для загруженных файлов. Для веб-сервера требуется доступ на запись начиная с верхнего уровня каталога хранения."
-#: ../../Zotlabs/Module/Setup.php:631
+#: ../../Zotlabs/Module/Setup.php:627
msgid "store is writable"
msgstr "хранилище доступно для записи"
-#: ../../Zotlabs/Module/Setup.php:663
+#: ../../Zotlabs/Module/Setup.php:659
msgid ""
"SSL certificate cannot be validated. Fix certificate or disable https access "
"to this site."
msgstr "SSL certificate cannot be validated. Замените его или отключите https доступ к этому сайту."
-#: ../../Zotlabs/Module/Setup.php:664
+#: ../../Zotlabs/Module/Setup.php:660
msgid ""
"If you have https access to your website or allow connections to TCP port "
"443 (the https: port), you MUST use a browser-valid certificate. You MUST "
"NOT use self-signed certificates!"
msgstr "Если у вас есть https-доступ к вашему сайту или разрешено подключение к TCP-порту 443 (порт https), вы ДОЛЖНЫ использовать сертификат, действительный для браузера. Вы НЕ ДОЛЖНЫ использовать самоподписанные сертификаты!"
-#: ../../Zotlabs/Module/Setup.php:665
+#: ../../Zotlabs/Module/Setup.php:661
msgid ""
"This restriction is incorporated because public posts from you may for "
"example contain references to images on your own hub."
msgstr "Эти ограничения приняты поскольку ваши общедоступные публикации могут, например, содержать ссылки на изображения на вашем собственном хабе."
-#: ../../Zotlabs/Module/Setup.php:666
+#: ../../Zotlabs/Module/Setup.php:662
msgid ""
"If your certificate is not recognized, members of other sites (who may "
"themselves have valid certificates) will get a warning message on their own "
"site complaining about security issues."
msgstr "Если ваш сертификат не признан, пользователи других сайтов (которые могут сами иметь действительные сертификаты) получат предупреждающее сообщение о проблемах с безопасностью."
-#: ../../Zotlabs/Module/Setup.php:667
+#: ../../Zotlabs/Module/Setup.php:663
msgid ""
"This can cause usability issues elsewhere (not just on your own site) so we "
"must insist on this requirement."
msgstr "Это может привести к проблемам удобства использования из других мест (не только на вашем собственном сайте), поэтому мы настаиваем на этом требовании."
-#: ../../Zotlabs/Module/Setup.php:668
+#: ../../Zotlabs/Module/Setup.php:664
msgid ""
"Providers are available that issue free certificates which are browser-valid."
msgstr "Доступны поставщики, которые выдают действительные для браузера бесплатные сертификаты."
-#: ../../Zotlabs/Module/Setup.php:670
+#: ../../Zotlabs/Module/Setup.php:665
msgid ""
"If you are confident that the certificate is valid and signed by a trusted "
"authority, check to see if you have failed to install an intermediate cert. "
@@ -2282,308 +8152,161 @@ msgid ""
"server communications."
msgstr "Если вы уверены, что сертификат действителен и подписан доверенным органом, проверьте, установлен ли промежуточные сертификаты. Обычно они не требуются браузерами, но бывают необходимы для связи между серверами."
-#: ../../Zotlabs/Module/Setup.php:672
+#: ../../Zotlabs/Module/Setup.php:667
msgid "SSL certificate validation"
msgstr "Проверка SSL сертификата"
-#: ../../Zotlabs/Module/Setup.php:678
+#: ../../Zotlabs/Module/Setup.php:673
msgid ""
"Url rewrite in .htaccess is not working. Check your server configuration."
"Test: "
msgstr "Перезапись URL в .htaccess не работает. Проверьте настройки вашего сервера."
-#: ../../Zotlabs/Module/Setup.php:681
+#: ../../Zotlabs/Module/Setup.php:676
msgid "Url rewrite is working"
msgstr "Перезапись URL работает"
-#: ../../Zotlabs/Module/Setup.php:695
+#: ../../Zotlabs/Module/Setup.php:689
msgid ""
"The database configuration file \".htconfig.php\" could not be written. "
"Please use the enclosed text to create a configuration file in your web "
"server root."
msgstr "Файл конфигурации базы данных \".htconfig.php\" не может быть записан. Используйте прилагаемый текст для создания файла конфигурации в корневом каталоге веб-сервера."
-#: ../../Zotlabs/Module/Setup.php:719 ../../addon/rendezvous/rendezvous.php:401
+#: ../../Zotlabs/Module/Setup.php:718
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:401
msgid "Errors encountered creating database tables."
msgstr "При создании базы данных возникли ошибки."
-#: ../../Zotlabs/Module/Setup.php:759
+#: ../../Zotlabs/Module/Setup.php:764
msgid "<h1>What next?</h1>"
msgstr "<h1>Что дальше? </h1>"
-#: ../../Zotlabs/Module/Setup.php:760
+#: ../../Zotlabs/Module/Setup.php:765
msgid ""
"IMPORTANT: You will need to [manually] setup a scheduled task for the poller."
msgstr "Вам понадобится [вручную] настроить запланированную задачу для опрашивателя."
-#: ../../Zotlabs/Module/Connect.php:73 ../../Zotlabs/Module/Connect.php:135
-msgid "Continue"
-msgstr "Продолжить"
-
-#: ../../Zotlabs/Module/Connect.php:104
-msgid "Premium Channel App"
-msgstr "Приложение \"Премиальный канал\""
-
-#: ../../Zotlabs/Module/Connect.php:105
-msgid ""
-"Allows you to set restrictions and terms on those that connect with your "
-"channel"
-msgstr "Позволяет установить ограничения и условия для подключающихся к вашему каналу"
-
-#: ../../Zotlabs/Module/Connect.php:116
-msgid "Premium Channel Setup"
-msgstr "Установка премиального канала"
-
-#: ../../Zotlabs/Module/Connect.php:118
-msgid "Enable premium channel connection restrictions"
-msgstr "Включить ограничения для премиального канала"
-
-#: ../../Zotlabs/Module/Connect.php:119
-msgid ""
-"Please enter your restrictions or conditions, such as paypal receipt, usage "
-"guidelines, etc."
-msgstr "Пожалуйста введите ваши ограничения или условия, такие, как оплата PayPal, правила использования и т.п."
-
-#: ../../Zotlabs/Module/Connect.php:121 ../../Zotlabs/Module/Connect.php:141
-msgid ""
-"This channel may require additional steps or acknowledgement of the "
-"following conditions prior to connecting:"
-msgstr "Этот канал до подключения может требовать дополнительных шагов или подтверждений следующих условий:"
-
-#: ../../Zotlabs/Module/Connect.php:122
-msgid ""
-"Potential connections will then see the following text before proceeding:"
-msgstr "Потенциальные соединения будут видеть следующий предварительный текст:"
-
-#: ../../Zotlabs/Module/Connect.php:123 ../../Zotlabs/Module/Connect.php:144
-msgid ""
-"By continuing, I certify that I have complied with any instructions provided "
-"on this page."
-msgstr "Продолжая, я подтверждаю что я выполнил все условия представленные на данной странице."
+#: ../../Zotlabs/Module/Mitem.php:63
+msgid "Unable to create element."
+msgstr "Невозможно создать элемент."
-#: ../../Zotlabs/Module/Connect.php:132
-msgid "(No specific instructions have been provided by the channel owner.)"
-msgstr "(Владельцем канала не было представлено никаких специальных инструкций.)"
+#: ../../Zotlabs/Module/Mitem.php:87
+msgid "Unable to update menu element."
+msgstr "Невозможно обновить элемент меню."
-#: ../../Zotlabs/Module/Connect.php:140
-msgid "Restricted or Premium Channel"
-msgstr "Ограниченный или премиальный канал"
+#: ../../Zotlabs/Module/Mitem.php:103
+msgid "Unable to add menu element."
+msgstr "Невозможно добавить элемент меню."
-#: ../../Zotlabs/Module/Admin/Queue.php:35
-msgid "Queue Statistics"
-msgstr "Статистика очереди"
+#: ../../Zotlabs/Module/Mitem.php:167 ../../Zotlabs/Module/Mitem.php:246
+msgid "Menu Item Permissions"
+msgstr "Разрешения на пункт меню"
-#: ../../Zotlabs/Module/Admin/Queue.php:36
-msgid "Total Entries"
-msgstr "Всего записей"
+#: ../../Zotlabs/Module/Mitem.php:174 ../../Zotlabs/Module/Mitem.php:191
+msgid "Link Name"
+msgstr "Имя ссылки"
-#: ../../Zotlabs/Module/Admin/Queue.php:37
-msgid "Priority"
-msgstr "Приоритет"
+#: ../../Zotlabs/Module/Mitem.php:175 ../../Zotlabs/Module/Mitem.php:255
+msgid "Link or Submenu Target"
+msgstr "Ссылка или цель подменю"
-#: ../../Zotlabs/Module/Admin/Queue.php:38
-msgid "Destination URL"
-msgstr "Конечный URL-адрес"
+#: ../../Zotlabs/Module/Mitem.php:175
+msgid "Enter URL of the link or select a menu name to create a submenu"
+msgstr "Введите URL ссылки или выберите имя меню для создания подменю"
-#: ../../Zotlabs/Module/Admin/Queue.php:39
-msgid "Mark hub permanently offline"
-msgstr "Пометить хаб как постоянно отключенный"
+#: ../../Zotlabs/Module/Mitem.php:176 ../../Zotlabs/Module/Mitem.php:256
+msgid "Use magic-auth if available"
+msgstr "Использовать magic-auth если возможно"
-#: ../../Zotlabs/Module/Admin/Queue.php:40
-msgid "Empty queue for this hub"
-msgstr "Освободить очередь для этого хаба"
+#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:257
+msgid "Open link in new window"
+msgstr "Открыть ссылку в новом окне"
-#: ../../Zotlabs/Module/Admin/Queue.php:41
-msgid "Last known contact"
-msgstr "Последний известный контакт"
+#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258
+msgid "Order in list"
+msgstr "Порядок в списке"
-#: ../../Zotlabs/Module/Admin/Features.php:55
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#: ../../Zotlabs/Module/Settings/Features.php:36 ../../include/features.php:55
-msgid "Off"
-msgstr "Выкл."
+#: ../../Zotlabs/Module/Mitem.php:178 ../../Zotlabs/Module/Mitem.php:258
+msgid "Higher numbers will sink to bottom of listing"
+msgstr "Большие значения в конце списка"
-#: ../../Zotlabs/Module/Admin/Features.php:55
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#: ../../Zotlabs/Module/Settings/Features.php:36 ../../include/features.php:55
-msgid "On"
-msgstr "Вкл."
+#: ../../Zotlabs/Module/Mitem.php:179
+msgid "Submit and finish"
+msgstr "Отправить и завершить"
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#, php-format
-msgid "Lock feature %s"
-msgstr "Заблокировать функцию \"%s\""
+#: ../../Zotlabs/Module/Mitem.php:180
+msgid "Submit and continue"
+msgstr "Отправить и продолжить"
-#: ../../Zotlabs/Module/Admin/Features.php:64
-msgid "Manage Additional Features"
-msgstr "Управление дополнительными функциями"
+#: ../../Zotlabs/Module/Mitem.php:189
+msgid "Menu:"
+msgstr "Меню:"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:19
-msgid "Update has been marked successful"
-msgstr "Обновление было помечено как успешное"
+#: ../../Zotlabs/Module/Mitem.php:192
+msgid "Link Target"
+msgstr "Цель ссылки"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:31
-#, php-format
-msgid "Executing %s failed. Check system logs."
-msgstr "Выполнение %s неудачно. Проверьте системный журнал."
+#: ../../Zotlabs/Module/Mitem.php:195
+msgid "Edit menu"
+msgstr "Редактировать меню"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:34
-#, php-format
-msgid "Update %s was successfully applied."
-msgstr "Обновление %sбыло успешно применено."
+#: ../../Zotlabs/Module/Mitem.php:198
+msgid "Edit element"
+msgstr "Редактировать элемент"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:38
-#, php-format
-msgid "Update %s did not return a status. Unknown if it succeeded."
-msgstr "Обновление %s не вернуло статус. Неизвестно было ли оно успешным."
+#: ../../Zotlabs/Module/Mitem.php:199
+msgid "Drop element"
+msgstr "Удалить элемент"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:41
-#, php-format
-msgid "Update function %s could not be found."
-msgstr "Функция обновления %sне может быть найдена."
+#: ../../Zotlabs/Module/Mitem.php:200
+msgid "New element"
+msgstr "Новый элемент"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:59
-msgid "Failed Updates"
-msgstr "Обновления с ошибками"
+#: ../../Zotlabs/Module/Mitem.php:201
+msgid "Edit this menu container"
+msgstr "Редактировать контейнер меню"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:61
-msgid "Mark success (if update was manually applied)"
-msgstr "Пометить успешным (если обновление было применено вручную)"
+#: ../../Zotlabs/Module/Mitem.php:202
+msgid "Add menu element"
+msgstr "Добавить элемент меню"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:62
-msgid "Attempt to execute this update step automatically"
-msgstr "Попытаться применить это обновление автоматически"
+#: ../../Zotlabs/Module/Mitem.php:203
+msgid "Delete this menu item"
+msgstr "Удалить этот элемент меню"
-#: ../../Zotlabs/Module/Admin/Dbsync.php:67
-msgid "No failed updates."
-msgstr "Ошибок обновлений нет."
+#: ../../Zotlabs/Module/Mitem.php:204
+msgid "Edit this menu item"
+msgstr "Редактировать этот элемент меню"
-#: ../../Zotlabs/Module/Admin/Accounts.php:37
-#, php-format
-msgid "%s account blocked/unblocked"
-msgid_plural "%s account blocked/unblocked"
-msgstr[0] "%s аккаунт блокирован/разблокирован"
-msgstr[1] "%s аккаунта блокированы/разблокированы"
-msgstr[2] "%s аккаунтов блокированы/разблокированы"
+#: ../../Zotlabs/Module/Mitem.php:222
+msgid "Menu item not found."
+msgstr "Элемент меню не найден."
-#: ../../Zotlabs/Module/Admin/Accounts.php:44
-#, php-format
-msgid "%s account deleted"
-msgid_plural "%s accounts deleted"
-msgstr[0] "%s аккаунт удалён"
-msgstr[1] "%s аккаунта удалёны"
-msgstr[2] "%s аккаунтов удалёны"
+#: ../../Zotlabs/Module/Mitem.php:235
+msgid "Menu item deleted."
+msgstr "Элемент меню удалён."
-#: ../../Zotlabs/Module/Admin/Accounts.php:80
-msgid "Account not found"
-msgstr "Аккаунт не найден"
+#: ../../Zotlabs/Module/Mitem.php:237
+msgid "Menu item could not be deleted."
+msgstr "Невозможно удалить элемент меню."
-#: ../../Zotlabs/Module/Admin/Accounts.php:91 ../../include/channel.php:2562
-#, php-format
-msgid "Account '%s' deleted"
-msgstr "Аккаунт '%s' удален"
+#: ../../Zotlabs/Module/Mitem.php:244
+msgid "Edit Menu Element"
+msgstr "Редактировать элемент меню"
-#: ../../Zotlabs/Module/Admin/Accounts.php:99
-#, php-format
-msgid "Account '%s' blocked"
-msgstr "Аккаунт '%s' заблокирован"
+#: ../../Zotlabs/Module/Mitem.php:254
+msgid "Link text"
+msgstr "Текст ссылки"
-#: ../../Zotlabs/Module/Admin/Accounts.php:107
+#: ../../Zotlabs/Module/Admin/Features.php:56
#, php-format
-msgid "Account '%s' unblocked"
-msgstr "Аккаунт '%s' разблокирован"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:166
-#: ../../Zotlabs/Module/Admin/Logs.php:82
-#: ../../Zotlabs/Module/Admin/Channels.php:145
-#: ../../Zotlabs/Module/Admin/Themes.php:122
-#: ../../Zotlabs/Module/Admin/Themes.php:156
-#: ../../Zotlabs/Module/Admin/Site.php:287
-#: ../../Zotlabs/Module/Admin/Addons.php:341
-#: ../../Zotlabs/Module/Admin/Addons.php:439
-#: ../../Zotlabs/Module/Admin/Security.php:92
-#: ../../Zotlabs/Module/Admin.php:138
-msgid "Administration"
-msgstr "Администрирование"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:167
-#: ../../Zotlabs/Module/Admin/Accounts.php:180
-#: ../../Zotlabs/Module/Admin.php:96 ../../Zotlabs/Widget/Admin.php:23
-msgid "Accounts"
-msgstr "Учётные записи"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:169
-#: ../../Zotlabs/Module/Admin/Channels.php:148
-msgid "select all"
-msgstr "выбрать все"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:170
-msgid "Registrations waiting for confirm"
-msgstr "Регистрации ждут подтверждения"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:171
-msgid "Request date"
-msgstr "Дата запроса"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:172
-msgid "No registrations."
-msgstr "Нет новых регистраций."
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:173
-#: ../../Zotlabs/Module/Connections.php:306 ../../include/conversation.php:735
-msgid "Approve"
-msgstr "Утвердить"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:174
-#: ../../Zotlabs/Module/Authorize.php:33
-msgid "Deny"
-msgstr "Запретить"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:176
-#: ../../Zotlabs/Module/Connedit.php:636
-msgid "Block"
-msgstr "Блокировать"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:177
-#: ../../Zotlabs/Module/Connedit.php:636
-msgid "Unblock"
-msgstr "Разблокировать"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:182
-msgid "ID"
-msgstr ""
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:184
-msgid "All Channels"
-msgstr "Все каналы"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:185
-msgid "Register date"
-msgstr "Дата регистрации"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:186
-msgid "Last login"
-msgstr "Последний вход"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:187
-msgid "Expires"
-msgstr "Срок действия"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:188
-msgid "Service Class"
-msgstr "Класс обслуживания"
-
-#: ../../Zotlabs/Module/Admin/Accounts.php:190
-msgid ""
-"Selected accounts will be deleted!\\n\\nEverything these accounts had posted "
-"on this site will be permanently deleted!\\n\\nAre you sure?"
-msgstr "Выбранные учётные записи будут удалены!\n\nВсё что было ими опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?"
+msgid "Lock feature %s"
+msgstr "Заблокировать функцию \"%s\""
-#: ../../Zotlabs/Module/Admin/Accounts.php:191
-msgid ""
-"The account {0} will be deleted!\\n\\nEverything this account has posted on "
-"this site will be permanently deleted!\\n\\nAre you sure?"
-msgstr "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?"
+#: ../../Zotlabs/Module/Admin/Features.php:64
+msgid "Manage Additional Features"
+msgstr "Управление дополнительными функциями"
#: ../../Zotlabs/Module/Admin/Logs.php:28
msgid "Log settings updated."
@@ -2669,10 +8392,10 @@ msgstr "Код в канале '%s' разрешён"
msgid "Channel '%s' code disallowed"
msgstr "Код в канале '%s' запрещён"
-#: ../../Zotlabs/Module/Admin/Channels.php:146
-#: ../../Zotlabs/Module/Admin.php:114 ../../Zotlabs/Widget/Admin.php:24
-msgid "Channels"
-msgstr "Каналы"
+#: ../../Zotlabs/Module/Admin/Channels.php:148
+#: ../../Zotlabs/Module/Admin/Accounts.php:169
+msgid "select all"
+msgstr "выбрать все"
#: ../../Zotlabs/Module/Admin/Channels.php:150
msgid "Censor"
@@ -2690,10 +8413,6 @@ msgstr "Разрешить код"
msgid "Disallow Code"
msgstr "Запретить код"
-#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:421
-msgid "Channel"
-msgstr "Канал"
-
#: ../../Zotlabs/Module/Admin/Channels.php:158
msgid "UID"
msgstr ""
@@ -2710,87 +8429,243 @@ msgid ""
"channel on this site will be permanently deleted!\\n\\nAre you sure?"
msgstr "Канал {0} будет удалён!\n\nВсё что было опубликовано в этом канале на этом сайте будет удалено навсегда!\n\nВы уверены?"
-#: ../../Zotlabs/Module/Admin/Themes.php:26
-msgid "Theme settings updated."
-msgstr "Настройки темы обновленны."
+#: ../../Zotlabs/Module/Admin/Security.php:83
+msgid ""
+"By default, unfiltered HTML is allowed in embedded media. This is inherently "
+"insecure."
+msgstr "По умолчанию, HTML без фильтрации доступен во встраиваемых медиа. Это небезопасно."
-#: ../../Zotlabs/Module/Admin/Themes.php:61
-msgid "No themes found."
-msgstr "Темы не найдены."
+#: ../../Zotlabs/Module/Admin/Security.php:86
+msgid ""
+"The recommended setting is to only allow unfiltered HTML from the following "
+"sites:"
+msgstr "Рекомендуется настроить разрешения использовать HTML без фильтрации только для следующих сайтов:"
-#: ../../Zotlabs/Module/Admin/Themes.php:72
-#: ../../Zotlabs/Module/Admin/Addons.php:259 ../../Zotlabs/Module/Thing.php:94
-#: ../../Zotlabs/Module/Viewsrc.php:25 ../../Zotlabs/Module/Display.php:45
-#: ../../Zotlabs/Module/Display.php:450 ../../Zotlabs/Module/Filestorage.php:24
-#: ../../Zotlabs/Module/Admin.php:62 ../../include/items.php:3693
-msgid "Item not found."
-msgstr "Элемент не найден."
+#: ../../Zotlabs/Module/Admin/Security.php:87
+msgid ""
+"https://youtube.com/<br />https://www.youtube.com/<br />https://youtu.be/"
+"<br />https://vimeo.com/<br />https://soundcloud.com/<br />"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Security.php:88
+msgid ""
+"All other embedded content will be filtered, <strong>unless</strong> "
+"embedded content from that site is explicitly blocked."
+msgstr "се остальные встроенные материалы будут отфильтрованы, <strong>если </strong> встроенное содержимое с этого сайта явно заблокировано."
+
+#: ../../Zotlabs/Module/Admin/Security.php:93 ../../Zotlabs/Widget/Admin.php:25
+msgid "Security"
+msgstr "Безопасность"
+
+#: ../../Zotlabs/Module/Admin/Security.php:95
+msgid "Block public"
+msgstr "Блокировать публичный доступ"
+
+#: ../../Zotlabs/Module/Admin/Security.php:95
+msgid ""
+"Check to block public access to all otherwise public personal pages on this "
+"site unless you are currently authenticated."
+msgstr "Установите флажок для блокировки публичного доступа ко всем другим общедоступным страницам на этом сайте, если вы в настоящее время не аутентифицированы."
+
+#: ../../Zotlabs/Module/Admin/Security.php:96
+msgid "Provide a cloud root directory"
+msgstr "Предоставить корневой каталог в облаке"
+
+#: ../../Zotlabs/Module/Admin/Security.php:96
+msgid ""
+"The cloud root directory lists all channel names which provide public files"
+msgstr "В корневом каталоге облака показываются все имена каналов, которые предоставляют общедоступные файлы"
+
+#: ../../Zotlabs/Module/Admin/Security.php:97
+msgid "Show total disk space available to cloud uploads"
+msgstr "Показывать общее доступное для загрузок место в хранилище"
+
+#: ../../Zotlabs/Module/Admin/Security.php:98
+msgid "Set \"Transport Security\" HTTP header"
+msgstr "Установить HTTP-заголовок \"Transport Security\""
+
+#: ../../Zotlabs/Module/Admin/Security.php:99
+msgid "Set \"Content Security Policy\" HTTP header"
+msgstr "Установить HTTP-заголовок \"Content Security Policy\""
+
+#: ../../Zotlabs/Module/Admin/Security.php:100
+msgid "Allowed email domains"
+msgstr "Разрешённые домены email"
+
+#: ../../Zotlabs/Module/Admin/Security.php:100
+msgid ""
+"Comma separated list of domains which are allowed in email addresses for "
+"registrations to this site. Wildcards are accepted. Empty to allow any "
+"domains"
+msgstr "Список разделённых запятыми доменов для которых разрешена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены."
+
+#: ../../Zotlabs/Module/Admin/Security.php:101
+msgid "Not allowed email domains"
+msgstr "Запрещённые домены email"
+
+#: ../../Zotlabs/Module/Admin/Security.php:101
+msgid ""
+"Comma separated list of domains which are not allowed in email addresses for "
+"registrations to this site. Wildcards are accepted. Empty to allow any "
+"domains, unless allowed domains have been defined."
+msgstr "Список разделённых запятыми доменов для которых запрещена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены до тех пор, пока разрешённые домены не будут указаны."
+
+#: ../../Zotlabs/Module/Admin/Security.php:102
+msgid "Allow communications only from these sites"
+msgstr "Разрешить связь только с этими сайтами"
+
+#: ../../Zotlabs/Module/Admin/Security.php:102
+msgid ""
+"One site per line. Leave empty to allow communication from anywhere by "
+"default"
+msgstr "Один сайт на строку. Оставьте пустым для разрешения взаимодействия без ограничений (по умочанию)."
+
+#: ../../Zotlabs/Module/Admin/Security.php:103
+msgid "Block communications from these sites"
+msgstr "Блокировать связь с этими сайтами"
+
+#: ../../Zotlabs/Module/Admin/Security.php:104
+msgid "Allow communications only from these channels"
+msgstr "Разрешить связь только для этих каналов"
+
+#: ../../Zotlabs/Module/Admin/Security.php:104
+msgid ""
+"One channel (hash) per line. Leave empty to allow from any channel by default"
+msgstr "Один канал (или его хэш) на строку. Оставьте пустым для разрешения взаимодействия с любым каналом (по умолчанию)."
+
+#: ../../Zotlabs/Module/Admin/Security.php:105
+msgid "Block communications from these channels"
+msgstr "Блокировать связь с этими каналами"
+
+#: ../../Zotlabs/Module/Admin/Security.php:106
+msgid "Only allow embeds from secure (SSL) websites and links."
+msgstr "Разрешать встраивание только для безопасных (SSL/TLS) сайтов и ссылок."
+
+#: ../../Zotlabs/Module/Admin/Security.php:107
+msgid "Allow unfiltered embedded HTML content only from these domains"
+msgstr "Разрешить встраивать нефильтруемое HTML-содержимое только для этих доменов"
+
+#: ../../Zotlabs/Module/Admin/Security.php:107
+msgid "One site per line. By default embedded content is filtered."
+msgstr "Один сайт на строку. По умолчанию встраиваемое содержимое фильтруется."
+
+#: ../../Zotlabs/Module/Admin/Security.php:108
+msgid "Block embedded HTML from these domains"
+msgstr "Блокировать встраивание HTML-содержимого для этих доменов"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:289
+#, php-format
+msgid "Plugin %s disabled."
+msgstr "Плагин %s отключен."
+
+#: ../../Zotlabs/Module/Admin/Addons.php:294
+#, php-format
+msgid "Plugin %s enabled."
+msgstr "Плагин %s включен."
-#: ../../Zotlabs/Module/Admin/Themes.php:95
#: ../../Zotlabs/Module/Admin/Addons.php:310
+#: ../../Zotlabs/Module/Admin/Themes.php:95
msgid "Disable"
msgstr "Запретить"
-#: ../../Zotlabs/Module/Admin/Themes.php:97
#: ../../Zotlabs/Module/Admin/Addons.php:313
+#: ../../Zotlabs/Module/Admin/Themes.php:97
msgid "Enable"
msgstr "Разрешить"
-#: ../../Zotlabs/Module/Admin/Themes.php:116
-msgid "Screenshot"
-msgstr "Снимок экрана"
-
-#: ../../Zotlabs/Module/Admin/Themes.php:123
-#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../Zotlabs/Widget/Admin.php:28
-msgid "Themes"
-msgstr "Темы"
+#: ../../Zotlabs/Module/Admin/Addons.php:342
+#: ../../Zotlabs/Module/Admin/Addons.php:440 ../../Zotlabs/Widget/Admin.php:27
+msgid "Addons"
+msgstr "Расширения"
-#: ../../Zotlabs/Module/Admin/Themes.php:124
#: ../../Zotlabs/Module/Admin/Addons.php:343
+#: ../../Zotlabs/Module/Admin/Themes.php:124
msgid "Toggle"
msgstr "Переключить"
-#: ../../Zotlabs/Module/Admin/Themes.php:125
-#: ../../Zotlabs/Module/Admin/Addons.php:344 ../../Zotlabs/Lib/Apps.php:336
-#: ../../Zotlabs/Widget/Newmember.php:53
-#: ../../Zotlabs/Widget/Settings_menu.php:61 ../../include/nav.php:97
-msgid "Settings"
-msgstr "Настройки"
-
-#: ../../Zotlabs/Module/Admin/Themes.php:134
#: ../../Zotlabs/Module/Admin/Addons.php:351
+#: ../../Zotlabs/Module/Admin/Themes.php:134
msgid "Author: "
msgstr "Автор: "
-#: ../../Zotlabs/Module/Admin/Themes.php:135
#: ../../Zotlabs/Module/Admin/Addons.php:352
+#: ../../Zotlabs/Module/Admin/Themes.php:135
msgid "Maintainer: "
msgstr "Сопровождающий:"
-#: ../../Zotlabs/Module/Admin/Themes.php:162
-msgid "[Experimental]"
-msgstr "[экспериментальный]"
+#: ../../Zotlabs/Module/Admin/Addons.php:353
+msgid "Minimum project version: "
+msgstr "Минимальная версия проекта: "
-#: ../../Zotlabs/Module/Admin/Themes.php:163
-msgid "[Unsupported]"
-msgstr "[неподдерживаемый]"
+#: ../../Zotlabs/Module/Admin/Addons.php:354
+msgid "Maximum project version: "
+msgstr "Максимальная версия проекта: "
+
+#: ../../Zotlabs/Module/Admin/Addons.php:355
+msgid "Minimum PHP version: "
+msgstr "Минимальная версия PHP: "
+
+#: ../../Zotlabs/Module/Admin/Addons.php:356
+msgid "Compatible Server Roles: "
+msgstr "Совместимые роли сервера: "
+
+#: ../../Zotlabs/Module/Admin/Addons.php:357
+msgid "Requires: "
+msgstr "Необходимо:"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:358
+#: ../../Zotlabs/Module/Admin/Addons.php:445
+msgid "Disabled - version incompatibility"
+msgstr "Отключено - несовместимость версий"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:414
+msgid "Enter the public git repository URL of the addon repo."
+msgstr "Введите URL публичного репозитория расширений git"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:415
+msgid "Addon repo git URL"
+msgstr "URL репозитория расширений git"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:416
+msgid "Custom repo name"
+msgstr "Пользовательское имя репозитория"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:416
+msgid "(optional)"
+msgstr "(необязательно)"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:417
+msgid "Download Addon Repo"
+msgstr "Загрузить репозиторий расширений"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:424
+msgid "Install new repo"
+msgstr "Установить новый репозиторий"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:425 ../../Zotlabs/Lib/Apps.php:537
+msgid "Install"
+msgstr "Установить"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:448
+msgid "Manage Repos"
+msgstr "Управление репозиториями"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:449
+msgid "Installed Addon Repositories"
+msgstr "Установленные репозитории расширений"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:450
+msgid "Install a New Addon Repository"
+msgstr "Установить новый репозиторий расширений"
+
+#: ../../Zotlabs/Module/Admin/Addons.php:457
+msgid "Switch branch"
+msgstr "Переключить ветку"
#: ../../Zotlabs/Module/Admin/Site.php:161
msgid "Site settings updated."
msgstr "Настройки сайта обновлены."
-#: ../../Zotlabs/Module/Admin/Site.php:187
-#: ../../view/theme/redbasic_c/php/config.php:15
-#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3210
-msgid "Default"
-msgstr "По умолчанию"
-
-#: ../../Zotlabs/Module/Admin/Site.php:198
-#: ../../Zotlabs/Module/Settings/Display.php:119
-#, php-format
-msgid "%s - (Incompatible)"
-msgstr "%s - (несовместимо)"
-
#: ../../Zotlabs/Module/Admin/Site.php:205
msgid "mobile"
msgstr "мобильный"
@@ -2836,11 +8711,6 @@ msgstr "Эта роль будет использоваться для перв
msgid "Site"
msgstr "Сайт"
-#: ../../Zotlabs/Module/Admin/Site.php:290
-#: ../../Zotlabs/Module/Register.php:273
-msgid "Registration"
-msgstr "Регистрация"
-
#: ../../Zotlabs/Module/Admin/Site.php:291
msgid "File upload"
msgstr "Загрузка файла"
@@ -2849,12 +8719,8 @@ msgstr "Загрузка файла"
msgid "Policies"
msgstr "Правила"
-#: ../../Zotlabs/Module/Admin/Site.php:293 ../../include/contact_widgets.php:16
-msgid "Advanced"
-msgstr "Дополнительно"
-
#: ../../Zotlabs/Module/Admin/Site.php:297
-#: ../../addon/statusnet/statusnet.php:593
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:593
msgid "Site name"
msgstr "Название сайта"
@@ -3224,96 +9090,6 @@ msgstr "Необязательно: место размещения сайта"
msgid "Region or country"
msgstr "Регион или страна"
-#: ../../Zotlabs/Module/Admin/Addons.php:289
-#, php-format
-msgid "Plugin %s disabled."
-msgstr "Плагин %s отключен."
-
-#: ../../Zotlabs/Module/Admin/Addons.php:294
-#, php-format
-msgid "Plugin %s enabled."
-msgstr "Плагин %s включен."
-
-#: ../../Zotlabs/Module/Admin/Addons.php:342
-#: ../../Zotlabs/Module/Admin/Addons.php:440 ../../Zotlabs/Widget/Admin.php:27
-msgid "Addons"
-msgstr "Расширения"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:353
-msgid "Minimum project version: "
-msgstr "Минимальная версия проекта: "
-
-#: ../../Zotlabs/Module/Admin/Addons.php:354
-msgid "Maximum project version: "
-msgstr "Максимальная версия проекта: "
-
-#: ../../Zotlabs/Module/Admin/Addons.php:355
-msgid "Minimum PHP version: "
-msgstr "Минимальная версия PHP: "
-
-#: ../../Zotlabs/Module/Admin/Addons.php:356
-msgid "Compatible Server Roles: "
-msgstr "Совместимые роли сервера: "
-
-#: ../../Zotlabs/Module/Admin/Addons.php:357
-msgid "Requires: "
-msgstr "Необходимо:"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:358
-#: ../../Zotlabs/Module/Admin/Addons.php:445
-msgid "Disabled - version incompatibility"
-msgstr "Отключено - несовместимость версий"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:414
-msgid "Enter the public git repository URL of the addon repo."
-msgstr "Введите URL публичного репозитория расширений git"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:415
-msgid "Addon repo git URL"
-msgstr "URL репозитория расширений git"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:416
-msgid "Custom repo name"
-msgstr "Пользовательское имя репозитория"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:416
-msgid "(optional)"
-msgstr "(необязательно)"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:417
-msgid "Download Addon Repo"
-msgstr "Загрузить репозиторий расширений"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:424
-msgid "Install new repo"
-msgstr "Установить новый репозиторий"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:425 ../../Zotlabs/Lib/Apps.php:535
-msgid "Install"
-msgstr "Установить"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:448
-msgid "Manage Repos"
-msgstr "Управление репозиториями"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:449
-msgid "Installed Addon Repositories"
-msgstr "Установленные репозитории расширений"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:450
-msgid "Install a New Addon Repository"
-msgstr "Установить новый репозиторий расширений"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:457
-msgid "Switch branch"
-msgstr "Переключить ветку"
-
-#: ../../Zotlabs/Module/Admin/Addons.php:458
-#: ../../Zotlabs/Module/Photos.php:1035 ../../Zotlabs/Module/Tagrm.php:137
-#: ../../addon/superblock/Mod_Superblock.php:91
-msgid "Remove"
-msgstr "Удалить"
-
#: ../../Zotlabs/Module/Admin/Profs.php:89
msgid "New Profile Field"
msgstr "Поле нового профиля"
@@ -3353,15 +9129,6 @@ msgstr "Текст подсказки"
msgid "Additional info (optional)"
msgstr "Дополнительная информация (необязательно)"
-#: ../../Zotlabs/Module/Admin/Profs.php:94
-#: ../../Zotlabs/Module/Admin/Profs.php:114 ../../Zotlabs/Module/Rbmark.php:32
-#: ../../Zotlabs/Module/Rbmark.php:104 ../../Zotlabs/Module/Filer.php:53
-#: ../../Zotlabs/Widget/Notes.php:23
-#: ../../addon/queueworker/Mod_Queueworker.php:102 ../../include/text.php:1085
-#: ../../include/text.php:1097
-msgid "Save"
-msgstr "Запомнить"
-
#: ../../Zotlabs/Module/Admin/Profs.php:103
msgid "Field definition not found"
msgstr "Определения поля не найдено"
@@ -3398,855 +9165,219 @@ msgstr "Настраиваемые поля"
msgid "Create Custom Field"
msgstr "Создать настраиваемое поле"
-#: ../../Zotlabs/Module/Admin/Account_edit.php:29
-#, php-format
-msgid "Password changed for account %d."
-msgstr "Пароль для аккаунта %d изменён."
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:46
-msgid "Account settings updated."
-msgstr "Настройки аккаунта обновлены."
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:61
-msgid "Account not found."
-msgstr "Учётная запись не найдена."
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:68
-msgid "Account Edit"
-msgstr "Редактировать аккаунт"
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:69
-msgid "New Password"
-msgstr "Новый пароль"
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:70
-msgid "New Password again"
-msgstr "Повторите новый пароль"
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:71
-msgid "Account language (for emails)"
-msgstr "Язык сообщения для email"
-
-#: ../../Zotlabs/Module/Admin/Account_edit.php:72
-msgid "Service class"
-msgstr "Класс обслуживания"
-
-#: ../../Zotlabs/Module/Admin/Security.php:83
-msgid ""
-"By default, unfiltered HTML is allowed in embedded media. This is inherently "
-"insecure."
-msgstr "По умолчанию, HTML без фильтрации доступен во встраиваемых медиа. Это небезопасно."
-
-#: ../../Zotlabs/Module/Admin/Security.php:86
-msgid ""
-"The recommended setting is to only allow unfiltered HTML from the following "
-"sites:"
-msgstr "Рекомендуется настроить разрешения использовать HTML без фильтрации только для следующих сайтов:"
-
-#: ../../Zotlabs/Module/Admin/Security.php:87
-msgid ""
-"https://youtube.com/<br />https://www.youtube.com/<br />https://youtu.be/"
-"<br />https://vimeo.com/<br />https://soundcloud.com/<br />"
-msgstr ""
-
-#: ../../Zotlabs/Module/Admin/Security.php:88
-msgid ""
-"All other embedded content will be filtered, <strong>unless</strong> "
-"embedded content from that site is explicitly blocked."
-msgstr "се остальные встроенные материалы будут отфильтрованы, <strong>если </strong> встроенное содержимое с этого сайта явно заблокировано."
-
-#: ../../Zotlabs/Module/Admin/Security.php:93 ../../Zotlabs/Widget/Admin.php:25
-msgid "Security"
-msgstr "Безопасность"
-
-#: ../../Zotlabs/Module/Admin/Security.php:95
-msgid "Block public"
-msgstr "Блокировать публичный доступ"
-
-#: ../../Zotlabs/Module/Admin/Security.php:95
-msgid ""
-"Check to block public access to all otherwise public personal pages on this "
-"site unless you are currently authenticated."
-msgstr "Установите флажок для блокировки публичного доступа ко всем другим общедоступным страницам на этом сайте, если вы в настоящее время не аутентифицированы."
-
-#: ../../Zotlabs/Module/Admin/Security.php:96
-msgid "Provide a cloud root directory"
-msgstr "Предоставить корневой каталог в облаке"
-
-#: ../../Zotlabs/Module/Admin/Security.php:96
-msgid ""
-"The cloud root directory lists all channel names which provide public files"
-msgstr "В корневом каталоге облака показываются все имена каналов, которые предоставляют общедоступные файлы"
-
-#: ../../Zotlabs/Module/Admin/Security.php:97
-msgid "Show total disk space available to cloud uploads"
-msgstr "Показывать общее доступное для загрузок место в хранилище"
-
-#: ../../Zotlabs/Module/Admin/Security.php:98
-msgid "Set \"Transport Security\" HTTP header"
-msgstr "Установить HTTP-заголовок \"Transport Security\""
-
-#: ../../Zotlabs/Module/Admin/Security.php:99
-msgid "Set \"Content Security Policy\" HTTP header"
-msgstr "Установить HTTP-заголовок \"Content Security Policy\""
-
-#: ../../Zotlabs/Module/Admin/Security.php:100
-msgid "Allowed email domains"
-msgstr "Разрешённые домены email"
-
-#: ../../Zotlabs/Module/Admin/Security.php:100
-msgid ""
-"Comma separated list of domains which are allowed in email addresses for "
-"registrations to this site. Wildcards are accepted. Empty to allow any "
-"domains"
-msgstr "Список разделённых запятыми доменов для которых разрешена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены."
-
-#: ../../Zotlabs/Module/Admin/Security.php:101
-msgid "Not allowed email domains"
-msgstr "Запрещённые домены email"
-
-#: ../../Zotlabs/Module/Admin/Security.php:101
-msgid ""
-"Comma separated list of domains which are not allowed in email addresses for "
-"registrations to this site. Wildcards are accepted. Empty to allow any "
-"domains, unless allowed domains have been defined."
-msgstr "Список разделённых запятыми доменов для которых запрещена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены до тех пор, пока разрешённые домены не будут указаны."
-
-#: ../../Zotlabs/Module/Admin/Security.php:102
-msgid "Allow communications only from these sites"
-msgstr "Разрешить связь только с этими сайтами"
-
-#: ../../Zotlabs/Module/Admin/Security.php:102
-msgid ""
-"One site per line. Leave empty to allow communication from anywhere by "
-"default"
-msgstr "Один сайт на строку. Оставьте пустым для разрешения взаимодействия без ограничений (по умочанию)."
-
-#: ../../Zotlabs/Module/Admin/Security.php:103
-msgid "Block communications from these sites"
-msgstr "Блокировать связь с этими сайтами"
-
-#: ../../Zotlabs/Module/Admin/Security.php:104
-msgid "Allow communications only from these channels"
-msgstr "Разрешить связь только для этих каналов"
-
-#: ../../Zotlabs/Module/Admin/Security.php:104
-msgid ""
-"One channel (hash) per line. Leave empty to allow from any channel by default"
-msgstr "Один канал (или его хэш) на строку. Оставьте пустым для разрешения взаимодействия с любым каналом (по умолчанию)."
-
-#: ../../Zotlabs/Module/Admin/Security.php:105
-msgid "Block communications from these channels"
-msgstr "Блокировать связь с этими каналами"
-
-#: ../../Zotlabs/Module/Admin/Security.php:106
-msgid "Only allow embeds from secure (SSL) websites and links."
-msgstr "Разрешать встраивание только для безопасных (SSL/TLS) сайтов и ссылок."
-
-#: ../../Zotlabs/Module/Admin/Security.php:107
-msgid "Allow unfiltered embedded HTML content only from these domains"
-msgstr "Разрешить встраивать нефильтруемое HTML-содержимое только для этих доменов"
-
-#: ../../Zotlabs/Module/Admin/Security.php:107
-msgid "One site per line. By default embedded content is filtered."
-msgstr "Один сайт на строку. По умолчанию встраиваемое содержимое фильтруется."
-
-#: ../../Zotlabs/Module/Admin/Security.php:108
-msgid "Block embedded HTML from these domains"
-msgstr "Блокировать встраивание HTML-содержимого для этих доменов"
-
-#: ../../Zotlabs/Module/Lockview.php:75
-msgid "Remote privacy information not available."
-msgstr "Удаленная информация о конфиденциальности недоступна."
-
-#: ../../Zotlabs/Module/Lockview.php:96
-msgid "Visible to:"
-msgstr "Видимо для:"
-
-#: ../../Zotlabs/Module/Lockview.php:117 ../../Zotlabs/Module/Lockview.php:153
-#: ../../Zotlabs/Module/Acl.php:121 ../../include/acl_selectors.php:88
-msgctxt "acl"
-msgid "Profile"
-msgstr "Профиль"
-
-#: ../../Zotlabs/Module/Moderate.php:65
-msgid "Comment approved"
-msgstr "Комментарий одобрен"
-
-#: ../../Zotlabs/Module/Moderate.php:69
-msgid "Comment deleted"
-msgstr "Комментарий удалён"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:70
-#: ../../Zotlabs/Module/Settings/Channel.php:74
-#: ../../Zotlabs/Module/Settings/Channel.php:75
-#: ../../Zotlabs/Module/Settings/Channel.php:78
-#: ../../Zotlabs/Module/Settings/Channel.php:89
-#: ../../Zotlabs/Module/Connedit.php:725 ../../Zotlabs/Widget/Affinity.php:32
-#: ../../include/selectors.php:134 ../../include/channel.php:493
-#: ../../include/channel.php:494 ../../include/channel.php:501
-msgid "Friends"
-msgstr "Друзья"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:266
-#: ../../Zotlabs/Module/Defperms.php:111
-#: ../../addon/rendezvous/rendezvous.php:82
-#: ../../addon/openstreetmap/openstreetmap.php:185
-#: ../../addon/msgfooter/msgfooter.php:54 ../../addon/logrot/logrot.php:54
-#: ../../addon/twitter/twitter.php:605 ../../addon/piwik/piwik.php:116
-#: ../../addon/xmpp/xmpp.php:54
-msgid "Settings updated."
-msgstr "Настройки обновлены."
-
-#: ../../Zotlabs/Module/Settings/Channel.php:327
-msgid "Nobody except yourself"
-msgstr "Никто кроме вас"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:328
-msgid "Only those you specifically allow"
-msgstr "Только персонально разрешённые"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:329
-msgid "Approved connections"
-msgstr "Одобренные контакты"
+#: ../../Zotlabs/Module/Admin/Queue.php:35
+msgid "Queue Statistics"
+msgstr "Статистика очереди"
-#: ../../Zotlabs/Module/Settings/Channel.php:330
-msgid "Any connections"
-msgstr "Любые контакты"
+#: ../../Zotlabs/Module/Admin/Queue.php:36
+msgid "Total Entries"
+msgstr "Всего записей"
-#: ../../Zotlabs/Module/Settings/Channel.php:331
-msgid "Anybody on this website"
-msgstr "Любой на этом сайте"
+#: ../../Zotlabs/Module/Admin/Queue.php:37
+msgid "Priority"
+msgstr "Приоритет"
-#: ../../Zotlabs/Module/Settings/Channel.php:332
-msgid "Anybody in this network"
-msgstr "Любой в этой сети"
+#: ../../Zotlabs/Module/Admin/Queue.php:38
+msgid "Destination URL"
+msgstr "Конечный URL-адрес"
-#: ../../Zotlabs/Module/Settings/Channel.php:333
-msgid "Anybody authenticated"
-msgstr "Любой аутентифицированный"
+#: ../../Zotlabs/Module/Admin/Queue.php:39
+msgid "Mark hub permanently offline"
+msgstr "Пометить хаб как постоянно отключенный"
-#: ../../Zotlabs/Module/Settings/Channel.php:334
-msgid "Anybody on the internet"
-msgstr "Любой в интернете"
+#: ../../Zotlabs/Module/Admin/Queue.php:40
+msgid "Empty queue for this hub"
+msgstr "Освободить очередь для этого хаба"
-#: ../../Zotlabs/Module/Settings/Channel.php:409
-msgid "Publish your default profile in the network directory"
-msgstr "Публиковать ваш профиль по умолчанию в сетевом каталоге"
+#: ../../Zotlabs/Module/Admin/Queue.php:41
+msgid "Last known contact"
+msgstr "Последний известный контакт"
-#: ../../Zotlabs/Module/Settings/Channel.php:414
-msgid "Allow us to suggest you as a potential friend to new members?"
-msgstr "Разрешить предлагать вас как потенциального друга для новых пользователей?"
+#: ../../Zotlabs/Module/Admin/Themes.php:26
+msgid "Theme settings updated."
+msgstr "Настройки темы обновленны."
-#: ../../Zotlabs/Module/Settings/Channel.php:418
-msgid "or"
-msgstr "или"
+#: ../../Zotlabs/Module/Admin/Themes.php:61
+msgid "No themes found."
+msgstr "Темы не найдены."
-#: ../../Zotlabs/Module/Settings/Channel.php:427
-msgid "Your channel address is"
-msgstr "Адрес вашего канала"
+#: ../../Zotlabs/Module/Admin/Themes.php:116
+msgid "Screenshot"
+msgstr "Снимок экрана"
-#: ../../Zotlabs/Module/Settings/Channel.php:430
-msgid "Your files/photos are accessible via WebDAV at"
-msgstr "Ваши файлы / фотографии доступны через WebDAV по"
+#: ../../Zotlabs/Module/Admin/Themes.php:123
+#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../Zotlabs/Widget/Admin.php:28
+msgid "Themes"
+msgstr "Темы"
-#: ../../Zotlabs/Module/Settings/Channel.php:470
-msgid "Automatic membership approval"
-msgstr "Членство одобрено автоматически"
+#: ../../Zotlabs/Module/Admin/Themes.php:162
+msgid "[Experimental]"
+msgstr "[экспериментальный]"
-#: ../../Zotlabs/Module/Settings/Channel.php:470
-#: ../../Zotlabs/Module/Defperms.php:255
-msgid ""
-"If enabled, connection requests will be approved without your interaction"
-msgstr "Если включено, запросы контактов будут одобрены без вашего участия"
+#: ../../Zotlabs/Module/Admin/Themes.php:163
+msgid "[Unsupported]"
+msgstr "[неподдерживаемый]"
-#: ../../Zotlabs/Module/Settings/Channel.php:491
-msgid "Channel Settings"
-msgstr "Настройки канала"
+#: ../../Zotlabs/Module/Admin/Accounts.php:37
+#, php-format
+msgid "%s account blocked/unblocked"
+msgid_plural "%s account blocked/unblocked"
+msgstr[0] "%s аккаунт блокирован/разблокирован"
+msgstr[1] "%s аккаунта блокированы/разблокированы"
+msgstr[2] "%s аккаунтов блокированы/разблокированы"
-#: ../../Zotlabs/Module/Settings/Channel.php:498
-msgid "Basic Settings"
-msgstr "Основные настройки"
+#: ../../Zotlabs/Module/Admin/Accounts.php:44
+#, php-format
+msgid "%s account deleted"
+msgid_plural "%s accounts deleted"
+msgstr[0] "%s аккаунт удалён"
+msgstr[1] "%s аккаунта удалёны"
+msgstr[2] "%s аккаунтов удалёны"
-#: ../../Zotlabs/Module/Settings/Channel.php:499 ../../include/channel.php:1577
-msgid "Full Name:"
-msgstr "Полное имя:"
+#: ../../Zotlabs/Module/Admin/Accounts.php:80
+msgid "Account not found"
+msgstr "Аккаунт не найден"
-#: ../../Zotlabs/Module/Settings/Channel.php:500
-#: ../../Zotlabs/Module/Settings/Account.php:104
-msgid "Email Address:"
-msgstr "Адрес email:"
+#: ../../Zotlabs/Module/Admin/Accounts.php:99
+#, php-format
+msgid "Account '%s' blocked"
+msgstr "Аккаунт '%s' заблокирован"
-#: ../../Zotlabs/Module/Settings/Channel.php:501
-msgid "Your Timezone:"
-msgstr "Часовой пояс:"
+#: ../../Zotlabs/Module/Admin/Accounts.php:107
+#, php-format
+msgid "Account '%s' unblocked"
+msgstr "Аккаунт '%s' разблокирован"
-#: ../../Zotlabs/Module/Settings/Channel.php:502
-msgid "Default Post Location:"
-msgstr "Расположение по умолчанию:"
+#: ../../Zotlabs/Module/Admin/Accounts.php:170
+msgid "Registrations waiting for confirm"
+msgstr "Регистрации ждут подтверждения"
-#: ../../Zotlabs/Module/Settings/Channel.php:502
-msgid "Geographical location to display on your posts"
-msgstr "Показывать географическое положение в ваших публикациях"
+#: ../../Zotlabs/Module/Admin/Accounts.php:171
+msgid "Request date"
+msgstr "Дата запроса"
-#: ../../Zotlabs/Module/Settings/Channel.php:503
-msgid "Use Browser Location:"
-msgstr "Определять расположение из браузера"
+#: ../../Zotlabs/Module/Admin/Accounts.php:172
+msgid "No registrations."
+msgstr "Нет новых регистраций."
-#: ../../Zotlabs/Module/Settings/Channel.php:505
-msgid "Adult Content"
-msgstr "Содержимое для взрослых"
+#: ../../Zotlabs/Module/Admin/Accounts.php:176
+#: ../../Zotlabs/Module/Connedit.php:636
+msgid "Block"
+msgstr "Блокировать"
-#: ../../Zotlabs/Module/Settings/Channel.php:505
-msgid ""
-"This channel frequently or regularly publishes adult content. (Please tag "
-"any adult material and/or nudity with #NSFW)"
-msgstr "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW"
+#: ../../Zotlabs/Module/Admin/Accounts.php:177
+#: ../../Zotlabs/Module/Connedit.php:636
+msgid "Unblock"
+msgstr "Разблокировать"
-#: ../../Zotlabs/Module/Settings/Channel.php:507
-msgid "Security and Privacy Settings"
-msgstr "Безопасность и настройки приватности"
+#: ../../Zotlabs/Module/Admin/Accounts.php:182
+msgid "ID"
+msgstr ""
-#: ../../Zotlabs/Module/Settings/Channel.php:509
-msgid "Your permissions are already configured. Click to view/adjust"
-msgstr "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить"
+#: ../../Zotlabs/Module/Admin/Accounts.php:184
+msgid "All Channels"
+msgstr "Все каналы"
-#: ../../Zotlabs/Module/Settings/Channel.php:511
-msgid "Hide my online presence"
-msgstr "Скрывать моё присутствие онлайн"
+#: ../../Zotlabs/Module/Admin/Accounts.php:185
+msgid "Register date"
+msgstr "Дата регистрации"
-#: ../../Zotlabs/Module/Settings/Channel.php:511
-msgid "Prevents displaying in your profile that you are online"
-msgstr "Предотвращает отображения статуса \"в сети\" в вашем профиле"
+#: ../../Zotlabs/Module/Admin/Accounts.php:186
+msgid "Last login"
+msgstr "Последний вход"
-#: ../../Zotlabs/Module/Settings/Channel.php:513
-msgid "Simple Privacy Settings:"
-msgstr "Простые настройки безопасности:"
+#: ../../Zotlabs/Module/Admin/Accounts.php:187
+msgid "Expires"
+msgstr "Срок действия"
-#: ../../Zotlabs/Module/Settings/Channel.php:514
-msgid ""
-"Very Public - <em>extremely permissive (should be used with caution)</em>"
-msgstr "Полностью открытый - <em>сверхлиберальный (должен использоваться с осторожностью)</em>"
+#: ../../Zotlabs/Module/Admin/Accounts.php:188
+msgid "Service Class"
+msgstr "Класс обслуживания"
-#: ../../Zotlabs/Module/Settings/Channel.php:515
+#: ../../Zotlabs/Module/Admin/Accounts.php:190
msgid ""
-"Typical - <em>default public, privacy when desired (similar to social "
-"network permissions but with improved privacy)</em>"
-msgstr "Обычный - <em>открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)</em>"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:516
-msgid "Private - <em>default private, never open or public</em>"
-msgstr "Частный - <em>частный по умочанию, не открытый и не публичный</em>"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:517
-msgid "Blocked - <em>default blocked to/from everybody</em>"
-msgstr "Закрытый - <em>заблокированный по умолчанию от / для всех</em>"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:519
-msgid "Allow others to tag your posts"
-msgstr "Разрешить другим отмечать ваши публикации"
+"Selected accounts will be deleted!\\n\\nEverything these accounts had posted "
+"on this site will be permanently deleted!\\n\\nAre you sure?"
+msgstr "Выбранные учётные записи будут удалены!\n\nВсё что было ими опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?"
-#: ../../Zotlabs/Module/Settings/Channel.php:519
+#: ../../Zotlabs/Module/Admin/Accounts.php:191
msgid ""
-"Often used by the community to retro-actively flag inappropriate content"
-msgstr "Часто используется сообществом для маркировки неподобающего содержания"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:521
-msgid "Channel Permission Limits"
-msgstr "Ограничения разрешений канала"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:523
-msgid "Expire other channel content after this many days"
-msgstr "Храненить содержимое других каналов, дней"
+"The account {0} will be deleted!\\n\\nEverything this account has posted on "
+"this site will be permanently deleted!\\n\\nAre you sure?"
+msgstr "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?"
-#: ../../Zotlabs/Module/Settings/Channel.php:523
-msgid "0 or blank to use the website limit."
-msgstr "0 или пусто - использовать настройки сайта."
+#: ../../Zotlabs/Module/Admin/Dbsync.php:19
+msgid "Update has been marked successful"
+msgstr "Обновление было помечено как успешное"
-#: ../../Zotlabs/Module/Settings/Channel.php:523
+#: ../../Zotlabs/Module/Admin/Dbsync.php:31
#, php-format
-msgid "This website expires after %d days."
-msgstr "Срок хранения содержимого этого сайта истекает через %d дней"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:523
-msgid "This website does not expire imported content."
-msgstr "Срок хранения импортированного содержимого этого сайта не ограничен."
-
-#: ../../Zotlabs/Module/Settings/Channel.php:523
-msgid "The website limit takes precedence if lower than your limit."
-msgstr "Ограничение сайта имеет приоритет если ниже вашего значения."
-
-#: ../../Zotlabs/Module/Settings/Channel.php:524
-msgid "Maximum Friend Requests/Day:"
-msgstr "Запросов в друзья в день:"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:524
-msgid "May reduce spam activity"
-msgstr "Может ограничить спам активность"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:525
-msgid "Default Privacy Group"
-msgstr "Группа конфиденциальности по умолчанию"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:527
-msgid "Use my default audience setting for the type of object published"
-msgstr "Использовать настройки аудитории по умолчанию для типа опубликованного объекта"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:536
-msgid "Default permissions category"
-msgstr "Категория разрешений по умолчанию"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:542
-msgid "Maximum private messages per day from unknown people:"
-msgstr "Максимально количество сообщений от незнакомых людей, в день:"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:542
-msgid "Useful to reduce spamming"
-msgstr "Полезно для сокращения количества спама"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:545
-#: ../../Zotlabs/Lib/Enotify.php:68
-msgid "Notification Settings"
-msgstr "Настройки уведомлений"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:546
-msgid "By default post a status message when:"
-msgstr "По умолчанию публиковать новый статус при:"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:547
-msgid "accepting a friend request"
-msgstr "одобрении запроса в друзья"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:548
-msgid "joining a forum/community"
-msgstr "вступлении в сообщество / форум"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:549
-msgid "making an <em>interesting</em> profile change"
-msgstr "<em>интересном</em> изменении профиля"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:550
-msgid "Send a notification email when:"
-msgstr "Отправить уведомление по email когда:"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:551
-msgid "You receive a connection request"
-msgstr "вы получили новый запрос контакта"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:552
-msgid "Your connections are confirmed"
-msgstr "Ваш запрос контакта был одобрен"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:553
-msgid "Someone writes on your profile wall"
-msgstr "Кто-то написал на стене вашего профиля"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:554
-msgid "Someone writes a followup comment"
-msgstr "Кто-то пишет комментарий"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:555
-msgid "You receive a private message"
-msgstr "Вы получили личное сообщение"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:556
-msgid "You receive a friend suggestion"
-msgstr "Вы получили предложение друзей"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:557
-msgid "You are tagged in a post"
-msgstr "Вы были отмечены в публикации"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:558
-msgid "You are poked/prodded/etc. in a post"
-msgstr "Вас толкнули, подтолкнули и т.п. в публикации"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:560
-msgid "Someone likes your post/comment"
-msgstr "Кому-то нравится ваша публикация / комментарий"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:563
-msgid "Show visual notifications including:"
-msgstr "Показывать визуальные оповещения включая:"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:565
-msgid "Unseen stream activity"
-msgstr "Невидимая активность в потоке"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:566
-msgid "Unseen channel activity"
-msgstr "Невидимая активность в канале"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:567
-msgid "Unseen private messages"
-msgstr "Невидимые личные сообщения"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:567
-#: ../../Zotlabs/Module/Settings/Channel.php:572
-#: ../../Zotlabs/Module/Settings/Channel.php:573
-#: ../../Zotlabs/Module/Settings/Channel.php:574
-#: ../../addon/jappixmini/Mod_Jappixmini.php:191
-msgid "Recommended"
-msgstr "Рекомендовано"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:568
-msgid "Upcoming events"
-msgstr "Грядущие события"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:569
-msgid "Events today"
-msgstr "События сегодня"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:570
-msgid "Upcoming birthdays"
-msgstr "Грядущие дни рождения"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:570
-msgid "Not available in all themes"
-msgstr "Не доступно во всех темах"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:571
-msgid "System (personal) notifications"
-msgstr "Системные (личные) уведомления"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:572
-msgid "System info messages"
-msgstr "Сообщения с системной информацией"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:573
-msgid "System critical alerts"
-msgstr "Критические уведомления системы"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:574
-msgid "New connections"
-msgstr "Новые контакты"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:575
-msgid "System Registrations"
-msgstr "Системные регистрации"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:576
-msgid "Unseen shared files"
-msgstr "Невидимые общие файлы"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:577
-msgid "Unseen public stream activity"
-msgstr "Невидимая активность в публичном потоке"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:578
-msgid "Unseen likes and dislikes"
-msgstr "Невидимые лайки и дислайки"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:579
-msgid "Unseen forum posts"
-msgstr "Невидимые публикации на форуме"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:580
-msgid "Email notification hub (hostname)"
-msgstr "Центр уведомлений по email (имя хоста)"
+msgid "Executing %s failed. Check system logs."
+msgstr "Выполнение %s неудачно. Проверьте системный журнал."
-#: ../../Zotlabs/Module/Settings/Channel.php:580
+#: ../../Zotlabs/Module/Admin/Dbsync.php:34
#, php-format
-msgid ""
-"If your channel is mirrored to multiple hubs, set this to your preferred "
-"location. This will prevent duplicate email notifications. Example: %s"
-msgstr "Если ваш канал зеркалируется в нескольких местах, это ваше предпочтительное местоположение. Это должно предотвратить дублировать уведомлений по email. Например: %s"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:581
-msgid "Show new wall posts, private messages and connections under Notices"
-msgstr "Показать новые сообщения на стене, личные сообщения и контакты в \"Уведомлениях\""
-
-#: ../../Zotlabs/Module/Settings/Channel.php:583
-msgid "Notify me of events this many days in advance"
-msgstr "Уведомлять меня о событиях заранее, дней"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:583
-msgid "Must be greater than 0"
-msgstr "Должно быть больше 0"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:588
-msgid "Advanced Account/Page Type Settings"
-msgstr "Дополнительные настройки учётной записи / страницы"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:589
-msgid "Change the behaviour of this account for special situations"
-msgstr "Изменить поведение этого аккаунта в особых ситуациях"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:591
-msgid "Miscellaneous Settings"
-msgstr "Дополнительные настройки"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:592
-msgid "Default photo upload folder"
-msgstr "Каталог загрузки фотографий по умолчанию"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:592
-#: ../../Zotlabs/Module/Settings/Channel.php:593
-msgid "%Y - current year, %m - current month"
-msgstr "%Y - текущий год, %y - текущий месяц"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:593
-msgid "Default file upload folder"
-msgstr "Каталог загрузки файлов по умолчанию"
-
-#: ../../Zotlabs/Module/Settings/Channel.php:595
-msgid "Remove this channel."
-msgstr "Удалить этот канал."
-
-#: ../../Zotlabs/Module/Settings/Features.php:43
-msgid "Additional Features"
-msgstr "Дополнительные функции"
-
-#: ../../Zotlabs/Module/Settings/Events.php:39
-msgid "Events Settings"
-msgstr "Настройки событий"
-
-#: ../../Zotlabs/Module/Settings/Calendar.php:39
-msgid "CalDAV Settings"
-msgstr "Настройки CalDAV"
-
-#: ../../Zotlabs/Module/Settings/Conversation.php:22
-msgid "Settings saved."
-msgstr "Настройки сохранены."
-
-#: ../../Zotlabs/Module/Settings/Conversation.php:24
-msgid "Settings saved. Reload page please."
-msgstr "Настройки сохранены. Пожалуйста, перезагрузите страницу."
-
-#: ../../Zotlabs/Module/Settings/Conversation.php:46
-msgid "Conversation Settings"
-msgstr "Настройки бесед"
-
-#: ../../Zotlabs/Module/Settings/Connections.php:39
-msgid "Connections Settings"
-msgstr "Настройки контактов"
-
-#: ../../Zotlabs/Module/Settings/Photos.php:39
-msgid "Photos Settings"
-msgstr "Настройки фотографий"
-
-#: ../../Zotlabs/Module/Settings/Account.php:19
-msgid "Not valid email."
-msgstr "Не действительный адрес email."
-
-#: ../../Zotlabs/Module/Settings/Account.php:22
-msgid "Protected email address. Cannot change to that email."
-msgstr "Защищенный адрес электронной почты. Нельзя изменить."
-
-#: ../../Zotlabs/Module/Settings/Account.php:31
-msgid "System failure storing new email. Please try again."
-msgstr "Системная ошибка сохранения email. Пожалуйста попробуйте ещё раз."
-
-#: ../../Zotlabs/Module/Settings/Account.php:48
-msgid "Password verification failed."
-msgstr "Не удалось выполнить проверку пароля."
-
-#: ../../Zotlabs/Module/Settings/Account.php:55
-msgid "Passwords do not match. Password unchanged."
-msgstr "Пароли не совпадают. Пароль не изменён."
-
-#: ../../Zotlabs/Module/Settings/Account.php:59
-msgid "Empty passwords are not allowed. Password unchanged."
-msgstr "Пустые пароли не допускаются. Пароль не изменён."
-
-#: ../../Zotlabs/Module/Settings/Account.php:73
-msgid "Password changed."
-msgstr "Пароль изменен."
-
-#: ../../Zotlabs/Module/Settings/Account.php:75
-msgid "Password update failed. Please try again."
-msgstr "Изменение пароля не удалось. Пожалуйста, попробуйте ещё раз."
-
-#: ../../Zotlabs/Module/Settings/Account.php:99
-msgid "Account Settings"
-msgstr "Настройки аккаунта"
-
-#: ../../Zotlabs/Module/Settings/Account.php:100
-msgid "Current Password"
-msgstr "Текущий пароль"
-
-#: ../../Zotlabs/Module/Settings/Account.php:101
-msgid "Enter New Password"
-msgstr "Введите новый пароль:"
-
-#: ../../Zotlabs/Module/Settings/Account.php:102
-msgid "Confirm New Password"
-msgstr "Подтвердите новый пароль:"
-
-#: ../../Zotlabs/Module/Settings/Account.php:102
-msgid "Leave password fields blank unless changing"
-msgstr "Оставьте поля пустыми до измнения"
-
-#: ../../Zotlabs/Module/Settings/Account.php:105
-#: ../../Zotlabs/Module/Removeaccount.php:61
-msgid "Remove Account"
-msgstr "Удалить аккаунт"
-
-#: ../../Zotlabs/Module/Settings/Account.php:106
-msgid "Remove this account including all its channels"
-msgstr "Удалить этот аккаунт включая все каналы"
-
-#: ../../Zotlabs/Module/Settings/Profiles.php:47
-msgid "Profiles Settings"
-msgstr "Настройки профилей"
-
-#: ../../Zotlabs/Module/Settings/Manage.php:39
-msgid "Channel Manager Settings"
-msgstr "Настройки менеджера канала"
-
-#: ../../Zotlabs/Module/Settings/Featured.php:24
-msgid "No feature settings configured"
-msgstr "Параметры функций не настроены"
-
-#: ../../Zotlabs/Module/Settings/Featured.php:33
-msgid "Addon Settings"
-msgstr "Настройки расширений"
-
-#: ../../Zotlabs/Module/Settings/Featured.php:34
-msgid "Please save/submit changes to any panel before opening another."
-msgstr "Пожалуйста сохраните / отправьте изменения на панели прежде чем открывать другую."
-
-#: ../../Zotlabs/Module/Settings/Channel_home.php:44
-#: ../../Zotlabs/Module/Settings/Network.php:41
-msgid "Max height of content (in pixels)"
-msgstr "Максимальная высота содержимого (в пикселях)"
-
-#: ../../Zotlabs/Module/Settings/Channel_home.php:46
-#: ../../Zotlabs/Module/Settings/Network.php:43
-msgid "Click to expand content exceeding this height"
-msgstr "Нажмите чтобы развернуть содержимое превышающее эту высоту"
-
-#: ../../Zotlabs/Module/Settings/Channel_home.php:59
-msgid "Personal menu to display in your channel pages"
-msgstr "Персональное меню для отображения на странице вашего канала"
-
-#: ../../Zotlabs/Module/Settings/Channel_home.php:86
-msgid "Channel Home Settings"
-msgstr "Настройки главной страницы канала"
-
-#: ../../Zotlabs/Module/Settings/Directory.php:39
-msgid "Directory Settings"
-msgstr "Настройки каталога"
-
-#: ../../Zotlabs/Module/Settings/Editor.php:39
-msgid "Editor Settings"
-msgstr "Настройки редактора"
+msgid "Update %s was successfully applied."
+msgstr "Обновление %sбыло успешно применено."
-#: ../../Zotlabs/Module/Settings/Display.php:128
+#: ../../Zotlabs/Module/Admin/Dbsync.php:38
#, php-format
-msgid "%s - (Experimental)"
-msgstr "%s - (экспериментальный)"
-
-#: ../../Zotlabs/Module/Settings/Display.php:184
-msgid "Display Settings"
-msgstr "Настройки отображения"
-
-#: ../../Zotlabs/Module/Settings/Display.php:185
-msgid "Theme Settings"
-msgstr "Настройки темы"
-
-#: ../../Zotlabs/Module/Settings/Display.php:186
-msgid "Custom Theme Settings"
-msgstr "Дополнительные настройки темы"
-
-#: ../../Zotlabs/Module/Settings/Display.php:187
-msgid "Content Settings"
-msgstr "Настройки содержимого"
-
-#: ../../Zotlabs/Module/Settings/Display.php:193
-msgid "Display Theme:"
-msgstr "Тема отображения:"
-
-#: ../../Zotlabs/Module/Settings/Display.php:194
-msgid "Select scheme"
-msgstr "Выбрать схему"
-
-#: ../../Zotlabs/Module/Settings/Display.php:196
-msgid "Preload images before rendering the page"
-msgstr "Предзагрузка изображений перед обработкой страницы"
-
-#: ../../Zotlabs/Module/Settings/Display.php:196
-msgid ""
-"The subjective page load time will be longer but the page will be ready when "
-"displayed"
-msgstr "Субъективное время загрузки страницы будет длиннее, но страница будет готова при отображении"
-
-#: ../../Zotlabs/Module/Settings/Display.php:197
-msgid "Enable user zoom on mobile devices"
-msgstr "Включить масштабирование на мобильных устройствах"
-
-#: ../../Zotlabs/Module/Settings/Display.php:198
-msgid "Update browser every xx seconds"
-msgstr "Обновление браузера каждые N секунд"
-
-#: ../../Zotlabs/Module/Settings/Display.php:198
-msgid "Minimum of 10 seconds, no maximum"
-msgstr "Минимум 10 секунд, без максимума"
-
-#: ../../Zotlabs/Module/Settings/Display.php:199
-msgid "Maximum number of conversations to load at any time:"
-msgstr "Максимальное количество бесед для загрузки одновременно:"
+msgid "Update %s did not return a status. Unknown if it succeeded."
+msgstr "Обновление %s не вернуло статус. Неизвестно было ли оно успешным."
-#: ../../Zotlabs/Module/Settings/Display.php:199
-msgid "Maximum of 100 items"
-msgstr "Максимум 100 элементов"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:41
+#, php-format
+msgid "Update function %s could not be found."
+msgstr "Функция обновления %sне может быть найдена."
-#: ../../Zotlabs/Module/Settings/Display.php:200
-msgid "Show emoticons (smilies) as images"
-msgstr "Показывать эмотиконы (смайлики) как изображения"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:59
+msgid "Failed Updates"
+msgstr "Обновления с ошибками"
-#: ../../Zotlabs/Module/Settings/Display.php:201
-msgid "Provide channel menu in navigation bar"
-msgstr "Показывать меню канала в панели навигации"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:61
+msgid "Mark success (if update was manually applied)"
+msgstr "Пометить успешным (если обновление было применено вручную)"
-#: ../../Zotlabs/Module/Settings/Display.php:201
-msgid "Default: channel menu located in app menu"
-msgstr "По умолчанию каналы расположены в меню приложения"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:62
+msgid "Attempt to execute this update step automatically"
+msgstr "Попытаться применить это обновление автоматически"
-#: ../../Zotlabs/Module/Settings/Display.php:202
-msgid "Manual conversation updates"
-msgstr "Обновление бесед вручную"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:67
+msgid "No failed updates."
+msgstr "Ошибок обновлений нет."
-#: ../../Zotlabs/Module/Settings/Display.php:202
-msgid "Default is on, turning this off may increase screen jumping"
-msgstr "Включено по умолчанию, выключение может привести к рывкам в отображении"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:29
+#, php-format
+msgid "Password changed for account %d."
+msgstr "Пароль для аккаунта %d изменён."
-#: ../../Zotlabs/Module/Settings/Display.php:203
-msgid "Link post titles to source"
-msgstr "Ссылки на источник заголовков публикаций"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:46
+msgid "Account settings updated."
+msgstr "Настройки аккаунта обновлены."
-#: ../../Zotlabs/Module/Settings/Display.php:205
-#: ../../Zotlabs/Widget/Newmember.php:75
-msgid "New Member Links"
-msgstr "Ссылки для новичков"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:61
+msgid "Account not found."
+msgstr "Учётная запись не найдена."
-#: ../../Zotlabs/Module/Settings/Display.php:205
-msgid "Display new member quick links menu"
-msgstr "Показать меню быстрых ссылок для новых участников"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:68
+msgid "Account Edit"
+msgstr "Редактировать аккаунт"
-#: ../../Zotlabs/Module/Settings/Network.php:58
-msgid "Stream Settings"
-msgstr "Настройки потока"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:69
+msgid "New Password"
+msgstr "Новый пароль"
-#: ../../Zotlabs/Module/Embedphotos.php:148 ../../Zotlabs/Module/Photos.php:826
-#: ../../Zotlabs/Module/Photos.php:1374 ../../Zotlabs/Widget/Portfolio.php:87
-#: ../../Zotlabs/Widget/Album.php:78
-msgid "View Photo"
-msgstr "Посмотреть фотографию"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:70
+msgid "New Password again"
+msgstr "Повторите новый пароль"
-#: ../../Zotlabs/Module/Embedphotos.php:164 ../../Zotlabs/Module/Photos.php:857
-#: ../../Zotlabs/Widget/Portfolio.php:108 ../../Zotlabs/Widget/Album.php:95
-msgid "Edit Album"
-msgstr "Редактировать Фотоальбом"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:71
+msgid "Account language (for emails)"
+msgstr "Язык сообщения для email"
-#: ../../Zotlabs/Module/Embedphotos.php:166 ../../Zotlabs/Module/Photos.php:727
-#: ../../Zotlabs/Module/Profile_photo.php:459
-#: ../../Zotlabs/Module/Cover_photo.php:395
-#: ../../Zotlabs/Storage/Browser.php:392 ../../Zotlabs/Widget/Cdav.php:133
-#: ../../Zotlabs/Widget/Cdav.php:169 ../../Zotlabs/Widget/Portfolio.php:110
-#: ../../Zotlabs/Widget/Album.php:97
-msgid "Upload"
-msgstr "Загрузка"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:72
+msgid "Service class"
+msgstr "Класс обслуживания"
#: ../../Zotlabs/Module/Tokens.php:39
#, php-format
@@ -4303,9 +9434,32 @@ msgstr "Срок действия (yyyy-mm-dd)"
msgid "Their Settings"
msgstr "Их настройки"
-#: ../../Zotlabs/Module/Achievements.php:38
-msgid "Some blurb about what to do when you're new here"
-msgstr "Некоторые предложения о том, что делать, если вы здесь новичок "
+#: ../../Zotlabs/Module/Notifications.php:60
+#: ../../Zotlabs/Lib/ThreadItem.php:450
+msgid "Mark all seen"
+msgstr "Отметить как просмотренное"
+
+#: ../../Zotlabs/Module/Subthread.php:143
+#, php-format
+msgid "%1$s is following %2$s's %3$s"
+msgstr "%1$s отслеживает %2$s's %3$s"
+
+#: ../../Zotlabs/Module/Subthread.php:145
+#, php-format
+msgid "%1$s stopped following %2$s's %3$s"
+msgstr "%1$s прекратил отслеживать %2$s's %3$s"
+
+#: ../../Zotlabs/Module/Rpost.php:144 ../../Zotlabs/Module/Editpost.php:108
+msgid "Edit post"
+msgstr "Редактировать сообщение"
+
+#: ../../Zotlabs/Module/Editwebpage.php:139
+msgid "Page link"
+msgstr "Ссылка страницы"
+
+#: ../../Zotlabs/Module/Editwebpage.php:166
+msgid "Edit Webpage"
+msgstr "Редактировать веб-страницу"
#: ../../Zotlabs/Module/Thing.php:120
msgid "Thing updated"
@@ -4360,1287 +9514,165 @@ msgstr "URL (необязательно)"
msgid "URL for photo of thing (optional)"
msgstr "URL для фотографии (необязательно)"
-#: ../../Zotlabs/Module/Thing.php:319 ../../Zotlabs/Module/Thing.php:372
-#: ../../Zotlabs/Module/Photos.php:717 ../../Zotlabs/Module/Photos.php:1086
-#: ../../Zotlabs/Module/Connedit.php:690 ../../Zotlabs/Module/Chat.php:243
-#: ../../Zotlabs/Module/Filestorage.php:170 ../../include/acl_selectors.php:123
-msgid "Permissions"
-msgstr "Разрешения"
-
#: ../../Zotlabs/Module/Thing.php:362
msgid "Add Thing to your Profile"
msgstr "Добавить к вашему профилю"
-#: ../../Zotlabs/Module/Notify.php:61 ../../Zotlabs/Module/Notifications.php:55
-msgid "No more system notifications."
-msgstr "Нет новых оповещений системы."
-
-#: ../../Zotlabs/Module/Notify.php:65 ../../Zotlabs/Module/Notifications.php:59
-msgid "System Notifications"
-msgstr "Системные оповещения "
-
-#: ../../Zotlabs/Module/Follow.php:36
-msgid "Connection added."
-msgstr "Контакт добавлен."
-
-#: ../../Zotlabs/Module/Import.php:155
-#, php-format
-msgid "Your service plan only allows %d channels."
-msgstr "Ваш класс обслуживания разрешает только %d каналов."
-
-#: ../../Zotlabs/Module/Import.php:182
-msgid "No channel. Import failed."
-msgstr "Канала нет. Импорт невозможен."
-
-#: ../../Zotlabs/Module/Import.php:522
-#: ../../addon/diaspora/import_diaspora.php:141
-msgid "Import completed."
-msgstr "Импорт завершен."
-
-#: ../../Zotlabs/Module/Import.php:550
-msgid "You must be logged in to use this feature."
-msgstr "Вы должны войти в систему, чтобы использовать эту функцию."
-
-#: ../../Zotlabs/Module/Import.php:555
-msgid "Import Channel"
-msgstr "Импортировать канал"
-
-#: ../../Zotlabs/Module/Import.php:556
-msgid ""
-"Use this form to import an existing channel from a different server/hub. You "
-"may retrieve the channel identity from the old server/hub via the network or "
-"provide an export file."
-msgstr "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта."
-
-#: ../../Zotlabs/Module/Import.php:558
-msgid "Or provide the old server/hub details"
-msgstr "или предоставьте данные старого сервера"
-
-#: ../../Zotlabs/Module/Import.php:560
-msgid "Your old identity address (xyz@example.com)"
-msgstr "Ваш старый адрес идентичности (xyz@example.com)"
-
-#: ../../Zotlabs/Module/Import.php:561
-msgid "Your old login email address"
-msgstr "Ваш старый адрес электронной почты"
-
-#: ../../Zotlabs/Module/Import.php:562
-msgid "Your old login password"
-msgstr "Ваш старый пароль"
-
-#: ../../Zotlabs/Module/Import.php:563
-msgid "Import a few months of posts if possible (limited by available memory"
-msgstr "Импортировать несколько месяцев публикаций если возможно (ограничено доступной памятью)"
-
-#: ../../Zotlabs/Module/Import.php:565
-msgid ""
-"For either option, please choose whether to make this hub your new primary "
-"address, or whether your old location should continue this role. You will be "
-"able to post from either location, but only one can be marked as the primary "
-"location for files, photos, and media."
-msgstr "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа."
-
-#: ../../Zotlabs/Module/Import.php:567
-msgid "Make this hub my primary location"
-msgstr "Сделать этот хаб главным"
-
-#: ../../Zotlabs/Module/Import.php:568
-msgid "Move this channel (disable all previous locations)"
-msgstr "Переместить это канал (отключить все предыдущие месторасположения)"
-
-#: ../../Zotlabs/Module/Import.php:569
-msgid "Use this channel nickname instead of the one provided"
-msgstr "Использовать псевдоним этого канала вместо предоставленного"
-
-#: ../../Zotlabs/Module/Import.php:569
-msgid ""
-"Leave blank to keep your existing channel nickname. You will be randomly "
-"assigned a similar nickname if either name is already allocated on this site."
-msgstr "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте."
-
-#: ../../Zotlabs/Module/Import.php:571
-msgid ""
-"This process may take several minutes to complete. Please submit the form "
-"only once and leave this page open until finished."
-msgstr "Процесс может занять несколько минут. Пожалуйста, отправьте форму только один раз и оставьте эту страницу открытой до завершения."
-
-#: ../../Zotlabs/Module/Rmagic.php:44
-msgid "Authentication failed."
-msgstr "Ошибка аутентификации."
-
-#: ../../Zotlabs/Module/Rmagic.php:93 ../../boot.php:1630
-#: ../../include/channel.php:2405
-msgid "Remote Authentication"
-msgstr "Удаленная аутентификация"
-
-#: ../../Zotlabs/Module/Rmagic.php:94 ../../include/channel.php:2406
-msgid "Enter your channel address (e.g. channel@example.com)"
-msgstr "Введите адрес вашего канала (например: channel@example.com)"
-
-#: ../../Zotlabs/Module/Rmagic.php:95 ../../include/channel.php:2407
-msgid "Authenticate"
-msgstr "Проверка подлинности"
-
-#: ../../Zotlabs/Module/Oauth2.php:54
-msgid "Name and Secret are required"
-msgstr "Требуются имя и код"
-
-#: ../../Zotlabs/Module/Oauth2.php:106
-msgid "OAuth2 Apps Manager App"
-msgstr "Приложение \"Менеджер Oauth2\""
-
-#: ../../Zotlabs/Module/Oauth2.php:107
-msgid "OAuth2 authenticatication tokens for mobile and remote apps"
-msgstr "Аутентификация OAuth2 для мобильных и удаленных приложений"
-
-#: ../../Zotlabs/Module/Oauth2.php:115
-msgid "Add OAuth2 application"
-msgstr "Добавить приложение OAuth2"
-
-#: ../../Zotlabs/Module/Oauth2.php:118 ../../Zotlabs/Module/Oauth2.php:146
-#: ../../Zotlabs/Module/Oauth.php:113
-msgid "Name of application"
-msgstr "Название приложения"
-
-#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147
-#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141
-#: ../../addon/statusnet/statusnet.php:595 ../../addon/twitter/twitter.php:615
-msgid "Consumer Secret"
-msgstr "Код клиента"
-
-#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147
-#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:115
-msgid "Automatically generated - change if desired. Max length 20"
-msgstr "Сгенерирован автоматические - измените если требуется. Макс. длина 20"
-
-#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148
-#: ../../Zotlabs/Module/Oauth.php:116 ../../Zotlabs/Module/Oauth.php:142
-msgid "Redirect"
-msgstr "Перенаправление"
-
-#: ../../Zotlabs/Module/Oauth2.php:120 ../../Zotlabs/Module/Oauth2.php:148
-#: ../../Zotlabs/Module/Oauth.php:116
-msgid ""
-"Redirect URI - leave blank unless your application specifically requires this"
-msgstr "URI перенаправления - оставьте пустыми до тех пока ваше приложение не требует этого"
-
-#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:149
-msgid "Grant Types"
-msgstr "Разрешить типы"
-
-#: ../../Zotlabs/Module/Oauth2.php:121 ../../Zotlabs/Module/Oauth2.php:122
-msgid "leave blank unless your application sepcifically requires this"
-msgstr "оставьте пустыми до тех пока ваше приложение не требует этого"
-
-#: ../../Zotlabs/Module/Oauth2.php:122 ../../Zotlabs/Module/Oauth2.php:150
-msgid "Authorization scope"
-msgstr "Область полномочий"
-
-#: ../../Zotlabs/Module/Oauth2.php:134
-msgid "OAuth2 Application not found."
-msgstr "Приложение OAuth2 не найдено."
-
-#: ../../Zotlabs/Module/Oauth2.php:143 ../../Zotlabs/Module/Oauth2.php:193
-#: ../../Zotlabs/Module/Oauth.php:110 ../../Zotlabs/Module/Oauth.php:136
-#: ../../Zotlabs/Module/Oauth.php:172
-msgid "Add application"
-msgstr "Добавить приложение"
-
-#: ../../Zotlabs/Module/Oauth2.php:149 ../../Zotlabs/Module/Oauth2.php:150
-msgid "leave blank unless your application specifically requires this"
-msgstr "оставьте поле пустым, если ваше приложение не требует этого"
-
-#: ../../Zotlabs/Module/Oauth2.php:192
-msgid "Connected OAuth2 Apps"
-msgstr "Подключённые приложения OAuth2"
-
-#: ../../Zotlabs/Module/Oauth2.php:196 ../../Zotlabs/Module/Oauth.php:175
-msgid "Client key starts with"
-msgstr "Ключ клиента начинается с"
-
-#: ../../Zotlabs/Module/Oauth2.php:197 ../../Zotlabs/Module/Oauth.php:176
-msgid "No name"
-msgstr "Без названия"
-
-#: ../../Zotlabs/Module/Oauth2.php:198 ../../Zotlabs/Module/Oauth.php:177
-msgid "Remove authorization"
-msgstr "Удалить разрешение"
-
-#: ../../Zotlabs/Module/Cal.php:70
-msgid "Permissions denied."
-msgstr "Доступ запрещен."
-
-#: ../../Zotlabs/Module/Cal.php:343 ../../include/text.php:2558
-msgid "Import"
-msgstr "Импортировать"
-
-#: ../../Zotlabs/Module/Api.php:74 ../../Zotlabs/Module/Api.php:95
-msgid "Authorize application connection"
-msgstr "Авторизовать подключение приложения"
-
-#: ../../Zotlabs/Module/Api.php:75
-msgid "Return to your app and insert this Security Code:"
-msgstr "Вернитесь к своему приложению и вставьте этот код безопасности:"
-
-#: ../../Zotlabs/Module/Api.php:85
-msgid "Please login to continue."
-msgstr "Пожалуйста, войдите, чтобы продолжить."
-
-#: ../../Zotlabs/Module/Api.php:97
-msgid ""
-"Do you want to authorize this application to access your posts and contacts, "
-"and/or create new posts for you?"
-msgstr "Вы хотите авторизовать это приложение для доступа к вашим публикациям и контактам и / или созданию новых публикаций?"
-
-#: ../../Zotlabs/Module/Attach.php:13
-msgid "Item not available."
-msgstr "Элемент недоступен."
-
-#: ../../Zotlabs/Module/Randprof.php:29
-msgid "Random Channel App"
-msgstr "Приложение \"Случайный канал\""
-
-#: ../../Zotlabs/Module/Randprof.php:30
-msgid "Visit a random channel in the $Projectname network"
-msgstr "Посещение случайного канала в сети $Projectname"
-
-#: ../../Zotlabs/Module/Editblock.php:138
-msgid "Edit Block"
-msgstr "Редактировать блок"
-
-#: ../../Zotlabs/Module/Profile.php:93
-msgid "vcard"
-msgstr "vCard"
-
-#: ../../Zotlabs/Module/Apps.php:50 ../../Zotlabs/Widget/Appstore.php:14
-msgid "Available Apps"
-msgstr "Доступные приложения"
-
-#: ../../Zotlabs/Module/Apps.php:50
-msgid "Installed Apps"
-msgstr "Установленные приложения"
-
-#: ../../Zotlabs/Module/Apps.php:53
-msgid "Manage Apps"
-msgstr "Управление приложениями"
-
-#: ../../Zotlabs/Module/Apps.php:54
-msgid "Create Custom App"
-msgstr "Создать пользовательское приложение"
-
-#: ../../Zotlabs/Module/Mood.php:76 ../../include/conversation.php:268
-#, php-format
-msgctxt "mood"
-msgid "%1$s is %2$s"
-msgstr "%1$s в %2$s"
-
-#: ../../Zotlabs/Module/Mood.php:134
-msgid "Mood App"
-msgstr "Приложение \"Настроение\""
-
-#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155
-msgid "Set your current mood and tell your friends"
-msgstr "Установить текущее настроение и рассказать друзьям"
-
-#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:347
-msgid "Mood"
-msgstr "Настроение"
-
-#: ../../Zotlabs/Module/Connections.php:58
-#: ../../Zotlabs/Module/Connections.php:115
-#: ../../Zotlabs/Module/Connections.php:259
-msgid "Active"
-msgstr "Активен"
-
-#: ../../Zotlabs/Module/Connections.php:63
-#: ../../Zotlabs/Module/Connections.php:167
-#: ../../Zotlabs/Module/Connections.php:264
-msgid "Blocked"
-msgstr "Заблокирован"
-
-#: ../../Zotlabs/Module/Connections.php:68
-#: ../../Zotlabs/Module/Connections.php:174
-#: ../../Zotlabs/Module/Connections.php:263
-msgid "Ignored"
-msgstr "Игнорируется"
-
-#: ../../Zotlabs/Module/Connections.php:73
-#: ../../Zotlabs/Module/Connections.php:188
-#: ../../Zotlabs/Module/Connections.php:262
-msgid "Hidden"
-msgstr "Скрыт"
-
-#: ../../Zotlabs/Module/Connections.php:78
-#: ../../Zotlabs/Module/Connections.php:181
-msgid "Archived/Unreachable"
-msgstr "Заархивировано / недоступно"
-
-#: ../../Zotlabs/Module/Connections.php:83
-#: ../../Zotlabs/Module/Connections.php:92 ../../Zotlabs/Module/Menu.php:179
-#: ../../Zotlabs/Module/Notifications.php:50
-msgid "New"
-msgstr "Новые"
-
-#: ../../Zotlabs/Module/Connections.php:97
-#: ../../Zotlabs/Module/Connections.php:111
-#: ../../Zotlabs/Module/Connedit.php:727 ../../Zotlabs/Widget/Affinity.php:34
-msgid "All"
-msgstr "Все"
-
-#: ../../Zotlabs/Module/Connections.php:143
-msgid "Active Connections"
-msgstr "Активные контакты"
-
-#: ../../Zotlabs/Module/Connections.php:146
-msgid "Show active connections"
-msgstr "Показать активные контакты"
-
-#: ../../Zotlabs/Module/Connections.php:150
-#: ../../Zotlabs/Widget/Notifications.php:84
-msgid "New Connections"
-msgstr "Новые контакты"
-
-#: ../../Zotlabs/Module/Connections.php:153
-msgid "Show pending (new) connections"
-msgstr "Просмотр (новых) ожидающих контактов"
-
-#: ../../Zotlabs/Module/Connections.php:170
-msgid "Only show blocked connections"
-msgstr "Показать только заблокированные контакты"
-
-#: ../../Zotlabs/Module/Connections.php:177
-msgid "Only show ignored connections"
-msgstr "Показать только проигнорированные контакты"
-
-#: ../../Zotlabs/Module/Connections.php:184
-msgid "Only show archived/unreachable connections"
-msgstr "Показать только заархивированные / недоступные контакты"
-
-#: ../../Zotlabs/Module/Connections.php:191
-msgid "Only show hidden connections"
-msgstr "Показать только скрытые контакты"
-
-#: ../../Zotlabs/Module/Connections.php:206
-msgid "Show all connections"
-msgstr "Просмотр всех контактов"
-
-#: ../../Zotlabs/Module/Connections.php:260
-msgid "Pending approval"
-msgstr "Ожидающие подтверждения"
-
-#: ../../Zotlabs/Module/Connections.php:261
-msgid "Archived"
-msgstr "Зархивирован"
-
-#: ../../Zotlabs/Module/Connections.php:265
-msgid "Not connected at this location"
-msgstr "Не подключено в этом месте"
-
-#: ../../Zotlabs/Module/Connections.php:282
-#, php-format
-msgid "%1$s [%2$s]"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:283
-msgid "Edit connection"
-msgstr "Редактировать контакт"
-
-#: ../../Zotlabs/Module/Connections.php:285
-msgid "Delete connection"
-msgstr "Удалить контакт"
-
-#: ../../Zotlabs/Module/Connections.php:294
-msgid "Channel address"
-msgstr "Адрес канала"
-
-#: ../../Zotlabs/Module/Connections.php:296 ../../include/features.php:313
-msgid "Network"
-msgstr "Сеть"
-
-#: ../../Zotlabs/Module/Connections.php:299
-msgid "Call"
-msgstr "Вызов"
-
-#: ../../Zotlabs/Module/Connections.php:301
-msgid "Status"
-msgstr "Статус"
-
-#: ../../Zotlabs/Module/Connections.php:303
-msgid "Connected"
-msgstr "Подключено"
-
-#: ../../Zotlabs/Module/Connections.php:305
-msgid "Approve connection"
-msgstr "Утвердить контакт"
-
-#: ../../Zotlabs/Module/Connections.php:307
-msgid "Ignore connection"
-msgstr "Игнорировать контакт"
-
-#: ../../Zotlabs/Module/Connections.php:308
-#: ../../Zotlabs/Module/Connedit.php:644
-msgid "Ignore"
-msgstr "Игнорировать"
-
-#: ../../Zotlabs/Module/Connections.php:309
-msgid "Recent activity"
-msgstr "Последние действия"
-
-#: ../../Zotlabs/Module/Connections.php:334 ../../Zotlabs/Lib/Apps.php:330
-#: ../../include/text.php:991 ../../include/features.php:125
-msgid "Connections"
-msgstr "Контакты"
-
-#: ../../Zotlabs/Module/Connections.php:339
-msgid "Search your connections"
-msgstr "Поиск ваших контактов"
-
-#: ../../Zotlabs/Module/Connections.php:340
-msgid "Connections search"
-msgstr "Поиск контаков"
-
-#: ../../Zotlabs/Module/Connections.php:341
-#: ../../Zotlabs/Module/Directory.php:405
-#: ../../Zotlabs/Module/Directory.php:410 ../../include/contact_widgets.php:23
-msgid "Find"
-msgstr "Поиск"
-
-#: ../../Zotlabs/Module/Viewsrc.php:43
-msgid "item"
-msgstr "пункт"
-
-#: ../../Zotlabs/Module/Bookmarks.php:62
-msgid "Bookmark added"
-msgstr "Закладка добавлена"
-
-#: ../../Zotlabs/Module/Bookmarks.php:78
-msgid "Bookmarks App"
-msgstr "Приложение \"Закладки\""
-
-#: ../../Zotlabs/Module/Bookmarks.php:79
-msgid "Bookmark links from posts and manage them"
-msgstr "Поместить ссылки из публикации в закладки и управлять ими"
-
-#: ../../Zotlabs/Module/Bookmarks.php:92
-msgid "My Bookmarks"
-msgstr "Мои закладки"
-
-#: ../../Zotlabs/Module/Bookmarks.php:103
-msgid "My Connections Bookmarks"
-msgstr "Закладки моих контактов"
-
-#: ../../Zotlabs/Module/Removeaccount.php:35
-msgid ""
-"Account removals are not allowed within 48 hours of changing the account "
-"password."
-msgstr "Удаление канала не разрешается в течении 48 часов после смены пароля у аккаунта."
-
-#: ../../Zotlabs/Module/Removeaccount.php:57
-msgid "Remove This Account"
-msgstr "Удалить этот аккаунт"
-
-#: ../../Zotlabs/Module/Removeaccount.php:58
-msgid ""
-"This account and all its channels will be completely removed from the "
-"network. "
-msgstr "Этот аккаунт и все его каналы будут полностью удалены из сети."
-
-#: ../../Zotlabs/Module/Removeaccount.php:60
-msgid ""
-"Remove this account, all its channels and all its channel clones from the "
-"network"
-msgstr "Удалить этот аккаунт, все его каналы и их клоны из сети."
-
-#: ../../Zotlabs/Module/Removeaccount.php:60
-msgid ""
-"By default only the instances of the channels located on this hub will be "
-"removed from the network"
-msgstr "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети"
-
-#: ../../Zotlabs/Module/Photos.php:78
-msgid "Page owner information could not be retrieved."
-msgstr "Информация о владельце страницы не может быть получена."
-
-#: ../../Zotlabs/Module/Photos.php:94 ../../Zotlabs/Module/Photos.php:113
-msgid "Album not found."
-msgstr "Альбом не найден."
-
-#: ../../Zotlabs/Module/Photos.php:103
-msgid "Delete Album"
-msgstr "Удалить альбом"
-
-#: ../../Zotlabs/Module/Photos.php:174 ../../Zotlabs/Module/Photos.php:1098
-msgid "Delete Photo"
-msgstr "Удалить фотографию"
-
-#: ../../Zotlabs/Module/Photos.php:569
-msgid "No photos selected"
-msgstr "Никакие фотографии не выбраны"
+#: ../../Zotlabs/Module/Hq.php:140
+msgid "Welcome to Hubzilla!"
+msgstr "Добро пожаловать в Hubzilla!"
-#: ../../Zotlabs/Module/Photos.php:618
-msgid "Access to this item is restricted."
-msgstr "Доступ к этому элементу ограничен."
+#: ../../Zotlabs/Module/Hq.php:140
+msgid "You have got no unseen posts..."
+msgstr "У вас нет видимых публикаций..."
-#: ../../Zotlabs/Module/Photos.php:661
+#: ../../Zotlabs/Module/Search.php:230
#, php-format
-msgid "%1$.2f MB of %2$.2f MB photo storage used."
-msgstr "Вы использовали %1$.2f мегабайт из %2$.2f для хранения фото."
+msgid "Items tagged with: %s"
+msgstr "Объекты помечены как: %s"
-#: ../../Zotlabs/Module/Photos.php:664
+#: ../../Zotlabs/Module/Search.php:232
#, php-format
-msgid "%1$.2f MB photo storage used."
-msgstr "Вы использовали %1$.2f мегабайт для хранения фото."
-
-#: ../../Zotlabs/Module/Photos.php:706
-msgid "Upload Photos"
-msgstr "Загрузить фотографии"
-
-#: ../../Zotlabs/Module/Photos.php:710
-msgid "Enter an album name"
-msgstr "Введите название альбома"
-
-#: ../../Zotlabs/Module/Photos.php:711
-msgid "or select an existing album (doubleclick)"
-msgstr "или выберите существующий альбом (двойной щелчок)"
-
-#: ../../Zotlabs/Module/Photos.php:712
-msgid "Create a status post for this upload"
-msgstr "Сделать публикацию о статусе для этой загрузки"
-
-#: ../../Zotlabs/Module/Photos.php:714
-msgid "Description (optional)"
-msgstr "Описание (необязательно)"
-
-#: ../../Zotlabs/Module/Photos.php:800
-msgid "Show Newest First"
-msgstr "Показать новые первыми"
-
-#: ../../Zotlabs/Module/Photos.php:802
-msgid "Show Oldest First"
-msgstr "Показать старые первыми"
-
-#: ../../Zotlabs/Module/Photos.php:859 ../../Zotlabs/Module/Photos.php:1405
-msgid "Add Photos"
-msgstr "Добавить фотографии"
-
-#: ../../Zotlabs/Module/Photos.php:907
-msgid "Permission denied. Access to this item may be restricted."
-msgstr "Доступ запрещен. Доступ к этому элементу может быть ограничен."
-
-#: ../../Zotlabs/Module/Photos.php:909
-msgid "Photo not available"
-msgstr "Фотография не доступна"
-
-#: ../../Zotlabs/Module/Photos.php:967
-msgid "Use as profile photo"
-msgstr "Использовать в качестве фотографии профиля"
-
-#: ../../Zotlabs/Module/Photos.php:968
-msgid "Use as cover photo"
-msgstr "Использовать в качестве фотографии обложки"
-
-#: ../../Zotlabs/Module/Photos.php:975
-msgid "Private Photo"
-msgstr "Личная фотография"
-
-#: ../../Zotlabs/Module/Photos.php:990
-msgid "View Full Size"
-msgstr "Посмотреть в полный размер"
-
-#: ../../Zotlabs/Module/Photos.php:1072
-msgid "Edit photo"
-msgstr "Редактировать фотографию"
-
-#: ../../Zotlabs/Module/Photos.php:1074
-msgid "Rotate CW (right)"
-msgstr "Повернуть CW (направо)"
-
-#: ../../Zotlabs/Module/Photos.php:1075
-msgid "Rotate CCW (left)"
-msgstr "Повернуть CCW (налево)"
-
-#: ../../Zotlabs/Module/Photos.php:1078
-msgid "Move photo to album"
-msgstr "Переместить фотографию в альбом"
-
-#: ../../Zotlabs/Module/Photos.php:1079
-msgid "Enter a new album name"
-msgstr "Введите новое название альбома"
-
-#: ../../Zotlabs/Module/Photos.php:1080
-msgid "or select an existing one (doubleclick)"
-msgstr "или выбрать существующую (двойной щелчок)"
-
-#: ../../Zotlabs/Module/Photos.php:1085
-msgid "Add a Tag"
-msgstr "Добавить тег"
-
-#: ../../Zotlabs/Module/Photos.php:1093
-msgid "Example: @bob, @Barbara_Jensen, @jim@example.com"
-msgstr "Пример: @bob, @Barbara_Jensen, @jim@example.com"
-
-#: ../../Zotlabs/Module/Photos.php:1096
-msgid "Flag as adult in album view"
-msgstr "Пометить как альбом \"для взрослых\""
-
-#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Lib/ThreadItem.php:306
-msgid "I like this (toggle)"
-msgstr "мне это нравится (переключение)"
-
-#: ../../Zotlabs/Module/Photos.php:1116 ../../Zotlabs/Lib/ThreadItem.php:307
-msgid "I don't like this (toggle)"
-msgstr "мне это не нравится (переключение)"
-
-#: ../../Zotlabs/Module/Photos.php:1118 ../../Zotlabs/Lib/ThreadItem.php:469
-#: ../../include/conversation.php:787
-msgid "Please wait"
-msgstr "Подождите пожалуйста"
-
-#: ../../Zotlabs/Module/Photos.php:1135 ../../Zotlabs/Module/Photos.php:1254
-#: ../../Zotlabs/Lib/ThreadItem.php:792
-msgid "This is you"
-msgstr "Это вы"
-
-#: ../../Zotlabs/Module/Photos.php:1137 ../../Zotlabs/Module/Photos.php:1256
-#: ../../Zotlabs/Lib/ThreadItem.php:794 ../../include/js_strings.php:6
-msgid "Comment"
-msgstr "Комментарий"
-
-#: ../../Zotlabs/Module/Photos.php:1154 ../../include/conversation.php:619
-msgctxt "title"
-msgid "Likes"
-msgstr "Нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1154 ../../include/conversation.php:619
-msgctxt "title"
-msgid "Dislikes"
-msgstr "Не нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1155 ../../include/conversation.php:620
-msgctxt "title"
-msgid "Agree"
-msgstr "Согласен"
-
-#: ../../Zotlabs/Module/Photos.php:1155 ../../include/conversation.php:620
-msgctxt "title"
-msgid "Disagree"
-msgstr "Не согласен"
-
-#: ../../Zotlabs/Module/Photos.php:1155 ../../include/conversation.php:620
-msgctxt "title"
-msgid "Abstain"
-msgstr "Воздержался"
-
-#: ../../Zotlabs/Module/Photos.php:1156 ../../include/conversation.php:621
-msgctxt "title"
-msgid "Attending"
-msgstr "Посещаю"
-
-#: ../../Zotlabs/Module/Photos.php:1156 ../../include/conversation.php:621
-msgctxt "title"
-msgid "Not attending"
-msgstr "Не посещаю"
-
-#: ../../Zotlabs/Module/Photos.php:1156 ../../include/conversation.php:621
-msgctxt "title"
-msgid "Might attend"
-msgstr "Возможно посещу"
-
-#: ../../Zotlabs/Module/Photos.php:1173 ../../Zotlabs/Module/Photos.php:1185
-#: ../../Zotlabs/Lib/ThreadItem.php:231 ../../Zotlabs/Lib/ThreadItem.php:243
-msgid "View all"
-msgstr "Просмотреть все"
-
-#: ../../Zotlabs/Module/Photos.php:1177 ../../Zotlabs/Lib/ThreadItem.php:235
-#: ../../include/conversation.php:1702 ../../include/channel.php:1595
-#: ../../include/taxonomy.php:661
-msgctxt "noun"
-msgid "Like"
-msgid_plural "Likes"
-msgstr[0] "Нравится"
-msgstr[1] "Нравится"
-msgstr[2] "Нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1182 ../../Zotlabs/Lib/ThreadItem.php:240
-#: ../../include/conversation.php:1705
-msgctxt "noun"
-msgid "Dislike"
-msgid_plural "Dislikes"
-msgstr[0] "Не нравится"
-msgstr[1] "Не нравится"
-msgstr[2] "Не нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1288
-msgid "Photo Tools"
-msgstr "Фото-Инструменты"
-
-#: ../../Zotlabs/Module/Photos.php:1297
-msgid "In This Photo:"
-msgstr "На этой фотографии:"
-
-#: ../../Zotlabs/Module/Photos.php:1302
-msgid "Map"
-msgstr "Карта"
-
-#: ../../Zotlabs/Module/Photos.php:1310 ../../Zotlabs/Lib/ThreadItem.php:457
-msgctxt "noun"
-msgid "Likes"
-msgstr "Нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1311 ../../Zotlabs/Lib/ThreadItem.php:458
-msgctxt "noun"
-msgid "Dislikes"
-msgstr "Не нравится"
-
-#: ../../Zotlabs/Module/Photos.php:1316 ../../Zotlabs/Lib/ThreadItem.php:463
-#: ../../include/acl_selectors.php:125
-msgid "Close"
-msgstr "Закрыть"
-
-#: ../../Zotlabs/Module/Photos.php:1389 ../../Zotlabs/Module/Photos.php:1402
-#: ../../Zotlabs/Module/Photos.php:1403 ../../include/photos.php:670
-msgid "Recent Photos"
-msgstr "Последние фотографии"
-
-#: ../../Zotlabs/Module/Wiki.php:35
-#: ../../addon/flashcards/Mod_Flashcards.php:34 ../../addon/cart/cart.php:1298
-msgid "Profile Unavailable."
-msgstr "Профиль недоступен."
-
-#: ../../Zotlabs/Module/Wiki.php:52
-msgid "Wiki App"
-msgstr "Приложение \"Wiki\""
-
-#: ../../Zotlabs/Module/Wiki.php:53
-msgid "Provide a wiki for your channel"
-msgstr "Предоставьте Wiki для вашего канала"
-
-#: ../../Zotlabs/Module/Wiki.php:77 ../../addon/cart/myshop.php:37
-#: ../../addon/cart/cart.php:1444
-#: ../../addon/cart/submodules/paypalbutton.php:456
-#: ../../addon/cart/manual_payments.php:93
-msgid "Invalid channel"
-msgstr "Недействительный канал"
-
-#: ../../Zotlabs/Module/Wiki.php:133
-msgid "Error retrieving wiki"
-msgstr "Ошибка при получении Wiki"
-
-#: ../../Zotlabs/Module/Wiki.php:140
-msgid "Error creating zip file export folder"
-msgstr "Ошибка при создании zip-файла при экспорте каталога"
-
-#: ../../Zotlabs/Module/Wiki.php:191
-msgid "Error downloading wiki: "
-msgstr "Ошибка загрузки Wiki:"
-
-#: ../../Zotlabs/Module/Wiki.php:206 ../../Zotlabs/Widget/Wiki_list.php:15
-#: ../../include/nav.php:536
-msgid "Wikis"
-msgstr ""
-
-#: ../../Zotlabs/Module/Wiki.php:212
-msgid "Download"
-msgstr "Загрузить"
-
-#: ../../Zotlabs/Module/Wiki.php:214 ../../Zotlabs/Module/Chat.php:264
-#: ../../Zotlabs/Module/Profiles.php:831 ../../Zotlabs/Module/Manage.php:145
-msgid "Create New"
-msgstr "Создать новый"
-
-#: ../../Zotlabs/Module/Wiki.php:216
-msgid "Wiki name"
-msgstr "Название Wiki"
-
-#: ../../Zotlabs/Module/Wiki.php:217
-msgid "Content type"
-msgstr "Тип содержимого"
-
-#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371
-#: ../../Zotlabs/Widget/Wiki_pages.php:38
-#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../addon/mdpost/mdpost.php:41
-#: ../../include/text.php:1955
-msgid "Markdown"
-msgstr "Разметка Markdown"
+msgid "Search results for: %s"
+msgstr "Результаты поиска для: %s"
-#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371
-#: ../../Zotlabs/Widget/Wiki_pages.php:38
-#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:1953
-msgid "BBcode"
-msgstr ""
+#: ../../Zotlabs/Module/Notes.php:56
+msgid "Notes App"
+msgstr "Приложение \"Заметки\""
-#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:38
-#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:1956
-msgid "Text"
-msgstr "Текст"
+#: ../../Zotlabs/Module/Notes.php:57
+msgid "A simple notes app with a widget (note: notes are not encrypted)"
+msgstr "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)"
-#: ../../Zotlabs/Module/Wiki.php:219 ../../Zotlabs/Storage/Browser.php:286
-msgid "Type"
-msgstr "Тип"
+#: ../../Zotlabs/Module/Moderate.php:65
+msgid "Comment approved"
+msgstr "Комментарий одобрен"
-#: ../../Zotlabs/Module/Wiki.php:220
-msgid "Any&nbsp;type"
-msgstr "Любой&nbsp;тип"
+#: ../../Zotlabs/Module/Moderate.php:69
+msgid "Comment deleted"
+msgstr "Комментарий удалён"
-#: ../../Zotlabs/Module/Wiki.php:227
-msgid "Lock content type"
-msgstr "Зафиксировать тип содержимого"
+#: ../../Zotlabs/Module/Webpages.php:48
+msgid "Webpages App"
+msgstr "Приложение \"Веб-страницы\""
-#: ../../Zotlabs/Module/Wiki.php:228
-msgid "Create a status post for this wiki"
-msgstr "Создать публикацию о статусе этой Wiki"
+#: ../../Zotlabs/Module/Webpages.php:49
+msgid "Provide managed web pages on your channel"
+msgstr "Предоставлять управляемые веб-страницы на Вашем канале"
-#: ../../Zotlabs/Module/Wiki.php:229
-msgid "Edit Wiki Name"
-msgstr "Редактировать наименование Wiki"
+#: ../../Zotlabs/Module/Webpages.php:69
+msgid "Import Webpage Elements"
+msgstr "Импортировать части веб-страницы"
-#: ../../Zotlabs/Module/Wiki.php:274
-msgid "Wiki not found"
-msgstr "Wiki не найдена"
+#: ../../Zotlabs/Module/Webpages.php:70
+msgid "Import selected"
+msgstr "Импортировать выбранное"
-#: ../../Zotlabs/Module/Wiki.php:300
-msgid "Rename page"
-msgstr "Переименовать страницу"
+#: ../../Zotlabs/Module/Webpages.php:93
+msgid "Export Webpage Elements"
+msgstr "Экспортировать часть веб-страницы"
-#: ../../Zotlabs/Module/Wiki.php:321
-msgid "Error retrieving page content"
-msgstr "Ошибка при получении содержимого страницы"
+#: ../../Zotlabs/Module/Webpages.php:94
+msgid "Export selected"
+msgstr "Экспортировать выбранное"
-#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331
-msgid "New page"
-msgstr "Новая страница"
+#: ../../Zotlabs/Module/Webpages.php:263
+msgid "Actions"
+msgstr "Действия"
-#: ../../Zotlabs/Module/Wiki.php:366
-msgid "Revision Comparison"
-msgstr "Сравнение ревизий"
+#: ../../Zotlabs/Module/Webpages.php:264
+msgid "Page Link"
+msgstr "Ссылка страницы"
-#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:564
-#: ../../Zotlabs/Widget/Wiki_page_history.php:25
-msgid "Revert"
-msgstr "Отменить"
+#: ../../Zotlabs/Module/Webpages.php:265
+msgid "Page Title"
+msgstr "Заголовок страницы"
-#: ../../Zotlabs/Module/Wiki.php:374
-msgid "Short description of your changes (optional)"
-msgstr "Краткое описание ваших изменений (необязательно)"
+#: ../../Zotlabs/Module/Webpages.php:295
+msgid "Invalid file type."
+msgstr "Неверный тип файла."
-#: ../../Zotlabs/Module/Wiki.php:384
-msgid "Source"
-msgstr "Источник"
+#: ../../Zotlabs/Module/Webpages.php:307
+msgid "Error opening zip file"
+msgstr "Ошибка открытия ZIP файла"
-#: ../../Zotlabs/Module/Wiki.php:394
-msgid "New page name"
-msgstr "Новое имя страницы"
+#: ../../Zotlabs/Module/Webpages.php:318
+msgid "Invalid folder path."
+msgstr "Неверный путь к каталогу."
-#: ../../Zotlabs/Module/Wiki.php:399
-msgid "Embed image from photo albums"
-msgstr "Встроить изображение из фотоальбома"
+#: ../../Zotlabs/Module/Webpages.php:345
+msgid "No webpage elements detected."
+msgstr "Не обнаружено частей веб-страницы."
-#: ../../Zotlabs/Module/Wiki.php:400 ../../addon/hsse/hsse.php:208
-#: ../../include/conversation.php:1414
-msgid "Embed an image from your albums"
-msgstr "Встроить изображение из ваших альбомов"
+#: ../../Zotlabs/Module/Webpages.php:420
+msgid "Import complete."
+msgstr "Импорт завершен."
-#: ../../Zotlabs/Module/Wiki.php:402 ../../Zotlabs/Module/Profile_photo.php:466
-#: ../../Zotlabs/Module/Cover_photo.php:400 ../../addon/hsse/hsse.php:210
-#: ../../addon/hsse/hsse.php:257 ../../include/conversation.php:1416
-#: ../../include/conversation.php:1463
-msgid "OK"
+#: ../../Zotlabs/Module/Home.php:72 ../../Zotlabs/Module/Home.php:80
+#: ../../Zotlabs/Lib/Enotify.php:66
+#: ../../extend/addon/hzaddons/opensearch/opensearch.php:42
+msgid "$Projectname"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:403 ../../Zotlabs/Module/Profile_photo.php:467
-#: ../../Zotlabs/Module/Cover_photo.php:401 ../../addon/hsse/hsse.php:139
-#: ../../include/conversation.php:1342
-msgid "Choose images to embed"
-msgstr "Выбрать изображения для встраивания"
-
-#: ../../Zotlabs/Module/Wiki.php:404 ../../Zotlabs/Module/Profile_photo.php:468
-#: ../../Zotlabs/Module/Cover_photo.php:402 ../../addon/hsse/hsse.php:140
-#: ../../include/conversation.php:1343
-msgid "Choose an album"
-msgstr "Выбрать альбом"
-
-#: ../../Zotlabs/Module/Wiki.php:405 ../../Zotlabs/Module/Profile_photo.php:469
-#: ../../Zotlabs/Module/Cover_photo.php:403
-msgid "Choose a different album"
-msgstr "Выбрать другой альбом"
-
-#: ../../Zotlabs/Module/Wiki.php:406 ../../Zotlabs/Module/Profile_photo.php:470
-#: ../../Zotlabs/Module/Cover_photo.php:404 ../../addon/hsse/hsse.php:142
-#: ../../include/conversation.php:1345
-msgid "Error getting album list"
-msgstr "Ошибка получения списка альбомов"
-
-#: ../../Zotlabs/Module/Wiki.php:407 ../../Zotlabs/Module/Profile_photo.php:471
-#: ../../Zotlabs/Module/Cover_photo.php:405 ../../addon/hsse/hsse.php:143
-#: ../../include/conversation.php:1346
-msgid "Error getting photo link"
-msgstr "Ошибка получения ссылки на фотографию"
-
-#: ../../Zotlabs/Module/Wiki.php:408 ../../Zotlabs/Module/Profile_photo.php:472
-#: ../../Zotlabs/Module/Cover_photo.php:406 ../../addon/hsse/hsse.php:144
-#: ../../include/conversation.php:1347
-msgid "Error getting album"
-msgstr "Ошибка получения альбома"
-
-#: ../../Zotlabs/Module/Wiki.php:410
-msgid "History"
-msgstr "История"
-
-#: ../../Zotlabs/Module/Wiki.php:488
-msgid "Error creating wiki. Invalid name."
-msgstr "Ошибка создания Wiki. Неверное имя."
-
-#: ../../Zotlabs/Module/Wiki.php:495
-msgid "A wiki with this name already exists."
-msgstr "Wiki с таким именем уже существует."
-
-#: ../../Zotlabs/Module/Wiki.php:508
-msgid "Wiki created, but error creating Home page."
-msgstr "Wiki создана, но возникла ошибка при создании домашней страницы"
-
-#: ../../Zotlabs/Module/Wiki.php:515
-msgid "Error creating wiki"
-msgstr "Ошибка при создании Wiki"
-
-#: ../../Zotlabs/Module/Wiki.php:539
-msgid "Error updating wiki. Invalid name."
-msgstr "Ошибка при обновлении Wiki. Неверное имя."
-
-#: ../../Zotlabs/Module/Wiki.php:559
-msgid "Error updating wiki"
-msgstr "Ошибка при обновлении Wiki"
-
-#: ../../Zotlabs/Module/Wiki.php:574
-msgid "Wiki delete permission denied."
-msgstr "Нет прав на удаление Wiki."
-
-#: ../../Zotlabs/Module/Wiki.php:584
-msgid "Error deleting wiki"
-msgstr "Ошибка удаления Wiki"
-
-#: ../../Zotlabs/Module/Wiki.php:617
-msgid "New page created"
-msgstr "Создана новая страница"
-
-#: ../../Zotlabs/Module/Wiki.php:739
-msgid "Cannot delete Home"
-msgstr "Невозможно удалить домашнюю страницу"
-
-#: ../../Zotlabs/Module/Wiki.php:803
-msgid "Current Revision"
-msgstr "Текущая ревизия"
-
-#: ../../Zotlabs/Module/Wiki.php:803
-msgid "Selected Revision"
-msgstr "Выбранная ревизия"
-
-#: ../../Zotlabs/Module/Wiki.php:853
-msgid "You must be authenticated."
-msgstr "Вы должны быть аутентифицированы."
-
-#: ../../Zotlabs/Module/Share.php:103 ../../Zotlabs/Lib/Activity.php:1473
+#: ../../Zotlabs/Module/Home.php:90
#, php-format
-msgid "&#x1f501; Repeated %1$s's %2$s"
-msgstr "&#x1f501; Повторил %1$s %2$s"
-
-#: ../../Zotlabs/Module/Share.php:119
-msgid "Post repeated"
-msgstr "Публикация повторяется"
-
-#: ../../Zotlabs/Module/Chanview.php:139
-msgid "toggle full screen mode"
-msgstr "переключение полноэкранного режима"
-
-#: ../../Zotlabs/Module/Pdledit.php:26
-msgid "Layout updated."
-msgstr "Шаблон обновлен."
-
-#: ../../Zotlabs/Module/Pdledit.php:42
-msgid "PDL Editor App"
-msgstr "Приложение \"Редактор PDL\""
-
-#: ../../Zotlabs/Module/Pdledit.php:43
-msgid "Provides the ability to edit system page layouts"
-msgstr "Предоставляет возможность редактировать макеты системных страниц"
-
-#: ../../Zotlabs/Module/Pdledit.php:56 ../../Zotlabs/Module/Pdledit.php:99
-msgid "Edit System Page Description"
-msgstr "Редактировать описание системной страницы"
-
-#: ../../Zotlabs/Module/Pdledit.php:77
-msgid "(modified)"
-msgstr "(изменено)"
-
-#: ../../Zotlabs/Module/Pdledit.php:77 ../../Zotlabs/Module/Lostpass.php:133
-msgid "Reset"
-msgstr "Сбросить"
-
-#: ../../Zotlabs/Module/Pdledit.php:94
-msgid "Layout not found."
-msgstr "Шаблон не найден."
-
-#: ../../Zotlabs/Module/Pdledit.php:100
-msgid "Module Name:"
-msgstr "Имя модуля:"
-
-#: ../../Zotlabs/Module/Pdledit.php:101
-msgid "Layout Help"
-msgstr "Помощь к шаблону"
-
-#: ../../Zotlabs/Module/Pdledit.php:102
-msgid "Edit another layout"
-msgstr "Редактировать другой шаблон"
-
-#: ../../Zotlabs/Module/Pdledit.php:103
-msgid "System layout"
-msgstr "Системный шаблон"
-
-#: ../../Zotlabs/Module/Poke.php:165
-msgid "Poke App"
-msgstr "Приложение \"Ткнуть\""
-
-#: ../../Zotlabs/Module/Poke.php:166
-msgid "Poke somebody in your addressbook"
-msgstr "Ткнуть кого-нибудь в вашей адресной книге"
-
-#: ../../Zotlabs/Module/Poke.php:199 ../../Zotlabs/Lib/Apps.php:348
-#: ../../include/conversation.php:1098
-msgid "Poke"
-msgstr "Ткнуть"
-
-#: ../../Zotlabs/Module/Poke.php:200
-msgid "Poke somebody"
-msgstr "Ткнуть кого-нибудь"
-
-#: ../../Zotlabs/Module/Poke.php:203
-msgid "Poke/Prod"
-msgstr "Толкнуть / подтолкнуть"
-
-#: ../../Zotlabs/Module/Poke.php:204
-msgid "Poke, prod or do other things to somebody"
-msgstr "Толкнуть, подтолкнуть или сделать что-то ещё с кем-то"
-
-#: ../../Zotlabs/Module/Poke.php:211
-msgid "Recipient"
-msgstr "Получатель"
-
-#: ../../Zotlabs/Module/Poke.php:212
-msgid "Choose what you wish to do to recipient"
-msgstr "Выбрать что вы хотите сделать с получателем"
-
-#: ../../Zotlabs/Module/Poke.php:215 ../../Zotlabs/Module/Poke.php:216
-msgid "Make this post private"
-msgstr "Сделать эту публикацию приватной"
-
-#: ../../Zotlabs/Module/Profile_photo.php:66
-#: ../../Zotlabs/Module/Cover_photo.php:57
-msgid "Image uploaded but image cropping failed."
-msgstr "Изображение загружено но обрезка не удалась."
-
-#: ../../Zotlabs/Module/Profile_photo.php:120
-#: ../../Zotlabs/Module/Profile_photo.php:248
-#: ../../include/photo/photo_driver.php:367
-msgid "Profile Photos"
-msgstr "Фотографии профиля"
-
-#: ../../Zotlabs/Module/Profile_photo.php:142
-#: ../../Zotlabs/Module/Cover_photo.php:191
-msgid "Image resize failed."
-msgstr "Не удалось изменить размер изображения."
+msgid "Welcome to %s"
+msgstr "Добро пожаловать в %s"
-#: ../../Zotlabs/Module/Profile_photo.php:218
-#: ../../addon/openclipatar/openclipatar.php:298
+#: ../../Zotlabs/Module/Profile_photo.php:229
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:298
msgid ""
"Shift-reload the page or clear browser cache if the new photo does not "
"display immediately."
msgstr "Если новая фотография не отображается немедленно то нажмите Shift + \"Обновить\" для очистки кэша браузера"
-#: ../../Zotlabs/Module/Profile_photo.php:225
-#: ../../Zotlabs/Module/Cover_photo.php:205 ../../include/photos.php:196
-msgid "Unable to process image"
-msgstr "Не удается обработать изображение"
-
-#: ../../Zotlabs/Module/Profile_photo.php:260
-#: ../../Zotlabs/Module/Cover_photo.php:229
-msgid "Image upload failed."
-msgstr "Загрузка изображения не удалась."
-
-#: ../../Zotlabs/Module/Profile_photo.php:279
-#: ../../Zotlabs/Module/Cover_photo.php:246
-msgid "Unable to process image."
-msgstr "Невозможно обработать изображение."
-
-#: ../../Zotlabs/Module/Profile_photo.php:343
-#: ../../Zotlabs/Module/Profile_photo.php:390
-#: ../../Zotlabs/Module/Cover_photo.php:339
-#: ../../Zotlabs/Module/Cover_photo.php:354
-msgid "Photo not available."
-msgstr "Фотография недоступна."
-
-#: ../../Zotlabs/Module/Profile_photo.php:454
+#: ../../Zotlabs/Module/Profile_photo.php:468
msgid ""
"Your default profile photo is visible to anybody on the internet. Profile "
"photos for alternate profiles will inherit the permissions of the profile"
msgstr "Фотография вашего профиля по умолчанию видна всем в Интернете. Фотографияпрофиля для альтернативных профилей наследуют разрешения текущего профиля"
-#: ../../Zotlabs/Module/Profile_photo.php:454
+#: ../../Zotlabs/Module/Profile_photo.php:468
msgid ""
"Your profile photo is visible to anybody on the internet and may be "
"distributed to other websites."
msgstr "Фотография вашего профиля видна всем в Интернете и может быть отправлена на другие сайты."
-#: ../../Zotlabs/Module/Profile_photo.php:456
-#: ../../Zotlabs/Module/Cover_photo.php:392
-msgid "Upload File:"
-msgstr "Загрузить файл:"
-
-#: ../../Zotlabs/Module/Profile_photo.php:457
-#: ../../Zotlabs/Module/Cover_photo.php:393
-msgid "Select a profile:"
-msgstr "Выбрать профиль:"
-
-#: ../../Zotlabs/Module/Profile_photo.php:458
+#: ../../Zotlabs/Module/Profile_photo.php:472
msgid "Use Photo for Profile"
msgstr "Использовать фотографию для профиля"
-#: ../../Zotlabs/Module/Profile_photo.php:458
+#: ../../Zotlabs/Module/Profile_photo.php:472
msgid "Change Profile Photo"
msgstr "Изменить фотографию профиля"
-#: ../../Zotlabs/Module/Profile_photo.php:459
+#: ../../Zotlabs/Module/Profile_photo.php:473
msgid "Use"
msgstr "Использовать"
-#: ../../Zotlabs/Module/Profile_photo.php:463
-#: ../../Zotlabs/Module/Profile_photo.php:464
-#: ../../Zotlabs/Module/Cover_photo.php:397
-#: ../../Zotlabs/Module/Cover_photo.php:398
-msgid "Use a photo from your albums"
-msgstr "Использовать фотографию из ваших альбомов"
-
-#: ../../Zotlabs/Module/Profile_photo.php:474
-#: ../../Zotlabs/Module/Cover_photo.php:409
-msgid "Select existing photo"
-msgstr "Выбрать существующую фотографию"
-
-#: ../../Zotlabs/Module/Profile_photo.php:493
-#: ../../Zotlabs/Module/Cover_photo.php:426
-msgid "Crop Image"
-msgstr "Обрезать изображение"
-
-#: ../../Zotlabs/Module/Profile_photo.php:494
-#: ../../Zotlabs/Module/Cover_photo.php:427
-msgid "Please adjust the image cropping for optimum viewing."
-msgstr "Пожалуйста настройте обрезку изображения для оптимального просмотра."
-
-#: ../../Zotlabs/Module/Profile_photo.php:496
-#: ../../Zotlabs/Module/Cover_photo.php:429
-msgid "Done Editing"
-msgstr "Закончить редактирование"
-
-#: ../../Zotlabs/Module/Chatsvc.php:131
-msgid "Away"
-msgstr "Нет на месте"
-
-#: ../../Zotlabs/Module/Chatsvc.php:136
-msgid "Online"
-msgstr "В сети"
-
-#: ../../Zotlabs/Module/Item.php:341
-msgid "Unable to locate original post."
-msgstr "Не удалось найти оригинальную публикацию."
-
-#: ../../Zotlabs/Module/Item.php:628
-msgid "Empty post discarded."
-msgstr "Пустая публикация отклонена."
-
-#: ../../Zotlabs/Module/Item.php:1037
-msgid "Duplicate post suppressed."
-msgstr "Подавлена дублирующаяся публикация."
-
-#: ../../Zotlabs/Module/Item.php:1182
-msgid "System error. Post not saved."
-msgstr "Системная ошибка. Публикация не сохранена."
-
-#: ../../Zotlabs/Module/Item.php:1218
-msgid "Your comment is awaiting approval."
-msgstr "Ваш комментарий ожидает одобрения."
-
-#: ../../Zotlabs/Module/Item.php:1335
-msgid "Unable to obtain post information from database."
-msgstr "Невозможно получить информацию о публикации из базы данных"
-
-#: ../../Zotlabs/Module/Item.php:1342
-#, php-format
-msgid "You have reached your limit of %1$.0f top level posts."
-msgstr "Вы достигли вашего ограничения в %1$.0f публикаций высокого уровня."
-
-#: ../../Zotlabs/Module/Item.php:1349
-#, php-format
-msgid "You have reached your limit of %1$.0f webpages."
-msgstr "Вы достигли вашего ограничения в %1$.0f страниц."
-
-#: ../../Zotlabs/Module/Ping.php:338
-msgid "sent you a private message"
-msgstr "отправил вам личное сообщение"
-
-#: ../../Zotlabs/Module/Ping.php:394
-msgid "added your channel"
-msgstr "добавил ваш канал"
-
-#: ../../Zotlabs/Module/Ping.php:419
-msgid "requires approval"
-msgstr "Требуется подтверждение"
-
-#: ../../Zotlabs/Module/Ping.php:429
-msgid "g A l F d"
-msgstr "g A l F d"
-
-#: ../../Zotlabs/Module/Ping.php:447
-msgid "[today]"
-msgstr "[сегодня]"
-
-#: ../../Zotlabs/Module/Ping.php:457
-msgid "posted an event"
-msgstr "событие опубликовано"
-
-#: ../../Zotlabs/Module/Ping.php:491
-msgid "shared a file with you"
-msgstr "с вами поделились файлом"
-
-#: ../../Zotlabs/Module/Ping.php:673
-msgid "Private forum"
-msgstr "Частный форум"
+#: ../../Zotlabs/Module/Rbmark.php:94
+msgid "Select a bookmark folder"
+msgstr "Выбрать каталог для закладок"
-#: ../../Zotlabs/Module/Ping.php:673
-msgid "Public forum"
-msgstr "Публичный форум"
+#: ../../Zotlabs/Module/Rbmark.php:99
+msgid "Save Bookmark"
+msgstr "Сохранить закладку"
-#: ../../Zotlabs/Module/Page.php:39 ../../Zotlabs/Module/Block.php:29
-msgid "Invalid item."
-msgstr "Недействительный элемент."
+#: ../../Zotlabs/Module/Rbmark.php:100
+msgid "URL of bookmark"
+msgstr "URL закладки"
-#: ../../Zotlabs/Module/Page.php:136 ../../Zotlabs/Module/Block.php:77
-#: ../../Zotlabs/Module/Display.php:140 ../../Zotlabs/Module/Display.php:157
-#: ../../Zotlabs/Module/Display.php:174
-#: ../../Zotlabs/Lib/NativeWikiPage.php:521 ../../Zotlabs/Web/Router.php:185
-#: ../../addon/chess/Mod_Chess.php:447 ../../include/help.php:132
-msgid "Page not found."
-msgstr "Страница не найдена."
+#: ../../Zotlabs/Module/Rbmark.php:105
+msgid "Or enter new bookmark folder name"
+msgstr "или введите новое имя каталога закладок"
-#: ../../Zotlabs/Module/Page.php:173
-msgid ""
-"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
-"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
-"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo "
-"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
-"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
-"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
-msgstr ""
+#: ../../Zotlabs/Module/Follow.php:36
+msgid "Connection added."
+msgstr "Контакт добавлен."
-#: ../../Zotlabs/Module/Connedit.php:81 ../../Zotlabs/Module/Defperms.php:67
-msgid "Could not access contact record."
-msgstr "Не удалось получить доступ к записи контакта."
+#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43
+msgid "Item is not editable"
+msgstr "Элемент нельзя редактировать"
#: ../../Zotlabs/Module/Connedit.php:112
msgid "Could not locate selected profile."
@@ -5676,12 +9708,6 @@ msgstr "Не удалось получить доступ к параметра
msgid "Connection has been removed."
msgstr "Контакт был удалён."
-#: ../../Zotlabs/Module/Connedit.php:608 ../../Zotlabs/Lib/Apps.php:341
-#: ../../addon/openclipatar/openclipatar.php:57
-#: ../../include/conversation.php:1038 ../../include/nav.php:106
-msgid "View Profile"
-msgstr "Просмотреть профиль"
-
#: ../../Zotlabs/Module/Connedit.php:611
#, php-format
msgid "View %s's profile"
@@ -5703,10 +9729,6 @@ msgstr "Обновить фотографию"
msgid "Fetch updated photo"
msgstr "Получить обновлённую фотографию"
-#: ../../Zotlabs/Module/Connedit.php:629 ../../include/conversation.php:1048
-msgid "Recent Activity"
-msgstr "Последние действия"
-
#: ../../Zotlabs/Module/Connedit.php:632
msgid "View recent posts and comments"
msgstr "Просмотреть последние публикации и комментарии"
@@ -5723,6 +9745,11 @@ msgstr "Этот контакт заблокирован!"
msgid "Unignore"
msgstr "Не игнорировать"
+#: ../../Zotlabs/Module/Connedit.php:644
+#: ../../Zotlabs/Module/Connections.php:322
+msgid "Ignore"
+msgstr "Игнорировать"
+
#: ../../Zotlabs/Module/Connedit.php:647
msgid "Ignore (or Unignore) all inbound communications from this connection"
msgstr "Игнорировать (или не игнорировать) все связи для этого контакта"
@@ -5800,6 +9827,13 @@ msgstr "Семья"
msgid "Acquaintances"
msgstr "Знакомые"
+#: ../../Zotlabs/Module/Connedit.php:727
+#: ../../Zotlabs/Module/Connections.php:97
+#: ../../Zotlabs/Module/Connections.php:111
+#: ../../Zotlabs/Widget/Affinity.php:34
+msgid "All"
+msgstr "Все"
+
#: ../../Zotlabs/Module/Connedit.php:756
msgid "Filter"
msgstr "Фильтр"
@@ -5846,31 +9880,10 @@ msgid ""
"not supported by their network."
msgstr "Этот контакт недоступен из данного местоположения. Независимое местоположение не поддерживается их сетью."
-#: ../../Zotlabs/Module/Connedit.php:867 ../../Zotlabs/Module/Defperms.php:254
-msgid "Connection Default Permissions"
-msgstr "Разрешения по умолчанию для контакта"
-
-#: ../../Zotlabs/Module/Connedit.php:867 ../../include/items.php:4308
-#, php-format
-msgid "Connection: %s"
-msgstr "Контакт: %s"
-
-#: ../../Zotlabs/Module/Connedit.php:868 ../../Zotlabs/Module/Defperms.php:255
-msgid "Apply these permissions automatically"
-msgstr "Применить эти разрешения автоматически"
-
#: ../../Zotlabs/Module/Connedit.php:868
msgid "Connection requests will be approved without your interaction"
msgstr "Запросы контактов будут одобрены без вашего участия"
-#: ../../Zotlabs/Module/Connedit.php:869 ../../Zotlabs/Module/Defperms.php:256
-msgid "Permission role"
-msgstr "Роль разрешения"
-
-#: ../../Zotlabs/Module/Connedit.php:870 ../../Zotlabs/Module/Defperms.php:257
-msgid "Add permission role"
-msgstr "Добавить роль разрешения"
-
#: ../../Zotlabs/Module/Connedit.php:877
msgid "This connection's primary address is"
msgstr "Главный адрес это контакта"
@@ -5879,12 +9892,6 @@ msgstr "Главный адрес это контакта"
msgid "Available locations:"
msgstr "Доступные расположения:"
-#: ../../Zotlabs/Module/Connedit.php:883 ../../Zotlabs/Module/Defperms.php:261
-msgid ""
-"The permissions indicated on this page will be applied to all new "
-"connections."
-msgstr "Разрешения, указанные на этой странице, будут применяться ко всем новым соединениям."
-
#: ../../Zotlabs/Module/Connedit.php:884
msgid "Connection Tools"
msgstr "Инструменты контактов"
@@ -5893,11 +9900,6 @@ msgstr "Инструменты контактов"
msgid "Slide to adjust your degree of friendship"
msgstr "Прокрутить для настройки степени дружбы"
-#: ../../Zotlabs/Module/Connedit.php:887 ../../Zotlabs/Module/Rate.php:155
-#: ../../include/js_strings.php:20
-msgid "Rating"
-msgstr "Оценка"
-
#: ../../Zotlabs/Module/Connedit.php:888
msgid "Slide to adjust your rating"
msgstr "Прокрутить для настройки оценки"
@@ -5949,364 +9951,6 @@ msgstr "Последнее обновление:"
msgid "Details"
msgstr "Сведения"
-#: ../../Zotlabs/Module/Chat.php:102
-msgid "Chatrooms App"
-msgstr "Приложение \"Мои чаты\""
-
-#: ../../Zotlabs/Module/Chat.php:103
-msgid "Access Controlled Chatrooms"
-msgstr "Получить доступ к контролируемым чатам"
-
-#: ../../Zotlabs/Module/Chat.php:196
-msgid "Room not found"
-msgstr "Комната не найдена"
-
-#: ../../Zotlabs/Module/Chat.php:212
-msgid "Leave Room"
-msgstr "Покинуть комнату"
-
-#: ../../Zotlabs/Module/Chat.php:213
-msgid "Delete Room"
-msgstr "Удалить комнату"
-
-#: ../../Zotlabs/Module/Chat.php:214
-msgid "I am away right now"
-msgstr "Я сейчас отошёл"
-
-#: ../../Zotlabs/Module/Chat.php:215
-msgid "I am online"
-msgstr "Я на связи"
-
-#: ../../Zotlabs/Module/Chat.php:217
-msgid "Bookmark this room"
-msgstr "Запомнить эту комнату"
-
-#: ../../Zotlabs/Module/Chat.php:220 ../../Zotlabs/Module/Mail.php:241
-#: ../../Zotlabs/Module/Mail.php:362 ../../addon/hsse/hsse.php:134
-#: ../../include/conversation.php:1337
-msgid "Please enter a link URL:"
-msgstr "Пожалуйста введите URL ссылки:"
-
-#: ../../Zotlabs/Module/Chat.php:221 ../../Zotlabs/Module/Mail.php:294
-#: ../../Zotlabs/Module/Mail.php:436 ../../Zotlabs/Lib/ThreadItem.php:809
-#: ../../addon/hsse/hsse.php:255 ../../include/conversation.php:1461
-msgid "Encrypt text"
-msgstr "Зашифровать текст"
-
-#: ../../Zotlabs/Module/Chat.php:240
-msgid "New Chatroom"
-msgstr "Новый чат"
-
-#: ../../Zotlabs/Module/Chat.php:241
-msgid "Chatroom name"
-msgstr "Название чата"
-
-#: ../../Zotlabs/Module/Chat.php:242
-msgid "Expiration of chats (minutes)"
-msgstr "Завершение чатов (минут)"
-
-#: ../../Zotlabs/Module/Chat.php:258
-#, php-format
-msgid "%1$s's Chatrooms"
-msgstr "Чаты пользователя %1$s"
-
-#: ../../Zotlabs/Module/Chat.php:263
-msgid "No chatrooms available"
-msgstr "Нет доступных чатов"
-
-#: ../../Zotlabs/Module/Chat.php:267
-msgid "Expiration"
-msgstr "Срок действия"
-
-#: ../../Zotlabs/Module/Chat.php:268
-msgid "min"
-msgstr "мин."
-
-#: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:342
-#: ../../include/features.php:383 ../../include/nav.php:444
-msgid "Photos"
-msgstr "Фотографии"
-
-#: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Lib/Apps.php:337
-#: ../../Zotlabs/Storage/Browser.php:272 ../../include/nav.php:452
-msgid "Files"
-msgstr "Файлы"
-
-#: ../../Zotlabs/Module/Menu.php:67
-msgid "Unable to update menu."
-msgstr "Невозможно обновить меню."
-
-#: ../../Zotlabs/Module/Menu.php:78
-msgid "Unable to create menu."
-msgstr "Невозможно создать меню."
-
-#: ../../Zotlabs/Module/Menu.php:160 ../../Zotlabs/Module/Menu.php:173
-msgid "Menu Name"
-msgstr "Название меню"
-
-#: ../../Zotlabs/Module/Menu.php:160
-msgid "Unique name (not visible on webpage) - required"
-msgstr "Уникальное название (не видимо на странице) - требуется"
-
-#: ../../Zotlabs/Module/Menu.php:161 ../../Zotlabs/Module/Menu.php:174
-msgid "Menu Title"
-msgstr "Заголовок меню"
-
-#: ../../Zotlabs/Module/Menu.php:161
-msgid "Visible on webpage - leave empty for no title"
-msgstr "Видимость на странице - оставьте пустым если не хотите иметь заголовок"
-
-#: ../../Zotlabs/Module/Menu.php:162
-msgid "Allow Bookmarks"
-msgstr "Разрешить закладки"
-
-#: ../../Zotlabs/Module/Menu.php:162 ../../Zotlabs/Module/Menu.php:221
-msgid "Menu may be used to store saved bookmarks"
-msgstr "Меню может использоваться, чтобы сохранить закладки"
-
-#: ../../Zotlabs/Module/Menu.php:163 ../../Zotlabs/Module/Menu.php:224
-msgid "Submit and proceed"
-msgstr "Отправить и обработать"
-
-#: ../../Zotlabs/Module/Menu.php:170 ../../include/text.php:2535
-msgid "Menus"
-msgstr "Меню"
-
-#: ../../Zotlabs/Module/Menu.php:180
-msgid "Bookmarks allowed"
-msgstr "Закладки разрешены"
-
-#: ../../Zotlabs/Module/Menu.php:182
-msgid "Delete this menu"
-msgstr "Удалить это меню"
-
-#: ../../Zotlabs/Module/Menu.php:183 ../../Zotlabs/Module/Menu.php:218
-msgid "Edit menu contents"
-msgstr "Редактировать содержание меню"
-
-#: ../../Zotlabs/Module/Menu.php:184
-msgid "Edit this menu"
-msgstr "Редактировать это меню"
-
-#: ../../Zotlabs/Module/Menu.php:200
-msgid "Menu could not be deleted."
-msgstr "Меню не может быть удалено."
-
-#: ../../Zotlabs/Module/Menu.php:213
-msgid "Edit Menu"
-msgstr "Редактировать меню"
-
-#: ../../Zotlabs/Module/Menu.php:217
-msgid "Add or remove entries to this menu"
-msgstr "Добавить или удалить пункты этого меню"
-
-#: ../../Zotlabs/Module/Menu.php:219
-msgid "Menu name"
-msgstr "Название меню"
-
-#: ../../Zotlabs/Module/Menu.php:219
-msgid "Must be unique, only seen by you"
-msgstr "Должно быть уникальным (видно только вам)"
-
-#: ../../Zotlabs/Module/Menu.php:220
-msgid "Menu title"
-msgstr "Заголовок меню"
-
-#: ../../Zotlabs/Module/Menu.php:220
-msgid "Menu title as seen by others"
-msgstr "Видимый другими заголовок меню"
-
-#: ../../Zotlabs/Module/Menu.php:221
-msgid "Allow bookmarks"
-msgstr "Разрешить закладки"
-
-#: ../../Zotlabs/Module/Layouts.php:184 ../../include/text.php:2536
-msgid "Layouts"
-msgstr "Шаблоны"
-
-#: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:345
-#: ../../include/nav.php:168 ../../include/nav.php:319
-#: ../../include/help.php:117 ../../include/help.php:125
-msgid "Help"
-msgstr "Помощь"
-
-#: ../../Zotlabs/Module/Layouts.php:186
-msgid "Comanche page description language help"
-msgstr "Помощь по языку описания страниц Comanche "
-
-#: ../../Zotlabs/Module/Layouts.php:190
-msgid "Layout Description"
-msgstr "Описание шаблона"
-
-#: ../../Zotlabs/Module/Layouts.php:195
-msgid "Download PDL file"
-msgstr "Загрузить PDL файл"
-
-#: ../../Zotlabs/Module/Notes.php:56
-msgid "Notes App"
-msgstr "Приложение \"Заметки\""
-
-#: ../../Zotlabs/Module/Notes.php:57
-msgid "A simple notes app with a widget (note: notes are not encrypted)"
-msgstr "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)"
-
-#: ../../Zotlabs/Module/Cloud.php:123
-msgid "Not found"
-msgstr "Не найдено."
-
-#: ../../Zotlabs/Module/Cloud.php:129
-msgid "Please refresh page"
-msgstr "Пожалуйста обновите страницу"
-
-#: ../../Zotlabs/Module/Cloud.php:132
-msgid "Unknown error"
-msgstr "Неизвестная ошибка"
-
-#: ../../Zotlabs/Module/Email_validation.php:24
-#: ../../Zotlabs/Module/Email_resend.php:12
-msgid "Token verification failed."
-msgstr "Не удалось выполнить проверку токена."
-
-#: ../../Zotlabs/Module/Email_validation.php:36
-msgid "Email Verification Required"
-msgstr "Требуется проверка адреса email"
-
-#: ../../Zotlabs/Module/Email_validation.php:37
-#, php-format
-msgid ""
-"A verification token was sent to your email address [%s]. Enter that token "
-"here to complete the account verification step. Please allow a few minutes "
-"for delivery, and check your spam folder if you do not see the message."
-msgstr "Проверочный токен был отправлен на ваш адрес электронной почты [%s]. Введите этот токен здесь для завершения этапа проверки учётной записи. Пожалуйста, подождите несколько минут для завершения доставки и проверьте вашу папку \"Спам\" если вы не видите письма."
-
-#: ../../Zotlabs/Module/Email_validation.php:38
-msgid "Resend Email"
-msgstr "Выслать повторно"
-
-#: ../../Zotlabs/Module/Email_validation.php:41
-msgid "Validation token"
-msgstr "Проверочный токен"
-
-#: ../../Zotlabs/Module/Tagger.php:48
-msgid "Post not found."
-msgstr "Публикация не найдена"
-
-#: ../../Zotlabs/Module/Tagger.php:77 ../../include/markdown.php:200
-#: ../../include/bbcode.php:343
-msgid "post"
-msgstr "публикация"
-
-#: ../../Zotlabs/Module/Tagger.php:79 ../../include/conversation.php:146
-#: ../../include/text.php:2099
-msgid "comment"
-msgstr "комментарий"
-
-#: ../../Zotlabs/Module/Tagger.php:119
-#, php-format
-msgid "%1$s tagged %2$s's %3$s with %4$s"
-msgstr "%1$s отметил тегом %2$s %3$s с %4$s"
-
-#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68
-msgid "This setting requires special processing and editing has been blocked."
-msgstr "Этот параметр требует специальной обработки и редактирования и был заблокирован."
-
-#: ../../Zotlabs/Module/Pconfig.php:57
-msgid "Configuration Editor"
-msgstr "Редактор конфигурации"
-
-#: ../../Zotlabs/Module/Pconfig.php:58
-msgid ""
-"Warning: Changing some settings could render your channel inoperable. Please "
-"leave this page unless you are comfortable with and knowledgeable about how "
-"to correctly use this feature."
-msgstr "Предупреждение. Изменение некоторых настроек может привести к неработоспособности вашего канала. Пожалуйста, покиньте эту страницу, если вы точно не значете, как правильно использовать эту функцию."
-
-#: ../../Zotlabs/Module/Affinity.php:35
-msgid "Affinity Tool settings updated."
-msgstr "Настройки степени сходства обновлены."
-
-#: ../../Zotlabs/Module/Affinity.php:47
-msgid ""
-"This app presents a slider control in your connection editor and also on "
-"your network page. The slider represents your degree of friendship "
-"(affinity) with each connection. It allows you to zoom in or out and display "
-"conversations from only your closest friends or everybody in your stream."
-msgstr "Это приложение представляет управление ползунком на странице контактов и сетевом потоке, который позволяет выбирать вашу степень дружбы (сходства). Это позволяет вам увеличивать или уменьшать масштаб и отображать разговоры только от ваших самых близких друзей или всех в вашем потоке."
-
-#: ../../Zotlabs/Module/Affinity.php:52
-msgid "Affinity Tool App"
-msgstr "Приложение \"Степень сходства\""
-
-#: ../../Zotlabs/Module/Affinity.php:57
-msgid ""
-"The numbers below represent the minimum and maximum slider default positions "
-"for your network/stream page as a percentage."
-msgstr "Числа ниже представляют минимальное и максимальное значение по умолчанию для вашей сети / потока в процентах."
-
-#: ../../Zotlabs/Module/Affinity.php:64
-msgid "Default maximum affinity level"
-msgstr "Максимальная степень сходства по умолчанию."
-
-#: ../../Zotlabs/Module/Affinity.php:64
-msgid "0-99 default 99"
-msgstr "0-99 (по умолчанию 99)"
-
-#: ../../Zotlabs/Module/Affinity.php:70
-msgid "Default minimum affinity level"
-msgstr "Максимальная степень сходства по умолчанию."
-
-#: ../../Zotlabs/Module/Affinity.php:70
-msgid "0-99 - default 0"
-msgstr "0-99 (по умолчанию 0)"
-
-#: ../../Zotlabs/Module/Affinity.php:76
-msgid "Persistent affinity levels"
-msgstr "Устоявшиеся степени сходства"
-
-#: ../../Zotlabs/Module/Affinity.php:76
-msgid ""
-"If disabled the max and min levels will be reset to default after page reload"
-msgstr "Если этот параметр отключен, максимальный и минимальный уровни будут сброшены к значениям по умолчанию после перезагрузки страницы"
-
-#: ../../Zotlabs/Module/Affinity.php:84
-msgid "Affinity Tool Settings"
-msgstr "Настройки степени сходства"
-
-#: ../../Zotlabs/Module/Defperms.php:189
-msgid "Default Permissions App"
-msgstr "Приложение \"Разрешения по умолчанию\""
-
-#: ../../Zotlabs/Module/Defperms.php:190
-msgid "Set custom default permissions for new connections"
-msgstr "Настройка пользовательских разрешений по умолчанию для новых подключений "
-
-#: ../../Zotlabs/Module/Defperms.php:262
-msgid "Automatic approval settings"
-msgstr "Настройки автоматического одобрения"
-
-#: ../../Zotlabs/Module/Defperms.php:270
-msgid ""
-"Some individual permissions may have been preset or locked based on your "
-"channel type and privacy settings."
-msgstr "Некоторые индивидуальные разрешения могут быть предустановлены или заблокированы на основании типа вашего канала и настроек приватности."
-
-#: ../../Zotlabs/Module/Authorize.php:17
-msgid "Unknown App"
-msgstr "Неизвестное приложение"
-
-#: ../../Zotlabs/Module/Authorize.php:29
-msgid "Authorize"
-msgstr "Авторизовать"
-
-#: ../../Zotlabs/Module/Authorize.php:30
-#, php-format
-msgid "Do you authorize the app %s to access your channel data?"
-msgstr "Авторизуете ли вы приложение %s для доступа к данным вашего канала?"
-
-#: ../../Zotlabs/Module/Authorize.php:32
-msgid "Allow"
-msgstr "Разрешить"
-
#: ../../Zotlabs/Module/Group.php:45
msgid "Privacy group created."
msgstr "Группа безопасности создана."
@@ -6315,11 +9959,6 @@ msgstr "Группа безопасности создана."
msgid "Could not create privacy group."
msgstr "Не удалось создать группу безопасности."
-#: ../../Zotlabs/Module/Group.php:61 ../../Zotlabs/Module/Group.php:213
-#: ../../include/items.php:4275
-msgid "Privacy group not found."
-msgstr "Группа безопасности не найдена."
-
#: ../../Zotlabs/Module/Group.php:80
msgid "Privacy group updated."
msgstr "Группа безопасности обновлена."
@@ -6332,13 +9971,6 @@ msgstr "Приложение \"Группы безопасности\""
msgid "Management of privacy groups"
msgstr "Управление группами безопасности."
-#: ../../Zotlabs/Module/Group.php:141 ../../Zotlabs/Module/Group.php:153
-#: ../../Zotlabs/Lib/Apps.php:361 ../../Zotlabs/Lib/Group.php:324
-#: ../../Zotlabs/Widget/Activity_filter.php:41 ../../include/nav.php:95
-#: ../../include/group.php:320
-msgid "Privacy Groups"
-msgstr "Группы безопасности"
-
#: ../../Zotlabs/Module/Group.php:142
msgid "Add Group"
msgstr "Добавить группу"
@@ -6351,10 +9983,6 @@ msgstr "Имя группы безопасности"
msgid "Members are visible to other channels"
msgstr "Участники канала видимые для остальных"
-#: ../../Zotlabs/Module/Group.php:155 ../../Zotlabs/Module/Help.php:81
-msgid "Members"
-msgstr "Участники"
-
#: ../../Zotlabs/Module/Group.php:182
msgid "Privacy group removed."
msgstr "Группа безопасности удалена."
@@ -6388,953 +10016,629 @@ msgstr "Не в этой группе"
msgid "Click a channel to toggle membership"
msgstr "Нажмите на канал для просмотра членства"
-#: ../../Zotlabs/Module/Profiles.php:24 ../../Zotlabs/Module/Profiles.php:184
-#: ../../Zotlabs/Module/Profiles.php:241 ../../Zotlabs/Module/Profiles.php:659
-msgid "Profile not found."
-msgstr "Профиль не найден."
-
-#: ../../Zotlabs/Module/Profiles.php:44
-msgid "Profile deleted."
-msgstr "Профиль удален."
-
-#: ../../Zotlabs/Module/Profiles.php:68 ../../Zotlabs/Module/Profiles.php:105
-msgid "Profile-"
-msgstr "Профиль -"
-
-#: ../../Zotlabs/Module/Profiles.php:90 ../../Zotlabs/Module/Profiles.php:127
-msgid "New profile created."
-msgstr "Новый профиль создан."
-
-#: ../../Zotlabs/Module/Profiles.php:111
-msgid "Profile unavailable to clone."
-msgstr "Профиль недоступен для клонирования."
-
-#: ../../Zotlabs/Module/Profiles.php:146
-msgid "Profile unavailable to export."
-msgstr "Профиль недоступен для экспорта."
-
-#: ../../Zotlabs/Module/Profiles.php:252
-msgid "Profile Name is required."
-msgstr "Требуется имя профиля."
-
-#: ../../Zotlabs/Module/Profiles.php:459
-msgid "Marital Status"
-msgstr "Семейное положение"
-
-#: ../../Zotlabs/Module/Profiles.php:463
-msgid "Romantic Partner"
-msgstr "Романтический партнер"
-
-#: ../../Zotlabs/Module/Profiles.php:467 ../../Zotlabs/Module/Profiles.php:772
-msgid "Likes"
-msgstr "Нравится"
-
-#: ../../Zotlabs/Module/Profiles.php:471 ../../Zotlabs/Module/Profiles.php:773
-msgid "Dislikes"
-msgstr "Не нравится"
+#: ../../Zotlabs/Module/Connections.php:58
+#: ../../Zotlabs/Module/Connections.php:115
+#: ../../Zotlabs/Module/Connections.php:273
+msgid "Active"
+msgstr "Активен"
-#: ../../Zotlabs/Module/Profiles.php:475 ../../Zotlabs/Module/Profiles.php:780
-msgid "Work/Employment"
-msgstr "Работа / Занятость"
+#: ../../Zotlabs/Module/Connections.php:63
+#: ../../Zotlabs/Module/Connections.php:181
+#: ../../Zotlabs/Module/Connections.php:278
+msgid "Blocked"
+msgstr "Заблокирован"
-#: ../../Zotlabs/Module/Profiles.php:478
-msgid "Religion"
-msgstr "Религия"
+#: ../../Zotlabs/Module/Connections.php:68
+#: ../../Zotlabs/Module/Connections.php:188
+#: ../../Zotlabs/Module/Connections.php:277
+msgid "Ignored"
+msgstr "Игнорируется"
-#: ../../Zotlabs/Module/Profiles.php:482
-msgid "Political Views"
-msgstr "Политические взгляды"
+#: ../../Zotlabs/Module/Connections.php:73
+#: ../../Zotlabs/Module/Connections.php:202
+#: ../../Zotlabs/Module/Connections.php:276
+msgid "Hidden"
+msgstr "Скрыт"
-#: ../../Zotlabs/Module/Profiles.php:486
-#: ../../addon/openid/MysqlProvider.php:74
-msgid "Gender"
-msgstr "Гендер"
+#: ../../Zotlabs/Module/Connections.php:78
+#: ../../Zotlabs/Module/Connections.php:195
+msgid "Archived/Unreachable"
+msgstr "Заархивировано / недоступно"
-#: ../../Zotlabs/Module/Profiles.php:490
-msgid "Sexual Preference"
-msgstr "Сексуальная ориентация"
+#: ../../Zotlabs/Module/Connections.php:157
+msgid "Active Connections"
+msgstr "Активные контакты"
-#: ../../Zotlabs/Module/Profiles.php:494
-msgid "Homepage"
-msgstr "Домашняя страница"
+#: ../../Zotlabs/Module/Connections.php:160
+msgid "Show active connections"
+msgstr "Показать активные контакты"
-#: ../../Zotlabs/Module/Profiles.php:498
-msgid "Interests"
-msgstr "Интересы"
+#: ../../Zotlabs/Module/Connections.php:164
+#: ../../Zotlabs/Widget/Notifications.php:84
+msgid "New Connections"
+msgstr "Новые контакты"
-#: ../../Zotlabs/Module/Profiles.php:594
-msgid "Profile updated."
-msgstr "Профиль обновлен."
+#: ../../Zotlabs/Module/Connections.php:167
+msgid "Show pending (new) connections"
+msgstr "Просмотр (новых) ожидающих контактов"
-#: ../../Zotlabs/Module/Profiles.php:678
-msgid "Hide your connections list from viewers of this profile"
-msgstr "Скрывать от просмотра ваш список контактов в этом профиле"
+#: ../../Zotlabs/Module/Connections.php:184
+msgid "Only show blocked connections"
+msgstr "Показать только заблокированные контакты"
-#: ../../Zotlabs/Module/Profiles.php:722
-msgid "Edit Profile Details"
-msgstr "Редактирование профиля"
+#: ../../Zotlabs/Module/Connections.php:191
+msgid "Only show ignored connections"
+msgstr "Показать только проигнорированные контакты"
-#: ../../Zotlabs/Module/Profiles.php:724
-msgid "View this profile"
-msgstr "Посмотреть этот профиль"
+#: ../../Zotlabs/Module/Connections.php:198
+msgid "Only show archived/unreachable connections"
+msgstr "Показать только заархивированные / недоступные контакты"
-#: ../../Zotlabs/Module/Profiles.php:725 ../../Zotlabs/Module/Profiles.php:824
-#: ../../include/channel.php:1375
-msgid "Edit visibility"
-msgstr "Редактировать видимость"
+#: ../../Zotlabs/Module/Connections.php:205
+msgid "Only show hidden connections"
+msgstr "Показать только скрытые контакты"
-#: ../../Zotlabs/Module/Profiles.php:726
-msgid "Profile Tools"
-msgstr "Инструменты профиля"
+#: ../../Zotlabs/Module/Connections.php:220
+msgid "Show all connections"
+msgstr "Просмотр всех контактов"
-#: ../../Zotlabs/Module/Profiles.php:727
-msgid "Change cover photo"
-msgstr "Изменить фотографию обложки"
+#: ../../Zotlabs/Module/Connections.php:274
+msgid "Pending approval"
+msgstr "Ожидающие подтверждения"
-#: ../../Zotlabs/Module/Profiles.php:728 ../../include/channel.php:1345
-msgid "Change profile photo"
-msgstr "Изменить фотографию профиля"
+#: ../../Zotlabs/Module/Connections.php:275
+msgid "Archived"
+msgstr "Зархивирован"
-#: ../../Zotlabs/Module/Profiles.php:729
-msgid "Create a new profile using these settings"
-msgstr "Создать новый профиль с теми же настройками"
+#: ../../Zotlabs/Module/Connections.php:279
+msgid "Not connected at this location"
+msgstr "Не подключено в этом месте"
-#: ../../Zotlabs/Module/Profiles.php:730
-msgid "Clone this profile"
-msgstr "Клонировать этот профиль"
+#: ../../Zotlabs/Module/Connections.php:296
+#, php-format
+msgid "%1$s [%2$s]"
+msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:731
-msgid "Delete this profile"
-msgstr "Удалить этот профиль"
+#: ../../Zotlabs/Module/Connections.php:297
+msgid "Edit connection"
+msgstr "Редактировать контакт"
-#: ../../Zotlabs/Module/Profiles.php:732
-msgid "Add profile things"
-msgstr "Добавить в профиль"
+#: ../../Zotlabs/Module/Connections.php:299
+msgid "Delete connection"
+msgstr "Удалить контакт"
-#: ../../Zotlabs/Module/Profiles.php:733
-msgid "Personal"
-msgstr "Личное"
+#: ../../Zotlabs/Module/Connections.php:308
+msgid "Channel address"
+msgstr "Адрес канала"
-#: ../../Zotlabs/Module/Profiles.php:735
-msgid "Relationship"
-msgstr "Отношения"
+#: ../../Zotlabs/Module/Connections.php:313
+msgid "Call"
+msgstr "Вызов"
-#: ../../Zotlabs/Module/Profiles.php:736 ../../Zotlabs/Widget/Newmember.php:51
-#: ../../include/datetime.php:58
-msgid "Miscellaneous"
-msgstr "Прочее"
+#: ../../Zotlabs/Module/Connections.php:315
+msgid "Status"
+msgstr "Статус"
-#: ../../Zotlabs/Module/Profiles.php:738
-msgid "Import profile from file"
-msgstr "Импортировать профиль из файла"
+#: ../../Zotlabs/Module/Connections.php:317
+msgid "Connected"
+msgstr "Подключено"
-#: ../../Zotlabs/Module/Profiles.php:739
-msgid "Export profile to file"
-msgstr "Экспортировать профиль в файл"
+#: ../../Zotlabs/Module/Connections.php:319
+msgid "Approve connection"
+msgstr "Утвердить контакт"
-#: ../../Zotlabs/Module/Profiles.php:740
-msgid "Your gender"
-msgstr "Ваш пол"
+#: ../../Zotlabs/Module/Connections.php:321
+msgid "Ignore connection"
+msgstr "Игнорировать контакт"
-#: ../../Zotlabs/Module/Profiles.php:741
-msgid "Marital status"
-msgstr "Семейное положение"
+#: ../../Zotlabs/Module/Connections.php:323
+msgid "Recent activity"
+msgstr "Последние действия"
-#: ../../Zotlabs/Module/Profiles.php:742
-msgid "Sexual preference"
-msgstr "Сексуальная ориентация"
+#: ../../Zotlabs/Module/Connections.php:353
+msgid "Search your connections"
+msgstr "Поиск ваших контактов"
-#: ../../Zotlabs/Module/Profiles.php:745
-msgid "Profile name"
-msgstr "Имя профиля"
+#: ../../Zotlabs/Module/Connections.php:354
+msgid "Connections search"
+msgstr "Поиск контаков"
-#: ../../Zotlabs/Module/Profiles.php:747
-msgid "This is your default profile."
-msgstr "Это ваш профиль по умолчанию."
+#: ../../Zotlabs/Module/Mood.php:134
+msgid "Mood App"
+msgstr "Приложение \"Настроение\""
-#: ../../Zotlabs/Module/Profiles.php:749
-msgid "Your full name"
-msgstr "Ваше полное имя"
+#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Module/Mood.php:155
+msgid "Set your current mood and tell your friends"
+msgstr "Установить текущее настроение и рассказать друзьям"
-#: ../../Zotlabs/Module/Profiles.php:750
-msgid "Title/Description"
-msgstr "Заголовок / описание"
+#: ../../Zotlabs/Module/Mood.php:154 ../../Zotlabs/Lib/Apps.php:349
+msgid "Mood"
+msgstr "Настроение"
-#: ../../Zotlabs/Module/Profiles.php:753
-msgid "Street address"
-msgstr "Улица, дом, квартира"
+#: ../../Zotlabs/Module/Card_edit.php:128
+msgid "Edit Card"
+msgstr "Редактировать карточку"
-#: ../../Zotlabs/Module/Profiles.php:754
-msgid "Locality/City"
-msgstr "Населенный пункт / город"
+#: ../../Zotlabs/Module/Article_edit.php:128
+msgid "Edit Article"
+msgstr "Редактировать статью"
-#: ../../Zotlabs/Module/Profiles.php:755
-msgid "Region/State"
-msgstr "Регион / Область"
+#: ../../Zotlabs/Module/Lang.php:17
+msgid "Language App"
+msgstr "Приложение \"Язык\""
-#: ../../Zotlabs/Module/Profiles.php:756
-msgid "Postal/Zip code"
-msgstr "Почтовый индекс"
+#: ../../Zotlabs/Module/Lang.php:18
+msgid "Change UI language"
+msgstr "Изменить язык интерфейса"
-#: ../../Zotlabs/Module/Profiles.php:762
-msgid "Who (if applicable)"
-msgstr "Кто (если применимо)"
+#: ../../Zotlabs/Module/Blocks.php:156
+msgid "Block Title"
+msgstr "Заблокировать заголовок"
-#: ../../Zotlabs/Module/Profiles.php:762
-msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
-msgstr "Примеры: ivan1990, Ivan Petrov, ivan@example.com"
+#: ../../Zotlabs/Module/Randprof.php:29
+msgid "Random Channel App"
+msgstr "Приложение \"Случайный канал\""
-#: ../../Zotlabs/Module/Profiles.php:763
-msgid "Since (date)"
-msgstr "С (дата)"
+#: ../../Zotlabs/Module/Randprof.php:30
+msgid "Visit a random channel in the $Projectname network"
+msgstr "Посещение случайного канала в сети $Projectname"
-#: ../../Zotlabs/Module/Profiles.php:766
-msgid "Tell us about yourself"
-msgstr "Расскажите нам о себе"
+#: ../../Zotlabs/Module/Invite.php:37
+msgid "Total invitation limit exceeded."
+msgstr "Превышено общее количество приглашений."
-#: ../../Zotlabs/Module/Profiles.php:767
-#: ../../addon/openid/MysqlProvider.php:68
-msgid "Homepage URL"
-msgstr "URL домашней страницы"
+#: ../../Zotlabs/Module/Invite.php:61
+#, php-format
+msgid "%s : Not a valid email address."
+msgstr "%s : Недействительный адрес электронной почты."
-#: ../../Zotlabs/Module/Profiles.php:768
-msgid "Hometown"
-msgstr "Родной город"
+#: ../../Zotlabs/Module/Invite.php:75
+msgid "Please join us on $Projectname"
+msgstr "Присоединятесь к $Projectname !"
-#: ../../Zotlabs/Module/Profiles.php:769
-msgid "Political views"
-msgstr "Политические взгляды"
+#: ../../Zotlabs/Module/Invite.php:85
+msgid "Invitation limit exceeded. Please contact your site administrator."
+msgstr "Превышен лимит приглашений. Пожалуйста, свяжитесь с администрацией сайта."
-#: ../../Zotlabs/Module/Profiles.php:770
-msgid "Religious views"
-msgstr "Религиозные взгляды"
+#: ../../Zotlabs/Module/Invite.php:90
+#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:40
+#, php-format
+msgid "%s : Message delivery failed."
+msgstr "%s : Доставка сообщения не удалась."
-#: ../../Zotlabs/Module/Profiles.php:771
-msgid "Keywords used in directory listings"
-msgstr "Ключевые слова для участия в каталоге"
+#: ../../Zotlabs/Module/Invite.php:94
+#, php-format
+msgid "%d message sent."
+msgid_plural "%d messages sent."
+msgstr[0] "%d сообщение отправлено."
+msgstr[1] "%d сообщения отправлено."
+msgstr[2] "%d сообщений отправлено."
-#: ../../Zotlabs/Module/Profiles.php:771
-msgid "Example: fishing photography software"
-msgstr "Например: fishing photography software"
+#: ../../Zotlabs/Module/Invite.php:110
+msgid "Invite App"
+msgstr "Приложение \"Пригласить\""
-#: ../../Zotlabs/Module/Profiles.php:774
-msgid "Musical interests"
-msgstr "Музыкальные интересы"
+#: ../../Zotlabs/Module/Invite.php:111
+msgid "Send email invitations to join this network"
+msgstr "Отправить приглашение присоединиться к этой сети по электронной почте"
-#: ../../Zotlabs/Module/Profiles.php:775
-msgid "Books, literature"
-msgstr "Книги, литература"
+#: ../../Zotlabs/Module/Invite.php:124
+msgid "You have no more invitations available"
+msgstr "У вас больше нет приглашений"
-#: ../../Zotlabs/Module/Profiles.php:776
-msgid "Television"
-msgstr "Телевидение"
+#: ../../Zotlabs/Module/Invite.php:155
+msgid "Send invitations"
+msgstr "Отправить приглашение"
-#: ../../Zotlabs/Module/Profiles.php:777
-msgid "Film/Dance/Culture/Entertainment"
-msgstr "Кино / танцы / культура / развлечения"
+#: ../../Zotlabs/Module/Invite.php:156
+msgid "Enter email addresses, one per line:"
+msgstr "Введите адреса электронной почты, по одному в строке:"
-#: ../../Zotlabs/Module/Profiles.php:778
-msgid "Hobbies/Interests"
-msgstr "Хобби / интересы"
+#: ../../Zotlabs/Module/Invite.php:158
+msgid "Please join my community on $Projectname."
+msgstr "Присоединятесь к нашему сообществу $Projectname !"
-#: ../../Zotlabs/Module/Profiles.php:779
-msgid "Love/Romance"
-msgstr "Любовь / романтические отношения"
+#: ../../Zotlabs/Module/Invite.php:160
+msgid "You will need to supply this invitation code:"
+msgstr "Вам нужно предоставит этот код приглашения:"
-#: ../../Zotlabs/Module/Profiles.php:781
-msgid "School/Education"
-msgstr "Школа / образование"
+#: ../../Zotlabs/Module/Invite.php:161
+msgid "1. Register at any $Projectname location (they are all inter-connected)"
+msgstr "1. Зарегистрируйтесь на любом из серверов $Projectname"
-#: ../../Zotlabs/Module/Profiles.php:782
-msgid "Contact information and social networks"
-msgstr "Информация и социальные сети для связи"
+#: ../../Zotlabs/Module/Invite.php:163
+msgid "2. Enter my $Projectname network address into the site searchbar."
+msgstr "2. Введите сетевой адрес $Projectname в поисковой строке сайта"
-#: ../../Zotlabs/Module/Profiles.php:783
-msgid "My other channels"
-msgstr "Мои другие контакты"
+#: ../../Zotlabs/Module/Invite.php:164
+msgid "or visit"
+msgstr "или посетите"
-#: ../../Zotlabs/Module/Profiles.php:785
-msgid "Communications"
-msgstr "Связи"
+#: ../../Zotlabs/Module/Invite.php:166
+msgid "3. Click [Connect]"
+msgstr "Нажать [Подключиться]"
-#: ../../Zotlabs/Module/Profiles.php:820 ../../include/channel.php:1371
-msgid "Profile Image"
-msgstr "Изображение профиля"
+#: ../../Zotlabs/Module/Articles.php:51
+msgid "Articles App"
+msgstr "Приложение \"Статьи\""
-#: ../../Zotlabs/Module/Profiles.php:830 ../../include/channel.php:1352
-#: ../../include/nav.php:109
-msgid "Edit Profiles"
-msgstr "Редактирование профилей"
+#: ../../Zotlabs/Module/Articles.php:52
+msgid "Create interactive articles"
+msgstr "Создать интерактивные статьи"
-#: ../../Zotlabs/Module/Go.php:21
-msgid "This page is available only to site members"
-msgstr "Эта страница доступна только для подписчиков сайта"
+#: ../../Zotlabs/Module/Articles.php:115
+msgid "Add Article"
+msgstr "Добавить статью"
-#: ../../Zotlabs/Module/Go.php:27
-msgid "Welcome"
-msgstr "Добро пожаловать"
+#: ../../Zotlabs/Module/Connect.php:73 ../../Zotlabs/Module/Connect.php:135
+msgid "Continue"
+msgstr "Продолжить"
-#: ../../Zotlabs/Module/Go.php:29
-msgid "What would you like to do?"
-msgstr "Что бы вы хотели сделать?"
+#: ../../Zotlabs/Module/Connect.php:104
+msgid "Premium Channel App"
+msgstr "Приложение \"Премиальный канал\""
-#: ../../Zotlabs/Module/Go.php:31
+#: ../../Zotlabs/Module/Connect.php:105
msgid ""
-"Please bookmark this page if you would like to return to it in the future"
-msgstr "Пожалуйста, запомните эту страницу если вы хотите вернуться на неё в будущем"
-
-#: ../../Zotlabs/Module/Go.php:35
-msgid "Upload a profile photo"
-msgstr "Загрузить фотографию профиля"
-
-#: ../../Zotlabs/Module/Go.php:36
-msgid "Upload a cover photo"
-msgstr "Загрузить фотографию обложки"
-
-#: ../../Zotlabs/Module/Go.php:37
-msgid "Edit your default profile"
-msgstr "Редактировать ваш профиль по умолчанию"
-
-#: ../../Zotlabs/Module/Go.php:38 ../../Zotlabs/Widget/Newmember.php:41
-msgid "View friend suggestions"
-msgstr "Просмотр рекомендуемых друзей"
-
-#: ../../Zotlabs/Module/Go.php:39
-msgid "View the channel directory"
-msgstr "Просмотр каталога каналов"
-
-#: ../../Zotlabs/Module/Go.php:40
-msgid "View/edit your channel settings"
-msgstr "Просмотреть / редактировать настройки вашего канала"
+"Allows you to set restrictions and terms on those that connect with your "
+"channel"
+msgstr "Позволяет установить ограничения и условия для подключающихся к вашему каналу"
-#: ../../Zotlabs/Module/Go.php:41
-msgid "View the site or project documentation"
-msgstr "Просмотр документации сайта / проекта"
+#: ../../Zotlabs/Module/Connect.php:116
+msgid "Premium Channel Setup"
+msgstr "Установка премиального канала"
-#: ../../Zotlabs/Module/Go.php:42
-msgid "Visit your channel homepage"
-msgstr "Посетить страницу вашего канала"
+#: ../../Zotlabs/Module/Connect.php:118
+msgid "Enable premium channel connection restrictions"
+msgstr "Включить ограничения для премиального канала"
-#: ../../Zotlabs/Module/Go.php:43
+#: ../../Zotlabs/Module/Connect.php:119
msgid ""
-"View your connections and/or add somebody whose address you already know"
-msgstr "Просмотреть ваши контакты и / или добавить кого-то чей адрес в уже знаете"
+"Please enter your restrictions or conditions, such as paypal receipt, usage "
+"guidelines, etc."
+msgstr "Пожалуйста введите ваши ограничения или условия, такие, как оплата PayPal, правила использования и т.п."
-#: ../../Zotlabs/Module/Go.php:44
+#: ../../Zotlabs/Module/Connect.php:121 ../../Zotlabs/Module/Connect.php:141
msgid ""
-"View your personal stream (this may be empty until you add some connections)"
-msgstr "Ваш персональный поток (может быть пуст пока вы не добавите контакты)"
-
-#: ../../Zotlabs/Module/Go.php:52
-msgid "View the public stream. Warning: this content is not moderated"
-msgstr "Просмотр публичного потока. Предупреждение: этот контент не модерируется"
-
-#: ../../Zotlabs/Module/Editwebpage.php:139
-msgid "Page link"
-msgstr "Ссылка страницы"
-
-#: ../../Zotlabs/Module/Editwebpage.php:166
-msgid "Edit Webpage"
-msgstr "Редактировать веб-страницу"
-
-#: ../../Zotlabs/Module/Manage.php:145
-msgid "Create a new channel"
-msgstr "Создать новый канал"
-
-#: ../../Zotlabs/Module/Manage.php:170 ../../Zotlabs/Lib/Apps.php:334
-#: ../../include/nav.php:92
-msgid "Channel Manager"
-msgstr "Менеджер каналов"
-
-#: ../../Zotlabs/Module/Manage.php:171
-msgid "Current Channel"
-msgstr "Текущий канал"
-
-#: ../../Zotlabs/Module/Manage.php:173
-msgid "Switch to one of your channels by selecting it."
-msgstr "Выбрать и переключиться на один из ваших каналов"
-
-#: ../../Zotlabs/Module/Manage.php:174
-msgid "Default Channel"
-msgstr "Основной канал"
-
-#: ../../Zotlabs/Module/Manage.php:175
-msgid "Make Default"
-msgstr "Сделать основным"
-
-#: ../../Zotlabs/Module/Manage.php:178
-#, php-format
-msgid "%d new messages"
-msgstr "%d новых сообщений"
-
-#: ../../Zotlabs/Module/Manage.php:179
-#, php-format
-msgid "%d new introductions"
-msgstr "%d новых представлений"
-
-#: ../../Zotlabs/Module/Manage.php:181
-msgid "Delegated Channel"
-msgstr "Делегированный канал"
-
-#: ../../Zotlabs/Module/Cards.php:51
-msgid "Cards App"
-msgstr "Приложение \"Карточки\""
-
-#: ../../Zotlabs/Module/Cards.php:52
-msgid "Create personal planning cards"
-msgstr "Создать личные карточки планирования"
-
-#: ../../Zotlabs/Module/Cards.php:112
-msgid "Add Card"
-msgstr "Добавить карточку"
-
-#: ../../Zotlabs/Module/Cards.php:207 ../../Zotlabs/Lib/Apps.php:325
-#: ../../include/nav.php:501
-msgid "Cards"
-msgstr "Карточки"
-
-#: ../../Zotlabs/Module/Dirsearch.php:33
-msgid "This directory server requires an access token"
-msgstr "Для доступа к этому серверу каталогов требуется токен"
-
-#: ../../Zotlabs/Module/Siteinfo.php:21
-msgid "About this site"
-msgstr "Об этом сайте"
-
-#: ../../Zotlabs/Module/Siteinfo.php:22
-msgid "Site Name"
-msgstr "Название сайта"
-
-#: ../../Zotlabs/Module/Siteinfo.php:26
-msgid "Administrator"
-msgstr "Администратор"
-
-#: ../../Zotlabs/Module/Siteinfo.php:28 ../../Zotlabs/Module/Register.php:236
-msgid "Terms of Service"
-msgstr "Условия предоставления услуг"
-
-#: ../../Zotlabs/Module/Siteinfo.php:29
-msgid "Software and Project information"
-msgstr "Информация о программном обеспечении и проекте"
-
-#: ../../Zotlabs/Module/Siteinfo.php:30
-msgid "This site is powered by $Projectname"
-msgstr "Этот сайт работает на $Projectname"
+"This channel may require additional steps or acknowledgement of the "
+"following conditions prior to connecting:"
+msgstr "Этот канал до подключения может требовать дополнительных шагов или подтверждений следующих условий:"
-#: ../../Zotlabs/Module/Siteinfo.php:31
+#: ../../Zotlabs/Module/Connect.php:122
msgid ""
-"Federated and decentralised networking and identity services provided by Zot"
-msgstr "Объединенные и децентрализованные сети и службы идентификациии обеспечиваются Zot"
-
-#: ../../Zotlabs/Module/Siteinfo.php:34
-msgid "Additional federated transport protocols:"
-msgstr "Дополнительные федеративные транспортные протоколы:"
-
-#: ../../Zotlabs/Module/Siteinfo.php:36
-#, php-format
-msgid "Version %s"
-msgstr "Версия %s"
-
-#: ../../Zotlabs/Module/Siteinfo.php:37
-msgid "Project homepage"
-msgstr "Домашняя страница проекта"
-
-#: ../../Zotlabs/Module/Siteinfo.php:38
-msgid "Developer homepage"
-msgstr "Домашняя страница разработчика"
-
-#: ../../Zotlabs/Module/Ratings.php:70
-msgid "No ratings"
-msgstr "Оценок нет"
-
-#: ../../Zotlabs/Module/Ratings.php:97 ../../Zotlabs/Module/Pubsites.php:35
-#: ../../include/conversation.php:1088
-msgid "Ratings"
-msgstr "Оценки"
-
-#: ../../Zotlabs/Module/Ratings.php:98
-msgid "Rating: "
-msgstr "Оценкa:"
+"Potential connections will then see the following text before proceeding:"
+msgstr "Потенциальные соединения будут видеть следующий предварительный текст:"
-#: ../../Zotlabs/Module/Ratings.php:99
-msgid "Website: "
-msgstr "Веб-сайт:"
+#: ../../Zotlabs/Module/Connect.php:123 ../../Zotlabs/Module/Connect.php:144
+msgid ""
+"By continuing, I certify that I have complied with any instructions provided "
+"on this page."
+msgstr "Продолжая, я подтверждаю что я выполнил все условия представленные на данной странице."
-#: ../../Zotlabs/Module/Ratings.php:101
-msgid "Description: "
-msgstr "Описание:"
+#: ../../Zotlabs/Module/Connect.php:132
+msgid "(No specific instructions have been provided by the channel owner.)"
+msgstr "(Владельцем канала не было представлено никаких специальных инструкций.)"
-#: ../../Zotlabs/Module/Webpages.php:48
-msgid "Webpages App"
-msgstr "Приложение \"Веб-страницы\""
+#: ../../Zotlabs/Module/Connect.php:140
+msgid "Restricted or Premium Channel"
+msgstr "Ограниченный или премиальный канал"
-#: ../../Zotlabs/Module/Webpages.php:49
-msgid "Provide managed web pages on your channel"
-msgstr "Предоставлять управляемые веб-страницы на Вашем канале"
+#: ../../Zotlabs/Module/Cloud.php:123
+msgid "Not found"
+msgstr "Не найдено."
-#: ../../Zotlabs/Module/Webpages.php:69
-msgid "Import Webpage Elements"
-msgstr "Импортировать части веб-страницы"
+#: ../../Zotlabs/Module/Cloud.php:129
+msgid "Please refresh page"
+msgstr "Пожалуйста обновите страницу"
-#: ../../Zotlabs/Module/Webpages.php:70
-msgid "Import selected"
-msgstr "Импортировать выбранное"
+#: ../../Zotlabs/Module/Cloud.php:132
+msgid "Unknown error"
+msgstr "Неизвестная ошибка"
-#: ../../Zotlabs/Module/Webpages.php:93
-msgid "Export Webpage Elements"
-msgstr "Экспортировать часть веб-страницы"
+#: ../../Zotlabs/Module/Pdledit.php:26
+msgid "Layout updated."
+msgstr "Шаблон обновлен."
-#: ../../Zotlabs/Module/Webpages.php:94
-msgid "Export selected"
-msgstr "Экспортировать выбранное"
+#: ../../Zotlabs/Module/Pdledit.php:42
+msgid "PDL Editor App"
+msgstr "Приложение \"Редактор PDL\""
-#: ../../Zotlabs/Module/Webpages.php:252 ../../Zotlabs/Lib/Apps.php:338
-#: ../../include/nav.php:524
-msgid "Webpages"
-msgstr "Веб-страницы"
+#: ../../Zotlabs/Module/Pdledit.php:43
+msgid "Provides the ability to edit system page layouts"
+msgstr "Предоставляет возможность редактировать макеты системных страниц"
-#: ../../Zotlabs/Module/Webpages.php:263
-msgid "Actions"
-msgstr "Действия"
+#: ../../Zotlabs/Module/Pdledit.php:56 ../../Zotlabs/Module/Pdledit.php:99
+msgid "Edit System Page Description"
+msgstr "Редактировать описание системной страницы"
-#: ../../Zotlabs/Module/Webpages.php:264
-msgid "Page Link"
-msgstr "Ссылка страницы"
+#: ../../Zotlabs/Module/Pdledit.php:77
+msgid "(modified)"
+msgstr "(изменено)"
-#: ../../Zotlabs/Module/Webpages.php:265
-msgid "Page Title"
-msgstr "Заголовок страницы"
+#: ../../Zotlabs/Module/Pdledit.php:94
+msgid "Layout not found."
+msgstr "Шаблон не найден."
-#: ../../Zotlabs/Module/Webpages.php:295
-msgid "Invalid file type."
-msgstr "Неверный тип файла."
+#: ../../Zotlabs/Module/Pdledit.php:100
+msgid "Module Name:"
+msgstr "Имя модуля:"
-#: ../../Zotlabs/Module/Webpages.php:307
-msgid "Error opening zip file"
-msgstr "Ошибка открытия ZIP файла"
+#: ../../Zotlabs/Module/Pdledit.php:101
+msgid "Layout Help"
+msgstr "Помощь к шаблону"
-#: ../../Zotlabs/Module/Webpages.php:318
-msgid "Invalid folder path."
-msgstr "Неверный путь к каталогу."
+#: ../../Zotlabs/Module/Pdledit.php:102
+msgid "Edit another layout"
+msgstr "Редактировать другой шаблон"
-#: ../../Zotlabs/Module/Webpages.php:345
-msgid "No webpage elements detected."
-msgstr "Не обнаружено частей веб-страницы."
+#: ../../Zotlabs/Module/Pdledit.php:103
+msgid "System layout"
+msgstr "Системный шаблон"
-#: ../../Zotlabs/Module/Webpages.php:420
-msgid "Import complete."
-msgstr "Импорт завершен."
+#: ../../Zotlabs/Module/Affinity.php:35
+msgid "Affinity Tool settings updated."
+msgstr "Настройки степени сходства обновлены."
-#: ../../Zotlabs/Module/Changeaddr.php:35
+#: ../../Zotlabs/Module/Affinity.php:47
msgid ""
-"Channel name changes are not allowed within 48 hours of changing the account "
-"password."
-msgstr "Изменение названия канала не разрешается в течении 48 часов после смены пароля у аккаунта."
+"This app presents a slider control in your connection editor and also on "
+"your network page. The slider represents your degree of friendship "
+"(affinity) with each connection. It allows you to zoom in or out and display "
+"conversations from only your closest friends or everybody in your stream."
+msgstr "Это приложение представляет управление ползунком на странице контактов и сетевом потоке, который позволяет выбирать вашу степень дружбы (сходства). Это позволяет вам увеличивать или уменьшать масштаб и отображать разговоры только от ваших самых близких друзей или всех в вашем потоке."
-#: ../../Zotlabs/Module/Changeaddr.php:46 ../../include/channel.php:222
-#: ../../include/channel.php:655
-msgid "Reserved nickname. Please choose another."
-msgstr "Зарезервированый псевдоним. Пожалуйста, выберите другой."
+#: ../../Zotlabs/Module/Affinity.php:52
+msgid "Affinity Tool App"
+msgstr "Приложение \"Степень сходства\""
-#: ../../Zotlabs/Module/Changeaddr.php:51 ../../include/channel.php:227
-#: ../../include/channel.php:660
+#: ../../Zotlabs/Module/Affinity.php:57
msgid ""
-"Nickname has unsupported characters or is already being used on this site."
-msgstr "Псевдоним имеет недопустимые символы или уже используется на этом сайте."
-
-#: ../../Zotlabs/Module/Changeaddr.php:77
-msgid "Change channel nickname/address"
-msgstr "Изменить псевдоним / адрес канала"
-
-#: ../../Zotlabs/Module/Changeaddr.php:78
-msgid "Any/all connections on other networks will be lost!"
-msgstr "Любые / все контакты в других сетях будут утеряны!"
-
-#: ../../Zotlabs/Module/Changeaddr.php:80
-msgid "New channel address"
-msgstr "Новый адрес канала"
-
-#: ../../Zotlabs/Module/Changeaddr.php:81
-msgid "Rename Channel"
-msgstr "Переименовать канал"
+"The numbers below represent the minimum and maximum slider default positions "
+"for your network/stream page as a percentage."
+msgstr "Числа ниже представляют минимальное и максимальное значение по умолчанию для вашей сети / потока в процентах."
-#: ../../Zotlabs/Module/Editpost.php:38 ../../Zotlabs/Module/Editpost.php:43
-msgid "Item is not editable"
-msgstr "Элемент нельзя редактировать"
+#: ../../Zotlabs/Module/Affinity.php:64
+msgid "Default maximum affinity level"
+msgstr "Максимальная степень сходства по умолчанию."
-#: ../../Zotlabs/Module/Editpost.php:108 ../../Zotlabs/Module/Rpost.php:144
-msgid "Edit post"
-msgstr "Редактировать сообщение"
+#: ../../Zotlabs/Module/Affinity.php:64
+msgid "0-99 default 99"
+msgstr "0-99 (по умолчанию 99)"
-#: ../../Zotlabs/Module/Dreport.php:56
-msgid "Invalid message"
-msgstr "Неверное сообщение"
+#: ../../Zotlabs/Module/Affinity.php:70
+msgid "Default minimum affinity level"
+msgstr "Максимальная степень сходства по умолчанию."
-#: ../../Zotlabs/Module/Dreport.php:90
-msgid "no results"
-msgstr "Ничего не найдено."
+#: ../../Zotlabs/Module/Affinity.php:70
+msgid "0-99 - default 0"
+msgstr "0-99 (по умолчанию 0)"
-#: ../../Zotlabs/Module/Dreport.php:104
-msgid "channel sync processed"
-msgstr "синхронизация канала завершена"
+#: ../../Zotlabs/Module/Affinity.php:76
+msgid "Persistent affinity levels"
+msgstr "Устоявшиеся степени сходства"
-#: ../../Zotlabs/Module/Dreport.php:108
-msgid "queued"
-msgstr "в очереди"
+#: ../../Zotlabs/Module/Affinity.php:76
+msgid ""
+"If disabled the max and min levels will be reset to default after page reload"
+msgstr "Если этот параметр отключен, максимальный и минимальный уровни будут сброшены к значениям по умолчанию после перезагрузки страницы"
-#: ../../Zotlabs/Module/Dreport.php:112
-msgid "posted"
-msgstr "опубликовано"
+#: ../../Zotlabs/Module/Affinity.php:84
+msgid "Affinity Tool Settings"
+msgstr "Настройки степени сходства"
-#: ../../Zotlabs/Module/Dreport.php:116
-msgid "accepted for delivery"
-msgstr "принято к доставке"
+#: ../../Zotlabs/Module/Wiki.php:35
+#: ../../extend/addon/hzaddons/flashcards/Mod_Flashcards.php:34
+#: ../../extend/addon/hzaddons/cart/cart.php:1298
+msgid "Profile Unavailable."
+msgstr "Профиль недоступен."
-#: ../../Zotlabs/Module/Dreport.php:120
-msgid "updated"
-msgstr "обновлено"
+#: ../../Zotlabs/Module/Wiki.php:52
+msgid "Wiki App"
+msgstr "Приложение \"Wiki\""
-#: ../../Zotlabs/Module/Dreport.php:123
-msgid "update ignored"
-msgstr "обновление игнорируется"
+#: ../../Zotlabs/Module/Wiki.php:53
+msgid "Provide a wiki for your channel"
+msgstr "Предоставьте Wiki для вашего канала"
-#: ../../Zotlabs/Module/Dreport.php:126
-msgid "permission denied"
-msgstr "доступ запрещен"
+#: ../../Zotlabs/Module/Wiki.php:77
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:456
+#: ../../extend/addon/hzaddons/cart/myshop.php:37
+#: ../../extend/addon/hzaddons/cart/manual_payments.php:93
+#: ../../extend/addon/hzaddons/cart/cart.php:1444
+msgid "Invalid channel"
+msgstr "Недействительный канал"
-#: ../../Zotlabs/Module/Dreport.php:130
-msgid "recipient not found"
-msgstr "получатель не найден"
+#: ../../Zotlabs/Module/Wiki.php:133
+msgid "Error retrieving wiki"
+msgstr "Ошибка при получении Wiki"
-#: ../../Zotlabs/Module/Dreport.php:133
-msgid "mail recalled"
-msgstr "почта отозвана"
+#: ../../Zotlabs/Module/Wiki.php:140
+msgid "Error creating zip file export folder"
+msgstr "Ошибка при создании zip-файла при экспорте каталога"
-#: ../../Zotlabs/Module/Dreport.php:136
-msgid "duplicate mail received"
-msgstr "получено дублирующее сообщение"
+#: ../../Zotlabs/Module/Wiki.php:191
+msgid "Error downloading wiki: "
+msgstr "Ошибка загрузки Wiki:"
-#: ../../Zotlabs/Module/Dreport.php:139
-msgid "mail delivered"
-msgstr "почта доставлен"
+#: ../../Zotlabs/Module/Wiki.php:212
+msgid "Download"
+msgstr "Загрузить"
-#: ../../Zotlabs/Module/Dreport.php:159
-#, php-format
-msgid "Delivery report for %1$s"
-msgstr "Отчёт о доставке для %1$s"
+#: ../../Zotlabs/Module/Wiki.php:216
+msgid "Wiki name"
+msgstr "Название Wiki"
-#: ../../Zotlabs/Module/Dreport.php:162 ../../Zotlabs/Widget/Wiki_pages.php:41
-#: ../../Zotlabs/Widget/Wiki_pages.php:98
-msgid "Options"
-msgstr "Параметры"
+#: ../../Zotlabs/Module/Wiki.php:217
+msgid "Content type"
+msgstr "Тип содержимого"
-#: ../../Zotlabs/Module/Dreport.php:163
-msgid "Redeliver"
-msgstr "Доставить повторно"
+#: ../../Zotlabs/Module/Wiki.php:220
+msgid "Any&nbsp;type"
+msgstr "Любой&nbsp;тип"
-#: ../../Zotlabs/Module/Sources.php:41
-msgid "Failed to create source. No channel selected."
-msgstr "Не удалось создать источник. Канал не выбран."
+#: ../../Zotlabs/Module/Wiki.php:227
+msgid "Lock content type"
+msgstr "Зафиксировать тип содержимого"
-#: ../../Zotlabs/Module/Sources.php:57
-msgid "Source created."
-msgstr "Источник создан."
+#: ../../Zotlabs/Module/Wiki.php:228
+msgid "Create a status post for this wiki"
+msgstr "Создать публикацию о статусе этой Wiki"
-#: ../../Zotlabs/Module/Sources.php:70
-msgid "Source updated."
-msgstr "Источник обновлен."
+#: ../../Zotlabs/Module/Wiki.php:229
+msgid "Edit Wiki Name"
+msgstr "Редактировать наименование Wiki"
-#: ../../Zotlabs/Module/Sources.php:88
-msgid "Sources App"
-msgstr "Приложение \"Источники канала\""
+#: ../../Zotlabs/Module/Wiki.php:274
+msgid "Wiki not found"
+msgstr "Wiki не найдена"
-#: ../../Zotlabs/Module/Sources.php:89
-msgid "Automatically import channel content from other channels or feeds"
-msgstr "Автоматический импорт контента из других каналов или лент"
+#: ../../Zotlabs/Module/Wiki.php:300
+msgid "Rename page"
+msgstr "Переименовать страницу"
-#: ../../Zotlabs/Module/Sources.php:101
-msgid "*"
-msgstr ""
+#: ../../Zotlabs/Module/Wiki.php:321
+msgid "Error retrieving page content"
+msgstr "Ошибка при получении содержимого страницы"
-#: ../../Zotlabs/Module/Sources.php:107 ../../Zotlabs/Lib/Apps.php:366
-msgid "Channel Sources"
-msgstr "Источники канала"
+#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331
+msgid "New page"
+msgstr "Новая страница"
-#: ../../Zotlabs/Module/Sources.php:108
-msgid "Manage remote sources of content for your channel."
-msgstr "Управление удалённым источниками содержимого для вашего канала"
+#: ../../Zotlabs/Module/Wiki.php:366
+msgid "Revision Comparison"
+msgstr "Сравнение ревизий"
-#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:119
-msgid "New Source"
-msgstr "Новый источник"
+#: ../../Zotlabs/Module/Wiki.php:367
+#: ../../Zotlabs/Widget/Wiki_page_history.php:25
+#: ../../Zotlabs/Lib/NativeWikiPage.php:564
+msgid "Revert"
+msgstr "Отменить"
-#: ../../Zotlabs/Module/Sources.php:120 ../../Zotlabs/Module/Sources.php:154
-msgid ""
-"Import all or selected content from the following channel into this channel "
-"and distribute it according to your channel settings."
-msgstr "Импортировать всё или выбранное содержимое из следующего канала в этот канал и распределить его в соответствии с вашими настройками."
+#: ../../Zotlabs/Module/Wiki.php:374
+msgid "Short description of your changes (optional)"
+msgstr "Краткое описание ваших изменений (необязательно)"
-#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155
-msgid "Only import content with these words (one per line)"
-msgstr "Импортировать содержимое только с этим текстом (построчно)"
+#: ../../Zotlabs/Module/Wiki.php:384
+msgid "Source"
+msgstr "Источник"
-#: ../../Zotlabs/Module/Sources.php:121 ../../Zotlabs/Module/Sources.php:155
-msgid "Leave blank to import all public content"
-msgstr "Оставьте пустым для импорта всего общедоступного содержимого"
+#: ../../Zotlabs/Module/Wiki.php:394
+msgid "New page name"
+msgstr "Новое имя страницы"
-#: ../../Zotlabs/Module/Sources.php:122 ../../Zotlabs/Module/Sources.php:161
-msgid "Channel Name"
-msgstr "Название канала"
+#: ../../Zotlabs/Module/Wiki.php:399
+msgid "Embed image from photo albums"
+msgstr "Встроить изображение из фотоальбома"
-#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158
-msgid ""
-"Add the following categories to posts imported from this source (comma "
-"separated)"
-msgstr "Добавить следующие категории к импортированным публикациям из этого источника (через запятые)"
+#: ../../Zotlabs/Module/Wiki.php:410
+msgid "History"
+msgstr "История"
-#: ../../Zotlabs/Module/Sources.php:123 ../../Zotlabs/Module/Sources.php:158
-#: ../../Zotlabs/Module/Oauth.php:117
-msgid "Optional"
-msgstr "Необязательно"
+#: ../../Zotlabs/Module/Wiki.php:488
+msgid "Error creating wiki. Invalid name."
+msgstr "Ошибка создания Wiki. Неверное имя."
-#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
-msgid "Resend posts with this channel as author"
-msgstr "Отправить публикации в этот канал повторно как автор"
+#: ../../Zotlabs/Module/Wiki.php:495
+msgid "A wiki with this name already exists."
+msgstr "Wiki с таким именем уже существует."
-#: ../../Zotlabs/Module/Sources.php:124 ../../Zotlabs/Module/Sources.php:159
-msgid "Copyrights may apply"
-msgstr "Могут применяться авторские права"
+#: ../../Zotlabs/Module/Wiki.php:508
+msgid "Wiki created, but error creating Home page."
+msgstr "Wiki создана, но возникла ошибка при создании домашней страницы"
-#: ../../Zotlabs/Module/Sources.php:144 ../../Zotlabs/Module/Sources.php:174
-msgid "Source not found."
-msgstr "Источник не найден."
+#: ../../Zotlabs/Module/Wiki.php:515
+msgid "Error creating wiki"
+msgstr "Ошибка при создании Wiki"
-#: ../../Zotlabs/Module/Sources.php:151
-msgid "Edit Source"
-msgstr "Редактировать источник"
+#: ../../Zotlabs/Module/Wiki.php:539
+msgid "Error updating wiki. Invalid name."
+msgstr "Ошибка при обновлении Wiki. Неверное имя."
-#: ../../Zotlabs/Module/Sources.php:152
-msgid "Delete Source"
-msgstr "Удалить источник"
+#: ../../Zotlabs/Module/Wiki.php:559
+msgid "Error updating wiki"
+msgstr "Ошибка при обновлении Wiki"
-#: ../../Zotlabs/Module/Sources.php:182
-msgid "Source removed"
-msgstr "Источник удален"
+#: ../../Zotlabs/Module/Wiki.php:574
+msgid "Wiki delete permission denied."
+msgstr "Нет прав на удаление Wiki."
-#: ../../Zotlabs/Module/Sources.php:184
-msgid "Unable to remove source."
-msgstr "Невозможно удалить источник."
+#: ../../Zotlabs/Module/Wiki.php:584
+msgid "Error deleting wiki"
+msgstr "Ошибка удаления Wiki"
-#: ../../Zotlabs/Module/Like.php:56
-msgid "Like/Dislike"
-msgstr "Нравится / не нравится"
+#: ../../Zotlabs/Module/Wiki.php:617
+msgid "New page created"
+msgstr "Создана новая страница"
-#: ../../Zotlabs/Module/Like.php:61
-msgid "This action is restricted to members."
-msgstr "Это действие доступно только участникам."
+#: ../../Zotlabs/Module/Wiki.php:739
+msgid "Cannot delete Home"
+msgstr "Невозможно удалить домашнюю страницу"
-#: ../../Zotlabs/Module/Like.php:62
-msgid ""
-"Please <a href=\"rmagic\">login with your $Projectname ID</a> or <a href="
-"\"register\">register as a new $Projectname member</a> to continue."
-msgstr "Пожалуйста, для продолжения <a href=\"rmagic\"> войдите с вашим $Projectname ID</a> или <a href=\"register\">зарегистрируйтесь как новый участник $Projectname</a>."
+#: ../../Zotlabs/Module/Wiki.php:803
+msgid "Current Revision"
+msgstr "Текущая ревизия"
-#: ../../Zotlabs/Module/Like.php:111 ../../Zotlabs/Module/Like.php:137
-#: ../../Zotlabs/Module/Like.php:175
-msgid "Invalid request."
-msgstr "Неверный запрос."
+#: ../../Zotlabs/Module/Wiki.php:803
+msgid "Selected Revision"
+msgstr "Выбранная ревизия"
-#: ../../Zotlabs/Module/Like.php:123 ../../include/conversation.php:122
-msgid "channel"
-msgstr "канал"
+#: ../../Zotlabs/Module/Wiki.php:853
+msgid "You must be authenticated."
+msgstr "Вы должны быть аутентифицированы."
-#: ../../Zotlabs/Module/Like.php:152
-msgid "thing"
-msgstr "предмет"
+#: ../../Zotlabs/Module/Email_resend.php:30
+msgid "Email verification resent"
+msgstr "Сообщение для проверки email отправлено повторно"
-#: ../../Zotlabs/Module/Like.php:198
-msgid "Channel unavailable."
-msgstr "Канал недоступен."
+#: ../../Zotlabs/Module/Email_resend.php:33
+msgid "Unable to resend email verification message."
+msgstr "Невозможно повторно отправить сообщение для проверки email"
-#: ../../Zotlabs/Module/Like.php:246
-msgid "Previous action reversed."
-msgstr "Предыдущее действие отменено."
+#: ../../Zotlabs/Module/Filer.php:52
+msgid "Enter a folder name"
+msgstr "Введите название каталога"
-#: ../../Zotlabs/Module/Like.php:447 ../../Zotlabs/Lib/Activity.php:1994
-#: ../../addon/diaspora/Receiver.php:1491 ../../addon/pubcrawl/as.php:1540
-#: ../../include/conversation.php:160
-#, php-format
-msgid "%1$s likes %2$s's %3$s"
-msgstr "%1$s нравится %3$s %2$s"
+#: ../../Zotlabs/Module/Filer.php:52
+msgid "or select an existing folder (doubleclick)"
+msgstr "или выберите существующий каталог (двойной щелчок)"
-#: ../../Zotlabs/Module/Like.php:449 ../../Zotlabs/Lib/Activity.php:1996
-#: ../../addon/pubcrawl/as.php:1542 ../../include/conversation.php:163
-#, php-format
-msgid "%1$s doesn't like %2$s's %3$s"
-msgstr "%1$s не нравится %2$s %3$s"
+#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Lib/ThreadItem.php:181
+msgid "Save to Folder"
+msgstr "Сохранить в каталог"
-#: ../../Zotlabs/Module/Like.php:451
-#, php-format
-msgid "%1$s agrees with %2$s's %3$s"
-msgstr "%1$s согласен с %2$s %3$s"
+#: ../../Zotlabs/Module/Manage.php:145
+msgid "Create a new channel"
+msgstr "Создать новый канал"
-#: ../../Zotlabs/Module/Like.php:453
-#, php-format
-msgid "%1$s doesn't agree with %2$s's %3$s"
-msgstr "%1$s не согласен с %2$s %3$s"
+#: ../../Zotlabs/Module/Manage.php:171
+msgid "Current Channel"
+msgstr "Текущий канал"
-#: ../../Zotlabs/Module/Like.php:455
-#, php-format
-msgid "%1$s abstains from a decision on %2$s's %3$s"
-msgstr "%1$s воздерживается от решения по %2$s%3$s"
+#: ../../Zotlabs/Module/Manage.php:173
+msgid "Switch to one of your channels by selecting it."
+msgstr "Выбрать и переключиться на один из ваших каналов"
-#: ../../Zotlabs/Module/Like.php:457 ../../addon/diaspora/Receiver.php:2137
-#, php-format
-msgid "%1$s is attending %2$s's %3$s"
-msgstr "%1$s посещает %2$s%3$s"
+#: ../../Zotlabs/Module/Manage.php:174
+msgid "Default Channel"
+msgstr "Основной канал"
-#: ../../Zotlabs/Module/Like.php:459 ../../addon/diaspora/Receiver.php:2139
-#, php-format
-msgid "%1$s is not attending %2$s's %3$s"
-msgstr "%1$s не посещает %2$s%3$s"
+#: ../../Zotlabs/Module/Manage.php:175
+msgid "Make Default"
+msgstr "Сделать основным"
-#: ../../Zotlabs/Module/Like.php:461 ../../addon/diaspora/Receiver.php:2141
+#: ../../Zotlabs/Module/Manage.php:178
#, php-format
-msgid "%1$s may attend %2$s's %3$s"
-msgstr "%1$s может посетить %2$s%3$s"
-
-#: ../../Zotlabs/Module/Like.php:572
-msgid "Action completed."
-msgstr "Действие завершено."
-
-#: ../../Zotlabs/Module/Like.php:573
-msgid "Thank you."
-msgstr "Спасибо."
-
-#: ../../Zotlabs/Module/Directory.php:110
-msgid "No default suggestions were found."
-msgstr "Предложений по умолчанию не найдено."
+msgid "%d new messages"
+msgstr "%d новых сообщений"
-#: ../../Zotlabs/Module/Directory.php:259
+#: ../../Zotlabs/Module/Manage.php:179
#, php-format
-msgid "%d rating"
-msgid_plural "%d ratings"
-msgstr[0] "%d оценка"
-msgstr[1] "%d оценки"
-msgstr[2] "%d оценок"
-
-#: ../../Zotlabs/Module/Directory.php:270
-msgid "Gender: "
-msgstr "Пол:"
-
-#: ../../Zotlabs/Module/Directory.php:272
-msgid "Status: "
-msgstr "Статус:"
-
-#: ../../Zotlabs/Module/Directory.php:274
-msgid "Homepage: "
-msgstr "Домашняя страница:"
-
-#: ../../Zotlabs/Module/Directory.php:323 ../../include/channel.php:1620
-msgid "Age:"
-msgstr "Возраст:"
-
-#: ../../Zotlabs/Module/Directory.php:328 ../../include/channel.php:1447
-#: ../../include/event.php:58 ../../include/event.php:90
-msgid "Location:"
-msgstr "Местоположение:"
-
-#: ../../Zotlabs/Module/Directory.php:334
-msgid "Description:"
-msgstr "Описание:"
-
-#: ../../Zotlabs/Module/Directory.php:339 ../../include/channel.php:1649
-msgid "Hometown:"
-msgstr "Родной город:"
-
-#: ../../Zotlabs/Module/Directory.php:341 ../../include/channel.php:1655
-msgid "About:"
-msgstr "О себе:"
-
-#: ../../Zotlabs/Module/Directory.php:342 ../../Zotlabs/Module/Suggest.php:71
-#: ../../Zotlabs/Widget/Follow.php:32 ../../Zotlabs/Widget/Suggestions.php:44
-#: ../../include/conversation.php:1058 ../../include/channel.php:1432
-#: ../../include/connections.php:110
-msgid "Connect"
-msgstr "Подключить"
-
-#: ../../Zotlabs/Module/Directory.php:343
-msgid "Public Forum:"
-msgstr "Публичный форум:"
-
-#: ../../Zotlabs/Module/Directory.php:346
-msgid "Keywords: "
-msgstr "Ключевые слова:"
-
-#: ../../Zotlabs/Module/Directory.php:349
-msgid "Don't suggest"
-msgstr "Не предлагать"
-
-#: ../../Zotlabs/Module/Directory.php:351
-msgid "Common connections (estimated):"
-msgstr "Общие контакты (оценочно):"
-
-#: ../../Zotlabs/Module/Directory.php:400
-msgid "Global Directory"
-msgstr "Глобальный каталог"
-
-#: ../../Zotlabs/Module/Directory.php:400
-msgid "Local Directory"
-msgstr "Локальный каталог"
-
-#: ../../Zotlabs/Module/Directory.php:406
-msgid "Finding:"
-msgstr "Поиск:"
-
-#: ../../Zotlabs/Module/Directory.php:409 ../../Zotlabs/Module/Suggest.php:79
-#: ../../include/contact_widgets.php:24
-msgid "Channel Suggestions"
-msgstr "Рекомендации каналов"
-
-#: ../../Zotlabs/Module/Directory.php:411
-msgid "next page"
-msgstr "следующая страница"
-
-#: ../../Zotlabs/Module/Directory.php:411
-msgid "previous page"
-msgstr "предыдущая страница"
-
-#: ../../Zotlabs/Module/Directory.php:412
-msgid "Sort options"
-msgstr "Параметры сортировки"
-
-#: ../../Zotlabs/Module/Directory.php:413
-msgid "Alphabetic"
-msgstr "По алфавиту"
-
-#: ../../Zotlabs/Module/Directory.php:414
-msgid "Reverse Alphabetic"
-msgstr "Против алфавита"
-
-#: ../../Zotlabs/Module/Directory.php:415
-msgid "Newest to Oldest"
-msgstr "От новых к старым"
-
-#: ../../Zotlabs/Module/Directory.php:416
-msgid "Oldest to Newest"
-msgstr "От старых к новым"
-
-#: ../../Zotlabs/Module/Directory.php:433
-msgid "No entries (some entries may be hidden)."
-msgstr "Нет записей (некоторые записи могут быть скрыты)."
-
-#: ../../Zotlabs/Module/Xchan.php:10
-msgid "Xchan Lookup"
-msgstr "Поиск Xchan"
+msgid "%d new introductions"
+msgstr "%d новых представлений"
-#: ../../Zotlabs/Module/Xchan.php:13
-msgid "Lookup xchan beginning with (or webbie): "
-msgstr "Запрос Xchan начинается с (или webbie):"
+#: ../../Zotlabs/Module/Manage.php:181
+msgid "Delegated Channel"
+msgstr "Делегированный канал"
#: ../../Zotlabs/Module/Suggest.php:40
msgid "Suggest Channels App"
@@ -7352,1195 +10656,1024 @@ msgid ""
"hours."
msgstr "Нет предложений. Если это новый сайт, повторите попытку через 24 часа."
-#: ../../Zotlabs/Module/Suggest.php:73 ../../Zotlabs/Widget/Suggestions.php:46
+#: ../../Zotlabs/Module/Suggest.php:73 ../../Zotlabs/Widget/Suggestions.php:48
msgid "Ignore/Hide"
msgstr "Игнорировать / cкрыть"
-#: ../../Zotlabs/Module/Oexchange.php:27
-msgid "Unable to find your hub."
-msgstr "Невозможно найти ваш сервер"
-
-#: ../../Zotlabs/Module/Oexchange.php:41
-msgid "Post successful."
-msgstr "Успешно опубликовано."
-
-#: ../../Zotlabs/Module/Mail.php:73
-msgid "Unable to lookup recipient."
-msgstr "Не удалось найти получателя."
-
-#: ../../Zotlabs/Module/Mail.php:80
-msgid "Unable to communicate with requested channel."
-msgstr "Не удалось установить связь с запрашиваемым каналом."
-
-#: ../../Zotlabs/Module/Mail.php:87
-msgid "Cannot verify requested channel."
-msgstr "Не удалось установить подлинность требуемого канала."
-
-#: ../../Zotlabs/Module/Mail.php:105
-msgid "Selected channel has private message restrictions. Send failed."
-msgstr "Выбранный канал ограничивает частные сообщения. Отправка не удалась."
-
-#: ../../Zotlabs/Module/Mail.php:160
-msgid "Messages"
-msgstr "Сообщения"
-
-#: ../../Zotlabs/Module/Mail.php:173
-msgid "message"
-msgstr "сообщение"
-
-#: ../../Zotlabs/Module/Mail.php:214
-msgid "Message recalled."
-msgstr "Сообщение отозванно."
+#: ../../Zotlabs/Module/Import.php:68 ../../Zotlabs/Module/Import_items.php:48
+msgid "Nothing to import."
+msgstr "Ничего импортировать."
-#: ../../Zotlabs/Module/Mail.php:227
-msgid "Conversation removed."
-msgstr "Беседа удалена."
+#: ../../Zotlabs/Module/Import.php:83 ../../Zotlabs/Module/Import.php:99
+#: ../../Zotlabs/Module/Import_items.php:72
+msgid "Unable to download data from old server"
+msgstr "Невозможно загрузить данные со старого сервера"
-#: ../../Zotlabs/Module/Mail.php:242 ../../Zotlabs/Module/Mail.php:363
-msgid "Expires YYYY-MM-DD HH:MM"
-msgstr "Истекает YYYY-MM-DD HH:MM"
+#: ../../Zotlabs/Module/Import.php:106 ../../Zotlabs/Module/Import_items.php:77
+msgid "Imported file is empty."
+msgstr "Импортированный файл пуст."
-#: ../../Zotlabs/Module/Mail.php:270
-msgid "Requested channel is not in this network"
-msgstr "Запрашиваемый канал не доступен."
+#: ../../Zotlabs/Module/Import.php:157
+#, php-format
+msgid "Your service plan only allows %d channels."
+msgstr "Ваш класс обслуживания разрешает только %d каналов."
-#: ../../Zotlabs/Module/Mail.php:278
-msgid "Send Private Message"
-msgstr "Отправить личное сообщение"
+#: ../../Zotlabs/Module/Import.php:184
+msgid "No channel. Import failed."
+msgstr "Канала нет. Импорт невозможен."
-#: ../../Zotlabs/Module/Mail.php:279 ../../Zotlabs/Module/Mail.php:421
-msgid "To:"
-msgstr "Кому:"
+#: ../../Zotlabs/Module/Import.php:559
+#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:141
+msgid "Import completed."
+msgstr "Импорт завершен."
-#: ../../Zotlabs/Module/Mail.php:282 ../../Zotlabs/Module/Mail.php:423
-msgid "Subject:"
-msgstr "Тема:"
+#: ../../Zotlabs/Module/Import.php:587
+msgid "You must be logged in to use this feature."
+msgstr "Вы должны войти в систему, чтобы использовать эту функцию."
-#: ../../Zotlabs/Module/Mail.php:287 ../../Zotlabs/Module/Mail.php:429
-msgid "Attach file"
-msgstr "Прикрепить файл"
+#: ../../Zotlabs/Module/Import.php:592
+msgid "Import Channel"
+msgstr "Импортировать канал"
-#: ../../Zotlabs/Module/Mail.php:289
-msgid "Send"
-msgstr "Отправить"
+#: ../../Zotlabs/Module/Import.php:593
+msgid ""
+"Use this form to import an existing channel from a different server/hub. You "
+"may retrieve the channel identity from the old server/hub via the network or "
+"provide an export file."
+msgstr "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта."
-#: ../../Zotlabs/Module/Mail.php:292 ../../Zotlabs/Module/Mail.php:434
-#: ../../addon/hsse/hsse.php:250 ../../include/conversation.php:1456
-msgid "Set expiration date"
-msgstr "Установить срок действия"
+#: ../../Zotlabs/Module/Import.php:594
+#: ../../Zotlabs/Module/Import_items.php:127
+msgid "File to Upload"
+msgstr "Файл для загрузки"
-#: ../../Zotlabs/Module/Mail.php:393
-msgid "Delete message"
-msgstr "Удалить сообщение"
+#: ../../Zotlabs/Module/Import.php:595
+msgid "Or provide the old server/hub details"
+msgstr "или предоставьте данные старого сервера"
-#: ../../Zotlabs/Module/Mail.php:394
-msgid "Delivery report"
-msgstr "Отчёт о доставке"
+#: ../../Zotlabs/Module/Import.php:597
+msgid "Your old identity address (xyz@example.com)"
+msgstr "Ваш старый адрес канала (xyz@example.com)"
-#: ../../Zotlabs/Module/Mail.php:395
-msgid "Recall message"
-msgstr "Отозвать сообщение"
+#: ../../Zotlabs/Module/Import.php:598
+msgid "Your old login email address"
+msgstr "Ваш старый адрес электронной почты"
-#: ../../Zotlabs/Module/Mail.php:397
-msgid "Message has been recalled."
-msgstr "Сообщение отозванно"
+#: ../../Zotlabs/Module/Import.php:599
+msgid "Your old login password"
+msgstr "Ваш старый пароль"
-#: ../../Zotlabs/Module/Mail.php:414
-msgid "Delete Conversation"
-msgstr "Удалить беседу"
+#: ../../Zotlabs/Module/Import.php:600
+msgid "Import a few months of posts if possible (limited by available memory"
+msgstr "Импортировать несколько месяцев публикаций если возможно (ограничено доступной памятью)"
-#: ../../Zotlabs/Module/Mail.php:416
+#: ../../Zotlabs/Module/Import.php:602
msgid ""
-"No secure communications available. You <strong>may</strong> be able to "
-"respond from the sender's profile page."
-msgstr "Безопасная связь недоступна. Вы <strong>можете</strong> попытаться ответить со страницы профиля отправителя."
+"For either option, please choose whether to make this hub your new primary "
+"address, or whether your old location should continue this role. You will be "
+"able to post from either location, but only one can be marked as the primary "
+"location for files, photos, and media."
+msgstr "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа."
-#: ../../Zotlabs/Module/Mail.php:420
-msgid "Send Reply"
-msgstr "Отправить ответ"
+#: ../../Zotlabs/Module/Import.php:604
+msgid "Make this hub my primary location"
+msgstr "Сделать этот хаб главным"
-#: ../../Zotlabs/Module/Mail.php:425
-#, php-format
-msgid "Your message for %s (%s):"
-msgstr "Ваше сообщение для %s (%s):"
+#: ../../Zotlabs/Module/Import.php:605
+msgid "Move this channel (disable all previous locations)"
+msgstr "Переместить это канал (отключить все предыдущие месторасположения)"
-#: ../../Zotlabs/Module/Pubsites.php:24 ../../Zotlabs/Widget/Pubsites.php:12
-msgid "Public Hubs"
-msgstr "Публичные хабы"
+#: ../../Zotlabs/Module/Import.php:606
+msgid "Use this channel nickname instead of the one provided"
+msgstr "Использовать псевдоним этого канала вместо предоставленного"
-#: ../../Zotlabs/Module/Pubsites.php:27
+#: ../../Zotlabs/Module/Import.php:606
msgid ""
-"The listed hubs allow public registration for the $Projectname network. All "
-"hubs in the network are interlinked so membership on any of them conveys "
-"membership in the network as a whole. Some hubs may require subscription or "
-"provide tiered service plans. The hub itself <strong>may</strong> provide "
-"additional details."
-msgstr "Указанные хабы разрешают публичную регистрацию для сети $Projectname. Все хабы в сети взаимосвязаны, поэтому членство в любом из них передает членство во всю сеть. Некоторым хабам может потребоваться подписка или предоставление многоуровневых планов обслуживания. Сам хаб <strong>может</strong> предоставить дополнительные сведения."
-
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Hub URL"
-msgstr "URL сервера"
-
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Access Type"
-msgstr "Тип доступа"
-
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Registration Policy"
-msgstr "Политика регистрации"
-
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Stats"
-msgstr "Статистика"
-
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Software"
-msgstr "Программное обеспечение"
-
-#: ../../Zotlabs/Module/Pubsites.php:49
-msgid "Rate"
-msgstr "Оценка"
-
-#: ../../Zotlabs/Module/Impel.php:43 ../../include/bbcode.php:269
-msgid "webpage"
-msgstr "веб-страница"
-
-#: ../../Zotlabs/Module/Impel.php:48 ../../include/bbcode.php:275
-msgid "block"
-msgstr "заблокировать"
-
-#: ../../Zotlabs/Module/Impel.php:53 ../../include/bbcode.php:272
-msgid "layout"
-msgstr "шаблон"
+"Leave blank to keep your existing channel nickname. You will be randomly "
+"assigned a similar nickname if either name is already allocated on this site."
+msgstr "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте."
-#: ../../Zotlabs/Module/Impel.php:60 ../../include/bbcode.php:278
-msgid "menu"
-msgstr "меню"
+#: ../../Zotlabs/Module/Import.php:608
+msgid ""
+"This process may take several minutes to complete. Please submit the form "
+"only once and leave this page open until finished."
+msgstr "Процесс может занять несколько минут. Пожалуйста, отправьте форму только один раз и оставьте эту страницу открытой до завершения."
-#: ../../Zotlabs/Module/Impel.php:185
-#, php-format
-msgid "%s element installed"
-msgstr "%s элемент установлен"
+#: ../../Zotlabs/Module/Magic.php:76
+msgid "Hub not found."
+msgstr "Узел не найден."
-#: ../../Zotlabs/Module/Impel.php:188
+#: ../../Zotlabs/Module/Import_items.php:93
#, php-format
-msgid "%s element installation failed"
-msgstr "%sустановка элемента неудачна."
-
-#: ../../Zotlabs/Module/Rbmark.php:94
-msgid "Select a bookmark folder"
-msgstr "Выбрать каталог для закладок"
-
-#: ../../Zotlabs/Module/Rbmark.php:99
-msgid "Save Bookmark"
-msgstr "Сохранить закладку"
-
-#: ../../Zotlabs/Module/Rbmark.php:100
-msgid "URL of bookmark"
-msgstr "URL закладки"
-
-#: ../../Zotlabs/Module/Rbmark.php:105
-msgid "Or enter new bookmark folder name"
-msgstr "или введите новое имя каталога закладок"
-
-#: ../../Zotlabs/Module/Filer.php:52
-msgid "Enter a folder name"
-msgstr "Введите название каталога"
+msgid "Warning: Database versions differ by %1$d updates."
+msgstr "Предупреждение: Версия базы данных отличается от %1$d обновления."
-#: ../../Zotlabs/Module/Filer.php:52
-msgid "or select an existing folder (doubleclick)"
-msgstr "или выберите существующий каталог (двойной щелчок)"
+#: ../../Zotlabs/Module/Import_items.php:108
+msgid "Import completed"
+msgstr "Импорт завершён."
-#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Lib/ThreadItem.php:181
-msgid "Save to Folder"
-msgstr "Сохранить в каталог"
+#: ../../Zotlabs/Module/Import_items.php:125
+msgid "Import Items"
+msgstr "Импортировать объекты"
-#: ../../Zotlabs/Module/Probe.php:18
-msgid "Remote Diagnostics App"
-msgstr "Приложение \"Удалённая диагностика\""
+#: ../../Zotlabs/Module/Import_items.php:126
+msgid "Use this form to import existing posts and content from an export file."
+msgstr "Используйте эту форму для импорта существующих публикаций и содержимого из файла."
-#: ../../Zotlabs/Module/Probe.php:19
-msgid "Perform diagnostics on remote channels"
-msgstr "Производит диагностику удалённых каналов"
+#: ../../Zotlabs/Module/Siteinfo.php:21
+msgid "About this site"
+msgstr "Об этом сайте"
-#: ../../Zotlabs/Module/Register.php:49
-msgid "Maximum daily site registrations exceeded. Please try again tomorrow."
-msgstr "Превышено максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра."
+#: ../../Zotlabs/Module/Siteinfo.php:22
+msgid "Site Name"
+msgstr "Название сайта"
-#: ../../Zotlabs/Module/Register.php:55
-msgid ""
-"Please indicate acceptance of the Terms of Service. Registration failed."
-msgstr "Пожалуйста, подтвердите согласие с \"Условиями обслуживания\". Регистрация не удалась."
+#: ../../Zotlabs/Module/Siteinfo.php:26
+msgid "Administrator"
+msgstr "Администратор"
-#: ../../Zotlabs/Module/Register.php:89
-msgid "Passwords do not match."
-msgstr "Пароли не совпадают."
+#: ../../Zotlabs/Module/Siteinfo.php:29
+msgid "Software and Project information"
+msgstr "Информация о программном обеспечении и проекте"
-#: ../../Zotlabs/Module/Register.php:132
-msgid "Registration successful. Continue to create your first channel..."
-msgstr "Регистрация завершена успешно. Для продолжения создайте свой первый канал..."
+#: ../../Zotlabs/Module/Siteinfo.php:30
+msgid "This site is powered by $Projectname"
+msgstr "Этот сайт работает на $Projectname"
-#: ../../Zotlabs/Module/Register.php:135
+#: ../../Zotlabs/Module/Siteinfo.php:31
msgid ""
-"Registration successful. Please check your email for validation instructions."
-msgstr "Регистрация завершена успешно. Пожалуйста проверьте вашу электронную почту для подтверждения."
-
-#: ../../Zotlabs/Module/Register.php:142
-msgid "Your registration is pending approval by the site owner."
-msgstr "Ваша регистрация ожидает одобрения администрации сайта."
-
-#: ../../Zotlabs/Module/Register.php:145
-msgid "Your registration can not be processed."
-msgstr "Ваша регистрация не может быть обработана."
-
-#: ../../Zotlabs/Module/Register.php:192
-msgid "Registration on this hub is disabled."
-msgstr "Регистрация на этом хабе отключена."
-
-#: ../../Zotlabs/Module/Register.php:201
-msgid "Registration on this hub is by approval only."
-msgstr "Регистрация на этом хабе только по утверждению."
-
-#: ../../Zotlabs/Module/Register.php:202 ../../Zotlabs/Module/Register.php:211
-msgid "<a href=\"pubsites\">Register at another affiliated hub.</a>"
-msgstr "<a href=\"pubsites\">Зарегистрироваться на другом хабе.</a>"
-
-#: ../../Zotlabs/Module/Register.php:210
-msgid "Registration on this hub is by invitation only."
-msgstr "Регистрация на этом хабе доступна только по приглашениям."
+"Federated and decentralised networking and identity services provided by Zot"
+msgstr "Объединенные и децентрализованные сети и службы идентификациии обеспечиваются Zot"
-#: ../../Zotlabs/Module/Register.php:221
-msgid ""
-"This site has exceeded the number of allowed daily account registrations. "
-"Please try again tomorrow."
-msgstr "Этот сайт превысил максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра. "
+#: ../../Zotlabs/Module/Siteinfo.php:34
+msgid "Additional federated transport protocols:"
+msgstr "Дополнительные федеративные транспортные протоколы:"
-#: ../../Zotlabs/Module/Register.php:242
+#: ../../Zotlabs/Module/Siteinfo.php:36
#, php-format
-msgid "I accept the %s for this website"
-msgstr "Я принимаю %s для этого веб-сайта."
+msgid "Version %s"
+msgstr "Версия %s"
-#: ../../Zotlabs/Module/Register.php:249
-#, php-format
-msgid "I am over %s years of age and accept the %s for this website"
-msgstr "Мой возраст превышает %s лет и я принимаю %s для этого веб-сайта."
+#: ../../Zotlabs/Module/Siteinfo.php:37
+msgid "Project homepage"
+msgstr "Домашняя страница проекта"
-#: ../../Zotlabs/Module/Register.php:254
-msgid "Your email address"
-msgstr "Ваш адрес электронной почты"
+#: ../../Zotlabs/Module/Siteinfo.php:38
+msgid "Developer homepage"
+msgstr "Домашняя страница разработчика"
-#: ../../Zotlabs/Module/Register.php:255
-msgid "Choose a password"
-msgstr "Выберите пароль"
+#: ../../Zotlabs/Module/Cards.php:51
+msgid "Cards App"
+msgstr "Приложение \"Карточки\""
-#: ../../Zotlabs/Module/Register.php:256
-msgid "Please re-enter your password"
-msgstr "Пожалуйста, введите пароль еще раз"
+#: ../../Zotlabs/Module/Cards.php:52
+msgid "Create personal planning cards"
+msgstr "Создать личные карточки планирования"
-#: ../../Zotlabs/Module/Register.php:257
-msgid "Please enter your invitation code"
-msgstr "Пожалуйста, введите Ваш код приглашения"
+#: ../../Zotlabs/Module/Cards.php:112
+msgid "Add Card"
+msgstr "Добавить карточку"
-#: ../../Zotlabs/Module/Register.php:258
-msgid "Your Name"
-msgstr "Ваше имя"
+#: ../../Zotlabs/Module/Removeaccount.php:35
+msgid ""
+"Account removals are not allowed within 48 hours of changing the account "
+"password."
+msgstr "Удаление канала не разрешается в течении 48 часов после смены пароля у аккаунта."
-#: ../../Zotlabs/Module/Register.php:258
-msgid "Real names are preferred."
-msgstr "Предпочтительны реальные имена."
+#: ../../Zotlabs/Module/Removeaccount.php:57
+msgid "Remove This Account"
+msgstr "Удалить этот аккаунт"
-#: ../../Zotlabs/Module/Register.php:260
-#, php-format
+#: ../../Zotlabs/Module/Removeaccount.php:58
msgid ""
-"Your nickname will be used to create an easy to remember channel address e."
-"g. nickname%s"
-msgstr "Ваш псевдоним будет использован для создания легко запоминаемого адреса канала, напр. nickname %s"
+"This account and all its channels will be completely removed from the "
+"network. "
+msgstr "Этот аккаунт и все его каналы будут полностью удалены из сети."
-#: ../../Zotlabs/Module/Register.php:261
+#: ../../Zotlabs/Module/Removeaccount.php:60
msgid ""
-"Select a channel permission role for your usage needs and privacy "
-"requirements."
-msgstr "Выберите разрешения для канала в зависимости от ваших потребностей и требований приватности."
-
-#: ../../Zotlabs/Module/Register.php:262
-msgid "no"
-msgstr "нет"
-
-#: ../../Zotlabs/Module/Register.php:262
-msgid "yes"
-msgstr "да"
-
-#: ../../Zotlabs/Module/Register.php:289 ../../boot.php:1609
-#: ../../include/nav.php:156
-msgid "Register"
-msgstr "Регистрация"
+"Remove this account, all its channels and all its channel clones from the "
+"network"
+msgstr "Удалить этот аккаунт, все его каналы и их клоны из сети."
-#: ../../Zotlabs/Module/Register.php:290
+#: ../../Zotlabs/Module/Removeaccount.php:60
msgid ""
-"This site requires email verification. After completing this form, please "
-"check your email for further instructions."
-msgstr "Этот сайт требует проверку адреса электронной почты. После заполнения этой формы, пожалуйста, проверьте ваш почтовый ящик для дальнейших инструкций."
-
-#: ../../Zotlabs/Module/Cover_photo.php:168
-#: ../../Zotlabs/Module/Cover_photo.php:218
-msgid "Cover Photos"
-msgstr "Фотографии обложки"
-
-#: ../../Zotlabs/Module/Cover_photo.php:269 ../../include/items.php:4652
-msgid "female"
-msgstr "женщина"
-
-#: ../../Zotlabs/Module/Cover_photo.php:270 ../../include/items.php:4653
-#, php-format
-msgid "%1$s updated her %2$s"
-msgstr "%1$s обновила её %2$s"
-
-#: ../../Zotlabs/Module/Cover_photo.php:271 ../../include/items.php:4654
-msgid "male"
-msgstr "мужчина"
-
-#: ../../Zotlabs/Module/Cover_photo.php:272 ../../include/items.php:4655
-#, php-format
-msgid "%1$s updated his %2$s"
-msgstr "%1$s обновил его %2$s"
+"By default only the instances of the channels located on this hub will be "
+"removed from the network"
+msgstr "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети"
-#: ../../Zotlabs/Module/Cover_photo.php:274 ../../include/items.php:4657
-#, php-format
-msgid "%1$s updated their %2$s"
-msgstr "%1$s обновили их %2$s"
+#: ../../Zotlabs/Module/Oexchange.php:27
+msgid "Unable to find your hub."
+msgstr "Невозможно найти ваш сервер"
-#: ../../Zotlabs/Module/Cover_photo.php:276 ../../include/channel.php:2137
-msgid "cover photo"
-msgstr "фотография обложки"
+#: ../../Zotlabs/Module/Oexchange.php:41
+msgid "Post successful."
+msgstr "Успешно опубликовано."
-#: ../../Zotlabs/Module/Cover_photo.php:390
-msgid "Your cover photo may be visible to anybody on the internet"
-msgstr "Фотография вашей обложки может быть видна всем в Интернете"
+#: ../../Zotlabs/Module/Rmagic.php:44
+msgid "Authentication failed."
+msgstr "Ошибка аутентификации."
-#: ../../Zotlabs/Module/Cover_photo.php:394
-msgid "Change Cover Photo"
-msgstr "Изменить фотографию обложки"
+#: ../../Zotlabs/Module/Layouts.php:186
+msgid "Comanche page description language help"
+msgstr "Помощь по языку описания страниц Comanche "
-#: ../../Zotlabs/Module/Help.php:23
-msgid "Documentation Search"
-msgstr "Поиск документации"
+#: ../../Zotlabs/Module/Layouts.php:190
+msgid "Layout Description"
+msgstr "Описание шаблона"
-#: ../../Zotlabs/Module/Help.php:80 ../../include/nav.php:434
-msgid "About"
-msgstr "О себе"
+#: ../../Zotlabs/Module/Layouts.php:195
+msgid "Download PDL file"
+msgstr "Загрузить PDL файл"
-#: ../../Zotlabs/Module/Help.php:82
-msgid "Administrators"
-msgstr "Администраторы"
+#: ../../Zotlabs/Module/Go.php:21
+msgid "This page is available only to site members"
+msgstr "Эта страница доступна только для подписчиков сайта"
-#: ../../Zotlabs/Module/Help.php:83
-msgid "Developers"
-msgstr "Разработчики"
+#: ../../Zotlabs/Module/Go.php:27
+msgid "Welcome"
+msgstr "Добро пожаловать"
-#: ../../Zotlabs/Module/Help.php:84
-msgid "Tutorials"
-msgstr "Руководства"
+#: ../../Zotlabs/Module/Go.php:29
+msgid "What would you like to do?"
+msgstr "Что бы вы хотели сделать?"
-#: ../../Zotlabs/Module/Help.php:95
-msgid "$Projectname Documentation"
-msgstr "$Projectname Документация"
+#: ../../Zotlabs/Module/Go.php:31
+msgid ""
+"Please bookmark this page if you would like to return to it in the future"
+msgstr "Пожалуйста, запомните эту страницу если вы хотите вернуться на неё в будущем"
-#: ../../Zotlabs/Module/Help.php:96
-msgid "Contents"
-msgstr "Содержимое"
+#: ../../Zotlabs/Module/Go.php:35
+msgid "Upload a profile photo"
+msgstr "Загрузить фотографию профиля"
-#: ../../Zotlabs/Module/Display.php:391
-msgid "Article"
-msgstr "Статья"
+#: ../../Zotlabs/Module/Go.php:36
+msgid "Upload a cover photo"
+msgstr "Загрузить фотографию обложки"
-#: ../../Zotlabs/Module/Display.php:443
-msgid "Item has been removed."
-msgstr "Элемент был удалён."
+#: ../../Zotlabs/Module/Go.php:37
+msgid "Edit your default profile"
+msgstr "Редактировать ваш профиль по умолчанию"
-#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98
-msgid "Tag removed"
-msgstr "Тег удалён"
+#: ../../Zotlabs/Module/Go.php:38 ../../Zotlabs/Widget/Newmember.php:41
+msgid "View friend suggestions"
+msgstr "Просмотр рекомендуемых друзей"
-#: ../../Zotlabs/Module/Tagrm.php:123
-msgid "Remove Item Tag"
-msgstr "Удалить тег элемента"
+#: ../../Zotlabs/Module/Go.php:39
+msgid "View the channel directory"
+msgstr "Просмотр каталога каналов"
-#: ../../Zotlabs/Module/Tagrm.php:125
-msgid "Select a tag to remove: "
-msgstr "Выбрать тег для удаления:"
+#: ../../Zotlabs/Module/Go.php:40
+msgid "View/edit your channel settings"
+msgstr "Просмотреть / редактировать настройки вашего канала"
-#: ../../Zotlabs/Module/Network.php:109
-msgid "No such group"
-msgstr "Нет такой группы"
+#: ../../Zotlabs/Module/Go.php:41
+msgid "View the site or project documentation"
+msgstr "Просмотр документации сайта / проекта"
-#: ../../Zotlabs/Module/Network.php:158
-msgid "No such channel"
-msgstr "Нет такого канала"
+#: ../../Zotlabs/Module/Go.php:42
+msgid "Visit your channel homepage"
+msgstr "Посетить страницу вашего канала"
-#: ../../Zotlabs/Module/Network.php:242
-msgid "Privacy group is empty"
-msgstr "Группа безопасности пуста"
+#: ../../Zotlabs/Module/Go.php:43
+msgid ""
+"View your connections and/or add somebody whose address you already know"
+msgstr "Просмотреть ваши контакты и / или добавить кого-то чей адрес в уже знаете"
-#: ../../Zotlabs/Module/Network.php:252
-msgid "Privacy group: "
-msgstr "Группа безопасности: "
+#: ../../Zotlabs/Module/Go.php:44
+msgid ""
+"View your personal stream (this may be empty until you add some connections)"
+msgstr "Ваш персональный поток (может быть пуст пока вы не добавите контакты)"
-#: ../../Zotlabs/Module/Network.php:325 ../../addon/redred/Mod_Redred.php:29
-msgid "Invalid channel."
-msgstr "Недействительный канал."
+#: ../../Zotlabs/Module/Go.php:52
+msgid "View the public stream. Warning: this content is not moderated"
+msgstr "Просмотр публичного потока. Предупреждение: этот контент не модерируется"
-#: ../../Zotlabs/Module/Acl.php:360
-msgid "network"
-msgstr "сеть"
+#: ../../Zotlabs/Widget/Forums.php:100
+#: ../../Zotlabs/Widget/Notifications.php:119
+#: ../../Zotlabs/Widget/Notifications.php:120
+#: ../../Zotlabs/Widget/Activity_filter.php:73
+msgid "Forums"
+msgstr "Форумы"
-#: ../../Zotlabs/Module/Home.php:72 ../../Zotlabs/Module/Home.php:80
-#: ../../Zotlabs/Lib/Enotify.php:66 ../../addon/opensearch/opensearch.php:42
-msgid "$Projectname"
-msgstr ""
+#: ../../Zotlabs/Widget/Notes.php:21 ../../Zotlabs/Lib/Apps.php:370
+msgid "Notes"
+msgstr "Заметки"
-#: ../../Zotlabs/Module/Home.php:90
-#, php-format
-msgid "Welcome to %s"
-msgstr "Добро пожаловать в %s"
+#: ../../Zotlabs/Widget/Suggestions.php:53
+msgid "Suggestions"
+msgstr "Рекомендации"
-#: ../../Zotlabs/Module/Filestorage.php:79
-msgid "Permission Denied."
-msgstr "Доступ запрещен."
+#: ../../Zotlabs/Widget/Suggestions.php:54
+msgid "See more..."
+msgstr "Просмотреть больше..."
-#: ../../Zotlabs/Module/Filestorage.php:112
-msgid "File not found."
-msgstr "Файл не найден."
+#: ../../Zotlabs/Widget/Notifications.php:16
+msgid "New Network Activity"
+msgstr "Новая сетевая активность"
-#: ../../Zotlabs/Module/Filestorage.php:165
-msgid "Edit file permissions"
-msgstr "Редактировать разрешения файла"
+#: ../../Zotlabs/Widget/Notifications.php:17
+msgid "New Network Activity Notifications"
+msgstr "Новые уведомления о сетевой активности"
-#: ../../Zotlabs/Module/Filestorage.php:177
-msgid "Set/edit permissions"
-msgstr "Редактировать разрешения"
+#: ../../Zotlabs/Widget/Notifications.php:20
+msgid "View your network activity"
+msgstr "Просмотреть вашу сетевую активность"
-#: ../../Zotlabs/Module/Filestorage.php:178
-msgid "Include all files and sub folders"
-msgstr "Включить все файлы и подкаталоги"
+#: ../../Zotlabs/Widget/Notifications.php:23
+msgid "Mark all notifications read"
+msgstr "Пометить уведомления как прочитанные"
-#: ../../Zotlabs/Module/Filestorage.php:179
-msgid "Return to file list"
-msgstr "Вернутся к списку файлов"
+#: ../../Zotlabs/Widget/Notifications.php:26
+#: ../../Zotlabs/Widget/Notifications.php:45
+#: ../../Zotlabs/Widget/Notifications.php:152
+msgid "Show new posts only"
+msgstr "Показывать только новые публикации"
-#: ../../Zotlabs/Module/Filestorage.php:181
-msgid "Copy/paste this code to attach file to a post"
-msgstr "Копировать / вставить этот код для прикрепления файла к публикации"
+#: ../../Zotlabs/Widget/Notifications.php:27
+#: ../../Zotlabs/Widget/Notifications.php:46
+#: ../../Zotlabs/Widget/Notifications.php:122
+#: ../../Zotlabs/Widget/Notifications.php:153
+msgid "Filter by name or address"
+msgstr "Фильтровать по имени или адресу"
-#: ../../Zotlabs/Module/Filestorage.php:182
-msgid "Copy/paste this URL to link file from a web page"
-msgstr "Копировать / вставить эту URL для ссылки на файл со страницы"
+#: ../../Zotlabs/Widget/Notifications.php:35
+msgid "New Home Activity"
+msgstr "Новая локальная активность"
-#: ../../Zotlabs/Module/Filestorage.php:184
-msgid "Share this file"
-msgstr "Поделиться этим файлом"
+#: ../../Zotlabs/Widget/Notifications.php:36
+msgid "New Home Activity Notifications"
+msgstr "Новые уведомления локальной активности"
-#: ../../Zotlabs/Module/Filestorage.php:185
-msgid "Show URL to this file"
-msgstr "Показать URL этого файла"
+#: ../../Zotlabs/Widget/Notifications.php:39
+msgid "View your home activity"
+msgstr "Просмотреть локальную активность"
-#: ../../Zotlabs/Module/Filestorage.php:186
-#: ../../Zotlabs/Storage/Browser.php:405
-msgid "Show in your contacts shared folder"
-msgstr "Показать общий каталог в ваших контактах"
+#: ../../Zotlabs/Widget/Notifications.php:42
+#: ../../Zotlabs/Widget/Notifications.php:149
+msgid "Mark all notifications seen"
+msgstr "Пометить уведомления как просмотренные"
-#: ../../Zotlabs/Module/Common.php:14
-msgid "No channel."
-msgstr "Канала нет."
+#: ../../Zotlabs/Widget/Notifications.php:54
+msgid "New Mails"
+msgstr "Новая переписка"
-#: ../../Zotlabs/Module/Common.php:45
-msgid "No connections in common."
-msgstr "Общих контактов нет."
+#: ../../Zotlabs/Widget/Notifications.php:55
+msgid "New Mails Notifications"
+msgstr "Уведомления о новой переписке"
-#: ../../Zotlabs/Module/Common.php:65
-msgid "View Common Connections"
-msgstr "Просмотр общий контактов"
+#: ../../Zotlabs/Widget/Notifications.php:58
+msgid "View your private mails"
+msgstr "Просмотреть вашу личную переписку"
-#: ../../Zotlabs/Module/Email_resend.php:30
-msgid "Email verification resent"
-msgstr "Сообщение для проверки email отправлено повторно"
+#: ../../Zotlabs/Widget/Notifications.php:61
+msgid "Mark all messages seen"
+msgstr "Пометить сообщения как просмотренные"
-#: ../../Zotlabs/Module/Email_resend.php:33
-msgid "Unable to resend email verification message."
-msgstr "Невозможно повторно отправить сообщение для проверки email"
+#: ../../Zotlabs/Widget/Notifications.php:69
+msgid "New Events"
+msgstr "Новые события"
-#: ../../Zotlabs/Module/Viewconnections.php:65
-msgid "No connections."
-msgstr "Контактов нет."
+#: ../../Zotlabs/Widget/Notifications.php:70
+msgid "New Events Notifications"
+msgstr "Уведомления о новых событиях"
-#: ../../Zotlabs/Module/Viewconnections.php:83
-#, php-format
-msgid "Visit %s's profile [%s]"
-msgstr "Посетить %s ​​профиль [%s]"
+#: ../../Zotlabs/Widget/Notifications.php:73
+msgid "View events"
+msgstr "Просмотреть события"
-#: ../../Zotlabs/Module/Viewconnections.php:113
-msgid "View Connections"
-msgstr "Просмотр контактов"
+#: ../../Zotlabs/Widget/Notifications.php:76
+msgid "Mark all events seen"
+msgstr "Пометить все события как просмотренные"
-#: ../../Zotlabs/Module/Admin.php:97
-msgid "Blocked accounts"
-msgstr "Заблокированные аккаунты"
+#: ../../Zotlabs/Widget/Notifications.php:85
+msgid "New Connections Notifications"
+msgstr "Уведомления о новых контактах"
-#: ../../Zotlabs/Module/Admin.php:98
-msgid "Expired accounts"
-msgstr "Просроченные аккаунты"
+#: ../../Zotlabs/Widget/Notifications.php:88
+msgid "View all connections"
+msgstr "Просмотр всех контактов"
-#: ../../Zotlabs/Module/Admin.php:99
-msgid "Expiring accounts"
-msgstr "Близкие к просрочке аккаунты"
+#: ../../Zotlabs/Widget/Notifications.php:96
+msgid "New Files"
+msgstr "Новые файлы"
-#: ../../Zotlabs/Module/Admin.php:120
-msgid "Message queues"
-msgstr "Очередь сообщений"
+#: ../../Zotlabs/Widget/Notifications.php:97
+msgid "New Files Notifications"
+msgstr "Уведомления о новых файлах"
-#: ../../Zotlabs/Module/Admin.php:134
-msgid "Your software should be updated"
-msgstr "Ваше программное обеспечение должно быть обновлено"
+#: ../../Zotlabs/Widget/Notifications.php:104
+#: ../../Zotlabs/Widget/Notifications.php:105
+msgid "Notices"
+msgstr "Оповещения"
-#: ../../Zotlabs/Module/Admin.php:139
-msgid "Summary"
-msgstr "Резюме"
+#: ../../Zotlabs/Widget/Notifications.php:108
+msgid "View all notices"
+msgstr "Просмотреть все оповещения"
-#: ../../Zotlabs/Module/Admin.php:142
-msgid "Registered accounts"
-msgstr "Зарегистрированные аккаунты"
+#: ../../Zotlabs/Widget/Notifications.php:111
+msgid "Mark all notices seen"
+msgstr "Пометить все оповещения как просмотренные"
-#: ../../Zotlabs/Module/Admin.php:143
-msgid "Pending registrations"
-msgstr "Ждут утверждения"
+#: ../../Zotlabs/Widget/Notifications.php:132
+msgid "New Registrations"
+msgstr "Новые регистрации"
-#: ../../Zotlabs/Module/Admin.php:144
-msgid "Registered channels"
-msgstr "Зарегистрированные каналы"
+#: ../../Zotlabs/Widget/Notifications.php:133
+msgid "New Registrations Notifications"
+msgstr "Уведомления о новых регистрациях"
-#: ../../Zotlabs/Module/Admin.php:145
-msgid "Active addons"
-msgstr "Активные расширения"
+#: ../../Zotlabs/Widget/Notifications.php:143
+msgid "Public Stream Notifications"
+msgstr "Уведомления публичного потока"
-#: ../../Zotlabs/Module/Admin.php:146
-msgid "Version"
-msgstr "Версия системы"
+#: ../../Zotlabs/Widget/Notifications.php:146
+msgid "View the public stream"
+msgstr "Просмотреть публичный поток"
-#: ../../Zotlabs/Module/Admin.php:147
-msgid "Repository version (master)"
-msgstr "Версия репозитория (master)"
+#: ../../Zotlabs/Widget/Notifications.php:161
+msgid "Sorry, you have got no notifications at the moment"
+msgstr "Извините, но сейчас у вас нет уведомлений"
-#: ../../Zotlabs/Module/Admin.php:148
-msgid "Repository version (dev)"
-msgstr "Версия репозитория (dev)"
+#: ../../Zotlabs/Widget/Tasklist.php:23
+msgid "Tasks"
+msgstr "Задачи"
-#: ../../Zotlabs/Module/Service_limits.php:23
-msgid "No service class restrictions found."
-msgstr "Ограничений класса обслуживание не найдено."
+#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58
+msgid "photo/image"
+msgstr "фотография / изображение"
-#: ../../Zotlabs/Module/Rate.php:156
-msgid "Website:"
-msgstr "Веб-сайт:"
+#: ../../Zotlabs/Widget/Cdav.php:37
+msgid "Select Channel"
+msgstr "Выбрать канал"
-#: ../../Zotlabs/Module/Rate.php:159
-#, php-format
-msgid "Remote Channel [%s] (not yet known on this site)"
-msgstr "Удалённый канал [%s] (пока неизвестен на этом сайте)"
+#: ../../Zotlabs/Widget/Cdav.php:42
+msgid "Read-write"
+msgstr "Чтение-запись"
-#: ../../Zotlabs/Module/Rate.php:160
-msgid "Rating (this information is public)"
-msgstr "Оценка (эта информация общедоступна)"
+#: ../../Zotlabs/Widget/Cdav.php:43
+msgid "Read-only"
+msgstr "Только чтение"
-#: ../../Zotlabs/Module/Rate.php:161
-msgid "Optionally explain your rating (this information is public)"
-msgstr "Объясните свою оценку (необязательно; эта информация общедоступна)"
+#: ../../Zotlabs/Widget/Cdav.php:117
+msgid "My Calendars"
+msgstr "Мои календари"
-#: ../../Zotlabs/Module/Card_edit.php:128
-msgid "Edit Card"
-msgstr "Редактировать карточку"
+#: ../../Zotlabs/Widget/Cdav.php:119
+msgid "Shared Calendars"
+msgstr "Общие календари"
-#: ../../Zotlabs/Module/Lostpass.php:19
-msgid "No valid account found."
-msgstr "Действительный аккаунт не найден."
+#: ../../Zotlabs/Widget/Cdav.php:123
+msgid "Share this calendar"
+msgstr "Поделиться этим календарём"
-#: ../../Zotlabs/Module/Lostpass.php:33
-msgid "Password reset request issued. Check your email."
-msgstr "Запрос на сброс пароля отправлен. Проверьте вашу электронную почту."
+#: ../../Zotlabs/Widget/Cdav.php:125
+msgid "Calendar name and color"
+msgstr "Имя и цвет календаря"
-#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108
-#, php-format
-msgid "Site Member (%s)"
-msgstr "Участник сайта (%s)"
+#: ../../Zotlabs/Widget/Cdav.php:127
+msgid "Create new calendar"
+msgstr "Создать новый календарь"
-#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49
-#, php-format
-msgid "Password reset requested at %s"
-msgstr "Запрошен сброс пароля на %s"
+#: ../../Zotlabs/Widget/Cdav.php:129
+msgid "Calendar Name"
+msgstr "Имя календаря"
-#: ../../Zotlabs/Module/Lostpass.php:68
-msgid ""
-"Request could not be verified. (You may have previously submitted it.) "
-"Password reset failed."
-msgstr "Запрос не может быть проверен. (Вы могли отправить его раньше). Сброс пароля не возможен."
+#: ../../Zotlabs/Widget/Cdav.php:130
+msgid "Calendar Tools"
+msgstr "Инструменты календаря"
-#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1638
-msgid "Password Reset"
-msgstr "Сбросить пароль"
+#: ../../Zotlabs/Widget/Cdav.php:131
+msgid "Import calendar"
+msgstr "Импортировать календарь"
-#: ../../Zotlabs/Module/Lostpass.php:92
-msgid "Your password has been reset as requested."
-msgstr "Ваш пароль в соответствии с просьбой сброшен."
+#: ../../Zotlabs/Widget/Cdav.php:132
+msgid "Select a calendar to import to"
+msgstr "Выбрать календарь для импорта в"
-#: ../../Zotlabs/Module/Lostpass.php:93
-msgid "Your new password is"
-msgstr "Ваш новый пароль"
+#: ../../Zotlabs/Widget/Cdav.php:159
+msgid "Addressbooks"
+msgstr "Адресные книги"
-#: ../../Zotlabs/Module/Lostpass.php:94
-msgid "Save or copy your new password - and then"
-msgstr "Сохраните ваш новый пароль и затем"
+#: ../../Zotlabs/Widget/Cdav.php:161
+msgid "Addressbook name"
+msgstr "Имя адресной книги"
-#: ../../Zotlabs/Module/Lostpass.php:95
-msgid "click here to login"
-msgstr "нажмите здесь чтобы войти"
+#: ../../Zotlabs/Widget/Cdav.php:163
+msgid "Create new addressbook"
+msgstr "Создать новую адресную книгу"
-#: ../../Zotlabs/Module/Lostpass.php:96
-msgid ""
-"Your password may be changed from the <em>Settings</em> page after "
-"successful login."
-msgstr "Ваш пароль может быть изменён на странице <em>Настройки</em> после успешного входа."
+#: ../../Zotlabs/Widget/Cdav.php:164
+msgid "Addressbook Name"
+msgstr "Имя адресной книги"
-#: ../../Zotlabs/Module/Lostpass.php:117
-#, php-format
-msgid "Your password has changed at %s"
-msgstr "Пароль был изменен на %s"
+#: ../../Zotlabs/Widget/Cdav.php:166
+msgid "Addressbook Tools"
+msgstr "Инструменты адресной книги"
-#: ../../Zotlabs/Module/Lostpass.php:130
-msgid "Forgot your Password?"
-msgstr "Забыли ваш пароль?"
+#: ../../Zotlabs/Widget/Cdav.php:167
+msgid "Import addressbook"
+msgstr "Импортировать адресную книгу"
-#: ../../Zotlabs/Module/Lostpass.php:131
-msgid ""
-"Enter your email address and submit to have your password reset. Then check "
-"your email for further instructions."
-msgstr "Введите ваш адрес электронной почты и нажмите отправить чтобы сбросить пароль. Затем проверьте ваш почтовый ящик для дальнейших инструкций. "
+#: ../../Zotlabs/Widget/Cdav.php:168
+msgid "Select an addressbook to import to"
+msgstr "Выбрать адресную книгу для импорта в"
-#: ../../Zotlabs/Module/Lostpass.php:132
-msgid "Email Address"
-msgstr "Адрес электронной почты"
+#: ../../Zotlabs/Widget/Activity.php:50
+msgctxt "widget"
+msgid "Activity"
+msgstr "Активность"
-#: ../../Zotlabs/Module/Oauth.php:45
-msgid "Name is required"
-msgstr "Необходимо имя"
+#: ../../Zotlabs/Widget/Hq_controls.php:14
+msgid "HQ Control Panel"
+msgstr "Панель управления HQ"
-#: ../../Zotlabs/Module/Oauth.php:49
-msgid "Key and Secret are required"
-msgstr "Требуются ключ и код"
+#: ../../Zotlabs/Widget/Hq_controls.php:17
+msgid "Create a new post"
+msgstr "Создать новую публикацию"
-#: ../../Zotlabs/Module/Oauth.php:100
-msgid "OAuth Apps Manager App"
-msgstr "Приложение \"Менеджер Oauth\""
+#: ../../Zotlabs/Widget/Follow.php:22
+#, php-format
+msgid "You have %1$.0f of %2$.0f allowed connections."
+msgstr "У вас есть %1$.0f из %2$.0f разрешенных контактов."
-#: ../../Zotlabs/Module/Oauth.php:101
-msgid "OAuth authentication tokens for mobile and remote apps"
-msgstr "Токены аутентификации OAuth для мобильный и удалённых приложений"
+#: ../../Zotlabs/Widget/Follow.php:29
+msgid "Add New Connection"
+msgstr "Добавить новый контакт"
-#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140
-#: ../../addon/statusnet/statusnet.php:596 ../../addon/twitter/twitter.php:614
-msgid "Consumer Key"
-msgstr "Ключ клиента"
+#: ../../Zotlabs/Widget/Follow.php:30
+msgid "Enter channel address"
+msgstr "Введите адрес канала"
-#: ../../Zotlabs/Module/Oauth.php:117 ../../Zotlabs/Module/Oauth.php:143
-msgid "Icon url"
-msgstr "URL значка"
+#: ../../Zotlabs/Widget/Follow.php:31
+msgid "Examples: bob@example.com, https://example.com/barbara"
+msgstr "Пример: ivan@example.com, http://example.com/ivan"
-#: ../../Zotlabs/Module/Oauth.php:128
-msgid "Application not found."
-msgstr "Приложение не найдено."
+#: ../../Zotlabs/Widget/Archive.php:43
+msgid "Archives"
+msgstr "Архивы"
-#: ../../Zotlabs/Module/Oauth.php:171
-msgid "Connected OAuth Apps"
-msgstr "Подключенные приложения OAuth"
+#: ../../Zotlabs/Widget/Suggestedchats.php:32
+msgid "Suggested Chatrooms"
+msgstr "Рекомендуемые чаты"
-#: ../../Zotlabs/Module/Notifications.php:60
-#: ../../Zotlabs/Lib/ThreadItem.php:450
-msgid "Mark all seen"
-msgstr "Отметить как просмотренное"
+#: ../../Zotlabs/Widget/Rating.php:51
+msgid "Rating Tools"
+msgstr "Инструменты оценки"
-#: ../../Zotlabs/Lib/Activity.php:1458
-#, php-format
-msgid "Likes %1$s's %2$s"
-msgstr "Нравится %1$s %2$s"
+#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57
+msgid "Rate Me"
+msgstr "Оценить меня"
-#: ../../Zotlabs/Lib/Activity.php:1461
-#, php-format
-msgid "Doesn't like %1$s's %2$s"
-msgstr "Не нравится %1$s %2$s"
+#: ../../Zotlabs/Widget/Rating.php:60
+msgid "View Ratings"
+msgstr "Просмотр оценок"
-#: ../../Zotlabs/Lib/Activity.php:1464
-#, php-format
-msgid "Will attend %1$s's %2$s"
-msgstr "Примет участие %1$s %2$s"
+#: ../../Zotlabs/Widget/Newmember.php:31
+msgid "Profile Creation"
+msgstr "Создание профиля"
-#: ../../Zotlabs/Lib/Activity.php:1467
-#, php-format
-msgid "Will not attend %1$s's %2$s"
-msgstr "Не примет участие %1$s %2$s"
+#: ../../Zotlabs/Widget/Newmember.php:33
+msgid "Upload profile photo"
+msgstr "Загрузить фотографию профиля"
-#: ../../Zotlabs/Lib/Activity.php:1470
-#, php-format
-msgid "May attend %1$s's %2$s"
-msgstr "Возможно примет участие %1$s %2$s"
+#: ../../Zotlabs/Widget/Newmember.php:34
+msgid "Upload cover photo"
+msgstr "Загрузить фотографию обложки"
-#: ../../Zotlabs/Lib/Activity.php:1806 ../../Zotlabs/Lib/Activity.php:2003
-#: ../../widget/Netselect/Netselect.php:42 ../../addon/pubcrawl/as.php:1214
-#: ../../addon/pubcrawl/as.php:1369 ../../addon/pubcrawl/as.php:1549
-#: ../../include/network.php:1720
-msgid "ActivityPub"
-msgstr ""
+#: ../../Zotlabs/Widget/Newmember.php:38
+msgid "Find and Connect with others"
+msgstr "Найти и вступить в контакт"
-#: ../../Zotlabs/Lib/Techlevels.php:10
-msgid "0. Beginner/Basic"
-msgstr "Начинающий / Базовый"
+#: ../../Zotlabs/Widget/Newmember.php:40
+msgid "View the directory"
+msgstr "Просмотреть каталог"
-#: ../../Zotlabs/Lib/Techlevels.php:11
-msgid "1. Novice - not skilled but willing to learn"
-msgstr "1. Новичок - не опытный, но желающий учиться"
+#: ../../Zotlabs/Widget/Newmember.php:42
+msgid "Manage your connections"
+msgstr "Управление вашими контактами"
-#: ../../Zotlabs/Lib/Techlevels.php:12
-msgid "2. Intermediate - somewhat comfortable"
-msgstr "2. Промежуточный - более удобный"
+#: ../../Zotlabs/Widget/Newmember.php:45
+msgid "Communicate"
+msgstr "Связаться"
-#: ../../Zotlabs/Lib/Techlevels.php:13
-msgid "3. Advanced - very comfortable"
-msgstr "3. Продвинутый - очень удобный"
+#: ../../Zotlabs/Widget/Newmember.php:47
+msgid "View your channel homepage"
+msgstr "Домашняя страница канала"
-#: ../../Zotlabs/Lib/Techlevels.php:14
-msgid "4. Expert - I can write computer code"
-msgstr "4. Эксперт - я умею программировать"
+#: ../../Zotlabs/Widget/Newmember.php:48
+msgid "View your network stream"
+msgstr "Просмотреть ваш сетевой поток"
-#: ../../Zotlabs/Lib/Techlevels.php:15
-msgid "5. Wizard - I probably know more than you do"
-msgstr "5. Волшебник - возможно я знаю больше чем ты"
+#: ../../Zotlabs/Widget/Newmember.php:54
+msgid "Documentation"
+msgstr "Документация"
-#: ../../Zotlabs/Lib/Libzot.php:652 ../../include/zot.php:802
-msgid "Unable to verify channel signature"
-msgstr "Невозможно проверить подпись канала"
+#: ../../Zotlabs/Widget/Newmember.php:57
+msgid "Missing Features?"
+msgstr "Отсутствует функция?"
-#: ../../Zotlabs/Lib/Apps.php:322
-msgid "Apps"
-msgstr "Приложения"
+#: ../../Zotlabs/Widget/Newmember.php:59
+msgid "Pin apps to navigation bar"
+msgstr "Прикрепить приложение к панели"
-#: ../../Zotlabs/Lib/Apps.php:323
-msgid "Affinity Tool"
-msgstr "Степень сходства"
+#: ../../Zotlabs/Widget/Newmember.php:60
+msgid "Install more apps"
+msgstr "Установить больше приложений"
-#: ../../Zotlabs/Lib/Apps.php:326
-msgid "Site Admin"
-msgstr "Администратор сайта"
+#: ../../Zotlabs/Widget/Newmember.php:71
+msgid "View public stream"
+msgstr "Просмотреть публичный поток"
-#: ../../Zotlabs/Lib/Apps.php:327 ../../addon/buglink/buglink.php:16
-msgid "Report Bug"
-msgstr "Сообщить об ошибке"
+#: ../../Zotlabs/Widget/Mailmenu.php:13
+msgid "Private Mail Menu"
+msgstr "Меню личной переписки"
-#: ../../Zotlabs/Lib/Apps.php:328 ../../include/nav.php:490
-msgid "Bookmarks"
-msgstr "Закладки"
+#: ../../Zotlabs/Widget/Mailmenu.php:15
+msgid "Combined View"
+msgstr "Комбинированный вид"
-#: ../../Zotlabs/Lib/Apps.php:329 ../../Zotlabs/Widget/Chatroom_list.php:16
-#: ../../include/nav.php:477 ../../include/nav.php:480
-msgid "Chatrooms"
-msgstr "Чаты"
+#: ../../Zotlabs/Widget/Mailmenu.php:20
+msgid "Inbox"
+msgstr "Входящие"
-#: ../../Zotlabs/Lib/Apps.php:331
-msgid "Remote Diagnostics"
-msgstr "Удалённая диагностика"
+#: ../../Zotlabs/Widget/Mailmenu.php:25
+msgid "Outbox"
+msgstr "Исходящие"
-#: ../../Zotlabs/Lib/Apps.php:332 ../../include/features.php:365
-msgid "Suggest Channels"
-msgstr "Предлагаемые каналы"
+#: ../../Zotlabs/Widget/Mailmenu.php:30
+msgid "New Message"
+msgstr "Новое сообщение"
-#: ../../Zotlabs/Lib/Apps.php:333 ../../boot.php:1629 ../../include/nav.php:118
-#: ../../include/nav.php:122
-msgid "Login"
-msgstr "Войти"
+#: ../../Zotlabs/Widget/Wiki_pages.php:34
+#: ../../Zotlabs/Widget/Wiki_pages.php:91
+msgid "Add new page"
+msgstr "Добавить новую страницу"
-#: ../../Zotlabs/Lib/Apps.php:335
-msgid "Stream"
-msgstr "Поток"
+#: ../../Zotlabs/Widget/Wiki_pages.php:85
+msgid "Wiki Pages"
+msgstr "Wiki страницы"
-#: ../../Zotlabs/Lib/Apps.php:339 ../../include/nav.php:539
-msgid "Wiki"
-msgstr ""
+#: ../../Zotlabs/Widget/Wiki_pages.php:96
+msgid "Page name"
+msgstr "Название страницы"
-#: ../../Zotlabs/Lib/Apps.php:340 ../../include/features.php:96
-msgid "Channel Home"
-msgstr "Главная канала"
+#: ../../Zotlabs/Widget/Eventstools.php:13
+msgid "Events Tools"
+msgstr "Инструменты для событий"
-#: ../../Zotlabs/Lib/Apps.php:343 ../../include/features.php:269
-msgid "Events"
-msgstr "События"
+#: ../../Zotlabs/Widget/Eventstools.php:14
+msgid "Export Calendar"
+msgstr "Экспортировать календарь"
-#: ../../Zotlabs/Lib/Apps.php:344 ../../include/features.php:176
-msgid "Directory"
-msgstr "Каталог"
+#: ../../Zotlabs/Widget/Eventstools.php:15
+msgid "Import Calendar"
+msgstr "Импортировать календарь"
-#: ../../Zotlabs/Lib/Apps.php:346
-msgid "Mail"
-msgstr "Переписка"
+#: ../../Zotlabs/Widget/Chatroom_list.php:20
+msgid "Overview"
+msgstr "Обзор"
-#: ../../Zotlabs/Lib/Apps.php:349
-msgid "Chat"
-msgstr "Чат"
+#: ../../Zotlabs/Widget/Settings_menu.php:32
+msgid "Account settings"
+msgstr "Настройки аккаунта"
-#: ../../Zotlabs/Lib/Apps.php:351
-msgid "Probe"
-msgstr "Проба"
+#: ../../Zotlabs/Widget/Settings_menu.php:38
+msgid "Channel settings"
+msgstr "Настройки канала"
-#: ../../Zotlabs/Lib/Apps.php:352
-msgid "Suggest"
-msgstr "Предложить"
+#: ../../Zotlabs/Widget/Settings_menu.php:46
+msgid "Display settings"
+msgstr "Настройки отображения"
-#: ../../Zotlabs/Lib/Apps.php:353
-msgid "Random Channel"
-msgstr "Случайный канал"
+#: ../../Zotlabs/Widget/Settings_menu.php:53
+msgid "Manage locations"
+msgstr "Управление местоположением"
-#: ../../Zotlabs/Lib/Apps.php:354
-msgid "Invite"
-msgstr "Пригласить"
+#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60
+msgid "Member registrations waiting for confirmation"
+msgstr "Регистрации участников, ожидающие подверждения"
-#: ../../Zotlabs/Lib/Apps.php:355 ../../Zotlabs/Widget/Admin.php:26
+#: ../../Zotlabs/Widget/Admin.php:26 ../../Zotlabs/Lib/Apps.php:357
msgid "Features"
msgstr "Функции"
-#: ../../Zotlabs/Lib/Apps.php:356 ../../addon/openid/MysqlProvider.php:69
-msgid "Language"
-msgstr "Язык"
-
-#: ../../Zotlabs/Lib/Apps.php:357
-msgid "Post"
-msgstr "Публикация"
-
-#: ../../Zotlabs/Lib/Apps.php:358 ../../addon/openid/MysqlProvider.php:58
-#: ../../addon/openid/MysqlProvider.php:59
-#: ../../addon/openid/MysqlProvider.php:60
-msgid "Profile Photo"
-msgstr "Фотография профиля"
-
-#: ../../Zotlabs/Lib/Apps.php:360 ../../include/features.php:397
-msgid "Profiles"
-msgstr "Редактировать профиль"
+#: ../../Zotlabs/Widget/Admin.php:29
+msgid "Inspect queue"
+msgstr "Просмотр очереди"
-#: ../../Zotlabs/Lib/Apps.php:362
-msgid "Notifications"
-msgstr "Оповещения"
+#: ../../Zotlabs/Widget/Admin.php:31
+msgid "DB updates"
+msgstr "Обновление базы данных"
-#: ../../Zotlabs/Lib/Apps.php:363
-msgid "Order Apps"
-msgstr "Порядок приложений"
+#: ../../Zotlabs/Widget/Admin.php:56
+msgid "Addon Features"
+msgstr "Настройки расширений"
-#: ../../Zotlabs/Lib/Apps.php:364 ../../include/features.php:82
-msgid "CalDAV"
-msgstr ""
+#: ../../Zotlabs/Widget/Appstore.php:11
+msgid "App Collections"
+msgstr "Коллекции приложений"
-#: ../../Zotlabs/Lib/Apps.php:365
-msgid "CardDAV"
-msgstr ""
+#: ../../Zotlabs/Widget/Appstore.php:13
+msgid "Installed apps"
+msgstr "Установленные приложения"
-#: ../../Zotlabs/Lib/Apps.php:367
-msgid "Guest Access"
-msgstr "Гостевой доступ"
+#: ../../Zotlabs/Widget/Savedsearch.php:75
+msgid "Remove term"
+msgstr "Удалить термин"
-#: ../../Zotlabs/Lib/Apps.php:368 ../../Zotlabs/Widget/Notes.php:21
-msgid "Notes"
-msgstr "Заметки"
+#: ../../Zotlabs/Widget/Activity_filter.php:36
+#, php-format
+msgid "Show posts related to the %s privacy group"
+msgstr "Показывать публикации относящиеся к группе безопасности %s"
-#: ../../Zotlabs/Lib/Apps.php:369
-msgid "OAuth Apps Manager"
-msgstr "Менеджер OAuth"
+#: ../../Zotlabs/Widget/Activity_filter.php:45
+msgid "Show my privacy groups"
+msgstr "Показывать мои группы безопасности"
-#: ../../Zotlabs/Lib/Apps.php:370
-msgid "OAuth2 Apps Manager"
-msgstr "Менеджер OAuth2"
+#: ../../Zotlabs/Widget/Activity_filter.php:66
+msgid "Show posts to this forum"
+msgstr "Показывать публикации этого форума"
-#: ../../Zotlabs/Lib/Apps.php:371
-msgid "PDL Editor"
-msgstr "Редактор PDL"
+#: ../../Zotlabs/Widget/Activity_filter.php:77
+msgid "Show forums"
+msgstr "Показывать форумы"
-#: ../../Zotlabs/Lib/Apps.php:373
-msgid "Premium Channel"
-msgstr "Премиальный канал"
+#: ../../Zotlabs/Widget/Activity_filter.php:91
+msgid "Starred Posts"
+msgstr "Отмеченные публикации"
-#: ../../Zotlabs/Lib/Apps.php:375
-msgid "My Chatrooms"
-msgstr "Мои чаты"
+#: ../../Zotlabs/Widget/Activity_filter.php:95
+msgid "Show posts that I have starred"
+msgstr "Показывать публикации которые я отметил"
-#: ../../Zotlabs/Lib/Apps.php:376
-msgid "Channel Export"
-msgstr "Экспорт канала"
+#: ../../Zotlabs/Widget/Activity_filter.php:106
+msgid "Personal Posts"
+msgstr "Личные публикации"
-#: ../../Zotlabs/Lib/Apps.php:553
-msgid "Purchase"
-msgstr "Купить"
+#: ../../Zotlabs/Widget/Activity_filter.php:110
+msgid "Show posts that mention or involve me"
+msgstr "Показывать публикации где вы были упомянуты или привлечены"
-#: ../../Zotlabs/Lib/Apps.php:558
-msgid "Undelete"
-msgstr "Восстановить"
+#: ../../Zotlabs/Widget/Activity_filter.php:131
+#, php-format
+msgid "Show posts that I have filed to %s"
+msgstr "Показывать публикации которые я добавил в %s"
-#: ../../Zotlabs/Lib/Apps.php:567
-msgid "Add to app-tray"
-msgstr "Добавить в app-tray"
+#: ../../Zotlabs/Widget/Activity_filter.php:141
+msgid "Show filed post categories"
+msgstr "Показывать категории добавленных публикаций"
-#: ../../Zotlabs/Lib/Apps.php:568
-msgid "Remove from app-tray"
-msgstr "Удалить из app-tray"
+#: ../../Zotlabs/Widget/Activity_filter.php:155
+msgid "Panel search"
+msgstr "Панель поиска"
-#: ../../Zotlabs/Lib/Apps.php:569
-msgid "Pin to navbar"
-msgstr "Добавить на панель навигации"
+#: ../../Zotlabs/Widget/Activity_filter.php:165
+msgid "Filter by name"
+msgstr "Отфильтровать по имени"
-#: ../../Zotlabs/Lib/Apps.php:570
-msgid "Unpin from navbar"
-msgstr "Удалить с панели навигации"
+#: ../../Zotlabs/Widget/Activity_filter.php:180
+msgid "Remove active filter"
+msgstr "Удалить активный фильтр"
-#: ../../Zotlabs/Lib/Permcat.php:82
-msgctxt "permcat"
-msgid "default"
-msgstr "по умолчанию"
+#: ../../Zotlabs/Widget/Activity_filter.php:196
+msgid "Stream Filters"
+msgstr "Фильтры потока"
-#: ../../Zotlabs/Lib/Permcat.php:133
-msgctxt "permcat"
-msgid "follower"
-msgstr "поклонник"
+#: ../../Zotlabs/Widget/Chatroom_members.php:11
+msgid "Chat Members"
+msgstr "Участники чата"
-#: ../../Zotlabs/Lib/Permcat.php:137
-msgctxt "permcat"
-msgid "contributor"
-msgstr "участник"
+#: ../../Zotlabs/Widget/Cover_photo.php:65
+msgid "Click to show more"
+msgstr "Нажмите чтобы показать больше"
-#: ../../Zotlabs/Lib/Permcat.php:141
-msgctxt "permcat"
-msgid "publisher"
-msgstr "издатель"
+#: ../../Zotlabs/Widget/Affinity.php:54
+msgid "Refresh"
+msgstr "Обновить"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:42
-#: ../../Zotlabs/Lib/NativeWikiPage.php:94
-msgid "(No Title)"
-msgstr "(нет заголовка)"
+#: ../../Zotlabs/Widget/Activity_order.php:90
+msgid "Commented Date"
+msgstr "По комментариям"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:109
-msgid "Wiki page create failed."
-msgstr "Не удалось создать страницу Wiki."
+#: ../../Zotlabs/Widget/Activity_order.php:94
+msgid "Order by last commented date"
+msgstr "Сортировка по дате последнего комментария"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:122
-msgid "Wiki not found."
-msgstr "Wiki не найдена."
+#: ../../Zotlabs/Widget/Activity_order.php:97
+msgid "Posted Date"
+msgstr "По публикациям"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:133
-msgid "Destination name already exists"
-msgstr "Имя назначения уже существует"
+#: ../../Zotlabs/Widget/Activity_order.php:101
+msgid "Order by last posted date"
+msgstr "Сортировка по дате последней публикации"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:166
-#: ../../Zotlabs/Lib/NativeWikiPage.php:362
-msgid "Page not found"
-msgstr "Страница не найдена."
+#: ../../Zotlabs/Widget/Activity_order.php:104
+msgid "Date Unthreaded"
+msgstr "По порядку"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:197
-msgid "Error reading page content"
-msgstr "Ошибка чтения содержимого страницы"
+#: ../../Zotlabs/Widget/Activity_order.php:108
+msgid "Order unthreaded by date"
+msgstr "Сортировка в порядке поступления"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:353
-#: ../../Zotlabs/Lib/NativeWikiPage.php:402
-#: ../../Zotlabs/Lib/NativeWikiPage.php:469
-#: ../../Zotlabs/Lib/NativeWikiPage.php:510
-msgid "Error reading wiki"
-msgstr "Ошибка чтения Wiki"
+#: ../../Zotlabs/Widget/Activity_order.php:123
+msgid "Stream Order"
+msgstr "Упорядочить поток"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:390
-msgid "Page update failed."
-msgstr "Не удалось обновить страницу."
+#: ../../Zotlabs/Widget/Bookmarkedchats.php:24
+msgid "Bookmarked Chatrooms"
+msgstr "Закладки чатов"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:424
-msgid "Nothing deleted"
-msgstr "Ничего не удалено"
+#: ../../Zotlabs/Widget/Conversations.php:17
+msgid "Received Messages"
+msgstr "Полученные сообщения"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:490
-msgid "Compare: object not found."
-msgstr "Сравнение: объект не найден."
+#: ../../Zotlabs/Widget/Conversations.php:21
+msgid "Sent Messages"
+msgstr "Отправленные сообщения"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:496
-msgid "Page updated"
-msgstr "Страница обновлена"
+#: ../../Zotlabs/Widget/Conversations.php:25
+msgid "Conversations"
+msgstr "Беседы"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:499
-msgid "Untitled"
-msgstr "Не озаглавлено"
+#: ../../Zotlabs/Widget/Conversations.php:37
+msgid "No messages."
+msgstr "Сообщений нет."
-#: ../../Zotlabs/Lib/NativeWikiPage.php:505
-msgid "Wiki resource_id required for git commit"
-msgstr "Требуется resource_id Wiki для отправки в Git"
+#: ../../Zotlabs/Widget/Conversations.php:57
+msgid "Delete conversation"
+msgstr "Удалить беседу"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:562
#: ../../Zotlabs/Widget/Wiki_page_history.php:23
+#: ../../Zotlabs/Lib/NativeWikiPage.php:562
msgctxt "wiki_history"
msgid "Message"
msgstr "Сообщение"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:563
#: ../../Zotlabs/Widget/Wiki_page_history.php:24
+#: ../../Zotlabs/Lib/NativeWikiPage.php:563
msgid "Date"
msgstr "Дата"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:565
#: ../../Zotlabs/Widget/Wiki_page_history.php:26
+#: ../../Zotlabs/Lib/NativeWikiPage.php:565
msgid "Compare"
msgstr "Сравнить"
-#: ../../Zotlabs/Lib/NativeWikiPage.php:603 ../../include/bbcode.php:735
-#: ../../include/bbcode.php:905
-msgid "Different viewers will see this text differently"
-msgstr "Различные зрители увидят этот текст по-разному"
+#: ../../Zotlabs/Access/Permissions.php:56
+msgid "Can view my channel stream and posts"
+msgstr "Может просматривать мой поток и сообщения"
-#: ../../Zotlabs/Lib/PermissionDescription.php:34
-#: ../../include/acl_selectors.php:33
-msgid "Visible to your default audience"
-msgstr "Видно вашей аудитории по умолчанию."
+#: ../../Zotlabs/Access/Permissions.php:57
+msgid "Can send me their channel stream and posts"
+msgstr "Может присылать мне свои потоки и сообщения"
-#: ../../Zotlabs/Lib/PermissionDescription.php:107
-#: ../../include/acl_selectors.php:106
-msgid "Only me"
-msgstr "Только мне"
+#: ../../Zotlabs/Access/Permissions.php:58
+msgid "Can view my default channel profile"
+msgstr "Может просматривать мой стандартный профиль канала"
-#: ../../Zotlabs/Lib/PermissionDescription.php:108
-msgid "Public"
-msgstr "Общедоступно"
+#: ../../Zotlabs/Access/Permissions.php:59
+msgid "Can view my connections"
+msgstr "Может просматривать мои контакты"
-#: ../../Zotlabs/Lib/PermissionDescription.php:109
-msgid "Anybody in the $Projectname network"
-msgstr "Любому в сети $Projectname"
+#: ../../Zotlabs/Access/Permissions.php:60
+msgid "Can view my file storage and photos"
+msgstr "Может просматривать мое хранилище файлов"
-#: ../../Zotlabs/Lib/PermissionDescription.php:110
-#, php-format
-msgid "Any account on %s"
-msgstr "Любой аккаунт в %s"
+#: ../../Zotlabs/Access/Permissions.php:61
+msgid "Can upload/modify my file storage and photos"
+msgstr "Может загружать/изменять мои файлы и фотографии в хранилище"
-#: ../../Zotlabs/Lib/PermissionDescription.php:111
-msgid "Any of my connections"
-msgstr "Любой из моих контактов"
+#: ../../Zotlabs/Access/Permissions.php:62
+msgid "Can view my channel webpages"
+msgstr "Может просматривать мои веб-страницы"
-#: ../../Zotlabs/Lib/PermissionDescription.php:112
-msgid "Only connections I specifically allow"
-msgstr "Только те контакты, кому я дам разрешение"
+#: ../../Zotlabs/Access/Permissions.php:63
+msgid "Can view my wiki pages"
+msgstr "Может просматривать мои вики-страницы"
-#: ../../Zotlabs/Lib/PermissionDescription.php:113
-msgid "Anybody authenticated (could include visitors from other networks)"
-msgstr "Любой аутентифицированный (может включать посетителей их других сетей)"
+#: ../../Zotlabs/Access/Permissions.php:64
+msgid "Can create/edit my channel webpages"
+msgstr "Может редактировать мои веб-страницы"
-#: ../../Zotlabs/Lib/PermissionDescription.php:114
-msgid "Any connections including those who haven't yet been approved"
-msgstr "Любые контакты включая те, которые вы ещё не одобрили"
+#: ../../Zotlabs/Access/Permissions.php:65
+msgid "Can write to my wiki pages"
+msgstr "Может редактировать мои вики-страницы"
-#: ../../Zotlabs/Lib/PermissionDescription.php:150
-msgid ""
-"This is your default setting for the audience of your normal stream, and "
-"posts."
-msgstr "Это настройка по умолчанию для аудитории ваших обычных потоков и публикаций"
+#: ../../Zotlabs/Access/Permissions.php:66
+msgid "Can post on my channel (wall) page"
+msgstr "Может публиковать на моей странице канала"
-#: ../../Zotlabs/Lib/PermissionDescription.php:151
-msgid ""
-"This is your default setting for who can view your default channel profile"
-msgstr "Это настройка по умолчанию для тех, кто может просматривать профиль вашего основного канала"
+#: ../../Zotlabs/Access/Permissions.php:67
+msgid "Can comment on or like my posts"
+msgstr "Может прокомментировать или отмечать как понравившиеся мои публикации"
-#: ../../Zotlabs/Lib/PermissionDescription.php:152
-msgid "This is your default setting for who can view your connections"
-msgstr "Это настройка по умолчанию для тех, кто может просматривать ваши контакты"
+#: ../../Zotlabs/Access/Permissions.php:68
+msgid "Can send me private mail messages"
+msgstr "Может отправлять мне личные сообщения по эл. почте"
-#: ../../Zotlabs/Lib/PermissionDescription.php:153
-msgid ""
-"This is your default setting for who can view your file storage and photos"
-msgstr "Это настройка по умолчанию для тех, кто может просматривать ваше хранилище файлов и фотографий"
+#: ../../Zotlabs/Access/Permissions.php:69
+msgid "Can like/dislike profiles and profile things"
+msgstr "Может комментировать или отмечать как нравится/ненравится мой профиль"
-#: ../../Zotlabs/Lib/PermissionDescription.php:154
-msgid "This is your default setting for the audience of your webpages"
-msgstr "Это настройка по умолчанию для аудитории ваших веб-страниц"
+#: ../../Zotlabs/Access/Permissions.php:70
+msgid "Can forward to all my channel connections via ! mentions in posts"
+msgstr "Может пересылать всем подписчикам моего канала используя ! в публикациях"
-#: ../../Zotlabs/Lib/Libzotdir.php:160 ../../include/dir_fns.php:141
-msgid "Directory Options"
-msgstr "Параметры каталога"
+#: ../../Zotlabs/Access/Permissions.php:71
+msgid "Can chat with me"
+msgstr "Может общаться со мной в чате"
-#: ../../Zotlabs/Lib/Libzotdir.php:162 ../../include/dir_fns.php:143
-msgid "Safe Mode"
-msgstr "Безопасный режим"
+#: ../../Zotlabs/Access/Permissions.php:72
+msgid "Can source my public posts in derived channels"
+msgstr "Может использовать мои публичные сообщения в клонированных лентах сообщений"
-#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../include/dir_fns.php:144
-msgid "Public Forums Only"
-msgstr "Только публичные форумы"
+#: ../../Zotlabs/Access/Permissions.php:73
+msgid "Can administer my channel"
+msgstr "Может администрировать мой канал"
-#: ../../Zotlabs/Lib/Libzotdir.php:165 ../../include/dir_fns.php:145
-msgid "This Website Only"
-msgstr "Только этот веб-сайт"
+#: ../../Zotlabs/Access/PermissionRoles.php:283
+msgid "Social Networking"
+msgstr "Социальная Сеть"
-#: ../../Zotlabs/Lib/Group.php:28 ../../include/group.php:22
-msgid ""
-"A deleted group with this name was revived. Existing item permissions "
-"<strong>may</strong> apply to this group and any future members. If this is "
-"not what you intended, please create another group with a different name."
-msgstr "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт <strong>могут</strong> применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем."
+#: ../../Zotlabs/Access/PermissionRoles.php:284
+msgid "Social - Federation"
+msgstr "Социальная - Федерация"
-#: ../../Zotlabs/Lib/Group.php:270 ../../include/group.php:264
-msgid "Add new connections to this privacy group"
-msgstr "Добавить новые контакты в группу безопасности"
+#: ../../Zotlabs/Access/PermissionRoles.php:285
+msgid "Social - Mostly Public"
+msgstr "Социальная - В основном общественный"
-#: ../../Zotlabs/Lib/Group.php:302 ../../include/group.php:298
-msgid "edit"
-msgstr "редактировать"
+#: ../../Zotlabs/Access/PermissionRoles.php:286
+msgid "Social - Restricted"
+msgstr "Социальная - Ограниченный"
-#: ../../Zotlabs/Lib/Group.php:325 ../../include/group.php:321
-msgid "Edit group"
-msgstr "Редактировать группу"
+#: ../../Zotlabs/Access/PermissionRoles.php:287
+msgid "Social - Private"
+msgstr "Социальная - Частный"
-#: ../../Zotlabs/Lib/Group.php:326 ../../include/group.php:322
-msgid "Add privacy group"
-msgstr "Добавить группу безопасности"
+#: ../../Zotlabs/Access/PermissionRoles.php:290
+msgid "Community Forum"
+msgstr "Форум сообщества"
-#: ../../Zotlabs/Lib/Group.php:327 ../../include/group.php:323
-msgid "Channels not in any privacy group"
-msgstr "Каналы не включены ни в одну группу безопасности"
+#: ../../Zotlabs/Access/PermissionRoles.php:291
+msgid "Forum - Mostly Public"
+msgstr "Форум - В основном общественный"
-#: ../../Zotlabs/Lib/Group.php:329 ../../Zotlabs/Widget/Savedsearch.php:84
-#: ../../include/group.php:325
-msgid "add"
-msgstr "добавить"
+#: ../../Zotlabs/Access/PermissionRoles.php:292
+msgid "Forum - Restricted"
+msgstr "Форум - Ограниченный"
-#: ../../Zotlabs/Lib/Chatroom.php:23
-msgid "Missing room name"
-msgstr "Отсутствует название комнаты"
+#: ../../Zotlabs/Access/PermissionRoles.php:293
+msgid "Forum - Private"
+msgstr "Форум - Частный"
-#: ../../Zotlabs/Lib/Chatroom.php:32
-msgid "Duplicate room name"
-msgstr "Название комнаты дублируется"
+#: ../../Zotlabs/Access/PermissionRoles.php:296
+msgid "Feed Republish"
+msgstr "Публиковать ленты новостей"
-#: ../../Zotlabs/Lib/Chatroom.php:82 ../../Zotlabs/Lib/Chatroom.php:90
-msgid "Invalid room specifier."
-msgstr "Неверный указатель комнаты."
+#: ../../Zotlabs/Access/PermissionRoles.php:297
+msgid "Feed - Mostly Public"
+msgstr "Ленты новостей - В основном общественный"
-#: ../../Zotlabs/Lib/Chatroom.php:122
-msgid "Room not found."
-msgstr "Комната не найдена."
+#: ../../Zotlabs/Access/PermissionRoles.php:298
+msgid "Feed - Restricted"
+msgstr "Ленты новостей - Ограниченный"
-#: ../../Zotlabs/Lib/Chatroom.php:143
-msgid "Room is full"
-msgstr "Комната переполнена"
+#: ../../Zotlabs/Access/PermissionRoles.php:301
+msgid "Special Purpose"
+msgstr "Спец. назначение"
+
+#: ../../Zotlabs/Access/PermissionRoles.php:302
+msgid "Special - Celebrity/Soapbox"
+msgstr "Спец. назначение - Знаменитость/Soapbox"
+
+#: ../../Zotlabs/Access/PermissionRoles.php:303
+msgid "Special - Group Repository"
+msgstr "Спец. назначение - Групповой репозиторий"
+
+#: ../../Zotlabs/Access/PermissionRoles.php:307
+msgid "Custom/Expert Mode"
+msgstr "Экспертный режим"
-#: ../../Zotlabs/Lib/Libsync.php:733 ../../include/zot.php:2591
+#: ../../Zotlabs/Lib/DB_Upgrade.php:83
#, php-format
-msgid "Unable to verify site signature for %s"
-msgstr "Невозможно проверить подпись сайта %s"
+msgid "Update Error at %s"
+msgstr "Ошибка обновления на %s"
+
+#: ../../Zotlabs/Lib/DB_Upgrade.php:89
+#, php-format
+msgid "Update %s failed. See error logs."
+msgstr "Выполнение %s неудачно. Проверьте системный журнал."
#: ../../Zotlabs/Lib/Enotify.php:60
msgid "$Projectname Notification"
msgstr "Оповещение $Projectname "
-#: ../../Zotlabs/Lib/Enotify.php:61 ../../addon/diaspora/util.php:313
-#: ../../addon/diaspora/util.php:326 ../../addon/diaspora/p.php:48
+#: ../../Zotlabs/Lib/Enotify.php:61
+#: ../../extend/addon/hzaddons/diaspora/p.php:48
+#: ../../extend/addon/hzaddons/diaspora/util.php:324
+#: ../../extend/addon/hzaddons/diaspora/util.php:337
msgid "$projectname"
msgstr ""
@@ -8548,7 +11681,8 @@ msgstr ""
msgid "Thank You,"
msgstr "Спасибо,"
-#: ../../Zotlabs/Lib/Enotify.php:65 ../../addon/hubwall/hubwall.php:33
+#: ../../Zotlabs/Lib/Enotify.php:65
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:33
#, php-format
msgid "%s Administrator"
msgstr "администратор %s"
@@ -8802,40 +11936,229 @@ msgstr "отредактировал публикацию датированну
msgid "edited a comment dated %s"
msgstr "отредактировал комментарий датированный %s"
-#: ../../Zotlabs/Lib/NativeWiki.php:143
-msgid "Wiki updated successfully"
-msgstr "Wiki успешно обновлена"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:42
+#: ../../Zotlabs/Lib/NativeWikiPage.php:94
+msgid "(No Title)"
+msgstr "(нет заголовка)"
-#: ../../Zotlabs/Lib/NativeWiki.php:197
-msgid "Wiki files deleted successfully"
-msgstr "Wiki успешно удалена"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:109
+msgid "Wiki page create failed."
+msgstr "Не удалось создать страницу Wiki."
-#: ../../Zotlabs/Lib/DB_Upgrade.php:83
-#, php-format
-msgid "Update Error at %s"
-msgstr "Ошибка обновления на %s"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:122
+msgid "Wiki not found."
+msgstr "Wiki не найдена."
-#: ../../Zotlabs/Lib/DB_Upgrade.php:89
-#, php-format
-msgid "Update %s failed. See error logs."
-msgstr "Выполнение %s неудачно. Проверьте системный журнал."
+#: ../../Zotlabs/Lib/NativeWikiPage.php:133
+msgid "Destination name already exists"
+msgstr "Имя назначения уже существует"
-#: ../../Zotlabs/Lib/ThreadItem.php:102 ../../include/conversation.php:700
-msgid "Private Message"
-msgstr "Личное сообщение"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:166
+#: ../../Zotlabs/Lib/NativeWikiPage.php:362
+msgid "Page not found"
+msgstr "Страница не найдена."
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:197
+msgid "Error reading page content"
+msgstr "Ошибка чтения содержимого страницы"
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:353
+#: ../../Zotlabs/Lib/NativeWikiPage.php:402
+#: ../../Zotlabs/Lib/NativeWikiPage.php:469
+#: ../../Zotlabs/Lib/NativeWikiPage.php:510
+msgid "Error reading wiki"
+msgstr "Ошибка чтения Wiki"
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:390
+msgid "Page update failed."
+msgstr "Не удалось обновить страницу."
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:424
+msgid "Nothing deleted"
+msgstr "Ничего не удалено"
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:490
+msgid "Compare: object not found."
+msgstr "Сравнение: объект не найден."
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:496
+msgid "Page updated"
+msgstr "Страница обновлена"
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:499
+msgid "Untitled"
+msgstr "Не озаглавлено"
+
+#: ../../Zotlabs/Lib/NativeWikiPage.php:505
+msgid "Wiki resource_id required for git commit"
+msgstr "Требуется resource_id Wiki для отправки в Git"
+
+#: ../../Zotlabs/Lib/Permcat.php:82
+msgctxt "permcat"
+msgid "default"
+msgstr "по умолчанию"
+
+#: ../../Zotlabs/Lib/Permcat.php:133
+msgctxt "permcat"
+msgid "follower"
+msgstr "поклонник"
+
+#: ../../Zotlabs/Lib/Permcat.php:137
+msgctxt "permcat"
+msgid "contributor"
+msgstr "участник"
+
+#: ../../Zotlabs/Lib/Permcat.php:141
+msgctxt "permcat"
+msgid "publisher"
+msgstr "издатель"
+
+#: ../../Zotlabs/Lib/Apps.php:322
+msgid "Apps"
+msgstr "Приложения"
+
+#: ../../Zotlabs/Lib/Apps.php:323
+msgid "Affinity Tool"
+msgstr "Степень сходства"
+
+#: ../../Zotlabs/Lib/Apps.php:326
+msgid "Site Admin"
+msgstr "Администратор сайта"
+
+#: ../../Zotlabs/Lib/Apps.php:327
+#: ../../extend/addon/hzaddons/buglink/buglink.php:16
+msgid "Report Bug"
+msgstr "Сообщить об ошибке"
+
+#: ../../Zotlabs/Lib/Apps.php:330
+msgid "Content Filter"
+msgstr "Фильтр содержимого"
+
+#: ../../Zotlabs/Lib/Apps.php:331
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:135
+msgid "Content Import"
+msgstr "Импорт содержимого"
+
+#: ../../Zotlabs/Lib/Apps.php:333
+msgid "Remote Diagnostics"
+msgstr "Удалённая диагностика"
+
+#: ../../Zotlabs/Lib/Apps.php:334
+msgid "Suggest Channels"
+msgstr "Предлагаемые каналы"
+
+#: ../../Zotlabs/Lib/Apps.php:337
+msgid "Stream"
+msgstr "Поток"
+
+#: ../../Zotlabs/Lib/Apps.php:348
+msgid "Mail"
+msgstr "Переписка"
+
+#: ../../Zotlabs/Lib/Apps.php:351
+msgid "Chat"
+msgstr "Чат"
+
+#: ../../Zotlabs/Lib/Apps.php:353
+msgid "Probe"
+msgstr "Проба"
+
+#: ../../Zotlabs/Lib/Apps.php:354
+msgid "Suggest"
+msgstr "Предложить"
+
+#: ../../Zotlabs/Lib/Apps.php:355
+msgid "Random Channel"
+msgstr "Случайный канал"
+
+#: ../../Zotlabs/Lib/Apps.php:356
+msgid "Invite"
+msgstr "Пригласить"
+
+#: ../../Zotlabs/Lib/Apps.php:358
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:69
+msgid "Language"
+msgstr "Язык"
+
+#: ../../Zotlabs/Lib/Apps.php:359
+msgid "Post"
+msgstr "Публикация"
+
+#: ../../Zotlabs/Lib/Apps.php:360
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:58
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:59
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:60
+msgid "Profile Photo"
+msgstr "Фотография профиля"
+
+#: ../../Zotlabs/Lib/Apps.php:364
+msgid "Notifications"
+msgstr "Оповещения"
+
+#: ../../Zotlabs/Lib/Apps.php:365
+msgid "Order Apps"
+msgstr "Порядок приложений"
+
+#: ../../Zotlabs/Lib/Apps.php:367
+msgid "CardDAV"
+msgstr ""
+
+#: ../../Zotlabs/Lib/Apps.php:369
+msgid "Guest Access"
+msgstr "Гостевой доступ"
+
+#: ../../Zotlabs/Lib/Apps.php:371
+msgid "OAuth Apps Manager"
+msgstr "Менеджер OAuth"
+
+#: ../../Zotlabs/Lib/Apps.php:372
+msgid "OAuth2 Apps Manager"
+msgstr "Менеджер OAuth2"
+
+#: ../../Zotlabs/Lib/Apps.php:373
+msgid "PDL Editor"
+msgstr "Редактор PDL"
+
+#: ../../Zotlabs/Lib/Apps.php:375
+msgid "Premium Channel"
+msgstr "Премиальный канал"
+
+#: ../../Zotlabs/Lib/Apps.php:377
+msgid "My Chatrooms"
+msgstr "Мои чаты"
+
+#: ../../Zotlabs/Lib/Apps.php:378
+msgid "Channel Export"
+msgstr "Экспорт канала"
+
+#: ../../Zotlabs/Lib/Apps.php:555
+msgid "Purchase"
+msgstr "Купить"
+
+#: ../../Zotlabs/Lib/Apps.php:560
+msgid "Undelete"
+msgstr "Восстановить"
+
+#: ../../Zotlabs/Lib/Apps.php:569
+msgid "Add to app-tray"
+msgstr "Добавить в app-tray"
+
+#: ../../Zotlabs/Lib/Apps.php:570
+msgid "Remove from app-tray"
+msgstr "Удалить из app-tray"
+
+#: ../../Zotlabs/Lib/Apps.php:571
+msgid "Pin to navbar"
+msgstr "Добавить на панель навигации"
+
+#: ../../Zotlabs/Lib/Apps.php:572
+msgid "Unpin from navbar"
+msgstr "Удалить с панели навигации"
#: ../../Zotlabs/Lib/ThreadItem.php:129
msgid "Privacy conflict. Discretion advised."
msgstr "Конфиликт настроек конфиденциальности."
-#: ../../Zotlabs/Lib/ThreadItem.php:171 ../../Zotlabs/Storage/Browser.php:280
-msgid "Admin Delete"
-msgstr "Удалено администратором"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:177 ../../include/conversation.php:690
-msgid "Select"
-msgstr "Выбрать"
-
#: ../../Zotlabs/Lib/ThreadItem.php:202
msgid "I will attend"
msgstr "Я буду участвовать"
@@ -8860,34 +12183,10 @@ msgstr "Я не согласен"
msgid "I abstain"
msgstr "Я воздержался"
-#: ../../Zotlabs/Lib/ThreadItem.php:266 ../../include/conversation.php:695
-msgid "Toggle Star Status"
-msgstr "Переключить статус пометки"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:277 ../../include/conversation.php:707
-msgid "Message signature validated"
-msgstr "Подпись сообщения проверена"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:278 ../../include/conversation.php:708
-msgid "Message signature incorrect"
-msgstr "Подпись сообщения неверная"
-
#: ../../Zotlabs/Lib/ThreadItem.php:286
msgid "Add Tag"
msgstr "Добавить тег"
-#: ../../Zotlabs/Lib/ThreadItem.php:290 ../../include/conversation.php:891
-msgid "Conversation Tools"
-msgstr "Инструменты общения"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:306 ../../include/taxonomy.php:575
-msgid "like"
-msgstr "нравится"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:307 ../../include/taxonomy.php:576
-msgid "dislike"
-msgstr "не нравится"
-
#: ../../Zotlabs/Lib/ThreadItem.php:317
msgid "Share This"
msgstr "Поделиться этим"
@@ -8929,21 +12228,6 @@ msgstr "Стена-к-Стене"
msgid "via Wall-To-Wall:"
msgstr "через Стена-к-Стене:"
-#: ../../Zotlabs/Lib/ThreadItem.php:402 ../../include/conversation.php:766
-#, php-format
-msgid "from %s"
-msgstr "от %s"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:405 ../../include/conversation.php:769
-#, php-format
-msgid "last edited: %s"
-msgstr "последнее редактирование: %s"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:406 ../../include/conversation.php:770
-#, php-format
-msgid "Expires: %s"
-msgstr "Срок действия: %s"
-
#: ../../Zotlabs/Lib/ThreadItem.php:414
msgid "Attend"
msgstr "Посетить"
@@ -8961,7 +12245,7 @@ msgid "Voting Options"
msgstr "Параметры голосования"
#: ../../Zotlabs/Lib/ThreadItem.php:439
-#: ../../addon/bookmarker/bookmarker.php:38
+#: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38
msgid "Save Bookmarks"
msgstr "Сохранить закладки"
@@ -8969,49 +12253,10 @@ msgstr "Сохранить закладки"
msgid "Add to Calendar"
msgstr "Добавить в календарь"
-#: ../../Zotlabs/Lib/ThreadItem.php:468 ../../include/conversation.php:483
-msgid "This is an unsaved preview"
-msgstr "Это несохранённый просмотр"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:501 ../../include/js_strings.php:7
-#, php-format
-msgid "%s show all"
-msgstr "%s показать всё"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:796 ../../addon/hsse/hsse.php:200
-#: ../../include/conversation.php:1406
-msgid "Bold"
-msgstr "Жирный"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:797 ../../addon/hsse/hsse.php:201
-#: ../../include/conversation.php:1407
-msgid "Italic"
-msgstr "Курсив"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:798 ../../addon/hsse/hsse.php:202
-#: ../../include/conversation.php:1408
-msgid "Underline"
-msgstr "Подчеркнутый"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:799 ../../addon/hsse/hsse.php:203
-#: ../../include/conversation.php:1409
-msgid "Quote"
-msgstr "Цитата"
-
-#: ../../Zotlabs/Lib/ThreadItem.php:800 ../../addon/hsse/hsse.php:204
-#: ../../include/conversation.php:1410
-msgid "Code"
-msgstr "Код"
-
#: ../../Zotlabs/Lib/ThreadItem.php:801
msgid "Image"
msgstr "Изображение"
-#: ../../Zotlabs/Lib/ThreadItem.php:802 ../../addon/hsse/hsse.php:205
-#: ../../include/conversation.php:1411
-msgid "Attach/Upload file"
-msgstr "Прикрепить/загрузить файл"
-
#: ../../Zotlabs/Lib/ThreadItem.php:803
msgid "Insert Link"
msgstr "Вставить ссылку"
@@ -9032,2903 +12277,1518 @@ msgstr "Ваш адрес электронной почты (требуется)
msgid "Your website URL (optional)"
msgstr "URL вашего вебсайта (необязательно)"
-#: ../../Zotlabs/Zot/Auth.php:152
-msgid ""
-"Remote authentication blocked. You are logged into this site locally. Please "
-"logout and retry."
-msgstr "Удалённая аутентификация заблокирована. Вы вошли на этот сайт локально. Пожалуйста, выйдите и попробуйте ещё раз."
-
-#: ../../Zotlabs/Zot/Auth.php:264 ../../addon/openid/Mod_Openid.php:76
-#: ../../addon/openid/Mod_Openid.php:178
-#, php-format
-msgid "Welcome %s. Remote authentication successful."
-msgstr "Добро пожаловать %s. Удаленная аутентификация успешно завершена."
-
-#: ../../Zotlabs/Storage/Browser.php:107 ../../Zotlabs/Storage/Browser.php:289
-msgid "parent"
-msgstr "источник"
-
-#: ../../Zotlabs/Storage/Browser.php:131 ../../include/text.php:2941
-msgid "Collection"
-msgstr "Коллекция"
-
-#: ../../Zotlabs/Storage/Browser.php:134
-msgid "Principal"
-msgstr "Субъект"
-
-#: ../../Zotlabs/Storage/Browser.php:137
-msgid "Addressbook"
-msgstr "Адресная книга"
-
-#: ../../Zotlabs/Storage/Browser.php:140 ../../include/nav.php:463
-#: ../../include/nav.php:466
-msgid "Calendar"
-msgstr "Календарь"
+#: ../../Zotlabs/Lib/Chatroom.php:23
+msgid "Missing room name"
+msgstr "Отсутствует название комнаты"
-#: ../../Zotlabs/Storage/Browser.php:143
-msgid "Schedule Inbox"
-msgstr "План занятий входящий"
+#: ../../Zotlabs/Lib/Chatroom.php:32
+msgid "Duplicate room name"
+msgstr "Название комнаты дублируется"
-#: ../../Zotlabs/Storage/Browser.php:146
-msgid "Schedule Outbox"
-msgstr "План занятий исходящий"
+#: ../../Zotlabs/Lib/Chatroom.php:82 ../../Zotlabs/Lib/Chatroom.php:90
+msgid "Invalid room specifier."
+msgstr "Неверный указатель комнаты."
-#: ../../Zotlabs/Storage/Browser.php:273
-msgid "Total"
-msgstr "Всего"
+#: ../../Zotlabs/Lib/Chatroom.php:122
+msgid "Room not found."
+msgstr "Комната не найдена."
-#: ../../Zotlabs/Storage/Browser.php:275
-msgid "Shared"
-msgstr "Общие"
+#: ../../Zotlabs/Lib/Chatroom.php:143
+msgid "Room is full"
+msgstr "Комната переполнена"
-#: ../../Zotlabs/Storage/Browser.php:277
-msgid "Add Files"
-msgstr "Добавить файлы"
+#: ../../Zotlabs/Lib/PermissionDescription.php:108
+msgid "Public"
+msgstr "Общедоступно"
-#: ../../Zotlabs/Storage/Browser.php:361
-#, php-format
-msgid "You are using %1$s of your available file storage."
-msgstr "Вы используете %1$s из доступного вам хранилища файлов."
+#: ../../Zotlabs/Lib/PermissionDescription.php:109
+msgid "Anybody in the $Projectname network"
+msgstr "Любому в сети $Projectname"
-#: ../../Zotlabs/Storage/Browser.php:366
+#: ../../Zotlabs/Lib/PermissionDescription.php:110
#, php-format
-msgid "You are using %1$s of %2$s available file storage. (%3$s&#37;)"
-msgstr "Вы используете %1$s из %2$s доступного хранилища файлов (%3$s&#37;)."
-
-#: ../../Zotlabs/Storage/Browser.php:377
-msgid "WARNING:"
-msgstr "Предупреждение:"
-
-#: ../../Zotlabs/Storage/Browser.php:389
-msgid "Create new folder"
-msgstr "Создать новую папку"
-
-#: ../../Zotlabs/Storage/Browser.php:391
-msgid "Upload file"
-msgstr "Загрузить файл"
-
-#: ../../Zotlabs/Storage/Browser.php:404
-msgid "Drop files here to immediately upload"
-msgstr "Поместите файлы сюда для немедленной загрузки"
-
-#: ../../Zotlabs/Widget/Forums.php:100
-#: ../../Zotlabs/Widget/Activity_filter.php:73
-#: ../../Zotlabs/Widget/Notifications.php:119
-#: ../../Zotlabs/Widget/Notifications.php:120
-msgid "Forums"
-msgstr "Форумы"
-
-#: ../../Zotlabs/Widget/Cdav.php:37
-msgid "Select Channel"
-msgstr "Выбрать канал"
-
-#: ../../Zotlabs/Widget/Cdav.php:42
-msgid "Read-write"
-msgstr "Чтение-запись"
-
-#: ../../Zotlabs/Widget/Cdav.php:43
-msgid "Read-only"
-msgstr "Только чтение"
-
-#: ../../Zotlabs/Widget/Cdav.php:117
-msgid "My Calendars"
-msgstr "Мои календари"
-
-#: ../../Zotlabs/Widget/Cdav.php:119
-msgid "Shared Calendars"
-msgstr "Общие календари"
-
-#: ../../Zotlabs/Widget/Cdav.php:123
-msgid "Share this calendar"
-msgstr "Поделиться этим календарём"
-
-#: ../../Zotlabs/Widget/Cdav.php:125
-msgid "Calendar name and color"
-msgstr "Имя и цвет календаря"
-
-#: ../../Zotlabs/Widget/Cdav.php:127
-msgid "Create new calendar"
-msgstr "Создать новый календарь"
-
-#: ../../Zotlabs/Widget/Cdav.php:129
-msgid "Calendar Name"
-msgstr "Имя календаря"
-
-#: ../../Zotlabs/Widget/Cdav.php:130
-msgid "Calendar Tools"
-msgstr "Инструменты календаря"
-
-#: ../../Zotlabs/Widget/Cdav.php:131
-msgid "Import calendar"
-msgstr "Импортировать календарь"
-
-#: ../../Zotlabs/Widget/Cdav.php:132
-msgid "Select a calendar to import to"
-msgstr "Выбрать календарь для импорта в"
-
-#: ../../Zotlabs/Widget/Cdav.php:159
-msgid "Addressbooks"
-msgstr "Адресные книги"
-
-#: ../../Zotlabs/Widget/Cdav.php:161
-msgid "Addressbook name"
-msgstr "Имя адресной книги"
-
-#: ../../Zotlabs/Widget/Cdav.php:163
-msgid "Create new addressbook"
-msgstr "Создать новую адресную книгу"
-
-#: ../../Zotlabs/Widget/Cdav.php:164
-msgid "Addressbook Name"
-msgstr "Имя адресной книги"
-
-#: ../../Zotlabs/Widget/Cdav.php:166
-msgid "Addressbook Tools"
-msgstr "Инструменты адресной книги"
-
-#: ../../Zotlabs/Widget/Cdav.php:167
-msgid "Import addressbook"
-msgstr "Импортировать адресную книгу"
-
-#: ../../Zotlabs/Widget/Cdav.php:168
-msgid "Select an addressbook to import to"
-msgstr "Выбрать адресную книгу для импорта в"
-
-#: ../../Zotlabs/Widget/Appcategories.php:43
-#: ../../include/contact_widgets.php:96 ../../include/contact_widgets.php:139
-#: ../../include/contact_widgets.php:184 ../../include/taxonomy.php:409
-#: ../../include/taxonomy.php:491 ../../include/taxonomy.php:511
-#: ../../include/taxonomy.php:532
-msgid "Categories"
-msgstr "Категории"
-
-#: ../../Zotlabs/Widget/Appcategories.php:46 ../../Zotlabs/Widget/Filer.php:31
-#: ../../widget/Netselect/Netselect.php:26 ../../include/contact_widgets.php:56
-#: ../../include/contact_widgets.php:99 ../../include/contact_widgets.php:142
-#: ../../include/contact_widgets.php:187
-msgid "Everything"
-msgstr "Всё"
-
-#: ../../Zotlabs/Widget/Eventstools.php:13
-msgid "Events Tools"
-msgstr "Инструменты для событий"
-
-#: ../../Zotlabs/Widget/Eventstools.php:14
-msgid "Export Calendar"
-msgstr "Экспортировать календарь"
-
-#: ../../Zotlabs/Widget/Eventstools.php:15
-msgid "Import Calendar"
-msgstr "Импортировать календарь"
-
-#: ../../Zotlabs/Widget/Suggestedchats.php:32
-msgid "Suggested Chatrooms"
-msgstr "Рекомендуемые чаты"
-
-#: ../../Zotlabs/Widget/Hq_controls.php:14
-msgid "HQ Control Panel"
-msgstr "Панель управления HQ"
-
-#: ../../Zotlabs/Widget/Hq_controls.php:17
-msgid "Create a new post"
-msgstr "Создать новую публикацию"
-
-#: ../../Zotlabs/Widget/Mailmenu.php:13
-msgid "Private Mail Menu"
-msgstr "Меню личной переписки"
+msgid "Any account on %s"
+msgstr "Любой аккаунт в %s"
-#: ../../Zotlabs/Widget/Mailmenu.php:15
-msgid "Combined View"
-msgstr "Комбинированный вид"
+#: ../../Zotlabs/Lib/PermissionDescription.php:111
+msgid "Any of my connections"
+msgstr "Любой из моих контактов"
-#: ../../Zotlabs/Widget/Mailmenu.php:20
-msgid "Inbox"
-msgstr "Входящие"
+#: ../../Zotlabs/Lib/PermissionDescription.php:112
+msgid "Only connections I specifically allow"
+msgstr "Только те контакты, кому я дам разрешение"
-#: ../../Zotlabs/Widget/Mailmenu.php:25
-msgid "Outbox"
-msgstr "Исходящие"
+#: ../../Zotlabs/Lib/PermissionDescription.php:113
+msgid "Anybody authenticated (could include visitors from other networks)"
+msgstr "Любой аутентифицированный (может включать посетителей их других сетей)"
-#: ../../Zotlabs/Widget/Mailmenu.php:30
-msgid "New Message"
-msgstr "Новое сообщение"
+#: ../../Zotlabs/Lib/PermissionDescription.php:114
+msgid "Any connections including those who haven't yet been approved"
+msgstr "Любые контакты включая те, которые вы ещё не одобрили"
-#: ../../Zotlabs/Widget/Chatroom_list.php:20
-msgid "Overview"
-msgstr "Обзор"
+#: ../../Zotlabs/Lib/PermissionDescription.php:150
+msgid ""
+"This is your default setting for the audience of your normal stream, and "
+"posts."
+msgstr "Это настройка по умолчанию для аудитории ваших обычных потоков и публикаций"
-#: ../../Zotlabs/Widget/Rating.php:51
-msgid "Rating Tools"
-msgstr "Инструменты оценки"
+#: ../../Zotlabs/Lib/PermissionDescription.php:151
+msgid ""
+"This is your default setting for who can view your default channel profile"
+msgstr "Это настройка по умолчанию для тех, кто может просматривать профиль вашего основного канала"
-#: ../../Zotlabs/Widget/Rating.php:55 ../../Zotlabs/Widget/Rating.php:57
-msgid "Rate Me"
-msgstr "Оценить меня"
+#: ../../Zotlabs/Lib/PermissionDescription.php:152
+msgid "This is your default setting for who can view your connections"
+msgstr "Это настройка по умолчанию для тех, кто может просматривать ваши контакты"
-#: ../../Zotlabs/Widget/Rating.php:60
-msgid "View Ratings"
-msgstr "Просмотр оценок"
+#: ../../Zotlabs/Lib/PermissionDescription.php:153
+msgid ""
+"This is your default setting for who can view your file storage and photos"
+msgstr "Это настройка по умолчанию для тех, кто может просматривать ваше хранилище файлов и фотографий"
-#: ../../Zotlabs/Widget/Activity.php:50
-msgctxt "widget"
-msgid "Activity"
-msgstr "Активность"
+#: ../../Zotlabs/Lib/PermissionDescription.php:154
+msgid "This is your default setting for the audience of your webpages"
+msgstr "Это настройка по умолчанию для аудитории ваших веб-страниц"
-#: ../../Zotlabs/Widget/Activity_filter.php:36
+#: ../../Zotlabs/Lib/Activity.php:1506
#, php-format
-msgid "Show posts related to the %s privacy group"
-msgstr "Показывать публикации относящиеся к группе безопасности %s"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:45
-msgid "Show my privacy groups"
-msgstr "Показывать мои группы безопасности"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:66
-msgid "Show posts to this forum"
-msgstr "Показывать публикации этого форума"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:77
-msgid "Show forums"
-msgstr "Показывать форумы"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:91
-msgid "Starred Posts"
-msgstr "Отмеченные публикации"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:95
-msgid "Show posts that I have starred"
-msgstr "Показывать публикации которые я отметил"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:106
-msgid "Personal Posts"
-msgstr "Личные публикации"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:110
-msgid "Show posts that mention or involve me"
-msgstr "Показывать публикации где вы были упомянуты или привлечены"
+msgid "Likes %1$s's %2$s"
+msgstr "Нравится %1$s %2$s"
-#: ../../Zotlabs/Widget/Activity_filter.php:131
+#: ../../Zotlabs/Lib/Activity.php:1509
#, php-format
-msgid "Show posts that I have filed to %s"
-msgstr "Показывать публикации которые я добавил в %s"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:137
-#: ../../Zotlabs/Widget/Filer.php:28 ../../include/contact_widgets.php:53
-#: ../../include/features.php:325
-msgid "Saved Folders"
-msgstr "Сохранённые каталоги"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:141
-msgid "Show filed post categories"
-msgstr "Показывать категории добавленных публикаций"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:155
-msgid "Panel search"
-msgstr "Панель поиска"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:165
-msgid "Filter by name"
-msgstr "Отфильтровать по имени"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:180
-msgid "Remove active filter"
-msgstr "Удалить активный фильтр"
-
-#: ../../Zotlabs/Widget/Activity_filter.php:196
-msgid "Stream Filters"
-msgstr "Фильтры потока"
+msgid "Doesn't like %1$s's %2$s"
+msgstr "Не нравится %1$s %2$s"
-#: ../../Zotlabs/Widget/Follow.php:22
+#: ../../Zotlabs/Lib/Activity.php:1512
#, php-format
-msgid "You have %1$.0f of %2$.0f allowed connections."
-msgstr "У вас есть %1$.0f из %2$.0f разрешенных контактов."
-
-#: ../../Zotlabs/Widget/Follow.php:29
-msgid "Add New Connection"
-msgstr "Добавить новый контакт"
-
-#: ../../Zotlabs/Widget/Follow.php:30
-msgid "Enter channel address"
-msgstr "Введите адрес канала"
-
-#: ../../Zotlabs/Widget/Follow.php:31
-msgid "Examples: bob@example.com, https://example.com/barbara"
-msgstr "Пример: ivan@example.com, http://example.com/ivan"
-
-#: ../../Zotlabs/Widget/Archive.php:43
-msgid "Archives"
-msgstr "Архивы"
-
-#: ../../Zotlabs/Widget/Conversations.php:17
-msgid "Received Messages"
-msgstr "Полученные сообщения"
-
-#: ../../Zotlabs/Widget/Conversations.php:21
-msgid "Sent Messages"
-msgstr "Отправленные сообщения"
-
-#: ../../Zotlabs/Widget/Conversations.php:25
-msgid "Conversations"
-msgstr "Беседы"
-
-#: ../../Zotlabs/Widget/Conversations.php:37
-msgid "No messages."
-msgstr "Сообщений нет."
-
-#: ../../Zotlabs/Widget/Conversations.php:57
-msgid "Delete conversation"
-msgstr "Удалить беседу"
-
-#: ../../Zotlabs/Widget/Chatroom_members.php:11
-msgid "Chat Members"
-msgstr "Участники чата"
-
-#: ../../Zotlabs/Widget/Photo.php:48 ../../Zotlabs/Widget/Photo_rand.php:58
-msgid "photo/image"
-msgstr "фотография / изображение"
-
-#: ../../Zotlabs/Widget/Savedsearch.php:75
-msgid "Remove term"
-msgstr "Удалить термин"
-
-#: ../../Zotlabs/Widget/Savedsearch.php:83 ../../include/features.php:317
-msgid "Saved Searches"
-msgstr "Сохранённые поиски"
-
-#: ../../Zotlabs/Widget/Wiki_pages.php:34
-#: ../../Zotlabs/Widget/Wiki_pages.php:91
-msgid "Add new page"
-msgstr "Добавить новую страницу"
-
-#: ../../Zotlabs/Widget/Wiki_pages.php:85
-msgid "Wiki Pages"
-msgstr "Wiki страницы"
-
-#: ../../Zotlabs/Widget/Wiki_pages.php:96
-msgid "Page name"
-msgstr "Название страницы"
-
-#: ../../Zotlabs/Widget/Affinity.php:54
-msgid "Refresh"
-msgstr "Обновить"
-
-#: ../../Zotlabs/Widget/Tasklist.php:23
-msgid "Tasks"
-msgstr "Задачи"
-
-#: ../../Zotlabs/Widget/Suggestions.php:51
-msgid "Suggestions"
-msgstr "Рекомендации"
-
-#: ../../Zotlabs/Widget/Suggestions.php:52
-msgid "See more..."
-msgstr "Просмотреть больше..."
-
-#: ../../Zotlabs/Widget/Activity_order.php:90
-msgid "Commented Date"
-msgstr "По комментариям"
-
-#: ../../Zotlabs/Widget/Activity_order.php:94
-msgid "Order by last commented date"
-msgstr "Сортировка по дате последнего комментария"
-
-#: ../../Zotlabs/Widget/Activity_order.php:97
-msgid "Posted Date"
-msgstr "По публикациям"
-
-#: ../../Zotlabs/Widget/Activity_order.php:101
-msgid "Order by last posted date"
-msgstr "Сортировка по дате последней публикации"
-
-#: ../../Zotlabs/Widget/Activity_order.php:104
-msgid "Date Unthreaded"
-msgstr "По порядку"
-
-#: ../../Zotlabs/Widget/Activity_order.php:108
-msgid "Order unthreaded by date"
-msgstr "Сортировка в порядке поступления"
-
-#: ../../Zotlabs/Widget/Activity_order.php:123
-msgid "Stream Order"
-msgstr "Упорядочить поток"
-
-#: ../../Zotlabs/Widget/Cover_photo.php:65
-msgid "Click to show more"
-msgstr "Нажмите чтобы показать больше"
-
-#: ../../Zotlabs/Widget/Tagcloud.php:22 ../../include/taxonomy.php:320
-#: ../../include/taxonomy.php:449 ../../include/taxonomy.php:470
-msgid "Tags"
-msgstr "Теги"
-
-#: ../../Zotlabs/Widget/Appstore.php:11
-msgid "App Collections"
-msgstr "Коллекции приложений"
-
-#: ../../Zotlabs/Widget/Appstore.php:13
-msgid "Installed apps"
-msgstr "Установленные приложения"
-
-#: ../../Zotlabs/Widget/Newmember.php:31
-msgid "Profile Creation"
-msgstr "Создание профиля"
-
-#: ../../Zotlabs/Widget/Newmember.php:33
-msgid "Upload profile photo"
-msgstr "Загрузить фотографию профиля"
-
-#: ../../Zotlabs/Widget/Newmember.php:34
-msgid "Upload cover photo"
-msgstr "Загрузить фотографию обложки"
-
-#: ../../Zotlabs/Widget/Newmember.php:35 ../../include/nav.php:111
-msgid "Edit your profile"
-msgstr "Редактировать профиль"
-
-#: ../../Zotlabs/Widget/Newmember.php:38
-msgid "Find and Connect with others"
-msgstr "Найти и вступить в контакт"
-
-#: ../../Zotlabs/Widget/Newmember.php:40
-msgid "View the directory"
-msgstr "Просмотреть каталог"
-
-#: ../../Zotlabs/Widget/Newmember.php:42
-msgid "Manage your connections"
-msgstr "Управление вашими контактами"
-
-#: ../../Zotlabs/Widget/Newmember.php:45
-msgid "Communicate"
-msgstr "Связаться"
-
-#: ../../Zotlabs/Widget/Newmember.php:47
-msgid "View your channel homepage"
-msgstr "Домашняя страница канала"
-
-#: ../../Zotlabs/Widget/Newmember.php:48
-msgid "View your network stream"
-msgstr "Просмотреть ваш сетевой поток"
-
-#: ../../Zotlabs/Widget/Newmember.php:54
-msgid "Documentation"
-msgstr "Документация"
-
-#: ../../Zotlabs/Widget/Newmember.php:57
-msgid "Missing Features?"
-msgstr "Отсутствует функция?"
-
-#: ../../Zotlabs/Widget/Newmember.php:59
-msgid "Pin apps to navigation bar"
-msgstr "Прикрепить приложение к панели"
-
-#: ../../Zotlabs/Widget/Newmember.php:60
-msgid "Install more apps"
-msgstr "Установить больше приложений"
-
-#: ../../Zotlabs/Widget/Newmember.php:71
-msgid "View public stream"
-msgstr "Просмотреть публичный поток"
-
-#: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60
-msgid "Member registrations waiting for confirmation"
-msgstr "Регистрации участников, ожидающие подверждения"
-
-#: ../../Zotlabs/Widget/Admin.php:29
-msgid "Inspect queue"
-msgstr "Просмотр очереди"
-
-#: ../../Zotlabs/Widget/Admin.php:31
-msgid "DB updates"
-msgstr "Обновление базы данных"
-
-#: ../../Zotlabs/Widget/Admin.php:55 ../../include/nav.php:189
-msgid "Admin"
-msgstr "Администрирование"
-
-#: ../../Zotlabs/Widget/Admin.php:56
-msgid "Addon Features"
-msgstr "Настройки расширений"
-
-#: ../../Zotlabs/Widget/Settings_menu.php:32
-msgid "Account settings"
-msgstr "Настройки аккаунта"
-
-#: ../../Zotlabs/Widget/Settings_menu.php:38
-msgid "Channel settings"
-msgstr "Настройки канала"
-
-#: ../../Zotlabs/Widget/Settings_menu.php:46
-msgid "Display settings"
-msgstr "Настройки отображения"
-
-#: ../../Zotlabs/Widget/Settings_menu.php:53
-msgid "Manage locations"
-msgstr "Управление местоположением"
-
-#: ../../Zotlabs/Widget/Bookmarkedchats.php:24
-msgid "Bookmarked Chatrooms"
-msgstr "Закладки чатов"
-
-#: ../../Zotlabs/Widget/Notifications.php:16
-msgid "New Network Activity"
-msgstr "Новая сетевая активность"
-
-#: ../../Zotlabs/Widget/Notifications.php:17
-msgid "New Network Activity Notifications"
-msgstr "Новые уведомления о сетевой активности"
-
-#: ../../Zotlabs/Widget/Notifications.php:20
-msgid "View your network activity"
-msgstr "Просмотреть вашу сетевую активность"
-
-#: ../../Zotlabs/Widget/Notifications.php:23
-msgid "Mark all notifications read"
-msgstr "Пометить уведомления как прочитанные"
-
-#: ../../Zotlabs/Widget/Notifications.php:26
-#: ../../Zotlabs/Widget/Notifications.php:45
-#: ../../Zotlabs/Widget/Notifications.php:152
-msgid "Show new posts only"
-msgstr "Показывать только новые публикации"
-
-#: ../../Zotlabs/Widget/Notifications.php:27
-#: ../../Zotlabs/Widget/Notifications.php:46
-#: ../../Zotlabs/Widget/Notifications.php:122
-#: ../../Zotlabs/Widget/Notifications.php:153
-msgid "Filter by name or address"
-msgstr "Фильтровать по имени или адресу"
-
-#: ../../Zotlabs/Widget/Notifications.php:35
-msgid "New Home Activity"
-msgstr "Новая локальная активность"
-
-#: ../../Zotlabs/Widget/Notifications.php:36
-msgid "New Home Activity Notifications"
-msgstr "Новые уведомления локальной активности"
-
-#: ../../Zotlabs/Widget/Notifications.php:39
-msgid "View your home activity"
-msgstr "Просмотреть локальную активность"
-
-#: ../../Zotlabs/Widget/Notifications.php:42
-#: ../../Zotlabs/Widget/Notifications.php:149
-msgid "Mark all notifications seen"
-msgstr "Пометить уведомления как просмотренные"
-
-#: ../../Zotlabs/Widget/Notifications.php:54
-msgid "New Mails"
-msgstr "Новая переписка"
-
-#: ../../Zotlabs/Widget/Notifications.php:55
-msgid "New Mails Notifications"
-msgstr "Уведомления о новой переписке"
-
-#: ../../Zotlabs/Widget/Notifications.php:58
-msgid "View your private mails"
-msgstr "Просмотреть вашу личную переписку"
-
-#: ../../Zotlabs/Widget/Notifications.php:61
-msgid "Mark all messages seen"
-msgstr "Пометить сообщения как просмотренные"
-
-#: ../../Zotlabs/Widget/Notifications.php:69
-msgid "New Events"
-msgstr "Новые события"
-
-#: ../../Zotlabs/Widget/Notifications.php:70
-msgid "New Events Notifications"
-msgstr "Уведомления о новых событиях"
-
-#: ../../Zotlabs/Widget/Notifications.php:73
-msgid "View events"
-msgstr "Просмотреть события"
-
-#: ../../Zotlabs/Widget/Notifications.php:76
-msgid "Mark all events seen"
-msgstr "Пометить все события как просмотренные"
-
-#: ../../Zotlabs/Widget/Notifications.php:85
-msgid "New Connections Notifications"
-msgstr "Уведомления о новых контактах"
-
-#: ../../Zotlabs/Widget/Notifications.php:88
-msgid "View all connections"
-msgstr "Просмотр всех контактов"
-
-#: ../../Zotlabs/Widget/Notifications.php:96
-msgid "New Files"
-msgstr "Новые файлы"
-
-#: ../../Zotlabs/Widget/Notifications.php:97
-msgid "New Files Notifications"
-msgstr "Уведомления о новых файлах"
-
-#: ../../Zotlabs/Widget/Notifications.php:104
-#: ../../Zotlabs/Widget/Notifications.php:105
-msgid "Notices"
-msgstr "Оповещения"
-
-#: ../../Zotlabs/Widget/Notifications.php:108
-msgid "View all notices"
-msgstr "Просмотреть все оповещения"
-
-#: ../../Zotlabs/Widget/Notifications.php:111
-msgid "Mark all notices seen"
-msgstr "Пометить все оповещения как просмотренные"
-
-#: ../../Zotlabs/Widget/Notifications.php:132
-msgid "New Registrations"
-msgstr "Новые регистрации"
-
-#: ../../Zotlabs/Widget/Notifications.php:133
-msgid "New Registrations Notifications"
-msgstr "Уведомления о новых регистрациях"
-
-#: ../../Zotlabs/Widget/Notifications.php:143
-msgid "Public Stream Notifications"
-msgstr "Уведомления публичного потока"
-
-#: ../../Zotlabs/Widget/Notifications.php:146
-msgid "View the public stream"
-msgstr "Просмотреть публичный поток"
-
-#: ../../Zotlabs/Widget/Notifications.php:161
-msgid "Sorry, you have got no notifications at the moment"
-msgstr "Извините, но сейчас у вас нет уведомлений"
-
-#: ../../util/nconfig.php:34
-msgid "Source channel not found."
-msgstr "Канал-источник не найден."
-
-#: ../../widget/Netselect/Netselect.php:24
-msgid "Network/Protocol"
-msgstr "Сеть / протокол"
-
-#: ../../widget/Netselect/Netselect.php:28 ../../include/network.php:1724
-msgid "Zot"
-msgstr ""
-
-#: ../../widget/Netselect/Netselect.php:31 ../../include/network.php:1722
-msgid "Diaspora"
-msgstr ""
-
-#: ../../widget/Netselect/Netselect.php:33 ../../include/network.php:1715
-#: ../../include/network.php:1716
-msgid "Friendica"
-msgstr ""
-
-#: ../../widget/Netselect/Netselect.php:38 ../../include/network.php:1717
-msgid "OStatus"
-msgstr ""
-
-#: ../../boot.php:1608
-msgid "Create an account to access services and applications"
-msgstr "Создайте аккаунт для доступа к службам и приложениям"
-
-#: ../../boot.php:1628 ../../include/nav.php:103 ../../include/nav.php:132
-#: ../../include/nav.php:151
-msgid "Logout"
-msgstr "Выход"
-
-#: ../../boot.php:1632
-msgid "Login/Email"
-msgstr "Пользователь / email"
-
-#: ../../boot.php:1633
-msgid "Password"
-msgstr "Пароль"
-
-#: ../../boot.php:1634
-msgid "Remember me"
-msgstr "Запомнить меня"
-
-#: ../../boot.php:1637
-msgid "Forgot your password?"
-msgstr "Забыли пароль или логин?"
+msgid "Will attend %1$s's %2$s"
+msgstr "Примет участие %1$s %2$s"
-#: ../../boot.php:2433
+#: ../../Zotlabs/Lib/Activity.php:1515
#, php-format
-msgid "[$Projectname] Website SSL error for %s"
-msgstr "[$Projectname] Ошибка SSL/TLS веб-сайта для %s"
-
-#: ../../boot.php:2438
-msgid "Website SSL certificate is not valid. Please correct."
-msgstr "SSL/TLS сертификат веб-сайт недействителен. Исправьте это."
+msgid "Will not attend %1$s's %2$s"
+msgstr "Не примет участие %1$s %2$s"
-#: ../../boot.php:2554
+#: ../../Zotlabs/Lib/Activity.php:1518
#, php-format
-msgid "[$Projectname] Cron tasks not running on %s"
-msgstr "[$Projectname] Задания Cron не запущены на %s"
-
-#: ../../boot.php:2559
-msgid "Cron/Scheduled tasks not running."
-msgstr "Задания Cron / планировщика не запущены."
-
-#: ../../boot.php:2560 ../../include/datetime.php:238
-msgid "never"
-msgstr "никогда"
-
-#: ../../view/theme/redbasic_c/php/config.php:16
-#: ../../view/theme/redbasic_c/php/config.php:19
-#: ../../view/theme/redbasic/php/config.php:16
-#: ../../view/theme/redbasic/php/config.php:19
-msgid "Focus (Hubzilla default)"
-msgstr "Фокус (по умолчанию Hubzilla)"
-
-#: ../../view/theme/redbasic_c/php/config.php:99
-#: ../../view/theme/redbasic/php/config.php:98
-msgid "Theme settings"
-msgstr "Настройки темы"
-
-#: ../../view/theme/redbasic_c/php/config.php:100
-#: ../../view/theme/redbasic/php/config.php:99
-msgid "Narrow navbar"
-msgstr "Узкая панель навигации"
-
-#: ../../view/theme/redbasic_c/php/config.php:101
-#: ../../view/theme/redbasic/php/config.php:100
-msgid "Navigation bar background color"
-msgstr "Панель навигации, цвет фона"
-
-#: ../../view/theme/redbasic_c/php/config.php:102
-#: ../../view/theme/redbasic/php/config.php:101
-msgid "Navigation bar icon color "
-msgstr "Панель навигации, цвет значков"
-
-#: ../../view/theme/redbasic_c/php/config.php:103
-#: ../../view/theme/redbasic/php/config.php:102
-msgid "Navigation bar active icon color "
-msgstr "Панель навигации, цвет активного значка"
-
-#: ../../view/theme/redbasic_c/php/config.php:104
-#: ../../view/theme/redbasic/php/config.php:103
-msgid "Link color"
-msgstr "Цвет ссылок"
-
-#: ../../view/theme/redbasic_c/php/config.php:105
-#: ../../view/theme/redbasic/php/config.php:104
-msgid "Set font-color for banner"
-msgstr "Цвет текста в шапке"
+msgid "May attend %1$s's %2$s"
+msgstr "Возможно примет участие %1$s %2$s"
-#: ../../view/theme/redbasic_c/php/config.php:106
-#: ../../view/theme/redbasic/php/config.php:105
-msgid "Set the background color"
-msgstr "Цвет фона"
+#: ../../Zotlabs/Lib/Techlevels.php:10
+msgid "0. Beginner/Basic"
+msgstr "Начинающий / Базовый"
-#: ../../view/theme/redbasic_c/php/config.php:107
-#: ../../view/theme/redbasic/php/config.php:106
-msgid "Set the background image"
-msgstr "Фоновое изображение"
+#: ../../Zotlabs/Lib/Techlevels.php:11
+msgid "1. Novice - not skilled but willing to learn"
+msgstr "1. Новичок - не опытный, но желающий учиться"
-#: ../../view/theme/redbasic_c/php/config.php:108
-#: ../../view/theme/redbasic/php/config.php:107
-msgid "Set the background color of items"
-msgstr "Цвет фона элементов"
+#: ../../Zotlabs/Lib/Techlevels.php:12
+msgid "2. Intermediate - somewhat comfortable"
+msgstr "2. Промежуточный - более удобный"
-#: ../../view/theme/redbasic_c/php/config.php:109
-#: ../../view/theme/redbasic/php/config.php:108
-msgid "Set the background color of comments"
-msgstr "Цвет фона комментариев"
+#: ../../Zotlabs/Lib/Techlevels.php:13
+msgid "3. Advanced - very comfortable"
+msgstr "3. Продвинутый - очень удобный"
-#: ../../view/theme/redbasic_c/php/config.php:110
-#: ../../view/theme/redbasic/php/config.php:109
-msgid "Set font-size for the entire application"
-msgstr "Установить системный размер шрифта"
+#: ../../Zotlabs/Lib/Techlevels.php:14
+msgid "4. Expert - I can write computer code"
+msgstr "4. Эксперт - я умею программировать"
-#: ../../view/theme/redbasic_c/php/config.php:110
-#: ../../view/theme/redbasic/php/config.php:109
-msgid "Examples: 1rem, 100%, 16px"
-msgstr "Например: 1rem, 100%, 16px"
+#: ../../Zotlabs/Lib/Techlevels.php:15
+msgid "5. Wizard - I probably know more than you do"
+msgstr "5. Волшебник - возможно я знаю больше чем ты"
-#: ../../view/theme/redbasic_c/php/config.php:111
-#: ../../view/theme/redbasic/php/config.php:110
-msgid "Set font-color for posts and comments"
-msgstr "Цвет шрифта для публикаций и комментариев"
+#: ../../Zotlabs/Lib/NativeWiki.php:143
+msgid "Wiki updated successfully"
+msgstr "Wiki успешно обновлена"
-#: ../../view/theme/redbasic_c/php/config.php:112
-#: ../../view/theme/redbasic/php/config.php:111
-msgid "Set radius of corners"
-msgstr "Радиус скруглений"
+#: ../../Zotlabs/Lib/NativeWiki.php:197
+msgid "Wiki files deleted successfully"
+msgstr "Wiki успешно удалена"
-#: ../../view/theme/redbasic_c/php/config.php:112
-#: ../../view/theme/redbasic/php/config.php:111
-msgid "Example: 4px"
-msgstr "Например: 4px"
+#: ../../extend/addon/hzaddons/mdpost/mdpost.php:42
+msgid "Use markdown for editing posts"
+msgstr "Использовать язык разметки Markdown для редактирования публикаций"
-#: ../../view/theme/redbasic_c/php/config.php:113
-#: ../../view/theme/redbasic/php/config.php:112
-msgid "Set shadow depth of photos"
-msgstr "Глубина теней фотографий"
+#: ../../extend/addon/hzaddons/dwpost/dwpost.php:48
+msgid "Post to Dreamwidth"
+msgstr "Публиковать в Dreamwidth"
-#: ../../view/theme/redbasic_c/php/config.php:114
-#: ../../view/theme/redbasic/php/config.php:113
-msgid "Set maximum width of content region in pixel"
-msgstr "Максимальная ширина содержания региона (в пикселях)"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:24
+msgid "Dreamwidth Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Dreamwidth сохранены."
-#: ../../view/theme/redbasic_c/php/config.php:114
-#: ../../view/theme/redbasic/php/config.php:113
-msgid "Leave empty for default width"
-msgstr "Оставьте пустым для ширины по умолчанию"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:36
+msgid "Dreamwidth Crosspost Connector App"
+msgstr "Приложение \"Публикация в Dreamwidth\""
-#: ../../view/theme/redbasic_c/php/config.php:115
-msgid "Left align page content"
-msgstr "Выровнять содержимое страницы по левому краю"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:37
+msgid "Relay public postings to Dreamwidth"
+msgstr "Пересылает общедоступные публикации в Dreamwidth"
-#: ../../view/theme/redbasic_c/php/config.php:116
-#: ../../view/theme/redbasic/php/config.php:114
-msgid "Set size of conversation author photo"
-msgstr "Размер фотографии автора беседы"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:52
+msgid "Dreamwidth username"
+msgstr "Имя пользователя Dreamwidth"
-#: ../../view/theme/redbasic_c/php/config.php:117
-#: ../../view/theme/redbasic/php/config.php:115
-msgid "Set size of followup author photos"
-msgstr "Размер фотографий подписчиков"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:56
+msgid "Dreamwidth password"
+msgstr "Пароль Dreamwidth"
-#: ../../view/theme/redbasic/php/config.php:116
-msgid "Show advanced settings"
-msgstr "Показать расширенные настройки"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:60
+msgid "Post to Dreamwidth by default"
+msgstr "Публиковать в Dreamwidth по умолчанию"
-#: ../../addon/rendezvous/rendezvous.php:57
-msgid "Errors encountered deleting database table "
-msgstr "Возникшие при удалении таблицы базы данных ошибки"
+#: ../../extend/addon/hzaddons/dwpost/Mod_Dwpost.php:68
+msgid "Dreamwidth Crosspost Connector"
+msgstr "Публикация в Dreamwidth"
-#: ../../addon/rendezvous/rendezvous.php:95 ../../addon/twitter/twitter.php:612
-msgid "Submit Settings"
-msgstr "Отправить настройки"
+#: ../../extend/addon/hzaddons/donate/donate.php:21
+msgid "Project Servers and Resources"
+msgstr "Серверы и ресурсы проекта"
-#: ../../addon/rendezvous/rendezvous.php:96
-msgid "Drop tables when uninstalling?"
-msgstr "Удалить таблицы при деинсталляции?"
+#: ../../extend/addon/hzaddons/donate/donate.php:22
+msgid "Project Creator and Tech Lead"
+msgstr "Создатель проекта и технический руководитель"
-#: ../../addon/rendezvous/rendezvous.php:96
+#: ../../extend/addon/hzaddons/donate/donate.php:49
msgid ""
-"If checked, the Rendezvous database tables will be deleted when the plugin "
-"is uninstalled."
-msgstr "Если включено, то таблицы базы данных Rendezvous будут удалены при удалении плагина."
-
-#: ../../addon/rendezvous/rendezvous.php:97
-msgid "Mapbox Access Token"
-msgstr "Токен доступа к Mapbox"
+"And the hundreds of other people and organisations who helped make the "
+"Hubzilla possible."
+msgstr "И сотни других людей и организаций которые помогали в создании Hubzilla."
-#: ../../addon/rendezvous/rendezvous.php:97
+#: ../../extend/addon/hzaddons/donate/donate.php:52
msgid ""
-"If you enter a Mapbox access token, it will be used to retrieve map tiles "
-"from Mapbox instead of the default OpenStreetMap tile server."
-msgstr "Если вы введете токен доступа к Mapbox, он будет использоваться для извлечения фрагментов карты из Mapbox вместо стандартного сервера OpenStreetMap."
-
-#: ../../addon/rendezvous/rendezvous.php:162
-msgid "Rendezvous"
-msgstr ""
+"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving "
+"their time and expertise - and often paying out of pocket for services they "
+"share with others."
+msgstr "Проекты Redmatrix / Hubzilla предоставляются, в основном, добровольцами, которые предоставляют свое время и опыт и, часто, оплачивают из своего кармана услуги, которыми они делятся с другими."
-#: ../../addon/rendezvous/rendezvous.php:167
+#: ../../extend/addon/hzaddons/donate/donate.php:53
msgid ""
-"This identity has been deleted by another member due to inactivity. Please "
-"press the \"New identity\" button or refresh the page to register a new "
-"identity. You may use the same name."
-msgstr "Этот идентификатор был удалён другим участником из-за неактивности. Пожалуйста нажмите кнопку \"Новый идентификатор\" для обновления страницы и получения нового идентификатора. Вы можете использовать то же имя."
-
-#: ../../addon/rendezvous/rendezvous.php:168
-msgid "Welcome to Rendezvous!"
-msgstr "Добро пожаловать в Rendezvous!"
+"There is no corporate funding and no ads, and we do not collect and sell "
+"your personal information. (We don't control your personal information - "
+"<strong>you do</strong>.)"
+msgstr "Здесь нет корпоративного финансирования и рекламы, мы не собираем и не продаем вашу личную информацию. (Мы не контролируем вашу личную информацию - <strong>это делаете вы</strong>.)"
-#: ../../addon/rendezvous/rendezvous.php:169
+#: ../../extend/addon/hzaddons/donate/donate.php:54
msgid ""
-"Enter your name to join this rendezvous. To begin sharing your location with "
-"the other members, tap the GPS control. When your location is discovered, a "
-"red dot will appear and others will be able to see you on the map."
-msgstr "Введите ваше имя для вступления в это Rendezvous. Для того, чтобы делиться вашим положением с другими участниками, нажмите \"GPS control\". Когда ваше местоположение определно, красная точка появится и остальные смогут увидеть вас на карте."
-
-#: ../../addon/rendezvous/rendezvous.php:171
-msgid "Let's meet here"
-msgstr "Давайте встретимся здесь"
-
-#: ../../addon/rendezvous/rendezvous.php:174
-msgid "New marker"
-msgstr "Новый маркер"
-
-#: ../../addon/rendezvous/rendezvous.php:175
-msgid "Edit marker"
-msgstr "Редактировать маркер"
-
-#: ../../addon/rendezvous/rendezvous.php:176
-msgid "New identity"
-msgstr "Новый идентификатор"
-
-#: ../../addon/rendezvous/rendezvous.php:177
-msgid "Delete marker"
-msgstr "Удалить маркер"
-
-#: ../../addon/rendezvous/rendezvous.php:178
-msgid "Delete member"
-msgstr "Удалить участника"
-
-#: ../../addon/rendezvous/rendezvous.php:179
-msgid "Edit proximity alert"
-msgstr "Изменить оповещение о близости"
+"Help support our ground-breaking work in decentralisation, web identity, and "
+"privacy."
+msgstr "Помогите поддержать нашу новаторскую работу в областях децентрализации, веб-идентификации и конфиденциальности."
-#: ../../addon/rendezvous/rendezvous.php:180
+#: ../../extend/addon/hzaddons/donate/donate.php:56
msgid ""
-"A proximity alert will be issued when this member is within a certain radius "
-"of you.<br><br>Enter a radius in meters (0 to disable):"
-msgstr "Оповещение о близости будет произведено, если этот участник находится на определённом расстоянии от вас. <br><br>Введите радиус в метрах (0 для отключения):"
-
-#: ../../addon/rendezvous/rendezvous.php:180
-#: ../../addon/rendezvous/rendezvous.php:185
-msgid "distance"
-msgstr "расстояние"
+"Your donations keep servers and services running and also helps us to "
+"provide innovative new features and continued development."
+msgstr "В ваших пожертвованиях поддерживают серверы и службы, а также помогают нам предоставлять новые возможности и продолжать развитие."
-#: ../../addon/rendezvous/rendezvous.php:181
-msgid "Proximity alert distance (meters)"
-msgstr "Расстояние для уведомления о близости (метров)"
+#: ../../extend/addon/hzaddons/donate/donate.php:59
+msgid "Donate"
+msgstr "Пожертвовать"
-#: ../../addon/rendezvous/rendezvous.php:182
-#: ../../addon/rendezvous/rendezvous.php:184
+#: ../../extend/addon/hzaddons/donate/donate.php:61
msgid ""
-"A proximity alert will be issued when you are within a certain radius of the "
-"marker location.<br><br>Enter a radius in meters (0 to disable):"
-msgstr "Оповещение о близости будет произведено, если вы находитесь на определённом расстоянии местоположения маркера. <br><br>Введите радиус в метрах (0 для отключения):"
-
-#: ../../addon/rendezvous/rendezvous.php:183
-msgid "Marker proximity alert"
-msgstr "Маркер уведомления о близости"
+"Choose a project, developer, or public hub to support with a one-time "
+"donation"
+msgstr "Выберите проект, разработчика или общедоступный узел для поддержки в форме единоразового пожертвования"
-#: ../../addon/rendezvous/rendezvous.php:186
-msgid "Reminder note"
-msgstr "Напоминание"
+#: ../../extend/addon/hzaddons/donate/donate.php:62
+msgid "Donate Now"
+msgstr "Пожертвовать сейчас"
-#: ../../addon/rendezvous/rendezvous.php:187
+#: ../../extend/addon/hzaddons/donate/donate.php:63
msgid ""
-"Enter a note to be displayed when you are within the specified proximity..."
-msgstr "Введите сообщение для отображения когда вы находитесь рядом"
-
-#: ../../addon/rendezvous/rendezvous.php:199
-msgid "Add new rendezvous"
-msgstr "Добавить новое Rendezvous."
+"<strong><em>Or</em></strong> become a project sponsor (Hubzilla Project only)"
+msgstr "<strong><em>или</em></strong> станьте спонсором проекта (только для Hubzilla)"
-#: ../../addon/rendezvous/rendezvous.php:200
+#: ../../extend/addon/hzaddons/donate/donate.php:64
msgid ""
-"Create a new rendezvous and share the access link with those you wish to "
-"invite to the group. Those who open the link become members of the "
-"rendezvous. They can view other member locations, add markers to the map, or "
-"share their own locations with the group."
-msgstr "Создайте новое Rendezvous и поделитесь ссылкой доступа с теми, кого вы хотите пригласить в группу. Тот, кто откроет эту ссылку, станет её участником. Участники могут видеть местоположение, добавлять маркеры на карту или делится своим собственным местоположением с группой."
-
-#: ../../addon/rendezvous/rendezvous.php:232
-msgid "You have no rendezvous. Press the button above to create a rendezvous!"
-msgstr "У вас нет Rendezvous. Нажмите на кнопку ниже чтобы создать его!"
-
-#: ../../addon/skeleton/Mod_Skeleton.php:32
-msgid "Skeleton App"
-msgstr "Приложение \"Скелет\""
+"Please indicate if you would like your first name or full name (or nothing) "
+"to appear in our sponsor listing"
+msgstr "Пожалуйста, если желаете, укажите ваше имя для отображения в списке спонсоров."
-#: ../../addon/skeleton/Mod_Skeleton.php:33
-msgid "A skeleton for addons, you can copy/paste"
-msgstr "Скелет для приложений. Вы можете использовать copy/paste"
+#: ../../extend/addon/hzaddons/donate/donate.php:65
+msgid "Sponsor"
+msgstr "Спонсор"
-#: ../../addon/skeleton/Mod_Skeleton.php:40
-msgid "Some setting"
-msgstr "Некоторые настройки"
+#: ../../extend/addon/hzaddons/donate/donate.php:68
+msgid "Special thanks to: "
+msgstr "Особые благодарности:"
-#: ../../addon/skeleton/Mod_Skeleton.php:40
-msgid "A setting"
-msgstr "Настройка"
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:22
+msgid "Fuzzloc Settings updated."
+msgstr "Настройки примерного положения обновлены."
-#: ../../addon/skeleton/Mod_Skeleton.php:48
-msgid "Skeleton Settings"
-msgstr "Настройки скелета"
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:34
+msgid "Fuzzy Location App"
+msgstr "Приложение \"Примерное положение\""
-#: ../../addon/gnusoc/Mod_Gnusoc.php:16
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:35
msgid ""
-"The GNU-Social protocol does not support location independence. Connections "
-"you make within that network may be unreachable from alternate channel "
-"locations."
-msgstr "Протокол GNU-Social не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
+"Blur your precise location if your channel uses browser location mapping"
+msgstr "Размывает вашего точное местоположение в случае если ваш канал использует отображение местоположения из браузера"
-#: ../../addon/gnusoc/Mod_Gnusoc.php:22
-msgid "GNU-Social Protocol App"
-msgstr "Приложение \"Протокол GNU-Social\""
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:40
+msgid "Minimum offset in meters"
+msgstr "Минимальное смещение в метрах"
-#: ../../addon/gnusoc/Mod_Gnusoc.php:34
-msgid "GNU-Social Protocol"
-msgstr "Протокол GNU-Social"
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:44
+msgid "Maximum offset in meters"
+msgstr "Максимальное смещение в метрах"
-#: ../../addon/gnusoc/gnusoc.php:451
-msgid "Follow"
-msgstr "Отслеживать"
+#: ../../extend/addon/hzaddons/fuzzloc/Mod_Fuzzloc.php:53
+msgid "Fuzzy Location"
+msgstr "Примерное положение"
-#: ../../addon/gnusoc/gnusoc.php:454
-#, php-format
-msgid "%1$s is now following %2$s"
-msgstr "%1$s сейчас отслеживает %2$s"
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:22
+msgid ""
+"Allow magic authentication only to websites of your immediate connections"
+msgstr "Разрешить волшебную аутентификацию только на сайтах ваших непосредственных соединений"
-#: ../../addon/planets/Mod_Planets.php:20
-#: ../../addon/planets/Mod_Planets.php:23
-msgid "Random Planet App"
-msgstr "Приложение \"Случайная планета\""
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:28
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33
+msgid "Authchoose App"
+msgstr "Приложение Authchoose"
-#: ../../addon/planets/Mod_Planets.php:23
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:26
-#: ../../addon/nsabait/Mod_Nsabait.php:24 ../../addon/hsse/Mod_Hsse.php:26
-#: ../../addon/authchoose/Mod_Authchoose.php:33
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:33
+#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26
+#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26
msgid "Installed"
msgstr "Установлено"
-#: ../../addon/planets/Mod_Planets.php:25
-msgid ""
-"Set a random planet from the Star Wars Empire as your location when posting"
-msgstr "Установить случайную планету из Империи Звездных Войн в качестве вашего местоположения при публикации"
-
-#: ../../addon/openclipatar/openclipatar.php:50
-#: ../../addon/openclipatar/openclipatar.php:128
-msgid "System defaults:"
-msgstr "Системные по умолчанию:"
-
-#: ../../addon/openclipatar/openclipatar.php:54
-msgid "Preferred Clipart IDs"
-msgstr "Предпочитаемый Clipart ID"
-
-#: ../../addon/openclipatar/openclipatar.php:54
-msgid "List of preferred clipart ids. These will be shown first."
-msgstr "Список предпочитаемых Clipart ID. Эти будут показаны первыми."
-
-#: ../../addon/openclipatar/openclipatar.php:55
-msgid "Default Search Term"
-msgstr "Условие поиска по умолчанию"
-
-#: ../../addon/openclipatar/openclipatar.php:55
-msgid "The default search term. These will be shown second."
-msgstr "Условие поиска по умолчанию. Показываются во вторую очередь."
-
-#: ../../addon/openclipatar/openclipatar.php:56
-msgid "Return After"
-msgstr "Вернуться после"
-
-#: ../../addon/openclipatar/openclipatar.php:56
-msgid "Page to load after image selection."
-msgstr "Страница для загрузки после выбора изображения."
-
-#: ../../addon/openclipatar/openclipatar.php:58 ../../include/channel.php:1356
-#: ../../include/nav.php:111
-msgid "Edit Profile"
-msgstr "Редактировать профиль"
-
-#: ../../addon/openclipatar/openclipatar.php:59
-msgid "Profile List"
-msgstr "Список профилей"
-
-#: ../../addon/openclipatar/openclipatar.php:61
-msgid "Order of Preferred"
-msgstr "Порядок предпочтения"
-
-#: ../../addon/openclipatar/openclipatar.php:61
-msgid "Sort order of preferred clipart ids."
-msgstr "Порядок сортировки предпочитаемых Clipart ID. "
-
-#: ../../addon/openclipatar/openclipatar.php:62
-#: ../../addon/openclipatar/openclipatar.php:68
-msgid "Newest first"
-msgstr "Новое первым"
-
-#: ../../addon/openclipatar/openclipatar.php:65
-msgid "As entered"
-msgstr "По мере ввода"
-
-#: ../../addon/openclipatar/openclipatar.php:67
-msgid "Order of other"
-msgstr "Порядок других"
-
-#: ../../addon/openclipatar/openclipatar.php:67
-msgid "Sort order of other clipart ids."
-msgstr "Порядок сортировки остальных Clipart ID."
-
-#: ../../addon/openclipatar/openclipatar.php:69
-msgid "Most downloaded first"
-msgstr "Самое загружаемое первым"
-
-#: ../../addon/openclipatar/openclipatar.php:70
-msgid "Most liked first"
-msgstr "Самое нравящееся первым"
-
-#: ../../addon/openclipatar/openclipatar.php:72
-msgid "Preferred IDs Message"
-msgstr "Сообщение от предпочитаемых ID"
-
-#: ../../addon/openclipatar/openclipatar.php:72
-msgid "Message to display above preferred results."
-msgstr "Отображаемое сообщение над предпочитаемыми результатами."
-
-#: ../../addon/openclipatar/openclipatar.php:78
-msgid "Uploaded by: "
-msgstr "Загружено:"
-
-#: ../../addon/openclipatar/openclipatar.php:78
-msgid "Drawn by: "
-msgstr "Нарисовано:"
-
-#: ../../addon/openclipatar/openclipatar.php:182
-#: ../../addon/openclipatar/openclipatar.php:194
-msgid "Use this image"
-msgstr "Использовать это изображение"
-
-#: ../../addon/openclipatar/openclipatar.php:192
-msgid "Or select from a free OpenClipart.org image:"
-msgstr "Или выберите из бесплатных изображений на OpenClipart.org"
-
-#: ../../addon/openclipatar/openclipatar.php:195
-msgid "Search Term"
-msgstr "Условие поиска"
-
-#: ../../addon/openclipatar/openclipatar.php:232
-msgid "Unknown error. Please try again later."
-msgstr "Неизвестная ошибка. Пожалуйста, повторите попытку позже."
-
-#: ../../addon/openclipatar/openclipatar.php:308
-msgid "Profile photo updated successfully."
-msgstr "Фотография профиля обновлена успешно."
-
-#: ../../addon/adultphotoflag/adultphotoflag.php:24
-msgid "Flag Adult Photos"
-msgstr "Пометка фотографий для взрослых"
-
-#: ../../addon/adultphotoflag/adultphotoflag.php:25
-msgid ""
-"Provide photo edit option to hide inappropriate photos from default album "
-"view"
-msgstr "Предоставьте возможность редактирования фотографий, чтобы скрыть неприемлемые фотографии из альбома по умолчанию"
-
-#: ../../addon/totp/Settings/Totp.php:90
-msgid ""
-"You haven't set a TOTP secret yet.\n"
-"Please click the button below to generate one and register this site\n"
-"with your preferred authenticator app."
-msgstr "Вы еще не установили секретный код TOTP. Пожалуйста, нажмите на кнопку ниже, чтобы сгенерировать его и зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации."
-
-#: ../../addon/totp/Settings/Totp.php:93
-msgid "Your TOTP secret is"
-msgstr "Ваш секретный код TOTP"
-
-#: ../../addon/totp/Settings/Totp.php:94
-msgid ""
-"Be sure to save it somewhere in case you lose or replace your mobile "
-"device.\n"
-"Use your mobile device to scan the QR code below to register this site\n"
-"with your preferred authenticator app."
-msgstr "Обязательно сохраните его где-нибудь на случай потери или замены мобильного устройства. С помощью мобильного устройства отсканируйте приведенный ниже QR-код, чтобы зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации."
-
-#: ../../addon/totp/Settings/Totp.php:99
-msgid "Test"
-msgstr "Тест"
-
-#: ../../addon/totp/Settings/Totp.php:100
-msgid "Generate New Secret"
-msgstr "Сгенерировать новый секретный код"
-
-#: ../../addon/totp/Settings/Totp.php:101
-msgid "Go"
-msgstr "Вперёд"
-
-#: ../../addon/totp/Settings/Totp.php:102
-msgid "Enter your password"
-msgstr "Введите ваш пароль"
+#: ../../extend/addon/hzaddons/authchoose/Mod_Authchoose.php:39
+msgid "Authchoose"
+msgstr ""
-#: ../../addon/totp/Settings/Totp.php:103
-msgid "enter TOTP code from your device"
-msgstr "введите код TOTP из вашего устройства"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:106
+msgid "Photos imported"
+msgstr "Фотографии импортированы"
-#: ../../addon/totp/Settings/Totp.php:104
-msgid "Pass!"
-msgstr "Принято!"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:129
+msgid "Redmatrix Photo Album Import"
+msgstr "Импортировать альбом фотографий Redmatrix"
-#: ../../addon/totp/Settings/Totp.php:105
-msgid "Fail"
-msgstr "Отказано"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:130
+msgid "This will import all your Redmatrix photo albums to this channel."
+msgstr "Это позволит импортировать все ваши альбомы фотографий Redmatrix в этот канал."
-#: ../../addon/totp/Settings/Totp.php:106
-msgid "Incorrect password, try again."
-msgstr "Неверный пароль, попробуйте снова."
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:131
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:121
+msgid "Redmatrix Server base URL"
+msgstr "Базовый URL сервера Redmatrix"
-#: ../../addon/totp/Settings/Totp.php:107
-msgid "Record your new TOTP secret and rescan the QR code above."
-msgstr "Запишите ваш секретный код TOTP и повторно отсканируйте приведенный ниже QR-код."
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:132
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:122
+msgid "Redmatrix Login Username"
+msgstr "Имя пользователя Redmatrix"
-#: ../../addon/totp/Settings/Totp.php:115
-msgid "TOTP Settings"
-msgstr "Настройки TOTP"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:133
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:123
+msgid "Redmatrix Login Password"
+msgstr "Пароль Redmatrix"
-#: ../../addon/totp/Mod_Totp.php:23
-msgid "TOTP Two-Step Verification"
-msgstr "Двухэтапная верификация TOTP"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134
+msgid "Import just this album"
+msgstr "Импортировать только этот альбом"
-#: ../../addon/totp/Mod_Totp.php:24
-msgid "Enter the 2-step verification generated by your authenticator app:"
-msgstr "Введите код проверки, созданный вашим приложением для аутентификации"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:134
+msgid "Leave blank to import all albums"
+msgstr "Оставьте пустым для импорта всех альбомов"
-#: ../../addon/totp/Mod_Totp.php:25
-msgid "Success!"
-msgstr "Успех!"
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135
+msgid "Maximum count to import"
+msgstr "Максимальное количество для импорта"
-#: ../../addon/totp/Mod_Totp.php:26
-msgid "Invalid code, please try again."
-msgstr "Неверный код. Пожалуйста, попробуйте ещё раз."
+#: ../../extend/addon/hzaddons/redphotos/redphotos.php:135
+msgid "0 or blank to import all available"
+msgstr "0 или пусто для импорта всех доступных"
-#: ../../addon/totp/Mod_Totp.php:27
-msgid "Too many invalid codes..."
-msgstr "Слишком много неверных кодов..."
+#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:58
+msgid "Gallery App"
+msgstr "Приложение \"Галерея\""
-#: ../../addon/totp/Mod_Totp.php:28
-msgid "Verify"
-msgstr "Проверить"
+#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:59
+msgid "A simple gallery for your photo albums"
+msgstr "Простая галлерея для ваших фотоальбомов"
-#: ../../addon/wppost/Mod_Wppost.php:28
-msgid "Wordpress Settings saved."
-msgstr "Настройки WordPress сохранены."
+#: ../../extend/addon/hzaddons/gallery/Mod_Gallery.php:136
+#: ../../extend/addon/hzaddons/gallery/gallery.php:38
+msgid "Gallery"
+msgstr "Галерея"
-#: ../../addon/wppost/Mod_Wppost.php:41
-msgid "Wordpress Post App"
-msgstr "Приложение \"Публикация в Wordpress\""
+#: ../../extend/addon/hzaddons/gallery/gallery.php:41
+msgid "Photo Gallery"
+msgstr "Фотогалерея"
-#: ../../addon/wppost/Mod_Wppost.php:42
-msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API"
-msgstr "Опубликовать в WordPress или в чём-то ещё, поддерживающем wordpress XMLRPC API"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:24
+msgid "Friendica Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Friendica сохранены."
-#: ../../addon/wppost/Mod_Wppost.php:65
-msgid "WordPress username"
-msgstr "Имя пользователя WordPress"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:36
+msgid "Friendica Crosspost Connector App"
+msgstr "Приложение \"Публикация в Friendica\""
-#: ../../addon/wppost/Mod_Wppost.php:69
-msgid "WordPress password"
-msgstr "Пароль WordPress"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:37
+msgid "Relay public postings to a connected Friendica account"
+msgstr "Пересылает общедоступные публикации на подключённую учётную запись Friendica"
-#: ../../addon/wppost/Mod_Wppost.php:73
-msgid "WordPress API URL"
-msgstr "URL API WordPress"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
+msgid "Send public postings to Friendica by default"
+msgstr "Отправлять общедоступные публикации во Friendica по умолчанию"
-#: ../../addon/wppost/Mod_Wppost.php:74
-msgid "Typically https://your-blog.tld/xmlrpc.php"
-msgstr "Обычно https://your-blog.tld/xmlrpc.php"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53
+msgid "Friendica API Path"
+msgstr "Путь к Friendica API"
-#: ../../addon/wppost/Mod_Wppost.php:77
-msgid "WordPress blogid"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67
+msgid "https://{sitename}/api"
msgstr ""
-#: ../../addon/wppost/Mod_Wppost.php:78
-msgid "For multi-user sites such as wordpress.com, otherwise leave blank"
-msgstr "Для многопользовательских сайтов, таких, как wordpress.com. В противном случае оставьте пустым"
-
-#: ../../addon/wppost/Mod_Wppost.php:82
-msgid "Post to WordPress by default"
-msgstr "Публиковать в WordPress по умолчанию"
-
-#: ../../addon/wppost/Mod_Wppost.php:86
-msgid "Forward comments (requires hubzilla_wp plugin)"
-msgstr "Пересылать комментарии (требуется плагин hubzilla_wp)"
-
-#: ../../addon/wppost/Mod_Wppost.php:94
-msgid "Wordpress Post"
-msgstr "Публикация в WordPress"
-
-#: ../../addon/wppost/wppost.php:46
-msgid "Post to WordPress"
-msgstr "Опубликовать в WordPress"
-
-#: ../../addon/nsfw/nsfw.php:152
-msgid "Possible adult content"
-msgstr "Возможно содержимое для взрослых"
-
-#: ../../addon/nsfw/nsfw.php:167
-#, php-format
-msgid "%s - view"
-msgstr "%s - просмотр"
-
-#: ../../addon/nsfw/Mod_Nsfw.php:22
-msgid "NSFW Settings saved."
-msgstr "Настройки NSFW сохранены."
-
-#: ../../addon/nsfw/Mod_Nsfw.php:33
-msgid "NSFW App"
-msgstr "Приложение NSFW"
-
-#: ../../addon/nsfw/Mod_Nsfw.php:34
-msgid "Collapse content that contains predefined words"
-msgstr "Свернуть содержимое, содержащее предопределенные слова"
-
-#: ../../addon/nsfw/Mod_Nsfw.php:44
-msgid ""
-"This app looks in posts for the words/text you specify below, and collapses "
-"any content containing those keywords so it is not displayed at "
-"inappropriate times, such as sexual innuendo that may be improper in a work "
-"setting. It is polite and recommended to tag any content containing nudity "
-"with #NSFW. This filter can also match any other word/text you specify, and "
-"can thereby be used as a general purpose content filter."
-msgstr "Это приложение просматривает публикации для слов / текста, которые вы указываете ниже, и сворачивает любой контент, содержащий эти ключевые слова, поэтому он не отображается в неподходящее время, например, сексуальные инсинуации, которые могут быть неправильными в настройке работы. Например, мы рекомендуем отмечать любой контент, содержащий наготу, тегом #NSFW. Этот фильтр также способен реагировать на любое другое указанное вами слово / текст и может использоваться в качестве фильтра содержимого общего назначения."
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57
+msgid "Friendica login name"
+msgstr "Имя входа Friendica"
-#: ../../addon/nsfw/Mod_Nsfw.php:49
-msgid "Comma separated list of keywords to hide"
-msgstr "Список ключевых слов для скрытия, через запятую"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:61
+msgid "Friendica password"
+msgstr "Пароль Friendica"
-#: ../../addon/nsfw/Mod_Nsfw.php:49
-msgid "Word, /regular-expression/, lang=xx, lang!=xx"
-msgstr "слово, /регулярное_выражение/, lang=xx, lang!=xx"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:69
+msgid "Friendica Crosspost Connector"
+msgstr "Публикация в Friendica"
-#: ../../addon/nsfw/Mod_Nsfw.php:58
-msgid "NSFW"
-msgstr ""
+#: ../../extend/addon/hzaddons/rtof/rtof.php:51
+msgid "Post to Friendica"
+msgstr "Опубликовать в Friendica"
-#: ../../addon/queueworker/Mod_Queueworker.php:73
-msgid "Max queueworker threads"
-msgstr "Макс. количество обработчиков очереди"
+#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:70
+msgid "An account has been created for you."
+msgstr "Учётная запись, которая была для вас создана."
-#: ../../addon/queueworker/Mod_Queueworker.php:87
-msgid "Assume workers dead after ___ seconds"
-msgstr "Считать обработчики неактивными через секунд"
+#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:77
+msgid "Authentication successful but rejected: account creation is disabled."
+msgstr "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено."
-#: ../../addon/queueworker/Mod_Queueworker.php:99
-msgid "Queueworker Settings"
-msgstr "Настройки обработчика очереди"
+#: ../../extend/addon/hzaddons/ijpost/ijpost.php:45
+msgid "Post to Insane Journal"
+msgstr "Опубликовать в Insane Journal"
-#: ../../addon/ijpost/Mod_Ijpost.php:23
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:23
msgid "Insane Journal Crosspost Connector Settings saved."
msgstr "Настройки пересылки публикаций Insane Journal сохранены."
-#: ../../addon/ijpost/Mod_Ijpost.php:35
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:35
msgid "Insane Journal Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Insane Journal\""
+msgstr "Приложение \"Публикация в Insane Journal\""
-#: ../../addon/ijpost/Mod_Ijpost.php:36
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:36
msgid "Relay public postings to Insane Journal"
msgstr "Пересылает общедоступные публикации в Insane Journal"
-#: ../../addon/ijpost/Mod_Ijpost.php:53
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:53
msgid "InsaneJournal username"
msgstr "Имя пользователя Insane Journal"
-#: ../../addon/ijpost/Mod_Ijpost.php:57
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:57
msgid "InsaneJournal password"
msgstr "Пароль Insane Journal"
-#: ../../addon/ijpost/Mod_Ijpost.php:61
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:61
msgid "Post to InsaneJournal by default"
msgstr "Публиковать в Insane Journal по умолчанию"
-#: ../../addon/ijpost/Mod_Ijpost.php:69
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:69
msgid "Insane Journal Crosspost Connector"
-msgstr "Пересылка публикаций Insane Journal"
-
-#: ../../addon/ijpost/ijpost.php:45
-msgid "Post to Insane Journal"
-msgstr "Опубликовать в Insane Journal"
-
-#: ../../addon/dwpost/dwpost.php:48
-msgid "Post to Dreamwidth"
-msgstr "Публиковать в Dreamwidth"
+msgstr "Публикация в Insane Journal"
-#: ../../addon/dwpost/Mod_Dwpost.php:24
-msgid "Dreamwidth Crosspost Connector Settings saved."
-msgstr "Настройки пересылки публикаций Dreamwidth сохранены."
-
-#: ../../addon/dwpost/Mod_Dwpost.php:36
-msgid "Dreamwidth Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Dreamwidth\""
-
-#: ../../addon/dwpost/Mod_Dwpost.php:37
-msgid "Relay public postings to Dreamwidth"
-msgstr "Пересылает общедоступные публикации в Dreamwidth"
-
-#: ../../addon/dwpost/Mod_Dwpost.php:52
-msgid "Dreamwidth username"
-msgstr "Имя пользователя Dreamwidth"
-
-#: ../../addon/dwpost/Mod_Dwpost.php:56
-msgid "Dreamwidth password"
-msgstr "Пароль Dreamwidth"
-
-#: ../../addon/dwpost/Mod_Dwpost.php:60
-msgid "Post to Dreamwidth by default"
-msgstr "Публиковать в Dreamwidth по умолчанию"
-
-#: ../../addon/dwpost/Mod_Dwpost.php:68
-msgid "Dreamwidth Crosspost Connector"
-msgstr "Пересылка публикаций Dreamwidth"
-
-#: ../../addon/notifyadmin/notifyadmin.php:34
-msgid "New registration"
-msgstr "Новая регистрация"
-
-#: ../../addon/notifyadmin/notifyadmin.php:42
+#: ../../extend/addon/hzaddons/testdrive/testdrive.php:104
#, php-format
-msgid "Message sent to %s. New account registration: %s"
-msgstr "Сообщение отправлено в %s. Регистрация нового аккаунта: %s"
-
-#: ../../addon/dirstats/dirstats.php:94
-msgid "Hubzilla Directory Stats"
-msgstr "Каталог статистики Hubzilla"
-
-#: ../../addon/dirstats/dirstats.php:95
-msgid "Total Hubs"
-msgstr "Всего хабов"
-
-#: ../../addon/dirstats/dirstats.php:97
-msgid "Hubzilla Hubs"
-msgstr "Хабы Hubzilla"
-
-#: ../../addon/dirstats/dirstats.php:99
-msgid "Friendica Hubs"
-msgstr "Хабы Friendica"
+msgid "Your account on %s will expire in a few days."
+msgstr "Ваш аккаунт на %s перестанет работать через несколько дней."
-#: ../../addon/dirstats/dirstats.php:101
-msgid "Diaspora Pods"
-msgstr "Стручки Diaspora"
+#: ../../extend/addon/hzaddons/testdrive/testdrive.php:105
+msgid "Your $Productname test account is about to expire."
+msgstr "Ваш тестовый аккаунт в $Productname близок к окончанию срока действия."
-#: ../../addon/dirstats/dirstats.php:103
-msgid "Hubzilla Channels"
-msgstr "Каналы Hubzilla"
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:119
+msgid "Redmatrix File Storage Import"
+msgstr "Импорт файлового хранилища Redmatrix"
-#: ../../addon/dirstats/dirstats.php:105
-msgid "Friendica Channels"
-msgstr "Каналы Friendica"
+#: ../../extend/addon/hzaddons/redfiles/redfiles.php:120
+msgid "This will import all your Redmatrix cloud files to this channel."
+msgstr "Это позволит импортировать все ваши файлы в Redmatrix в этот канал."
-#: ../../addon/dirstats/dirstats.php:107
-msgid "Diaspora Channels"
-msgstr "Каналы Diaspora"
+#: ../../extend/addon/hzaddons/redfiles/redfilehelper.php:64
+msgid "file"
+msgstr "файл"
-#: ../../addon/dirstats/dirstats.php:109
-msgid "Aged 35 and above"
-msgstr "Возраст 35 и выше"
+#: ../../extend/addon/hzaddons/twitter/twitter.php:107
+msgid "Post to Twitter"
+msgstr "Опубликовать в Twitter"
-#: ../../addon/dirstats/dirstats.php:111
-msgid "Aged 34 and under"
-msgstr "Возраст 34 и ниже"
+#: ../../extend/addon/hzaddons/twitter/twitter.php:612
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:95
+msgid "Submit Settings"
+msgstr "Отправить настройки"
-#: ../../addon/dirstats/dirstats.php:113
-msgid "Average Age"
-msgstr "Средний возраст"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:65
+msgid "Twitter settings updated."
+msgstr "Настройки Twitter обновлены"
-#: ../../addon/dirstats/dirstats.php:115
-msgid "Known Chatrooms"
-msgstr "Известные чаты"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:78
+msgid "Twitter Crosspost Connector App"
+msgstr "Приложение \"Публикация в Twitter\""
-#: ../../addon/dirstats/dirstats.php:117
-msgid "Known Tags"
-msgstr "Известные теги"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:79
+msgid "Relay public posts to Twitter"
+msgstr "Пересылает общедоступные публикации в Twitter"
-#: ../../addon/dirstats/dirstats.php:119
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:103
msgid ""
-"Please note Diaspora and Friendica statistics are merely those **this "
-"directory** is aware of, and not all those known in the network. This also "
-"applies to chatrooms,"
-msgstr "Обратите внимание, что статистика Diaspora и Friendica это только те, о которых ** этот каталог ** знает, а не все известные в сети. Это также относится и к чатам."
-
-#: ../../addon/likebanner/likebanner.php:51
-msgid "Your Webbie:"
-msgstr "Ваш Webbie:"
-
-#: ../../addon/likebanner/likebanner.php:54
-msgid "Fontsize (px):"
-msgstr "Размер шрифта (px):"
-
-#: ../../addon/likebanner/likebanner.php:68
-msgid "Link:"
-msgstr "Ссылка:"
-
-#: ../../addon/likebanner/likebanner.php:70
-msgid "Like us on Hubzilla"
-msgstr "Нравится на Hubzilla"
-
-#: ../../addon/likebanner/likebanner.php:72
-msgid "Embed:"
-msgstr "Встроить:"
-
-#: ../../addon/redphotos/redphotos.php:106
-msgid "Photos imported"
-msgstr "Фотографии импортированы"
-
-#: ../../addon/redphotos/redphotos.php:129
-msgid "Redmatrix Photo Album Import"
-msgstr "Импортировать альбом фотографий Redmatrix"
-
-#: ../../addon/redphotos/redphotos.php:130
-msgid "This will import all your Redmatrix photo albums to this channel."
-msgstr "Это позволит импортировать все ваши альбомы фотографий Redmatrix в этот канал."
-
-#: ../../addon/redphotos/redphotos.php:131
-#: ../../addon/redfiles/redfiles.php:121
-msgid "Redmatrix Server base URL"
-msgstr "Базовый URL сервера Redmatrix"
-
-#: ../../addon/redphotos/redphotos.php:132
-#: ../../addon/redfiles/redfiles.php:122
-msgid "Redmatrix Login Username"
-msgstr "Имя пользователя Redmatrix"
+"No consumer key pair for Twitter found. Please contact your site "
+"administrator."
+msgstr "Не найдено пары ключей для Twitter. Пожалуйста, свяжитесь с администратором сайта."
-#: ../../addon/redphotos/redphotos.php:133
-#: ../../addon/redfiles/redfiles.php:123
-msgid "Redmatrix Login Password"
-msgstr "Пароль Redmatrix"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:125
+msgid ""
+"At this Hubzilla instance the Twitter plugin was enabled but you have not "
+"yet connected your account to your Twitter account. To do so click the "
+"button below to get a PIN from Twitter which you have to copy into the input "
+"box below and submit the form. Only your <strong>public</strong> posts will "
+"be posted to Twitter."
+msgstr "В этой установке Hubzilla плагин Twitter был включён, однако пока он не подключён к вашему аккаунту в Twitter. Для этого нажмите на кнопку ниже для получения PIN-кода от Twitter который нужно скопировать в поле ввода и отправить форму. Только ваши <strong>общедоступные</strong> публикации будут опубликованы в Twitter."
-#: ../../addon/redphotos/redphotos.php:134
-msgid "Import just this album"
-msgstr "Импортировать только этот альбом"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:127
+msgid "Log in with Twitter"
+msgstr "Войти в Twitter"
-#: ../../addon/redphotos/redphotos.php:134
-msgid "Leave blank to import all albums"
-msgstr "Оставьте пустым для импорта всех альбомов"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:130
+msgid "Copy the PIN from Twitter here"
+msgstr "Скопируйте PIN-код из Twitter здесь"
-#: ../../addon/redphotos/redphotos.php:135
-msgid "Maximum count to import"
-msgstr "Максимальное количество для импорта"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:147
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:272
+msgid "Currently connected to: "
+msgstr "В настоящее время подключён к:"
-#: ../../addon/redphotos/redphotos.php:135
-msgid "0 or blank to import all available"
-msgstr "0 или пусто для импорта всех доступных"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:152
+msgid ""
+"<strong>Note:</strong> Due your privacy settings (<em>Hide your profile "
+"details from unknown viewers?</em>) the link potentially included in public "
+"postings relayed to Twitter will lead the visitor to a blank page informing "
+"the visitor that the access to your profile has been restricted."
+msgstr "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в Twitter, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен."
-#: ../../addon/irc/Mod_Irc.php:23 ../../addon/irc/irc.php:41
-msgid "Popular Channels"
-msgstr "Популярные каналы"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157
+msgid "Twitter post length"
+msgstr "Длина публикации Twitter"
-#: ../../addon/irc/irc.php:37
-msgid "Channels to auto connect"
-msgstr "Каналы для автоматического подключения"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:157
+msgid "Maximum tweet length"
+msgstr "Максимальная длина твита"
-#: ../../addon/irc/irc.php:37 ../../addon/irc/irc.php:41
-msgid "Comma separated list"
-msgstr "Список, разделённый запятыми"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162
+msgid "Send public postings to Twitter by default"
+msgstr "Отправлять общедоступные публикации в Twitter по умолчанию"
-#: ../../addon/irc/irc.php:45
-msgid "IRC Settings"
-msgstr "Настройки IRC"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:162
+msgid ""
+"If enabled your public postings will be posted to the associated Twitter "
+"account by default"
+msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи Twitter по умолчанию"
-#: ../../addon/irc/irc.php:54
-msgid "IRC settings saved."
-msgstr "Настройки IRC сохранены"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:171
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
+msgid "Clear OAuth configuration"
+msgstr "Очистить конфигурацию OAuth"
-#: ../../addon/irc/irc.php:58
-msgid "IRC Chatroom"
-msgstr "Чат IRC"
+#: ../../extend/addon/hzaddons/twitter/Mod_Twitter.php:181
+msgid "Twitter Crosspost Connector"
+msgstr "Публикация в Twitter"
-#: ../../addon/gallery/gallery.php:38 ../../addon/gallery/Mod_Gallery.php:135
-msgid "Gallery"
-msgstr "Галерея"
+#: ../../extend/addon/hzaddons/tour/tour.php:76
+msgid "Edit your profile and change settings."
+msgstr "Отредактировать ваш профиль и изменить настройки."
-#: ../../addon/gallery/gallery.php:41
-msgid "Photo Gallery"
-msgstr "Фотогалерея"
+#: ../../extend/addon/hzaddons/tour/tour.php:77
+msgid "Click here to see activity from your connections."
+msgstr "Нажмите сюда для отображения активности ваши контактов."
-#: ../../addon/gallery/Mod_Gallery.php:58
-msgid "Gallery App"
-msgstr "Приложение \"Галерея\""
+#: ../../extend/addon/hzaddons/tour/tour.php:78
+msgid "Click here to see your channel home."
+msgstr "Нажмите сюда чтобы увидеть главную страницу вашего канала."
-#: ../../addon/gallery/Mod_Gallery.php:59
-msgid "A simple gallery for your photo albums"
-msgstr "Простая галлерея для ваших фотоальбомов"
+#: ../../extend/addon/hzaddons/tour/tour.php:79
+msgid "You can access your private messages from here."
+msgstr "Вы можете получить доступ с личной переписке здесь."
-#: ../../addon/ljpost/Mod_Ljpost.php:36
-msgid "Livejournal Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Livejournal\""
+#: ../../extend/addon/hzaddons/tour/tour.php:80
+msgid "Create new events here."
+msgstr "Создать новое событие здесь."
-#: ../../addon/ljpost/Mod_Ljpost.php:37
-msgid "Relay public posts to Livejournal"
-msgstr "Пересылает общедоступные публикации в Livejournal"
+#: ../../extend/addon/hzaddons/tour/tour.php:81
+msgid ""
+"You can accept new connections and change permissions for existing ones "
+"here. You can also e.g. create groups of contacts."
+msgstr "Вы можете подключать новые контакты и менять разрешения для существующих здесь. Также вы можете создавать их группы."
-#: ../../addon/ljpost/Mod_Ljpost.php:54
-msgid "Livejournal username"
-msgstr "Имя пользователя Livejournal"
+#: ../../extend/addon/hzaddons/tour/tour.php:82
+msgid "System notifications will arrive here"
+msgstr "Системные оповещения будут показываться здесь"
-#: ../../addon/ljpost/Mod_Ljpost.php:58
-msgid "Livejournal password"
-msgstr "Пароль Livejournal"
+#: ../../extend/addon/hzaddons/tour/tour.php:83
+msgid "Search for content and users"
+msgstr "Поиск пользователей и содержимого"
-#: ../../addon/ljpost/Mod_Ljpost.php:62
-msgid "Post to Livejournal by default"
-msgstr "Публиковать в Livejournal по умолчанию"
+#: ../../extend/addon/hzaddons/tour/tour.php:84
+msgid "Browse for new contacts"
+msgstr "Поиск новых контактов"
-#: ../../addon/ljpost/Mod_Ljpost.php:70
-msgid "Livejournal Crosspost Connector"
-msgstr "Пересылка публикаций Livejournal"
+#: ../../extend/addon/hzaddons/tour/tour.php:85
+msgid "Launch installed apps"
+msgstr "Запустить установленные приложения"
-#: ../../addon/ljpost/ljpost.php:45
-msgid "Post to Livejournal"
-msgstr "Опубликовать в Livejournal"
+#: ../../extend/addon/hzaddons/tour/tour.php:86
+msgid "Looking for help? Click here."
+msgstr "Нужна помощь? Нажмите сюда."
-#: ../../addon/openid/openid.php:49
+#: ../../extend/addon/hzaddons/tour/tour.php:87
msgid ""
-"We encountered a problem while logging in with the OpenID you provided. "
-"Please check the correct spelling of the ID."
-msgstr "Мы столкнулись с проблемой входа с предоставленным вами OpenID. Пожалуйста, проверьте корректность его написания."
+"New events have occurred in your network. Click here to see what has "
+"happened!"
+msgstr "Новые события произошли в вашей сети. Нажмите здесь для того, чтобы знать что случилось!"
-#: ../../addon/openid/openid.php:49
-msgid "The error message was:"
-msgstr "Сообщение об ошибке было:"
+#: ../../extend/addon/hzaddons/tour/tour.php:88
+msgid "You have received a new private message. Click here to see from who!"
+msgstr "Вы получили новое личное сообщение. Нажмите чтобы увидеть от кого!"
-#: ../../addon/openid/MysqlProvider.php:52
-msgid "First Name"
-msgstr "Имя"
+#: ../../extend/addon/hzaddons/tour/tour.php:89
+msgid "There are events this week. Click here too see which!"
+msgstr "На этой неделе есть события. Нажмите здесь чтобы увидеть какие!"
-#: ../../addon/openid/MysqlProvider.php:53
-msgid "Last Name"
-msgstr "Фамилия"
+#: ../../extend/addon/hzaddons/tour/tour.php:90
+msgid "You have received a new introduction. Click here to see who!"
+msgstr "Вы были представлены. Нажмите чтобы увидеть кому!"
-#: ../../addon/openid/MysqlProvider.php:54 ../../addon/redred/Mod_Redred.php:75
-msgid "Nickname"
-msgstr "Псевдоним"
+#: ../../extend/addon/hzaddons/tour/tour.php:91
+msgid ""
+"There is a new system notification. Click here to see what has happened!"
+msgstr "Это новое системное уведомление. Нажмите чтобы посмотреть что случилось!"
-#: ../../addon/openid/MysqlProvider.php:55
-msgid "Full Name"
-msgstr "Полное имя"
+#: ../../extend/addon/hzaddons/tour/tour.php:94
+msgid "Click here to share text, images, videos and sound."
+msgstr "Нажмите сюда чтобы поделиться текстом, изображениями, видео или треком."
-#: ../../addon/openid/MysqlProvider.php:61
-msgid "Profile Photo 16px"
-msgstr "Фотография профиля 16px"
+#: ../../extend/addon/hzaddons/tour/tour.php:95
+msgid "You can write an optional title for your update (good for long posts)."
+msgstr "Вы можете написать необязательный заголовок для вашей публикации (желательно для больших публикаций)."
-#: ../../addon/openid/MysqlProvider.php:62
-msgid "Profile Photo 32px"
-msgstr "Фотография профиля 32px"
+#: ../../extend/addon/hzaddons/tour/tour.php:96
+msgid "Entering some categories here makes it easier to find your post later."
+msgstr "Введите категории здесь чтобы было проще найти вашу публикацию позднее."
-#: ../../addon/openid/MysqlProvider.php:63
-msgid "Profile Photo 48px"
-msgstr "Фотография профиля 48px"
+#: ../../extend/addon/hzaddons/tour/tour.php:97
+msgid "Share photos, links, location, etc."
+msgstr "Поделиться фотографией, ссылками, местоположение и т.п."
-#: ../../addon/openid/MysqlProvider.php:64
-msgid "Profile Photo 64px"
-msgstr "Фотография профиля 64px"
+#: ../../extend/addon/hzaddons/tour/tour.php:98
+msgid ""
+"Only want to share content for a while? Make it expire at a certain date."
+msgstr "Хотите только поделиться временным содержимым? Установите срок его действия."
-#: ../../addon/openid/MysqlProvider.php:65
-msgid "Profile Photo 80px"
-msgstr "Фотография профиля 80px"
+#: ../../extend/addon/hzaddons/tour/tour.php:99
+msgid "You can password protect content."
+msgstr "Вы можете защитить содержимое паролем."
-#: ../../addon/openid/MysqlProvider.php:66
-msgid "Profile Photo 128px"
-msgstr "Фотография профиля 128px"
+#: ../../extend/addon/hzaddons/tour/tour.php:100
+msgid "Choose who you share with."
+msgstr "Выбрать с кем поделиться."
-#: ../../addon/openid/MysqlProvider.php:67
-msgid "Timezone"
-msgstr "Часовой пояс"
+#: ../../extend/addon/hzaddons/tour/tour.php:102
+msgid "Click here when you are done."
+msgstr "Нажмите здесь когда закончите."
-#: ../../addon/openid/MysqlProvider.php:70
-msgid "Birth Year"
-msgstr "Год рождения"
+#: ../../extend/addon/hzaddons/tour/tour.php:105
+msgid "Adjust from which channels posts should be displayed."
+msgstr "Настройте из каких каналов должны отображаться публикации."
-#: ../../addon/openid/MysqlProvider.php:71
-msgid "Birth Month"
-msgstr "Месяц рождения"
+#: ../../extend/addon/hzaddons/tour/tour.php:106
+msgid "Only show posts from channels in the specified privacy group."
+msgstr "Показывать только публикации из определённой группы безопасности."
-#: ../../addon/openid/MysqlProvider.php:72
-msgid "Birth Day"
-msgstr "День рождения"
+#: ../../extend/addon/hzaddons/tour/tour.php:110
+msgid ""
+"Easily find posts containing tags (keywords preceded by the \"#\" symbol)."
+msgstr "Лёгкий поиск сообщения, содержащего теги (ключевые слова, которым предшествует символ #)."
-#: ../../addon/openid/MysqlProvider.php:73
-msgid "Birthdate"
-msgstr "Дата рождения"
+#: ../../extend/addon/hzaddons/tour/tour.php:111
+msgid "Easily find posts in given category."
+msgstr "Лёгкий поиск публикаций в данной категории."
-#: ../../addon/openid/Mod_Openid.php:30
-msgid "OpenID protocol error. No ID returned."
-msgstr "Ошибка протокола OpenID. Идентификатор не возвращён."
+#: ../../extend/addon/hzaddons/tour/tour.php:112
+msgid "Easily find posts by date."
+msgstr "Лёгкий поиск публикаций по дате."
-#: ../../addon/openid/Mod_Openid.php:188 ../../include/auth.php:317
-msgid "Login failed."
-msgstr "Не удалось войти."
+#: ../../extend/addon/hzaddons/tour/tour.php:113
+msgid ""
+"Suggested users who have volounteered to be shown as suggestions, and who we "
+"think you might find interesting."
+msgstr "Рекомендуемые пользователи, которые были представлены в качестве предложений, и которые, по нашему мнению, могут оказаться интересными."
-#: ../../addon/openid/Mod_Id.php:85 ../../include/selectors.php:60
-#: ../../include/selectors.php:77 ../../include/channel.php:1536
-msgid "Male"
-msgstr "Мужчина"
+#: ../../extend/addon/hzaddons/tour/tour.php:114
+msgid "Here you see channels you have connected to."
+msgstr "Здесь вы видите каналы, к которым вы подключились."
-#: ../../addon/openid/Mod_Id.php:87 ../../include/selectors.php:60
-#: ../../include/selectors.php:77 ../../include/channel.php:1534
-msgid "Female"
-msgstr "Женщина"
+#: ../../extend/addon/hzaddons/tour/tour.php:115
+msgid "Save your search so you can repeat it at a later date."
+msgstr "Сохраните ваш поиск с тем, чтобы повторить его позже."
-#: ../../addon/randpost/randpost.php:97
-msgid "You're welcome."
-msgstr "Пожалуйста."
+#: ../../extend/addon/hzaddons/tour/tour.php:118
+msgid ""
+"If you see this icon you can be sure that the sender is who it say it is. It "
+"is normal that it is not always possible to verify the sender, so the icon "
+"will be missing sometimes. There is usually no need to worry about that."
+msgstr "Если вы видите этот значок, вы можете быть уверены, что отправитель - это тот, кто это говорит. Это нормально, что не всегда можно проверить отправителя, поэтому значок иногда будет отсутствовать. Обычно об этом не нужно беспокоиться."
-#: ../../addon/randpost/randpost.php:98
-msgid "Ah shucks..."
-msgstr "О, чёрт..."
+#: ../../extend/addon/hzaddons/tour/tour.php:119
+msgid ""
+"Danger! It seems someone tried to forge a message! This message is not "
+"necessarily from who it says it is from!"
+msgstr "Опасность! Кажется, кто-то пытался подделать сообщение! Это сообщение не обязательно от того, от кого оно значится!"
-#: ../../addon/randpost/randpost.php:99
-msgid "Don't mention it."
-msgstr "Не стоит благодарности."
+#: ../../extend/addon/hzaddons/tour/tour.php:126
+msgid ""
+"Welcome to Hubzilla! Would you like to see a tour of the UI?</p> <p>You can "
+"pause it at any time and continue where you left off by reloading the page, "
+"or navigting to another page.</p><p>You can also advance by pressing the "
+"return key"
+msgstr "Добро пожаловать в Hubzilla! Желаете получить обзор пользовательского интерфейса?</p> <p>Вы можете его приостановаить и в любое время перезагрузив страницу или перейдя на другую.</p><p>Также вы можете нажать клавишу \"Назад\""
-#: ../../addon/randpost/randpost.php:100
-msgid "&lt;blush&gt;"
-msgstr "&lt;краснею&gt;"
+#: ../../extend/addon/hzaddons/superblock/superblock.php:337
+msgid "Block Completely"
+msgstr "Заблокировать полностью"
-#: ../../addon/startpage/Mod_Startpage.php:50
-msgid "Startpage App"
-msgstr "Приложение \"Стартовая страница\""
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:20
+msgid "Superblock App"
+msgstr "Приложение Superblock"
-#: ../../addon/startpage/Mod_Startpage.php:51
-msgid "Set a preferred page to load on login from home page"
-msgstr "Устанавливает предпочтительную страницу для загрузки при входе с домашней страницы"
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:21
+msgid "Block channels"
+msgstr "Заблокировать каналы"
-#: ../../addon/startpage/Mod_Startpage.php:62
-msgid "Page to load after login"
-msgstr "Страница для загрузки после входа"
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:63
+msgid "superblock settings updated"
+msgstr "Настройки Superblock обновлены."
-#: ../../addon/startpage/Mod_Startpage.php:62
-msgid ""
-"Examples: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy "
-"collection), &quot;channel&quot; or &quot;notifications/system&quot; (leave "
-"blank for default network page (grid)."
-msgstr "Примеры: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy collection), &quot;channel&quot; or &quot;notifications/system&quot; (оставьте пустым для для страницы сети по умолчанию)."
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:87
+msgid "Currently blocked"
+msgstr "В настоящее время заблокирован"
-#: ../../addon/startpage/Mod_Startpage.php:70
-msgid "Startpage"
-msgstr "Стартовая страница"
+#: ../../extend/addon/hzaddons/superblock/Mod_Superblock.php:89
+msgid "No channels currently blocked"
+msgstr "В настоящее время никакие каналы не блокируются"
-#: ../../addon/morepokes/morepokes.php:19
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19
msgid "bitchslap"
-msgstr "дать леща"
+msgstr "дал леща"
-#: ../../addon/morepokes/morepokes.php:19
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:19
msgid "bitchslapped"
msgstr "получил леща"
-#: ../../addon/morepokes/morepokes.php:20
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20
msgid "shag"
-msgstr "вздрючить"
+msgstr "вздрючил"
-#: ../../addon/morepokes/morepokes.php:20
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:20
msgid "shagged"
msgstr "вздрюченный"
-#: ../../addon/morepokes/morepokes.php:21
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21
msgid "patent"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:21
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:21
msgid "patented"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:22
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22
msgid "hug"
-msgstr "обнять"
+msgstr "обнял"
-#: ../../addon/morepokes/morepokes.php:22
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:22
msgid "hugged"
msgstr "обнятый"
-#: ../../addon/morepokes/morepokes.php:23
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23
msgid "murder"
-msgstr "убить"
+msgstr "убил"
-#: ../../addon/morepokes/morepokes.php:23
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:23
msgid "murdered"
msgstr "убитый"
-#: ../../addon/morepokes/morepokes.php:24
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24
msgid "worship"
-msgstr "почитать"
+msgstr "почитает"
-#: ../../addon/morepokes/morepokes.php:24
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:24
msgid "worshipped"
msgstr "почитаемый"
-#: ../../addon/morepokes/morepokes.php:25
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25
msgid "kiss"
-msgstr "целовать"
+msgstr "поцеловал"
-#: ../../addon/morepokes/morepokes.php:25
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:25
msgid "kissed"
msgstr "поцелованный"
-#: ../../addon/morepokes/morepokes.php:26
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26
msgid "tempt"
-msgstr "искушать"
+msgstr "искушает"
-#: ../../addon/morepokes/morepokes.php:26
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:26
msgid "tempted"
msgstr "искушённый"
-#: ../../addon/morepokes/morepokes.php:27
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27
msgid "raise eyebrows at"
-msgstr "поднять брови"
+msgstr "поднял брови"
-#: ../../addon/morepokes/morepokes.php:27
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:27
msgid "raised their eyebrows at"
msgstr "поднял брови"
-#: ../../addon/morepokes/morepokes.php:28
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28
msgid "insult"
-msgstr "оскорбить"
+msgstr "оскорбил"
-#: ../../addon/morepokes/morepokes.php:28
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:28
msgid "insulted"
msgstr "оскорблённый"
-#: ../../addon/morepokes/morepokes.php:29
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29
msgid "praise"
-msgstr "хвалить"
+msgstr "похвалил"
-#: ../../addon/morepokes/morepokes.php:29
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:29
msgid "praised"
msgstr "похваленный"
-#: ../../addon/morepokes/morepokes.php:30
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30
msgid "be dubious of"
-msgstr "усомниться"
+msgstr "сомневается"
-#: ../../addon/morepokes/morepokes.php:30
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:30
msgid "was dubious of"
msgstr "усомнился"
-#: ../../addon/morepokes/morepokes.php:31
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31
msgid "eat"
-msgstr "есть"
+msgstr "ест"
-#: ../../addon/morepokes/morepokes.php:31
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:31
msgid "ate"
msgstr "съел"
-#: ../../addon/morepokes/morepokes.php:32
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32
msgid "giggle and fawn at"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:32
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:32
msgid "giggled and fawned at"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:33
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33
msgid "doubt"
-msgstr "сомневаться"
+msgstr "сомневается"
-#: ../../addon/morepokes/morepokes.php:33
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:33
msgid "doubted"
-msgstr "сомневался"
+msgstr "усомнился"
-#: ../../addon/morepokes/morepokes.php:34
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34
msgid "glare"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:34
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:34
msgid "glared at"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:35
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35
msgid "fuck"
-msgstr "трахнуть"
+msgstr "трахает"
-#: ../../addon/morepokes/morepokes.php:35
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:35
msgid "fucked"
msgstr "трахнул"
-#: ../../addon/morepokes/morepokes.php:36
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36
msgid "bonk"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:36
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:36
msgid "bonked"
msgstr ""
-#: ../../addon/morepokes/morepokes.php:37
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37
msgid "declare undying love for"
-msgstr "признаться в любви к"
+msgstr "признаётся в любви к"
-#: ../../addon/morepokes/morepokes.php:37
+#: ../../extend/addon/hzaddons/morepokes/morepokes.php:37
msgid "declared undying love for"
msgstr "признался в любви к"
-#: ../../addon/diaspora/Receiver.php:1495
-#, php-format
-msgid "%1$s dislikes %2$s's %3$s"
-msgstr "%1$s не нравится %2$s's %3$s"
-
-#: ../../addon/diaspora/Mod_Diaspora.php:40
-msgid "Diaspora Protocol Settings updated."
-msgstr "Настройки протокола Diaspora обновлены."
-
-#: ../../addon/diaspora/Mod_Diaspora.php:49
-msgid ""
-"The diaspora protocol does not support location independence. Connections "
-"you make within that network may be unreachable from alternate channel "
-"locations."
-msgstr "Протокол Diaspora не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
-
-#: ../../addon/diaspora/Mod_Diaspora.php:55
-msgid "Diaspora Protocol App"
-msgstr "Приложение \"Протокол Diaspora\""
-
-#: ../../addon/diaspora/Mod_Diaspora.php:74
-msgid "Allow any Diaspora member to comment on your public posts"
-msgstr "Разрешить любому участнику Diaspora комментировать ваши общедоступные публикации"
-
-#: ../../addon/diaspora/Mod_Diaspora.php:78
-msgid "Prevent your hashtags from being redirected to other sites"
-msgstr "Предотвратить перенаправление тегов на другие сайты"
-
-#: ../../addon/diaspora/Mod_Diaspora.php:82
-msgid "Sign and forward posts and comments with no existing Diaspora signature"
-msgstr "Подписывать и отправлять публикации и комментарии с несуществующей подписью Diaspora"
-
-#: ../../addon/diaspora/Mod_Diaspora.php:87
-msgid "Followed hashtags (comma separated, do not include the #)"
-msgstr "Отслеживаемые теги (через запятую, исключая #)"
-
-#: ../../addon/diaspora/Mod_Diaspora.php:96
-msgid "Diaspora Protocol"
-msgstr "Протокол Diaspora"
-
-#: ../../addon/diaspora/import_diaspora.php:18
-msgid "No username found in import file."
-msgstr "Имя пользователя не найдено в файле для импорта."
-
-#: ../../addon/diaspora/import_diaspora.php:43 ../../include/import.php:73
-msgid "Unable to create a unique channel address. Import failed."
-msgstr "Не удалось создать уникальный адрес канала. Импорт не завершен."
-
-#: ../../addon/photocache/Mod_Photocache.php:27
-msgid "Photo Cache settings saved."
-msgstr "Настройки кэширования изображений сохранены."
-
-#: ../../addon/photocache/Mod_Photocache.php:36
-msgid ""
-"Photo Cache addon saves a copy of images from external sites locally to "
-"increase your anonymity in the web."
-msgstr "Приложение \"Кэшировние изображений\" сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет."
-
-#: ../../addon/photocache/Mod_Photocache.php:42
-msgid "Photo Cache App"
-msgstr "Приложение \"Кэширование изображений\""
-
-#: ../../addon/photocache/Mod_Photocache.php:53
-msgid "Minimal photo size for caching"
-msgstr "Минимальный размер изображений для кэширования"
-
-#: ../../addon/photocache/Mod_Photocache.php:55
-msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default."
-msgstr "В пикселях. От 1 до 1024, 0 будет заменён значением по умолчанию."
-
-#: ../../addon/photocache/Mod_Photocache.php:64
-msgid "Photo Cache"
-msgstr "Кэширование изображений"
-
-#: ../../addon/testdrive/testdrive.php:104
-#, php-format
-msgid "Your account on %s will expire in a few days."
-msgstr "Ваш аккаунт на %s перестанет работать через несколько дней."
-
-#: ../../addon/testdrive/testdrive.php:105
-msgid "Your $Productname test account is about to expire."
-msgstr "Ваш тестовый аккаунт в $Productname близок к окончанию срока действия."
-
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:15
-msgid "Add some colour to tag clouds"
-msgstr "Добавить немного цвета для облака тегов"
-
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:21
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:26
-msgid "Rainbow Tag App"
-msgstr "Приложение \"Радуга тегов\""
-
-#: ../../addon/rainbowtag/Mod_Rainbowtag.php:34
-msgid "Rainbow Tag"
-msgstr "Радуга тегов"
-
-#: ../../addon/upload_limits/upload_limits.php:25
-msgid "Show Upload Limits"
-msgstr "Показать ограничения на загрузку"
-
-#: ../../addon/upload_limits/upload_limits.php:27
-msgid "Hubzilla configured maximum size: "
-msgstr "Максимальный размер настроенный в Hubzilla:"
-
-#: ../../addon/upload_limits/upload_limits.php:28
-msgid "PHP upload_max_filesize: "
-msgstr ""
-
-#: ../../addon/upload_limits/upload_limits.php:29
-msgid "PHP post_max_size (must be larger than upload_max_filesize): "
-msgstr "PHP post_max_size (должен быть больше чем upload_max_filesize): "
-
-#: ../../addon/gravatar/gravatar.php:123
-msgid "generic profile image"
-msgstr "Стандартное изображение профиля"
-
-#: ../../addon/gravatar/gravatar.php:124
-msgid "random geometric pattern"
-msgstr "Случайный геометрический рисунок"
-
-#: ../../addon/gravatar/gravatar.php:125
-msgid "monster face"
-msgstr "Лицо чудовища"
-
-#: ../../addon/gravatar/gravatar.php:126
-msgid "computer generated face"
-msgstr "Сгенерированное компьютером лицо"
-
-#: ../../addon/gravatar/gravatar.php:127
-msgid "retro arcade style face"
-msgstr "Лицо в стиле старой аркадной игры"
-
-#: ../../addon/gravatar/gravatar.php:128
-msgid "Hub default profile photo"
-msgstr "Фотография профиля по умолчанию"
-
-#: ../../addon/gravatar/gravatar.php:143
-msgid "Information"
-msgstr "Информация"
-
-#: ../../addon/gravatar/gravatar.php:143
-msgid ""
-"Libravatar addon is installed, too. Please disable Libravatar addon or this "
-"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
-"nothing was found at Libravatar."
-msgstr "Плагин Libravatar также установлен. Пожалуйста, отключите плагин Libravatar или этот плагин Gravatar. Если Плагин Libravatar ничего не найдёт, он вернётся в Gravatar."
-
-#: ../../addon/gravatar/gravatar.php:150 ../../addon/msgfooter/msgfooter.php:46
-#: ../../addon/xmpp/xmpp.php:43
-msgid "Save Settings"
-msgstr "Сохранить настройки"
-
-#: ../../addon/gravatar/gravatar.php:151
-msgid "Default avatar image"
-msgstr "Изображение аватара по умолчанию"
-
-#: ../../addon/gravatar/gravatar.php:151
-msgid "Select default avatar image if none was found at Gravatar. See README"
-msgstr "Выберите изображения аватар по умолчанию если ничего не было найдено в Gravatar (см. README)."
-
-#: ../../addon/gravatar/gravatar.php:152
-msgid "Rating of images"
-msgstr "Оценки изображений"
-
-#: ../../addon/gravatar/gravatar.php:152
-msgid "Select the appropriate avatar rating for your site. See README"
-msgstr "Выберите подходящую оценку аватара для вашего сайта (см. README)."
-
-#: ../../addon/gravatar/gravatar.php:165
-msgid "Gravatar settings updated."
-msgstr "Настройки Gravatar обновлены."
-
-#: ../../addon/hzfiles/hzfiles.php:79
-msgid "Hubzilla File Storage Import"
-msgstr "Импорт файлового хранилища Hubzilla"
-
-#: ../../addon/hzfiles/hzfiles.php:80
-msgid "This will import all your cloud files from another server."
-msgstr "Это позволит импортировать все ваши файлы с другого сервера."
-
-#: ../../addon/hzfiles/hzfiles.php:81
-msgid "Hubzilla Server base URL"
-msgstr "Базовый URL сервера Hubzilla"
-
-#: ../../addon/hzfiles/hzfiles.php:82
-msgid "Since modified date yyyy-mm-dd"
-msgstr "Начиная с даты изменений yyyy-mm-dd"
-
-#: ../../addon/hzfiles/hzfiles.php:83
-msgid "Until modified date yyyy-mm-dd"
-msgstr "Заканчивая датой изменений yyyy-mm-dd"
-
-#: ../../addon/visage/Mod_Visage.php:21
-msgid "Who viewed my channel/profile"
-msgstr "Кто смотрел мой канал / профиль"
+#: ../../extend/addon/hzaddons/logrot/logrot.php:36
+msgid "Logfile archive directory"
+msgstr "Каталог архивирования журнала"
-#: ../../addon/visage/Mod_Visage.php:25
-msgid "Recent Channel/Profile Viewers"
-msgstr "Последние просмотры канала / профиля"
+#: ../../extend/addon/hzaddons/logrot/logrot.php:36
+msgid "Directory to store rotated logs"
+msgstr "Каталог для хранения заархивированных журналов"
-#: ../../addon/visage/Mod_Visage.php:36
-msgid "No entries."
-msgstr "Нет записей."
+#: ../../extend/addon/hzaddons/logrot/logrot.php:37
+msgid "Logfile size in bytes before rotating"
+msgstr "Размер файла журнала в байтах для архивирования"
-#: ../../addon/nsabait/Mod_Nsabait.php:20
-#: ../../addon/nsabait/Mod_Nsabait.php:24
-msgid "NSA Bait App"
-msgstr "Приложение NSA Bait"
+#: ../../extend/addon/hzaddons/logrot/logrot.php:38
+msgid "Number of logfiles to retain"
+msgstr "Количество сохраняемых файлов журналов"
-#: ../../addon/nsabait/Mod_Nsabait.php:26
-msgid "Make yourself a political target"
-msgstr "Сделать себя политической мишенью"
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:51
+msgid "Your Webbie:"
+msgstr "Ваш Webbie:"
-#: ../../addon/mailtest/mailtest.php:19
-msgid "Send test email"
-msgstr "Отправить тестовый email"
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:54
+msgid "Fontsize (px):"
+msgstr "Размер шрифта (px):"
-#: ../../addon/mailtest/mailtest.php:50 ../../addon/hubwall/hubwall.php:50
-msgid "No recipients found."
-msgstr "Получателей не найдено."
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:68
+msgid "Link:"
+msgstr "Ссылка:"
-#: ../../addon/mailtest/mailtest.php:66
-msgid "Mail sent."
-msgstr "Сообщение отправлено"
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:70
+msgid "Like us on Hubzilla"
+msgstr "Нравится на Hubzilla"
-#: ../../addon/mailtest/mailtest.php:68
-msgid "Sending of mail failed."
-msgstr "Не удалось отправить сообщение."
+#: ../../extend/addon/hzaddons/likebanner/likebanner.php:72
+msgid "Embed:"
+msgstr "Встроить:"
-#: ../../addon/mailtest/mailtest.php:77
-msgid "Mail Test"
-msgstr "Тестовое сообщение"
+#: ../../extend/addon/hzaddons/qrator/qrator.php:48
+msgid "QR code"
+msgstr "QR-код"
-#: ../../addon/mailtest/mailtest.php:96 ../../addon/hubwall/hubwall.php:92
-msgid "Message subject"
-msgstr "Тема сообщения"
+#: ../../extend/addon/hzaddons/qrator/qrator.php:63
+msgid "QR Generator"
+msgstr "Генератор QR-кодов"
-#: ../../addon/mdpost/mdpost.php:42
-msgid "Use markdown for editing posts"
-msgstr "Использовать язык разметки Markdown для редактирования публикаций"
+#: ../../extend/addon/hzaddons/qrator/qrator.php:64
+msgid "Enter some text"
+msgstr "Введите любой текст"
-#: ../../addon/openstreetmap/openstreetmap.php:146
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:146
msgid "View Larger"
msgstr "Увеличить"
-#: ../../addon/openstreetmap/openstreetmap.php:170
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
msgid "Tile Server URL"
msgstr "URL сервера Tile"
-#: ../../addon/openstreetmap/openstreetmap.php:170
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
msgid ""
"A list of <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank"
"\">public tile servers</a>"
msgstr "Список <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">общедоступных серверов</a>"
-#: ../../addon/openstreetmap/openstreetmap.php:171
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
msgid "Nominatim (reverse geocoding) Server URL"
msgstr "URL сервера Nominatim (обратное геокодирование)"
-#: ../../addon/openstreetmap/openstreetmap.php:171
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
msgid ""
"A list of <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target="
"\"_blank\">Nominatim servers</a>"
msgstr "Список <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">серверов Nominatim</a>"
-#: ../../addon/openstreetmap/openstreetmap.php:172
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
msgid "Default zoom"
msgstr "Масштаб по умолчанию"
-#: ../../addon/openstreetmap/openstreetmap.php:172
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
msgid ""
"The default zoom level. (1:world, 18:highest, also depends on tile server)"
msgstr "Уровень размера по умолчанию (1 - весь мир, 18 - максимальный; зависит от сервера)."
-#: ../../addon/openstreetmap/openstreetmap.php:173
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:173
msgid "Include marker on map"
msgstr "Включите маркер на карте"
-#: ../../addon/openstreetmap/openstreetmap.php:173
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:173
msgid "Include a marker on the map."
msgstr "Включить маркер на карте"
-#: ../../addon/msgfooter/msgfooter.php:47
-msgid "text to include in all outgoing posts from this site"
-msgstr "текст, который будет добавлен во все исходящие публикации с этого сайта"
-
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:22
-msgid "Fuzzloc Settings updated."
-msgstr "Настройки примерного положения обновлены."
-
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:34
-msgid "Fuzzy Location App"
-msgstr "Приложение \"Примерное положение\""
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:27
+msgid "Photo Cache settings saved."
+msgstr "Настройки кэширования изображений сохранены."
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:35
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:36
msgid ""
-"Blur your precise location if your channel uses browser location mapping"
-msgstr "Размывает вашего точное местоположение в случае если ваш канал использует отображение местоположения из браузера"
-
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:40
-msgid "Minimum offset in meters"
-msgstr "Минимальное смещение в метрах"
-
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:44
-msgid "Maximum offset in meters"
-msgstr "Максимальное смещение в метрах"
-
-#: ../../addon/fuzzloc/Mod_Fuzzloc.php:53
-msgid "Fuzzy Location"
-msgstr "Примерное положение"
-
-#: ../../addon/rtof/rtof.php:51
-msgid "Post to Friendica"
-msgstr "Опубликовать в Friendica"
-
-#: ../../addon/rtof/Mod_Rtof.php:24
-msgid "Friendica Crosspost Connector Settings saved."
-msgstr "Настройки пересылки публикаций Friendica сохранены."
-
-#: ../../addon/rtof/Mod_Rtof.php:36
-msgid "Friendica Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Friendica\""
-
-#: ../../addon/rtof/Mod_Rtof.php:37
-msgid "Relay public postings to a connected Friendica account"
-msgstr "Пересылает общедоступные публикации на подключённую учётную запись Friendica"
-
-#: ../../addon/rtof/Mod_Rtof.php:49
-msgid "Send public postings to Friendica by default"
-msgstr "Отправлять общедоступные публикации во Friendica по умолчанию"
-
-#: ../../addon/rtof/Mod_Rtof.php:53
-msgid "Friendica API Path"
-msgstr "Путь к Friendica API"
+"Photo Cache addon saves a copy of images from external sites locally to "
+"increase your anonymity in the web."
+msgstr "Приложение \"Кэшировние изображений\" сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет."
-#: ../../addon/rtof/Mod_Rtof.php:53 ../../addon/redred/Mod_Redred.php:67
-msgid "https://{sitename}/api"
-msgstr ""
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:42
+msgid "Photo Cache App"
+msgstr "Приложение \"Кэширование изображений\""
-#: ../../addon/rtof/Mod_Rtof.php:57
-msgid "Friendica login name"
-msgstr "Имя входа Friendica"
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:53
+msgid "Minimal photo size for caching"
+msgstr "Минимальный размер изображений для кэширования"
-#: ../../addon/rtof/Mod_Rtof.php:61
-msgid "Friendica password"
-msgstr "Пароль Friendica"
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:55
+msgid "In pixels. From 1 up to 1024, 0 will be replaced with system default."
+msgstr "В пикселях. От 1 до 1024, 0 будет заменён значением по умолчанию."
-#: ../../addon/rtof/Mod_Rtof.php:69
-msgid "Friendica Crosspost Connector"
-msgstr "Пересылка публикаций Friendica"
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:64
+msgid "Photo Cache"
+msgstr "Кэширование изображений"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:96
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:96
msgid "Jappixmini App"
msgstr "Приложение Jappix Mini"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:97
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:97
msgid "Provides a Facebook-like chat using Jappix Mini"
msgstr "Предоставляет Facebook-подобный чат с использованием Jappix Mini"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:157 ../../include/channel.php:1452
-#: ../../include/channel.php:1623
-msgid "Status:"
-msgstr "Статус:"
-
-#: ../../addon/jappixmini/Mod_Jappixmini.php:161
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:161
msgid "Hide Jappixmini Chat-Widget from the webinterface"
msgstr "Скрыть виджет чата Jappix Mini из веб-интерфейса"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:166
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:166
msgid "Jabber username"
msgstr "Имя пользователя Jabber"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:172
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:172
msgid "Jabber server"
msgstr "Сервер Jabber"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:178
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:178
msgid "Jabber BOSH host URL"
msgstr "URL узла Jabber BOSH"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:185
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:185
msgid "Jabber password"
msgstr "Пароль Jabber"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:191
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:191
msgid "Encrypt Jabber password with Hubzilla password"
msgstr "Зашифровать пароль Jabber с помощью пароля Hubzilla"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:195
-#: ../../addon/redred/Mod_Redred.php:79
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:195
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:79
msgid "Hubzilla password"
msgstr "Пароль Hubzilla"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:199
-#: ../../addon/jappixmini/Mod_Jappixmini.php:203
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:199
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:203
msgid "Approve subscription requests from Hubzilla contacts automatically"
msgstr "Утверждать запросы на подписку от контактов Hubzilla автоматически"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:207
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:207
msgid "Purge internal list of jabber addresses of contacts"
msgstr "Очистить внутренний список адресов контактов Jabber"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:212
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:212
msgid "Configuration Help"
msgstr "Помощь по конфигурации"
-#: ../../addon/jappixmini/Mod_Jappixmini.php:258
+#: ../../extend/addon/hzaddons/jappixmini/Mod_Jappixmini.php:258
msgid "Jappixmini Settings"
msgstr "Настройки Jappix Мini"
-#: ../../addon/upgrade_info/upgrade_info.php:43
-msgid "Your channel has been upgraded to the latest $Projectname version."
-msgstr "Ваш канал был обновлён на последнюю версию $Projectname."
-
-#: ../../addon/upgrade_info/upgrade_info.php:44
-msgid ""
-"To improve usability, we have converted some features into installable stand-"
-"alone apps."
-msgstr "Чтобы улучшить удобство использования, некоторые функции теперь доступны в виде устанавливаемых автономных приложений."
-
-#: ../../addon/upgrade_info/upgrade_info.php:45
-msgid "Please visit the $Projectname"
-msgstr "Пожалуйста, посетите $Projectname"
-
-#: ../../addon/upgrade_info/upgrade_info.php:46
-msgid "app store"
-msgstr "раздел \"Приложения\""
-
-#: ../../addon/upgrade_info/upgrade_info.php:47
-msgid "and install possibly missing apps."
-msgstr "и установите необходимые вам."
-
-#: ../../addon/upgrade_info/upgrade_info.php:52
-msgid "Upgrade Info"
-msgstr "Сведения об обновлении"
-
-#: ../../addon/upgrade_info/upgrade_info.php:56
-msgid "Do not show this again"
-msgstr "Больше не показывать"
-
-#: ../../addon/channelreputation/channelreputation.php:98
-#: ../../addon/channelreputation/channelreputation.php:99
-#: ../../addon/cart/myshop.php:141 ../../addon/cart/myshop.php:177
-#: ../../addon/cart/myshop.php:211 ../../addon/cart/myshop.php:259
-#: ../../addon/cart/myshop.php:294 ../../addon/cart/myshop.php:317
-msgid "Access Denied"
-msgstr "Доступ запрещён"
-
-#: ../../addon/channelreputation/channelreputation.php:106
-msgid "Enable Community Moderation"
-msgstr "Включить модерацию сообщества"
-
-#: ../../addon/channelreputation/channelreputation.php:114
-msgid "Reputation automatically given to new members"
-msgstr "Репутация автоматически предоставляемая новым участникам"
-
-#: ../../addon/channelreputation/channelreputation.php:115
-msgid "Reputation will never fall below this value"
-msgstr "Репутация никогда не упадёт ниже этого значения"
-
-#: ../../addon/channelreputation/channelreputation.php:116
-msgid "Minimum reputation before posting is allowed"
-msgstr "Минимальная репутация для разрешения возможности размещать публикации"
-
-#: ../../addon/channelreputation/channelreputation.php:117
-msgid "Minimum reputation before commenting is allowed"
-msgstr "Минимальная репутация для разрешения комментирования"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:57
+msgid "Errors encountered deleting database table "
+msgstr "Возникшие при удалении таблицы базы данных ошибки"
-#: ../../addon/channelreputation/channelreputation.php:118
-msgid "Minimum reputation before a member is able to moderate other posts"
-msgstr "Минимальная репутация для возможности модерирования участником чужих публикаций"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96
+msgid "Drop tables when uninstalling?"
+msgstr "Удалить таблицы при деинсталляции?"
-#: ../../addon/channelreputation/channelreputation.php:119
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:96
msgid ""
-"Max ratio of moderator's reputation that can be added to/deducted from "
-"reputation of person being moderated"
-msgstr "Максимальное соотношение репутации модератора, которое может быть добавлено / вычтено из репутации модерируемого участника"
-
-#: ../../addon/channelreputation/channelreputation.php:120
-msgid "Reputation \"cost\" to post"
-msgstr "\"Стоимость\" репутации для публикации"
-
-#: ../../addon/channelreputation/channelreputation.php:121
-msgid "Reputation \"cost\" to comment"
-msgstr "\"Стоимость\" репутации для комментирования"
+"If checked, the Rendezvous database tables will be deleted when the plugin "
+"is uninstalled."
+msgstr "Если включено, то таблицы базы данных Rendezvous будут удалены при удалении плагина."
-#: ../../addon/channelreputation/channelreputation.php:122
-msgid ""
-"Reputation automatically recovers at this rate per hour until it reaches "
-"minimum_to_post"
-msgstr "Репутация автоматически восстанавливается с этой скоростью в час пока не достигает значения minimum_to_post"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97
+msgid "Mapbox Access Token"
+msgstr "Токен доступа к Mapbox"
-#: ../../addon/channelreputation/channelreputation.php:123
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:97
msgid ""
-"When minimum_to_moderate > reputation > minimum_to_post reputation recovers "
-"at this rate per hour"
-msgstr "При minimum_to_moderate > репутация > minimum_to_post репутация восстанавливается с этой скоростью в час"
-
-#: ../../addon/channelreputation/channelreputation.php:137
-msgid "Community Moderation Settings"
-msgstr "Настройки модерирования сообщества"
-
-#: ../../addon/channelreputation/channelreputation.php:365
-msgid "Can moderate reputation on my channel."
-msgstr "Может модерировать репутацию на моём канале"
-
-#: ../../addon/channelreputation/channelreputation.php:549
-#: ../../addon/channelreputation/channelreputation.php:552
-msgid "Channel Reputation"
-msgstr "Репутация канала"
-
-#: ../../addon/superblock/superblock.php:337
-msgid "Block Completely"
-msgstr "Заблокировать полностью"
-
-#: ../../addon/superblock/Mod_Superblock.php:20
-msgid "Superblock App"
-msgstr "Приложение Superblock"
-
-#: ../../addon/superblock/Mod_Superblock.php:21
-msgid "Block channels"
-msgstr "Заблокировать каналы"
-
-#: ../../addon/superblock/Mod_Superblock.php:63
-msgid "superblock settings updated"
-msgstr "Настройки Superblock обновлены."
-
-#: ../../addon/superblock/Mod_Superblock.php:87
-msgid "Currently blocked"
-msgstr "В настоящее время заблокирован"
-
-#: ../../addon/superblock/Mod_Superblock.php:89
-msgid "No channels currently blocked"
-msgstr "В настоящее время никакие каналы не блокируются"
-
-#: ../../addon/nofed/Mod_Nofed.php:21
-msgid "nofed Settings saved."
-msgstr "Настройки nofed сохранены."
+"If you enter a Mapbox access token, it will be used to retrieve map tiles "
+"from Mapbox instead of the default OpenStreetMap tile server."
+msgstr "Если вы введете токен доступа к Mapbox, он будет использоваться для извлечения фрагментов карты из Mapbox вместо стандартного сервера OpenStreetMap."
-#: ../../addon/nofed/Mod_Nofed.php:33
-msgid "No Federation App"
-msgstr "Приложение No Federation"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:162
+msgid "Rendezvous"
+msgstr ""
-#: ../../addon/nofed/Mod_Nofed.php:34
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:167
msgid ""
-"Prevent posting from being federated to anybody. It will exist only on your "
-"channel page."
-msgstr "Запрещает федеративные функций для публикаций. Они будут существовать только на странице вашего канала."
-
-#: ../../addon/nofed/Mod_Nofed.php:42
-msgid "Federate posts by default"
-msgstr "Разрешить федерацию публикаций по умолчанию"
-
-#: ../../addon/nofed/Mod_Nofed.php:50
-msgid "No Federation"
-msgstr "Отключить Federation"
-
-#: ../../addon/nofed/nofed.php:47
-msgid "Federate"
-msgstr "Федерировать"
+"This identity has been deleted by another member due to inactivity. Please "
+"press the \"New identity\" button or refresh the page to register a new "
+"identity. You may use the same name."
+msgstr "Этот идентификатор был удалён другим участником из-за неактивности. Пожалуйста нажмите кнопку \"Новый идентификатор\" для обновления страницы и получения нового идентификатора. Вы можете использовать то же имя."
-#: ../../addon/redred/Mod_Redred.php:24
-msgid "Channel is required."
-msgstr "Необходим канал."
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:168
+msgid "Welcome to Rendezvous!"
+msgstr "Добро пожаловать в Rendezvous!"
-#: ../../addon/redred/Mod_Redred.php:38
-msgid "Hubzilla Crosspost Connector Settings saved."
-msgstr "Настройки пересылки публикаций Hubzilla сохранены."
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:169
+msgid ""
+"Enter your name to join this rendezvous. To begin sharing your location with "
+"the other members, tap the GPS control. When your location is discovered, a "
+"red dot will appear and others will be able to see you on the map."
+msgstr "Введите ваше имя для вступления в это Rendezvous. Для того, чтобы делиться вашим положением с другими участниками, нажмите \"GPS control\". Когда ваше местоположение определно, красная точка появится и остальные смогут увидеть вас на карте."
-#: ../../addon/redred/Mod_Redred.php:50
-#: ../../addon/statusnet/Mod_Statusnet.php:146
-msgid "Hubzilla Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Hubzilla\""
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:171
+msgid "Let's meet here"
+msgstr "Давайте встретимся здесь"
-#: ../../addon/redred/Mod_Redred.php:51
-msgid "Relay public postings to another Hubzilla channel"
-msgstr "Пересылает общедоступные публикации в другой канал Hubzilla"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:174
+msgid "New marker"
+msgstr "Новый маркер"
-#: ../../addon/redred/Mod_Redred.php:63
-msgid "Send public postings to Hubzilla channel by default"
-msgstr "Отправлять общедоступные публикации в канал Hubzilla по умолчанию"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:175
+msgid "Edit marker"
+msgstr "Редактировать маркер"
-#: ../../addon/redred/Mod_Redred.php:67
-msgid "Hubzilla API Path"
-msgstr "Путь к Hubzilla API"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:176
+msgid "New identity"
+msgstr "Новый идентификатор"
-#: ../../addon/redred/Mod_Redred.php:71
-msgid "Hubzilla login name"
-msgstr "Имя входа Hubzilla"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:177
+msgid "Delete marker"
+msgstr "Удалить маркер"
-#: ../../addon/redred/Mod_Redred.php:75
-msgid "Hubzilla channel name"
-msgstr "Название канала Hubzilla"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:178
+msgid "Delete member"
+msgstr "Удалить участника"
-#: ../../addon/redred/Mod_Redred.php:87
-msgid "Hubzilla Crosspost Connector"
-msgstr "Пересылка публикаций Hubzilla"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:179
+msgid "Edit proximity alert"
+msgstr "Изменить оповещение о близости"
-#: ../../addon/redred/redred.php:50
-msgid "Post to Hubzilla"
-msgstr "Опубликовать в Hubzilla"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180
+msgid ""
+"A proximity alert will be issued when this member is within a certain radius "
+"of you.<br><br>Enter a radius in meters (0 to disable):"
+msgstr "Оповещение о близости будет произведено, если этот участник находится на определённом расстоянии от вас. <br><br>Введите радиус в метрах (0 для отключения):"
-#: ../../addon/logrot/logrot.php:36
-msgid "Logfile archive directory"
-msgstr "Каталог архивирования журнала"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:180
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:185
+msgid "distance"
+msgstr "расстояние"
-#: ../../addon/logrot/logrot.php:36
-msgid "Directory to store rotated logs"
-msgstr "Каталог для хранения заархивированных журналов"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:181
+msgid "Proximity alert distance (meters)"
+msgstr "Расстояние для уведомления о близости (метров)"
-#: ../../addon/logrot/logrot.php:37
-msgid "Logfile size in bytes before rotating"
-msgstr "Размер файла журнала в байтах для архивирования"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:182
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:184
+msgid ""
+"A proximity alert will be issued when you are within a certain radius of the "
+"marker location.<br><br>Enter a radius in meters (0 to disable):"
+msgstr "Оповещение о близости будет произведено, если вы находитесь на определённом расстоянии местоположения маркера. <br><br>Введите радиус в метрах (0 для отключения):"
-#: ../../addon/logrot/logrot.php:38
-msgid "Number of logfiles to retain"
-msgstr "Количество сохраняемых файлов журналов"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:183
+msgid "Marker proximity alert"
+msgstr "Маркер уведомления о близости"
-#: ../../addon/frphotos/frphotos.php:92
-msgid "Friendica Photo Album Import"
-msgstr "Импортировать альбом фотографий Friendica"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:186
+msgid "Reminder note"
+msgstr "Напоминание"
-#: ../../addon/frphotos/frphotos.php:93
-msgid "This will import all your Friendica photo albums to this Red channel."
-msgstr "Это позволит импортировать все ваши альбомы фотографий Friendica в этот канал."
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:187
+msgid ""
+"Enter a note to be displayed when you are within the specified proximity..."
+msgstr "Введите сообщение для отображения когда вы находитесь рядом"
-#: ../../addon/frphotos/frphotos.php:94
-msgid "Friendica Server base URL"
-msgstr "Базовый URL сервера Friendica"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:199
+msgid "Add new rendezvous"
+msgstr "Добавить новое Rendezvous."
-#: ../../addon/frphotos/frphotos.php:95
-msgid "Friendica Login Username"
-msgstr "Имя пользователя для входа Friendica"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:200
+msgid ""
+"Create a new rendezvous and share the access link with those you wish to "
+"invite to the group. Those who open the link become members of the "
+"rendezvous. They can view other member locations, add markers to the map, or "
+"share their own locations with the group."
+msgstr "Создайте новое Rendezvous и поделитесь ссылкой доступа с теми, кого вы хотите пригласить в группу. Тот, кто откроет эту ссылку, станет её участником. Участники могут видеть местоположение, добавлять маркеры на карту или делится своим собственным местоположением с группой."
-#: ../../addon/frphotos/frphotos.php:96
-msgid "Friendica Login Password"
-msgstr "Пароль для входа Firendica"
+#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:232
+msgid "You have no rendezvous. Press the button above to create a rendezvous!"
+msgstr "У вас нет Rendezvous. Нажмите на кнопку ниже чтобы создать его!"
-#: ../../addon/hsse/Mod_Hsse.php:15
-msgid "WYSIWYG status editor"
-msgstr "WYSIWYG редактор статуса "
+#: ../../extend/addon/hzaddons/piwik/piwik.php:85
+msgid ""
+"This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> "
+"analytics tool."
+msgstr "Этот сайт отслеживается с помощью инструментов аналитики <a href='http://www.piwik.org'>Piwik</a>."
-#: ../../addon/hsse/Mod_Hsse.php:21 ../../addon/hsse/Mod_Hsse.php:26
-msgid "WYSIWYG Status App"
-msgstr "Приложение \"WYSIWYG статус\""
+#: ../../extend/addon/hzaddons/piwik/piwik.php:88
+#, php-format
+msgid ""
+"If you do not want that your visits are logged this way you <a href='%s'>can "
+"set a cookie to prevent Piwik from tracking further visits of the site</a> "
+"(opt-out)."
+msgstr "Если вы не хотите, чтобы ваши визиты регистрировались таким образом, вы <a href='%s'>можете отключить cookie с тем, чтобы Piwik не отслеживал дальнейшие посещения сайта</a>."
-#: ../../addon/hsse/Mod_Hsse.php:34
-msgid "WYSIWYG Status"
-msgstr "WYSIWYG статус"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:96
+msgid "Piwik Base URL"
+msgstr "Базовый URL Piwik"
-#: ../../addon/hsse/hsse.php:82 ../../include/conversation.php:1285
-msgid "Set your location"
-msgstr "Задать своё местоположение"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:96
+msgid ""
+"Absolute path to your Piwik installation. (without protocol (http/s), with "
+"trailing slash)"
+msgstr "Абсолютный путь к вашей установке Piwik (без типа протокола, с начальным слэшем)"
-#: ../../addon/hsse/hsse.php:83 ../../include/conversation.php:1286
-msgid "Clear browser location"
-msgstr "Очистить местоположение из браузера"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:97
+msgid "Site ID"
+msgstr "ID сайта"
-#: ../../addon/hsse/hsse.php:99 ../../include/conversation.php:1302
-msgid "Embed (existing) photo from your photo albums"
-msgstr "Встроить (существующее) фото из вашего фотоальбома"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:98
+msgid "Show opt-out cookie link?"
+msgstr "Показывать ссылку на отказ от использования cookies?"
-#: ../../addon/hsse/hsse.php:135 ../../include/conversation.php:1338
-msgid "Tag term:"
-msgstr "Теги:"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:99
+msgid "Asynchronous tracking"
+msgstr "Асинхронное отслеживание"
-#: ../../addon/hsse/hsse.php:136 ../../include/conversation.php:1339
-msgid "Where are you right now?"
-msgstr "Где вы сейчас?"
+#: ../../extend/addon/hzaddons/piwik/piwik.php:100
+msgid "Enable frontend JavaScript error tracking"
+msgstr "Включить отслеживание ошибок JavaScript на фронтенде."
-#: ../../addon/hsse/hsse.php:141 ../../include/conversation.php:1344
-msgid "Choose a different album..."
-msgstr "Выбрать другой альбом..."
+#: ../../extend/addon/hzaddons/piwik/piwik.php:100
+msgid "This feature requires Piwik >= 2.2.0"
+msgstr "Эта функция требует версию Piwik >= 2.2.0"
-#: ../../addon/hsse/hsse.php:145 ../../include/conversation.php:1348
-msgid "Comments enabled"
-msgstr "Комментарии включены"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:40
+msgid "Pump.io Settings saved."
+msgstr "Настройки Pump.io сохранены."
-#: ../../addon/hsse/hsse.php:146 ../../include/conversation.php:1349
-msgid "Comments disabled"
-msgstr "Комментарии отключены"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:53
+msgid "Pump.io Crosspost Connector App"
+msgstr "Приложение \"Публикация в Pump.io\""
-#: ../../addon/hsse/hsse.php:195 ../../include/conversation.php:1401
-msgid "Page link name"
-msgstr "Название ссылки на страницу "
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:54
+msgid "Relay public posts to pump.io"
+msgstr "Пересылает общедоступные публикации в Pump.io"
-#: ../../addon/hsse/hsse.php:198 ../../include/conversation.php:1404
-msgid "Post as"
-msgstr "Опубликовать как"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73
+msgid "Pump.io servername"
+msgstr "Имя сервера Pump.io"
-#: ../../addon/hsse/hsse.php:212 ../../include/conversation.php:1418
-msgid "Toggle voting"
-msgstr "Подключить голосование"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:73
+msgid "Without \"http://\" or \"https://\""
+msgstr "Без \"http://\" или \"https://\""
-#: ../../addon/hsse/hsse.php:215 ../../include/conversation.php:1421
-msgid "Disable comments"
-msgstr "Отключить комментарии"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77
+msgid "Pump.io username"
+msgstr "Имя пользователя Pump.io"
-#: ../../addon/hsse/hsse.php:216 ../../include/conversation.php:1422
-msgid "Toggle comments"
-msgstr "Переключить комментарии"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:77
+msgid "Without the servername"
+msgstr "без имени сервера"
-#: ../../addon/hsse/hsse.php:224 ../../include/conversation.php:1430
-msgid "Categories (optional, comma-separated list)"
-msgstr "Категории (необязательно, список через запятую)"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:88
+msgid "You are not authenticated to pumpio"
+msgstr "Вы не аутентифицированы на Pump.io"
-#: ../../addon/hsse/hsse.php:247 ../../include/conversation.php:1453
-msgid "Other networks and post services"
-msgstr "Другие сети и службы публикаций"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:90
+msgid "(Re-)Authenticate your pump.io connection"
+msgstr "Аутентифицировать (повторно) ваше соединение с Pump.io"
-#: ../../addon/hsse/hsse.php:253 ../../include/conversation.php:1459
-msgid "Set publish date"
-msgstr "Установить дату публикации"
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:94
+msgid "Post to pump.io by default"
+msgstr "Публиковать в Pump.io по умолчанию"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:25
-msgid "ActivityPub Protocol Settings updated."
-msgstr "Настройки протокола ActivityPub обновлены."
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:98
+msgid "Should posts be public"
+msgstr "Публикации должны быть общедоступными"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:34
-msgid ""
-"The activitypub protocol does not support location independence. Connections "
-"you make within that network may be unreachable from alternate channel "
-"locations."
-msgstr "Протокол ActivityPub не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:102
+msgid "Mirror all public posts"
+msgstr "Отображать все общедоступные публикации"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:40
-msgid "Activitypub Protocol App"
-msgstr "Приложение \"Протокол ActivityPub\""
+#: ../../extend/addon/hzaddons/pumpio/Mod_Pumpio.php:112
+msgid "Pump.io Crosspost Connector"
+msgstr "Публикация в Pump.io"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:48
-msgid "Deliver to ActivityPub recipients in privacy groups"
-msgstr "Доставить получателям ActivityPub в группах безопасности"
+#: ../../extend/addon/hzaddons/pumpio/pumpio.php:152
+msgid "You are now authenticated to pumpio."
+msgstr "Вы аутентифицированы в Pump.io"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:48
-msgid ""
-"May result in a large number of mentions and expose all the members of your "
-"privacy group"
-msgstr "Может привести к большому количеству упоминаний и раскрытию участников группы безопасности"
+#: ../../extend/addon/hzaddons/pumpio/pumpio.php:153
+msgid "return to the featured settings page"
+msgstr "Вернутся к странице настроек"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:52
-msgid "Send multi-media HTML articles"
-msgstr "Отправить HTML статьи с мультимедиа"
+#: ../../extend/addon/hzaddons/pumpio/pumpio.php:168
+msgid "Post to Pump.io"
+msgstr "Опубликовать в Pump.io"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:52
-msgid "Not supported by some microblog services such as Mastodon"
-msgstr "Не поддерживается некоторыми микроблогами, например Mastodon"
+#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:20
+#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:24
+msgid "NSA Bait App"
+msgstr "Приложение NSA Bait"
-#: ../../addon/pubcrawl/Mod_Pubcrawl.php:60
-msgid "Activitypub Protocol"
-msgstr "Протокол ActivityPub"
+#: ../../extend/addon/hzaddons/nsabait/Mod_Nsabait.php:26
+msgid "Make yourself a political target"
+msgstr "Сделать себя политической мишенью"
-#: ../../addon/donate/donate.php:21
-msgid "Project Servers and Resources"
-msgstr "Серверы и ресурсы проекта"
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:19
+msgid "Send test email"
+msgstr "Отправить тестовый email"
-#: ../../addon/donate/donate.php:22
-msgid "Project Creator and Tech Lead"
-msgstr "Создатель проекта и технический руководитель"
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:50
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:50
+msgid "No recipients found."
+msgstr "Получателей не найдено."
-#: ../../addon/donate/donate.php:49
-msgid ""
-"And the hundreds of other people and organisations who helped make the "
-"Hubzilla possible."
-msgstr "И сотни других людей и организаций которые помогали в создании Hubzilla."
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:66
+msgid "Mail sent."
+msgstr "Сообщение отправлено"
-#: ../../addon/donate/donate.php:52
-msgid ""
-"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving "
-"their time and expertise - and often paying out of pocket for services they "
-"share with others."
-msgstr "Проекты Redmatrix / Hubzilla предоставляются, в основном, добровольцами, которые предоставляют свое время и опыт и, часто, оплачивают из своего кармана услуги, которыми они делятся с другими."
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:68
+msgid "Sending of mail failed."
+msgstr "Не удалось отправить сообщение."
-#: ../../addon/donate/donate.php:53
-msgid ""
-"There is no corporate funding and no ads, and we do not collect and sell "
-"your personal information. (We don't control your personal information - "
-"<strong>you do</strong>.)"
-msgstr "Здесь нет корпоративного финансирования и рекламы, мы не собираем и не продаем вашу личную информацию. (Мы не контролируем вашу личную информацию - <strong>это делаете вы</strong>.)"
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:77
+msgid "Mail Test"
+msgstr "Тестовое сообщение"
-#: ../../addon/donate/donate.php:54
-msgid ""
-"Help support our ground-breaking work in decentralisation, web identity, and "
-"privacy."
-msgstr "Помогите поддержать нашу новаторскую работу в областях децентрализации, веб-идентификации и конфиденциальности."
+#: ../../extend/addon/hzaddons/mailtest/mailtest.php:96
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:92
+msgid "Message subject"
+msgstr "Тема сообщения"
-#: ../../addon/donate/donate.php:56
-msgid ""
-"Your donations keep servers and services running and also helps us to "
-"provide innovative new features and continued development."
-msgstr "В ваших пожертвованиях поддерживают серверы и службы, а также помогают нам предоставлять новые возможности и продолжать развитие."
+#: ../../extend/addon/hzaddons/randpost/randpost.php:97
+msgid "You're welcome."
+msgstr "Пожалуйста."
-#: ../../addon/donate/donate.php:59
-msgid "Donate"
-msgstr "Пожертвовать"
+#: ../../extend/addon/hzaddons/randpost/randpost.php:98
+msgid "Ah shucks..."
+msgstr "О, чёрт..."
-#: ../../addon/donate/donate.php:61
-msgid ""
-"Choose a project, developer, or public hub to support with a one-time "
-"donation"
-msgstr "Выберите проект, разработчика или общедоступный узел для поддержки в форме единоразового пожертвования"
+#: ../../extend/addon/hzaddons/randpost/randpost.php:99
+msgid "Don't mention it."
+msgstr "Не стоит благодарности."
-#: ../../addon/donate/donate.php:62
-msgid "Donate Now"
-msgstr "Пожертвовать сейчас"
+#: ../../extend/addon/hzaddons/randpost/randpost.php:100
+msgid "&lt;blush&gt;"
+msgstr "&lt;краснею&gt;"
-#: ../../addon/donate/donate.php:63
-msgid ""
-"<strong><em>Or</em></strong> become a project sponsor (Hubzilla Project only)"
-msgstr "<strong><em>или</em></strong> станьте спонсором проекта (только для Hubzilla)"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:50
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:128
+msgid "System defaults:"
+msgstr "Системные по умолчанию:"
-#: ../../addon/donate/donate.php:64
-msgid ""
-"Please indicate if you would like your first name or full name (or nothing) "
-"to appear in our sponsor listing"
-msgstr "Пожалуйста, если желаете, укажите ваше имя для отображения в списке спонсоров."
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54
+msgid "Preferred Clipart IDs"
+msgstr "Предпочитаемый Clipart ID"
-#: ../../addon/donate/donate.php:65
-msgid "Sponsor"
-msgstr "Спонсор"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:54
+msgid "List of preferred clipart ids. These will be shown first."
+msgstr "Список предпочитаемых Clipart ID. Эти будут показаны первыми."
-#: ../../addon/donate/donate.php:68
-msgid "Special thanks to: "
-msgstr "Особые благодарности:"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55
+msgid "Default Search Term"
+msgstr "Условие поиска по умолчанию"
-#: ../../addon/chords/Mod_Chords.php:44
-msgid ""
-"This is a fairly comprehensive and complete guitar chord dictionary which "
-"will list most of the available ways to play a certain chord, starting from "
-"the base of the fingerboard up to a few frets beyond the twelfth fret "
-"(beyond which everything repeats). A couple of non-standard tunings are "
-"provided for the benefit of slide players, etc."
-msgstr ""
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:55
+msgid "The default search term. These will be shown second."
+msgstr "Условие поиска по умолчанию. Показываются во вторую очередь."
-#: ../../addon/chords/Mod_Chords.php:46
-msgid ""
-"Chord names start with a root note (A-G) and may include sharps (#) and "
-"flats (b). This software will parse most of the standard naming conventions "
-"such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."
-msgstr ""
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56
+msgid "Return After"
+msgstr "Вернуться после"
-#: ../../addon/chords/Mod_Chords.php:48
-msgid ""
-"Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, "
-"E7b13b11 ..."
-msgstr "Примеры действительных включают A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ..."
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:56
+msgid "Page to load after image selection."
+msgstr "Страница для загрузки после выбора изображения."
-#: ../../addon/chords/Mod_Chords.php:51
-msgid "Guitar Chords"
-msgstr "Гитарные аккорды"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:59
+msgid "Profile List"
+msgstr "Список профилей"
-#: ../../addon/chords/Mod_Chords.php:52
-msgid "The complete online chord dictionary"
-msgstr "Полный онлайн словарь аккордов"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61
+msgid "Order of Preferred"
+msgstr "Порядок предпочтения"
-#: ../../addon/chords/Mod_Chords.php:57
-msgid "Tuning"
-msgstr "Настройка"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:61
+msgid "Sort order of preferred clipart ids."
+msgstr "Порядок сортировки предпочитаемых Clipart ID. "
-#: ../../addon/chords/Mod_Chords.php:58
-msgid "Chord name: example: Em7"
-msgstr "Наименование аккорда - example: Em7"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:62
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:68
+msgid "Newest first"
+msgstr "Новое первым"
-#: ../../addon/chords/Mod_Chords.php:59
-msgid "Show for left handed stringing"
-msgstr "Показывать струны для левшей"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:65
+msgid "As entered"
+msgstr "По мере ввода"
-#: ../../addon/chords/chords.php:33
-msgid "Quick Reference"
-msgstr "Быстрая ссылка"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67
+msgid "Order of other"
+msgstr "Порядок других"
-#: ../../addon/libertree/libertree.php:43
-msgid "Post to Libertree"
-msgstr "Опубликовать в Libertree"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:67
+msgid "Sort order of other clipart ids."
+msgstr "Порядок сортировки остальных Clipart ID."
-#: ../../addon/libertree/Mod_Libertree.php:25
-msgid "Libertree Crosspost Connector Settings saved."
-msgstr "Настройки пересылки публикаций Libertree сохранены."
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:69
+msgid "Most downloaded first"
+msgstr "Самое загружаемое первым"
-#: ../../addon/libertree/Mod_Libertree.php:35
-msgid "Libertree Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Libertree\""
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:70
+msgid "Most liked first"
+msgstr "Самое нравящееся первым"
-#: ../../addon/libertree/Mod_Libertree.php:36
-msgid "Relay public posts to Libertree"
-msgstr "Пересылает общедоступные публикации в Libertree"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72
+msgid "Preferred IDs Message"
+msgstr "Сообщение от предпочитаемых ID"
-#: ../../addon/libertree/Mod_Libertree.php:51
-msgid "Libertree API token"
-msgstr "Токен Libertree API"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:72
+msgid "Message to display above preferred results."
+msgstr "Отображаемое сообщение над предпочитаемыми результатами."
-#: ../../addon/libertree/Mod_Libertree.php:55
-msgid "Libertree site URL"
-msgstr "URL сайта Libertree"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78
+msgid "Uploaded by: "
+msgstr "Загружено:"
-#: ../../addon/libertree/Mod_Libertree.php:59
-msgid "Post to Libertree by default"
-msgstr "Публиковать в Libertree по умолчанию"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:78
+msgid "Drawn by: "
+msgstr "Нарисовано:"
-#: ../../addon/libertree/Mod_Libertree.php:67
-msgid "Libertree Crosspost Connector"
-msgstr "Пересылка публикаций Libertree"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:182
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:194
+msgid "Use this image"
+msgstr "Использовать это изображение"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:41
-msgid "Flattr widget settings updated."
-msgstr "Настройки виджета Flattr обновлены."
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:192
+msgid "Or select from a free OpenClipart.org image:"
+msgstr "Или выберите из бесплатных изображений на OpenClipart.org"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:53
-msgid "Flattr Widget App"
-msgstr "Приложение \"Виджет Flattr\""
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:195
+msgid "Search Term"
+msgstr "Условие поиска"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:54
-msgid "Add a Flattr button to your channel page"
-msgstr "Добавить кнопку Flattr на страницу вашего канала"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:232
+msgid "Unknown error. Please try again later."
+msgstr "Неизвестная ошибка. Пожалуйста, повторите попытку позже."
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:65
-msgid "Flattr user"
-msgstr "Пользователь Flattr"
+#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:308
+msgid "Profile photo updated successfully."
+msgstr "Фотография профиля обновлена успешно."
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:69
-msgid "URL of the Thing to flattr"
-msgstr "URL ccылки на Flattr"
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:81
+msgid "Hubzilla File Storage Import"
+msgstr "Импорт файлового хранилища Hubzilla"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:69
-msgid "If empty channel URL is used"
-msgstr "Если пусто, то используется URL канала"
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:82
+msgid "This will import all your cloud files from another server."
+msgstr "Это позволит импортировать все ваши файлы с другого сервера."
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:73
-msgid "Title of the Thing to flattr"
-msgstr "Заголовок вещи на Flattr"
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:83
+msgid "Hubzilla Server base URL"
+msgstr "Базовый URL сервера Hubzilla"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:73
-msgid "If empty \"channel name on The Hubzilla\" will be used"
-msgstr "Если пусто, то будет использовано \"Название канала Hubzilla\""
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:84
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:140
+msgid "Since modified date yyyy-mm-dd"
+msgstr "Начиная с даты изменений yyyy-mm-dd"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:77
-msgid "Static or dynamic flattr button"
-msgstr "Статическая или динамическая кнопка Flattr"
+#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:85
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:141
+msgid "Until modified date yyyy-mm-dd"
+msgstr "Заканчивая датой изменений yyyy-mm-dd"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:77
-msgid "static"
-msgstr "статическая"
+#: ../../extend/addon/hzaddons/ljpost/ljpost.php:45
+msgid "Post to Livejournal"
+msgstr "Опубликовать в Livejournal"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:77
-msgid "dynamic"
-msgstr "динамическая"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:36
+msgid "Livejournal Crosspost Connector App"
+msgstr "Приложение \"Публикация в Livejournal\""
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:81
-msgid "Alignment of the widget"
-msgstr "Выравнивание виджета"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:37
+msgid "Relay public posts to Livejournal"
+msgstr "Пересылает общедоступные публикации в Livejournal"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:81
-msgid "left"
-msgstr "слева"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:54
+msgid "Livejournal username"
+msgstr "Имя пользователя Livejournal"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:81
-msgid "right"
-msgstr "справа"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:58
+msgid "Livejournal password"
+msgstr "Пароль Livejournal"
-#: ../../addon/flattrwidget/Mod_Flattrwidget.php:89
-msgid "Flattr Widget"
-msgstr "Виджет Flattr"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:62
+msgid "Post to Livejournal by default"
+msgstr "Публиковать в Livejournal по умолчанию"
-#: ../../addon/flattrwidget/flattrwidget.php:50
-msgid "Flattr this!"
-msgstr "Flattr это!"
+#: ../../extend/addon/hzaddons/ljpost/Mod_Ljpost.php:70
+msgid "Livejournal Crosspost Connector"
+msgstr "Публикация в Livejournal"
-#: ../../addon/statusnet/Mod_Statusnet.php:61
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:61
msgid ""
"Please contact your site administrator.<br />The provided API URL is not "
"valid."
msgstr "Пожалуйста свяжитесь с администратором сайта. <br />Предоставленный URL API недействителен."
-#: ../../addon/statusnet/Mod_Statusnet.php:98
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:98
msgid "We could not contact the GNU social API with the Path you entered."
msgstr "Нам не удалось установить контакт с GNU Social API по введённому вами пути"
-#: ../../addon/statusnet/Mod_Statusnet.php:130
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:130
msgid "GNU social settings updated."
msgstr "Настройки GNU Social обновлены."
-#: ../../addon/statusnet/Mod_Statusnet.php:147
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:146
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:50
+msgid "Hubzilla Crosspost Connector App"
+msgstr "Приложение \"Пересылка публикаций Hubzilla\""
+
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:147
msgid ""
"Relay public postings to a connected GNU social account (formerly StatusNet)"
msgstr "Пересылает общедоступные публикации на подключённую учётную запись GNU social (бывшая StatusNet)"
-#: ../../addon/statusnet/Mod_Statusnet.php:181
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:181
msgid "Globally Available GNU social OAuthKeys"
msgstr "Глобально доступные ключи OAuthKeys GNU Social"
-#: ../../addon/statusnet/Mod_Statusnet.php:183
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:183
msgid ""
"There are preconfigured OAuth key pairs for some GNU social servers "
"available. If you are using one of them, please use these credentials.<br /"
">If not feel free to connect to any other GNU social instance (see below)."
msgstr "Существуют предварительно настроенные пары ключей OAuth для некоторых доступных серверов GNU social. Если вы используете один из них, используйте эти учетные данные. <br />Если вы не хотите подключаться к какому-либо другому серверу GNU social (см. ниже)."
-#: ../../addon/statusnet/Mod_Statusnet.php:198
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:198
msgid "Provide your own OAuth Credentials"
msgstr "Предоставьте ваши собственные регистрационные данные OAuth"
-#: ../../addon/statusnet/Mod_Statusnet.php:200
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:200
msgid ""
"No consumer key pair for GNU social found. Register your Hubzilla Account as "
"an desktop client on your GNU social account, copy the consumer key pair "
@@ -11937,27 +13797,27 @@ msgid ""
"Hubzilla installation at your favourite GNU social installation."
msgstr "Не найдена пользовательская пара ключей для GNU social. Зарегистрируйте свою учетную запись Hubzilla в качестве настольного клиента в своей учетной записи GNU social, скопируйте cюда пару ключей пользователя и введите корневой каталог базы API. <br />Прежде чем регистрировать свою собственную пару ключей OAuth, спросите администратора, если ли уже пара ключей для этой установки Hubzilla в вашем GNU social."
-#: ../../addon/statusnet/Mod_Statusnet.php:204
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:204
msgid "OAuth Consumer Key"
msgstr "Ключ клиента OAuth"
-#: ../../addon/statusnet/Mod_Statusnet.php:208
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:208
msgid "OAuth Consumer Secret"
msgstr "Пароль клиента OAuth"
-#: ../../addon/statusnet/Mod_Statusnet.php:212
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212
msgid "Base API Path"
msgstr "Основной путь к API"
-#: ../../addon/statusnet/Mod_Statusnet.php:212
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212
msgid "Remember the trailing /"
msgstr "Запомнить закрывающий /"
-#: ../../addon/statusnet/Mod_Statusnet.php:216
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:216
msgid "GNU social application name"
msgstr "Имя приложения GNU social"
-#: ../../addon/statusnet/Mod_Statusnet.php:239
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:239
msgid ""
"To connect to your GNU social account click the button below to get a "
"security code from GNU social which you have to copy into the input box "
@@ -11965,32 +13825,27 @@ msgid ""
"posted to GNU social."
msgstr "Чтобы подключиться к вашей учетной записи GNU social нажмите кнопку ниже для получения кода безопасности из GNU social, который вы должны скопировать в поле ввода ниже и отправить форму. Только ваши общедоступные сообщения будут опубликованы в GNU social."
-#: ../../addon/statusnet/Mod_Statusnet.php:241
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:241
msgid "Log in with GNU social"
msgstr "Войти с GNU social"
-#: ../../addon/statusnet/Mod_Statusnet.php:244
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:244
msgid "Copy the security code from GNU social here"
msgstr "Скопируйте код безопасности GNU social здесь"
-#: ../../addon/statusnet/Mod_Statusnet.php:254
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:254
msgid "Cancel Connection Process"
msgstr "Отменить процесс подключения"
-#: ../../addon/statusnet/Mod_Statusnet.php:256
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:256
msgid "Current GNU social API is"
msgstr "Текущий GNU social API"
-#: ../../addon/statusnet/Mod_Statusnet.php:260
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
msgid "Cancel GNU social Connection"
msgstr "Отменить подключение с GNU social"
-#: ../../addon/statusnet/Mod_Statusnet.php:272
-#: ../../addon/twitter/Mod_Twitter.php:147
-msgid "Currently connected to: "
-msgstr "В настоящее время подключён к:"
-
-#: ../../addon/statusnet/Mod_Statusnet.php:277
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:277
msgid ""
"<strong>Note</strong>: Due your privacy settings (<em>Hide your profile "
"details from unknown viewers?</em>) the link potentially included in public "
@@ -11998,3315 +13853,1606 @@ msgid ""
"informing the visitor that the access to your profile has been restricted."
msgstr "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в GNU social, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен."
-#: ../../addon/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
msgid "Post to GNU social by default"
msgstr "Публиковать в GNU social по умолчанию"
-#: ../../addon/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
msgid ""
"If enabled your public postings will be posted to the associated GNU-social "
"account by default"
msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social по умолчанию"
-#: ../../addon/statusnet/Mod_Statusnet.php:291
-#: ../../addon/twitter/Mod_Twitter.php:171
-msgid "Clear OAuth configuration"
-msgstr "Очистить конфигурацию OAuth"
-
-#: ../../addon/statusnet/Mod_Statusnet.php:303
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:303
msgid "GNU-Social Crosspost Connector"
msgstr "Подключение пересылки публикаций GNU Social"
-#: ../../addon/statusnet/statusnet.php:145
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:145
msgid "Post to GNU social"
msgstr "Опубликовать в GNU Social"
-#: ../../addon/statusnet/statusnet.php:594
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:594
msgid "API URL"
msgstr ""
-#: ../../addon/statusnet/statusnet.php:597
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:597
msgid "Application name"
msgstr "Название приложения"
-#: ../../addon/qrator/qrator.php:48
-msgid "QR code"
-msgstr "QR-код"
-
-#: ../../addon/qrator/qrator.php:63
-msgid "QR Generator"
-msgstr "Генератор QR-кодов"
-
-#: ../../addon/qrator/qrator.php:64
-msgid "Enter some text"
-msgstr "Введите любой текст"
-
-#: ../../addon/chess/Mod_Chess.php:180 ../../addon/chess/Mod_Chess.php:377
-msgid "Invalid game."
-msgstr "Недействительная игра."
-
-#: ../../addon/chess/Mod_Chess.php:186 ../../addon/chess/Mod_Chess.php:417
-msgid "You are not a player in this game."
-msgstr "Вы не играете в эту игру."
-
-#: ../../addon/chess/Mod_Chess.php:242
-msgid "You must be a local channel to create a game."
-msgstr "Ваш канал должен быть локальным чтобы создать игру."
-
-#: ../../addon/chess/Mod_Chess.php:260
-msgid "You must select one opponent that is not yourself."
-msgstr "Вы должны выбрать противника который не является вами."
-
-#: ../../addon/chess/Mod_Chess.php:271
-msgid "Random color chosen."
-msgstr "Выбран случайный цвет."
-
-#: ../../addon/chess/Mod_Chess.php:279
-msgid "Error creating new game."
-msgstr "Ошибка создания новой игры."
-
-#: ../../addon/chess/Mod_Chess.php:306 ../../include/channel.php:1207
-msgid "Requested channel is not available."
-msgstr "Запрошенный канал не доступен."
-
-#: ../../addon/chess/Mod_Chess.php:311 ../../addon/chess/Mod_Chess.php:333
-msgid "Chess not installed."
-msgstr "Шахматы не установлены."
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:100
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:101
+#: ../../extend/addon/hzaddons/cart/myshop.php:141
+#: ../../extend/addon/hzaddons/cart/myshop.php:177
+#: ../../extend/addon/hzaddons/cart/myshop.php:211
+#: ../../extend/addon/hzaddons/cart/myshop.php:259
+#: ../../extend/addon/hzaddons/cart/myshop.php:294
+#: ../../extend/addon/hzaddons/cart/myshop.php:317
+msgid "Access Denied"
+msgstr "Доступ запрещён"
-#: ../../addon/chess/Mod_Chess.php:326
-msgid "You must select a local channel /chess/channelname"
-msgstr "Вы должны выбрать локальный канал /chess/channelname"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:108
+msgid "Enable Community Moderation"
+msgstr "Включить модерацию сообщества"
-#: ../../addon/chess/chess.php:642
-msgid "Enable notifications"
-msgstr "Включить оповещения"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:116
+msgid "Reputation automatically given to new members"
+msgstr "Репутация автоматически предоставляемая новым участникам"
-#: ../../addon/twitter/Mod_Twitter.php:65
-msgid "Twitter settings updated."
-msgstr "Настройки Twitter обновлены"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:117
+msgid "Reputation will never fall below this value"
+msgstr "Репутация никогда не упадёт ниже этого значения"
-#: ../../addon/twitter/Mod_Twitter.php:78
-msgid "Twitter Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Twitter\""
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:118
+msgid "Minimum reputation before posting is allowed"
+msgstr "Минимальная репутация для разрешения возможности размещать публикации"
-#: ../../addon/twitter/Mod_Twitter.php:79
-msgid "Relay public posts to Twitter"
-msgstr "Пересылает общедоступные публикации в Twitter"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:119
+msgid "Minimum reputation before commenting is allowed"
+msgstr "Минимальная репутация для разрешения комментирования"
-#: ../../addon/twitter/Mod_Twitter.php:103
-msgid ""
-"No consumer key pair for Twitter found. Please contact your site "
-"administrator."
-msgstr "Не найдено пары ключей для Twitter. Пожалуйста, свяжитесь с администратором сайта."
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:120
+msgid "Minimum reputation before a member is able to moderate other posts"
+msgstr "Минимальная репутация для возможности модерирования участником чужих публикаций"
-#: ../../addon/twitter/Mod_Twitter.php:125
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:121
msgid ""
-"At this Hubzilla instance the Twitter plugin was enabled but you have not "
-"yet connected your account to your Twitter account. To do so click the "
-"button below to get a PIN from Twitter which you have to copy into the input "
-"box below and submit the form. Only your <strong>public</strong> posts will "
-"be posted to Twitter."
-msgstr "В этой установке Hubzilla плагин Twitter был включён, однако пока он не подключён к вашему аккаунту в Twitter. Для этого нажмите на кнопку ниже для получения PIN-кода от Twitter который нужно скопировать в поле ввода и отправить форму. Только ваши <strong>общедоступные</strong> публикации будут опубликованы в Twitter."
+"Max ratio of moderator's reputation that can be added to/deducted from "
+"reputation of person being moderated"
+msgstr "Максимальное соотношение репутации модератора, которое может быть добавлено / вычтено из репутации модерируемого участника"
-#: ../../addon/twitter/Mod_Twitter.php:127
-msgid "Log in with Twitter"
-msgstr "Войти в Twitter"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:122
+msgid "Reputation \"cost\" to post"
+msgstr "\"Стоимость\" репутации для публикации"
-#: ../../addon/twitter/Mod_Twitter.php:130
-msgid "Copy the PIN from Twitter here"
-msgstr "Скопируйте PIN-код из Twitter здесь"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:123
+msgid "Reputation \"cost\" to comment"
+msgstr "\"Стоимость\" репутации для комментирования"
-#: ../../addon/twitter/Mod_Twitter.php:152
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:124
msgid ""
-"<strong>Note:</strong> Due your privacy settings (<em>Hide your profile "
-"details from unknown viewers?</em>) the link potentially included in public "
-"postings relayed to Twitter will lead the visitor to a blank page informing "
-"the visitor that the access to your profile has been restricted."
-msgstr "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в Twitter, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен."
-
-#: ../../addon/twitter/Mod_Twitter.php:157
-msgid "Twitter post length"
-msgstr "Длина публикации Twitter"
-
-#: ../../addon/twitter/Mod_Twitter.php:157
-msgid "Maximum tweet length"
-msgstr "Максимальная длина твита"
-
-#: ../../addon/twitter/Mod_Twitter.php:162
-msgid "Send public postings to Twitter by default"
-msgstr "Отправлять общедоступные публикации в Twitter по умолчанию"
+"Reputation automatically recovers at this rate per hour until it reaches "
+"minimum_to_post"
+msgstr "Репутация автоматически восстанавливается с этой скоростью в час пока не достигает значения minimum_to_post"
-#: ../../addon/twitter/Mod_Twitter.php:162
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:125
msgid ""
-"If enabled your public postings will be posted to the associated Twitter "
-"account by default"
-msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи Twitter по умолчанию"
-
-#: ../../addon/twitter/Mod_Twitter.php:181
-msgid "Twitter Crosspost Connector"
-msgstr "Пересылка публикаций Twitter"
-
-#: ../../addon/twitter/twitter.php:107
-msgid "Post to Twitter"
-msgstr "Опубликовать в Twitter"
-
-#: ../../addon/smileybutton/Mod_Smileybutton.php:35
-msgid "Smileybutton App"
-msgstr "Приложение \"Кнопка со смайликам\""
-
-#: ../../addon/smileybutton/Mod_Smileybutton.php:36
-msgid "Adds a smileybutton to the jot editor"
-msgstr "Добавлять кнопку со смайликами в редактор Jot"
-
-#: ../../addon/smileybutton/Mod_Smileybutton.php:44
-msgid "Hide the button and show the smilies directly."
-msgstr "Скрыть кнопку и сразу показывать смайлики."
+"When minimum_to_moderate > reputation > minimum_to_post reputation recovers "
+"at this rate per hour"
+msgstr "При minimum_to_moderate > репутация > minimum_to_post репутация восстанавливается с этой скоростью в час"
-#: ../../addon/smileybutton/Mod_Smileybutton.php:52
-msgid "Smileybutton Settings"
-msgstr "Настройки кнопки со смайликами"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:139
+msgid "Community Moderation Settings"
+msgstr "Настройки модерирования сообщества"
-#: ../../addon/cart/Settings/Cart.php:56
-msgid "Enable Test Catalog"
-msgstr "Включить тестовый каталог"
+#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:367
+msgid "Can moderate reputation on my channel."
+msgstr "Может модерировать репутацию на моём канале"
-#: ../../addon/cart/Settings/Cart.php:68
-msgid "Enable Manual Payments"
-msgstr "Включить ручные платежи"
+#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:24
+msgid "Flag Adult Photos"
+msgstr "Пометка фотографий для взрослых"
-#: ../../addon/cart/Settings/Cart.php:88
-msgid "Base Merchant Currency"
-msgstr "Основная торговая валюта"
+#: ../../extend/addon/hzaddons/adultphotoflag/adultphotoflag.php:25
+msgid ""
+"Provide photo edit option to hide inappropriate photos from default album "
+"view"
+msgstr "Предоставьте возможность редактирования фотографий, чтобы скрыть неприемлемые фотографии из альбома по умолчанию"
-#: ../../addon/cart/Settings/Cart.php:111 ../../addon/cart/cart.php:1263
-msgid "Cart Settings"
-msgstr "Настройки карточек"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:52
+msgid "First Name"
+msgstr "Имя"
-#: ../../addon/cart/myshop.php:30
-msgid "Access Denied."
-msgstr "Доступ запрещён."
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:53
+msgid "Last Name"
+msgstr "Фамилия"
-#: ../../addon/cart/myshop.php:111 ../../addon/cart/cart.php:1334
-msgid "Order Not Found"
-msgstr "Заказ не найден"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75
+msgid "Nickname"
+msgstr "Псевдоним"
-#: ../../addon/cart/myshop.php:186 ../../addon/cart/myshop.php:220
-#: ../../addon/cart/myshop.php:269 ../../addon/cart/myshop.php:327
-msgid "Invalid Item"
-msgstr "Недействительный элемент"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:55
+msgid "Full Name"
+msgstr "Полное имя"
-#: ../../addon/cart/cart.php:159
-msgid "DB Cleanup Failure"
-msgstr "Сбой очистки базы данных"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:61
+msgid "Profile Photo 16px"
+msgstr "Фотография профиля 16px"
-#: ../../addon/cart/cart.php:565
-msgid "[cart] Item Added"
-msgstr "[cart] Элемент добавлен"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:62
+msgid "Profile Photo 32px"
+msgstr "Фотография профиля 32px"
-#: ../../addon/cart/cart.php:953
-msgid "Order already checked out."
-msgstr "Заказ уже проверен."
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:63
+msgid "Profile Photo 48px"
+msgstr "Фотография профиля 48px"
-#: ../../addon/cart/cart.php:1256
-msgid "Drop database tables when uninstalling."
-msgstr "Сбросить таблицы базы данных при деинсталляции"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:64
+msgid "Profile Photo 64px"
+msgstr "Фотография профиля 64px"
-#: ../../addon/cart/cart.php:1275 ../../addon/cart/cart.php:1278
-msgid "Shop"
-msgstr "Магазин"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:65
+msgid "Profile Photo 80px"
+msgstr "Фотография профиля 80px"
-#: ../../addon/cart/cart.php:1395
-msgid "Cart utilities for orders and payments"
-msgstr "Утилиты карточек для заказов и платежей"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:66
+msgid "Profile Photo 128px"
+msgstr "Фотография профиля 128px"
-#: ../../addon/cart/cart.php:1433
-msgid "You must be logged into the Grid to shop."
-msgstr "Вы должны быть в сети для доступа к магазину"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:67
+msgid "Timezone"
+msgstr "Часовой пояс"
-#: ../../addon/cart/cart.php:1466
-#: ../../addon/cart/submodules/paypalbutton.php:392
-#: ../../addon/cart/manual_payments.php:68
-msgid "Order not found."
-msgstr "Заказ не найден."
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:70
+msgid "Birth Year"
+msgstr "Год рождения"
-#: ../../addon/cart/cart.php:1474
-msgid "Access denied."
-msgstr "Доступ запрещён."
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:71
+msgid "Birth Month"
+msgstr "Месяц рождения"
-#: ../../addon/cart/cart.php:1526 ../../addon/cart/cart.php:1669
-msgid "No Order Found"
-msgstr "Нет найденных заказов"
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:72
+msgid "Birth Day"
+msgstr "День рождения"
-#: ../../addon/cart/cart.php:1535
-msgid "An unknown error has occurred Please start again."
-msgstr "Произошла неизвестная ошибка. Пожалуйста, начните снова."
+#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:73
+msgid "Birthdate"
+msgstr "Дата рождения"
-#: ../../addon/cart/cart.php:1702
-msgid "Invalid Payment Type. Please start again."
-msgstr "Недействительный тип платежа. Пожалуйста, начните снова."
+#: ../../extend/addon/hzaddons/openid/openid.php:49
+msgid ""
+"We encountered a problem while logging in with the OpenID you provided. "
+"Please check the correct spelling of the ID."
+msgstr "Мы столкнулись с проблемой входа с предоставленным вами OpenID. Пожалуйста, проверьте корректность его написания."
-#: ../../addon/cart/cart.php:1709
-msgid "Order not found"
-msgstr "Заказ не найден"
+#: ../../extend/addon/hzaddons/openid/openid.php:49
+msgid "The error message was:"
+msgstr "Сообщение об ошибке было:"
-#: ../../addon/cart/submodules/paypalbutton.php:85
-msgid "Enable Paypal Button Module"
-msgstr "Включить модуль кнопки Paypal"
+#: ../../extend/addon/hzaddons/openid/Mod_Openid.php:30
+msgid "OpenID protocol error. No ID returned."
+msgstr "Ошибка протокола OpenID. Идентификатор не возвращён."
-#: ../../addon/cart/submodules/paypalbutton.php:93
-msgid "Use Production Key"
-msgstr "Использовать ключ Production"
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:50
+msgid "Startpage App"
+msgstr "Приложение \"Стартовая страница\""
-#: ../../addon/cart/submodules/paypalbutton.php:100
-msgid "Paypal Sandbox Client Key"
-msgstr "Ключ клиента Paypal Sandbox"
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:51
+msgid "Set a preferred page to load on login from home page"
+msgstr "Устанавливает предпочтительную страницу для загрузки при входе с домашней страницы"
-#: ../../addon/cart/submodules/paypalbutton.php:107
-msgid "Paypal Sandbox Secret Key"
-msgstr "Секретный ключ Paypal Sandbox"
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62
+msgid "Page to load after login"
+msgstr "Страница для загрузки после входа"
-#: ../../addon/cart/submodules/paypalbutton.php:113
-msgid "Paypal Production Client Key"
-msgstr "Ключ клиента Paypal Production"
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:62
+msgid ""
+"Examples: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy "
+"collection), &quot;channel&quot; or &quot;notifications/system&quot; (leave "
+"blank for default network page (grid)."
+msgstr "Примеры: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy collection), &quot;channel&quot; or &quot;notifications/system&quot; (оставьте пустым для для страницы сети по умолчанию)."
-#: ../../addon/cart/submodules/paypalbutton.php:120
-msgid "Paypal Production Secret Key"
-msgstr "Секретный ключ Paypal Production"
+#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:70
+msgid "Startpage"
+msgstr "Стартовая страница"
-#: ../../addon/cart/submodules/paypalbutton.php:252
-msgid "Paypal button payments are not enabled."
-msgstr "Кнопка Paypal для платежей не включена."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:94
+msgid "Hubzilla Directory Stats"
+msgstr "Каталог статистики Hubzilla"
-#: ../../addon/cart/submodules/paypalbutton.php:270
-msgid ""
-"Paypal button payments are not properly configured. Please choose another "
-"payment option."
-msgstr "Кнопка Paypal для платежей настроена неправильно. Пожалуйста, используйте другой вариант оплаты."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:95
+msgid "Total Hubs"
+msgstr "Всего хабов"
-#: ../../addon/cart/submodules/manualcat.php:61
-msgid "Enable Manual Cart Module"
-msgstr "Включить модуль ручного управления карточками"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:97
+msgid "Hubzilla Hubs"
+msgstr "Хабы Hubzilla"
-#: ../../addon/cart/submodules/manualcat.php:173
-#: ../../addon/cart/submodules/hzservices.php:160
-msgid "New Sku"
-msgstr "Новый код"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:99
+msgid "Friendica Hubs"
+msgstr "Хабы Friendica"
-#: ../../addon/cart/submodules/manualcat.php:209
-#: ../../addon/cart/submodules/hzservices.php:195
-msgid "Cannot save edits to locked item."
-msgstr "Невозможно сохранить изменения заблокированной позиции."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:101
+msgid "Diaspora Pods"
+msgstr "Стручки Diaspora"
-#: ../../addon/cart/submodules/manualcat.php:252
-#: ../../addon/cart/submodules/hzservices.php:644
-msgid "Changes Locked"
-msgstr "Изменения заблокированы"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:103
+msgid "Hubzilla Channels"
+msgstr "Каналы Hubzilla"
-#: ../../addon/cart/submodules/manualcat.php:256
-#: ../../addon/cart/submodules/hzservices.php:648
-msgid "Item available for purchase."
-msgstr "Позиция доступна для приобретения."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:105
+msgid "Friendica Channels"
+msgstr "Каналы Friendica"
-#: ../../addon/cart/submodules/manualcat.php:263
-#: ../../addon/cart/submodules/hzservices.php:655
-msgid "Price"
-msgstr "Цена"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:107
+msgid "Diaspora Channels"
+msgstr "Каналы Diaspora"
-#: ../../addon/cart/submodules/hzservices.php:62
-msgid "Enable Hubzilla Services Module"
-msgstr "Включить модуль сервиса Hubzilla"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:109
+msgid "Aged 35 and above"
+msgstr "Возраст 35 и выше"
-#: ../../addon/cart/submodules/hzservices.php:243
-#: ../../addon/cart/submodules/hzservices.php:330
-msgid "SKU not found."
-msgstr "Код не найден."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:111
+msgid "Aged 34 and under"
+msgstr "Возраст 34 и ниже"
-#: ../../addon/cart/submodules/hzservices.php:296
-#: ../../addon/cart/submodules/hzservices.php:300
-msgid "Invalid Activation Directive."
-msgstr "Недействительная директива активации."
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:113
+msgid "Average Age"
+msgstr "Средний возраст"
-#: ../../addon/cart/submodules/hzservices.php:371
-#: ../../addon/cart/submodules/hzservices.php:375
-msgid "Invalid Deactivation Directive."
-msgstr "Недействительная директива деактивации"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:115
+msgid "Known Chatrooms"
+msgstr "Известные чаты"
-#: ../../addon/cart/submodules/hzservices.php:561
-msgid "Add to this privacy group"
-msgstr "Добавить в эту группу безопасности"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:117
+msgid "Known Tags"
+msgstr "Известные теги"
-#: ../../addon/cart/submodules/hzservices.php:577
-msgid "Set user service class"
-msgstr "Установить класс обслуживания пользователя"
+#: ../../extend/addon/hzaddons/dirstats/dirstats.php:119
+msgid ""
+"Please note Diaspora and Friendica statistics are merely those **this "
+"directory** is aware of, and not all those known in the network. This also "
+"applies to chatrooms,"
+msgstr "Обратите внимание, что статистика Diaspora и Friendica это только те, о которых ** этот каталог ** знает, а не все известные в сети. Это также относится и к чатам."
-#: ../../addon/cart/submodules/hzservices.php:604
-msgid "You must be using a local account to purchase this service."
-msgstr "Вы должны использовать локальную учётноую запись для покупки этого сервиса."
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:56
+msgid "Enable Test Catalog"
+msgstr "Включить тестовый каталог"
-#: ../../addon/cart/submodules/hzservices.php:659
-msgid "Add buyer to privacy group"
-msgstr "Добавить покупателя в группу безопасности"
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:68
+msgid "Enable Manual Payments"
+msgstr "Включить ручные платежи"
-#: ../../addon/cart/submodules/hzservices.php:664
-msgid "Add buyer as connection"
-msgstr "Добавить покупателя как контакт"
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:88
+msgid "Base Merchant Currency"
+msgstr "Основная торговая валюта"
-#: ../../addon/cart/submodules/hzservices.php:672
-#: ../../addon/cart/submodules/hzservices.php:714
-msgid "Set Service Class"
-msgstr "Установить класс обслуживания"
+#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:111
+#: ../../extend/addon/hzaddons/cart/cart.php:1263
+msgid "Cart Settings"
+msgstr "Настройки карточек"
-#: ../../addon/cart/submodules/subscriptions.php:151
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:151
msgid "Enable Subscription Management Module"
msgstr "Включить модуль управления подписками"
-#: ../../addon/cart/submodules/subscriptions.php:223
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:223
msgid ""
"Cannot include subscription items with different terms in the same order."
msgstr "Нельзя включать элементы подписки с разными условиями в том же заказе."
-#: ../../addon/cart/submodules/subscriptions.php:372
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:372
msgid "Select Subscription to Edit"
msgstr "Выбрать подписку для редактирования"
-#: ../../addon/cart/submodules/subscriptions.php:380
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:380
msgid "Edit Subscriptions"
msgstr "Редактировать подписки"
-#: ../../addon/cart/submodules/subscriptions.php:414
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:414
msgid "Subscription SKU"
msgstr "Код подписки"
-#: ../../addon/cart/submodules/subscriptions.php:419
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:419
msgid "Catalog Description"
msgstr "Описание каталога"
-#: ../../addon/cart/submodules/subscriptions.php:423
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:423
msgid "Subscription available for purchase."
msgstr "Подписка доступна для покупки."
-#: ../../addon/cart/submodules/subscriptions.php:428
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:428
msgid "Maximum active subscriptions to this item per account."
msgstr "Максимальное количество подписок на аккаунт для этой позиции"
-#: ../../addon/cart/submodules/subscriptions.php:431
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:431
msgid "Subscription price."
msgstr "Цена подписки."
-#: ../../addon/cart/submodules/subscriptions.php:435
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:435
msgid "Quantity"
msgstr "Количество"
-#: ../../addon/cart/submodules/subscriptions.php:439
+#: ../../extend/addon/hzaddons/cart/submodules/subscriptions.php:439
msgid "Term"
msgstr "Условия"
-#: ../../addon/cart/manual_payments.php:7
-msgid "Error: order mismatch. Please try again."
-msgstr "Ошибка: несоответствие заказа. Пожалуйста, попробуйте ещё раз"
-
-#: ../../addon/cart/manual_payments.php:61
-msgid "Manual payments are not enabled."
-msgstr "Ручные платежи не подключены."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:62
+msgid "Enable Hubzilla Services Module"
+msgstr "Включить модуль сервиса Hubzilla"
-#: ../../addon/cart/manual_payments.php:77
-msgid "Finished"
-msgstr "Завершено"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:160
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:173
+msgid "New Sku"
+msgstr "Новый код"
-#: ../../addon/piwik/piwik.php:85
-msgid ""
-"This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> "
-"analytics tool."
-msgstr "Этот сайт отслеживается с помощью инструментов аналитики <a href='http://www.piwik.org'>Piwik</a>."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:195
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:209
+msgid "Cannot save edits to locked item."
+msgstr "Невозможно сохранить изменения заблокированной позиции."
-#: ../../addon/piwik/piwik.php:88
-#, php-format
-msgid ""
-"If you do not want that your visits are logged this way you <a href='%s'>can "
-"set a cookie to prevent Piwik from tracking further visits of the site</a> "
-"(opt-out)."
-msgstr "Если вы не хотите, чтобы ваши визиты регистрировались таким образом, вы <a href='%s'>можете отключить cookie с тем, чтобы Piwik не отслеживал дальнейшие посещения сайта</a>."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:243
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:330
+msgid "SKU not found."
+msgstr "Код не найден."
-#: ../../addon/piwik/piwik.php:96
-msgid "Piwik Base URL"
-msgstr "Базовый URL Piwik"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:296
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:300
+msgid "Invalid Activation Directive."
+msgstr "Недействительная директива активации."
-#: ../../addon/piwik/piwik.php:96
-msgid ""
-"Absolute path to your Piwik installation. (without protocol (http/s), with "
-"trailing slash)"
-msgstr "Абсолютный путь к вашей установке Piwik (без типа протокола, с начальным слэшем)"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:371
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:375
+msgid "Invalid Deactivation Directive."
+msgstr "Недействительная директива деактивации"
-#: ../../addon/piwik/piwik.php:97
-msgid "Site ID"
-msgstr "ID сайта"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:561
+msgid "Add to this privacy group"
+msgstr "Добавить в эту группу безопасности"
-#: ../../addon/piwik/piwik.php:98
-msgid "Show opt-out cookie link?"
-msgstr "Показывать ссылку на отказ от использования cookies?"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:577
+msgid "Set user service class"
+msgstr "Установить класс обслуживания пользователя"
-#: ../../addon/piwik/piwik.php:99
-msgid "Asynchronous tracking"
-msgstr "Асинхронное отслеживание"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:604
+msgid "You must be using a local account to purchase this service."
+msgstr "Вы должны использовать локальную учётноую запись для покупки этого сервиса."
-#: ../../addon/piwik/piwik.php:100
-msgid "Enable frontend JavaScript error tracking"
-msgstr "Включить отслеживание ошибок JavaScript на фронтенде."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:644
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:252
+msgid "Changes Locked"
+msgstr "Изменения заблокированы"
-#: ../../addon/piwik/piwik.php:100
-msgid "This feature requires Piwik >= 2.2.0"
-msgstr "Эта функция требует версию Piwik >= 2.2.0"
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:648
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:256
+msgid "Item available for purchase."
+msgstr "Позиция доступна для приобретения."
-#: ../../addon/tour/tour.php:76
-msgid "Edit your profile and change settings."
-msgstr "Отредактировать ваш профиль и изменить настройки."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:655
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:263
+msgid "Price"
+msgstr "Цена"
-#: ../../addon/tour/tour.php:77
-msgid "Click here to see activity from your connections."
-msgstr "Нажмите сюда для отображения активности ваши контактов."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:659
+msgid "Add buyer to privacy group"
+msgstr "Добавить покупателя в группу безопасности"
-#: ../../addon/tour/tour.php:78
-msgid "Click here to see your channel home."
-msgstr "Нажмите сюда чтобы увидеть главную страницу вашего канала."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:664
+msgid "Add buyer as connection"
+msgstr "Добавить покупателя как контакт"
-#: ../../addon/tour/tour.php:79
-msgid "You can access your private messages from here."
-msgstr "Вы можете получить доступ с личной переписке здесь."
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:672
+#: ../../extend/addon/hzaddons/cart/submodules/hzservices.php:714
+msgid "Set Service Class"
+msgstr "Установить класс обслуживания"
-#: ../../addon/tour/tour.php:80
-msgid "Create new events here."
-msgstr "Создать новое событие здесь."
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:85
+msgid "Enable Paypal Button Module"
+msgstr "Включить модуль кнопки Paypal"
-#: ../../addon/tour/tour.php:81
-msgid ""
-"You can accept new connections and change permissions for existing ones "
-"here. You can also e.g. create groups of contacts."
-msgstr "Вы можете подключать новые контакты и менять разрешения для существующих здесь. Также вы можете создавать их группы."
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:93
+msgid "Use Production Key"
+msgstr "Использовать ключ Production"
-#: ../../addon/tour/tour.php:82
-msgid "System notifications will arrive here"
-msgstr "Системные оповещения будут показываться здесь"
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:100
+msgid "Paypal Sandbox Client Key"
+msgstr "Ключ клиента Paypal Sandbox"
-#: ../../addon/tour/tour.php:83
-msgid "Search for content and users"
-msgstr "Поиск пользователей и содержимого"
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:107
+msgid "Paypal Sandbox Secret Key"
+msgstr "Секретный ключ Paypal Sandbox"
-#: ../../addon/tour/tour.php:84
-msgid "Browse for new contacts"
-msgstr "Поиск новых контактов"
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:113
+msgid "Paypal Production Client Key"
+msgstr "Ключ клиента Paypal Production"
-#: ../../addon/tour/tour.php:85
-msgid "Launch installed apps"
-msgstr "Запустить установленные приложения"
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:120
+msgid "Paypal Production Secret Key"
+msgstr "Секретный ключ Paypal Production"
-#: ../../addon/tour/tour.php:86
-msgid "Looking for help? Click here."
-msgstr "Нужна помощь? Нажмите сюда."
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:252
+msgid "Paypal button payments are not enabled."
+msgstr "Кнопка Paypal для платежей не включена."
-#: ../../addon/tour/tour.php:87
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:270
msgid ""
-"New events have occurred in your network. Click here to see what has "
-"happened!"
-msgstr "Новые события произошли в вашей сети. Нажмите здесь для того, чтобы знать что случилось!"
+"Paypal button payments are not properly configured. Please choose another "
+"payment option."
+msgstr "Кнопка Paypal для платежей настроена неправильно. Пожалуйста, используйте другой вариант оплаты."
-#: ../../addon/tour/tour.php:88
-msgid "You have received a new private message. Click here to see from who!"
-msgstr "Вы получили новое личное сообщение. Нажмите чтобы увидеть от кого!"
+#: ../../extend/addon/hzaddons/cart/submodules/paypalbutton.php:392
+#: ../../extend/addon/hzaddons/cart/manual_payments.php:68
+#: ../../extend/addon/hzaddons/cart/cart.php:1466
+msgid "Order not found."
+msgstr "Заказ не найден."
-#: ../../addon/tour/tour.php:89
-msgid "There are events this week. Click here too see which!"
-msgstr "На этой неделе есть события. Нажмите здесь чтобы увидеть какие!"
+#: ../../extend/addon/hzaddons/cart/submodules/manualcat.php:61
+msgid "Enable Manual Cart Module"
+msgstr "Включить модуль ручного управления карточками"
-#: ../../addon/tour/tour.php:90
-msgid "You have received a new introduction. Click here to see who!"
-msgstr "Вы были представлены. Нажмите чтобы увидеть кому!"
+#: ../../extend/addon/hzaddons/cart/myshop.php:30
+msgid "Access Denied."
+msgstr "Доступ запрещён."
-#: ../../addon/tour/tour.php:91
-msgid ""
-"There is a new system notification. Click here to see what has happened!"
-msgstr "Это новое системное уведомление. Нажмите чтобы посмотреть что случилось!"
+#: ../../extend/addon/hzaddons/cart/myshop.php:111
+#: ../../extend/addon/hzaddons/cart/cart.php:1334
+msgid "Order Not Found"
+msgstr "Заказ не найден"
-#: ../../addon/tour/tour.php:94
-msgid "Click here to share text, images, videos and sound."
-msgstr "Нажмите сюда чтобы поделиться текстом, изображениями, видео или треком."
+#: ../../extend/addon/hzaddons/cart/myshop.php:186
+#: ../../extend/addon/hzaddons/cart/myshop.php:220
+#: ../../extend/addon/hzaddons/cart/myshop.php:269
+#: ../../extend/addon/hzaddons/cart/myshop.php:327
+msgid "Invalid Item"
+msgstr "Недействительный элемент"
-#: ../../addon/tour/tour.php:95
-msgid "You can write an optional title for your update (good for long posts)."
-msgstr "Вы можете написать необязательный заголовок для вашей публикации (желательно для больших публикаций)."
+#: ../../extend/addon/hzaddons/cart/manual_payments.php:7
+msgid "Error: order mismatch. Please try again."
+msgstr "Ошибка: несоответствие заказа. Пожалуйста, попробуйте ещё раз"
-#: ../../addon/tour/tour.php:96
-msgid "Entering some categories here makes it easier to find your post later."
-msgstr "Введите категории здесь чтобы было проще найти вашу публикацию позднее."
+#: ../../extend/addon/hzaddons/cart/manual_payments.php:61
+msgid "Manual payments are not enabled."
+msgstr "Ручные платежи не подключены."
-#: ../../addon/tour/tour.php:97
-msgid "Share photos, links, location, etc."
-msgstr "Поделиться фотографией, ссылками, местоположение и т.п."
+#: ../../extend/addon/hzaddons/cart/manual_payments.php:77
+msgid "Finished"
+msgstr "Завершено"
-#: ../../addon/tour/tour.php:98
-msgid ""
-"Only want to share content for a while? Make it expire at a certain date."
-msgstr "Хотите только поделиться временным содержимым? Установите срок его действия."
+#: ../../extend/addon/hzaddons/cart/cart.php:159
+msgid "DB Cleanup Failure"
+msgstr "Сбой очистки базы данных"
-#: ../../addon/tour/tour.php:99
-msgid "You can password protect content."
-msgstr "Вы можете защитить содержимое паролем."
+#: ../../extend/addon/hzaddons/cart/cart.php:565
+msgid "[cart] Item Added"
+msgstr "[cart] Элемент добавлен"
-#: ../../addon/tour/tour.php:100
-msgid "Choose who you share with."
-msgstr "Выбрать с кем поделиться."
+#: ../../extend/addon/hzaddons/cart/cart.php:953
+msgid "Order already checked out."
+msgstr "Заказ уже проверен."
-#: ../../addon/tour/tour.php:102
-msgid "Click here when you are done."
-msgstr "Нажмите здесь когда закончите."
+#: ../../extend/addon/hzaddons/cart/cart.php:1256
+msgid "Drop database tables when uninstalling."
+msgstr "Сбросить таблицы базы данных при деинсталляции"
-#: ../../addon/tour/tour.php:105
-msgid "Adjust from which channels posts should be displayed."
-msgstr "Настройте из каких каналов должны отображаться публикации."
+#: ../../extend/addon/hzaddons/cart/cart.php:1275
+#: ../../extend/addon/hzaddons/cart/cart.php:1278
+msgid "Shop"
+msgstr "Магазин"
-#: ../../addon/tour/tour.php:106
-msgid "Only show posts from channels in the specified privacy group."
-msgstr "Показывать только публикации из определённой группы безопасности."
+#: ../../extend/addon/hzaddons/cart/cart.php:1395
+msgid "Cart utilities for orders and payments"
+msgstr "Утилиты карточек для заказов и платежей"
-#: ../../addon/tour/tour.php:110
-msgid ""
-"Easily find posts containing tags (keywords preceded by the \"#\" symbol)."
-msgstr "Лёгкий поиск сообщения, содержащего теги (ключевые слова, которым предшествует символ #)."
+#: ../../extend/addon/hzaddons/cart/cart.php:1433
+msgid "You must be logged into the Grid to shop."
+msgstr "Вы должны быть в сети для доступа к магазину"
-#: ../../addon/tour/tour.php:111
-msgid "Easily find posts in given category."
-msgstr "Лёгкий поиск публикаций в данной категории."
+#: ../../extend/addon/hzaddons/cart/cart.php:1474
+msgid "Access denied."
+msgstr "Доступ запрещён."
-#: ../../addon/tour/tour.php:112
-msgid "Easily find posts by date."
-msgstr "Лёгкий поиск публикаций по дате."
+#: ../../extend/addon/hzaddons/cart/cart.php:1526
+#: ../../extend/addon/hzaddons/cart/cart.php:1669
+msgid "No Order Found"
+msgstr "Нет найденных заказов"
-#: ../../addon/tour/tour.php:113
-msgid ""
-"Suggested users who have volounteered to be shown as suggestions, and who we "
-"think you might find interesting."
-msgstr "Рекомендуемые пользователи, которые были представлены в качестве предложений, и которые, по нашему мнению, могут оказаться интересными."
+#: ../../extend/addon/hzaddons/cart/cart.php:1535
+msgid "An unknown error has occurred Please start again."
+msgstr "Произошла неизвестная ошибка. Пожалуйста, начните снова."
-#: ../../addon/tour/tour.php:114
-msgid "Here you see channels you have connected to."
-msgstr "Здесь вы видите каналы, к которым вы подключились."
+#: ../../extend/addon/hzaddons/cart/cart.php:1702
+msgid "Invalid Payment Type. Please start again."
+msgstr "Недействительный тип платежа. Пожалуйста, начните снова."
-#: ../../addon/tour/tour.php:115
-msgid "Save your search so you can repeat it at a later date."
-msgstr "Сохраните ваш поиск с тем, чтобы повторить его позже."
+#: ../../extend/addon/hzaddons/cart/cart.php:1709
+msgid "Order not found"
+msgstr "Заказ не найден"
-#: ../../addon/tour/tour.php:118
-msgid ""
-"If you see this icon you can be sure that the sender is who it say it is. It "
-"is normal that it is not always possible to verify the sender, so the icon "
-"will be missing sometimes. There is usually no need to worry about that."
-msgstr "Если вы видите этот значок, вы можете быть уверены, что отправитель - это тот, кто это говорит. Это нормально, что не всегда можно проверить отправителя, поэтому значок иногда будет отсутствовать. Обычно об этом не нужно беспокоиться."
+#: ../../extend/addon/hzaddons/nofed/nofed.php:47
+msgid "Federate"
+msgstr "Федерировать"
-#: ../../addon/tour/tour.php:119
-msgid ""
-"Danger! It seems someone tried to forge a message! This message is not "
-"necessarily from who it says it is from!"
-msgstr "Опасность! Кажется, кто-то пытался подделать сообщение! Это сообщение не обязательно от того, от кого оно значится!"
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:21
+msgid "nofed Settings saved."
+msgstr "Настройки nofed сохранены."
-#: ../../addon/tour/tour.php:126
-msgid ""
-"Welcome to Hubzilla! Would you like to see a tour of the UI?</p> <p>You can "
-"pause it at any time and continue where you left off by reloading the page, "
-"or navigting to another page.</p><p>You can also advance by pressing the "
-"return key"
-msgstr "Добро пожаловать в Hubzilla! Желаете получить обзор пользовательского интерфейса?</p> <p>Вы можете его приостановаить и в любое время перезагрузив страницу или перейдя на другую.</p><p>Также вы можете нажать клавишу \"Назад\""
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:33
+msgid "No Federation App"
+msgstr "Приложение No Federation"
-#: ../../addon/sendzid/Mod_Sendzid.php:14
-msgid "Send your identity to all websites"
-msgstr "Отправить ваши данные на все веб-сайты"
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:34
+msgid ""
+"Prevent posting from being federated to anybody. It will exist only on your "
+"channel page."
+msgstr "Запрещает федеративные функций для публикаций. Они будут существовать только на странице вашего канала."
-#: ../../addon/sendzid/Mod_Sendzid.php:20
-msgid "Sendzid App"
-msgstr "Приложение \"Отправить ZID\""
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:42
+msgid "Federate posts by default"
+msgstr "Разрешить федерацию публикаций по умолчанию"
-#: ../../addon/sendzid/Mod_Sendzid.php:32
-msgid "Send ZID"
-msgstr "Отправить ZID"
+#: ../../extend/addon/hzaddons/nofed/Mod_Nofed.php:50
+msgid "No Federation"
+msgstr "Отключить Federation"
-#: ../../addon/tictac/tictac.php:21
-msgid "Three Dimensional Tic-Tac-Toe"
-msgstr "Tic-Tac-Toe в трёх измерениях"
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:43
+msgid "Your channel has been upgraded to the latest $Projectname version."
+msgstr "Ваш канал был обновлён на последнюю версию $Projectname."
-#: ../../addon/tictac/tictac.php:54
-msgid "3D Tic-Tac-Toe"
-msgstr ""
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:44
+msgid ""
+"To improve usability, we have converted some features into installable stand-"
+"alone apps."
+msgstr "Чтобы улучшить удобство использования, некоторые функции теперь доступны в виде устанавливаемых автономных приложений."
-#: ../../addon/tictac/tictac.php:59
-msgid "New game"
-msgstr "Новая игра"
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:45
+msgid "Please visit the $Projectname"
+msgstr "Пожалуйста, посетите $Projectname"
-#: ../../addon/tictac/tictac.php:60
-msgid "New game with handicap"
-msgstr "Новая игра с форой"
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:46
+msgid "app store"
+msgstr "раздел \"Приложения\""
-#: ../../addon/tictac/tictac.php:61
-msgid ""
-"Three dimensional tic-tac-toe is just like the traditional game except that "
-"it is played on multiple levels simultaneously. "
-msgstr "Трехмерный Tic-Tac-Toe похож на традиционную игру, за исключением того, что игра идёт на нескольких уровнях одновременно."
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:47
+msgid "and install possibly missing apps."
+msgstr "и установите необходимые вам."
-#: ../../addon/tictac/tictac.php:62
-msgid ""
-"In this case there are three levels. You win by getting three in a row on "
-"any level, as well as up, down, and diagonally across the different levels."
-msgstr "Имеется три уровня. Вы выигрываете, получая три подряд на любом уровне, а также вверх, вниз и по диагонали на разных уровнях."
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:52
+msgid "Upgrade Info"
+msgstr "Сведения об обновлении"
-#: ../../addon/tictac/tictac.php:64
-msgid ""
-"The handicap game disables the center position on the middle level because "
-"the player claiming this square often has an unfair advantage."
-msgstr "Игра с форой отключает центральную позицию на среднем уровне, потому что игрок, претендующий на этот квадрат, часто имеет несправедливое преимущество."
+#: ../../extend/addon/hzaddons/upgrade_info/upgrade_info.php:56
+msgid "Do not show this again"
+msgstr "Больше не показывать"
-#: ../../addon/tictac/tictac.php:183
-msgid "You go first..."
-msgstr "Вы начинаете..."
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:123
+msgid "generic profile image"
+msgstr "Стандартное изображение профиля"
-#: ../../addon/tictac/tictac.php:188
-msgid "I'm going first this time..."
-msgstr "На этот раз начинаю я..."
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:124
+msgid "random geometric pattern"
+msgstr "Случайный геометрический рисунок"
-#: ../../addon/tictac/tictac.php:194
-msgid "You won!"
-msgstr "Вы выиграли!"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:125
+msgid "monster face"
+msgstr "Лицо чудовища"
-#: ../../addon/tictac/tictac.php:200 ../../addon/tictac/tictac.php:225
-msgid "\"Cat\" game!"
-msgstr "Ничья!"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:126
+msgid "computer generated face"
+msgstr "Сгенерированное компьютером лицо"
-#: ../../addon/tictac/tictac.php:223
-msgid "I won!"
-msgstr "Я выиграл!"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:127
+msgid "retro arcade style face"
+msgstr "Лицо в стиле старой аркадной игры"
-#: ../../addon/pageheader/Mod_Pageheader.php:22
-msgid "pageheader Settings saved."
-msgstr "Настройки шапки страницы сохранены."
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:128
+msgid "Hub default profile photo"
+msgstr "Фотография профиля по умолчанию"
-#: ../../addon/pageheader/Mod_Pageheader.php:34
-msgid "Page Header App"
-msgstr "Приложение \"Заголовок страницы\""
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143
+msgid "Information"
+msgstr "Информация"
-#: ../../addon/pageheader/Mod_Pageheader.php:35
-msgid "Inserts a page header"
-msgstr "Вставляет заголовок страницы"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:143
+msgid ""
+"Libravatar addon is installed, too. Please disable Libravatar addon or this "
+"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
+"nothing was found at Libravatar."
+msgstr "Плагин Libravatar также установлен. Пожалуйста, отключите плагин Libravatar или этот плагин Gravatar. Если Плагин Libravatar ничего не найдёт, он вернётся в Gravatar."
-#: ../../addon/pageheader/Mod_Pageheader.php:43
-msgid "Message to display on every page on this server"
-msgstr "Отображаемое сообщение на каждой странице на этом сервере."
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:150
+#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:46
+#: ../../extend/addon/hzaddons/xmpp/xmpp.php:43
+msgid "Save Settings"
+msgstr "Сохранить настройки"
-#: ../../addon/pageheader/Mod_Pageheader.php:51
-msgid "Page Header"
-msgstr "Заголовок страницы"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151
+msgid "Default avatar image"
+msgstr "Изображение аватара по умолчанию"
-#: ../../addon/authchoose/Mod_Authchoose.php:22
-msgid ""
-"Allow magic authentication only to websites of your immediate connections"
-msgstr "Разрешить волшебную аутентификацию только на сайтах ваших непосредственных соединений"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:151
+msgid "Select default avatar image if none was found at Gravatar. See README"
+msgstr "Выберите изображения аватар по умолчанию если ничего не было найдено в Gravatar (см. README)."
-#: ../../addon/authchoose/Mod_Authchoose.php:28
-#: ../../addon/authchoose/Mod_Authchoose.php:33
-msgid "Authchoose App"
-msgstr "Приложение Authchoose"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152
+msgid "Rating of images"
+msgstr "Оценки изображений"
-#: ../../addon/authchoose/Mod_Authchoose.php:39
-msgid "Authchoose"
-msgstr ""
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:152
+msgid "Select the appropriate avatar rating for your site. See README"
+msgstr "Выберите подходящую оценку аватара для вашего сайта (см. README)."
-#: ../../addon/moremoods/moremoods.php:19
-msgid "lonely"
-msgstr "одинокий"
+#: ../../extend/addon/hzaddons/gravatar/gravatar.php:165
+msgid "Gravatar settings updated."
+msgstr "Настройки Gravatar обновлены."
-#: ../../addon/moremoods/moremoods.php:20
-msgid "drunk"
-msgstr "пьяный"
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:15
+msgid "WYSIWYG status editor"
+msgstr "WYSIWYG редактор статуса "
-#: ../../addon/moremoods/moremoods.php:21
-msgid "horny"
-msgstr "возбуждённый"
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:21
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:26
+msgid "WYSIWYG Status App"
+msgstr "Приложение \"WYSIWYG статус\""
-#: ../../addon/moremoods/moremoods.php:22
-msgid "stoned"
-msgstr "под кайфом"
+#: ../../extend/addon/hzaddons/hsse/Mod_Hsse.php:34
+msgid "WYSIWYG Status"
+msgstr "WYSIWYG статус"
-#: ../../addon/moremoods/moremoods.php:23
-msgid "fucked up"
-msgstr "облажался"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:27
+msgid "No server specified"
+msgstr "Сервер не указан"
-#: ../../addon/moremoods/moremoods.php:24
-msgid "clusterfucked"
-msgstr "в полной заднице"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:73
+msgid "Posts imported"
+msgstr "Публикации импортированы"
-#: ../../addon/moremoods/moremoods.php:25
-msgid "crazy"
-msgstr "сумасшедший"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:113
+msgid "Files imported"
+msgstr "Файлы импортированы"
-#: ../../addon/moremoods/moremoods.php:26
-msgid "hurt"
-msgstr "обиженный"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:122
+msgid ""
+"This addon app copies existing content and file storage to a cloned/copied "
+"channel. Once the app is installed, visit the newly installed app. This will "
+"allow you to set the location of your original channel and an optional date "
+"range of files/conversations to copy."
+msgstr "Это дополнительное приложение копирует существующее содержимое и хранилище файлов в клонированный / скопированный канал. После того, как приложение установлено, посетите его страницу. Это позволит вам задать местоположение вашего исходного канала и диапазон дат файлов / бесед для копирования."
-#: ../../addon/moremoods/moremoods.php:27
-msgid "sleepy"
-msgstr "сонный"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:136
+msgid ""
+"This will import all your conversations and cloud files from a cloned "
+"channel on another server. This may take a while if you have lots of posts "
+"and or files."
+msgstr "Импортировать все ваши разговоры и хранилище файлов из клонируемого канала на другом сервере. Это может занять некоторое время, если у вас много публикаций и / или файлов."
-#: ../../addon/moremoods/moremoods.php:28
-msgid "grumpy"
-msgstr "сердитый"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137
+msgid "Include posts"
+msgstr "Включая публикации"
-#: ../../addon/moremoods/moremoods.php:29
-msgid "high"
-msgstr "кайфует"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:137
+msgid "Conversations, Articles, Cards, and other posted content"
+msgstr "Беседы, Статьи, Карточки и другое опубликованное содержимое"
-#: ../../addon/moremoods/moremoods.php:30
-msgid "semi-conscious"
-msgstr "в полубезсознании"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138
+msgid "Include files"
+msgstr "Включая файлы"
-#: ../../addon/moremoods/moremoods.php:31
-msgid "in love"
-msgstr "влюблённый"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:138
+msgid "Files, Photos and other cloud storage"
+msgstr "Файлы, Фотографии и прочее из хранилища"
-#: ../../addon/moremoods/moremoods.php:32
-msgid "in lust"
-msgstr "похотливый"
+#: ../../extend/addon/hzaddons/content_import/Mod_content_import.php:139
+msgid "Original Server base URL"
+msgstr "Базовый URL сервера-источника"
-#: ../../addon/moremoods/moremoods.php:33
-msgid "naked"
-msgstr "обнажённый"
+#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:20
+#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:23
+msgid "Random Planet App"
+msgstr "Приложение \"Случайная планета\""
-#: ../../addon/moremoods/moremoods.php:34
-msgid "stinky"
-msgstr "вонючий"
+#: ../../extend/addon/hzaddons/planets/Mod_Planets.php:25
+msgid ""
+"Set a random planet from the Star Wars Empire as your location when posting"
+msgstr "Установить случайную планету из Империи Звездных Войн в качестве вашего местоположения при публикации"
-#: ../../addon/moremoods/moremoods.php:35
-msgid "sweaty"
-msgstr "потный"
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:15
+msgid "Add some colour to tag clouds"
+msgstr "Добавить немного цвета для облака тегов"
-#: ../../addon/moremoods/moremoods.php:36
-msgid "bleeding out"
-msgstr "истекающий кровью"
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:21
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:26
+msgid "Rainbow Tag App"
+msgstr "Приложение \"Радуга тегов\""
-#: ../../addon/moremoods/moremoods.php:37
-msgid "victorious"
-msgstr "победивший"
+#: ../../extend/addon/hzaddons/rainbowtag/Mod_Rainbowtag.php:34
+msgid "Rainbow Tag"
+msgstr "Радуга тегов"
-#: ../../addon/moremoods/moremoods.php:38
-msgid "defeated"
-msgstr "проигравший"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:180
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:377
+msgid "Invalid game."
+msgstr "Недействительная игра."
-#: ../../addon/moremoods/moremoods.php:39
-msgid "envious"
-msgstr "завидует"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:186
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:417
+msgid "You are not a player in this game."
+msgstr "Вы не играете в эту игру."
-#: ../../addon/moremoods/moremoods.php:40
-msgid "jealous"
-msgstr "ревнует"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:242
+msgid "You must be a local channel to create a game."
+msgstr "Ваш канал должен быть локальным чтобы создать игру."
-#: ../../addon/xmpp/Mod_Xmpp.php:23
-msgid "XMPP settings updated."
-msgstr "Настройки XMPP обновлены."
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:260
+msgid "You must select one opponent that is not yourself."
+msgstr "Вы должны выбрать противника который не является вами."
-#: ../../addon/xmpp/Mod_Xmpp.php:35
-msgid "XMPP App"
-msgstr "Приложение XMPP"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:271
+msgid "Random color chosen."
+msgstr "Выбран случайный цвет."
-#: ../../addon/xmpp/Mod_Xmpp.php:36
-msgid "Embedded XMPP (Jabber) client"
-msgstr "Встренный клиент XMPP (Jabber)"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:279
+msgid "Error creating new game."
+msgstr "Ошибка создания новой игры."
-#: ../../addon/xmpp/Mod_Xmpp.php:52
-msgid "Individual credentials"
-msgstr "Индивидуальные разрешения"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:311
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:333
+msgid "Chess not installed."
+msgstr "Шахматы не установлены."
-#: ../../addon/xmpp/Mod_Xmpp.php:58
-msgid "Jabber BOSH server"
-msgstr "Сервер Jabber BOSH"
+#: ../../extend/addon/hzaddons/chess/Mod_Chess.php:326
+msgid "You must select a local channel /chess/channelname"
+msgstr "Вы должны выбрать локальный канал /chess/channelname"
-#: ../../addon/xmpp/Mod_Xmpp.php:67
-msgid "XMPP Settings"
-msgstr "Настройки XMPP"
+#: ../../extend/addon/hzaddons/chess/chess.php:645
+msgid "Enable notifications"
+msgstr "Включить оповещения"
-#: ../../addon/xmpp/xmpp.php:44
-msgid "Jabber BOSH host"
-msgstr "Узел Jabber BOSH"
+#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:451
+msgid "Follow"
+msgstr "Отслеживать"
-#: ../../addon/xmpp/xmpp.php:45
-msgid "Use central userbase"
-msgstr "Использовать центральную базу данных"
+#: ../../extend/addon/hzaddons/gnusoc/gnusoc.php:454
+#, php-format
+msgid "%1$s is now following %2$s"
+msgstr "%1$s сейчас отслеживает %2$s"
-#: ../../addon/xmpp/xmpp.php:45
+#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:16
msgid ""
-"If enabled, members will automatically login to an ejabberd server that has "
-"to be installed on this machine with synchronized credentials via the "
-"\"auth_ejabberd.php\" script."
-msgstr "Если включено, участники автоматически войдут на сервер ejabberd, который должен быть установлен на этом компьютере с синхронизированными учетными данными через скрипт \"auth_ejabberd.php\"."
+"The GNU-Social protocol does not support location independence. Connections "
+"you make within that network may be unreachable from alternate channel "
+"locations."
+msgstr "Протокол GNU-Social не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
-#: ../../addon/wholikesme/wholikesme.php:29
-msgid "Who likes me?"
-msgstr "Кому я нравлюсь?"
+#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:22
+msgid "GNU-Social Protocol App"
+msgstr "Приложение \"Протокол GNU-Social\""
-#: ../../addon/pumpio/Mod_Pumpio.php:40
-msgid "Pump.io Settings saved."
-msgstr "Настройки Pump.io сохранены."
+#: ../../extend/addon/hzaddons/gnusoc/Mod_Gnusoc.php:34
+msgid "GNU-Social Protocol"
+msgstr "Протокол GNU-Social"
-#: ../../addon/pumpio/Mod_Pumpio.php:53
-msgid "Pump.io Crosspost Connector App"
-msgstr "Приложение \"Пересылка публикаций Pump.io\""
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:23
+msgid "TOTP Two-Step Verification"
+msgstr "Двухэтапная верификация TOTP"
-#: ../../addon/pumpio/Mod_Pumpio.php:54
-msgid "Relay public posts to pump.io"
-msgstr "Пересылает общедоступные публикации в Pump.io"
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:24
+msgid "Enter the 2-step verification generated by your authenticator app:"
+msgstr "Введите код проверки, созданный вашим приложением для аутентификации"
-#: ../../addon/pumpio/Mod_Pumpio.php:73
-msgid "Pump.io servername"
-msgstr "Имя сервера Pump.io"
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:25
+msgid "Success!"
+msgstr "Успех!"
-#: ../../addon/pumpio/Mod_Pumpio.php:73
-msgid "Without \"http://\" or \"https://\""
-msgstr "Без \"http://\" или \"https://\""
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:26
+msgid "Invalid code, please try again."
+msgstr "Неверный код. Пожалуйста, попробуйте ещё раз."
-#: ../../addon/pumpio/Mod_Pumpio.php:77
-msgid "Pump.io username"
-msgstr "Имя пользователя Pump.io"
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:27
+msgid "Too many invalid codes..."
+msgstr "Слишком много неверных кодов..."
-#: ../../addon/pumpio/Mod_Pumpio.php:77
-msgid "Without the servername"
-msgstr "без имени сервера"
+#: ../../extend/addon/hzaddons/totp/Mod_Totp.php:28
+msgid "Verify"
+msgstr "Проверить"
-#: ../../addon/pumpio/Mod_Pumpio.php:88
-msgid "You are not authenticated to pumpio"
-msgstr "Вы не аутентифицированы на Pump.io"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:90
+msgid ""
+"You haven't set a TOTP secret yet.\n"
+"Please click the button below to generate one and register this site\n"
+"with your preferred authenticator app."
+msgstr "Вы еще не установили секретный код TOTP. Пожалуйста, нажмите на кнопку ниже, чтобы сгенерировать его и зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации."
-#: ../../addon/pumpio/Mod_Pumpio.php:90
-msgid "(Re-)Authenticate your pump.io connection"
-msgstr "Аутентифицировать (повторно) ваше соединение с Pump.io"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:93
+msgid "Your TOTP secret is"
+msgstr "Ваш секретный код TOTP"
-#: ../../addon/pumpio/Mod_Pumpio.php:94
-msgid "Post to pump.io by default"
-msgstr "Публиковать в Pump.io по умолчанию"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:94
+msgid ""
+"Be sure to save it somewhere in case you lose or replace your mobile "
+"device.\n"
+"Use your mobile device to scan the QR code below to register this site\n"
+"with your preferred authenticator app."
+msgstr "Обязательно сохраните его где-нибудь на случай потери или замены мобильного устройства. С помощью мобильного устройства отсканируйте приведенный ниже QR-код, чтобы зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации."
-#: ../../addon/pumpio/Mod_Pumpio.php:98
-msgid "Should posts be public"
-msgstr "Публикации должны быть общедоступными"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:99
+msgid "Test"
+msgstr "Тест"
-#: ../../addon/pumpio/Mod_Pumpio.php:102
-msgid "Mirror all public posts"
-msgstr "Отображать все общедоступные публикации"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:100
+msgid "Generate New Secret"
+msgstr "Сгенерировать новый код"
-#: ../../addon/pumpio/Mod_Pumpio.php:112
-msgid "Pump.io Crosspost Connector"
-msgstr "Пересылка публикаций Pump.io"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:101
+msgid "Go"
+msgstr "Вперёд"
-#: ../../addon/pumpio/pumpio.php:152
-msgid "You are now authenticated to pumpio."
-msgstr "Вы аутентифицированы в Pump.io"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:102
+msgid "Enter your password"
+msgstr "Введите ваш пароль"
-#: ../../addon/pumpio/pumpio.php:153
-msgid "return to the featured settings page"
-msgstr "Вернутся к странице настроек"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:103
+msgid "enter TOTP code from your device"
+msgstr "введите код TOTP из вашего устройства"
-#: ../../addon/pumpio/pumpio.php:168
-msgid "Post to Pump.io"
-msgstr "Опубликовать в Pump.io"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:104
+msgid "Pass!"
+msgstr "Принято!"
-#: ../../addon/ldapauth/ldapauth.php:70
-msgid "An account has been created for you."
-msgstr "Учётная запись, которая была для вас создана."
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:105
+msgid "Fail"
+msgstr "Отказано"
-#: ../../addon/ldapauth/ldapauth.php:77
-msgid "Authentication successful but rejected: account creation is disabled."
-msgstr "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено."
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:106
+msgid "Incorrect password, try again."
+msgstr "Неверный пароль, попробуйте снова."
-#: ../../addon/opensearch/opensearch.php:26
-#, php-format
-msgctxt "opensearch"
-msgid "Search %1$s (%2$s)"
-msgstr "Искать %1$s (%2$s)"
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:107
+msgid "Record your new TOTP secret and rescan the QR code above."
+msgstr "Запишите ваш секретный код TOTP и повторно отсканируйте приведенный ниже QR-код."
-#: ../../addon/opensearch/opensearch.php:28
-msgctxt "opensearch"
-msgid "$Projectname"
-msgstr ""
+#: ../../extend/addon/hzaddons/totp/Settings/Totp.php:115
+msgid "TOTP Settings"
+msgstr "Настройки TOTP"
-#: ../../addon/opensearch/opensearch.php:43
-msgid "Search $Projectname"
-msgstr "Поиск $Projectname"
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:22
+msgid "pageheader Settings saved."
+msgstr "Настройки шапки страницы сохранены."
-#: ../../addon/redfiles/redfiles.php:119
-msgid "Redmatrix File Storage Import"
-msgstr "Импорт файлового хранилища Redmatrix"
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:34
+msgid "Page Header App"
+msgstr "Приложение \"Заголовок страницы\""
-#: ../../addon/redfiles/redfiles.php:120
-msgid "This will import all your Redmatrix cloud files to this channel."
-msgstr "Это позволит импортировать все ваши файлы в Redmatrix в этот канал."
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:35
+msgid "Inserts a page header"
+msgstr "Вставляет заголовок страницы"
-#: ../../addon/redfiles/redfilehelper.php:64
-msgid "file"
-msgstr "файл"
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:43
+msgid "Message to display on every page on this server"
+msgstr "Отображаемое сообщение на каждой странице на этом сервере."
+
+#: ../../extend/addon/hzaddons/pageheader/Mod_Pageheader.php:51
+msgid "Page Header"
+msgstr "Заголовок страницы"
+
+#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:47
+msgid "text to include in all outgoing posts from this site"
+msgstr "текст, который будет добавлен во все исходящие публикации с этого сайта"
-#: ../../addon/hubwall/hubwall.php:19
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:19
msgid "Send email to all members"
msgstr "Отправить email всем участникам"
-#: ../../addon/hubwall/hubwall.php:73
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:73
#, php-format
msgid "%1$d of %2$d messages sent."
msgstr "%1$d из %2$d сообщений отправлено."
-#: ../../addon/hubwall/hubwall.php:81
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:81
msgid "Send email to all hub members."
msgstr "Отправить email всем участникам узла."
-#: ../../addon/hubwall/hubwall.php:93
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:93
msgid "Sender Email address"
msgstr "Адрес электронной почты отправителя"
-#: ../../addon/hubwall/hubwall.php:94
+#: ../../extend/addon/hzaddons/hubwall/hubwall.php:94
msgid "Test mode (only send to hub administrator)"
msgstr "Тестовый режим (отправка только администратору узла)"
-#: ../../include/selectors.php:18
-msgid "Profile to assign new connections"
-msgstr "Назначить профиль для новых контактов"
-
-#: ../../include/selectors.php:41
-msgid "Frequently"
-msgstr "Часто"
-
-#: ../../include/selectors.php:42
-msgid "Hourly"
-msgstr "Ежечасно"
-
-#: ../../include/selectors.php:43
-msgid "Twice daily"
-msgstr "Дважды в день"
-
-#: ../../include/selectors.php:44
-msgid "Daily"
-msgstr "Ежедневно"
-
-#: ../../include/selectors.php:45
-msgid "Weekly"
-msgstr "Еженедельно"
-
-#: ../../include/selectors.php:46
-msgid "Monthly"
-msgstr "Ежемесячно"
-
-#: ../../include/selectors.php:60
-msgid "Currently Male"
-msgstr "В настоящее время мужской"
-
-#: ../../include/selectors.php:60
-msgid "Currently Female"
-msgstr "В настоящее время женский"
-
-#: ../../include/selectors.php:60
-msgid "Mostly Male"
-msgstr "В основном мужской"
-
-#: ../../include/selectors.php:60
-msgid "Mostly Female"
-msgstr "В основном женский"
-
-#: ../../include/selectors.php:60
-msgid "Transgender"
-msgstr "Трансгендер"
-
-#: ../../include/selectors.php:60
-msgid "Intersex"
-msgstr "Интерсексуал"
-
-#: ../../include/selectors.php:60
-msgid "Transsexual"
-msgstr "Транссексуал"
-
-#: ../../include/selectors.php:60
-msgid "Hermaphrodite"
-msgstr "Гермафродит"
-
-#: ../../include/selectors.php:60 ../../include/channel.php:1540
-msgid "Neuter"
-msgstr "Среднего рода"
-
-#: ../../include/selectors.php:60 ../../include/channel.php:1542
-msgid "Non-specific"
-msgstr "Неспецифический"
-
-#: ../../include/selectors.php:60
-msgid "Undecided"
-msgstr "Не решил"
-
-#: ../../include/selectors.php:96 ../../include/selectors.php:115
-msgid "Males"
-msgstr "Мужчины"
-
-#: ../../include/selectors.php:96 ../../include/selectors.php:115
-msgid "Females"
-msgstr "Женщины"
-
-#: ../../include/selectors.php:96
-msgid "Gay"
-msgstr "Гей"
-
-#: ../../include/selectors.php:96
-msgid "Lesbian"
-msgstr "Лесбиянка"
-
-#: ../../include/selectors.php:96
-msgid "No Preference"
-msgstr "Без предпочтений"
-
-#: ../../include/selectors.php:96
-msgid "Bisexual"
-msgstr "Бисексуал"
-
-#: ../../include/selectors.php:96
-msgid "Autosexual"
-msgstr "Автосексуал"
-
-#: ../../include/selectors.php:96
-msgid "Abstinent"
-msgstr "Воздержание"
-
-#: ../../include/selectors.php:96
-msgid "Virgin"
-msgstr "Девственник"
-
-#: ../../include/selectors.php:96
-msgid "Deviant"
-msgstr "Отклоняющийся от нормы"
-
-#: ../../include/selectors.php:96
-msgid "Fetish"
-msgstr "Фетишист"
-
-#: ../../include/selectors.php:96
-msgid "Oodles"
-msgstr "Множественный"
-
-#: ../../include/selectors.php:96
-msgid "Nonsexual"
-msgstr "Асексуал"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Single"
-msgstr "Одиночка"
-
-#: ../../include/selectors.php:134
-msgid "Lonely"
-msgstr "Одинокий"
-
-#: ../../include/selectors.php:134
-msgid "Available"
-msgstr "Свободен"
-
-#: ../../include/selectors.php:134
-msgid "Unavailable"
-msgstr "Занят"
-
-#: ../../include/selectors.php:134
-msgid "Has crush"
-msgstr "Влюблён"
-
-#: ../../include/selectors.php:134
-msgid "Infatuated"
-msgstr "без ума"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Dating"
-msgstr "Встречаюсь"
-
-#: ../../include/selectors.php:134
-msgid "Unfaithful"
-msgstr "Неверный"
-
-#: ../../include/selectors.php:134
-msgid "Sex Addict"
-msgstr "Эротоман"
-
-#: ../../include/selectors.php:134
-msgid "Friends/Benefits"
-msgstr "Друзья / Выгоды"
-
-#: ../../include/selectors.php:134
-msgid "Casual"
-msgstr "Легкомысленный"
-
-#: ../../include/selectors.php:134
-msgid "Engaged"
-msgstr "Помолвлен"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Married"
-msgstr "В браке"
-
-#: ../../include/selectors.php:134
-msgid "Imaginarily married"
-msgstr "В воображаемом браке"
-
-#: ../../include/selectors.php:134
-msgid "Partners"
-msgstr "Партнёрство"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Cohabiting"
-msgstr "Сожительствующие"
-
-#: ../../include/selectors.php:134
-msgid "Common law"
-msgstr "Гражданский брак"
-
-#: ../../include/selectors.php:134
-msgid "Happy"
-msgstr "Счастлив"
-
-#: ../../include/selectors.php:134
-msgid "Not looking"
-msgstr "Не нуждаюсь"
-
-#: ../../include/selectors.php:134
-msgid "Swinger"
-msgstr "Свингер"
-
-#: ../../include/selectors.php:134
-msgid "Betrayed"
-msgstr "Предан"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Separated"
-msgstr "Разделён"
-
-#: ../../include/selectors.php:134
-msgid "Unstable"
-msgstr "Нестабильно"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Divorced"
-msgstr "В разводе"
-
-#: ../../include/selectors.php:134
-msgid "Imaginarily divorced"
-msgstr "В воображаемом разводе"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "Widowed"
-msgstr "Вдовец / вдова"
-
-#: ../../include/selectors.php:134
-msgid "Uncertain"
-msgstr "Неопределенный"
-
-#: ../../include/selectors.php:134 ../../include/selectors.php:151
-msgid "It's complicated"
-msgstr "Это сложно"
-
-#: ../../include/selectors.php:134
-msgid "Don't care"
-msgstr "Всё равно"
-
-#: ../../include/selectors.php:134
-msgid "Ask me"
-msgstr "Спроси меня"
-
-#: ../../include/conversation.php:169
-#, php-format
-msgid "likes %1$s's %2$s"
-msgstr "Нравится %1$s %2$s"
-
-#: ../../include/conversation.php:172
-#, php-format
-msgid "doesn't like %1$s's %2$s"
-msgstr "Не нравится %1$s %2$s"
-
-#: ../../include/conversation.php:212
-#, php-format
-msgid "%1$s is now connected with %2$s"
-msgstr "%1$s теперь в контакте с %2$s"
-
-#: ../../include/conversation.php:247
-#, php-format
-msgid "%1$s poked %2$s"
-msgstr "%1$s ткнул %2$s"
-
-#: ../../include/conversation.php:251 ../../include/text.php:1176
-#: ../../include/text.php:1180
-msgid "poked"
-msgstr "ткнут"
-
-#: ../../include/conversation.php:739
-#, php-format
-msgid "View %s's profile @ %s"
-msgstr "Просмотреть профиль %s @ %s"
-
-#: ../../include/conversation.php:759
-msgid "Categories:"
-msgstr "Категории:"
-
-#: ../../include/conversation.php:760
-msgid "Filed under:"
-msgstr "Хранить под:"
-
-#: ../../include/conversation.php:785
-msgid "View in context"
-msgstr "Показать в контексте"
-
-#: ../../include/conversation.php:886
-msgid "remove"
-msgstr "удалить"
-
-#: ../../include/conversation.php:890
-msgid "Loading..."
-msgstr "Загрузка..."
-
-#: ../../include/conversation.php:892
-msgid "Delete Selected Items"
-msgstr "Удалить выбранные элементы"
-
-#: ../../include/conversation.php:935
-msgid "View Source"
-msgstr "Просмотреть источник"
-
-#: ../../include/conversation.php:945
-msgid "Follow Thread"
-msgstr "Следить за темой"
-
-#: ../../include/conversation.php:954
-msgid "Unfollow Thread"
-msgstr "Прекратить отслеживать тему"
-
-#: ../../include/conversation.php:1068
-msgid "Edit Connection"
-msgstr "Редактировать контакт"
-
-#: ../../include/conversation.php:1078
-msgid "Message"
-msgstr "Сообщение"
-
-#: ../../include/conversation.php:1212
-#, php-format
-msgid "%s likes this."
-msgstr "%s нравится это."
-
-#: ../../include/conversation.php:1212
-#, php-format
-msgid "%s doesn't like this."
-msgstr "%s не нравится это."
-
-#: ../../include/conversation.php:1216
-#, php-format
-msgid "<span %1$s>%2$d people</span> like this."
-msgid_plural "<span %1$s>%2$d people</span> like this."
-msgstr[0] "<span %1$s>%2$d человеку</span> это нравится."
-msgstr[1] "<span %1$s>%2$d человекам</span> это нравится."
-msgstr[2] "<span %1$s>%2$d человекам</span> это нравится."
-
-#: ../../include/conversation.php:1218
-#, php-format
-msgid "<span %1$s>%2$d people</span> don't like this."
-msgid_plural "<span %1$s>%2$d people</span> don't like this."
-msgstr[0] "<span %1$s>%2$d человеку</span> это не нравится."
-msgstr[1] "<span %1$s>%2$d человекам</span> это не нравится."
-msgstr[2] "<span %1$s>%2$d человекам</span> это не нравится."
-
-#: ../../include/conversation.php:1224
-msgid "and"
-msgstr "и"
-
-#: ../../include/conversation.php:1227
-#, php-format
-msgid ", and %d other people"
-msgid_plural ", and %d other people"
-msgstr[0] ", и ещё %d человеку"
-msgstr[1] ", и ещё %d человекам"
-msgstr[2] ", и ещё %d человекам"
-
-#: ../../include/conversation.php:1228
-#, php-format
-msgid "%s like this."
-msgstr "%s нравится это."
-
-#: ../../include/conversation.php:1228
-#, php-format
-msgid "%s don't like this."
-msgstr "%s не нравится это."
-
-#: ../../include/conversation.php:1708
-msgctxt "noun"
-msgid "Attending"
-msgid_plural "Attending"
-msgstr[0] "Посетит"
-msgstr[1] "Посетят"
-msgstr[2] "Посетят"
-
-#: ../../include/conversation.php:1711
-msgctxt "noun"
-msgid "Not Attending"
-msgid_plural "Not Attending"
-msgstr[0] "Не посетит"
-msgstr[1] "Не посетят"
-msgstr[2] "Не посетят"
-
-#: ../../include/conversation.php:1714
-msgctxt "noun"
-msgid "Undecided"
-msgid_plural "Undecided"
-msgstr "Не решил"
-
-#: ../../include/conversation.php:1717
-msgctxt "noun"
-msgid "Agree"
-msgid_plural "Agrees"
-msgstr[0] "Согласен"
-msgstr[1] "Согласны"
-msgstr[2] "Согласны"
-
-#: ../../include/conversation.php:1720
-msgctxt "noun"
-msgid "Disagree"
-msgid_plural "Disagrees"
-msgstr[0] "Не согласен"
-msgstr[1] "Не согласны"
-msgstr[2] "Не согласны"
-
-#: ../../include/conversation.php:1723
-msgctxt "noun"
-msgid "Abstain"
-msgid_plural "Abstains"
-msgstr[0] "Воздержался"
-msgstr[1] "Воздержались"
-msgstr[2] "Воздержались"
-
-#: ../../include/bookmarks.php:34
-#, php-format
-msgid "%1$s's bookmarks"
-msgstr "Закладки пользователя %1$s"
-
-#: ../../include/import.php:26
-msgid "Unable to import a removed channel."
-msgstr "Невозможно импортировать удалённый канал."
-
-#: ../../include/import.php:52
-msgid ""
-"Cannot create a duplicate channel identifier on this system. Import failed."
-msgstr "Не удалось создать дублирующийся идентификатор канала. Импорт невозможен."
-
-#: ../../include/import.php:117
-msgid "Cloned channel not found. Import failed."
-msgstr "Клон канала не найден. Импорт невозможен."
-
-#: ../../include/text.php:501
-msgid "prev"
-msgstr "предыдущий"
-
-#: ../../include/text.php:503
-msgid "first"
-msgstr "первый"
-
-#: ../../include/text.php:532
-msgid "last"
-msgstr "последний"
-
-#: ../../include/text.php:535
-msgid "next"
-msgstr "следующий"
-
-#: ../../include/text.php:553
-msgid "older"
-msgstr "старше"
-
-#: ../../include/text.php:555
-msgid "newer"
-msgstr "новее"
-
-#: ../../include/text.php:979
-msgid "No connections"
-msgstr "Нет контактов"
-
-#: ../../include/text.php:1011
-#, php-format
-msgid "View all %s connections"
-msgstr "Просмотреть все %s контактов"
-
-#: ../../include/text.php:1073
-#, php-format
-msgid "Network: %s"
-msgstr "Сеть: %s"
-
-#: ../../include/text.php:1176 ../../include/text.php:1180
-msgid "poke"
-msgstr "Ткнуть"
-
-#: ../../include/text.php:1181
-msgid "ping"
-msgstr "Пингануть"
-
-#: ../../include/text.php:1181
-msgid "pinged"
-msgstr "Отпингован"
-
-#: ../../include/text.php:1182
-msgid "prod"
-msgstr "Подтолкнуть"
-
-#: ../../include/text.php:1182
-msgid "prodded"
-msgstr "Подтолкнут"
-
-#: ../../include/text.php:1183
-msgid "slap"
-msgstr "Шлёпнуть"
-
-#: ../../include/text.php:1183
-msgid "slapped"
-msgstr "Шлёпнут"
-
-#: ../../include/text.php:1184
-msgid "finger"
-msgstr "Указать"
-
-#: ../../include/text.php:1184
-msgid "fingered"
-msgstr "Указан"
-
-#: ../../include/text.php:1185
-msgid "rebuff"
-msgstr "Дать отпор"
-
-#: ../../include/text.php:1185
-msgid "rebuffed"
-msgstr "Дан отпор"
-
-#: ../../include/text.php:1208
-msgid "happy"
-msgstr "счастливый"
-
-#: ../../include/text.php:1209
-msgid "sad"
-msgstr "грустный"
-
-#: ../../include/text.php:1210
-msgid "mellow"
-msgstr "спокойный"
-
-#: ../../include/text.php:1211
-msgid "tired"
-msgstr "усталый"
-
-#: ../../include/text.php:1212
-msgid "perky"
-msgstr "весёлый"
-
-#: ../../include/text.php:1213
-msgid "angry"
-msgstr "сердитый"
-
-#: ../../include/text.php:1214
-msgid "stupefied"
-msgstr "отупевший"
-
-#: ../../include/text.php:1215
-msgid "puzzled"
-msgstr "недоумевающий"
-
-#: ../../include/text.php:1216
-msgid "interested"
-msgstr "заинтересованный"
-
-#: ../../include/text.php:1217
-msgid "bitter"
-msgstr "едкий"
-
-#: ../../include/text.php:1218
-msgid "cheerful"
-msgstr "бодрый"
-
-#: ../../include/text.php:1219
-msgid "alive"
-msgstr "энергичный"
-
-#: ../../include/text.php:1220
-msgid "annoyed"
-msgstr "раздражённый"
-
-#: ../../include/text.php:1221
-msgid "anxious"
-msgstr "обеспокоенный"
-
-#: ../../include/text.php:1222
-msgid "cranky"
-msgstr "капризный"
-
-#: ../../include/text.php:1223
-msgid "disturbed"
-msgstr "встревоженный"
-
-#: ../../include/text.php:1224
-msgid "frustrated"
-msgstr "разочарованный"
-
-#: ../../include/text.php:1225
-msgid "depressed"
-msgstr "подавленный"
-
-#: ../../include/text.php:1226
-msgid "motivated"
-msgstr "мотивированный"
-
-#: ../../include/text.php:1227
-msgid "relaxed"
-msgstr "расслабленный"
-
-#: ../../include/text.php:1228
-msgid "surprised"
-msgstr "удивленный"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:95
-msgid "Monday"
-msgstr "Понедельник"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:96
-msgid "Tuesday"
-msgstr "Вторник"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:97
-msgid "Wednesday"
-msgstr "Среда"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:98
-msgid "Thursday"
-msgstr "Четверг"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:99
-msgid "Friday"
-msgstr "Пятница"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:100
-msgid "Saturday"
-msgstr "Суббота"
-
-#: ../../include/text.php:1416 ../../include/js_strings.php:94
-msgid "Sunday"
-msgstr "Воскресенье"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:70
-msgid "January"
-msgstr "Январь"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:71
-msgid "February"
-msgstr "Февраль"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:72
-msgid "March"
-msgstr "Март"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:73
-msgid "April"
-msgstr "Апрель"
-
-#: ../../include/text.php:1420
-msgid "May"
-msgstr "Май"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:75
-msgid "June"
-msgstr "Июнь"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:76
-msgid "July"
-msgstr "Июль"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:77
-msgid "August"
-msgstr "Август"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:78
-msgid "September"
-msgstr "Сентябрь"
-
-#: ../../include/text.php:1420 ../../include/js_strings.php:79
-msgid "October"
-msgstr "Октябрь"
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:35
+msgid "Smileybutton App"
+msgstr "Приложение \"Кнопка со смайликам\""
-#: ../../include/text.php:1420 ../../include/js_strings.php:80
-msgid "November"
-msgstr "Ноябрь"
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:36
+msgid "Adds a smileybutton to the jot editor"
+msgstr "Добавлять кнопку со смайликами в редактор Jot"
-#: ../../include/text.php:1420 ../../include/js_strings.php:81
-msgid "December"
-msgstr "Декабрь"
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:44
+msgid "Hide the button and show the smilies directly."
+msgstr "Скрыть кнопку и сразу показывать смайлики."
-#: ../../include/text.php:1494
-msgid "Unknown Attachment"
-msgstr "Неизвестное вложение"
+#: ../../extend/addon/hzaddons/smileybutton/Mod_Smileybutton.php:52
+msgid "Smileybutton Settings"
+msgstr "Настройки кнопки со смайликами"
-#: ../../include/text.php:1496 ../../include/feedutils.php:858
-msgid "unknown"
-msgstr "неизвестный"
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:92
+msgid "Friendica Photo Album Import"
+msgstr "Импортировать альбом фотографий Friendica"
-#: ../../include/text.php:1532
-msgid "remove category"
-msgstr "удалить категорию"
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:93
+msgid "This will import all your Friendica photo albums to this Red channel."
+msgstr "Это позволит импортировать все ваши альбомы фотографий Friendica в этот канал."
-#: ../../include/text.php:1606
-msgid "remove from file"
-msgstr "удалить из файла"
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:94
+msgid "Friendica Server base URL"
+msgstr "Базовый URL сервера Friendica"
-#: ../../include/text.php:1765 ../../include/message.php:13
-msgid "Download binary/encrypted content"
-msgstr "Загрузить двоичное / зашифрованное содержимое"
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:95
+msgid "Friendica Login Username"
+msgstr "Имя пользователя для входа Friendica"
-#: ../../include/text.php:1935 ../../include/language.php:423
-msgid "default"
-msgstr "по умолчанию"
+#: ../../extend/addon/hzaddons/frphotos/frphotos.php:96
+msgid "Friendica Login Password"
+msgstr "Пароль для входа Firendica"
-#: ../../include/text.php:1943
-msgid "Page layout"
-msgstr "Шаблон страницы"
+#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:25
+msgid "Show Upload Limits"
+msgstr "Показать ограничения на загрузку"
-#: ../../include/text.php:1943
-msgid "You can create your own with the layouts tool"
-msgstr "Вы можете создать свой собственный с помощью инструмента шаблонов"
+#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:27
+msgid "Hubzilla configured maximum size: "
+msgstr "Максимальный размер настроенный в Hubzilla:"
-#: ../../include/text.php:1954
-msgid "HTML"
+#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:28
+msgid "PHP upload_max_filesize: "
msgstr ""
-#: ../../include/text.php:1957
-msgid "Comanche Layout"
-msgstr "Шаблон Comanche"
-
-#: ../../include/text.php:1962
-msgid "PHP"
-msgstr ""
+#: ../../extend/addon/hzaddons/upload_limits/upload_limits.php:29
+msgid "PHP post_max_size (must be larger than upload_max_filesize): "
+msgstr "PHP post_max_size (должен быть больше чем upload_max_filesize): "
-#: ../../include/text.php:1971
-msgid "Page content type"
-msgstr "Тип содержимого страницы"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:41
+msgid "Flattr widget settings updated."
+msgstr "Настройки виджета Flattr обновлены."
-#: ../../include/text.php:2104
-msgid "activity"
-msgstr "активность"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:53
+msgid "Flattr Widget App"
+msgstr "Приложение \"Виджет Flattr\""
-#: ../../include/text.php:2205
-msgid "a-z, 0-9, -, and _ only"
-msgstr "Только a-z, 0-9, -, и _"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:54
+msgid "Add a Flattr button to your channel page"
+msgstr "Добавить кнопку Flattr на страницу вашего канала"
-#: ../../include/text.php:2531
-msgid "Design Tools"
-msgstr "Инструменты дизайна"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:65
+msgid "Flattr user"
+msgstr "Пользователь Flattr"
-#: ../../include/text.php:2537
-msgid "Pages"
-msgstr "Страницы"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:69
+msgid "URL of the Thing to flattr"
+msgstr "URL ccылки на Flattr"
-#: ../../include/text.php:2559
-msgid "Import website..."
-msgstr "Импорт веб-сайта..."
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:69
+msgid "If empty channel URL is used"
+msgstr "Если пусто, то используется URL канала"
-#: ../../include/text.php:2560
-msgid "Select folder to import"
-msgstr "Выбрать каталог для импорта"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:73
+msgid "Title of the Thing to flattr"
+msgstr "Заголовок вещи на Flattr"
-#: ../../include/text.php:2561
-msgid "Import from a zipped folder:"
-msgstr "Импортировать из каталога в zip-архиве:"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:73
+msgid "If empty \"channel name on The Hubzilla\" will be used"
+msgstr "Если пусто, то будет использовано \"Название канала Hubzilla\""
-#: ../../include/text.php:2562
-msgid "Import from cloud files:"
-msgstr "Импортировать из сетевых файлов:"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:77
+msgid "Static or dynamic flattr button"
+msgstr "Статическая или динамическая кнопка Flattr"
-#: ../../include/text.php:2563
-msgid "/cloud/channel/path/to/folder"
-msgstr ""
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:77
+msgid "static"
+msgstr "статическая"
-#: ../../include/text.php:2564
-msgid "Enter path to website files"
-msgstr "Введите путь к файлам веб-сайта"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:77
+msgid "dynamic"
+msgstr "динамическая"
-#: ../../include/text.php:2565
-msgid "Select folder"
-msgstr "Выбрать каталог"
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:81
+msgid "Alignment of the widget"
+msgstr "Выравнивание виджета"
-#: ../../include/text.php:2566
-msgid "Export website..."
-msgstr "Экспорт веб-сайта..."
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:81
+msgid "left"
+msgstr "слева"
-#: ../../include/text.php:2567
-msgid "Export to a zip file"
-msgstr "Экспортировать в ZIP файл."
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:81
+msgid "right"
+msgstr "справа"
-#: ../../include/text.php:2568
-msgid "website.zip"
-msgstr ""
+#: ../../extend/addon/hzaddons/flattrwidget/Mod_Flattrwidget.php:89
+msgid "Flattr Widget"
+msgstr "Виджет Flattr"
-#: ../../include/text.php:2569
-msgid "Enter a name for the zip file."
-msgstr "Введите имя для ZIP файла."
+#: ../../extend/addon/hzaddons/flattrwidget/flattrwidget.php:50
+msgid "Flattr this!"
+msgstr "Flattr это!"
-#: ../../include/text.php:2570
-msgid "Export to cloud files"
-msgstr "Эскпортировать в сетевые файлы:"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:21
+msgid "Three Dimensional Tic-Tac-Toe"
+msgstr "Tic-Tac-Toe в трёх измерениях"
-#: ../../include/text.php:2571
-msgid "/path/to/export/folder"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:54
+msgid "3D Tic-Tac-Toe"
msgstr ""
-#: ../../include/text.php:2572
-msgid "Enter a path to a cloud files destination."
-msgstr "Введите путь к расположению сетевых файлов."
-
-#: ../../include/text.php:2573
-msgid "Specify folder"
-msgstr "Указать каталог"
-
-#: ../../include/contact_widgets.php:11
-#, php-format
-msgid "%d invitation available"
-msgid_plural "%d invitations available"
-msgstr[0] "доступно %d приглашение"
-msgstr[1] "доступны %d приглашения"
-msgstr[2] "доступны %d приглашений"
-
-#: ../../include/contact_widgets.php:19
-msgid "Find Channels"
-msgstr "Поиск каналов"
-
-#: ../../include/contact_widgets.php:20
-msgid "Enter name or interest"
-msgstr "Впишите имя или интерес"
-
-#: ../../include/contact_widgets.php:21
-msgid "Connect/Follow"
-msgstr "Подключить / отслеживать"
-
-#: ../../include/contact_widgets.php:22
-msgid "Examples: Robert Morgenstein, Fishing"
-msgstr "Примеры: Владимир Ильич, Революционер"
-
-#: ../../include/contact_widgets.php:26
-msgid "Random Profile"
-msgstr "Случайный профиль"
-
-#: ../../include/contact_widgets.php:27
-msgid "Invite Friends"
-msgstr "Пригласить друзей"
-
-#: ../../include/contact_widgets.php:29
-msgid "Advanced example: name=fred and country=iceland"
-msgstr "Расширенный пример: name=ivan and country=russia"
-
-#: ../../include/contact_widgets.php:218
-msgid "Common Connections"
-msgstr "Общие контакты"
-
-#: ../../include/contact_widgets.php:222
-#, php-format
-msgid "View all %d common connections"
-msgstr "Просмотреть все %d общих контактов"
-
-#: ../../include/markdown.php:198 ../../include/bbcode.php:347
-#, php-format
-msgid "%1$s wrote the following %2$s %3$s"
-msgstr "%1$s была создана %2$s %3$s"
-
-#: ../../include/follow.php:37
-msgid "Channel is blocked on this site."
-msgstr "Канал блокируется на этом сайте."
-
-#: ../../include/follow.php:42
-msgid "Channel location missing."
-msgstr "Местоположение канала отсутствует."
-
-#: ../../include/follow.php:84
-msgid "Response from remote channel was incomplete."
-msgstr "Ответ удаленного канала неполный."
-
-#: ../../include/follow.php:96
-msgid "Premium channel - please visit:"
-msgstr "Премимум-канал - пожалуйста посетите:"
-
-#: ../../include/follow.php:110
-msgid "Channel was deleted and no longer exists."
-msgstr "Канал удален и больше не существует."
-
-#: ../../include/follow.php:165
-msgid "Remote channel or protocol unavailable."
-msgstr "Удалённый канал или протокол недоступен."
-
-#: ../../include/follow.php:188
-msgid "Channel discovery failed."
-msgstr "Не удалось обнаружить канал."
-
-#: ../../include/follow.php:200
-msgid "Protocol disabled."
-msgstr "Протокол отключен."
-
-#: ../../include/follow.php:211
-msgid "Cannot connect to yourself."
-msgstr "Нельзя подключиться к самому себе."
-
-#: ../../include/js_strings.php:5
-msgid "Delete this item?"
-msgstr "Удалить этот элемент?"
-
-#: ../../include/js_strings.php:8
-#, php-format
-msgid "%s show less"
-msgstr "%s показать меньше"
-
-#: ../../include/js_strings.php:9
-#, php-format
-msgid "%s expand"
-msgstr "%s развернуть"
-
-#: ../../include/js_strings.php:10
-#, php-format
-msgid "%s collapse"
-msgstr "%s свернуть"
-
-#: ../../include/js_strings.php:11
-msgid "Password too short"
-msgstr "Пароль слишком короткий"
-
-#: ../../include/js_strings.php:12
-msgid "Passwords do not match"
-msgstr "Пароли не совпадают"
-
-#: ../../include/js_strings.php:13
-msgid "everybody"
-msgstr "все"
-
-#: ../../include/js_strings.php:14
-msgid "Secret Passphrase"
-msgstr "Тайный пароль"
-
-#: ../../include/js_strings.php:15
-msgid "Passphrase hint"
-msgstr "Подсказка для пароля"
-
-#: ../../include/js_strings.php:16
-msgid "Notice: Permissions have changed but have not yet been submitted."
-msgstr "Уведомление: Права доступа изменились, но до сих пор не сохранены."
-
-#: ../../include/js_strings.php:17
-msgid "close all"
-msgstr "закрыть все"
-
-#: ../../include/js_strings.php:18
-msgid "Nothing new here"
-msgstr "Здесь нет ничего нового"
-
-#: ../../include/js_strings.php:19
-msgid "Rate This Channel (this is public)"
-msgstr "Оценкa этoго канала (общедоступно)"
-
-#: ../../include/js_strings.php:21
-msgid "Describe (optional)"
-msgstr "Охарактеризовать (необязательно)"
-
-#: ../../include/js_strings.php:23
-msgid "Please enter a link URL"
-msgstr "Пожалуйста, введите URL ссылки"
-
-#: ../../include/js_strings.php:24
-msgid "Unsaved changes. Are you sure you wish to leave this page?"
-msgstr "Есть несохраненные изменения. Вы уверены, что хотите покинуть эту страницу?"
-
-#: ../../include/js_strings.php:26
-msgid "lovely"
-msgstr "прекрасно"
-
-#: ../../include/js_strings.php:27
-msgid "wonderful"
-msgstr "замечательно"
-
-#: ../../include/js_strings.php:28
-msgid "fantastic"
-msgstr "фантастично"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:59
+msgid "New game"
+msgstr "Новая игра"
-#: ../../include/js_strings.php:29
-msgid "great"
-msgstr "отлично"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:60
+msgid "New game with handicap"
+msgstr "Новая игра с форой"
-#: ../../include/js_strings.php:30
+#: ../../extend/addon/hzaddons/tictac/tictac.php:61
msgid ""
-"Your chosen nickname was either already taken or not valid. Please use our "
-"suggestion ("
-msgstr "Выбранный вами псевдоним уже используется или недействителен. Попробуйте использовать наше предложение ("
-
-#: ../../include/js_strings.php:31
-msgid ") or enter a new one."
-msgstr ") или введите новый."
-
-#: ../../include/js_strings.php:32
-msgid "Thank you, this nickname is valid."
-msgstr "Спасибо, этот псевдоним может быть использован."
-
-#: ../../include/js_strings.php:33
-msgid "A channel name is required."
-msgstr "Требуется название канала."
-
-#: ../../include/js_strings.php:34
-msgid "This is a "
-msgstr "Это "
-
-#: ../../include/js_strings.php:35
-msgid " channel name"
-msgstr " название канала"
-
-#: ../../include/js_strings.php:41
-#, php-format
-msgid "%d minutes"
-msgid_plural "%d minutes"
-msgstr[0] "%d минуту"
-msgstr[1] "%d минуты"
-msgstr[2] "%d минут"
-
-#: ../../include/js_strings.php:42
-#, php-format
-msgid "about %d hours"
-msgid_plural "about %d hours"
-msgstr[0] "около %d часa"
-msgstr[1] "около %d часов"
-msgstr[2] "около %d часов"
-
-#: ../../include/js_strings.php:43
-#, php-format
-msgid "%d days"
-msgid_plural "%d days"
-msgstr[0] "%d день"
-msgstr[1] "%d дня"
-msgstr[2] "%d дней"
-
-#: ../../include/js_strings.php:44
-#, php-format
-msgid "%d months"
-msgid_plural "%d months"
-msgstr[0] "%d месяц"
-msgstr[1] "%d месяца"
-msgstr[2] "%d месяцев"
-
-#: ../../include/js_strings.php:45
-#, php-format
-msgid "%d years"
-msgid_plural "%d years"
-msgstr[0] "%d год"
-msgstr[1] "%d года"
-msgstr[2] "%d лет"
-
-#: ../../include/js_strings.php:50
-msgid "timeago.prefixAgo"
-msgstr ""
-
-#: ../../include/js_strings.php:51
-msgid "timeago.prefixFromNow"
-msgstr "через"
-
-#: ../../include/js_strings.php:52
-msgid "timeago.suffixAgo"
-msgstr "назад"
-
-#: ../../include/js_strings.php:53
-msgid "timeago.suffixFromNow"
-msgstr ""
-
-#: ../../include/js_strings.php:56
-msgid "less than a minute"
-msgstr "менее чем одну минуту"
-
-#: ../../include/js_strings.php:57
-msgid "about a minute"
-msgstr "около минуты"
-
-#: ../../include/js_strings.php:59
-msgid "about an hour"
-msgstr "около часа"
-
-#: ../../include/js_strings.php:61
-msgid "a day"
-msgstr "день"
-
-#: ../../include/js_strings.php:63
-msgid "about a month"
-msgstr "около месяца"
-
-#: ../../include/js_strings.php:65
-msgid "about a year"
-msgstr "около года"
-
-#: ../../include/js_strings.php:67
-msgid " "
-msgstr " "
-
-#: ../../include/js_strings.php:68
-msgid "timeago.numbers"
-msgstr ""
-
-#: ../../include/js_strings.php:74
-msgctxt "long"
-msgid "May"
-msgstr "Май"
-
-#: ../../include/js_strings.php:82
-msgid "Jan"
-msgstr "Янв"
-
-#: ../../include/js_strings.php:83
-msgid "Feb"
-msgstr "Фев"
-
-#: ../../include/js_strings.php:84
-msgid "Mar"
-msgstr "Мар"
-
-#: ../../include/js_strings.php:85
-msgid "Apr"
-msgstr "Апр"
-
-#: ../../include/js_strings.php:86
-msgctxt "short"
-msgid "May"
-msgstr "Май"
-
-#: ../../include/js_strings.php:87
-msgid "Jun"
-msgstr "Июн"
-
-#: ../../include/js_strings.php:88
-msgid "Jul"
-msgstr "Июл"
-
-#: ../../include/js_strings.php:89
-msgid "Aug"
-msgstr "Авг"
-
-#: ../../include/js_strings.php:90
-msgid "Sep"
-msgstr "Сен"
-
-#: ../../include/js_strings.php:91
-msgid "Oct"
-msgstr "Окт"
-
-#: ../../include/js_strings.php:92
-msgid "Nov"
-msgstr "Ноя"
-
-#: ../../include/js_strings.php:93
-msgid "Dec"
-msgstr "Дек"
-
-#: ../../include/js_strings.php:101
-msgid "Sun"
-msgstr "Вск"
-
-#: ../../include/js_strings.php:102
-msgid "Mon"
-msgstr "Пон"
-
-#: ../../include/js_strings.php:103
-msgid "Tue"
-msgstr "Вт"
-
-#: ../../include/js_strings.php:104
-msgid "Wed"
-msgstr "Ср"
-
-#: ../../include/js_strings.php:105
-msgid "Thu"
-msgstr "Чет"
-
-#: ../../include/js_strings.php:106
-msgid "Fri"
-msgstr "Пят"
-
-#: ../../include/js_strings.php:107
-msgid "Sat"
-msgstr "Суб"
-
-#: ../../include/js_strings.php:108
-msgctxt "calendar"
-msgid "today"
-msgstr "сегодня"
-
-#: ../../include/js_strings.php:109
-msgctxt "calendar"
-msgid "month"
-msgstr "месяц"
-
-#: ../../include/js_strings.php:110
-msgctxt "calendar"
-msgid "week"
-msgstr "неделя"
-
-#: ../../include/js_strings.php:111
-msgctxt "calendar"
-msgid "day"
-msgstr "день"
-
-#: ../../include/js_strings.php:112
-msgctxt "calendar"
-msgid "All day"
-msgstr "Весь день"
-
-#: ../../include/message.php:41
-msgid "Unable to determine sender."
-msgstr "Невозможно определить отправителя."
-
-#: ../../include/message.php:80
-msgid "No recipient provided."
-msgstr "Получатель не предоставлен."
-
-#: ../../include/message.php:85
-msgid "[no subject]"
-msgstr "[без темы]"
-
-#: ../../include/message.php:215
-msgid "Stored post could not be verified."
-msgstr "Сохранённая публикация не может быть проверена."
-
-#: ../../include/activities.php:42
-msgid " and "
-msgstr " и "
-
-#: ../../include/activities.php:50
-msgid "public profile"
-msgstr "общедоступный профиль"
-
-#: ../../include/activities.php:59
-#, php-format
-msgid "%1$s changed %2$s to &ldquo;%3$s&rdquo;"
-msgstr "%1$s изменил %2$s на &ldquo;%3$s&rdquo;"
-
-#: ../../include/activities.php:60
-#, php-format
-msgid "Visit %1$s's %2$s"
-msgstr "Посетить %1$s %2$s"
-
-#: ../../include/activities.php:63
-#, php-format
-msgid "%1$s has an updated %2$s, changing %3$s."
-msgstr "%1$s обновлено %2$s, изменено %3$s."
-
-#: ../../include/attach.php:267 ../../include/attach.php:376
-msgid "Item was not found."
-msgstr "Элемент не найден."
-
-#: ../../include/attach.php:284
-msgid "Unknown error."
-msgstr "Неизвестная ошибка."
-
-#: ../../include/attach.php:569
-msgid "No source file."
-msgstr "Нет исходного файла."
-
-#: ../../include/attach.php:591
-msgid "Cannot locate file to replace"
-msgstr "Не удается найти файл для замены"
-
-#: ../../include/attach.php:610
-msgid "Cannot locate file to revise/update"
-msgstr "Не удается найти файл для пересмотра / обновления"
-
-#: ../../include/attach.php:752
-#, php-format
-msgid "File exceeds size limit of %d"
-msgstr "Файл превышает предельный размер %d"
-
-#: ../../include/attach.php:773
-#, php-format
-msgid "You have reached your limit of %1$.0f Mbytes attachment storage."
-msgstr "Вы достигли предела %1$.0f Мбайт для хранения вложений."
-
-#: ../../include/attach.php:955
-msgid "File upload failed. Possible system limit or action terminated."
-msgstr "Загрузка файла не удалась. Возможно система перегружена или попытка прекращена."
-
-#: ../../include/attach.php:984
-msgid "Stored file could not be verified. Upload failed."
-msgstr "Файл для сохранения не может быть проверен. Загрузка не удалась."
-
-#: ../../include/attach.php:1058 ../../include/attach.php:1074
-msgid "Path not available."
-msgstr "Путь недоступен."
-
-#: ../../include/attach.php:1123 ../../include/attach.php:1288
-msgid "Empty pathname"
-msgstr "Пустое имя пути"
-
-#: ../../include/attach.php:1149
-msgid "duplicate filename or path"
-msgstr "дублирующееся имя файла или пути"
-
-#: ../../include/attach.php:1174
-msgid "Path not found."
-msgstr "Путь не найден."
-
-#: ../../include/attach.php:1242
-msgid "mkdir failed."
-msgstr "mkdir не удался"
-
-#: ../../include/attach.php:1246
-msgid "database storage failed."
-msgstr "ошибка при записи базы данных."
-
-#: ../../include/attach.php:1294
-msgid "Empty path"
-msgstr "Пустое имя пути"
+"Three dimensional tic-tac-toe is just like the traditional game except that "
+"it is played on multiple levels simultaneously. "
+msgstr "Трехмерный Tic-Tac-Toe похож на традиционную игру, за исключением того, что игра идёт на нескольких уровнях одновременно."
-#: ../../include/security.php:541
+#: ../../extend/addon/hzaddons/tictac/tictac.php:62
msgid ""
-"The form security token was not correct. This probably happened because the "
-"form has been opened for too long (>3 hours) before submitting it."
-msgstr "Не верный токен безопасности для формы. Вероятно, это произошло потому, что форма была открыта слишком долго (> 3-х часов) перед его отправкой."
-
-#: ../../include/items.php:955 ../../include/items.php:1015
-msgid "(Unknown)"
-msgstr "(Неизвестный)"
-
-#: ../../include/items.php:1203
-msgid "Visible to anybody on the internet."
-msgstr "Виден всем в интернете."
-
-#: ../../include/items.php:1205
-msgid "Visible to you only."
-msgstr "Видно только вам."
-
-#: ../../include/items.php:1207
-msgid "Visible to anybody in this network."
-msgstr "Видно всем в этой сети."
-
-#: ../../include/items.php:1209
-msgid "Visible to anybody authenticated."
-msgstr "Видно всем аутентифицированным."
-
-#: ../../include/items.php:1211
-#, php-format
-msgid "Visible to anybody on %s."
-msgstr "Видно всем в %s."
-
-#: ../../include/items.php:1213
-msgid "Visible to all connections."
-msgstr "Видно всем контактам."
-
-#: ../../include/items.php:1215
-msgid "Visible to approved connections."
-msgstr "Видно только одобренным контактам."
-
-#: ../../include/items.php:1217
-msgid "Visible to specific connections."
-msgstr "Видно указанным контактам."
-
-#: ../../include/items.php:4291
-msgid "Privacy group is empty."
-msgstr "Группа безопасности пуста"
-
-#: ../../include/items.php:4298
-#, php-format
-msgid "Privacy group: %s"
-msgstr "Группа безопасности: %s"
-
-#: ../../include/items.php:4310
-msgid "Connection not found."
-msgstr "Контакт не найден."
-
-#: ../../include/items.php:4659
-msgid "profile photo"
-msgstr "Фотография профиля"
-
-#: ../../include/items.php:4851
-#, php-format
-msgid "[Edited %s]"
-msgstr "[Отредактировано %s]"
-
-#: ../../include/items.php:4851
-msgctxt "edit_activity"
-msgid "Post"
-msgstr "Публикация"
-
-#: ../../include/items.php:4851
-msgctxt "edit_activity"
-msgid "Comment"
-msgstr "Комментарий"
-
-#: ../../include/channel.php:43
-msgid "Unable to obtain identity information from database"
-msgstr "Невозможно получить идентификационную информацию из базы данных"
-
-#: ../../include/channel.php:76
-msgid "Empty name"
-msgstr "Пустое имя"
-
-#: ../../include/channel.php:79
-msgid "Name too long"
-msgstr "Слишком длинное имя"
+"In this case there are three levels. You win by getting three in a row on "
+"any level, as well as up, down, and diagonally across the different levels."
+msgstr "Имеется три уровня. Вы выигрываете, получая три подряд на любом уровне, а также вверх, вниз и по диагонали на разных уровнях."
-#: ../../include/channel.php:196
-msgid "No account identifier"
-msgstr "Идентификатор аккаунта отсутствует"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:64
+msgid ""
+"The handicap game disables the center position on the middle level because "
+"the player claiming this square often has an unfair advantage."
+msgstr "Игра с форой отключает центральную позицию на среднем уровне, потому что игрок, претендующий на этот квадрат, часто имеет несправедливое преимущество."
-#: ../../include/channel.php:208
-msgid "Nickname is required."
-msgstr "Требуется псевдоним."
+#: ../../extend/addon/hzaddons/tictac/tictac.php:183
+msgid "You go first..."
+msgstr "Вы начинаете..."
-#: ../../include/channel.php:287
-msgid "Unable to retrieve created identity"
-msgstr "Не удается получить созданный идентификатор"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:188
+msgid "I'm going first this time..."
+msgstr "На этот раз начинаю я..."
-#: ../../include/channel.php:429
-msgid "Default Profile"
-msgstr "Профиль по умолчанию"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:194
+msgid "You won!"
+msgstr "Вы выиграли!"
-#: ../../include/channel.php:588 ../../include/channel.php:677
-msgid "Unable to retrieve modified identity"
-msgstr "Не удается найти изменённый идентификатор"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:200
+#: ../../extend/addon/hzaddons/tictac/tictac.php:225
+msgid "\"Cat\" game!"
+msgstr "Ничья!"
-#: ../../include/channel.php:1353
-msgid "Create New Profile"
-msgstr "Создать новый профиль"
+#: ../../extend/addon/hzaddons/tictac/tictac.php:223
+msgid "I won!"
+msgstr "Я выиграл!"
-#: ../../include/channel.php:1374
-msgid "Visible to everybody"
-msgstr "Видно всем"
+#: ../../extend/addon/hzaddons/xmpp/xmpp.php:44
+msgid "Jabber BOSH host"
+msgstr "Узел Jabber BOSH"
-#: ../../include/channel.php:1451 ../../include/channel.php:1579
-msgid "Gender:"
-msgstr "Пол:"
+#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45
+msgid "Use central userbase"
+msgstr "Использовать центральную базу данных"
-#: ../../include/channel.php:1453 ../../include/channel.php:1647
-msgid "Homepage:"
-msgstr "Домашняя страница:"
+#: ../../extend/addon/hzaddons/xmpp/xmpp.php:45
+msgid ""
+"If enabled, members will automatically login to an ejabberd server that has "
+"to be installed on this machine with synchronized credentials via the "
+"\"auth_ejabberd.php\" script."
+msgstr "Если включено, участники автоматически войдут на сервер ejabberd, который должен быть установлен на этом компьютере с синхронизированными учетными данными через скрипт \"auth_ejabberd.php\"."
-#: ../../include/channel.php:1454
-msgid "Online Now"
-msgstr "Сейчас в сети"
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:23
+msgid "XMPP settings updated."
+msgstr "Настройки XMPP обновлены."
-#: ../../include/channel.php:1507
-msgid "Change your profile photo"
-msgstr "Изменить фотографию вашего профиля"
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:35
+msgid "XMPP App"
+msgstr "Приложение XMPP"
-#: ../../include/channel.php:1538
-msgid "Trans"
-msgstr "Трансексуал"
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:36
+msgid "Embedded XMPP (Jabber) client"
+msgstr "Встренный клиент XMPP (Jabber)"
-#: ../../include/channel.php:1584
-msgid "Like this channel"
-msgstr "нравится этот канал"
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:52
+msgid "Individual credentials"
+msgstr "Индивидуальные разрешения"
-#: ../../include/channel.php:1608
-msgid "j F, Y"
-msgstr ""
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:58
+msgid "Jabber BOSH server"
+msgstr "Сервер Jabber BOSH"
-#: ../../include/channel.php:1609
-msgid "j F"
-msgstr ""
+#: ../../extend/addon/hzaddons/xmpp/Mod_Xmpp.php:67
+msgid "XMPP Settings"
+msgstr "Настройки XMPP"
-#: ../../include/channel.php:1616
-msgid "Birthday:"
-msgstr "День рождения:"
+#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:34
+msgid "New registration"
+msgstr "Новая регистрация"
-#: ../../include/channel.php:1629
+#: ../../extend/addon/hzaddons/notifyadmin/notifyadmin.php:42
#, php-format
-msgid "for %1$d %2$s"
-msgstr "для %1$d %2$s"
-
-#: ../../include/channel.php:1641
-msgid "Tags:"
-msgstr "Теги:"
+msgid "Message sent to %s. New account registration: %s"
+msgstr "Сообщение отправлено в %s. Регистрация нового аккаунта: %s"
-#: ../../include/channel.php:1645
-msgid "Sexual Preference:"
-msgstr "Сексуальные предпочтения:"
+#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:14
+msgid "Send your identity to all websites"
+msgstr "Отправить ваши данные на все веб-сайты"
-#: ../../include/channel.php:1651
-msgid "Political Views:"
-msgstr "Политические взгляды:"
+#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:20
+msgid "Sendzid App"
+msgstr "Приложение \"Отправить ZID\""
-#: ../../include/channel.php:1653
-msgid "Religion:"
-msgstr "Религия:"
+#: ../../extend/addon/hzaddons/sendzid/Mod_Sendzid.php:32
+msgid "Send ZID"
+msgstr "Отправить ZID"
-#: ../../include/channel.php:1657
-msgid "Hobbies/Interests:"
-msgstr "Хобби / интересы:"
+#: ../../extend/addon/hzaddons/wholikesme/wholikesme.php:29
+msgid "Who likes me?"
+msgstr "Кому я нравлюсь?"
-#: ../../include/channel.php:1659
-msgid "Likes:"
-msgstr "Что вам нравится:"
+#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:73
+msgid "Max queueworker threads"
+msgstr "Макс. количество обработчиков очереди"
-#: ../../include/channel.php:1661
-msgid "Dislikes:"
-msgstr "Что вам не нравится:"
+#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:87
+msgid "Assume workers dead after ___ seconds"
+msgstr "Считать обработчики неактивными через секунд"
-#: ../../include/channel.php:1663
-msgid "Contact information and Social Networks:"
-msgstr "Контактная информация и социальные сети:"
+#: ../../extend/addon/hzaddons/queueworker/Mod_Queueworker.php:99
+msgid "Queueworker Settings"
+msgstr "Настройки обработчика очереди"
-#: ../../include/channel.php:1665
-msgid "My other channels:"
-msgstr "Мои другие каналы:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:19
+msgid "lonely"
+msgstr "одинокий"
-#: ../../include/channel.php:1667
-msgid "Musical interests:"
-msgstr "Музыкальные интересы:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:20
+msgid "drunk"
+msgstr "пьяный"
-#: ../../include/channel.php:1669
-msgid "Books, literature:"
-msgstr "Книги, литература:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:21
+msgid "horny"
+msgstr "возбуждённый"
-#: ../../include/channel.php:1671
-msgid "Television:"
-msgstr "Телевидение:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:22
+msgid "stoned"
+msgstr "под кайфом"
-#: ../../include/channel.php:1673
-msgid "Film/dance/culture/entertainment:"
-msgstr "Кино / танцы / культура / развлечения:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:23
+msgid "fucked up"
+msgstr "облажался"
-#: ../../include/channel.php:1675
-msgid "Love/Romance:"
-msgstr "Любовь / романтика:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:24
+msgid "clusterfucked"
+msgstr "в полной заднице"
-#: ../../include/channel.php:1677
-msgid "Work/employment:"
-msgstr "Работа / занятость:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:25
+msgid "crazy"
+msgstr "сумасшедший"
-#: ../../include/channel.php:1679
-msgid "School/education:"
-msgstr "Школа / образование:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:26
+msgid "hurt"
+msgstr "обиженный"
-#: ../../include/channel.php:1702
-msgid "Like this thing"
-msgstr "нравится этo"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:27
+msgid "sleepy"
+msgstr "сонный"
-#: ../../include/event.php:28 ../../include/event.php:75
-msgid "l F d, Y \\@ g:i A"
-msgstr ""
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:28
+msgid "grumpy"
+msgstr "сердитый"
-#: ../../include/event.php:36 ../../include/event.php:79
-msgid "Starts:"
-msgstr "Начало:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:29
+msgid "high"
+msgstr "кайфует"
-#: ../../include/event.php:46 ../../include/event.php:83
-msgid "Finishes:"
-msgstr "Окончание:"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:30
+msgid "semi-conscious"
+msgstr "в полубезсознании"
-#: ../../include/event.php:1020
-msgid "This event has been added to your calendar."
-msgstr "Это событие было добавлено в ваш календарь."
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:31
+msgid "in love"
+msgstr "влюблённый"
-#: ../../include/event.php:1239
-msgid "Not specified"
-msgstr "Не указано"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:32
+msgid "in lust"
+msgstr "похотливый"
-#: ../../include/event.php:1240
-msgid "Needs Action"
-msgstr "Требует действия"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:33
+msgid "naked"
+msgstr "обнажённый"
-#: ../../include/event.php:1241
-msgid "Completed"
-msgstr "Завершено"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:34
+msgid "stinky"
+msgstr "вонючий"
-#: ../../include/event.php:1242
-msgid "In Process"
-msgstr "В процессе"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:35
+msgid "sweaty"
+msgstr "потный"
-#: ../../include/event.php:1243
-msgid "Cancelled"
-msgstr "Отменено"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:36
+msgid "bleeding out"
+msgstr "истекающий кровью"
-#: ../../include/event.php:1322 ../../include/connections.php:698
-msgid "Home, Voice"
-msgstr "Дом, голос"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:37
+msgid "victorious"
+msgstr "победивший"
-#: ../../include/event.php:1323 ../../include/connections.php:699
-msgid "Home, Fax"
-msgstr "Дом, факс"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:38
+msgid "defeated"
+msgstr "проигравший"
-#: ../../include/event.php:1325 ../../include/connections.php:701
-msgid "Work, Voice"
-msgstr "Работа, голос"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:39
+msgid "envious"
+msgstr "завидует"
-#: ../../include/event.php:1326 ../../include/connections.php:702
-msgid "Work, Fax"
-msgstr "Работа, факс"
+#: ../../extend/addon/hzaddons/moremoods/moremoods.php:40
+msgid "jealous"
+msgstr "ревнует"
-#: ../../include/network.php:1718
-msgid "GNU-Social"
-msgstr ""
+#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:21
+msgid "Who viewed my channel/profile"
+msgstr "Кто смотрел мой канал / профиль"
-#: ../../include/network.php:1719
-msgid "RSS/Atom"
-msgstr ""
+#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:25
+msgid "Recent Channel/Profile Viewers"
+msgstr "Последние просмотры канала / профиля"
-#: ../../include/network.php:1723
-msgid "Facebook"
-msgstr ""
+#: ../../extend/addon/hzaddons/visage/Mod_Visage.php:36
+msgid "No entries."
+msgstr "Нет записей."
-#: ../../include/network.php:1725
-msgid "LinkedIn"
-msgstr ""
+#: ../../extend/addon/hzaddons/irc/irc.php:37
+msgid "Channels to auto connect"
+msgstr "Каналы для автоматического подключения"
-#: ../../include/network.php:1726
-msgid "XMPP/IM"
-msgstr ""
+#: ../../extend/addon/hzaddons/irc/irc.php:37
+#: ../../extend/addon/hzaddons/irc/irc.php:41
+msgid "Comma separated list"
+msgstr "Список, разделённый запятыми"
-#: ../../include/network.php:1727
-msgid "MySpace"
-msgstr ""
+#: ../../extend/addon/hzaddons/irc/irc.php:41
+#: ../../extend/addon/hzaddons/irc/Mod_Irc.php:23
+msgid "Popular Channels"
+msgstr "Популярные каналы"
-#: ../../include/language.php:436
-msgid "Select an alternate language"
-msgstr "Выбор дополнительного языка"
+#: ../../extend/addon/hzaddons/irc/irc.php:45
+msgid "IRC Settings"
+msgstr "Настройки IRC"
-#: ../../include/acl_selectors.php:113
-msgid "Who can see this?"
-msgstr "Кто может это видеть?"
+#: ../../extend/addon/hzaddons/irc/irc.php:54
+msgid "IRC settings saved."
+msgstr "Настройки IRC сохранены"
-#: ../../include/acl_selectors.php:114
-msgid "Custom selection"
-msgstr "Настраиваемый выбор"
+#: ../../extend/addon/hzaddons/irc/irc.php:58
+msgid "IRC Chatroom"
+msgstr "Чат IRC"
-#: ../../include/acl_selectors.php:115
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:44
msgid ""
-"Select \"Show\" to allow viewing. \"Don't show\" lets you override and limit "
-"the scope of \"Show\"."
-msgstr "Нажмите \"Показать\" чтобы разрешить просмотр. \"Не показывать\" позволит вам переопределить и ограничить область показа."
-
-#: ../../include/acl_selectors.php:116
-msgid "Show"
-msgstr "Показать"
-
-#: ../../include/acl_selectors.php:117
-msgid "Don't show"
-msgstr "Не показывать"
+"This is a fairly comprehensive and complete guitar chord dictionary which "
+"will list most of the available ways to play a certain chord, starting from "
+"the base of the fingerboard up to a few frets beyond the twelfth fret "
+"(beyond which everything repeats). A couple of non-standard tunings are "
+"provided for the benefit of slide players, etc."
+msgstr ""
-#: ../../include/acl_selectors.php:150
-#, php-format
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:46
msgid ""
-"Post permissions %s cannot be changed %s after a post is shared.</br />These "
-"permissions set who is allowed to view the post."
-msgstr "Разрешения публикации %s не могут быть изменены %s после того, как ею поделились. Эти разрешения устанавливают кому разрешено просматривать эту публикацию."
-
-#: ../../include/bbcode.php:200 ../../include/bbcode.php:1190
-#: ../../include/bbcode.php:1193 ../../include/bbcode.php:1198
-#: ../../include/bbcode.php:1201 ../../include/bbcode.php:1204
-#: ../../include/bbcode.php:1207 ../../include/bbcode.php:1212
-#: ../../include/bbcode.php:1215 ../../include/bbcode.php:1220
-#: ../../include/bbcode.php:1223 ../../include/bbcode.php:1226
-#: ../../include/bbcode.php:1229
-msgid "Image/photo"
-msgstr "Изображение / фотография"
-
-#: ../../include/bbcode.php:239 ../../include/bbcode.php:1240
-msgid "Encrypted content"
-msgstr "Зашифрованное содержание"
-
-#: ../../include/bbcode.php:255
-#, php-format
-msgid "Install %1$s element %2$s"
-msgstr "Установить %1$s элемент %2$s"
+"Chord names start with a root note (A-G) and may include sharps (#) and "
+"flats (b). This software will parse most of the standard naming conventions "
+"such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."
+msgstr ""
-#: ../../include/bbcode.php:259
-#, php-format
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:48
msgid ""
-"This post contains an installable %s element, however you lack permissions "
-"to install it on this site."
-msgstr "Эта публикация содержит устанавливаемый %s элемент, однако у вас нет разрешений для его установки на этом сайте."
-
-#: ../../include/bbcode.php:339
-msgid "card"
-msgstr "карточка"
-
-#: ../../include/bbcode.php:341
-msgid "article"
-msgstr "статья"
-
-#: ../../include/bbcode.php:424 ../../include/bbcode.php:432
-msgid "Click to open/close"
-msgstr "Нажмите, чтобы открыть/закрыть"
-
-#: ../../include/bbcode.php:432
-msgid "spoiler"
-msgstr "спойлер"
-
-#: ../../include/bbcode.php:445
-msgid "View article"
-msgstr "Просмотр статьи"
-
-#: ../../include/bbcode.php:445
-msgid "View summary"
-msgstr "Просмотр резюме"
-
-#: ../../include/bbcode.php:1178
-msgid "$1 wrote:"
-msgstr "$1 писал:"
-
-#: ../../include/oembed.php:226
-msgid "View PDF"
-msgstr "Просмотреть PDF"
-
-#: ../../include/oembed.php:356
-msgid " by "
-msgstr " по "
-
-#: ../../include/oembed.php:357
-msgid " on "
-msgstr " на "
-
-#: ../../include/oembed.php:386
-msgid "Embedded content"
-msgstr "Встроенное содержимое"
-
-#: ../../include/oembed.php:395
-msgid "Embedding disabled"
-msgstr "Встраивание отключено"
-
-#: ../../include/zid.php:351
-#, php-format
-msgid "OpenWebAuth: %1$s welcomes %2$s"
-msgstr "OpenWebAuth: %1$s приветствует %2$s"
-
-#: ../../include/features.php:86 ../../include/features.php:273
-msgid "Start calendar week on Monday"
-msgstr "Начинать календарную неделю с понедельника"
-
-#: ../../include/features.php:87 ../../include/features.php:274
-msgid "Default is Sunday"
-msgstr "По умолчанию - воскресенье"
-
-#: ../../include/features.php:100
-msgid "Search by Date"
-msgstr "Поиск по дате"
-
-#: ../../include/features.php:101
-msgid "Ability to select posts by date ranges"
-msgstr "Возможность выбора сообщений по диапазонам дат"
-
-#: ../../include/features.php:108
-msgid "Tag Cloud"
-msgstr "Облако тегов"
-
-#: ../../include/features.php:109
-msgid "Provide a personal tag cloud on your channel page"
-msgstr "Показывает личное облако тегов на странице канала"
-
-#: ../../include/features.php:116 ../../include/features.php:373
-msgid "Use blog/list mode"
-msgstr "Использовать режим блога / списка"
-
-#: ../../include/features.php:117 ../../include/features.php:374
-msgid "Comments will be displayed separately"
-msgstr "Комментарии будут отображаться отдельно"
-
-#: ../../include/features.php:129
-msgid "Connection Filtering"
-msgstr "Фильтрация контактов"
-
-#: ../../include/features.php:130
-msgid "Filter incoming posts from connections based on keywords/content"
-msgstr "Фильтр входящих сообщений от контактов на основе ключевых слов / контента"
-
-#: ../../include/features.php:138
-msgid "Conversation"
-msgstr "Диалоги"
-
-#: ../../include/features.php:142
-msgid "Community Tagging"
-msgstr "Отметки сообщества"
-
-#: ../../include/features.php:143
-msgid "Ability to tag existing posts"
-msgstr "Возможность помечать тегами существующие публикации"
+"Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, "
+"E7b13b11 ..."
+msgstr "Примеры действительных включают A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ..."
-#: ../../include/features.php:150
-msgid "Emoji Reactions"
-msgstr "Реакции Emoji"
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:51
+msgid "Guitar Chords"
+msgstr "Гитарные аккорды"
-#: ../../include/features.php:151
-msgid "Add emoji reaction ability to posts"
-msgstr "Возможность добавлять реакции Emoji к публикациям"
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:52
+msgid "The complete online chord dictionary"
+msgstr "Полный онлайн словарь аккордов"
-#: ../../include/features.php:158
-msgid "Dislike Posts"
-msgstr "Не нравящиеся публикации"
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:57
+msgid "Tuning"
+msgstr "Настройка"
-#: ../../include/features.php:159
-msgid "Ability to dislike posts/comments"
-msgstr "Возможность отмечать не нравящиеся публикации / комментарии"
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:58
+msgid "Chord name: example: Em7"
+msgstr "Наименование аккорда - example: Em7"
-#: ../../include/features.php:166
-msgid "Star Posts"
-msgstr "Помечать сообщения"
+#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:59
+msgid "Show for left handed stringing"
+msgstr "Показывать струны для левшей"
-#: ../../include/features.php:167
-msgid "Ability to mark special posts with a star indicator"
-msgstr "Возможность отметить специальные сообщения индикатором-звёздочкой"
+#: ../../extend/addon/hzaddons/chords/chords.php:33
+msgid "Quick Reference"
+msgstr "Быстрая ссылка"
-#: ../../include/features.php:180
-msgid "Advanced Directory Search"
-msgstr "Расширенный поиск в каталоге"
+#: ../../extend/addon/hzaddons/libertree/libertree.php:43
+msgid "Post to Libertree"
+msgstr "Опубликовать в Libertree"
-#: ../../include/features.php:181
-msgid "Allows creation of complex directory search queries"
-msgstr "Позволяет создание сложных поисковых запросов в каталоге"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:25
+msgid "Libertree Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Libertree сохранены."
-#: ../../include/features.php:190
-msgid "Editor"
-msgstr "Редактор"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:35
+msgid "Libertree Crosspost Connector App"
+msgstr "Приложение \"Пересылка публикаций Libertree\""
-#: ../../include/features.php:194
-msgid "Post Categories"
-msgstr "Категории публикаций"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:36
+msgid "Relay public posts to Libertree"
+msgstr "Пересылает общедоступные публикации в Libertree"
-#: ../../include/features.php:195
-msgid "Add categories to your posts"
-msgstr "Добавить категории для ваших публикаций"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:51
+msgid "Libertree API token"
+msgstr "Токен Libertree API"
-#: ../../include/features.php:203
-msgid "Large Photos"
-msgstr "Большие фотографии"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:55
+msgid "Libertree site URL"
+msgstr "URL сайта Libertree"
-#: ../../include/features.php:204
-msgid ""
-"Include large (1024px) photo thumbnails in posts. If not enabled, use small "
-"(640px) photo thumbnails"
-msgstr "Включить большие (1024px) миниатюры изображений в публикациях. Если не включено, использовать маленькие (640px) миниатюры."
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:59
+msgid "Post to Libertree by default"
+msgstr "Публиковать в Libertree по умолчанию"
-#: ../../include/features.php:211
-msgid "Even More Encryption"
-msgstr "Еще больше шифрования"
+#: ../../extend/addon/hzaddons/libertree/Mod_Libertree.php:67
+msgid "Libertree Crosspost Connector"
+msgstr "Пересылка публикаций Libertree"
-#: ../../include/features.php:212
-msgid ""
-"Allow optional encryption of content end-to-end with a shared secret key"
-msgstr "Разрешить дополнительное end-to-end шифрование содержимого с общим секретным ключом"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:24
+msgid "Channel is required."
+msgstr "Необходим канал."
-#: ../../include/features.php:219
-msgid "Enable Voting Tools"
-msgstr "Включить инструменты голосования"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:38
+msgid "Hubzilla Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Hubzilla сохранены."
-#: ../../include/features.php:220
-msgid "Provide a class of post which others can vote on"
-msgstr "Предоставь класс публикаций с возможностью голосования"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:51
+msgid "Relay public postings to another Hubzilla channel"
+msgstr "Пересылает общедоступные публикации в другой канал Hubzilla"
-#: ../../include/features.php:227
-msgid "Disable Comments"
-msgstr "Отключить комментарии"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
+msgid "Send public postings to Hubzilla channel by default"
+msgstr "Отправлять общедоступные публикации в канал Hubzilla по умолчанию"
-#: ../../include/features.php:228
-msgid "Provide the option to disable comments for a post"
-msgstr "Предоставить возможность отключать комментарии для публикаций"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67
+msgid "Hubzilla API Path"
+msgstr "Путь к Hubzilla API"
-#: ../../include/features.php:235
-msgid "Delayed Posting"
-msgstr "Задержанная публикация"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71
+msgid "Hubzilla login name"
+msgstr "Имя входа Hubzilla"
-#: ../../include/features.php:236
-msgid "Allow posts to be published at a later date"
-msgstr "Разрешить размешать публикации следующими датами"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75
+msgid "Hubzilla channel name"
+msgstr "Название канала Hubzilla"
-#: ../../include/features.php:243
-msgid "Content Expiration"
-msgstr "Истечение срока действия содержимого"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:87
+msgid "Hubzilla Crosspost Connector"
+msgstr "Пересылка публикаций Hubzilla"
-#: ../../include/features.php:244
-msgid "Remove posts/comments and/or private messages at a future time"
-msgstr "Удалять публикации / комментарии и / или личные сообщения"
+#: ../../extend/addon/hzaddons/redred/redred.php:50
+msgid "Post to Hubzilla"
+msgstr "Опубликовать в Hubzilla"
-#: ../../include/features.php:251
-msgid "Suppress Duplicate Posts/Comments"
-msgstr "Подавлять дублирующие публикации / комментарии"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:25
+msgid "ActivityPub Protocol Settings updated."
+msgstr "Настройки протокола ActivityPub обновлены."
-#: ../../include/features.php:252
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:34
msgid ""
-"Prevent posts with identical content to be published with less than two "
-"minutes in between submissions."
-msgstr "Предотвращает появление публикаций с одинаковым содержимым если интервал между ними менее 2 минут"
-
-#: ../../include/features.php:259
-msgid "Auto-save drafts of posts and comments"
-msgstr "Автоматически сохранять черновики публикаций и комментариев"
+"The activitypub protocol does not support location independence. Connections "
+"you make within that network may be unreachable from alternate channel "
+"locations."
+msgstr "Протокол ActivityPub не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
-#: ../../include/features.php:260
-msgid ""
-"Automatically saves post and comment drafts in local browser storage to help "
-"prevent accidental loss of compositions"
-msgstr "Автоматически сохраняет черновики публикаций и комментариев в локальном хранилище браузера для предотвращения их случайной утраты"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:40
+msgid "Activitypub Protocol App"
+msgstr "Приложение \"Протокол ActivityPub\""
-#: ../../include/features.php:281
-msgid "Smart Birthdays"
-msgstr "\"Умные\" Дни рождений"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50
+msgid "Deliver to ActivityPub recipients in privacy groups"
+msgstr "Доставить получателям ActivityPub в группах безопасности"
-#: ../../include/features.php:282
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:50
msgid ""
-"Make birthday events timezone aware in case your friends are scattered "
-"across the planet."
-msgstr "Сделать уведомления о днях рождения зависимыми от часового пояса в том случае, если ваши друзья разбросаны по планете."
-
-#: ../../include/features.php:289
-msgid "Event Timezone Selection"
-msgstr "Выбор часового пояса события"
-
-#: ../../include/features.php:290
-msgid "Allow event creation in timezones other than your own."
-msgstr "Разрешить создание события в часовой зоне отличной от вашей"
-
-#: ../../include/features.php:299
-msgid "Manage"
-msgstr "Управление"
+"May result in a large number of mentions and expose all the members of your "
+"privacy group"
+msgstr "Может привести к большому количеству упоминаний и раскрытию участников группы безопасности"
-#: ../../include/features.php:303
-msgid "Navigation Channel Select"
-msgstr "Выбор канала навигации"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54
+msgid "Send multi-media HTML articles"
+msgstr "Отправить HTML статьи с мультимедиа"
-#: ../../include/features.php:304
-msgid "Change channels directly from within the navigation dropdown menu"
-msgstr "Изменить канал напрямую из выпадающего меню"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:54
+msgid "Not supported by some microblog services such as Mastodon"
+msgstr "Не поддерживается некоторыми микроблогами, например Mastodon"
-#: ../../include/features.php:318
-msgid "Save search terms for re-use"
-msgstr "Сохранять результаты поиска для повторного использования"
+#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:62
+msgid "Activitypub Protocol"
+msgstr "Протокол ActivityPub"
-#: ../../include/features.php:326
-msgid "Ability to file posts under folders"
-msgstr "Возможность размещать публикации в каталогах"
+#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:18
+msgid "No username found in import file."
+msgstr "Имя пользователя не найдено в файле для импорта."
-#: ../../include/features.php:333
-msgid "Alternate Stream Order"
-msgstr "Отображение потока"
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:42
+msgid "Diaspora Protocol Settings updated."
+msgstr "Настройки протокола Diaspora обновлены."
-#: ../../include/features.php:334
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:51
msgid ""
-"Ability to order the stream by last post date, last comment date or "
-"unthreaded activities"
-msgstr "Возможность показывать поток по дате последнего сообщения, последнего комментария или в порядке поступления"
-
-#: ../../include/features.php:341
-msgid "Contact Filter"
-msgstr "Фильтр контактов"
-
-#: ../../include/features.php:342
-msgid "Ability to display only posts of a selected contact"
-msgstr "Возможность показа публикаций только от выбранных контактов"
-
-#: ../../include/features.php:349
-msgid "Forum Filter"
-msgstr "Фильтр по форумам"
-
-#: ../../include/features.php:350
-msgid "Ability to display only posts of a specific forum"
-msgstr "Возможность показа публикаций только определённого форума"
-
-#: ../../include/features.php:357
-msgid "Personal Posts Filter"
-msgstr "Персональный фильтр публикаций"
-
-#: ../../include/features.php:358
-msgid "Ability to display only posts that you've interacted on"
-msgstr "Возможность показа только тех публикаций с которыми вы взаимодействовали"
-
-#: ../../include/features.php:366
-msgid "Show friend and connection suggestions"
-msgstr "Показать предложения в друзья"
-
-#: ../../include/features.php:387
-msgid "Photo Location"
-msgstr "Местоположение фотографии"
-
-#: ../../include/features.php:388
-msgid "If location data is available on uploaded photos, link this to a map."
-msgstr "Если данные о местоположении доступны на загруженных фотографий, связать их с картой."
-
-#: ../../include/features.php:401
-msgid "Advanced Profiles"
-msgstr "Расширенные профили"
-
-#: ../../include/features.php:402
-msgid "Additional profile sections and selections"
-msgstr "Дополнительные секции и выборы профиля"
-
-#: ../../include/features.php:409
-msgid "Profile Import/Export"
-msgstr "Импорт / экспорт профиля"
-
-#: ../../include/features.php:410
-msgid "Save and load profile details across sites/channels"
-msgstr "Сохранение и загрузка настроек профиля на всех сайтах / каналах"
-
-#: ../../include/features.php:417
-msgid "Multiple Profiles"
-msgstr "Несколько профилей"
-
-#: ../../include/features.php:418
-msgid "Ability to create multiple profiles"
-msgstr "Возможность создания нескольких профилей"
-
-#: ../../include/taxonomy.php:320
-msgid "Trending"
-msgstr "В тренде"
-
-#: ../../include/taxonomy.php:552
-msgid "Keywords"
-msgstr "Ключевые слова"
-
-#: ../../include/taxonomy.php:573
-msgid "have"
-msgstr "иметь"
-
-#: ../../include/taxonomy.php:573
-msgid "has"
-msgstr "есть"
-
-#: ../../include/taxonomy.php:574
-msgid "want"
-msgstr "хотеть"
-
-#: ../../include/taxonomy.php:574
-msgid "wants"
-msgstr "хотеть"
-
-#: ../../include/taxonomy.php:575
-msgid "likes"
-msgstr "нравится"
-
-#: ../../include/taxonomy.php:576
-msgid "dislikes"
-msgstr "не нравится"
-
-#: ../../include/account.php:36
-msgid "Not a valid email address"
-msgstr "Недействительный адрес электронной почты"
-
-#: ../../include/account.php:38
-msgid "Your email domain is not among those allowed on this site"
-msgstr "Домен электронной почты не входит в число тех, которые разрешены на этом сайте"
-
-#: ../../include/account.php:44
-msgid "Your email address is already registered at this site."
-msgstr "Ваш адрес электронной почты уже зарегистрирован на этом сайте."
-
-#: ../../include/account.php:76
-msgid "An invitation is required."
-msgstr "Требуется приглашение."
-
-#: ../../include/account.php:80
-msgid "Invitation could not be verified."
-msgstr "Не удалось проверить приглашение."
-
-#: ../../include/account.php:158
-msgid "Please enter the required information."
-msgstr "Пожалуйста, введите необходимую информацию."
+"The diaspora protocol does not support location independence. Connections "
+"you make within that network may be unreachable from alternate channel "
+"locations."
+msgstr "Протокол Diaspora не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала."
-#: ../../include/account.php:225
-msgid "Failed to store account information."
-msgstr "Не удалось сохранить информацию аккаунта."
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:57
+msgid "Diaspora Protocol App"
+msgstr "Приложение \"Протокол Diaspora\""
-#: ../../include/account.php:314
-#, php-format
-msgid "Registration confirmation for %s"
-msgstr "Подтверждение регистрации на %s"
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:74
+msgid "Allow any Diaspora member to comment on your public posts"
+msgstr "Разрешить любому участнику Diaspora комментировать ваши общедоступные публикации"
-#: ../../include/account.php:385
-#, php-format
-msgid "Registration request at %s"
-msgstr "Запрос регистрации на %s"
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:78
+msgid "Prevent your hashtags from being redirected to other sites"
+msgstr "Предотвратить перенаправление тегов на другие сайты"
-#: ../../include/account.php:407
-msgid "your registration password"
-msgstr "ваш пароль регистрации"
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:82
+msgid "Sign and forward posts and comments with no existing Diaspora signature"
+msgstr "Подписывать и отправлять публикации и комментарии с несуществующей подписью Diaspora"
-#: ../../include/account.php:413 ../../include/account.php:475
-#, php-format
-msgid "Registration details for %s"
-msgstr "Регистрационные данные для %s"
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:87
+msgid "Followed hashtags (comma separated, do not include the #)"
+msgstr "Отслеживаемые теги (через запятую, исключая #)"
-#: ../../include/account.php:486
-msgid "Account approved."
-msgstr "Аккаунт утвержден."
+#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:96
+msgid "Diaspora Protocol"
+msgstr "Протокол Diaspora"
-#: ../../include/account.php:526
+#: ../../extend/addon/hzaddons/diaspora/Receiver.php:1509
#, php-format
-msgid "Registration revoked for %s"
-msgstr "Регистрация отозвана для %s"
-
-#: ../../include/account.php:805 ../../include/account.php:807
-msgid "Click here to upgrade."
-msgstr "Нажмите здесь для обновления."
-
-#: ../../include/account.php:813
-msgid "This action exceeds the limits set by your subscription plan."
-msgstr "Это действие превышает ограничения, установленные в вашем плане."
+msgid "%1$s dislikes %2$s's %3$s"
+msgstr "%1$s не нравится %2$s's %3$s"
-#: ../../include/account.php:818
-msgid "This action is not available under your subscription plan."
-msgstr "Это действие невозможно из-за ограничений в вашем плане."
+#: ../../extend/addon/hzaddons/wppost/wppost.php:46
+msgid "Post to WordPress"
+msgstr "Опубликовать в WordPress"
-#: ../../include/datetime.php:140
-msgid "Birthday"
-msgstr "День рождения"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:28
+msgid "Wordpress Settings saved."
+msgstr "Настройки WordPress сохранены."
-#: ../../include/datetime.php:140
-msgid "Age: "
-msgstr "Возраст:"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:41
+msgid "Wordpress Post App"
+msgstr "Приложение \"Публикация в Wordpress\""
-#: ../../include/datetime.php:140
-msgid "YYYY-MM-DD or MM-DD"
-msgstr "YYYY-MM-DD или MM-DD"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:42
+msgid "Post to WordPress or anything else which uses the wordpress XMLRPC API"
+msgstr "Опубликовать в WordPress или в чём-то ещё, поддерживающем wordpress XMLRPC API"
-#: ../../include/datetime.php:244
-msgid "less than a second ago"
-msgstr "менее чем одну секунду"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:65
+msgid "WordPress username"
+msgstr "Имя пользователя WordPress"
-#: ../../include/datetime.php:262
-#, php-format
-msgctxt "e.g. 22 hours ago, 1 minute ago"
-msgid "%1$d %2$s ago"
-msgstr "%1$d %2$s назад"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:69
+msgid "WordPress password"
+msgstr "Пароль WordPress"
-#: ../../include/datetime.php:273
-msgctxt "relative_date"
-msgid "year"
-msgid_plural "years"
-msgstr[0] "год"
-msgstr[1] "года"
-msgstr[2] "лет"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:73
+msgid "WordPress API URL"
+msgstr "URL API WordPress"
-#: ../../include/datetime.php:276
-msgctxt "relative_date"
-msgid "month"
-msgid_plural "months"
-msgstr[0] "месяц"
-msgstr[1] "месяца"
-msgstr[2] "месяцев"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:74
+msgid "Typically https://your-blog.tld/xmlrpc.php"
+msgstr "Обычно https://your-blog.tld/xmlrpc.php"
-#: ../../include/datetime.php:279
-msgctxt "relative_date"
-msgid "week"
-msgid_plural "weeks"
-msgstr[0] "неделю"
-msgstr[1] "недели"
-msgstr[2] "недель"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:77
+msgid "WordPress blogid"
+msgstr ""
-#: ../../include/datetime.php:282
-msgctxt "relative_date"
-msgid "day"
-msgid_plural "days"
-msgstr[0] "день"
-msgstr[1] "дня"
-msgstr[2] "дней"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:78
+msgid "For multi-user sites such as wordpress.com, otherwise leave blank"
+msgstr "Для многопользовательских сайтов, таких, как wordpress.com. В противном случае оставьте пустым"
-#: ../../include/datetime.php:285
-msgctxt "relative_date"
-msgid "hour"
-msgid_plural "hours"
-msgstr[0] "час"
-msgstr[1] "часа"
-msgstr[2] "часов"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82
+msgid "Post to WordPress by default"
+msgstr "Публиковать в WordPress по умолчанию"
-#: ../../include/datetime.php:288
-msgctxt "relative_date"
-msgid "minute"
-msgid_plural "minutes"
-msgstr[0] "минуту"
-msgstr[1] "минуты"
-msgstr[2] "минут"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86
+msgid "Forward comments (requires hubzilla_wp plugin)"
+msgstr "Пересылать комментарии (требуется плагин hubzilla_wp)"
-#: ../../include/datetime.php:291
-msgctxt "relative_date"
-msgid "second"
-msgid_plural "seconds"
-msgstr[0] "секунду"
-msgstr[1] "секунды"
-msgstr[2] "секунд"
+#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:94
+msgid "Wordpress Post"
+msgstr "Публикация в WordPress"
-#: ../../include/datetime.php:520
-#, php-format
-msgid "%1$s's birthday"
-msgstr "У %1$s День рождения"
+#: ../../extend/addon/hzaddons/nsfw/nsfw.php:152
+msgid "Possible adult content"
+msgstr "Возможно содержимое для взрослых"
-#: ../../include/datetime.php:521
+#: ../../extend/addon/hzaddons/nsfw/nsfw.php:167
#, php-format
-msgid "Happy Birthday %1$s"
-msgstr "С Днем рождения %1$s !"
-
-#: ../../include/nav.php:86
-msgid "Remote authentication"
-msgstr "Удаленная аутентификация"
-
-#: ../../include/nav.php:86
-msgid "Click to authenticate to your home hub"
-msgstr "Нажмите, чтобы аутентифицировать себя на домашнем узле"
-
-#: ../../include/nav.php:92
-msgid "Manage your channels"
-msgstr "Управление вашими каналами"
-
-#: ../../include/nav.php:95
-msgid "Manage your privacy groups"
-msgstr "Управление вашим группами безопасности"
-
-#: ../../include/nav.php:97
-msgid "Account/Channel Settings"
-msgstr "Настройки аккаунта / канала"
-
-#: ../../include/nav.php:103 ../../include/nav.php:132
-msgid "End this session"
-msgstr "Закончить эту сессию"
-
-#: ../../include/nav.php:106
-msgid "Your profile page"
-msgstr "Страницa вашего профиля"
-
-#: ../../include/nav.php:109
-msgid "Manage/Edit profiles"
-msgstr "Управление / редактирование профилей"
-
-#: ../../include/nav.php:118 ../../include/nav.php:122
-msgid "Sign in"
-msgstr "Войти"
-
-#: ../../include/nav.php:149
-msgid "Take me home"
-msgstr "Домой"
-
-#: ../../include/nav.php:151
-msgid "Log me out of this site"
-msgstr "Выйти с этого сайта"
-
-#: ../../include/nav.php:156
-msgid "Create an account"
-msgstr "Создать аккаунт"
-
-#: ../../include/nav.php:168
-msgid "Help and documentation"
-msgstr "Справочная информация и документация"
-
-#: ../../include/nav.php:183
-msgid "Search site @name, !forum, #tag, ?docs, content"
-msgstr "Искать на сайте @имя, !форум, #тег, ?документ, содержимое"
-
-#: ../../include/nav.php:189
-msgid "Site Setup and Configuration"
-msgstr "Установка и конфигурация сайта"
-
-#: ../../include/nav.php:329
-msgid "@name, !forum, #tag, ?doc, content"
-msgstr "@имя, !форум, #тег, ?документ, содержимое"
-
-#: ../../include/nav.php:330
-msgid "Please wait..."
-msgstr "Подождите пожалуйста ..."
-
-#: ../../include/nav.php:336
-msgid "Add Apps"
-msgstr "Добавить приложения"
-
-#: ../../include/nav.php:337
-msgid "Arrange Apps"
-msgstr "Упорядочить приложения"
-
-#: ../../include/nav.php:338
-msgid "Toggle System Apps"
-msgstr "Показать системные приложения"
+msgid "%s - view"
+msgstr "%s - просмотр"
-#: ../../include/nav.php:424
-msgid "Status Messages and Posts"
-msgstr "Статусы и публикации"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:22
+msgid "NSFW Settings saved."
+msgstr "Настройки NSFW сохранены."
-#: ../../include/nav.php:437
-msgid "Profile Details"
-msgstr "Информация о профиле"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:33
+msgid "NSFW App"
+msgstr "Приложение NSFW"
-#: ../../include/nav.php:447 ../../include/photos.php:669
-msgid "Photo Albums"
-msgstr "Фотоальбомы"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:34
+msgid "Collapse content that contains predefined words"
+msgstr "Свернуть содержимое, содержащее предопределенные слова"
-#: ../../include/nav.php:455
-msgid "Files and Storage"
-msgstr "Файлы и хранилище"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:44
+msgid ""
+"This app looks in posts for the words/text you specify below, and collapses "
+"any content containing those keywords so it is not displayed at "
+"inappropriate times, such as sexual innuendo that may be improper in a work "
+"setting. It is polite and recommended to tag any content containing nudity "
+"with #NSFW. This filter can also match any other word/text you specify, and "
+"can thereby be used as a general purpose content filter."
+msgstr "Это приложение просматривает публикации для слов / текста, которые вы указываете ниже, и сворачивает любой контент, содержащий эти ключевые слова, поэтому он не отображается в неподходящее время, например, сексуальные инсинуации, которые могут быть неправильными в настройке работы. Например, мы рекомендуем отмечать любой контент, содержащий наготу, тегом #NSFW. Этот фильтр также способен реагировать на любое другое указанное вами слово / текст и может использоваться в качестве фильтра содержимого общего назначения."
-#: ../../include/nav.php:493
-msgid "Saved Bookmarks"
-msgstr "Сохранённые закладки"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49
+msgid "Comma separated list of keywords to hide"
+msgstr "Список ключевых слов для скрытия, через запятую"
-#: ../../include/nav.php:504
-msgid "View Cards"
-msgstr "Просмотреть карточки"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:49
+msgid "Word, /regular-expression/, lang=xx, lang!=xx"
+msgstr "слово, /регулярное_выражение/, lang=xx, lang!=xx"
-#: ../../include/nav.php:515
-msgid "View Articles"
-msgstr "Просмотр статей"
+#: ../../extend/addon/hzaddons/nsfw/Mod_Nsfw.php:58
+msgid "NSFW"
+msgstr ""
-#: ../../include/nav.php:527
-msgid "View Webpages"
-msgstr "Просмотр веб-страниц"
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:32
+msgid "Skeleton App"
+msgstr "Приложение \"Скелет\""
-#: ../../include/photos.php:151
-#, php-format
-msgid "Image exceeds website size limit of %lu bytes"
-msgstr "Файл превышает предельный размер для сайта в %lu байт"
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:33
+msgid "A skeleton for addons, you can copy/paste"
+msgstr "Скелет для приложений. Вы можете использовать copy/paste"
-#: ../../include/photos.php:162
-msgid "Image file is empty."
-msgstr "Файл изображения пуст."
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40
+msgid "Some setting"
+msgstr "Некоторые настройки"
-#: ../../include/photos.php:327
-msgid "Photo storage failed."
-msgstr "Ошибка хранилища фотографий."
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:40
+msgid "A setting"
+msgstr "Настройка"
-#: ../../include/photos.php:376
-msgid "a new photo"
-msgstr "новая фотография"
+#: ../../extend/addon/hzaddons/skeleton/Mod_Skeleton.php:48
+msgid "Skeleton Settings"
+msgstr "Настройки скелета"
-#: ../../include/photos.php:380
+#: ../../extend/addon/hzaddons/opensearch/opensearch.php:26
#, php-format
-msgctxt "photo_upload"
-msgid "%1$s posted %2$s to %3$s"
-msgstr "%1$s опубликовал %2$s в %3$s"
-
-#: ../../include/photos.php:674
-msgid "Upload New Photos"
-msgstr "Загрузить новые фотографии"
-
-#: ../../include/zot.php:775
-msgid "Invalid data packet"
-msgstr "Неверный пакет данных"
-
-#: ../../include/zot.php:4288
-msgid "invalid target signature"
-msgstr "недопустимая целевая подпись"
-
-#: ../../include/connections.php:133
-msgid "New window"
-msgstr "Новое окно"
-
-#: ../../include/connections.php:134
-msgid "Open the selected location in a different window or browser tab"
-msgstr "Открыть выбранное местоположение в другом окне или вкладке браузера"
-
-#: ../../include/auth.php:192
-msgid "Delegation session ended."
-msgstr "Делегированная сессия завершена."
-
-#: ../../include/auth.php:196
-msgid "Logged out."
-msgstr "Вышел из системы."
-
-#: ../../include/auth.php:291
-msgid "Email validation is incomplete. Please check your email."
-msgstr "Проверка email не завершена. Пожалуйста, проверьте вашу почту."
-
-#: ../../include/auth.php:307
-msgid "Failed authentication"
-msgstr "Ошибка аутентификации"
+msgctxt "opensearch"
+msgid "Search %1$s (%2$s)"
+msgstr "Искать %1$s (%2$s)"
-#: ../../include/help.php:80
-msgid "Help:"
-msgstr "Помощь:"
+#: ../../extend/addon/hzaddons/opensearch/opensearch.php:28
+msgctxt "opensearch"
+msgid "$Projectname"
+msgstr ""
-#: ../../include/help.php:129
-msgid "Not Found"
-msgstr "Не найдено"
+#: ../../extend/addon/hzaddons/opensearch/opensearch.php:43
+msgid "Search $Projectname"
+msgstr "Поиск $Projectname"
diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php
index 79e5e9000..60bd744cc 100644
--- a/view/ru/hstrings.php
+++ b/view/ru/hstrings.php
@@ -6,96 +6,1062 @@ function string_plural_select_ru($n){
}}
App::$rtl = 0;
App::$strings["plural_function_code"] = "(n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))";
-App::$strings["Can view my channel stream and posts"] = "Может просматривать мой поток и сообщения";
-App::$strings["Can send me their channel stream and posts"] = "Может присылать мне свои потоки и сообщения";
-App::$strings["Can view my default channel profile"] = "Может просматривать мой стандартный профиль канала";
-App::$strings["Can view my connections"] = "Может просматривать мои контакты";
-App::$strings["Can view my file storage and photos"] = "Может просматривать мое хранилище файлов";
-App::$strings["Can upload/modify my file storage and photos"] = "Может загружать/изменять мои файлы и фотографии в хранилище";
-App::$strings["Can view my channel webpages"] = "Может просматривать мои веб-страницы";
-App::$strings["Can view my wiki pages"] = "Может просматривать мои вики-страницы";
-App::$strings["Can create/edit my channel webpages"] = "Может редактировать мои веб-страницы";
-App::$strings["Can write to my wiki pages"] = "Может редактировать мои вики-страницы";
-App::$strings["Can post on my channel (wall) page"] = "Может публиковать на моей странице канала";
-App::$strings["Can comment on or like my posts"] = "Может прокомментировать или отмечать как понравившиеся мои публикации";
-App::$strings["Can send me private mail messages"] = "Может отправлять мне личные сообщения по эл. почте";
-App::$strings["Can like/dislike profiles and profile things"] = "Может комментировать или отмечать как нравится/ненравится мой профиль";
-App::$strings["Can forward to all my channel connections via ! mentions in posts"] = "Может пересылать всем подписчикам моего канала используя ! в публикациях";
-App::$strings["Can chat with me"] = "Может общаться со мной в чате";
-App::$strings["Can source my public posts in derived channels"] = "Может использовать мои публичные сообщения в клонированных лентах сообщений";
-App::$strings["Can administer my channel"] = "Может администрировать мой канал";
-App::$strings["Social Networking"] = "Социальная Сеть";
-App::$strings["Social - Federation"] = "Социальная - Федерация";
-App::$strings["Social - Mostly Public"] = "Социальная - В основном общественный";
-App::$strings["Social - Restricted"] = "Социальная - Ограниченный";
-App::$strings["Social - Private"] = "Социальная - Частный";
-App::$strings["Community Forum"] = "Форум сообщества";
-App::$strings["Forum - Mostly Public"] = "Форум - В основном общественный";
-App::$strings["Forum - Restricted"] = "Форум - Ограниченный";
-App::$strings["Forum - Private"] = "Форум - Частный";
-App::$strings["Feed Republish"] = "Публиковать ленты новостей";
-App::$strings["Feed - Mostly Public"] = "Ленты новостей - В основном общественный";
-App::$strings["Feed - Restricted"] = "Ленты новостей - Ограниченный";
-App::$strings["Special Purpose"] = "Спец. назначение";
-App::$strings["Special - Celebrity/Soapbox"] = "Спец. назначение - Знаменитость/Soapbox";
-App::$strings["Special - Group Repository"] = "Спец. назначение - Групповой репозиторий";
+App::$strings["Source channel not found."] = "Канал-источник не найден.";
+App::$strings["Default"] = "По умолчанию";
+App::$strings["Focus (Hubzilla default)"] = "Фокус (по умолчанию Hubzilla)";
+App::$strings["Submit"] = "Отправить";
+App::$strings["Theme settings"] = "Настройки темы";
+App::$strings["Narrow navbar"] = "Узкая панель навигации";
+App::$strings["No"] = "Нет";
+App::$strings["Yes"] = "Да";
+App::$strings["Navigation bar background color"] = "Панель навигации, цвет фона";
+App::$strings["Navigation bar icon color "] = "Панель навигации, цвет значков";
+App::$strings["Navigation bar active icon color "] = "Панель навигации, цвет активного значка";
+App::$strings["Link color"] = "Цвет ссылок";
+App::$strings["Set font-color for banner"] = "Цвет текста в шапке";
+App::$strings["Set the background color"] = "Цвет фона";
+App::$strings["Set the background image"] = "Фоновое изображение";
+App::$strings["Set the background color of items"] = "Цвет фона элементов";
+App::$strings["Set the background color of comments"] = "Цвет фона комментариев";
+App::$strings["Set font-size for the entire application"] = "Установить системный размер шрифта";
+App::$strings["Examples: 1rem, 100%, 16px"] = "Например: 1rem, 100%, 16px";
+App::$strings["Set font-color for posts and comments"] = "Цвет шрифта для публикаций и комментариев";
+App::$strings["Set radius of corners"] = "Радиус скруглений";
+App::$strings["Example: 4px"] = "Например: 4px";
+App::$strings["Set shadow depth of photos"] = "Глубина теней фотографий";
+App::$strings["Set maximum width of content region in pixel"] = "Максимальная ширина содержания региона (в пикселях)";
+App::$strings["Leave empty for default width"] = "Оставьте пустым для ширины по умолчанию";
+App::$strings["Set size of conversation author photo"] = "Размер фотографии автора беседы";
+App::$strings["Set size of followup author photos"] = "Размер фотографий подписчиков";
+App::$strings["Show advanced settings"] = "Показать расширенные настройки";
+App::$strings["Profile to assign new connections"] = "Назначить профиль для новых контактов";
+App::$strings["Frequently"] = "Часто";
+App::$strings["Hourly"] = "Ежечасно";
+App::$strings["Twice daily"] = "Дважды в день";
+App::$strings["Daily"] = "Ежедневно";
+App::$strings["Weekly"] = "Еженедельно";
+App::$strings["Monthly"] = "Ежемесячно";
+App::$strings["Male"] = "Мужчина";
+App::$strings["Female"] = "Женщина";
+App::$strings["Currently Male"] = "В настоящее время мужской";
+App::$strings["Currently Female"] = "В настоящее время женский";
+App::$strings["Mostly Male"] = "В основном мужской";
+App::$strings["Mostly Female"] = "В основном женский";
+App::$strings["Transgender"] = "Трансгендер";
+App::$strings["Intersex"] = "Интерсексуал";
+App::$strings["Transsexual"] = "Транссексуал";
+App::$strings["Hermaphrodite"] = "Гермафродит";
+App::$strings["Neuter"] = "Среднего рода";
+App::$strings["Non-specific"] = "Неспецифический";
App::$strings["Other"] = "Другой";
-App::$strings["Custom/Expert Mode"] = "Экспертный режим";
-App::$strings["Requested profile is not available."] = "Запрашиваемый профиль не доступен.";
+App::$strings["Undecided"] = "Не решил";
+App::$strings["Males"] = "Мужчины";
+App::$strings["Females"] = "Женщины";
+App::$strings["Gay"] = "Гей";
+App::$strings["Lesbian"] = "Лесбиянка";
+App::$strings["No Preference"] = "Без предпочтений";
+App::$strings["Bisexual"] = "Бисексуал";
+App::$strings["Autosexual"] = "Автосексуал";
+App::$strings["Abstinent"] = "Воздержание";
+App::$strings["Virgin"] = "Девственник";
+App::$strings["Deviant"] = "Отклоняющийся от нормы";
+App::$strings["Fetish"] = "Фетишист";
+App::$strings["Oodles"] = "Множественный";
+App::$strings["Nonsexual"] = "Асексуал";
+App::$strings["Single"] = "Одиночка";
+App::$strings["Lonely"] = "Одинокий";
+App::$strings["Available"] = "Свободен";
+App::$strings["Unavailable"] = "Занят";
+App::$strings["Has crush"] = "Влюблён";
+App::$strings["Infatuated"] = "без ума";
+App::$strings["Dating"] = "Встречаюсь";
+App::$strings["Unfaithful"] = "Неверный";
+App::$strings["Sex Addict"] = "Эротоман";
+App::$strings["Friends"] = "Друзья";
+App::$strings["Friends/Benefits"] = "Друзья / Выгоды";
+App::$strings["Casual"] = "Легкомысленный";
+App::$strings["Engaged"] = "Помолвлен";
+App::$strings["Married"] = "В браке";
+App::$strings["Imaginarily married"] = "В воображаемом браке";
+App::$strings["Partners"] = "Партнёрство";
+App::$strings["Cohabiting"] = "Сожительствующие";
+App::$strings["Common law"] = "Гражданский брак";
+App::$strings["Happy"] = "Счастлив";
+App::$strings["Not looking"] = "Не нуждаюсь";
+App::$strings["Swinger"] = "Свингер";
+App::$strings["Betrayed"] = "Предан";
+App::$strings["Separated"] = "Разделён";
+App::$strings["Unstable"] = "Нестабильно";
+App::$strings["Divorced"] = "В разводе";
+App::$strings["Imaginarily divorced"] = "В воображаемом разводе";
+App::$strings["Widowed"] = "Вдовец / вдова";
+App::$strings["Uncertain"] = "Неопределенный";
+App::$strings["It's complicated"] = "Это сложно";
+App::$strings["Don't care"] = "Всё равно";
+App::$strings["Ask me"] = "Спроси меня";
App::$strings["Permission denied."] = "Доступ запрещен.";
-App::$strings["Block Name"] = "Название блока";
-App::$strings["Blocks"] = "Блокировки";
-App::$strings["Block Title"] = "Заблокировать заголовок";
-App::$strings["Created"] = "Создано";
-App::$strings["Edited"] = "Отредактировано";
-App::$strings["Create"] = "Создать";
+App::$strings["Image exceeds website size limit of %lu bytes"] = "Файл превышает предельный размер для сайта в %lu байт";
+App::$strings["Image file is empty."] = "Файл изображения пуст.";
+App::$strings["Unable to process image"] = "Не удается обработать изображение";
+App::$strings["Photo storage failed."] = "Ошибка хранилища фотографий.";
+App::$strings["a new photo"] = "новая фотография";
+App::$strings["__ctx:photo_upload__ %1\$s posted %2\$s to %3\$s"] = "%1\$s опубликовал %2\$s в %3\$s";
+App::$strings["Photo Albums"] = "Фотоальбомы";
+App::$strings["Recent Photos"] = "Последние фотографии";
+App::$strings["Upload New Photos"] = "Загрузить новые фотографии";
+App::$strings["View PDF"] = "Просмотреть PDF";
+App::$strings[" by "] = " из ";
+App::$strings[" on "] = " на ";
+App::$strings["Embedded content"] = "Встроенное содержимое";
+App::$strings["Embedding disabled"] = "Встраивание отключено";
+App::$strings["The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."] = "Не верный токен безопасности для формы. Вероятно, это произошло потому, что форма была открыта слишком долго (> 3-х часов) перед его отправкой.";
+App::$strings["%d invitation available"] = array(
+ 0 => "доступно %d приглашение",
+ 1 => "доступны %d приглашения",
+ 2 => "доступны %d приглашений",
+);
+App::$strings["Advanced"] = "Дополнительно";
+App::$strings["Find Channels"] = "Поиск каналов";
+App::$strings["Enter name or interest"] = "Впишите имя или интерес";
+App::$strings["Connect/Follow"] = "Подключить / отслеживать";
+App::$strings["Examples: Robert Morgenstein, Fishing"] = "Примеры: Владимир Ильич, Революционер";
+App::$strings["Find"] = "Поиск";
+App::$strings["Channel Suggestions"] = "Рекомендации каналов";
+App::$strings["Random Profile"] = "Случайный профиль";
+App::$strings["Invite Friends"] = "Пригласить друзей";
+App::$strings["Advanced example: name=fred and country=iceland"] = "Расширенный пример: name=ivan and country=russia";
+App::$strings["Saved Folders"] = "Сохранённые каталоги";
+App::$strings["Everything"] = "Всё";
+App::$strings["Categories"] = "Категории";
+App::$strings["Common Connections"] = "Общие контакты";
+App::$strings["View all %d common connections"] = "Просмотреть все %d общих контактов";
App::$strings["Edit"] = "Изменить";
-App::$strings["Share"] = "Поделиться";
+App::$strings["Unable to obtain identity information from database"] = "Невозможно получить идентификационную информацию из базы данных";
+App::$strings["Empty name"] = "Пустое имя";
+App::$strings["Name too long"] = "Слишком длинное имя";
+App::$strings["No account identifier"] = "Идентификатор аккаунта отсутствует";
+App::$strings["Nickname is required."] = "Требуется псевдоним.";
+App::$strings["Reserved nickname. Please choose another."] = "Зарезервированый псевдоним. Пожалуйста, выберите другой.";
+App::$strings["Nickname has unsupported characters or is already being used on this site."] = "Псевдоним имеет недопустимые символы или уже используется на этом сайте.";
+App::$strings["Unable to retrieve created identity"] = "Не удается получить созданный идентификатор";
+App::$strings["Default Profile"] = "Профиль по умолчанию";
+App::$strings["Unable to retrieve modified identity"] = "Не удается найти изменённый идентификатор";
+App::$strings["Requested channel is not available."] = "Запрошенный канал не доступен.";
+App::$strings["Requested profile is not available."] = "Запрашиваемый профиль не доступен.";
+App::$strings["Change profile photo"] = "Изменить фотографию профиля";
+App::$strings["Edit Profiles"] = "Редактирование профилей";
+App::$strings["Create New Profile"] = "Создать новый профиль";
+App::$strings["Edit Profile"] = "Редактировать профиль";
+App::$strings["Profile Image"] = "Изображение профиля";
+App::$strings["Visible to everybody"] = "Видно всем";
+App::$strings["Edit visibility"] = "Редактировать видимость";
+App::$strings["Connect"] = "Подключить";
+App::$strings["Location:"] = "Местоположение:";
+App::$strings["Gender:"] = "Пол:";
+App::$strings["Status:"] = "Статус:";
+App::$strings["Homepage:"] = "Домашняя страница:";
+App::$strings["Online Now"] = "Сейчас в сети";
+App::$strings["Change your profile photo"] = "Изменить фотографию вашего профиля";
+App::$strings["Trans"] = "Трансексуал";
+App::$strings["Full Name:"] = "Полное имя:";
+App::$strings["Like this channel"] = "нравится этот канал";
+App::$strings["__ctx:noun__ Like"] = array(
+ 0 => "Нравится",
+ 1 => "Нравится",
+ 2 => "Нравится",
+);
+App::$strings["j F, Y"] = "";
+App::$strings["j F"] = "";
+App::$strings["Birthday:"] = "День рождения:";
+App::$strings["Age:"] = "Возраст:";
+App::$strings["for %1\$d %2\$s"] = "для %1\$d %2\$s";
+App::$strings["Tags:"] = "Теги:";
+App::$strings["Sexual Preference:"] = "Сексуальные предпочтения:";
+App::$strings["Hometown:"] = "Родной город:";
+App::$strings["Political Views:"] = "Политические взгляды:";
+App::$strings["Religion:"] = "Религия:";
+App::$strings["About:"] = "О себе:";
+App::$strings["Hobbies/Interests:"] = "Хобби / интересы:";
+App::$strings["Likes:"] = "Что вам нравится:";
+App::$strings["Dislikes:"] = "Что вам не нравится:";
+App::$strings["Contact information and Social Networks:"] = "Контактная информация и социальные сети:";
+App::$strings["My other channels:"] = "Мои другие каналы:";
+App::$strings["Musical interests:"] = "Музыкальные интересы:";
+App::$strings["Books, literature:"] = "Книги, литература:";
+App::$strings["Television:"] = "Телевидение:";
+App::$strings["Film/dance/culture/entertainment:"] = "Кино / танцы / культура / развлечения:";
+App::$strings["Love/Romance:"] = "Любовь / романтика:";
+App::$strings["Work/employment:"] = "Работа / занятость:";
+App::$strings["School/education:"] = "Школа / образование:";
+App::$strings["Profile"] = "Профиль";
+App::$strings["Like this thing"] = "нравится этo";
+App::$strings["Export"] = "Экспорт";
+App::$strings["cover photo"] = "фотография обложки";
+App::$strings["Remote Authentication"] = "Удаленная аутентификация";
+App::$strings["Enter your channel address (e.g. channel@example.com)"] = "Введите адрес вашего канала (например: channel@example.com)";
+App::$strings["Authenticate"] = "Проверка подлинности";
+App::$strings["Account '%s' deleted"] = "Аккаунт '%s' удален";
+App::$strings["Download binary/encrypted content"] = "Загрузить двоичное / зашифрованное содержимое";
+App::$strings["Unable to determine sender."] = "Невозможно определить отправителя.";
+App::$strings["No recipient provided."] = "Получатель не предоставлен.";
+App::$strings["[no subject]"] = "[без темы]";
+App::$strings["Stored post could not be verified."] = "Сохранённая публикация не может быть проверена.";
+App::$strings["%1\$s wrote the following %2\$s %3\$s"] = "%1\$s была создана %2\$s %3\$s";
+App::$strings["post"] = "публикация";
+App::$strings["Permission denied"] = "Доступ запрещен";
+App::$strings["(Unknown)"] = "(Неизвестный)";
+App::$strings["Visible to anybody on the internet."] = "Виден всем в интернете.";
+App::$strings["Visible to you only."] = "Видно только вам.";
+App::$strings["Visible to anybody in this network."] = "Видно всем в этой сети.";
+App::$strings["Visible to anybody authenticated."] = "Видно всем аутентифицированным.";
+App::$strings["Visible to anybody on %s."] = "Видно всем в %s.";
+App::$strings["Visible to all connections."] = "Видно всем контактам.";
+App::$strings["Visible to approved connections."] = "Видно только одобренным контактам.";
+App::$strings["Visible to specific connections."] = "Видно указанным контактам.";
+App::$strings["Item not found."] = "Элемент не найден.";
+App::$strings["Privacy group not found."] = "Группа безопасности не найдена.";
+App::$strings["Privacy group is empty."] = "Группа безопасности пуста";
+App::$strings["Privacy group: %s"] = "Группа безопасности: %s";
+App::$strings["Connection: %s"] = "Контакт: %s";
+App::$strings["Connection not found."] = "Контакт не найден.";
+App::$strings["female"] = "женщина";
+App::$strings["%1\$s updated her %2\$s"] = "%1\$s обновила её %2\$s";
+App::$strings["male"] = "мужчина";
+App::$strings["%1\$s updated his %2\$s"] = "%1\$s обновил его %2\$s";
+App::$strings["%1\$s updated their %2\$s"] = "%2\$s %1\$s обновлена";
+App::$strings["profile photo"] = "Фотография профиля";
+App::$strings["[Edited %s]"] = "[Отредактировано %s]";
+App::$strings["__ctx:edit_activity__ Post"] = "Публикация";
+App::$strings["__ctx:edit_activity__ Comment"] = "Комментарий";
+App::$strings[" and "] = " и ";
+App::$strings["public profile"] = "общедоступный профиль";
+App::$strings["%1\$s changed %2\$s to &ldquo;%3\$s&rdquo;"] = "%1\$s изменил %2\$s на &ldquo;%3\$s&rdquo;";
+App::$strings["Visit %1\$s's %2\$s"] = "Посетить %1\$s %2\$s";
+App::$strings["%1\$s has an updated %2\$s, changing %3\$s."] = "%1\$s обновлено %2\$s, изменено %3\$s.";
+App::$strings["Off"] = "Выкл.";
+App::$strings["On"] = "Вкл.";
+App::$strings["CalDAV"] = "";
+App::$strings["Start calendar week on Monday"] = "Начинать календарную неделю с понедельника";
+App::$strings["Default is Sunday"] = "По умолчанию - воскресенье";
+App::$strings["Channel Home"] = "Главная канала";
+App::$strings["Search by Date"] = "Поиск по дате";
+App::$strings["Ability to select posts by date ranges"] = "Возможность выбора сообщений по диапазонам дат";
+App::$strings["Tag Cloud"] = "Облако тегов";
+App::$strings["Provide a personal tag cloud on your channel page"] = "Показывает личное облако тегов на странице канала";
+App::$strings["Use blog/list mode"] = "Использовать режим блога / списка";
+App::$strings["Comments will be displayed separately"] = "Комментарии будут отображаться отдельно";
+App::$strings["Connections"] = "Контакты";
+App::$strings["Connection Filtering"] = "Фильтрация контактов";
+App::$strings["Filter incoming posts from connections based on keywords/content"] = "Фильтр входящих сообщений от контактов на основе ключевых слов / контента";
+App::$strings["Conversation"] = "Диалоги";
+App::$strings["Community Tagging"] = "Отметки сообщества";
+App::$strings["Ability to tag existing posts"] = "Возможность помечать тегами существующие публикации";
+App::$strings["Emoji Reactions"] = "Реакции Emoji";
+App::$strings["Add emoji reaction ability to posts"] = "Возможность добавлять реакции Emoji к публикациям";
+App::$strings["Dislike Posts"] = "Не нравящиеся публикации";
+App::$strings["Ability to dislike posts/comments"] = "Возможность отмечать не нравящиеся публикации / комментарии";
+App::$strings["Star Posts"] = "Помечать сообщения";
+App::$strings["Ability to mark special posts with a star indicator"] = "Возможность отметить специальные сообщения индикатором-звёздочкой";
+App::$strings["Directory"] = "Каталог";
+App::$strings["Advanced Directory Search"] = "Расширенный поиск в каталоге";
+App::$strings["Allows creation of complex directory search queries"] = "Позволяет создание сложных поисковых запросов в каталоге";
+App::$strings["Editor"] = "Редактор";
+App::$strings["Post Categories"] = "Категории публикаций";
+App::$strings["Add categories to your posts"] = "Добавить категории для ваших публикаций";
+App::$strings["Large Photos"] = "Большие фотографии";
+App::$strings["Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails"] = "Включить большие (1024px) миниатюры изображений в публикациях. Если не включено, использовать маленькие (640px) миниатюры.";
+App::$strings["Even More Encryption"] = "Еще больше шифрования";
+App::$strings["Allow optional encryption of content end-to-end with a shared secret key"] = "Разрешить дополнительное end-to-end шифрование содержимого с общим секретным ключом";
+App::$strings["Enable Voting Tools"] = "Включить инструменты голосования";
+App::$strings["Provide a class of post which others can vote on"] = "Предоставь класс публикаций с возможностью голосования";
+App::$strings["Disable Comments"] = "Отключить комментарии";
+App::$strings["Provide the option to disable comments for a post"] = "Предоставить возможность отключать комментарии для публикаций";
+App::$strings["Delayed Posting"] = "Задержанная публикация";
+App::$strings["Allow posts to be published at a later date"] = "Разрешить размешать публикации следующими датами";
+App::$strings["Content Expiration"] = "Истечение срока действия содержимого";
+App::$strings["Remove posts/comments and/or private messages at a future time"] = "Удалять публикации / комментарии и / или личные сообщения";
+App::$strings["Suppress Duplicate Posts/Comments"] = "Подавлять дублирующие публикации / комментарии";
+App::$strings["Prevent posts with identical content to be published with less than two minutes in between submissions."] = "Предотвращает появление публикаций с одинаковым содержимым если интервал между ними менее 2 минут";
+App::$strings["Auto-save drafts of posts and comments"] = "Автоматически сохранять черновики публикаций и комментариев";
+App::$strings["Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions"] = "Автоматически сохраняет черновики публикаций и комментариев в локальном хранилище браузера для предотвращения их случайной утраты";
+App::$strings["Events"] = "События";
+App::$strings["Smart Birthdays"] = "\"Умные\" Дни рождений";
+App::$strings["Make birthday events timezone aware in case your friends are scattered across the planet."] = "Сделать уведомления о днях рождения зависимыми от часового пояса в том случае, если ваши друзья разбросаны по планете.";
+App::$strings["Event Timezone Selection"] = "Выбор часового пояса события";
+App::$strings["Allow event creation in timezones other than your own."] = "Разрешить создание события в часовой зоне отличной от вашей";
+App::$strings["Manage"] = "Управление";
+App::$strings["Navigation Channel Select"] = "Выбор канала навигации";
+App::$strings["Change channels directly from within the navigation dropdown menu"] = "Изменить канал напрямую из выпадающего меню";
+App::$strings["Network"] = "Сеть";
+App::$strings["Saved Searches"] = "Сохранённые поиски";
+App::$strings["Save search terms for re-use"] = "Сохранять результаты поиска для повторного использования";
+App::$strings["Ability to file posts under folders"] = "Возможность размещать публикации в каталогах";
+App::$strings["Alternate Stream Order"] = "Отображение потока";
+App::$strings["Ability to order the stream by last post date, last comment date or unthreaded activities"] = "Возможность показывать поток по дате последнего сообщения, последнего комментария или в порядке поступления";
+App::$strings["Contact Filter"] = "Фильтр контактов";
+App::$strings["Ability to display only posts of a selected contact"] = "Возможность показа публикаций только от выбранных контактов";
+App::$strings["Forum Filter"] = "Фильтр по форумам";
+App::$strings["Ability to display only posts of a specific forum"] = "Возможность показа публикаций только определённого форума";
+App::$strings["Personal Posts Filter"] = "Персональный фильтр публикаций";
+App::$strings["Ability to display only posts that you've interacted on"] = "Возможность показа только тех публикаций с которыми вы взаимодействовали";
+App::$strings["Photos"] = "Фотографии";
+App::$strings["Photo Location"] = "Местоположение фотографии";
+App::$strings["If location data is available on uploaded photos, link this to a map."] = "Если данные о местоположении доступны на загруженных фотографий, связать их с картой.";
+App::$strings["Profiles"] = "Редактировать профиль";
+App::$strings["Advanced Profiles"] = "Расширенные профили";
+App::$strings["Additional profile sections and selections"] = "Дополнительные секции и выборы профиля";
+App::$strings["Profile Import/Export"] = "Импорт / экспорт профиля";
+App::$strings["Save and load profile details across sites/channels"] = "Сохранение и загрузка настроек профиля на всех сайтах / каналах";
+App::$strings["Multiple Profiles"] = "Несколько профилей";
+App::$strings["Ability to create multiple profiles"] = "Возможность создания нескольких профилей";
+App::$strings["prev"] = "предыдущий";
+App::$strings["first"] = "первый";
+App::$strings["last"] = "последний";
+App::$strings["next"] = "следующий";
+App::$strings["older"] = "старше";
+App::$strings["newer"] = "новее";
+App::$strings["No connections"] = "Нет контактов";
+App::$strings["View all %s connections"] = "Просмотреть все %s контактов";
+App::$strings["Network: %s"] = "Сеть: %s";
+App::$strings["Search"] = "Поиск";
+App::$strings["Save"] = "Запомнить";
+App::$strings["poke"] = "Ткнуть";
+App::$strings["poked"] = "ткнут";
+App::$strings["ping"] = "Пингануть";
+App::$strings["pinged"] = "Отпингован";
+App::$strings["prod"] = "Подтолкнуть";
+App::$strings["prodded"] = "Подтолкнут";
+App::$strings["slap"] = "Шлёпнуть";
+App::$strings["slapped"] = "Шлёпнут";
+App::$strings["finger"] = "Указать";
+App::$strings["fingered"] = "Указан";
+App::$strings["rebuff"] = "Дать отпор";
+App::$strings["rebuffed"] = "Дан отпор";
+App::$strings["happy"] = "счастливый";
+App::$strings["sad"] = "грустный";
+App::$strings["mellow"] = "спокойный";
+App::$strings["tired"] = "усталый";
+App::$strings["perky"] = "весёлый";
+App::$strings["angry"] = "сердитый";
+App::$strings["stupefied"] = "отупевший";
+App::$strings["puzzled"] = "недоумевающий";
+App::$strings["interested"] = "заинтересованный";
+App::$strings["bitter"] = "едкий";
+App::$strings["cheerful"] = "бодрый";
+App::$strings["alive"] = "энергичный";
+App::$strings["annoyed"] = "раздражённый";
+App::$strings["anxious"] = "обеспокоенный";
+App::$strings["cranky"] = "капризный";
+App::$strings["disturbed"] = "встревоженный";
+App::$strings["frustrated"] = "разочарованный";
+App::$strings["depressed"] = "подавленный";
+App::$strings["motivated"] = "мотивированный";
+App::$strings["relaxed"] = "расслабленный";
+App::$strings["surprised"] = "удивленный";
+App::$strings["Monday"] = "Понедельник";
+App::$strings["Tuesday"] = "Вторник";
+App::$strings["Wednesday"] = "Среда";
+App::$strings["Thursday"] = "Четверг";
+App::$strings["Friday"] = "Пятница";
+App::$strings["Saturday"] = "Суббота";
+App::$strings["Sunday"] = "Воскресенье";
+App::$strings["January"] = "Январь";
+App::$strings["February"] = "Февраль";
+App::$strings["March"] = "Март";
+App::$strings["April"] = "Апрель";
+App::$strings["May"] = "Май";
+App::$strings["June"] = "Июнь";
+App::$strings["July"] = "Июль";
+App::$strings["August"] = "Август";
+App::$strings["September"] = "Сентябрь";
+App::$strings["October"] = "Октябрь";
+App::$strings["November"] = "Ноябрь";
+App::$strings["December"] = "Декабрь";
+App::$strings["Unknown Attachment"] = "Неизвестное вложение";
+App::$strings["Size"] = "Размер";
+App::$strings["unknown"] = "неизвестный";
+App::$strings["remove category"] = "удалить категорию";
+App::$strings["remove from file"] = "удалить из файла";
+App::$strings["Link to Source"] = "Ссылка на источник";
+App::$strings["default"] = "по умолчанию";
+App::$strings["Page layout"] = "Шаблон страницы";
+App::$strings["You can create your own with the layouts tool"] = "Вы можете создать свой собственный с помощью инструмента шаблонов";
+App::$strings["BBcode"] = "";
+App::$strings["HTML"] = "";
+App::$strings["Markdown"] = "Разметка Markdown";
+App::$strings["Text"] = "Текст";
+App::$strings["Comanche Layout"] = "Шаблон Comanche";
+App::$strings["PHP"] = "";
+App::$strings["Page content type"] = "Тип содержимого страницы";
+App::$strings["photo"] = "фото";
+App::$strings["event"] = "событие";
+App::$strings["status"] = "статус";
+App::$strings["comment"] = "комментарий";
+App::$strings["activity"] = "активность";
+App::$strings["a-z, 0-9, -, and _ only"] = "Только a-z, 0-9, -, и _";
+App::$strings["Design Tools"] = "Инструменты дизайна";
+App::$strings["Blocks"] = "Блокировки";
+App::$strings["Menus"] = "Меню";
+App::$strings["Layouts"] = "Шаблоны";
+App::$strings["Pages"] = "Страницы";
+App::$strings["Import"] = "Импортировать";
+App::$strings["Import website..."] = "Импорт веб-сайта...";
+App::$strings["Select folder to import"] = "Выбрать каталог для импорта";
+App::$strings["Import from a zipped folder:"] = "Импортировать из каталога в zip-архиве:";
+App::$strings["Import from cloud files:"] = "Импортировать из сетевых файлов:";
+App::$strings["/cloud/channel/path/to/folder"] = "";
+App::$strings["Enter path to website files"] = "Введите путь к файлам веб-сайта";
+App::$strings["Select folder"] = "Выбрать каталог";
+App::$strings["Export website..."] = "Экспорт веб-сайта...";
+App::$strings["Export to a zip file"] = "Экспортировать в ZIP файл.";
+App::$strings["website.zip"] = "";
+App::$strings["Enter a name for the zip file."] = "Введите имя для ZIP файла.";
+App::$strings["Export to cloud files"] = "Эскпортировать в сетевые файлы:";
+App::$strings["/path/to/export/folder"] = "";
+App::$strings["Enter a path to a cloud files destination."] = "Введите путь к расположению сетевых файлов.";
+App::$strings["Specify folder"] = "Указать каталог";
+App::$strings["Collection"] = "Коллекция";
+App::$strings["Unable to import a removed channel."] = "Невозможно импортировать удалённый канал.";
+App::$strings["Cannot create a duplicate channel identifier on this system. Import failed."] = "Не удалось создать дублирующийся идентификатор канала. Импорт невозможен.";
+App::$strings["Unable to create a unique channel address. Import failed."] = "Не удалось создать уникальный адрес канала. Импорт не завершен.";
+App::$strings["Cloned channel not found. Import failed."] = "Клон канала не найден. Импорт невозможен.";
+App::$strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт <strong>могут</strong> применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем.";
+App::$strings["Add new connections to this privacy group"] = "Добавить новые контакты в группу безопасности";
+App::$strings["edit"] = "редактировать";
+App::$strings["Privacy Groups"] = "Группы безопасности";
+App::$strings["Edit group"] = "Редактировать группу";
+App::$strings["Add privacy group"] = "Добавить группу безопасности";
+App::$strings["Channels not in any privacy group"] = "Каналы не включены ни в одну группу безопасности";
+App::$strings["add"] = "добавить";
+App::$strings["Not a valid email address"] = "Недействительный адрес электронной почты";
+App::$strings["Your email domain is not among those allowed on this site"] = "Домен электронной почты не входит в число тех, которые разрешены на этом сайте";
+App::$strings["Your email address is already registered at this site."] = "Ваш адрес электронной почты уже зарегистрирован на этом сайте.";
+App::$strings["An invitation is required."] = "Требуется приглашение.";
+App::$strings["Invitation could not be verified."] = "Не удалось проверить приглашение.";
+App::$strings["Please enter the required information."] = "Пожалуйста, введите необходимую информацию.";
+App::$strings["Failed to store account information."] = "Не удалось сохранить информацию аккаунта.";
+App::$strings["Registration confirmation for %s"] = "Подтверждение регистрации на %s";
+App::$strings["Registration request at %s"] = "Запрос регистрации на %s";
+App::$strings["your registration password"] = "ваш пароль регистрации";
+App::$strings["Registration details for %s"] = "Регистрационные данные для %s";
+App::$strings["Account approved."] = "Аккаунт утвержден.";
+App::$strings["Registration revoked for %s"] = "Регистрация отозвана для %s";
+App::$strings["Click here to upgrade."] = "Нажмите здесь для обновления.";
+App::$strings["This action exceeds the limits set by your subscription plan."] = "Это действие превышает ограничения, установленные в вашем плане.";
+App::$strings["This action is not available under your subscription plan."] = "Это действие невозможно из-за ограничений в вашем плане.";
+App::$strings["Invalid data packet"] = "Неверный пакет данных";
+App::$strings["Unable to verify channel signature"] = "Невозможно проверить подпись канала";
+App::$strings["Unable to verify site signature for %s"] = "Невозможно проверить подпись сайта %s";
+App::$strings["invalid target signature"] = "недопустимая целевая подпись";
+App::$strings["Channel is blocked on this site."] = "Канал блокируется на этом сайте.";
+App::$strings["Channel location missing."] = "Местоположение канала отсутствует.";
+App::$strings["Response from remote channel was incomplete."] = "Ответ удаленного канала неполный.";
+App::$strings["Premium channel - please visit:"] = "Премимум-канал - пожалуйста посетите:";
+App::$strings["Channel was deleted and no longer exists."] = "Канал удален и больше не существует.";
+App::$strings["Remote channel or protocol unavailable."] = "Удалённый канал или протокол недоступен.";
+App::$strings["Channel discovery failed."] = "Не удалось обнаружить канал.";
+App::$strings["Protocol disabled."] = "Протокол отключен.";
+App::$strings["Cannot connect to yourself."] = "Нельзя подключиться к самому себе.";
+App::$strings["Help:"] = "Помощь:";
+App::$strings["Help"] = "Помощь";
+App::$strings["Not Found"] = "Не найдено";
+App::$strings["Page not found."] = "Страница не найдена.";
+App::$strings["Image/photo"] = "Изображение / фотография";
+App::$strings["Encrypted content"] = "Зашифрованное содержание";
+App::$strings["Install %1\$s element %2\$s"] = "Установить %1\$s элемент %2\$s";
+App::$strings["This post contains an installable %s element, however you lack permissions to install it on this site."] = "Эта публикация содержит устанавливаемый %s элемент, однако у вас нет разрешений для его установки на этом сайте.";
+App::$strings["webpage"] = "веб-страница";
+App::$strings["layout"] = "шаблон";
+App::$strings["block"] = "заблокировать";
+App::$strings["menu"] = "меню";
+App::$strings["card"] = "карточка";
+App::$strings["article"] = "статья";
+App::$strings["Click to open/close"] = "Нажмите, чтобы открыть/закрыть";
+App::$strings["spoiler"] = "спойлер";
+App::$strings["View article"] = "Просмотр статьи";
+App::$strings["View summary"] = "Просмотр резюме";
+App::$strings["Different viewers will see this text differently"] = "Различные зрители увидят этот текст по-разному";
+App::$strings["$1 wrote:"] = "$1 писал:";
+App::$strings["channel"] = "канал";
+App::$strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s нравится %3\$s %2\$s";
+App::$strings["%1\$s doesn't like %2\$s's %3\$s"] = "%1\$s не нравится %2\$s %3\$s";
+App::$strings["likes %1\$s's %2\$s"] = "Нравится %1\$s %2\$s";
+App::$strings["doesn't like %1\$s's %2\$s"] = "Не нравится %1\$s %2\$s";
+App::$strings["%1\$s is now connected with %2\$s"] = "%1\$s теперь в контакте с %2\$s";
+App::$strings["%1\$s poked %2\$s"] = "%1\$s ткнул %2\$s";
+App::$strings["__ctx:mood__ %1\$s is %2\$s"] = "%1\$s %2\$s";
+App::$strings["This is an unsaved preview"] = "Это несохранённый просмотр";
+App::$strings["__ctx:title__ Likes"] = "Нравится";
+App::$strings["__ctx:title__ Dislikes"] = "Не нравится";
+App::$strings["__ctx:title__ Agree"] = "Согласен";
+App::$strings["__ctx:title__ Disagree"] = "Не согласен";
+App::$strings["__ctx:title__ Abstain"] = "Воздержался";
+App::$strings["__ctx:title__ Attending"] = "Посещаю";
+App::$strings["__ctx:title__ Not attending"] = "Не посещаю";
+App::$strings["__ctx:title__ Might attend"] = "Возможно посещу";
+App::$strings["Select"] = "Выбрать";
App::$strings["Delete"] = "Удалить";
-App::$strings["View"] = "Просмотр";
-App::$strings["Total invitation limit exceeded."] = "Превышено общее количество приглашений.";
-App::$strings["%s : Not a valid email address."] = "%s : Недействительный адрес электронной почты.";
-App::$strings["Please join us on \$Projectname"] = "Присоединятесь к \$Projectname !";
-App::$strings["Invitation limit exceeded. Please contact your site administrator."] = "Превышен лимит приглашений. Пожалуйста, свяжитесь с администрацией сайта.";
-App::$strings["%s : Message delivery failed."] = "%s : Доставка сообщения не удалась.";
-App::$strings["%d message sent."] = array(
- 0 => "%d сообщение отправлено.",
- 1 => "%d сообщения отправлено.",
- 2 => "%d сообщений отправлено.",
+App::$strings["Toggle Star Status"] = "Переключить статус пометки";
+App::$strings["Private Message"] = "Личное сообщение";
+App::$strings["Message signature validated"] = "Подпись сообщения проверена";
+App::$strings["Message signature incorrect"] = "Подпись сообщения неверная";
+App::$strings["Approve"] = "Утвердить";
+App::$strings["View %s's profile @ %s"] = "Просмотреть профиль %s @ %s";
+App::$strings["Categories:"] = "Категории:";
+App::$strings["Filed under:"] = "Хранить под:";
+App::$strings["from %s"] = "от %s";
+App::$strings["last edited: %s"] = "последнее редактирование: %s";
+App::$strings["Expires: %s"] = "Срок действия: %s";
+App::$strings["View in context"] = "Показать в контексте";
+App::$strings["Please wait"] = "Подождите пожалуйста";
+App::$strings["remove"] = "удалить";
+App::$strings["Loading..."] = "Загрузка...";
+App::$strings["Conversation Tools"] = "Инструменты общения";
+App::$strings["Delete Selected Items"] = "Удалить выбранные элементы";
+App::$strings["View Source"] = "Просмотреть источник";
+App::$strings["Follow Thread"] = "Следить за темой";
+App::$strings["Unfollow Thread"] = "Прекратить отслеживать тему";
+App::$strings["View Profile"] = "Просмотреть профиль";
+App::$strings["Recent Activity"] = "Последние действия";
+App::$strings["Edit Connection"] = "Редактировать контакт";
+App::$strings["Message"] = "Сообщение";
+App::$strings["Ratings"] = "Оценки";
+App::$strings["Poke"] = "Ткнуть";
+App::$strings["Unknown"] = "Неизвестный";
+App::$strings["%s likes this."] = "%s нравится это.";
+App::$strings["%s doesn't like this."] = "%s не нравится это.";
+App::$strings["<span %1\$s>%2\$d people</span> like this."] = array(
+ 0 => "<span %1\$s>%2\$d человеку</span> это нравится.",
+ 1 => "<span %1\$s>%2\$d человекам</span> это нравится.",
+ 2 => "<span %1\$s>%2\$d человекам</span> это нравится.",
);
-App::$strings["Invite App"] = "Приложение \"Пригласить\"";
-App::$strings["Not Installed"] = "не установлено";
-App::$strings["Send email invitations to join this network"] = "Отправить приглашение присоединиться к этой сети по электронной почте";
-App::$strings["You have no more invitations available"] = "У вас больше нет приглашений";
-App::$strings["Send invitations"] = "Отправить приглашение";
-App::$strings["Enter email addresses, one per line:"] = "Введите адреса электронной почты, по одному в строке:";
-App::$strings["Your message:"] = "Сообщение:";
-App::$strings["Please join my community on \$Projectname."] = "Присоединятесь к нашему сообществу \$Projectname !";
-App::$strings["You will need to supply this invitation code:"] = "Вам нужно предоставит этот код приглашения:";
-App::$strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Зарегистрируйтесь на любом из серверов \$Projectname";
-App::$strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Введите сетевой адрес \$Projectname в поисковой строке сайта";
-App::$strings["or visit"] = "или посетите";
-App::$strings["3. Click [Connect]"] = "Нажать [Подключиться]";
-App::$strings["Submit"] = "Отправить";
-App::$strings["Articles App"] = "Приложение \"Статьи\"";
-App::$strings["Create interactive articles"] = "Создать интерактивные статьи";
-App::$strings["Add Article"] = "Добавить статью";
-App::$strings["Articles"] = "Статьи";
-App::$strings["Item not found"] = "Элемент не найден";
-App::$strings["Layout Name"] = "Название шаблона";
-App::$strings["Layout Description (Optional)"] = "Описание шаблона (необязательно)";
-App::$strings["Edit Layout"] = "Редактировать шаблон";
+App::$strings["<span %1\$s>%2\$d people</span> don't like this."] = array(
+ 0 => "<span %1\$s>%2\$d человеку</span> это не нравится.",
+ 1 => "<span %1\$s>%2\$d человекам</span> это не нравится.",
+ 2 => "<span %1\$s>%2\$d человекам</span> это не нравится.",
+);
+App::$strings["and"] = "и";
+App::$strings[", and %d other people"] = array(
+ 0 => ", и ещё %d человеку",
+ 1 => ", и ещё %d человекам",
+ 2 => ", и ещё %d человекам",
+);
+App::$strings["%s like this."] = "%s нравится это.";
+App::$strings["%s don't like this."] = "%s не нравится это.";
+App::$strings["Set your location"] = "Задать своё местоположение";
+App::$strings["Clear browser location"] = "Очистить местоположение из браузера";
+App::$strings["Insert web link"] = "Вставить веб-ссылку";
+App::$strings["Embed (existing) photo from your photo albums"] = "Встроить (существующее) фото из вашего фотоальбома";
+App::$strings["Please enter a link URL:"] = "Пожалуйста введите URL ссылки:";
+App::$strings["Tag term:"] = "Теги:";
+App::$strings["Where are you right now?"] = "Где вы сейчас?";
+App::$strings["Choose images to embed"] = "Выбрать изображения для встраивания";
+App::$strings["Choose an album"] = "Выбрать альбом";
+App::$strings["Choose a different album..."] = "Выбрать другой альбом...";
+App::$strings["Error getting album list"] = "Ошибка получения списка альбомов";
+App::$strings["Error getting photo link"] = "Ошибка получения ссылки на фотографию";
+App::$strings["Error getting album"] = "Ошибка получения альбома";
+App::$strings["Comments enabled"] = "Комментарии включены";
+App::$strings["Comments disabled"] = "Комментарии отключены";
+App::$strings["Preview"] = "Предварительный просмотр";
+App::$strings["Share"] = "Поделиться";
+App::$strings["Page link name"] = "Название ссылки на страницу ";
+App::$strings["Post as"] = "Опубликовать как";
+App::$strings["Bold"] = "Жирный";
+App::$strings["Italic"] = "Курсив";
+App::$strings["Underline"] = "Подчеркнутый";
+App::$strings["Quote"] = "Цитата";
+App::$strings["Code"] = "Код";
+App::$strings["Attach/Upload file"] = "Прикрепить/загрузить файл";
+App::$strings["Embed an image from your albums"] = "Встроить изображение из ваших альбомов";
App::$strings["Cancel"] = "Отменить";
-App::$strings["Permission denied"] = "Доступ запрещен";
-App::$strings["Invalid profile identifier."] = "Неверный идентификатор профиля";
-App::$strings["Profile Visibility Editor"] = "Редактор видимости профиля";
-App::$strings["Profile"] = "Профиль";
-App::$strings["Click on a contact to add or remove."] = "Нажмите на контакт, чтобы добавить или удалить.";
-App::$strings["Visible To"] = "Видно";
-App::$strings["All Connections"] = "Все контакты";
+App::$strings["OK"] = "";
+App::$strings["Toggle voting"] = "Подключить голосование";
+App::$strings["Disable comments"] = "Отключить комментарии";
+App::$strings["Toggle comments"] = "Переключить комментарии";
+App::$strings["Title (optional)"] = "Заголовок (необязательно)";
+App::$strings["Categories (optional, comma-separated list)"] = "Категории (необязательно, список через запятую)";
+App::$strings["Permission settings"] = "Настройки разрешений";
+App::$strings["Other networks and post services"] = "Другие сети и службы публикаций";
+App::$strings["Set expiration date"] = "Установить срок действия";
+App::$strings["Set publish date"] = "Установить дату публикации";
+App::$strings["Encrypt text"] = "Зашифровать текст";
+App::$strings["__ctx:noun__ Dislike"] = array(
+ 0 => "Не нравится",
+ 1 => "Не нравится",
+ 2 => "Не нравится",
+);
+App::$strings["__ctx:noun__ Attending"] = array(
+ 0 => "Посетит",
+ 1 => "Посетят",
+ 2 => "Посетят",
+);
+App::$strings["__ctx:noun__ Not Attending"] = array(
+ 0 => "Не посетит",
+ 1 => "Не посетят",
+ 2 => "Не посетят",
+);
+App::$strings["__ctx:noun__ Undecided"] = "Не решил";
+App::$strings["__ctx:noun__ Agree"] = array(
+ 0 => "Согласен",
+ 1 => "Согласны",
+ 2 => "Согласны",
+);
+App::$strings["__ctx:noun__ Disagree"] = array(
+ 0 => "Не согласен",
+ 1 => "Не согласны",
+ 2 => "Не согласны",
+);
+App::$strings["__ctx:noun__ Abstain"] = array(
+ 0 => "Воздержался",
+ 1 => "Воздержались",
+ 2 => "Воздержались",
+);
+App::$strings["Trending"] = "В тренде";
+App::$strings["Tags"] = "Теги";
+App::$strings["Keywords"] = "Ключевые слова";
+App::$strings["have"] = "иметь";
+App::$strings["has"] = "есть";
+App::$strings["want"] = "хотеть";
+App::$strings["wants"] = "хотеть";
+App::$strings["like"] = "нравится";
+App::$strings["likes"] = "нравится";
+App::$strings["dislike"] = "не нравится";
+App::$strings["dislikes"] = "не нравится";
+App::$strings["Select an alternate language"] = "Выбор дополнительного языка";
+App::$strings["Delete this item?"] = "Удалить этот элемент?";
+App::$strings["Comment"] = "Комментарий";
+App::$strings["%s show all"] = "%s показать всё";
+App::$strings["%s show less"] = "%s показать меньше";
+App::$strings["%s expand"] = "%s развернуть";
+App::$strings["%s collapse"] = "%s свернуть";
+App::$strings["Password too short"] = "Пароль слишком короткий";
+App::$strings["Passwords do not match"] = "Пароли не совпадают";
+App::$strings["everybody"] = "все";
+App::$strings["Secret Passphrase"] = "Тайный пароль";
+App::$strings["Passphrase hint"] = "Подсказка для пароля";
+App::$strings["Notice: Permissions have changed but have not yet been submitted."] = "Уведомление: Права доступа изменились, но до сих пор не сохранены.";
+App::$strings["close all"] = "закрыть все";
+App::$strings["Nothing new here"] = "Здесь нет ничего нового";
+App::$strings["Rate This Channel (this is public)"] = "Оценкa этoго канала (общедоступно)";
+App::$strings["Rating"] = "Оценка";
+App::$strings["Describe (optional)"] = "Охарактеризовать (необязательно)";
+App::$strings["Please enter a link URL"] = "Пожалуйста, введите URL ссылки";
+App::$strings["Unsaved changes. Are you sure you wish to leave this page?"] = "Есть несохраненные изменения. Вы уверены, что хотите покинуть эту страницу?";
+App::$strings["Location"] = "Место";
+App::$strings["lovely"] = "прекрасно";
+App::$strings["wonderful"] = "замечательно";
+App::$strings["fantastic"] = "фантастично";
+App::$strings["great"] = "отлично";
+App::$strings["Your chosen nickname was either already taken or not valid. Please use our suggestion ("] = "Выбранный вами псевдоним уже используется или недействителен. Попробуйте использовать наше предложение (";
+App::$strings[") or enter a new one."] = ") или введите новый.";
+App::$strings["Thank you, this nickname is valid."] = "Спасибо, этот псевдоним может быть использован.";
+App::$strings["A channel name is required."] = "Требуется название канала.";
+App::$strings["This is a "] = "Это ";
+App::$strings[" channel name"] = " название канала";
+App::$strings["%d minutes"] = array(
+ 0 => "%d минуту",
+ 1 => "%d минуты",
+ 2 => "%d минут",
+);
+App::$strings["about %d hours"] = array(
+ 0 => "около %d часa",
+ 1 => "около %d часов",
+ 2 => "около %d часов",
+);
+App::$strings["%d days"] = array(
+ 0 => "%d день",
+ 1 => "%d дня",
+ 2 => "%d дней",
+);
+App::$strings["%d months"] = array(
+ 0 => "%d месяц",
+ 1 => "%d месяца",
+ 2 => "%d месяцев",
+);
+App::$strings["%d years"] = array(
+ 0 => "%d год",
+ 1 => "%d года",
+ 2 => "%d лет",
+);
+App::$strings["timeago.prefixAgo"] = "";
+App::$strings["timeago.prefixFromNow"] = "через";
+App::$strings["timeago.suffixAgo"] = "назад";
+App::$strings["timeago.suffixFromNow"] = "";
+App::$strings["less than a minute"] = "менее чем одну минуту";
+App::$strings["about a minute"] = "около минуты";
+App::$strings["about an hour"] = "около часа";
+App::$strings["a day"] = "день";
+App::$strings["about a month"] = "около месяца";
+App::$strings["about a year"] = "около года";
+App::$strings[" "] = " ";
+App::$strings["timeago.numbers"] = "";
+App::$strings["__ctx:long__ May"] = "Май";
+App::$strings["Jan"] = "Янв";
+App::$strings["Feb"] = "Фев";
+App::$strings["Mar"] = "Мар";
+App::$strings["Apr"] = "Апр";
+App::$strings["__ctx:short__ May"] = "Май";
+App::$strings["Jun"] = "Июн";
+App::$strings["Jul"] = "Июл";
+App::$strings["Aug"] = "Авг";
+App::$strings["Sep"] = "Сен";
+App::$strings["Oct"] = "Окт";
+App::$strings["Nov"] = "Ноя";
+App::$strings["Dec"] = "Дек";
+App::$strings["Sun"] = "Вск";
+App::$strings["Mon"] = "Пон";
+App::$strings["Tue"] = "Вт";
+App::$strings["Wed"] = "Ср";
+App::$strings["Thu"] = "Чет";
+App::$strings["Fri"] = "Пят";
+App::$strings["Sat"] = "Суб";
+App::$strings["__ctx:calendar__ today"] = "сегодня";
+App::$strings["__ctx:calendar__ month"] = "месяц";
+App::$strings["__ctx:calendar__ week"] = "неделя";
+App::$strings["__ctx:calendar__ day"] = "день";
+App::$strings["__ctx:calendar__ All day"] = "Весь день";
+App::$strings["Directory Options"] = "Параметры каталога";
+App::$strings["Safe Mode"] = "Безопасный режим";
+App::$strings["Public Forums Only"] = "Только публичные форумы";
+App::$strings["This Website Only"] = "Только этот веб-сайт";
+App::$strings["Friendica"] = "";
+App::$strings["OStatus"] = "";
+App::$strings["GNU-Social"] = "";
+App::$strings["RSS/Atom"] = "";
+App::$strings["ActivityPub"] = "";
+App::$strings["Email"] = "Электронная почта";
+App::$strings["Diaspora"] = "";
+App::$strings["Facebook"] = "";
+App::$strings["Zot"] = "";
+App::$strings["LinkedIn"] = "";
+App::$strings["XMPP/IM"] = "";
+App::$strings["MySpace"] = "";
+App::$strings["Miscellaneous"] = "Прочее";
+App::$strings["Birthday"] = "День рождения";
+App::$strings["Age: "] = "Возраст:";
+App::$strings["YYYY-MM-DD or MM-DD"] = "YYYY-MM-DD или MM-DD";
+App::$strings["Required"] = "Требуется";
+App::$strings["never"] = "никогда";
+App::$strings["less than a second ago"] = "менее чем одну секунду";
+App::$strings["__ctx:e.g. 22 hours ago, 1 minute ago__ %1\$d %2\$s ago"] = "%1\$d %2\$s назад";
+App::$strings["__ctx:relative_date__ year"] = array(
+ 0 => "год",
+ 1 => "года",
+ 2 => "лет",
+);
+App::$strings["__ctx:relative_date__ month"] = array(
+ 0 => "месяц",
+ 1 => "месяца",
+ 2 => "месяцев",
+);
+App::$strings["__ctx:relative_date__ week"] = array(
+ 0 => "неделю",
+ 1 => "недели",
+ 2 => "недель",
+);
+App::$strings["__ctx:relative_date__ day"] = array(
+ 0 => "день",
+ 1 => "дня",
+ 2 => "дней",
+);
+App::$strings["__ctx:relative_date__ hour"] = array(
+ 0 => "час",
+ 1 => "часа",
+ 2 => "часов",
+);
+App::$strings["__ctx:relative_date__ minute"] = array(
+ 0 => "минуту",
+ 1 => "минуты",
+ 2 => "минут",
+);
+App::$strings["__ctx:relative_date__ second"] = array(
+ 0 => "секунду",
+ 1 => "секунды",
+ 2 => "секунд",
+);
+App::$strings["%1\$s's birthday"] = "У %1\$s День рождения";
+App::$strings["Happy Birthday %1\$s"] = "С Днем рождения %1\$s !";
+App::$strings["Visible to your default audience"] = "Видно вашей аудитории по умолчанию.";
+App::$strings["__ctx:acl__ Profile"] = "Профиль";
+App::$strings["Only me"] = "Только мне";
+App::$strings["Who can see this?"] = "Кто может это видеть?";
+App::$strings["Custom selection"] = "Настраиваемый выбор";
+App::$strings["Select \"Show\" to allow viewing. \"Don't show\" lets you override and limit the scope of \"Show\"."] = "Нажмите \"Показать\" чтобы разрешить просмотр. \"Не показывать\" позволит вам переопределить и ограничить область показа.";
+App::$strings["Show"] = "Показать";
+App::$strings["Don't show"] = "Не показывать";
+App::$strings["Permissions"] = "Разрешения";
+App::$strings["Close"] = "Закрыть";
+App::$strings["Post permissions %s cannot be changed %s after a post is shared.</br />These permissions set who is allowed to view the post."] = "Разрешения публикации %s не могут быть изменены %s после того, как ею поделились. Эти разрешения устанавливают кому разрешено просматривать эту публикацию.";
+App::$strings["OpenWebAuth: %1\$s welcomes %2\$s"] = "OpenWebAuth: %1\$s приветствует %2\$s";
+App::$strings["New window"] = "Новое окно";
+App::$strings["Open the selected location in a different window or browser tab"] = "Открыть выбранное местоположение в другом окне или вкладке браузера";
+App::$strings["Mobile"] = "Мобильный";
+App::$strings["Home"] = "Домашний";
+App::$strings["Home, Voice"] = "Дом, голос";
+App::$strings["Home, Fax"] = "Дом, факс";
+App::$strings["Work"] = "Рабочий";
+App::$strings["Work, Voice"] = "Работа, голос";
+App::$strings["Work, Fax"] = "Работа, факс";
+App::$strings["l F d, Y \\@ g:i A"] = "";
+App::$strings["Starts:"] = "Начало:";
+App::$strings["Finishes:"] = "Окончание:";
+App::$strings["This event has been added to your calendar."] = "Это событие было добавлено в ваш календарь.";
+App::$strings["Not specified"] = "Не указано";
+App::$strings["Needs Action"] = "Требует действия";
+App::$strings["Completed"] = "Завершено";
+App::$strings["In Process"] = "В процессе";
+App::$strings["Cancelled"] = "Отменено";
+App::$strings["Delegation session ended."] = "Делегированная сессия завершена.";
+App::$strings["Logged out."] = "Вышел из системы.";
+App::$strings["Email validation is incomplete. Please check your email."] = "Проверка email не завершена. Пожалуйста, проверьте вашу почту.";
+App::$strings["Failed authentication"] = "Ошибка аутентификации";
+App::$strings["Login failed."] = "Не удалось войти.";
+App::$strings["Remote authentication"] = "Удаленная аутентификация";
+App::$strings["Click to authenticate to your home hub"] = "Нажмите, чтобы аутентифицировать себя на домашнем узле";
+App::$strings["Channel Manager"] = "Менеджер каналов";
+App::$strings["Manage your channels"] = "Управление вашими каналами";
+App::$strings["Manage your privacy groups"] = "Управление вашим группами безопасности";
+App::$strings["Settings"] = "Настройки";
+App::$strings["Account/Channel Settings"] = "Настройки аккаунта / канала";
+App::$strings["Logout"] = "Выход";
+App::$strings["End this session"] = "Закончить эту сессию";
+App::$strings["Your profile page"] = "Страницa вашего профиля";
+App::$strings["Manage/Edit profiles"] = "Управление / редактирование профилей";
+App::$strings["Edit your profile"] = "Редактировать профиль";
+App::$strings["Login"] = "Войти";
+App::$strings["Sign in"] = "Войти";
+App::$strings["Take me home"] = "Домой";
+App::$strings["Log me out of this site"] = "Выйти с этого сайта";
+App::$strings["Register"] = "Регистрация";
+App::$strings["Create an account"] = "Создать аккаунт";
+App::$strings["Help and documentation"] = "Справочная информация и документация";
+App::$strings["Search site @name, !forum, #tag, ?docs, content"] = "Искать на сайте @имя, !форум, #тег, ?документ, содержимое";
+App::$strings["Admin"] = "Администрирование";
+App::$strings["Site Setup and Configuration"] = "Установка и конфигурация сайта";
+App::$strings["Loading"] = "Загрузка";
+App::$strings["@name, !forum, #tag, ?doc, content"] = "@имя, !форум, #тег, ?документ, содержимое";
+App::$strings["Please wait..."] = "Подождите пожалуйста ...";
+App::$strings["Add Apps"] = "Добавить приложения";
+App::$strings["Arrange Apps"] = "Упорядочить приложения";
+App::$strings["Toggle System Apps"] = "Показать системные приложения";
+App::$strings["Channel"] = "Канал";
+App::$strings["Status Messages and Posts"] = "Статусы и публикации";
+App::$strings["About"] = "О себе";
+App::$strings["Profile Details"] = "Информация о профиле";
+App::$strings["Files"] = "Файлы";
+App::$strings["Files and Storage"] = "Файлы и хранилище";
+App::$strings["Calendar"] = "Календарь";
+App::$strings["Chatrooms"] = "Чаты";
+App::$strings["Bookmarks"] = "Закладки";
+App::$strings["Saved Bookmarks"] = "Сохранённые закладки";
+App::$strings["Cards"] = "Карточки";
+App::$strings["View Cards"] = "Просмотреть карточки";
+App::$strings["Articles"] = "Статьи";
+App::$strings["View Articles"] = "Просмотр статей";
+App::$strings["Webpages"] = "Веб-страницы";
+App::$strings["View Webpages"] = "Просмотр веб-страниц";
+App::$strings["Wikis"] = "";
+App::$strings["Wiki"] = "";
+App::$strings["%1\$s's bookmarks"] = "Закладки пользователя %1\$s";
+App::$strings["Item was not found."] = "Элемент не найден.";
+App::$strings["Unknown error."] = "Неизвестная ошибка.";
+App::$strings["No source file."] = "Нет исходного файла.";
+App::$strings["Cannot locate file to replace"] = "Не удается найти файл для замены";
+App::$strings["Cannot locate file to revise/update"] = "Не удается найти файл для пересмотра / обновления";
+App::$strings["File exceeds size limit of %d"] = "Файл превышает предельный размер %d";
+App::$strings["You have reached your limit of %1$.0f Mbytes attachment storage."] = "Вы достигли предела %1$.0f Мбайт для хранения вложений.";
+App::$strings["File upload failed. Possible system limit or action terminated."] = "Загрузка файла не удалась. Возможно система перегружена или попытка прекращена.";
+App::$strings["Stored file could not be verified. Upload failed."] = "Файл для сохранения не может быть проверен. Загрузка не удалась.";
+App::$strings["Path not available."] = "Путь недоступен.";
+App::$strings["Empty pathname"] = "Пустое имя пути";
+App::$strings["duplicate filename or path"] = "дублирующееся имя файла или пути";
+App::$strings["Path not found."] = "Путь не найден.";
+App::$strings["mkdir failed."] = "mkdir не удался";
+App::$strings["database storage failed."] = "ошибка при записи базы данных.";
+App::$strings["Empty path"] = "Пустое имя пути";
+App::$strings["Profile Photos"] = "Фотографии профиля";
+App::$strings["Create an account to access services and applications"] = "Создайте аккаунт для доступа к службам и приложениям";
+App::$strings["Login/Email"] = "Пользователь / email";
+App::$strings["Password"] = "Пароль";
+App::$strings["Remember me"] = "Запомнить меня";
+App::$strings["Forgot your password?"] = "Забыли пароль или логин?";
+App::$strings["Password Reset"] = "Сбросить пароль";
+App::$strings["[\$Projectname] Website SSL error for %s"] = "[\$Projectname] Ошибка SSL/TLS веб-сайта для %s";
+App::$strings["Website SSL certificate is not valid. Please correct."] = "SSL/TLS сертификат веб-сайт недействителен. Исправьте это.";
+App::$strings["[\$Projectname] Cron tasks not running on %s"] = "[\$Projectname] Задания Cron не запущены на %s";
+App::$strings["Cron/Scheduled tasks not running."] = "Задания Cron / планировщика не запущены.";
+App::$strings["parent"] = "источник";
+App::$strings["Principal"] = "Субъект";
+App::$strings["Addressbook"] = "Адресная книга";
+App::$strings["Schedule Inbox"] = "План занятий входящий";
+App::$strings["Schedule Outbox"] = "План занятий исходящий";
+App::$strings["Total"] = "Всего";
+App::$strings["Shared"] = "Общие";
+App::$strings["Create"] = "Создать";
+App::$strings["Add Files"] = "Добавить файлы";
+App::$strings["Admin Delete"] = "Удалено администратором";
+App::$strings["Name"] = "Имя";
+App::$strings["Type"] = "Тип";
+App::$strings["Last Modified"] = "Последнее изменение";
+App::$strings["You are using %1\$s of your available file storage."] = "Вы используете %1\$s из доступного вам хранилища файлов.";
+App::$strings["You are using %1\$s of %2\$s available file storage. (%3\$s&#37;)"] = "Вы используете %1\$s из %2\$s доступного хранилища файлов (%3\$s&#37;).";
+App::$strings["WARNING:"] = "Предупреждение:";
+App::$strings["Create new folder"] = "Создать новую папку";
+App::$strings["Upload file"] = "Загрузить файл";
+App::$strings["Upload"] = "Загрузка";
+App::$strings["Drop files here to immediately upload"] = "Поместите файлы сюда для немедленной загрузки";
+App::$strings["Show in your contacts shared folder"] = "Показать общий каталог в ваших контактах";
+App::$strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "Удалённая аутентификация заблокирована. Вы вошли на этот сайт локально. Пожалуйста, выйдите и попробуйте ещё раз.";
+App::$strings["Welcome %s. Remote authentication successful."] = "Добро пожаловать %s. Удаленная аутентификация успешно завершена.";
+App::$strings["This site is not a directory server"] = "Этот сайт не является сервером каталога";
+App::$strings["Unable to lookup recipient."] = "Не удалось найти получателя.";
+App::$strings["Unable to communicate with requested channel."] = "Не удалось установить связь с запрашиваемым каналом.";
+App::$strings["Cannot verify requested channel."] = "Не удалось установить подлинность требуемого канала.";
+App::$strings["Selected channel has private message restrictions. Send failed."] = "Выбранный канал ограничивает частные сообщения. Отправка не удалась.";
+App::$strings["Messages"] = "Сообщения";
+App::$strings["message"] = "сообщение";
+App::$strings["Message recalled."] = "Сообщение отозванно.";
+App::$strings["Conversation removed."] = "Беседа удалена.";
+App::$strings["Expires YYYY-MM-DD HH:MM"] = "Истекает YYYY-MM-DD HH:MM";
+App::$strings["Requested channel is not in this network"] = "Запрашиваемый канал не доступен.";
+App::$strings["Send Private Message"] = "Отправить личное сообщение";
+App::$strings["To:"] = "Кому:";
+App::$strings["Subject:"] = "Тема:";
+App::$strings["Your message:"] = "Сообщение:";
+App::$strings["Attach file"] = "Прикрепить файл";
+App::$strings["Send"] = "Отправить";
+App::$strings["Delete message"] = "Удалить сообщение";
+App::$strings["Delivery report"] = "Отчёт о доставке";
+App::$strings["Recall message"] = "Отозвать сообщение";
+App::$strings["Message has been recalled."] = "Сообщение отозванно";
+App::$strings["Delete Conversation"] = "Удалить беседу";
+App::$strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Безопасная связь недоступна. Вы <strong>можете</strong> попытаться ответить со страницы профиля отправителя.";
+App::$strings["Send Reply"] = "Отправить ответ";
+App::$strings["Your message for %s (%s):"] = "Ваше сообщение для %s (%s):";
+App::$strings["This setting requires special processing and editing has been blocked."] = "Этот параметр требует специальной обработки и редактирования и был заблокирован.";
+App::$strings["Configuration Editor"] = "Редактор конфигурации";
+App::$strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Предупреждение. Изменение некоторых настроек может привести к неработоспособности вашего канала. Пожалуйста, покиньте эту страницу, если вы точно не значете, как правильно использовать эту функцию.";
+App::$strings["Could not access contact record."] = "Не удалось получить доступ к записи контакта.";
+App::$strings["Settings updated."] = "Настройки обновлены.";
+App::$strings["Default Permissions App"] = "Приложение \"Разрешения по умолчанию\"";
+App::$strings["Not Installed"] = "не установлено";
+App::$strings["Set custom default permissions for new connections"] = "Настройка пользовательских разрешений по умолчанию для новых подключений ";
+App::$strings["Connection Default Permissions"] = "Разрешения по умолчанию для контакта";
+App::$strings["Apply these permissions automatically"] = "Применить эти разрешения автоматически";
+App::$strings["If enabled, connection requests will be approved without your interaction"] = "Если включено, запросы контактов будут одобрены без вашего участия";
+App::$strings["Permission role"] = "Роль разрешения";
+App::$strings["Add permission role"] = "Добавить роль разрешения";
+App::$strings["The permissions indicated on this page will be applied to all new connections."] = "Разрешения, указанные на этой странице, будут применяться ко всем новым соединениям.";
+App::$strings["Automatic approval settings"] = "Настройки автоматического одобрения";
+App::$strings["inherited"] = "наследуется";
+App::$strings["My Settings"] = "Мои настройки";
+App::$strings["Individual Permissions"] = "Индивидуальные разрешения";
+App::$strings["Some individual permissions may have been preset or locked based on your channel type and privacy settings."] = "Некоторые индивидуальные разрешения могут быть предустановлены или заблокированы на основании типа вашего канала и настроек приватности.";
+App::$strings["Permission category name is required."] = "Требуется категория разрешений.";
+App::$strings["Permission category saved."] = "Категория разрешения сохранена.";
+App::$strings["Permission Categories App"] = "Приложение \"Категории разрешений\"";
+App::$strings["Create custom connection permission limits"] = "Создать пользовательские ограничения на доступ к подключению";
+App::$strings["Use this form to create permission rules for various classes of people or connections."] = "Используйте эту форму для создания правил разрешений для различных групп людей и контактов.";
+App::$strings["Permission Categories"] = "Категории разрешений";
+App::$strings["Permission category name"] = "Наименование категории разрешений";
+App::$strings["Some permissions may be inherited from your channel's <a href=\"settings\"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here."] = "Некоторые разрешения могут наследовать из <a href=\"settings\"><strong>настроек приватности</strong></a> ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы <strong>не можете</strong> менять эти настройки здесь.";
+App::$strings["Xchan Lookup"] = "Поиск Xchan";
+App::$strings["Lookup xchan beginning with (or webbie): "] = "Запрос Xchan начинается с (или webbie):";
+App::$strings["Not found."] = "Не найдено.";
+App::$strings["Invalid message"] = "Неверное сообщение";
+App::$strings["no results"] = "Ничего не найдено.";
+App::$strings["channel sync processed"] = "синхронизация канала завершена";
+App::$strings["queued"] = "в очереди";
+App::$strings["posted"] = "опубликовано";
+App::$strings["accepted for delivery"] = "принято к доставке";
+App::$strings["updated"] = "обновлено";
+App::$strings["update ignored"] = "обновление игнорируется";
+App::$strings["permission denied"] = "доступ запрещен";
+App::$strings["recipient not found"] = "получатель не найден";
+App::$strings["mail recalled"] = "почта отозвана";
+App::$strings["duplicate mail received"] = "получено дублирующее сообщение";
+App::$strings["mail delivered"] = "почта доставлен";
+App::$strings["Delivery report for %1\$s"] = "Отчёт о доставке для %1\$s";
+App::$strings["Options"] = "Параметры";
+App::$strings["Redeliver"] = "Доставить повторно";
+App::$strings["No such group"] = "Нет такой группы";
+App::$strings["No such channel"] = "Нет такого канала";
+App::$strings["Search Results For:"] = "Результаты поиска для:";
+App::$strings["Reset form"] = "Очистить форму";
+App::$strings["Privacy group is empty"] = "Группа безопасности пуста";
+App::$strings["Privacy group: "] = "Группа безопасности: ";
+App::$strings["Invalid channel."] = "Недействительный канал.";
+App::$strings["Token verification failed."] = "Не удалось выполнить проверку токена.";
+App::$strings["Email Verification Required"] = "Требуется проверка адреса email";
+App::$strings["A verification token was sent to your email address [%s]. Enter that token here to complete the account verification step. Please allow a few minutes for delivery, and check your spam folder if you do not see the message."] = "Проверочный токен был отправлен на ваш адрес электронной почты [%s]. Введите этот токен здесь для завершения этапа проверки учётной записи. Пожалуйста, подождите несколько минут для завершения доставки и проверьте вашу папку \"Спам\" если вы не видите письма.";
+App::$strings["Resend Email"] = "Выслать повторно";
+App::$strings["Validation token"] = "Проверочный токен";
+App::$strings["No channel."] = "Канала нет.";
+App::$strings["No connections in common."] = "Общих контактов нет.";
+App::$strings["View Common Connections"] = "Просмотр общий контактов";
+App::$strings["network"] = "сеть";
+App::$strings["Unable to locate original post."] = "Не удалось найти оригинальную публикацию.";
+App::$strings["Empty post discarded."] = "Пустая публикация отклонена.";
+App::$strings["Duplicate post suppressed."] = "Подавлена дублирующаяся публикация.";
+App::$strings["System error. Post not saved."] = "Системная ошибка. Публикация не сохранена.";
+App::$strings["Your comment is awaiting approval."] = "Ваш комментарий ожидает одобрения.";
+App::$strings["Unable to obtain post information from database."] = "Невозможно получить информацию о публикации из базы данных";
+App::$strings["You have reached your limit of %1$.0f top level posts."] = "Вы достигли вашего ограничения в %1$.0f публикаций высокого уровня.";
+App::$strings["You have reached your limit of %1$.0f webpages."] = "Вы достигли вашего ограничения в %1$.0f страниц.";
+App::$strings["Some blurb about what to do when you're new here"] = "Некоторые предложения о том, что делать, если вы здесь новичок ";
+App::$strings["Public access denied."] = "Публичный доступ запрещен.";
+App::$strings["You must enable javascript for your browser to be able to view this content."] = "Для просмотра этого содержимого в вашем браузере должен быть включён JavaScript";
+App::$strings["Article"] = "Статья";
+App::$strings["Item has been removed."] = "Элемент был удалён.";
+App::$strings["sent you a private message"] = "отправил вам личное сообщение";
+App::$strings["added your channel"] = "добавил ваш канал";
+App::$strings["requires approval"] = "Требуется подтверждение";
+App::$strings["g A l F d"] = "g A l F d";
+App::$strings["[today]"] = "[сегодня]";
+App::$strings["posted an event"] = "событие опубликовано";
+App::$strings["shared a file with you"] = "с вами поделились файлом";
+App::$strings["Private forum"] = "Частный форум";
+App::$strings["Public forum"] = "Публичный форум";
+App::$strings["Poke App"] = "Приложение \"Ткнуть\"";
+App::$strings["Poke somebody in your addressbook"] = "Ткнуть кого-нибудь в вашей адресной книге";
+App::$strings["Poke somebody"] = "Ткнуть кого-нибудь";
+App::$strings["Poke/Prod"] = "Толкнуть / подтолкнуть";
+App::$strings["Poke, prod or do other things to somebody"] = "Толкнуть, подтолкнуть или сделать что-то ещё с кем-то";
+App::$strings["Recipient"] = "Получатель";
+App::$strings["Choose what you wish to do to recipient"] = "Выбрать что вы хотите сделать с получателем";
+App::$strings["Make this post private"] = "Сделать эту публикацию приватной";
+App::$strings["Remote privacy information not available."] = "Удаленная информация о конфиденциальности недоступна.";
+App::$strings["Visible to:"] = "Видимо для:";
+App::$strings["Post not found."] = "Публикация не найдена";
+App::$strings["%1\$s tagged %2\$s's %3\$s with %4\$s"] = "%1\$s отметил тегом %2\$s %3\$s с %4\$s";
+App::$strings["No default suggestions were found."] = "Предложений по умолчанию не найдено.";
+App::$strings["%d rating"] = array(
+ 0 => "%d оценка",
+ 1 => "%d оценки",
+ 2 => "%d оценок",
+);
+App::$strings["Gender: "] = "Пол:";
+App::$strings["Status: "] = "Статус:";
+App::$strings["Homepage: "] = "Домашняя страница:";
+App::$strings["Description:"] = "Описание:";
+App::$strings["Public Forum:"] = "Публичный форум:";
+App::$strings["Keywords: "] = "Ключевые слова:";
+App::$strings["Don't suggest"] = "Не предлагать";
+App::$strings["Common connections (estimated):"] = "Общие контакты (оценочно):";
+App::$strings["Global Directory"] = "Глобальный каталог";
+App::$strings["Local Directory"] = "Локальный каталог";
+App::$strings["Finding:"] = "Поиск:";
+App::$strings["next page"] = "следующая страница";
+App::$strings["previous page"] = "предыдущая страница";
+App::$strings["Sort options"] = "Параметры сортировки";
+App::$strings["Alphabetic"] = "По алфавиту";
+App::$strings["Reverse Alphabetic"] = "Против алфавита";
+App::$strings["Newest to Oldest"] = "От новых к старым";
+App::$strings["Oldest to Newest"] = "От старых к новым";
+App::$strings["No entries (some entries may be hidden)."] = "Нет записей (некоторые записи могут быть скрыты).";
App::$strings["INVALID EVENT DISMISSED!"] = "НЕДЕЙСТВИТЕЛЬНОЕ СОБЫТИЕ ОТКЛОНЕНО!";
App::$strings["Summary: "] = "Резюме: ";
-App::$strings["Unknown"] = "Неизвестный";
App::$strings["Date: "] = "Дата: ";
App::$strings["Reason: "] = "Причина: ";
App::$strings["INVALID CARD DISMISSED!"] = "НЕДЕЙСТВИТЕЛЬНАЯ КАРТОЧКА ОТКЛОНЕНА!";
@@ -106,10 +1072,8 @@ App::$strings["CardDAV App"] = "Приложение CardDAV";
App::$strings["CalDAV capable addressbook"] = "Адресная книга с поддержкой CalDAV";
App::$strings["Event title"] = "Наименование события";
App::$strings["Start date and time"] = "Дата и время начала";
-App::$strings["Example: YYYY-MM-DD HH:mm"] = "Пример: YYYY-MM-DD HH:mm";
App::$strings["End date and time"] = "Дата и время окончания";
App::$strings["Description"] = "Описание";
-App::$strings["Location"] = "Место";
App::$strings["Previous"] = "Предыдущая";
App::$strings["Next"] = "Следующая";
App::$strings["Today"] = "Сегодня";
@@ -124,18 +1088,13 @@ App::$strings["Less"] = "Меньше";
App::$strings["Select calendar"] = "Выбрать календарь";
App::$strings["Delete all"] = "Удалить всё";
App::$strings["Sorry! Editing of recurrent events is not yet implemented."] = "Простите, но редактирование повторяющихся событий пока не реализовано.";
-App::$strings["Name"] = "Имя";
App::$strings["Organisation"] = "Организация";
App::$strings["Title"] = "Наименование";
App::$strings["Phone"] = "Телефон";
-App::$strings["Email"] = "Электронная почта";
App::$strings["Instant messenger"] = "Мессенджер";
App::$strings["Website"] = "Веб-сайт";
App::$strings["Address"] = "Адрес";
App::$strings["Note"] = "Заметка";
-App::$strings["Mobile"] = "Мобильный";
-App::$strings["Home"] = "Домашний";
-App::$strings["Work"] = "Рабочий";
App::$strings["Add Contact"] = "Добавить контакт";
App::$strings["Add Field"] = "Добавить поле";
App::$strings["Update"] = "Обновить";
@@ -148,105 +1107,215 @@ App::$strings["ZIP Code"] = "Индекс";
App::$strings["Country"] = "Страна";
App::$strings["Default Calendar"] = "Календарь по умолчанию";
App::$strings["Default Addressbook"] = "Адресная книга по умолчанию";
-App::$strings["This site is not a directory server"] = "Этот сайт не является сервером каталога";
-App::$strings["Permission category name is required."] = "Требуется категория разрешений.";
-App::$strings["Permission category saved."] = "Категория разрешения сохранена.";
-App::$strings["Permission Categories App"] = "Приложение \"Категории разрешений\"";
-App::$strings["Create custom connection permission limits"] = "Создать пользовательские ограничения на доступ к подключению";
-App::$strings["Use this form to create permission rules for various classes of people or connections."] = "Используйте эту форму для создания правил разрешений для различных групп людей и контактов.";
-App::$strings["Permission Categories"] = "Категории разрешений";
-App::$strings["Permission category name"] = "Наименование категории разрешений";
-App::$strings["My Settings"] = "Мои настройки";
-App::$strings["inherited"] = "наследуется";
-App::$strings["Individual Permissions"] = "Индивидуальные разрешения";
-App::$strings["Some permissions may be inherited from your channel's <a href=\"settings\"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can <strong>not</strong> change those settings here."] = "Некоторые разрешения могут наследовать из <a href=\"settings\"><strong>настроек приватности</strong></a> ваших каналов которые могут иметь более высокий приоритет чем индивидуальные. Вы <strong>не можете</strong> менять эти настройки здесь.";
-App::$strings["You must be logged in to see this page."] = "Вы должны авторизоваться, чтобы увидеть эту страницу.";
App::$strings["Posts and comments"] = "Публикации и комментарии";
App::$strings["Only posts"] = "Только публикации";
-App::$strings["Insufficient permissions. Request redirected to profile page."] = "Недостаточно прав. Запрос перенаправлен на страницу профиля.";
-App::$strings["Search Results For:"] = "Результаты поиска для:";
-App::$strings["Reset form"] = "Очистить форму";
-App::$strings["You must enable javascript for your browser to be able to view this content."] = "Для просмотра этого содержимого в вашем браузере должен быть включён JavaScript";
-App::$strings["Language App"] = "Приложение \"Язык\"";
-App::$strings["Change UI language"] = "Изменить язык интерфейса";
-App::$strings["Channel Export App"] = "Приложение \"Экспорт канала\"";
-App::$strings["Export your channel"] = "Экспортировать ваш канал";
-App::$strings["Export Channel"] = "Экспорт канала";
-App::$strings["Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content."] = "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер.";
-App::$strings["Export Content"] = "Экспортировать содержимое";
-App::$strings["Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin."] = "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка.";
-App::$strings["Export your posts from a given year."] = "Экспортировать ваши публикации за данный год.";
-App::$strings["You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range."] = "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат.";
-App::$strings["To select all posts for a given year, such as this year, visit <a href=\"%1\$s\">%2\$s</a>"] = "Для выбора всех публикаций заданного года, например текущего, посетите <a href=\"%1\$s\">%2\$s</a>";
-App::$strings["To select all posts for a given month, such as January of this year, visit <a href=\"%1\$s\">%2\$s</a>"] = "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите <a href=\"%1\$s\">%2\$s</a>";
-App::$strings["These content files may be imported or restored by visiting <a href=\"%1\$s\">%2\$s</a> on any site containing your channel. For best results please import or restore these in date order (oldest first)."] = "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите <a href=\"%1\$s\">%2\$s</a>. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала).";
-App::$strings["Welcome to Hubzilla!"] = "Добро пожаловать в Hubzilla!";
-App::$strings["You have got no unseen posts..."] = "У вас нет видимых публикаций...";
-App::$strings["Public access denied."] = "Публичный доступ запрещен.";
-App::$strings["Search"] = "Поиск";
-App::$strings["Items tagged with: %s"] = "Объекты помечены как: %s";
-App::$strings["Search results for: %s"] = "Результаты поиска для: %s";
-App::$strings["Public Stream App"] = "Приложение \"Публичный поток\"";
-App::$strings["The unmoderated public stream of this hub"] = "Немодерируемый публичный поток с этого хаба";
-App::$strings["Public Stream"] = "Публичный поток";
-App::$strings["Location not found."] = "Местоположение не найдено";
-App::$strings["Location lookup failed."] = "Поиск местоположения не удался";
-App::$strings["Please select another location to become primary before removing the primary location."] = "Пожалуйста, выберите другое местоположение в качестве основного прежде чем удалить предыдущее";
-App::$strings["Syncing locations"] = "Синхронизировать местоположение";
-App::$strings["No locations found."] = "Местоположений не найдено";
-App::$strings["Manage Channel Locations"] = "Управление местоположением канала";
-App::$strings["Primary"] = "Основной";
-App::$strings["Drop"] = "Удалить";
-App::$strings["Sync Now"] = "Синхронизировать";
-App::$strings["Please wait several minutes between consecutive operations."] = "Пожалуйста, подождите несколько минут между последовательными операциями.";
-App::$strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "По возможности, очистите местоположение, войдя на этот веб-сайт / хаб и удалив свой канал.";
-App::$strings["Use this form to drop the location if the hub is no longer operating."] = "Используйте эту форму, чтобы удалить местоположение, если хаб больше не функционирует.";
-App::$strings["Change Order of Pinned Navbar Apps"] = "Изменить порядок приложений на панели навигации";
-App::$strings["Change Order of App Tray Apps"] = "Изменить порядок приложений в лотке";
-App::$strings["Use arrows to move the corresponding app left (top) or right (bottom) in the navbar"] = "Используйте стрелки для перемещения приложения влево (вверх) или вправо (вниз) в панели навигации";
-App::$strings["Use arrows to move the corresponding app up or down in the app tray"] = "Используйте стрелки для перемещения приложения вверх или вниз в лотке";
-App::$strings["Menu not found."] = "Меню не найдено";
-App::$strings["Unable to create element."] = "Невозможно создать элемент.";
-App::$strings["Unable to update menu element."] = "Невозможно обновить элемент меню.";
-App::$strings["Unable to add menu element."] = "Невозможно добавить элемент меню.";
-App::$strings["Not found."] = "Не найдено.";
-App::$strings["Menu Item Permissions"] = "Разрешения на пункт меню";
-App::$strings["(click to open/close)"] = "(нажмите чтобы открыть/закрыть)";
-App::$strings["Link Name"] = "Имя ссылки";
-App::$strings["Link or Submenu Target"] = "Ссылка или цель подменю";
-App::$strings["Enter URL of the link or select a menu name to create a submenu"] = "Введите URL ссылки или выберите имя меню для создания подменю";
-App::$strings["Use magic-auth if available"] = "Использовать magic-auth если возможно";
-App::$strings["No"] = "Нет";
-App::$strings["Yes"] = "Да";
-App::$strings["Open link in new window"] = "Открыть ссылку в новом окне";
-App::$strings["Order in list"] = "Порядок в списке";
-App::$strings["Higher numbers will sink to bottom of listing"] = "Большие значения в конце списка";
-App::$strings["Submit and finish"] = "Отправить и завершить";
-App::$strings["Submit and continue"] = "Отправить и продолжить";
-App::$strings["Menu:"] = "Меню:";
-App::$strings["Link Target"] = "Цель ссылки";
-App::$strings["Edit menu"] = "Редактировать меню";
-App::$strings["Edit element"] = "Редактировать элемент";
-App::$strings["Drop element"] = "Удалить элемент";
-App::$strings["New element"] = "Новый элемент";
-App::$strings["Edit this menu container"] = "Редактировать контейнер меню";
-App::$strings["Add menu element"] = "Добавить элемент меню";
-App::$strings["Delete this menu item"] = "Удалить этот элемент меню";
-App::$strings["Edit this menu item"] = "Редактировать этот элемент меню";
-App::$strings["Menu item not found."] = "Элемент меню не найден.";
-App::$strings["Menu item deleted."] = "Элемент меню удалён.";
-App::$strings["Menu item could not be deleted."] = "Невозможно удалить элемент меню.";
-App::$strings["Edit Menu Element"] = "Редактировать элемент меню";
-App::$strings["Link text"] = "Текст ссылки";
+App::$strings["vcard"] = "vCard";
+App::$strings["You must be logged in to see this page."] = "Вы должны авторизоваться, чтобы увидеть эту страницу.";
+App::$strings["&#x1f501; Repeated %1\$s's %2\$s"] = "&#x1f501; Повторил %1\$s %2\$s";
+App::$strings["Post repeated"] = "Публикация повторяется";
+App::$strings["No more system notifications."] = "Нет новых оповещений системы.";
+App::$strings["System Notifications"] = "Системные оповещения ";
+App::$strings["%s element installed"] = "%s элемент установлен";
+App::$strings["%s element installation failed"] = "%sустановка элемента неудачна.";
+App::$strings["App installed."] = "Приложение установлено.";
+App::$strings["Malformed app."] = "Неработающее приложение.";
+App::$strings["Embed code"] = "Встроить код";
+App::$strings["Edit App"] = "Редактировать приложение";
+App::$strings["Create App"] = "Создать приложение";
+App::$strings["Name of app"] = "Наименование приложения";
+App::$strings["Location (URL) of app"] = "Местоположение (URL) приложения";
+App::$strings["Photo icon URL"] = "URL пиктограммы";
+App::$strings["80 x 80 pixels - optional"] = "80 x 80 пикселей - необязательно";
+App::$strings["Categories (optional, comma separated list)"] = "Категории (необязательно, список через запятую)";
+App::$strings["Version ID"] = "ID версии";
+App::$strings["Price of app"] = "Цена приложения";
+App::$strings["Location (URL) to purchase app"] = "Ссылка (URL) для покупки приложения";
+App::$strings["Invalid profile identifier."] = "Неверный идентификатор профиля";
+App::$strings["Profile Visibility Editor"] = "Редактор видимости профиля";
+App::$strings["Click on a contact to add or remove."] = "Нажмите на контакт, чтобы добавить или удалить.";
+App::$strings["Visible To"] = "Видно";
+App::$strings["All Connections"] = "Все контакты";
+App::$strings["Channel name changes are not allowed within 48 hours of changing the account password."] = "Изменение названия канала не разрешается в течении 48 часов после смены пароля у аккаунта.";
+App::$strings["Change channel nickname/address"] = "Изменить псевдоним / адрес канала";
+App::$strings["WARNING: "] = "ПРЕДУПРЕЖДЕНИЕ: ";
+App::$strings["Any/all connections on other networks will be lost!"] = "Любые / все контакты в других сетях будут утеряны!";
+App::$strings["Please enter your password for verification:"] = "Пожалуйста, введите ваш пароль для проверки:";
+App::$strings["New channel address"] = "Новый адрес канала";
+App::$strings["Rename Channel"] = "Переименовать канал";
+App::$strings["Accounts"] = "Учётные записи";
+App::$strings["Blocked accounts"] = "Заблокированные аккаунты";
+App::$strings["Expired accounts"] = "Просроченные аккаунты";
+App::$strings["Expiring accounts"] = "Близкие к просрочке аккаунты";
+App::$strings["Channels"] = "Каналы";
+App::$strings["Message queues"] = "Очередь сообщений";
+App::$strings["Your software should be updated"] = "Ваше программное обеспечение должно быть обновлено";
+App::$strings["Administration"] = "Администрирование";
+App::$strings["Summary"] = "Резюме";
+App::$strings["Registered accounts"] = "Зарегистрированные аккаунты";
+App::$strings["Pending registrations"] = "Ждут утверждения";
+App::$strings["Registered channels"] = "Зарегистрированные каналы";
+App::$strings["Active addons"] = "Активные расширения";
+App::$strings["Version"] = "Версия системы";
+App::$strings["Repository version (master)"] = "Версия репозитория (master)";
+App::$strings["Repository version (dev)"] = "Версия репозитория (dev)";
+App::$strings["Profile not found."] = "Профиль не найден.";
+App::$strings["Profile deleted."] = "Профиль удален.";
+App::$strings["Profile-"] = "Профиль -";
+App::$strings["New profile created."] = "Новый профиль создан.";
+App::$strings["Profile unavailable to clone."] = "Профиль недоступен для клонирования.";
+App::$strings["Profile unavailable to export."] = "Профиль недоступен для экспорта.";
+App::$strings["Profile Name is required."] = "Требуется имя профиля.";
+App::$strings["Marital Status"] = "Семейное положение";
+App::$strings["Romantic Partner"] = "Романтический партнер";
+App::$strings["Likes"] = "Нравится";
+App::$strings["Dislikes"] = "Не нравится";
+App::$strings["Work/Employment"] = "Работа / Занятость";
+App::$strings["Religion"] = "Религия";
+App::$strings["Political Views"] = "Политические взгляды";
+App::$strings["Gender"] = "Гендер";
+App::$strings["Sexual Preference"] = "Сексуальная ориентация";
+App::$strings["Homepage"] = "Домашняя страница";
+App::$strings["Interests"] = "Интересы";
+App::$strings["Profile updated."] = "Профиль обновлен.";
+App::$strings["Hide your connections list from viewers of this profile"] = "Скрывать от просмотра ваш список контактов в этом профиле";
+App::$strings["Edit Profile Details"] = "Редактирование профиля";
+App::$strings["View this profile"] = "Посмотреть этот профиль";
+App::$strings["Profile Tools"] = "Инструменты профиля";
+App::$strings["Change cover photo"] = "Изменить фотографию обложки";
+App::$strings["Create a new profile using these settings"] = "Создать новый профиль с теми же настройками";
+App::$strings["Clone this profile"] = "Клонировать этот профиль";
+App::$strings["Delete this profile"] = "Удалить этот профиль";
+App::$strings["Add profile things"] = "Добавить в профиль";
+App::$strings["Personal"] = "Личное";
+App::$strings["Relationship"] = "Отношения";
+App::$strings["Import profile from file"] = "Импортировать профиль из файла";
+App::$strings["Export profile to file"] = "Экспортировать профиль в файл";
+App::$strings["Your gender"] = "Ваш пол";
+App::$strings["Marital status"] = "Семейное положение";
+App::$strings["Sexual preference"] = "Сексуальная ориентация";
+App::$strings["Profile name"] = "Имя профиля";
+App::$strings["This is your default profile."] = "Это ваш профиль по умолчанию.";
+App::$strings["Your full name"] = "Ваше полное имя";
+App::$strings["Title/Description"] = "Заголовок / описание";
+App::$strings["Street address"] = "Улица, дом, квартира";
+App::$strings["Locality/City"] = "Населенный пункт / город";
+App::$strings["Region/State"] = "Регион / Область";
+App::$strings["Postal/Zip code"] = "Почтовый индекс";
+App::$strings["Who (if applicable)"] = "Кто (если применимо)";
+App::$strings["Examples: cathy123, Cathy Williams, cathy@example.com"] = "Примеры: ivan1990, Ivan Petrov, ivan@example.com";
+App::$strings["Since (date)"] = "С (дата)";
+App::$strings["Tell us about yourself"] = "Расскажите нам о себе";
+App::$strings["Homepage URL"] = "URL домашней страницы";
+App::$strings["Hometown"] = "Родной город";
+App::$strings["Political views"] = "Политические взгляды";
+App::$strings["Religious views"] = "Религиозные взгляды";
+App::$strings["Keywords used in directory listings"] = "Ключевые слова для участия в каталоге";
+App::$strings["Example: fishing photography software"] = "Например: fishing photography software";
+App::$strings["Musical interests"] = "Музыкальные интересы";
+App::$strings["Books, literature"] = "Книги, литература";
+App::$strings["Television"] = "Телевидение";
+App::$strings["Film/Dance/Culture/Entertainment"] = "Кино / танцы / культура / развлечения";
+App::$strings["Hobbies/Interests"] = "Хобби / интересы";
+App::$strings["Love/Romance"] = "Любовь / романтические отношения";
+App::$strings["School/Education"] = "Школа / образование";
+App::$strings["Contact information and social networks"] = "Информация и социальные сети для связи";
+App::$strings["My other channels"] = "Мои другие контакты";
+App::$strings["Communications"] = "Связи";
+App::$strings["Create New"] = "Создать новый";
+App::$strings["Page owner information could not be retrieved."] = "Информация о владельце страницы не может быть получена.";
+App::$strings["Album not found."] = "Альбом не найден.";
+App::$strings["Delete Album"] = "Удалить альбом";
+App::$strings["Delete Photo"] = "Удалить фотографию";
+App::$strings["No photos selected"] = "Никакие фотографии не выбраны";
+App::$strings["Access to this item is restricted."] = "Доступ к этому элементу ограничен.";
+App::$strings["%1$.2f MB of %2$.2f MB photo storage used."] = "Вы использовали %1$.2f мегабайт из %2$.2f для хранения фото.";
+App::$strings["%1$.2f MB photo storage used."] = "Вы использовали %1$.2f мегабайт для хранения фото.";
+App::$strings["Upload Photos"] = "Загрузить фотографии";
+App::$strings["Enter an album name"] = "Введите название альбома";
+App::$strings["or select an existing album (doubleclick)"] = "или выберите существующий альбом (двойной щелчок)";
+App::$strings["Create a status post for this upload"] = "Сделать публикацию о статусе для этой загрузки";
+App::$strings["Description (optional)"] = "Описание (необязательно)";
+App::$strings["Show Newest First"] = "Показать новые первыми";
+App::$strings["Show Oldest First"] = "Показать старые первыми";
+App::$strings["View Photo"] = "Посмотреть фотографию";
+App::$strings["Edit Album"] = "Редактировать Фотоальбом";
+App::$strings["Add Photos"] = "Добавить фотографии";
+App::$strings["Permission denied. Access to this item may be restricted."] = "Доступ запрещен. Доступ к этому элементу может быть ограничен.";
+App::$strings["Photo not available"] = "Фотография не доступна";
+App::$strings["Use as profile photo"] = "Использовать в качестве фотографии профиля";
+App::$strings["Use as cover photo"] = "Использовать в качестве фотографии обложки";
+App::$strings["Private Photo"] = "Личная фотография";
+App::$strings["View Full Size"] = "Посмотреть в полный размер";
+App::$strings["Remove"] = "Удалить";
+App::$strings["Edit photo"] = "Редактировать фотографию";
+App::$strings["Rotate CW (right)"] = "Повернуть CW (направо)";
+App::$strings["Rotate CCW (left)"] = "Повернуть CCW (налево)";
+App::$strings["Move photo to album"] = "Переместить фотографию в альбом";
+App::$strings["Enter a new album name"] = "Введите новое название альбома";
+App::$strings["or select an existing one (doubleclick)"] = "или выбрать существующую (двойной щелчок)";
+App::$strings["Add a Tag"] = "Добавить тег";
+App::$strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Пример: @bob, @Barbara_Jensen, @jim@example.com";
+App::$strings["Flag as adult in album view"] = "Пометить как альбом \"для взрослых\"";
+App::$strings["I like this (toggle)"] = "мне это нравится (переключение)";
+App::$strings["I don't like this (toggle)"] = "мне это не нравится (переключение)";
+App::$strings["This is you"] = "Это вы";
+App::$strings["View all"] = "Просмотреть все";
+App::$strings["Photo Tools"] = "Фото-Инструменты";
+App::$strings["In This Photo:"] = "На этой фотографии:";
+App::$strings["Map"] = "Карта";
+App::$strings["__ctx:noun__ Likes"] = "Нравится";
+App::$strings["__ctx:noun__ Dislikes"] = "Не нравится";
+App::$strings["Tag removed"] = "Тег удалён";
+App::$strings["Remove Item Tag"] = "Удалить тег элемента";
+App::$strings["Select a tag to remove: "] = "Выбрать тег для удаления:";
+App::$strings["Channel not found."] = "Канал не найден.";
+App::$strings["toggle full screen mode"] = "переключение полноэкранного режима";
+App::$strings["Invalid item."] = "Недействительный элемент.";
+App::$strings["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."] = "";
+App::$strings["Authorize application connection"] = "Авторизовать подключение приложения";
+App::$strings["Return to your app and insert this Security Code:"] = "Вернитесь к своему приложению и вставьте этот код безопасности:";
+App::$strings["Please login to continue."] = "Пожалуйста, войдите, чтобы продолжить.";
+App::$strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "Вы хотите авторизовать это приложение для доступа к вашим публикациям и контактам и / или созданию новых публикаций?";
+App::$strings["No valid account found."] = "Действительный аккаунт не найден.";
+App::$strings["Password reset request issued. Check your email."] = "Запрос на сброс пароля отправлен. Проверьте вашу электронную почту.";
+App::$strings["Site Member (%s)"] = "Участник сайта (%s)";
+App::$strings["Password reset requested at %s"] = "Запрошен сброс пароля на %s";
+App::$strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Запрос не может быть проверен. (Вы могли отправить его раньше). Сброс пароля не возможен.";
+App::$strings["Your password has been reset as requested."] = "Ваш пароль в соответствии с просьбой сброшен.";
+App::$strings["Your new password is"] = "Ваш новый пароль";
+App::$strings["Save or copy your new password - and then"] = "Сохраните ваш новый пароль и затем";
+App::$strings["click here to login"] = "нажмите здесь чтобы войти";
+App::$strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Ваш пароль может быть изменён на странице <em>Настройки</em> после успешного входа.";
+App::$strings["Your password has changed at %s"] = "Пароль был изменен на %s";
+App::$strings["Forgot your Password?"] = "Забыли ваш пароль?";
+App::$strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Введите ваш адрес электронной почты и нажмите отправить чтобы сбросить пароль. Затем проверьте ваш почтовый ящик для дальнейших инструкций. ";
+App::$strings["Email Address"] = "Адрес электронной почты";
+App::$strings["Reset"] = "Сбросить";
+App::$strings["Name is required"] = "Необходимо имя";
+App::$strings["Key and Secret are required"] = "Требуются ключ и код";
+App::$strings["OAuth Apps Manager App"] = "Приложение \"Менеджер Oauth\"";
+App::$strings["OAuth authentication tokens for mobile and remote apps"] = "Токены аутентификации OAuth для мобильный и удалённых приложений";
+App::$strings["Add application"] = "Добавить приложение";
+App::$strings["Name of application"] = "Название приложения";
+App::$strings["Consumer Key"] = "Ключ клиента";
+App::$strings["Automatically generated - change if desired. Max length 20"] = "Сгенерирован автоматические - измените если требуется. Макс. длина 20";
+App::$strings["Consumer Secret"] = "Код клиента";
+App::$strings["Redirect"] = "Перенаправление";
+App::$strings["Redirect URI - leave blank unless your application specifically requires this"] = "URI перенаправления - оставьте пустыми до тех пока ваше приложение не требует этого";
+App::$strings["Icon url"] = "URL значка";
+App::$strings["Optional"] = "Необязательно";
+App::$strings["Application not found."] = "Приложение не найдено.";
+App::$strings["Connected OAuth Apps"] = "Подключенные приложения OAuth";
+App::$strings["Client key starts with"] = "Ключ клиента начинается с";
+App::$strings["No name"] = "Без названия";
+App::$strings["Remove authorization"] = "Удалить разрешение";
App::$strings["Calendar entries imported."] = "События календаря импортированы.";
App::$strings["No calendar entries found."] = "Не найдено событий в календаре.";
App::$strings["Event can not end before it has started."] = "Событие не может завершиться до его начала.";
App::$strings["Unable to generate preview."] = "Невозможно создать предварительный просмотр.";
App::$strings["Event title and start time are required."] = "Требуются наименование события и время начала.";
App::$strings["Event not found."] = "Событие не найдено.";
-App::$strings["event"] = "событие";
App::$strings["Edit event title"] = "Редактировать наименование события";
-App::$strings["Required"] = "Требуется";
App::$strings["Categories (comma-separated list)"] = "Категории (список через запятую)";
App::$strings["Edit Category"] = "Редактировать категорию";
App::$strings["Category"] = "Категория";
@@ -258,53 +1327,26 @@ App::$strings["Adjust for viewer timezone"] = "Настройте просмот
App::$strings["Important for events that happen in a particular place. Not practical for global holidays."] = "Важно для событий, которые происходят в определённом месте. Не подходит для всеобщих праздников.";
App::$strings["Edit Description"] = "Редактировать описание";
App::$strings["Edit Location"] = "Редактировать местоположение";
-App::$strings["Preview"] = "Предварительный просмотр";
-App::$strings["Permission settings"] = "Настройки разрешений";
App::$strings["Timezone:"] = "Часовой пояс:";
App::$strings["Advanced Options"] = "Дополнительные настройки";
App::$strings["l, F j"] = "";
App::$strings["Edit event"] = "Редактировать событие";
App::$strings["Delete event"] = "Удалить событие";
-App::$strings["Link to Source"] = "Ссылка на источник";
App::$strings["calendar"] = "календарь";
App::$strings["Edit Event"] = "Редактировать событие";
App::$strings["Create Event"] = "Создать событие";
-App::$strings["Export"] = "Экспорт";
+App::$strings["View"] = "Просмотр";
App::$strings["Event removed"] = "Событие удалено";
App::$strings["Failed to remove event"] = "Не удалось удалить событие";
-App::$strings["App installed."] = "Приложение установлено.";
-App::$strings["Malformed app."] = "Неработающее приложение.";
-App::$strings["Embed code"] = "Встроить код";
-App::$strings["Edit App"] = "Редактировать приложение";
-App::$strings["Create App"] = "Создать приложение";
-App::$strings["Name of app"] = "Наименование приложения";
-App::$strings["Location (URL) of app"] = "Местоположение (URL) приложения";
-App::$strings["Photo icon URL"] = "URL пиктограммы";
-App::$strings["80 x 80 pixels - optional"] = "80 x 80 пикселей - необязательно";
-App::$strings["Categories (optional, comma separated list)"] = "Категории (необязательно, список через запятую)";
-App::$strings["Version ID"] = "ID версии";
-App::$strings["Price of app"] = "Цена приложения";
-App::$strings["Location (URL) to purchase app"] = "Ссылка (URL) для покупки приложения";
-App::$strings["Please login."] = "Пожалуйста, войдите.";
-App::$strings["Hub not found."] = "Узел не найден.";
-App::$strings["photo"] = "фото";
-App::$strings["status"] = "статус";
-App::$strings["%1\$s is following %2\$s's %3\$s"] = "%1\$s отслеживает %2\$s's %3\$s";
-App::$strings["%1\$s stopped following %2\$s's %3\$s"] = "%1\$s прекратил отслеживать %2\$s's %3\$s";
-App::$strings["Channel not found."] = "Канал не найден.";
-App::$strings["Insert web link"] = "Вставить веб-ссылку";
-App::$strings["Title (optional)"] = "Заголовок (необязательно)";
-App::$strings["Edit Article"] = "Редактировать статью";
-App::$strings["Nothing to import."] = "Ничего импортировать.";
-App::$strings["Unable to download data from old server"] = "Невозможно загрузить данные со старого сервера";
-App::$strings["Imported file is empty."] = "Импортированный файл пуст.";
-App::$strings["Warning: Database versions differ by %1\$d updates."] = "Предупреждение: Версия базы данных отличается от %1\$d обновления.";
-App::$strings["Import completed"] = "Импорт завершён.";
-App::$strings["Import Items"] = "Импортировать объекты";
-App::$strings["Use this form to import existing posts and content from an export file."] = "Используйте эту форму для импорта существующих публикаций и содержимого из файла.";
-App::$strings["File to Upload"] = "Файл для загрузки";
+App::$strings["Unknown App"] = "Неизвестное приложение";
+App::$strings["Authorize"] = "Авторизовать";
+App::$strings["Do you authorize the app %s to access your channel data?"] = "Авторизуете ли вы приложение %s для доступа к данным вашего канала?";
+App::$strings["Allow"] = "Разрешить";
+App::$strings["Deny"] = "Запретить";
+App::$strings["Public Stream App"] = "Приложение \"Публичный поток\"";
+App::$strings["The unmoderated public stream of this hub"] = "Немодерируемый публичный поток с этого хаба";
+App::$strings["Public Stream"] = "Публичный поток";
App::$strings["You have created %1$.0f of %2$.0f allowed channels."] = "Вы создали %1$.0f из %2$.0f возможных каналов.";
-App::$strings["Loading"] = "Загрузка";
App::$strings["Your real name is recommended."] = "Рекомендуется использовать ваше настоящее имя.";
App::$strings["Examples: \"Bob Jameson\", \"Lisa and her Horses\", \"Soccer\", \"Aviation Group\""] = "Примеры: \"Иван Иванов\", \"Оксана и кони\", \"Футбол\", \"Тимур и его команда\"";
App::$strings["This will be used to create a unique network address (like an email address)."] = "Это будет использовано для создания уникального сетевого адреса (наподобие email).";
@@ -318,21 +1360,386 @@ App::$strings["Create a Channel"] = "Создать канал";
App::$strings["A channel is a unique network identity. It can represent a person (social network profile), a forum (group), a business or celebrity page, a newsfeed, and many other things."] = "Канал это уникальная сетевая идентичность. Он может представлять человека (профиль в социальной сети), форум или группу, бизнес или страницу знаменитости, новостную ленту и многие другие вещи.";
App::$strings["or <a href=\"import\">import an existing channel</a> from another location."] = "или <a href=\"import\">импортировать существующий канал</a> из другого места.";
App::$strings["Validate"] = "Проверить";
+App::$strings["Image uploaded but image cropping failed."] = "Изображение загружено но обрезка не удалась.";
+App::$strings["Cover Photos"] = "Фотографии обложки";
+App::$strings["Image resize failed."] = "Не удалось изменить размер изображения.";
+App::$strings["Image upload failed."] = "Загрузка изображения не удалась.";
+App::$strings["Unable to process image."] = "Невозможно обработать изображение.";
+App::$strings["Photo not available."] = "Фотография недоступна.";
+App::$strings["Your cover photo may be visible to anybody on the internet"] = "Фотография вашей обложки может быть видна всем в Интернете";
+App::$strings["Upload File:"] = "Загрузить файл:";
+App::$strings["Select a profile:"] = "Выбрать профиль:";
+App::$strings["Change Cover Photo"] = "Изменить фотографию обложки";
+App::$strings["Use a photo from your albums"] = "Использовать фотографию из ваших альбомов";
+App::$strings["Choose a different album"] = "Выбрать другой альбом";
+App::$strings["Select existing photo"] = "Выбрать существующую фотографию";
+App::$strings["Crop Image"] = "Обрезать изображение";
+App::$strings["Please adjust the image cropping for optimum viewing."] = "Пожалуйста настройте обрезку изображения для оптимального просмотра.";
+App::$strings["Done Editing"] = "Закончить редактирование";
+App::$strings["Files: shared with me"] = "Файлы: поделились со мной";
+App::$strings["NEW"] = "НОВОЕ";
+App::$strings["Remove all files"] = "Удалить все файлы";
+App::$strings["Remove this file"] = "Удалить этот файл";
+App::$strings["Maximum daily site registrations exceeded. Please try again tomorrow."] = "Превышено максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра.";
+App::$strings["Please indicate acceptance of the Terms of Service. Registration failed."] = "Пожалуйста, подтвердите согласие с \"Условиями обслуживания\". Регистрация не удалась.";
+App::$strings["Passwords do not match."] = "Пароли не совпадают.";
+App::$strings["Registration successful. Continue to create your first channel..."] = "Регистрация завершена успешно. Для продолжения создайте свой первый канал...";
+App::$strings["Registration successful. Please check your email for validation instructions."] = "Регистрация завершена успешно. Пожалуйста проверьте вашу электронную почту для подтверждения.";
+App::$strings["Your registration is pending approval by the site owner."] = "Ваша регистрация ожидает одобрения администрации сайта.";
+App::$strings["Your registration can not be processed."] = "Ваша регистрация не может быть обработана.";
+App::$strings["Registration on this hub is disabled."] = "Регистрация на этом хабе отключена.";
+App::$strings["Registration on this hub is by approval only."] = "Регистрация на этом хабе только по утверждению.";
+App::$strings["<a href=\"pubsites\">Register at another affiliated hub.</a>"] = "<a href=\"pubsites\">Зарегистрироваться на другом хабе.</a>";
+App::$strings["Registration on this hub is by invitation only."] = "Регистрация на этом хабе доступна только по приглашениям.";
+App::$strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Этот сайт превысил максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра. ";
+App::$strings["Terms of Service"] = "Условия предоставления услуг";
+App::$strings["I accept the %s for this website"] = "Я принимаю %s для этого веб-сайта.";
+App::$strings["I am over %s years of age and accept the %s for this website"] = "Мой возраст превышает %s лет и я принимаю %s для этого веб-сайта.";
+App::$strings["Your email address"] = "Ваш адрес электронной почты";
+App::$strings["Choose a password"] = "Выберите пароль";
+App::$strings["Please re-enter your password"] = "Пожалуйста, введите пароль еще раз";
+App::$strings["Please enter your invitation code"] = "Пожалуйста, введите Ваш код приглашения";
+App::$strings["Your Name"] = "Ваше имя";
+App::$strings["Real names are preferred."] = "Предпочтительны реальные имена.";
+App::$strings["Your nickname will be used to create an easy to remember channel address e.g. nickname%s"] = "Ваш псевдоним будет использован для создания легко запоминаемого адреса канала, напр. nickname %s";
+App::$strings["Select a channel permission role for your usage needs and privacy requirements."] = "Выберите разрешения для канала в зависимости от ваших потребностей и требований приватности.";
+App::$strings["no"] = "нет";
+App::$strings["yes"] = "да";
+App::$strings["Registration"] = "Регистрация";
+App::$strings["This site requires email verification. After completing this form, please check your email for further instructions."] = "Этот сайт требует проверку адреса электронной почты. После заполнения этой формы, пожалуйста, проверьте ваш почтовый ящик для дальнейших инструкций.";
+App::$strings["Change Order of Pinned Navbar Apps"] = "Изменить порядок приложений на панели навигации";
+App::$strings["Change Order of App Tray Apps"] = "Изменить порядок приложений в лотке";
+App::$strings["Use arrows to move the corresponding app left (top) or right (bottom) in the navbar"] = "Используйте стрелки для перемещения приложения влево (вверх) или вправо (вниз) в панели навигации";
+App::$strings["Use arrows to move the corresponding app up or down in the app tray"] = "Используйте стрелки для перемещения приложения вверх или вниз в лотке";
+App::$strings["Documentation Search"] = "Поиск документации";
+App::$strings["Members"] = "Участники";
+App::$strings["Administrators"] = "Администраторы";
+App::$strings["Developers"] = "Разработчики";
+App::$strings["Tutorials"] = "Руководства";
+App::$strings["\$Projectname Documentation"] = "\$Projectname Документация";
+App::$strings["Contents"] = "Содержимое";
+App::$strings["No connections."] = "Контактов нет.";
+App::$strings["Visit %s's profile [%s]"] = "Посетить %s ​​профиль [%s]";
+App::$strings["View Connections"] = "Просмотр контактов";
+App::$strings["Website:"] = "Веб-сайт:";
+App::$strings["Remote Channel [%s] (not yet known on this site)"] = "Удалённый канал [%s] (пока неизвестен на этом сайте)";
+App::$strings["Rating (this information is public)"] = "Оценка (эта информация общедоступна)";
+App::$strings["Optionally explain your rating (this information is public)"] = "Объясните свою оценку (необязательно; эта информация общедоступна)";
+App::$strings["Please login."] = "Пожалуйста, войдите.";
+App::$strings["Location not found."] = "Местоположение не найдено";
+App::$strings["Location lookup failed."] = "Поиск местоположения не удался";
+App::$strings["Please select another location to become primary before removing the primary location."] = "Пожалуйста, выберите другое местоположение в качестве основного прежде чем удалить предыдущее";
+App::$strings["Syncing locations"] = "Синхронизировать местоположение";
+App::$strings["No locations found."] = "Местоположений не найдено";
+App::$strings["Manage Channel Locations"] = "Управление местоположением канала";
+App::$strings["Primary"] = "Основной";
+App::$strings["Drop"] = "Удалить";
+App::$strings["Sync Now"] = "Синхронизировать";
+App::$strings["Please wait several minutes between consecutive operations."] = "Пожалуйста, подождите несколько минут между последовательными операциями.";
+App::$strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "По возможности, очистите местоположение, войдя на этот веб-сайт / хаб и удалив свой канал.";
+App::$strings["Use this form to drop the location if the hub is no longer operating."] = "Используйте эту форму, чтобы удалить местоположение, если хаб больше не функционирует.";
+App::$strings["Failed to create source. No channel selected."] = "Не удалось создать источник. Канал не выбран.";
+App::$strings["Source created."] = "Источник создан.";
+App::$strings["Source updated."] = "Источник обновлен.";
+App::$strings["Sources App"] = "Приложение \"Источники канала\"";
+App::$strings["Automatically import channel content from other channels or feeds"] = "Автоматический импорт контента из других каналов или лент";
+App::$strings["*"] = "";
+App::$strings["Channel Sources"] = "Источники канала";
+App::$strings["Manage remote sources of content for your channel."] = "Управление удалённым источниками содержимого для вашего канала";
+App::$strings["New Source"] = "Новый источник";
+App::$strings["Import all or selected content from the following channel into this channel and distribute it according to your channel settings."] = "Импортировать всё или выбранное содержимое из следующего канала в этот канал и распределить его в соответствии с вашими настройками.";
+App::$strings["Only import content with these words (one per line)"] = "Импортировать содержимое только с этим текстом (построчно)";
+App::$strings["Leave blank to import all public content"] = "Оставьте пустым для импорта всего общедоступного содержимого";
+App::$strings["Channel Name"] = "Название канала";
+App::$strings["Add the following categories to posts imported from this source (comma separated)"] = "Добавить следующие категории к импортированным публикациям из этого источника (через запятые)";
+App::$strings["Resend posts with this channel as author"] = "Отправить публикации в этот канал повторно как автор";
+App::$strings["Copyrights may apply"] = "Могут применяться авторские права";
+App::$strings["Source not found."] = "Источник не найден.";
+App::$strings["Edit Source"] = "Редактировать источник";
+App::$strings["Delete Source"] = "Удалить источник";
+App::$strings["Source removed"] = "Источник удален";
+App::$strings["Unable to remove source."] = "Невозможно удалить источник.";
+App::$strings["Chatrooms App"] = "Приложение \"Мои чаты\"";
+App::$strings["Access Controlled Chatrooms"] = "Получить доступ к контролируемым чатам";
+App::$strings["Room not found"] = "Комната не найдена";
+App::$strings["Leave Room"] = "Покинуть комнату";
+App::$strings["Delete Room"] = "Удалить комнату";
+App::$strings["I am away right now"] = "Я сейчас отошёл";
+App::$strings["I am online"] = "Я на связи";
+App::$strings["Bookmark this room"] = "Запомнить эту комнату";
+App::$strings["New Chatroom"] = "Новый чат";
+App::$strings["Chatroom name"] = "Название чата";
+App::$strings["Expiration of chats (minutes)"] = "Завершение чатов (минут)";
+App::$strings["%1\$s's Chatrooms"] = "Чаты пользователя %1\$s";
+App::$strings["No chatrooms available"] = "Нет доступных чатов";
+App::$strings["Expiration"] = "Срок действия";
+App::$strings["min"] = "мин.";
+App::$strings["Name and Secret are required"] = "Требуются имя и код";
+App::$strings["OAuth2 Apps Manager App"] = "Приложение \"Менеджер Oauth2\"";
+App::$strings["OAuth2 authenticatication tokens for mobile and remote apps"] = "Аутентификация OAuth2 для мобильных и удаленных приложений";
+App::$strings["Add OAuth2 application"] = "Добавить приложение OAuth2";
+App::$strings["Grant Types"] = "Разрешить типы";
+App::$strings["leave blank unless your application sepcifically requires this"] = "оставьте пустыми до тех пока ваше приложение не требует этого";
+App::$strings["Authorization scope"] = "Область полномочий";
+App::$strings["OAuth2 Application not found."] = "Приложение OAuth2 не найдено.";
+App::$strings["leave blank unless your application specifically requires this"] = "оставьте поле пустым, если ваше приложение не требует этого";
+App::$strings["Connected OAuth2 Apps"] = "Подключённые приложения OAuth2";
+App::$strings["Channel Manager Settings"] = "Настройки менеджера канала";
+App::$strings["CalDAV Settings"] = "Настройки CalDAV";
+App::$strings["Not valid email."] = "Не действительный адрес email.";
+App::$strings["Protected email address. Cannot change to that email."] = "Защищенный адрес электронной почты. Нельзя изменить.";
+App::$strings["System failure storing new email. Please try again."] = "Системная ошибка сохранения email. Пожалуйста попробуйте ещё раз.";
+App::$strings["Password verification failed."] = "Не удалось выполнить проверку пароля.";
+App::$strings["Passwords do not match. Password unchanged."] = "Пароли не совпадают. Пароль не изменён.";
+App::$strings["Empty passwords are not allowed. Password unchanged."] = "Пустые пароли не допускаются. Пароль не изменён.";
+App::$strings["Password changed."] = "Пароль изменен.";
+App::$strings["Password update failed. Please try again."] = "Изменение пароля не удалось. Пожалуйста, попробуйте ещё раз.";
+App::$strings["Account Settings"] = "Настройки аккаунта";
+App::$strings["Current Password"] = "Текущий пароль";
+App::$strings["Enter New Password"] = "Введите новый пароль:";
+App::$strings["Confirm New Password"] = "Подтвердите новый пароль:";
+App::$strings["Leave password fields blank unless changing"] = "Оставьте поля пустыми до измнения";
+App::$strings["Email Address:"] = "Адрес email:";
+App::$strings["Remove Account"] = "Удалить аккаунт";
+App::$strings["Remove this account including all its channels"] = "Удалить этот аккаунт включая все каналы";
+App::$strings["Settings saved."] = "Настройки сохранены.";
+App::$strings["Settings saved. Reload page please."] = "Настройки сохранены. Пожалуйста, перезагрузите страницу.";
+App::$strings["Conversation Settings"] = "Настройки бесед";
+App::$strings["Editor Settings"] = "Настройки редактора";
+App::$strings["%s - (Incompatible)"] = "%s - (несовместимо)";
+App::$strings["%s - (Experimental)"] = "%s - (экспериментальный)";
+App::$strings["Display Settings"] = "Настройки отображения";
+App::$strings["Theme Settings"] = "Настройки темы";
+App::$strings["Custom Theme Settings"] = "Дополнительные настройки темы";
+App::$strings["Content Settings"] = "Настройки содержимого";
+App::$strings["Display Theme:"] = "Тема отображения:";
+App::$strings["Select scheme"] = "Выбрать схему";
+App::$strings["Preload images before rendering the page"] = "Предзагрузка изображений перед обработкой страницы";
+App::$strings["The subjective page load time will be longer but the page will be ready when displayed"] = "Субъективное время загрузки страницы будет длиннее, но страница будет готова при отображении";
+App::$strings["Enable user zoom on mobile devices"] = "Включить масштабирование на мобильных устройствах";
+App::$strings["Update browser every xx seconds"] = "Обновление браузера каждые N секунд";
+App::$strings["Minimum of 10 seconds, no maximum"] = "Минимум 10 секунд, без максимума";
+App::$strings["Maximum number of conversations to load at any time:"] = "Максимальное количество бесед для загрузки одновременно:";
+App::$strings["Maximum of 100 items"] = "Максимум 100 элементов";
+App::$strings["Show emoticons (smilies) as images"] = "Показывать эмотиконы (смайлики) как изображения";
+App::$strings["Provide channel menu in navigation bar"] = "Показывать меню канала в панели навигации";
+App::$strings["Default: channel menu located in app menu"] = "По умолчанию каналы расположены в меню приложения";
+App::$strings["Manual conversation updates"] = "Обновление бесед вручную";
+App::$strings["Default is on, turning this off may increase screen jumping"] = "Включено по умолчанию, выключение может привести к рывкам в отображении";
+App::$strings["Link post titles to source"] = "Ссылки на источник заголовков публикаций";
+App::$strings["New Member Links"] = "Ссылки для новичков";
+App::$strings["Display new member quick links menu"] = "Показать меню быстрых ссылок для новых участников";
+App::$strings["Additional Features"] = "Дополнительные функции";
+App::$strings["Max height of content (in pixels)"] = "Максимальная высота содержимого (в пикселях)";
+App::$strings["Click to expand content exceeding this height"] = "Нажмите чтобы развернуть содержимое превышающее эту высоту";
+App::$strings["Stream Settings"] = "Настройки потока";
+App::$strings["Events Settings"] = "Настройки событий";
+App::$strings["Personal menu to display in your channel pages"] = "Персональное меню для отображения на странице вашего канала";
+App::$strings["Channel Home Settings"] = "Настройки главной страницы канала";
+App::$strings["Directory Settings"] = "Настройки каталога";
+App::$strings["Photos Settings"] = "Настройки фотографий";
+App::$strings["Profiles Settings"] = "Настройки профилей";
+App::$strings["No feature settings configured"] = "Параметры функций не настроены";
+App::$strings["Addon Settings"] = "Настройки расширений";
+App::$strings["Please save/submit changes to any panel before opening another."] = "Пожалуйста сохраните / отправьте изменения на панели прежде чем открывать другую.";
+App::$strings["Connections Settings"] = "Настройки контактов";
+App::$strings["Nobody except yourself"] = "Никто кроме вас";
+App::$strings["Only those you specifically allow"] = "Только персонально разрешённые";
+App::$strings["Approved connections"] = "Одобренные контакты";
+App::$strings["Any connections"] = "Любые контакты";
+App::$strings["Anybody on this website"] = "Любой на этом сайте";
+App::$strings["Anybody in this network"] = "Любой в этой сети";
+App::$strings["Anybody authenticated"] = "Любой аутентифицированный";
+App::$strings["Anybody on the internet"] = "Любой в интернете";
+App::$strings["Publish your default profile in the network directory"] = "Публиковать ваш профиль по умолчанию в сетевом каталоге";
+App::$strings["Allow us to suggest you as a potential friend to new members?"] = "Разрешить предлагать вас как потенциального друга для новых пользователей?";
+App::$strings["or"] = "или";
+App::$strings["Your channel address is"] = "Адрес вашего канала";
+App::$strings["Your files/photos are accessible via WebDAV at"] = "Ваши файлы / фотографии доступны через WebDAV по";
+App::$strings["Automatic membership approval"] = "Членство одобрено автоматически";
+App::$strings["Channel Settings"] = "Настройки канала";
+App::$strings["Basic Settings"] = "Основные настройки";
+App::$strings["Your Timezone:"] = "Часовой пояс:";
+App::$strings["Default Post Location:"] = "Расположение по умолчанию:";
+App::$strings["Geographical location to display on your posts"] = "Показывать географическое положение в ваших публикациях";
+App::$strings["Use Browser Location:"] = "Определять расположение из браузера";
+App::$strings["Adult Content"] = "Содержимое для взрослых";
+App::$strings["This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)"] = "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW";
+App::$strings["Security and Privacy Settings"] = "Безопасность и настройки приватности";
+App::$strings["Your permissions are already configured. Click to view/adjust"] = "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить";
+App::$strings["Hide my online presence"] = "Скрывать моё присутствие онлайн";
+App::$strings["Prevents displaying in your profile that you are online"] = "Предотвращает отображения статуса \"в сети\" в вашем профиле";
+App::$strings["Simple Privacy Settings:"] = "Простые настройки безопасности:";
+App::$strings["Very Public - <em>extremely permissive (should be used with caution)</em>"] = "Полностью открытый - <em>сверхлиберальный (должен использоваться с осторожностью)</em>";
+App::$strings["Typical - <em>default public, privacy when desired (similar to social network permissions but with improved privacy)</em>"] = "Обычный - <em>открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)</em>";
+App::$strings["Private - <em>default private, never open or public</em>"] = "Частный - <em>частный по умочанию, не открытый и не публичный</em>";
+App::$strings["Blocked - <em>default blocked to/from everybody</em>"] = "Закрытый - <em>заблокированный по умолчанию от / для всех</em>";
+App::$strings["Allow others to tag your posts"] = "Разрешить другим отмечать ваши публикации";
+App::$strings["Often used by the community to retro-actively flag inappropriate content"] = "Часто используется сообществом для маркировки неподобающего содержания";
+App::$strings["Channel Permission Limits"] = "Ограничения разрешений канала";
+App::$strings["Expire other channel content after this many days"] = "Храненить содержимое других каналов, дней";
+App::$strings["0 or blank to use the website limit."] = "0 или пусто - использовать настройки сайта.";
+App::$strings["This website expires after %d days."] = "Срок хранения содержимого этого сайта истекает через %d дней";
+App::$strings["This website does not expire imported content."] = "Срок хранения импортированного содержимого этого сайта не ограничен.";
+App::$strings["The website limit takes precedence if lower than your limit."] = "Ограничение сайта имеет приоритет если ниже вашего значения.";
+App::$strings["Maximum Friend Requests/Day:"] = "Запросов в друзья в день:";
+App::$strings["May reduce spam activity"] = "Может ограничить спам активность";
+App::$strings["Default Privacy Group"] = "Группа конфиденциальности по умолчанию";
+App::$strings["(click to open/close)"] = "(нажмите чтобы открыть/закрыть)";
+App::$strings["Use my default audience setting for the type of object published"] = "Использовать настройки аудитории по умолчанию для типа опубликованного объекта";
+App::$strings["Default permissions category"] = "Категория разрешений по умолчанию";
+App::$strings["Maximum private messages per day from unknown people:"] = "Максимально количество сообщений от незнакомых людей, в день:";
+App::$strings["Useful to reduce spamming"] = "Полезно для сокращения количества спама";
+App::$strings["Notification Settings"] = "Настройки уведомлений";
+App::$strings["By default post a status message when:"] = "По умолчанию публиковать новый статус при:";
+App::$strings["accepting a friend request"] = "одобрении запроса в друзья";
+App::$strings["joining a forum/community"] = "вступлении в сообщество / форум";
+App::$strings["making an <em>interesting</em> profile change"] = "<em>интересном</em> изменении профиля";
+App::$strings["Send a notification email when:"] = "Отправить уведомление по email когда:";
+App::$strings["You receive a connection request"] = "вы получили новый запрос контакта";
+App::$strings["Your connections are confirmed"] = "Ваш запрос контакта был одобрен";
+App::$strings["Someone writes on your profile wall"] = "Кто-то написал на стене вашего профиля";
+App::$strings["Someone writes a followup comment"] = "Кто-то пишет комментарий";
+App::$strings["You receive a private message"] = "Вы получили личное сообщение";
+App::$strings["You receive a friend suggestion"] = "Вы получили предложение друзей";
+App::$strings["You are tagged in a post"] = "Вы были отмечены в публикации";
+App::$strings["You are poked/prodded/etc. in a post"] = "Вас толкнули, подтолкнули и т.п. в публикации";
+App::$strings["Someone likes your post/comment"] = "Кому-то нравится ваша публикация / комментарий";
+App::$strings["Show visual notifications including:"] = "Показывать визуальные оповещения включая:";
+App::$strings["Unseen stream activity"] = "Невидимая активность в потоке";
+App::$strings["Unseen channel activity"] = "Невидимая активность в канале";
+App::$strings["Unseen private messages"] = "Невидимые личные сообщения";
+App::$strings["Recommended"] = "Рекомендовано";
+App::$strings["Upcoming events"] = "Грядущие события";
+App::$strings["Events today"] = "События сегодня";
+App::$strings["Upcoming birthdays"] = "Грядущие дни рождения";
+App::$strings["Not available in all themes"] = "Не доступно во всех темах";
+App::$strings["System (personal) notifications"] = "Системные (личные) уведомления";
+App::$strings["System info messages"] = "Сообщения с системной информацией";
+App::$strings["System critical alerts"] = "Критические уведомления системы";
+App::$strings["New connections"] = "Новые контакты";
+App::$strings["System Registrations"] = "Системные регистрации";
+App::$strings["Unseen shared files"] = "Невидимые общие файлы";
+App::$strings["Unseen public stream activity"] = "Невидимая активность в публичном потоке";
+App::$strings["Unseen likes and dislikes"] = "Невидимые лайки и дислайки";
+App::$strings["Unseen forum posts"] = "Невидимые публикации на форуме";
+App::$strings["Email notification hub (hostname)"] = "Центр уведомлений по email (имя хоста)";
+App::$strings["If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s"] = "Если ваш канал зеркалируется в нескольких местах, это ваше предпочтительное местоположение. Это должно предотвратить дублировать уведомлений по email. Например: %s";
+App::$strings["Show new wall posts, private messages and connections under Notices"] = "Показать новые сообщения на стене, личные сообщения и контакты в \"Уведомлениях\"";
+App::$strings["Notify me of events this many days in advance"] = "Уведомлять меня о событиях заранее, дней";
+App::$strings["Must be greater than 0"] = "Должно быть больше 0";
+App::$strings["Advanced Account/Page Type Settings"] = "Дополнительные настройки учётной записи / страницы";
+App::$strings["Change the behaviour of this account for special situations"] = "Изменить поведение этого аккаунта в особых ситуациях";
+App::$strings["Miscellaneous Settings"] = "Дополнительные настройки";
+App::$strings["Default photo upload folder"] = "Каталог загрузки фотографий по умолчанию";
+App::$strings["%Y - current year, %m - current month"] = "%Y - текущий год, %y - текущий месяц";
+App::$strings["Default file upload folder"] = "Каталог загрузки файлов по умолчанию";
+App::$strings["Remove Channel"] = "Удаление канала";
+App::$strings["Remove this channel."] = "Удалить этот канал.";
+App::$strings["This directory server requires an access token"] = "Для доступа к этому серверу каталогов требуется токен";
+App::$strings["Item not found"] = "Элемент не найден";
+App::$strings["Layout Name"] = "Название шаблона";
+App::$strings["Layout Description (Optional)"] = "Описание шаблона (необязательно)";
+App::$strings["Edit Layout"] = "Редактировать шаблон";
+App::$strings["Available Apps"] = "Доступные приложения";
+App::$strings["Installed Apps"] = "Установленные приложения";
+App::$strings["Manage Apps"] = "Управление приложениями";
+App::$strings["Create Custom App"] = "Создать пользовательское приложение";
+App::$strings["File not found."] = "Файл не найден.";
+App::$strings["Permission Denied."] = "Доступ запрещен.";
+App::$strings["Edit file permissions"] = "Редактировать разрешения файла";
+App::$strings["Set/edit permissions"] = "Редактировать разрешения";
+App::$strings["Include all files and sub folders"] = "Включить все файлы и подкаталоги";
+App::$strings["Return to file list"] = "Вернутся к списку файлов";
+App::$strings["Copy/paste this code to attach file to a post"] = "Копировать / вставить этот код для прикрепления файла к публикации";
+App::$strings["Copy/paste this URL to link file from a web page"] = "Копировать / вставить эту URL для ссылки на файл со страницы";
+App::$strings["Share this file"] = "Поделиться этим файлом";
+App::$strings["Show URL to this file"] = "Показать URL этого файла";
+App::$strings["Block Name"] = "Название блока";
+App::$strings["Edit Block"] = "Редактировать блок";
+App::$strings["No service class restrictions found."] = "Ограничений класса обслуживание не найдено.";
+App::$strings["Insufficient permissions. Request redirected to profile page."] = "Недостаточно прав. Запрос перенаправлен на страницу профиля.";
+App::$strings["Channel Export App"] = "Приложение \"Экспорт канала\"";
+App::$strings["Export your channel"] = "Экспортировать ваш канал";
+App::$strings["Export Channel"] = "Экспорт канала";
+App::$strings["Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content."] = "Экспортировать основную информацию из канала в файл. Служит в качестве резервной копии ваших контактов, основных данных и профиля, однако не включает содержимое. Может быть использовано для импорта ваши данных на новый сервер.";
+App::$strings["Export Content"] = "Экспортировать содержимое";
+App::$strings["Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin."] = "Экспортировать информацию из вашего канала и его содержимое в резервную копию в формате JSON которая может быть использована для восстановления или импорта на другом сервере. Сохраняет все ваши контакты, разрешения, данные профиля и публикации за несколько месяцев. Файл может иметь очень большой размер. Пожалуйста, будьте терпеливы и подождите несколько минут пока не начнётся загрузка.";
+App::$strings["Export your posts from a given year."] = "Экспортировать ваши публикации за данный год.";
+App::$strings["You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range."] = "Вы также можете экспортировать ваши публикации и беседы за определённый месяц или год. Выберите дату в панели местоположения в браузере. Если экспорт будет неудачным (это возможно, например, из-за исчерпания памяти на сервере), повторите попытку, выбрав меньший диапазон дат.";
+App::$strings["To select all posts for a given year, such as this year, visit <a href=\"%1\$s\">%2\$s</a>"] = "Для выбора всех публикаций заданного года, например текущего, посетите <a href=\"%1\$s\">%2\$s</a>";
+App::$strings["To select all posts for a given month, such as January of this year, visit <a href=\"%1\$s\">%2\$s</a>"] = "Для выбора всех публикаций заданного месяца, например за январь сего года, посетите <a href=\"%1\$s\">%2\$s</a>";
+App::$strings["These content files may be imported or restored by visiting <a href=\"%1\$s\">%2\$s</a> on any site containing your channel. For best results please import or restore these in date order (oldest first)."] = "Данные файлы с содержимым могут быть импортированы и восстановлены на любом содержащем ваш канал сайте. Посетите <a href=\"%1\$s\">%2\$s</a>. Для лучших результатов пожалуйста производите импорт и восстановление в порядке датировки (старые сначала).";
+App::$strings["Away"] = "Нет на месте";
+App::$strings["Online"] = "В сети";
+App::$strings["Like/Dislike"] = "Нравится / не нравится";
+App::$strings["This action is restricted to members."] = "Это действие доступно только участникам.";
+App::$strings["Please <a href=\"rmagic\">login with your \$Projectname ID</a> or <a href=\"register\">register as a new \$Projectname member</a> to continue."] = "Пожалуйста, для продолжения <a href=\"rmagic\"> войдите с вашим \$Projectname ID</a> или <a href=\"register\">зарегистрируйтесь как новый участник \$Projectname</a>.";
+App::$strings["Invalid request."] = "Неверный запрос.";
+App::$strings["thing"] = "предмет";
+App::$strings["Channel unavailable."] = "Канал недоступен.";
+App::$strings["Previous action reversed."] = "Предыдущее действие отменено.";
+App::$strings["%1\$s agrees with %2\$s's %3\$s"] = "%1\$s согласен с %2\$s %3\$s";
+App::$strings["%1\$s doesn't agree with %2\$s's %3\$s"] = "%1\$s не согласен с %2\$s %3\$s";
+App::$strings["%1\$s abstains from a decision on %2\$s's %3\$s"] = "%1\$s воздерживается от решения по %2\$s%3\$s";
+App::$strings["%1\$s is attending %2\$s's %3\$s"] = "%1\$s посещает %2\$s%3\$s";
+App::$strings["%1\$s is not attending %2\$s's %3\$s"] = "%1\$s не посещает %2\$s%3\$s";
+App::$strings["%1\$s may attend %2\$s's %3\$s"] = "%1\$s может посетить %2\$s%3\$s";
+App::$strings["Action completed."] = "Действие завершено.";
+App::$strings["Thank you."] = "Спасибо.";
+App::$strings["Bookmark added"] = "Закладка добавлена";
+App::$strings["Bookmarks App"] = "Приложение \"Закладки\"";
+App::$strings["Bookmark links from posts and manage them"] = "Поместить ссылки из публикации в закладки и управлять ими";
+App::$strings["My Bookmarks"] = "Мои закладки";
+App::$strings["My Connections Bookmarks"] = "Закладки моих контактов";
+App::$strings["Item not available."] = "Элемент недоступен.";
+App::$strings["Remote Diagnostics App"] = "Приложение \"Удалённая диагностика\"";
+App::$strings["Perform diagnostics on remote channels"] = "Производит диагностику удалённых каналов";
+App::$strings["item"] = "пункт";
+App::$strings["Permissions denied."] = "Доступ запрещен.";
App::$strings["Channel removals are not allowed within 48 hours of changing the account password."] = "Удаление канала не разрешается в течении 48 часов после смены пароля у аккаунта.";
App::$strings["Remove This Channel"] = "Удалить этот канал";
-App::$strings["WARNING: "] = "ПРЕДУПРЕЖДЕНИЕ: ";
App::$strings["This channel will be completely removed from the network. "] = "Этот канал будет полностью удалён из сети. ";
App::$strings["This action is permanent and can not be undone!"] = "Это действие необратимо и не может быть отменено!";
-App::$strings["Please enter your password for verification:"] = "Пожалуйста, введите ваш пароль для проверки:";
App::$strings["Remove this channel and all its clones from the network"] = "Удалить этот канал и все его клоны из сети";
App::$strings["By default only the instance of the channel located on this hub will be removed from the network"] = "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети";
-App::$strings["Remove Channel"] = "Удаление канала";
-App::$strings["Files: shared with me"] = "Файлы: поделились со мной";
-App::$strings["NEW"] = "НОВОЕ";
-App::$strings["Size"] = "Размер";
-App::$strings["Last Modified"] = "Последнее изменение";
-App::$strings["Remove all files"] = "Удалить все файлы";
-App::$strings["Remove this file"] = "Удалить этот файл";
+App::$strings["Unable to update menu."] = "Невозможно обновить меню.";
+App::$strings["Unable to create menu."] = "Невозможно создать меню.";
+App::$strings["Menu Name"] = "Название меню";
+App::$strings["Unique name (not visible on webpage) - required"] = "Уникальное название (не видимо на странице) - требуется";
+App::$strings["Menu Title"] = "Заголовок меню";
+App::$strings["Visible on webpage - leave empty for no title"] = "Видимость на странице - оставьте пустым если не хотите иметь заголовок";
+App::$strings["Allow Bookmarks"] = "Разрешить закладки";
+App::$strings["Menu may be used to store saved bookmarks"] = "Меню может использоваться, чтобы сохранить закладки";
+App::$strings["Submit and proceed"] = "Отправить и обработать";
+App::$strings["Created"] = "Создано";
+App::$strings["Edited"] = "Отредактировано";
+App::$strings["New"] = "Новые";
+App::$strings["Bookmarks allowed"] = "Закладки разрешены";
+App::$strings["Delete this menu"] = "Удалить это меню";
+App::$strings["Edit menu contents"] = "Редактировать содержание меню";
+App::$strings["Edit this menu"] = "Редактировать это меню";
+App::$strings["Menu could not be deleted."] = "Меню не может быть удалено.";
+App::$strings["Menu not found."] = "Меню не найдено";
+App::$strings["Edit Menu"] = "Редактировать меню";
+App::$strings["Add or remove entries to this menu"] = "Добавить или удалить пункты этого меню";
+App::$strings["Menu name"] = "Название меню";
+App::$strings["Must be unique, only seen by you"] = "Должно быть уникальным (видно только вам)";
+App::$strings["Menu title"] = "Заголовок меню";
+App::$strings["Menu title as seen by others"] = "Видимый другими заголовок меню";
+App::$strings["Allow bookmarks"] = "Разрешить закладки";
+App::$strings["No ratings"] = "Оценок нет";
+App::$strings["Rating: "] = "Оценкa:";
+App::$strings["Website: "] = "Веб-сайт:";
+App::$strings["Description: "] = "Описание:";
+App::$strings["Public Hubs"] = "Публичные хабы";
+App::$strings["The listed hubs allow public registration for the \$Projectname network. All hubs in the network are interlinked so membership on any of them conveys membership in the network as a whole. Some hubs may require subscription or provide tiered service plans. The hub itself <strong>may</strong> provide additional details."] = "Указанные хабы разрешают публичную регистрацию для сети \$Projectname. Все хабы в сети взаимосвязаны, поэтому членство в любом из них передает членство во всю сеть. Некоторым хабам может потребоваться подписка или предоставление многоуровневых планов обслуживания. Сам хаб <strong>может</strong> предоставить дополнительные сведения.";
+App::$strings["Hub URL"] = "URL сервера";
+App::$strings["Access Type"] = "Тип доступа";
+App::$strings["Registration Policy"] = "Политика регистрации";
+App::$strings["Stats"] = "Статистика";
+App::$strings["Software"] = "Программное обеспечение";
+App::$strings["Rate"] = "Оценка";
App::$strings["\$Projectname Server - Setup"] = "\$Projectname сервер - Установка";
App::$strings["Could not connect to database."] = "Не удалось подключиться к серверу баз данных.";
App::$strings["Could not connect to specified site URL. Possible SSL certificate or DNS issue."] = "Не удалось подключиться к указанному URL. Вероятно проблема с SSL сертификатом или DNS.";
@@ -360,7 +1767,7 @@ App::$strings["Website URL"] = "URL веб-сайта";
App::$strings["Please use SSL (https) URL if available."] = "Пожалуйста, используйте SSL (https) URL если возможно.";
App::$strings["Please select a default timezone for your website"] = "Пожалуйста, выберите часовой пояс по умолчанию для вашего сайта";
App::$strings["Site settings"] = "Настройки сайта";
-App::$strings["PHP version 5.5 or greater is required."] = "Требуется PHP версии 5.5 или выше";
+App::$strings["PHP version 7.1 or greater is required."] = "Требуется PHP версии 7.1 или старше.";
App::$strings["PHP version"] = "Версия PHP";
App::$strings["Could not find a command line version of PHP in the web server PATH."] = "Не удалось найти консольную версию PHP в путях переменной PATH веб-сервера.";
App::$strings["If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron."] = "Если у вас на сервере не установлена консольная версия PHP вы не сможете запустить фоновый опрос через cron. ";
@@ -424,69 +1831,36 @@ App::$strings["The database configuration file \".htconfig.php\" could not be wr
App::$strings["Errors encountered creating database tables."] = "При создании базы данных возникли ошибки.";
App::$strings["<h1>What next?</h1>"] = "<h1>Что дальше? </h1>";
App::$strings["IMPORTANT: You will need to [manually] setup a scheduled task for the poller."] = "Вам понадобится [вручную] настроить запланированную задачу для опрашивателя.";
-App::$strings["Continue"] = "Продолжить";
-App::$strings["Premium Channel App"] = "Приложение \"Премиальный канал\"";
-App::$strings["Allows you to set restrictions and terms on those that connect with your channel"] = "Позволяет установить ограничения и условия для подключающихся к вашему каналу";
-App::$strings["Premium Channel Setup"] = "Установка премиального канала";
-App::$strings["Enable premium channel connection restrictions"] = "Включить ограничения для премиального канала";
-App::$strings["Please enter your restrictions or conditions, such as paypal receipt, usage guidelines, etc."] = "Пожалуйста введите ваши ограничения или условия, такие, как оплата PayPal, правила использования и т.п.";
-App::$strings["This channel may require additional steps or acknowledgement of the following conditions prior to connecting:"] = "Этот канал до подключения может требовать дополнительных шагов или подтверждений следующих условий:";
-App::$strings["Potential connections will then see the following text before proceeding:"] = "Потенциальные соединения будут видеть следующий предварительный текст:";
-App::$strings["By continuing, I certify that I have complied with any instructions provided on this page."] = "Продолжая, я подтверждаю что я выполнил все условия представленные на данной странице.";
-App::$strings["(No specific instructions have been provided by the channel owner.)"] = "(Владельцем канала не было представлено никаких специальных инструкций.)";
-App::$strings["Restricted or Premium Channel"] = "Ограниченный или премиальный канал";
-App::$strings["Queue Statistics"] = "Статистика очереди";
-App::$strings["Total Entries"] = "Всего записей";
-App::$strings["Priority"] = "Приоритет";
-App::$strings["Destination URL"] = "Конечный URL-адрес";
-App::$strings["Mark hub permanently offline"] = "Пометить хаб как постоянно отключенный";
-App::$strings["Empty queue for this hub"] = "Освободить очередь для этого хаба";
-App::$strings["Last known contact"] = "Последний известный контакт";
-App::$strings["Off"] = "Выкл.";
-App::$strings["On"] = "Вкл.";
+App::$strings["Unable to create element."] = "Невозможно создать элемент.";
+App::$strings["Unable to update menu element."] = "Невозможно обновить элемент меню.";
+App::$strings["Unable to add menu element."] = "Невозможно добавить элемент меню.";
+App::$strings["Menu Item Permissions"] = "Разрешения на пункт меню";
+App::$strings["Link Name"] = "Имя ссылки";
+App::$strings["Link or Submenu Target"] = "Ссылка или цель подменю";
+App::$strings["Enter URL of the link or select a menu name to create a submenu"] = "Введите URL ссылки или выберите имя меню для создания подменю";
+App::$strings["Use magic-auth if available"] = "Использовать magic-auth если возможно";
+App::$strings["Open link in new window"] = "Открыть ссылку в новом окне";
+App::$strings["Order in list"] = "Порядок в списке";
+App::$strings["Higher numbers will sink to bottom of listing"] = "Большие значения в конце списка";
+App::$strings["Submit and finish"] = "Отправить и завершить";
+App::$strings["Submit and continue"] = "Отправить и продолжить";
+App::$strings["Menu:"] = "Меню:";
+App::$strings["Link Target"] = "Цель ссылки";
+App::$strings["Edit menu"] = "Редактировать меню";
+App::$strings["Edit element"] = "Редактировать элемент";
+App::$strings["Drop element"] = "Удалить элемент";
+App::$strings["New element"] = "Новый элемент";
+App::$strings["Edit this menu container"] = "Редактировать контейнер меню";
+App::$strings["Add menu element"] = "Добавить элемент меню";
+App::$strings["Delete this menu item"] = "Удалить этот элемент меню";
+App::$strings["Edit this menu item"] = "Редактировать этот элемент меню";
+App::$strings["Menu item not found."] = "Элемент меню не найден.";
+App::$strings["Menu item deleted."] = "Элемент меню удалён.";
+App::$strings["Menu item could not be deleted."] = "Невозможно удалить элемент меню.";
+App::$strings["Edit Menu Element"] = "Редактировать элемент меню";
+App::$strings["Link text"] = "Текст ссылки";
App::$strings["Lock feature %s"] = "Заблокировать функцию \"%s\"";
App::$strings["Manage Additional Features"] = "Управление дополнительными функциями";
-App::$strings["Update has been marked successful"] = "Обновление было помечено как успешное";
-App::$strings["Executing %s failed. Check system logs."] = "Выполнение %s неудачно. Проверьте системный журнал.";
-App::$strings["Update %s was successfully applied."] = "Обновление %sбыло успешно применено.";
-App::$strings["Update %s did not return a status. Unknown if it succeeded."] = "Обновление %s не вернуло статус. Неизвестно было ли оно успешным.";
-App::$strings["Update function %s could not be found."] = "Функция обновления %sне может быть найдена.";
-App::$strings["Failed Updates"] = "Обновления с ошибками";
-App::$strings["Mark success (if update was manually applied)"] = "Пометить успешным (если обновление было применено вручную)";
-App::$strings["Attempt to execute this update step automatically"] = "Попытаться применить это обновление автоматически";
-App::$strings["No failed updates."] = "Ошибок обновлений нет.";
-App::$strings["%s account blocked/unblocked"] = array(
- 0 => "%s аккаунт блокирован/разблокирован",
- 1 => "%s аккаунта блокированы/разблокированы",
- 2 => "%s аккаунтов блокированы/разблокированы",
-);
-App::$strings["%s account deleted"] = array(
- 0 => "%s аккаунт удалён",
- 1 => "%s аккаунта удалёны",
- 2 => "%s аккаунтов удалёны",
-);
-App::$strings["Account not found"] = "Аккаунт не найден";
-App::$strings["Account '%s' deleted"] = "Аккаунт '%s' удален";
-App::$strings["Account '%s' blocked"] = "Аккаунт '%s' заблокирован";
-App::$strings["Account '%s' unblocked"] = "Аккаунт '%s' разблокирован";
-App::$strings["Administration"] = "Администрирование";
-App::$strings["Accounts"] = "Учётные записи";
-App::$strings["select all"] = "выбрать все";
-App::$strings["Registrations waiting for confirm"] = "Регистрации ждут подтверждения";
-App::$strings["Request date"] = "Дата запроса";
-App::$strings["No registrations."] = "Нет новых регистраций.";
-App::$strings["Approve"] = "Утвердить";
-App::$strings["Deny"] = "Запретить";
-App::$strings["Block"] = "Блокировать";
-App::$strings["Unblock"] = "Разблокировать";
-App::$strings["ID"] = "";
-App::$strings["All Channels"] = "Все каналы";
-App::$strings["Register date"] = "Дата регистрации";
-App::$strings["Last login"] = "Последний вход";
-App::$strings["Expires"] = "Срок действия";
-App::$strings["Service Class"] = "Класс обслуживания";
-App::$strings["Selected accounts will be deleted!\\n\\nEverything these accounts had posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Выбранные учётные записи будут удалены!\n\nВсё что было ими опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?";
-App::$strings["The account {0} will be deleted!\\n\\nEverything this account has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?";
App::$strings["Log settings updated."] = "Настройки журнала обновлены.";
App::$strings["Logs"] = "Журналы";
App::$strings["Clear"] = "Очистить";
@@ -515,31 +1889,66 @@ App::$strings["Channel '%s' censored"] = "Канал '%s' цензурирует
App::$strings["Channel '%s' uncensored"] = "Канал '%s' нецензурируется";
App::$strings["Channel '%s' code allowed"] = "Код в канале '%s' разрешён";
App::$strings["Channel '%s' code disallowed"] = "Код в канале '%s' запрещён";
-App::$strings["Channels"] = "Каналы";
+App::$strings["select all"] = "выбрать все";
App::$strings["Censor"] = "Цензурировать";
App::$strings["Uncensor"] = "Нецензурировать";
App::$strings["Allow Code"] = "Разрешить код";
App::$strings["Disallow Code"] = "Запретить код";
-App::$strings["Channel"] = "Канал";
App::$strings["UID"] = "";
App::$strings["Selected channels will be deleted!\\n\\nEverything that was posted in these channels on this site will be permanently deleted!\\n\\nAre you sure?"] = "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?";
App::$strings["The channel {0} will be deleted!\\n\\nEverything that was posted in this channel on this site will be permanently deleted!\\n\\nAre you sure?"] = "Канал {0} будет удалён!\n\nВсё что было опубликовано в этом канале на этом сайте будет удалено навсегда!\n\nВы уверены?";
-App::$strings["Theme settings updated."] = "Настройки темы обновленны.";
-App::$strings["No themes found."] = "Темы не найдены.";
-App::$strings["Item not found."] = "Элемент не найден.";
+App::$strings["By default, unfiltered HTML is allowed in embedded media. This is inherently insecure."] = "По умолчанию, HTML без фильтрации доступен во встраиваемых медиа. Это небезопасно.";
+App::$strings["The recommended setting is to only allow unfiltered HTML from the following sites:"] = "Рекомендуется настроить разрешения использовать HTML без фильтрации только для следующих сайтов:";
+App::$strings["https://youtube.com/<br />https://www.youtube.com/<br />https://youtu.be/<br />https://vimeo.com/<br />https://soundcloud.com/<br />"] = "";
+App::$strings["All other embedded content will be filtered, <strong>unless</strong> embedded content from that site is explicitly blocked."] = "се остальные встроенные материалы будут отфильтрованы, <strong>если </strong> встроенное содержимое с этого сайта явно заблокировано.";
+App::$strings["Security"] = "Безопасность";
+App::$strings["Block public"] = "Блокировать публичный доступ";
+App::$strings["Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated."] = "Установите флажок для блокировки публичного доступа ко всем другим общедоступным страницам на этом сайте, если вы в настоящее время не аутентифицированы.";
+App::$strings["Provide a cloud root directory"] = "Предоставить корневой каталог в облаке";
+App::$strings["The cloud root directory lists all channel names which provide public files"] = "В корневом каталоге облака показываются все имена каналов, которые предоставляют общедоступные файлы";
+App::$strings["Show total disk space available to cloud uploads"] = "Показывать общее доступное для загрузок место в хранилище";
+App::$strings["Set \"Transport Security\" HTTP header"] = "Установить HTTP-заголовок \"Transport Security\"";
+App::$strings["Set \"Content Security Policy\" HTTP header"] = "Установить HTTP-заголовок \"Content Security Policy\"";
+App::$strings["Allowed email domains"] = "Разрешённые домены email";
+App::$strings["Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains"] = "Список разделённых запятыми доменов для которых разрешена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены.";
+App::$strings["Not allowed email domains"] = "Запрещённые домены email";
+App::$strings["Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined."] = "Список разделённых запятыми доменов для которых запрещена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены до тех пор, пока разрешённые домены не будут указаны.";
+App::$strings["Allow communications only from these sites"] = "Разрешить связь только с этими сайтами";
+App::$strings["One site per line. Leave empty to allow communication from anywhere by default"] = "Один сайт на строку. Оставьте пустым для разрешения взаимодействия без ограничений (по умочанию).";
+App::$strings["Block communications from these sites"] = "Блокировать связь с этими сайтами";
+App::$strings["Allow communications only from these channels"] = "Разрешить связь только для этих каналов";
+App::$strings["One channel (hash) per line. Leave empty to allow from any channel by default"] = "Один канал (или его хэш) на строку. Оставьте пустым для разрешения взаимодействия с любым каналом (по умолчанию).";
+App::$strings["Block communications from these channels"] = "Блокировать связь с этими каналами";
+App::$strings["Only allow embeds from secure (SSL) websites and links."] = "Разрешать встраивание только для безопасных (SSL/TLS) сайтов и ссылок.";
+App::$strings["Allow unfiltered embedded HTML content only from these domains"] = "Разрешить встраивать нефильтруемое HTML-содержимое только для этих доменов";
+App::$strings["One site per line. By default embedded content is filtered."] = "Один сайт на строку. По умолчанию встраиваемое содержимое фильтруется.";
+App::$strings["Block embedded HTML from these domains"] = "Блокировать встраивание HTML-содержимого для этих доменов";
+App::$strings["Plugin %s disabled."] = "Плагин %s отключен.";
+App::$strings["Plugin %s enabled."] = "Плагин %s включен.";
App::$strings["Disable"] = "Запретить";
App::$strings["Enable"] = "Разрешить";
-App::$strings["Screenshot"] = "Снимок экрана";
-App::$strings["Themes"] = "Темы";
+App::$strings["Addons"] = "Расширения";
App::$strings["Toggle"] = "Переключить";
-App::$strings["Settings"] = "Настройки";
App::$strings["Author: "] = "Автор: ";
App::$strings["Maintainer: "] = "Сопровождающий:";
-App::$strings["[Experimental]"] = "[экспериментальный]";
-App::$strings["[Unsupported]"] = "[неподдерживаемый]";
+App::$strings["Minimum project version: "] = "Минимальная версия проекта: ";
+App::$strings["Maximum project version: "] = "Максимальная версия проекта: ";
+App::$strings["Minimum PHP version: "] = "Минимальная версия PHP: ";
+App::$strings["Compatible Server Roles: "] = "Совместимые роли сервера: ";
+App::$strings["Requires: "] = "Необходимо:";
+App::$strings["Disabled - version incompatibility"] = "Отключено - несовместимость версий";
+App::$strings["Enter the public git repository URL of the addon repo."] = "Введите URL публичного репозитория расширений git";
+App::$strings["Addon repo git URL"] = "URL репозитория расширений git";
+App::$strings["Custom repo name"] = "Пользовательское имя репозитория";
+App::$strings["(optional)"] = "(необязательно)";
+App::$strings["Download Addon Repo"] = "Загрузить репозиторий расширений";
+App::$strings["Install new repo"] = "Установить новый репозиторий";
+App::$strings["Install"] = "Установить";
+App::$strings["Manage Repos"] = "Управление репозиториями";
+App::$strings["Installed Addon Repositories"] = "Установленные репозитории расширений";
+App::$strings["Install a New Addon Repository"] = "Установить новый репозиторий расширений";
+App::$strings["Switch branch"] = "Переключить ветку";
App::$strings["Site settings updated."] = "Настройки сайта обновлены.";
-App::$strings["Default"] = "По умолчанию";
-App::$strings["%s - (Incompatible)"] = "%s - (несовместимо)";
App::$strings["mobile"] = "мобильный";
App::$strings["experimental"] = "экспериментальный";
App::$strings["unsupported"] = "неподдерживаемый";
@@ -551,10 +1960,8 @@ App::$strings["My site offers free accounts with optional paid upgrades"] = "Н
App::$strings["Default permission role for new accounts"] = "Разрешения по умолчанию для новых аккаунтов";
App::$strings["This role will be used for the first channel created after registration."] = "Эта роль будет использоваться для первого канала, созданного после регистрации.";
App::$strings["Site"] = "Сайт";
-App::$strings["Registration"] = "Регистрация";
App::$strings["File upload"] = "Загрузка файла";
App::$strings["Policies"] = "Правила";
-App::$strings["Advanced"] = "Дополнительно";
App::$strings["Site name"] = "Название сайта";
App::$strings["Banner/Logo"] = "Баннер / логотип";
App::$strings["Unfiltered HTML/CSS/JS is allowed"] = "Разрешён нефильтруемый HTML/CSS/JS";
@@ -635,27 +2042,6 @@ App::$strings["Page to display after creating a new channel"] = "Страниц
App::$strings["Default: profiles"] = "По умолчанию: profiles";
App::$strings["Optional: site location"] = "Необязательно: место размещения сайта";
App::$strings["Region or country"] = "Регион или страна";
-App::$strings["Plugin %s disabled."] = "Плагин %s отключен.";
-App::$strings["Plugin %s enabled."] = "Плагин %s включен.";
-App::$strings["Addons"] = "Расширения";
-App::$strings["Minimum project version: "] = "Минимальная версия проекта: ";
-App::$strings["Maximum project version: "] = "Максимальная версия проекта: ";
-App::$strings["Minimum PHP version: "] = "Минимальная версия PHP: ";
-App::$strings["Compatible Server Roles: "] = "Совместимые роли сервера: ";
-App::$strings["Requires: "] = "Необходимо:";
-App::$strings["Disabled - version incompatibility"] = "Отключено - несовместимость версий";
-App::$strings["Enter the public git repository URL of the addon repo."] = "Введите URL публичного репозитория расширений git";
-App::$strings["Addon repo git URL"] = "URL репозитория расширений git";
-App::$strings["Custom repo name"] = "Пользовательское имя репозитория";
-App::$strings["(optional)"] = "(необязательно)";
-App::$strings["Download Addon Repo"] = "Загрузить репозиторий расширений";
-App::$strings["Install new repo"] = "Установить новый репозиторий";
-App::$strings["Install"] = "Установить";
-App::$strings["Manage Repos"] = "Управление репозиториями";
-App::$strings["Installed Addon Repositories"] = "Установленные репозитории расширений";
-App::$strings["Install a New Addon Repository"] = "Установить новый репозиторий расширений";
-App::$strings["Switch branch"] = "Переключить ветку";
-App::$strings["Remove"] = "Удалить";
App::$strings["New Profile Field"] = "Поле нового профиля";
App::$strings["Field nickname"] = "Псевдоним поля";
App::$strings["System name of field"] = "Системное имя поля";
@@ -664,7 +2050,6 @@ App::$strings["Field Name"] = "Имя поля";
App::$strings["Label on profile pages"] = "Метка на странице профиля";
App::$strings["Help text"] = "Текст подсказки";
App::$strings["Additional info (optional)"] = "Дополнительная информация (необязательно)";
-App::$strings["Save"] = "Запомнить";
App::$strings["Field definition not found"] = "Определения поля не найдено";
App::$strings["Edit Profile Field"] = "Редактировать поле профиля";
App::$strings["Profile Fields"] = "Поля профиля";
@@ -674,6 +2059,54 @@ App::$strings["(In addition to basic fields)"] = "(к основым полям)
App::$strings["All available fields"] = "Все доступные поля";
App::$strings["Custom Fields"] = "Настраиваемые поля";
App::$strings["Create Custom Field"] = "Создать настраиваемое поле";
+App::$strings["Queue Statistics"] = "Статистика очереди";
+App::$strings["Total Entries"] = "Всего записей";
+App::$strings["Priority"] = "Приоритет";
+App::$strings["Destination URL"] = "Конечный URL-адрес";
+App::$strings["Mark hub permanently offline"] = "Пометить хаб как постоянно отключенный";
+App::$strings["Empty queue for this hub"] = "Освободить очередь для этого хаба";
+App::$strings["Last known contact"] = "Последний известный контакт";
+App::$strings["Theme settings updated."] = "Настройки темы обновленны.";
+App::$strings["No themes found."] = "Темы не найдены.";
+App::$strings["Screenshot"] = "Снимок экрана";
+App::$strings["Themes"] = "Темы";
+App::$strings["[Experimental]"] = "[экспериментальный]";
+App::$strings["[Unsupported]"] = "[неподдерживаемый]";
+App::$strings["%s account blocked/unblocked"] = array(
+ 0 => "%s аккаунт блокирован/разблокирован",
+ 1 => "%s аккаунта блокированы/разблокированы",
+ 2 => "%s аккаунтов блокированы/разблокированы",
+);
+App::$strings["%s account deleted"] = array(
+ 0 => "%s аккаунт удалён",
+ 1 => "%s аккаунта удалёны",
+ 2 => "%s аккаунтов удалёны",
+);
+App::$strings["Account not found"] = "Аккаунт не найден";
+App::$strings["Account '%s' blocked"] = "Аккаунт '%s' заблокирован";
+App::$strings["Account '%s' unblocked"] = "Аккаунт '%s' разблокирован";
+App::$strings["Registrations waiting for confirm"] = "Регистрации ждут подтверждения";
+App::$strings["Request date"] = "Дата запроса";
+App::$strings["No registrations."] = "Нет новых регистраций.";
+App::$strings["Block"] = "Блокировать";
+App::$strings["Unblock"] = "Разблокировать";
+App::$strings["ID"] = "";
+App::$strings["All Channels"] = "Все каналы";
+App::$strings["Register date"] = "Дата регистрации";
+App::$strings["Last login"] = "Последний вход";
+App::$strings["Expires"] = "Срок действия";
+App::$strings["Service Class"] = "Класс обслуживания";
+App::$strings["Selected accounts will be deleted!\\n\\nEverything these accounts had posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Выбранные учётные записи будут удалены!\n\nВсё что было ими опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?";
+App::$strings["The account {0} will be deleted!\\n\\nEverything this account has posted on this site will be permanently deleted!\\n\\nAre you sure?"] = "Этот аккаунт {0} будет удалён!\n\nВсё что им было опубликовано на этом сайте будет удалено навсегда!\n\nВы уверены?";
+App::$strings["Update has been marked successful"] = "Обновление было помечено как успешное";
+App::$strings["Executing %s failed. Check system logs."] = "Выполнение %s неудачно. Проверьте системный журнал.";
+App::$strings["Update %s was successfully applied."] = "Обновление %sбыло успешно применено.";
+App::$strings["Update %s did not return a status. Unknown if it succeeded."] = "Обновление %s не вернуло статус. Неизвестно было ли оно успешным.";
+App::$strings["Update function %s could not be found."] = "Функция обновления %sне может быть найдена.";
+App::$strings["Failed Updates"] = "Обновления с ошибками";
+App::$strings["Mark success (if update was manually applied)"] = "Пометить успешным (если обновление было применено вручную)";
+App::$strings["Attempt to execute this update step automatically"] = "Попытаться применить это обновление автоматически";
+App::$strings["No failed updates."] = "Ошибок обновлений нет.";
App::$strings["Password changed for account %d."] = "Пароль для аккаунта %d изменён.";
App::$strings["Account settings updated."] = "Настройки аккаунта обновлены.";
App::$strings["Account not found."] = "Учётная запись не найдена.";
@@ -682,193 +2115,6 @@ App::$strings["New Password"] = "Новый пароль";
App::$strings["New Password again"] = "Повторите новый пароль";
App::$strings["Account language (for emails)"] = "Язык сообщения для email";
App::$strings["Service class"] = "Класс обслуживания";
-App::$strings["By default, unfiltered HTML is allowed in embedded media. This is inherently insecure."] = "По умолчанию, HTML без фильтрации доступен во встраиваемых медиа. Это небезопасно.";
-App::$strings["The recommended setting is to only allow unfiltered HTML from the following sites:"] = "Рекомендуется настроить разрешения использовать HTML без фильтрации только для следующих сайтов:";
-App::$strings["https://youtube.com/<br />https://www.youtube.com/<br />https://youtu.be/<br />https://vimeo.com/<br />https://soundcloud.com/<br />"] = "";
-App::$strings["All other embedded content will be filtered, <strong>unless</strong> embedded content from that site is explicitly blocked."] = "се остальные встроенные материалы будут отфильтрованы, <strong>если </strong> встроенное содержимое с этого сайта явно заблокировано.";
-App::$strings["Security"] = "Безопасность";
-App::$strings["Block public"] = "Блокировать публичный доступ";
-App::$strings["Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated."] = "Установите флажок для блокировки публичного доступа ко всем другим общедоступным страницам на этом сайте, если вы в настоящее время не аутентифицированы.";
-App::$strings["Provide a cloud root directory"] = "Предоставить корневой каталог в облаке";
-App::$strings["The cloud root directory lists all channel names which provide public files"] = "В корневом каталоге облака показываются все имена каналов, которые предоставляют общедоступные файлы";
-App::$strings["Show total disk space available to cloud uploads"] = "Показывать общее доступное для загрузок место в хранилище";
-App::$strings["Set \"Transport Security\" HTTP header"] = "Установить HTTP-заголовок \"Transport Security\"";
-App::$strings["Set \"Content Security Policy\" HTTP header"] = "Установить HTTP-заголовок \"Content Security Policy\"";
-App::$strings["Allowed email domains"] = "Разрешённые домены email";
-App::$strings["Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains"] = "Список разделённых запятыми доменов для которых разрешена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены.";
-App::$strings["Not allowed email domains"] = "Запрещённые домены email";
-App::$strings["Comma separated list of domains which are not allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains, unless allowed domains have been defined."] = "Список разделённых запятыми доменов для которых запрещена регистрация на этом сайте. Wildcards разрешены. Если пусто то разрешены любые домены до тех пор, пока разрешённые домены не будут указаны.";
-App::$strings["Allow communications only from these sites"] = "Разрешить связь только с этими сайтами";
-App::$strings["One site per line. Leave empty to allow communication from anywhere by default"] = "Один сайт на строку. Оставьте пустым для разрешения взаимодействия без ограничений (по умочанию).";
-App::$strings["Block communications from these sites"] = "Блокировать связь с этими сайтами";
-App::$strings["Allow communications only from these channels"] = "Разрешить связь только для этих каналов";
-App::$strings["One channel (hash) per line. Leave empty to allow from any channel by default"] = "Один канал (или его хэш) на строку. Оставьте пустым для разрешения взаимодействия с любым каналом (по умолчанию).";
-App::$strings["Block communications from these channels"] = "Блокировать связь с этими каналами";
-App::$strings["Only allow embeds from secure (SSL) websites and links."] = "Разрешать встраивание только для безопасных (SSL/TLS) сайтов и ссылок.";
-App::$strings["Allow unfiltered embedded HTML content only from these domains"] = "Разрешить встраивать нефильтруемое HTML-содержимое только для этих доменов";
-App::$strings["One site per line. By default embedded content is filtered."] = "Один сайт на строку. По умолчанию встраиваемое содержимое фильтруется.";
-App::$strings["Block embedded HTML from these domains"] = "Блокировать встраивание HTML-содержимого для этих доменов";
-App::$strings["Remote privacy information not available."] = "Удаленная информация о конфиденциальности недоступна.";
-App::$strings["Visible to:"] = "Видимо для:";
-App::$strings["__ctx:acl__ Profile"] = "Профиль";
-App::$strings["Comment approved"] = "Комментарий одобрен";
-App::$strings["Comment deleted"] = "Комментарий удалён";
-App::$strings["Friends"] = "Друзья";
-App::$strings["Settings updated."] = "Настройки обновлены.";
-App::$strings["Nobody except yourself"] = "Никто кроме вас";
-App::$strings["Only those you specifically allow"] = "Только персонально разрешённые";
-App::$strings["Approved connections"] = "Одобренные контакты";
-App::$strings["Any connections"] = "Любые контакты";
-App::$strings["Anybody on this website"] = "Любой на этом сайте";
-App::$strings["Anybody in this network"] = "Любой в этой сети";
-App::$strings["Anybody authenticated"] = "Любой аутентифицированный";
-App::$strings["Anybody on the internet"] = "Любой в интернете";
-App::$strings["Publish your default profile in the network directory"] = "Публиковать ваш профиль по умолчанию в сетевом каталоге";
-App::$strings["Allow us to suggest you as a potential friend to new members?"] = "Разрешить предлагать вас как потенциального друга для новых пользователей?";
-App::$strings["or"] = "или";
-App::$strings["Your channel address is"] = "Адрес вашего канала";
-App::$strings["Your files/photos are accessible via WebDAV at"] = "Ваши файлы / фотографии доступны через WebDAV по";
-App::$strings["Automatic membership approval"] = "Членство одобрено автоматически";
-App::$strings["If enabled, connection requests will be approved without your interaction"] = "Если включено, запросы контактов будут одобрены без вашего участия";
-App::$strings["Channel Settings"] = "Настройки канала";
-App::$strings["Basic Settings"] = "Основные настройки";
-App::$strings["Full Name:"] = "Полное имя:";
-App::$strings["Email Address:"] = "Адрес email:";
-App::$strings["Your Timezone:"] = "Часовой пояс:";
-App::$strings["Default Post Location:"] = "Расположение по умолчанию:";
-App::$strings["Geographical location to display on your posts"] = "Показывать географическое положение в ваших публикациях";
-App::$strings["Use Browser Location:"] = "Определять расположение из браузера";
-App::$strings["Adult Content"] = "Содержимое для взрослых";
-App::$strings["This channel frequently or regularly publishes adult content. (Please tag any adult material and/or nudity with #NSFW)"] = "Этот канал часто или регулярно публикует содержимое для взрослых. Пожалуйста, помечайте любой такой материал тегом #NSFW";
-App::$strings["Security and Privacy Settings"] = "Безопасность и настройки приватности";
-App::$strings["Your permissions are already configured. Click to view/adjust"] = "Ваши разрешения уже настроены. Нажмите чтобы просмотреть или изменить";
-App::$strings["Hide my online presence"] = "Скрывать моё присутствие онлайн";
-App::$strings["Prevents displaying in your profile that you are online"] = "Предотвращает отображения статуса \"в сети\" в вашем профиле";
-App::$strings["Simple Privacy Settings:"] = "Простые настройки безопасности:";
-App::$strings["Very Public - <em>extremely permissive (should be used with caution)</em>"] = "Полностью открытый - <em>сверхлиберальный (должен использоваться с осторожностью)</em>";
-App::$strings["Typical - <em>default public, privacy when desired (similar to social network permissions but with improved privacy)</em>"] = "Обычный - <em>открытый по умолчанию, приватность по желанию (как в социальных сетях, но с улучшенными настройками)</em>";
-App::$strings["Private - <em>default private, never open or public</em>"] = "Частный - <em>частный по умочанию, не открытый и не публичный</em>";
-App::$strings["Blocked - <em>default blocked to/from everybody</em>"] = "Закрытый - <em>заблокированный по умолчанию от / для всех</em>";
-App::$strings["Allow others to tag your posts"] = "Разрешить другим отмечать ваши публикации";
-App::$strings["Often used by the community to retro-actively flag inappropriate content"] = "Часто используется сообществом для маркировки неподобающего содержания";
-App::$strings["Channel Permission Limits"] = "Ограничения разрешений канала";
-App::$strings["Expire other channel content after this many days"] = "Храненить содержимое других каналов, дней";
-App::$strings["0 or blank to use the website limit."] = "0 или пусто - использовать настройки сайта.";
-App::$strings["This website expires after %d days."] = "Срок хранения содержимого этого сайта истекает через %d дней";
-App::$strings["This website does not expire imported content."] = "Срок хранения импортированного содержимого этого сайта не ограничен.";
-App::$strings["The website limit takes precedence if lower than your limit."] = "Ограничение сайта имеет приоритет если ниже вашего значения.";
-App::$strings["Maximum Friend Requests/Day:"] = "Запросов в друзья в день:";
-App::$strings["May reduce spam activity"] = "Может ограничить спам активность";
-App::$strings["Default Privacy Group"] = "Группа конфиденциальности по умолчанию";
-App::$strings["Use my default audience setting for the type of object published"] = "Использовать настройки аудитории по умолчанию для типа опубликованного объекта";
-App::$strings["Default permissions category"] = "Категория разрешений по умолчанию";
-App::$strings["Maximum private messages per day from unknown people:"] = "Максимально количество сообщений от незнакомых людей, в день:";
-App::$strings["Useful to reduce spamming"] = "Полезно для сокращения количества спама";
-App::$strings["Notification Settings"] = "Настройки уведомлений";
-App::$strings["By default post a status message when:"] = "По умолчанию публиковать новый статус при:";
-App::$strings["accepting a friend request"] = "одобрении запроса в друзья";
-App::$strings["joining a forum/community"] = "вступлении в сообщество / форум";
-App::$strings["making an <em>interesting</em> profile change"] = "<em>интересном</em> изменении профиля";
-App::$strings["Send a notification email when:"] = "Отправить уведомление по email когда:";
-App::$strings["You receive a connection request"] = "вы получили новый запрос контакта";
-App::$strings["Your connections are confirmed"] = "Ваш запрос контакта был одобрен";
-App::$strings["Someone writes on your profile wall"] = "Кто-то написал на стене вашего профиля";
-App::$strings["Someone writes a followup comment"] = "Кто-то пишет комментарий";
-App::$strings["You receive a private message"] = "Вы получили личное сообщение";
-App::$strings["You receive a friend suggestion"] = "Вы получили предложение друзей";
-App::$strings["You are tagged in a post"] = "Вы были отмечены в публикации";
-App::$strings["You are poked/prodded/etc. in a post"] = "Вас толкнули, подтолкнули и т.п. в публикации";
-App::$strings["Someone likes your post/comment"] = "Кому-то нравится ваша публикация / комментарий";
-App::$strings["Show visual notifications including:"] = "Показывать визуальные оповещения включая:";
-App::$strings["Unseen stream activity"] = "Невидимая активность в потоке";
-App::$strings["Unseen channel activity"] = "Невидимая активность в канале";
-App::$strings["Unseen private messages"] = "Невидимые личные сообщения";
-App::$strings["Recommended"] = "Рекомендовано";
-App::$strings["Upcoming events"] = "Грядущие события";
-App::$strings["Events today"] = "События сегодня";
-App::$strings["Upcoming birthdays"] = "Грядущие дни рождения";
-App::$strings["Not available in all themes"] = "Не доступно во всех темах";
-App::$strings["System (personal) notifications"] = "Системные (личные) уведомления";
-App::$strings["System info messages"] = "Сообщения с системной информацией";
-App::$strings["System critical alerts"] = "Критические уведомления системы";
-App::$strings["New connections"] = "Новые контакты";
-App::$strings["System Registrations"] = "Системные регистрации";
-App::$strings["Unseen shared files"] = "Невидимые общие файлы";
-App::$strings["Unseen public stream activity"] = "Невидимая активность в публичном потоке";
-App::$strings["Unseen likes and dislikes"] = "Невидимые лайки и дислайки";
-App::$strings["Unseen forum posts"] = "Невидимые публикации на форуме";
-App::$strings["Email notification hub (hostname)"] = "Центр уведомлений по email (имя хоста)";
-App::$strings["If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s"] = "Если ваш канал зеркалируется в нескольких местах, это ваше предпочтительное местоположение. Это должно предотвратить дублировать уведомлений по email. Например: %s";
-App::$strings["Show new wall posts, private messages and connections under Notices"] = "Показать новые сообщения на стене, личные сообщения и контакты в \"Уведомлениях\"";
-App::$strings["Notify me of events this many days in advance"] = "Уведомлять меня о событиях заранее, дней";
-App::$strings["Must be greater than 0"] = "Должно быть больше 0";
-App::$strings["Advanced Account/Page Type Settings"] = "Дополнительные настройки учётной записи / страницы";
-App::$strings["Change the behaviour of this account for special situations"] = "Изменить поведение этого аккаунта в особых ситуациях";
-App::$strings["Miscellaneous Settings"] = "Дополнительные настройки";
-App::$strings["Default photo upload folder"] = "Каталог загрузки фотографий по умолчанию";
-App::$strings["%Y - current year, %m - current month"] = "%Y - текущий год, %y - текущий месяц";
-App::$strings["Default file upload folder"] = "Каталог загрузки файлов по умолчанию";
-App::$strings["Remove this channel."] = "Удалить этот канал.";
-App::$strings["Additional Features"] = "Дополнительные функции";
-App::$strings["Events Settings"] = "Настройки событий";
-App::$strings["CalDAV Settings"] = "Настройки CalDAV";
-App::$strings["Settings saved."] = "Настройки сохранены.";
-App::$strings["Settings saved. Reload page please."] = "Настройки сохранены. Пожалуйста, перезагрузите страницу.";
-App::$strings["Conversation Settings"] = "Настройки бесед";
-App::$strings["Connections Settings"] = "Настройки контактов";
-App::$strings["Photos Settings"] = "Настройки фотографий";
-App::$strings["Not valid email."] = "Не действительный адрес email.";
-App::$strings["Protected email address. Cannot change to that email."] = "Защищенный адрес электронной почты. Нельзя изменить.";
-App::$strings["System failure storing new email. Please try again."] = "Системная ошибка сохранения email. Пожалуйста попробуйте ещё раз.";
-App::$strings["Password verification failed."] = "Не удалось выполнить проверку пароля.";
-App::$strings["Passwords do not match. Password unchanged."] = "Пароли не совпадают. Пароль не изменён.";
-App::$strings["Empty passwords are not allowed. Password unchanged."] = "Пустые пароли не допускаются. Пароль не изменён.";
-App::$strings["Password changed."] = "Пароль изменен.";
-App::$strings["Password update failed. Please try again."] = "Изменение пароля не удалось. Пожалуйста, попробуйте ещё раз.";
-App::$strings["Account Settings"] = "Настройки аккаунта";
-App::$strings["Current Password"] = "Текущий пароль";
-App::$strings["Enter New Password"] = "Введите новый пароль:";
-App::$strings["Confirm New Password"] = "Подтвердите новый пароль:";
-App::$strings["Leave password fields blank unless changing"] = "Оставьте поля пустыми до измнения";
-App::$strings["Remove Account"] = "Удалить аккаунт";
-App::$strings["Remove this account including all its channels"] = "Удалить этот аккаунт включая все каналы";
-App::$strings["Profiles Settings"] = "Настройки профилей";
-App::$strings["Channel Manager Settings"] = "Настройки менеджера канала";
-App::$strings["No feature settings configured"] = "Параметры функций не настроены";
-App::$strings["Addon Settings"] = "Настройки расширений";
-App::$strings["Please save/submit changes to any panel before opening another."] = "Пожалуйста сохраните / отправьте изменения на панели прежде чем открывать другую.";
-App::$strings["Max height of content (in pixels)"] = "Максимальная высота содержимого (в пикселях)";
-App::$strings["Click to expand content exceeding this height"] = "Нажмите чтобы развернуть содержимое превышающее эту высоту";
-App::$strings["Personal menu to display in your channel pages"] = "Персональное меню для отображения на странице вашего канала";
-App::$strings["Channel Home Settings"] = "Настройки главной страницы канала";
-App::$strings["Directory Settings"] = "Настройки каталога";
-App::$strings["Editor Settings"] = "Настройки редактора";
-App::$strings["%s - (Experimental)"] = "%s - (экспериментальный)";
-App::$strings["Display Settings"] = "Настройки отображения";
-App::$strings["Theme Settings"] = "Настройки темы";
-App::$strings["Custom Theme Settings"] = "Дополнительные настройки темы";
-App::$strings["Content Settings"] = "Настройки содержимого";
-App::$strings["Display Theme:"] = "Тема отображения:";
-App::$strings["Select scheme"] = "Выбрать схему";
-App::$strings["Preload images before rendering the page"] = "Предзагрузка изображений перед обработкой страницы";
-App::$strings["The subjective page load time will be longer but the page will be ready when displayed"] = "Субъективное время загрузки страницы будет длиннее, но страница будет готова при отображении";
-App::$strings["Enable user zoom on mobile devices"] = "Включить масштабирование на мобильных устройствах";
-App::$strings["Update browser every xx seconds"] = "Обновление браузера каждые N секунд";
-App::$strings["Minimum of 10 seconds, no maximum"] = "Минимум 10 секунд, без максимума";
-App::$strings["Maximum number of conversations to load at any time:"] = "Максимальное количество бесед для загрузки одновременно:";
-App::$strings["Maximum of 100 items"] = "Максимум 100 элементов";
-App::$strings["Show emoticons (smilies) as images"] = "Показывать эмотиконы (смайлики) как изображения";
-App::$strings["Provide channel menu in navigation bar"] = "Показывать меню канала в панели навигации";
-App::$strings["Default: channel menu located in app menu"] = "По умолчанию каналы расположены в меню приложения";
-App::$strings["Manual conversation updates"] = "Обновление бесед вручную";
-App::$strings["Default is on, turning this off may increase screen jumping"] = "Включено по умолчанию, выключение может привести к рывкам в отображении";
-App::$strings["Link post titles to source"] = "Ссылки на источник заголовков публикаций";
-App::$strings["New Member Links"] = "Ссылки для новичков";
-App::$strings["Display new member quick links menu"] = "Показать меню быстрых ссылок для новых участников";
-App::$strings["Stream Settings"] = "Настройки потока";
-App::$strings["View Photo"] = "Посмотреть фотографию";
-App::$strings["Edit Album"] = "Редактировать Фотоальбом";
-App::$strings["Upload"] = "Загрузка";
App::$strings["This channel is limited to %d tokens"] = "Этот канал ограничен %d токенами";
App::$strings["Name and Password are required."] = "Требуются имя и пароль.";
App::$strings["Token saved."] = "Токен сохранён.";
@@ -881,7 +2127,12 @@ App::$strings["Login Name"] = "Имя";
App::$strings["Login Password"] = "Пароль";
App::$strings["Expires (yyyy-mm-dd)"] = "Срок действия (yyyy-mm-dd)";
App::$strings["Their Settings"] = "Их настройки";
-App::$strings["Some blurb about what to do when you're new here"] = "Некоторые предложения о том, что делать, если вы здесь новичок ";
+App::$strings["Mark all seen"] = "Отметить как просмотренное";
+App::$strings["%1\$s is following %2\$s's %3\$s"] = "%1\$s отслеживает %2\$s's %3\$s";
+App::$strings["%1\$s stopped following %2\$s's %3\$s"] = "%1\$s прекратил отслеживать %2\$s's %3\$s";
+App::$strings["Edit post"] = "Редактировать сообщение";
+App::$strings["Page link"] = "Ссылка страницы";
+App::$strings["Edit Webpage"] = "Редактировать веб-страницу";
App::$strings["Thing updated"] = "Обновлено";
App::$strings["Object store: failed"] = "Хранлищие объектов: неудача";
App::$strings["Thing added"] = "Добавлено";
@@ -895,296 +2146,43 @@ App::$strings["Only sends to viewers of the applicable profile"] = "Отправ
App::$strings["Name of thing e.g. something"] = "Наименование, например \"нечто\"";
App::$strings["URL of thing (optional)"] = "URL (необязательно)";
App::$strings["URL for photo of thing (optional)"] = "URL для фотографии (необязательно)";
-App::$strings["Permissions"] = "Разрешения";
App::$strings["Add Thing to your Profile"] = "Добавить к вашему профилю";
-App::$strings["No more system notifications."] = "Нет новых оповещений системы.";
-App::$strings["System Notifications"] = "Системные оповещения ";
-App::$strings["Connection added."] = "Контакт добавлен.";
-App::$strings["Your service plan only allows %d channels."] = "Ваш класс обслуживания разрешает только %d каналов.";
-App::$strings["No channel. Import failed."] = "Канала нет. Импорт невозможен.";
-App::$strings["Import completed."] = "Импорт завершен.";
-App::$strings["You must be logged in to use this feature."] = "Вы должны войти в систему, чтобы использовать эту функцию.";
-App::$strings["Import Channel"] = "Импортировать канал";
-App::$strings["Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file."] = "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта.";
-App::$strings["Or provide the old server/hub details"] = "или предоставьте данные старого сервера";
-App::$strings["Your old identity address (xyz@example.com)"] = "Ваш старый адрес идентичности (xyz@example.com)";
-App::$strings["Your old login email address"] = "Ваш старый адрес электронной почты";
-App::$strings["Your old login password"] = "Ваш старый пароль";
-App::$strings["Import a few months of posts if possible (limited by available memory"] = "Импортировать несколько месяцев публикаций если возможно (ограничено доступной памятью)";
-App::$strings["For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media."] = "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа.";
-App::$strings["Make this hub my primary location"] = "Сделать этот хаб главным";
-App::$strings["Move this channel (disable all previous locations)"] = "Переместить это канал (отключить все предыдущие месторасположения)";
-App::$strings["Use this channel nickname instead of the one provided"] = "Использовать псевдоним этого канала вместо предоставленного";
-App::$strings["Leave blank to keep your existing channel nickname. You will be randomly assigned a similar nickname if either name is already allocated on this site."] = "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте.";
-App::$strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Процесс может занять несколько минут. Пожалуйста, отправьте форму только один раз и оставьте эту страницу открытой до завершения.";
-App::$strings["Authentication failed."] = "Ошибка аутентификации.";
-App::$strings["Remote Authentication"] = "Удаленная аутентификация";
-App::$strings["Enter your channel address (e.g. channel@example.com)"] = "Введите адрес вашего канала (например: channel@example.com)";
-App::$strings["Authenticate"] = "Проверка подлинности";
-App::$strings["Name and Secret are required"] = "Требуются имя и код";
-App::$strings["OAuth2 Apps Manager App"] = "Приложение \"Менеджер Oauth2\"";
-App::$strings["OAuth2 authenticatication tokens for mobile and remote apps"] = "Аутентификация OAuth2 для мобильных и удаленных приложений";
-App::$strings["Add OAuth2 application"] = "Добавить приложение OAuth2";
-App::$strings["Name of application"] = "Название приложения";
-App::$strings["Consumer Secret"] = "Код клиента";
-App::$strings["Automatically generated - change if desired. Max length 20"] = "Сгенерирован автоматические - измените если требуется. Макс. длина 20";
-App::$strings["Redirect"] = "Перенаправление";
-App::$strings["Redirect URI - leave blank unless your application specifically requires this"] = "URI перенаправления - оставьте пустыми до тех пока ваше приложение не требует этого";
-App::$strings["Grant Types"] = "Разрешить типы";
-App::$strings["leave blank unless your application sepcifically requires this"] = "оставьте пустыми до тех пока ваше приложение не требует этого";
-App::$strings["Authorization scope"] = "Область полномочий";
-App::$strings["OAuth2 Application not found."] = "Приложение OAuth2 не найдено.";
-App::$strings["Add application"] = "Добавить приложение";
-App::$strings["leave blank unless your application specifically requires this"] = "оставьте поле пустым, если ваше приложение не требует этого";
-App::$strings["Connected OAuth2 Apps"] = "Подключённые приложения OAuth2";
-App::$strings["Client key starts with"] = "Ключ клиента начинается с";
-App::$strings["No name"] = "Без названия";
-App::$strings["Remove authorization"] = "Удалить разрешение";
-App::$strings["Permissions denied."] = "Доступ запрещен.";
-App::$strings["Import"] = "Импортировать";
-App::$strings["Authorize application connection"] = "Авторизовать подключение приложения";
-App::$strings["Return to your app and insert this Security Code:"] = "Вернитесь к своему приложению и вставьте этот код безопасности:";
-App::$strings["Please login to continue."] = "Пожалуйста, войдите, чтобы продолжить.";
-App::$strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "Вы хотите авторизовать это приложение для доступа к вашим публикациям и контактам и / или созданию новых публикаций?";
-App::$strings["Item not available."] = "Элемент недоступен.";
-App::$strings["Random Channel App"] = "Приложение \"Случайный канал\"";
-App::$strings["Visit a random channel in the \$Projectname network"] = "Посещение случайного канала в сети \$Projectname";
-App::$strings["Edit Block"] = "Редактировать блок";
-App::$strings["vcard"] = "vCard";
-App::$strings["Available Apps"] = "Доступные приложения";
-App::$strings["Installed Apps"] = "Установленные приложения";
-App::$strings["Manage Apps"] = "Управление приложениями";
-App::$strings["Create Custom App"] = "Создать пользовательское приложение";
-App::$strings["__ctx:mood__ %1\$s is %2\$s"] = "%1\$s в %2\$s";
-App::$strings["Mood App"] = "Приложение \"Настроение\"";
-App::$strings["Set your current mood and tell your friends"] = "Установить текущее настроение и рассказать друзьям";
-App::$strings["Mood"] = "Настроение";
-App::$strings["Active"] = "Активен";
-App::$strings["Blocked"] = "Заблокирован";
-App::$strings["Ignored"] = "Игнорируется";
-App::$strings["Hidden"] = "Скрыт";
-App::$strings["Archived/Unreachable"] = "Заархивировано / недоступно";
-App::$strings["New"] = "Новые";
-App::$strings["All"] = "Все";
-App::$strings["Active Connections"] = "Активные контакты";
-App::$strings["Show active connections"] = "Показать активные контакты";
-App::$strings["New Connections"] = "Новые контакты";
-App::$strings["Show pending (new) connections"] = "Просмотр (новых) ожидающих контактов";
-App::$strings["Only show blocked connections"] = "Показать только заблокированные контакты";
-App::$strings["Only show ignored connections"] = "Показать только проигнорированные контакты";
-App::$strings["Only show archived/unreachable connections"] = "Показать только заархивированные / недоступные контакты";
-App::$strings["Only show hidden connections"] = "Показать только скрытые контакты";
-App::$strings["Show all connections"] = "Просмотр всех контактов";
-App::$strings["Pending approval"] = "Ожидающие подтверждения";
-App::$strings["Archived"] = "Зархивирован";
-App::$strings["Not connected at this location"] = "Не подключено в этом месте";
-App::$strings["%1\$s [%2\$s]"] = "";
-App::$strings["Edit connection"] = "Редактировать контакт";
-App::$strings["Delete connection"] = "Удалить контакт";
-App::$strings["Channel address"] = "Адрес канала";
-App::$strings["Network"] = "Сеть";
-App::$strings["Call"] = "Вызов";
-App::$strings["Status"] = "Статус";
-App::$strings["Connected"] = "Подключено";
-App::$strings["Approve connection"] = "Утвердить контакт";
-App::$strings["Ignore connection"] = "Игнорировать контакт";
-App::$strings["Ignore"] = "Игнорировать";
-App::$strings["Recent activity"] = "Последние действия";
-App::$strings["Connections"] = "Контакты";
-App::$strings["Search your connections"] = "Поиск ваших контактов";
-App::$strings["Connections search"] = "Поиск контаков";
-App::$strings["Find"] = "Поиск";
-App::$strings["item"] = "пункт";
-App::$strings["Bookmark added"] = "Закладка добавлена";
-App::$strings["Bookmarks App"] = "Приложение \"Закладки\"";
-App::$strings["Bookmark links from posts and manage them"] = "Поместить ссылки из публикации в закладки и управлять ими";
-App::$strings["My Bookmarks"] = "Мои закладки";
-App::$strings["My Connections Bookmarks"] = "Закладки моих контактов";
-App::$strings["Account removals are not allowed within 48 hours of changing the account password."] = "Удаление канала не разрешается в течении 48 часов после смены пароля у аккаунта.";
-App::$strings["Remove This Account"] = "Удалить этот аккаунт";
-App::$strings["This account and all its channels will be completely removed from the network. "] = "Этот аккаунт и все его каналы будут полностью удалены из сети.";
-App::$strings["Remove this account, all its channels and all its channel clones from the network"] = "Удалить этот аккаунт, все его каналы и их клоны из сети.";
-App::$strings["By default only the instances of the channels located on this hub will be removed from the network"] = "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети";
-App::$strings["Page owner information could not be retrieved."] = "Информация о владельце страницы не может быть получена.";
-App::$strings["Album not found."] = "Альбом не найден.";
-App::$strings["Delete Album"] = "Удалить альбом";
-App::$strings["Delete Photo"] = "Удалить фотографию";
-App::$strings["No photos selected"] = "Никакие фотографии не выбраны";
-App::$strings["Access to this item is restricted."] = "Доступ к этому элементу ограничен.";
-App::$strings["%1$.2f MB of %2$.2f MB photo storage used."] = "Вы использовали %1$.2f мегабайт из %2$.2f для хранения фото.";
-App::$strings["%1$.2f MB photo storage used."] = "Вы использовали %1$.2f мегабайт для хранения фото.";
-App::$strings["Upload Photos"] = "Загрузить фотографии";
-App::$strings["Enter an album name"] = "Введите название альбома";
-App::$strings["or select an existing album (doubleclick)"] = "или выберите существующий альбом (двойной щелчок)";
-App::$strings["Create a status post for this upload"] = "Сделать публикацию о статусе для этой загрузки";
-App::$strings["Description (optional)"] = "Описание (необязательно)";
-App::$strings["Show Newest First"] = "Показать новые первыми";
-App::$strings["Show Oldest First"] = "Показать старые первыми";
-App::$strings["Add Photos"] = "Добавить фотографии";
-App::$strings["Permission denied. Access to this item may be restricted."] = "Доступ запрещен. Доступ к этому элементу может быть ограничен.";
-App::$strings["Photo not available"] = "Фотография не доступна";
-App::$strings["Use as profile photo"] = "Использовать в качестве фотографии профиля";
-App::$strings["Use as cover photo"] = "Использовать в качестве фотографии обложки";
-App::$strings["Private Photo"] = "Личная фотография";
-App::$strings["View Full Size"] = "Посмотреть в полный размер";
-App::$strings["Edit photo"] = "Редактировать фотографию";
-App::$strings["Rotate CW (right)"] = "Повернуть CW (направо)";
-App::$strings["Rotate CCW (left)"] = "Повернуть CCW (налево)";
-App::$strings["Move photo to album"] = "Переместить фотографию в альбом";
-App::$strings["Enter a new album name"] = "Введите новое название альбома";
-App::$strings["or select an existing one (doubleclick)"] = "или выбрать существующую (двойной щелчок)";
-App::$strings["Add a Tag"] = "Добавить тег";
-App::$strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Пример: @bob, @Barbara_Jensen, @jim@example.com";
-App::$strings["Flag as adult in album view"] = "Пометить как альбом \"для взрослых\"";
-App::$strings["I like this (toggle)"] = "мне это нравится (переключение)";
-App::$strings["I don't like this (toggle)"] = "мне это не нравится (переключение)";
-App::$strings["Please wait"] = "Подождите пожалуйста";
-App::$strings["This is you"] = "Это вы";
-App::$strings["Comment"] = "Комментарий";
-App::$strings["__ctx:title__ Likes"] = "Нравится";
-App::$strings["__ctx:title__ Dislikes"] = "Не нравится";
-App::$strings["__ctx:title__ Agree"] = "Согласен";
-App::$strings["__ctx:title__ Disagree"] = "Не согласен";
-App::$strings["__ctx:title__ Abstain"] = "Воздержался";
-App::$strings["__ctx:title__ Attending"] = "Посещаю";
-App::$strings["__ctx:title__ Not attending"] = "Не посещаю";
-App::$strings["__ctx:title__ Might attend"] = "Возможно посещу";
-App::$strings["View all"] = "Просмотреть все";
-App::$strings["__ctx:noun__ Like"] = array(
- 0 => "Нравится",
- 1 => "Нравится",
- 2 => "Нравится",
-);
-App::$strings["__ctx:noun__ Dislike"] = array(
- 0 => "Не нравится",
- 1 => "Не нравится",
- 2 => "Не нравится",
-);
-App::$strings["Photo Tools"] = "Фото-Инструменты";
-App::$strings["In This Photo:"] = "На этой фотографии:";
-App::$strings["Map"] = "Карта";
-App::$strings["__ctx:noun__ Likes"] = "Нравится";
-App::$strings["__ctx:noun__ Dislikes"] = "Не нравится";
-App::$strings["Close"] = "Закрыть";
-App::$strings["Recent Photos"] = "Последние фотографии";
-App::$strings["Profile Unavailable."] = "Профиль недоступен.";
-App::$strings["Wiki App"] = "Приложение \"Wiki\"";
-App::$strings["Provide a wiki for your channel"] = "Предоставьте Wiki для вашего канала";
-App::$strings["Invalid channel"] = "Недействительный канал";
-App::$strings["Error retrieving wiki"] = "Ошибка при получении Wiki";
-App::$strings["Error creating zip file export folder"] = "Ошибка при создании zip-файла при экспорте каталога";
-App::$strings["Error downloading wiki: "] = "Ошибка загрузки Wiki:";
-App::$strings["Wikis"] = "";
-App::$strings["Download"] = "Загрузить";
-App::$strings["Create New"] = "Создать новый";
-App::$strings["Wiki name"] = "Название Wiki";
-App::$strings["Content type"] = "Тип содержимого";
-App::$strings["Markdown"] = "Разметка Markdown";
-App::$strings["BBcode"] = "";
-App::$strings["Text"] = "Текст";
-App::$strings["Type"] = "Тип";
-App::$strings["Any&nbsp;type"] = "Любой&nbsp;тип";
-App::$strings["Lock content type"] = "Зафиксировать тип содержимого";
-App::$strings["Create a status post for this wiki"] = "Создать публикацию о статусе этой Wiki";
-App::$strings["Edit Wiki Name"] = "Редактировать наименование Wiki";
-App::$strings["Wiki not found"] = "Wiki не найдена";
-App::$strings["Rename page"] = "Переименовать страницу";
-App::$strings["Error retrieving page content"] = "Ошибка при получении содержимого страницы";
-App::$strings["New page"] = "Новая страница";
-App::$strings["Revision Comparison"] = "Сравнение ревизий";
-App::$strings["Revert"] = "Отменить";
-App::$strings["Short description of your changes (optional)"] = "Краткое описание ваших изменений (необязательно)";
-App::$strings["Source"] = "Источник";
-App::$strings["New page name"] = "Новое имя страницы";
-App::$strings["Embed image from photo albums"] = "Встроить изображение из фотоальбома";
-App::$strings["Embed an image from your albums"] = "Встроить изображение из ваших альбомов";
-App::$strings["OK"] = "";
-App::$strings["Choose images to embed"] = "Выбрать изображения для встраивания";
-App::$strings["Choose an album"] = "Выбрать альбом";
-App::$strings["Choose a different album"] = "Выбрать другой альбом";
-App::$strings["Error getting album list"] = "Ошибка получения списка альбомов";
-App::$strings["Error getting photo link"] = "Ошибка получения ссылки на фотографию";
-App::$strings["Error getting album"] = "Ошибка получения альбома";
-App::$strings["History"] = "История";
-App::$strings["Error creating wiki. Invalid name."] = "Ошибка создания Wiki. Неверное имя.";
-App::$strings["A wiki with this name already exists."] = "Wiki с таким именем уже существует.";
-App::$strings["Wiki created, but error creating Home page."] = "Wiki создана, но возникла ошибка при создании домашней страницы";
-App::$strings["Error creating wiki"] = "Ошибка при создании Wiki";
-App::$strings["Error updating wiki. Invalid name."] = "Ошибка при обновлении Wiki. Неверное имя.";
-App::$strings["Error updating wiki"] = "Ошибка при обновлении Wiki";
-App::$strings["Wiki delete permission denied."] = "Нет прав на удаление Wiki.";
-App::$strings["Error deleting wiki"] = "Ошибка удаления Wiki";
-App::$strings["New page created"] = "Создана новая страница";
-App::$strings["Cannot delete Home"] = "Невозможно удалить домашнюю страницу";
-App::$strings["Current Revision"] = "Текущая ревизия";
-App::$strings["Selected Revision"] = "Выбранная ревизия";
-App::$strings["You must be authenticated."] = "Вы должны быть аутентифицированы.";
-App::$strings["&#x1f501; Repeated %1\$s's %2\$s"] = "&#x1f501; Повторил %1\$s %2\$s";
-App::$strings["Post repeated"] = "Публикация повторяется";
-App::$strings["toggle full screen mode"] = "переключение полноэкранного режима";
-App::$strings["Layout updated."] = "Шаблон обновлен.";
-App::$strings["PDL Editor App"] = "Приложение \"Редактор PDL\"";
-App::$strings["Provides the ability to edit system page layouts"] = "Предоставляет возможность редактировать макеты системных страниц";
-App::$strings["Edit System Page Description"] = "Редактировать описание системной страницы";
-App::$strings["(modified)"] = "(изменено)";
-App::$strings["Reset"] = "Сбросить";
-App::$strings["Layout not found."] = "Шаблон не найден.";
-App::$strings["Module Name:"] = "Имя модуля:";
-App::$strings["Layout Help"] = "Помощь к шаблону";
-App::$strings["Edit another layout"] = "Редактировать другой шаблон";
-App::$strings["System layout"] = "Системный шаблон";
-App::$strings["Poke App"] = "Приложение \"Ткнуть\"";
-App::$strings["Poke somebody in your addressbook"] = "Ткнуть кого-нибудь в вашей адресной книге";
-App::$strings["Poke"] = "Ткнуть";
-App::$strings["Poke somebody"] = "Ткнуть кого-нибудь";
-App::$strings["Poke/Prod"] = "Толкнуть / подтолкнуть";
-App::$strings["Poke, prod or do other things to somebody"] = "Толкнуть, подтолкнуть или сделать что-то ещё с кем-то";
-App::$strings["Recipient"] = "Получатель";
-App::$strings["Choose what you wish to do to recipient"] = "Выбрать что вы хотите сделать с получателем";
-App::$strings["Make this post private"] = "Сделать эту публикацию приватной";
-App::$strings["Image uploaded but image cropping failed."] = "Изображение загружено но обрезка не удалась.";
-App::$strings["Profile Photos"] = "Фотографии профиля";
-App::$strings["Image resize failed."] = "Не удалось изменить размер изображения.";
+App::$strings["Welcome to Hubzilla!"] = "Добро пожаловать в Hubzilla!";
+App::$strings["You have got no unseen posts..."] = "У вас нет видимых публикаций...";
+App::$strings["Items tagged with: %s"] = "Объекты помечены как: %s";
+App::$strings["Search results for: %s"] = "Результаты поиска для: %s";
+App::$strings["Notes App"] = "Приложение \"Заметки\"";
+App::$strings["A simple notes app with a widget (note: notes are not encrypted)"] = "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)";
+App::$strings["Comment approved"] = "Комментарий одобрен";
+App::$strings["Comment deleted"] = "Комментарий удалён";
+App::$strings["Webpages App"] = "Приложение \"Веб-страницы\"";
+App::$strings["Provide managed web pages on your channel"] = "Предоставлять управляемые веб-страницы на Вашем канале";
+App::$strings["Import Webpage Elements"] = "Импортировать части веб-страницы";
+App::$strings["Import selected"] = "Импортировать выбранное";
+App::$strings["Export Webpage Elements"] = "Экспортировать часть веб-страницы";
+App::$strings["Export selected"] = "Экспортировать выбранное";
+App::$strings["Actions"] = "Действия";
+App::$strings["Page Link"] = "Ссылка страницы";
+App::$strings["Page Title"] = "Заголовок страницы";
+App::$strings["Invalid file type."] = "Неверный тип файла.";
+App::$strings["Error opening zip file"] = "Ошибка открытия ZIP файла";
+App::$strings["Invalid folder path."] = "Неверный путь к каталогу.";
+App::$strings["No webpage elements detected."] = "Не обнаружено частей веб-страницы.";
+App::$strings["Import complete."] = "Импорт завершен.";
+App::$strings["\$Projectname"] = "";
+App::$strings["Welcome to %s"] = "Добро пожаловать в %s";
App::$strings["Shift-reload the page or clear browser cache if the new photo does not display immediately."] = "Если новая фотография не отображается немедленно то нажмите Shift + \"Обновить\" для очистки кэша браузера";
-App::$strings["Unable to process image"] = "Не удается обработать изображение";
-App::$strings["Image upload failed."] = "Загрузка изображения не удалась.";
-App::$strings["Unable to process image."] = "Невозможно обработать изображение.";
-App::$strings["Photo not available."] = "Фотография недоступна.";
App::$strings["Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile"] = "Фотография вашего профиля по умолчанию видна всем в Интернете. Фотографияпрофиля для альтернативных профилей наследуют разрешения текущего профиля";
App::$strings["Your profile photo is visible to anybody on the internet and may be distributed to other websites."] = "Фотография вашего профиля видна всем в Интернете и может быть отправлена на другие сайты.";
-App::$strings["Upload File:"] = "Загрузить файл:";
-App::$strings["Select a profile:"] = "Выбрать профиль:";
App::$strings["Use Photo for Profile"] = "Использовать фотографию для профиля";
App::$strings["Change Profile Photo"] = "Изменить фотографию профиля";
App::$strings["Use"] = "Использовать";
-App::$strings["Use a photo from your albums"] = "Использовать фотографию из ваших альбомов";
-App::$strings["Select existing photo"] = "Выбрать существующую фотографию";
-App::$strings["Crop Image"] = "Обрезать изображение";
-App::$strings["Please adjust the image cropping for optimum viewing."] = "Пожалуйста настройте обрезку изображения для оптимального просмотра.";
-App::$strings["Done Editing"] = "Закончить редактирование";
-App::$strings["Away"] = "Нет на месте";
-App::$strings["Online"] = "В сети";
-App::$strings["Unable to locate original post."] = "Не удалось найти оригинальную публикацию.";
-App::$strings["Empty post discarded."] = "Пустая публикация отклонена.";
-App::$strings["Duplicate post suppressed."] = "Подавлена дублирующаяся публикация.";
-App::$strings["System error. Post not saved."] = "Системная ошибка. Публикация не сохранена.";
-App::$strings["Your comment is awaiting approval."] = "Ваш комментарий ожидает одобрения.";
-App::$strings["Unable to obtain post information from database."] = "Невозможно получить информацию о публикации из базы данных";
-App::$strings["You have reached your limit of %1$.0f top level posts."] = "Вы достигли вашего ограничения в %1$.0f публикаций высокого уровня.";
-App::$strings["You have reached your limit of %1$.0f webpages."] = "Вы достигли вашего ограничения в %1$.0f страниц.";
-App::$strings["sent you a private message"] = "отправил вам личное сообщение";
-App::$strings["added your channel"] = "добавил ваш канал";
-App::$strings["requires approval"] = "Требуется подтверждение";
-App::$strings["g A l F d"] = "g A l F d";
-App::$strings["[today]"] = "[сегодня]";
-App::$strings["posted an event"] = "событие опубликовано";
-App::$strings["shared a file with you"] = "с вами поделились файлом";
-App::$strings["Private forum"] = "Частный форум";
-App::$strings["Public forum"] = "Публичный форум";
-App::$strings["Invalid item."] = "Недействительный элемент.";
-App::$strings["Page not found."] = "Страница не найдена.";
-App::$strings["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."] = "";
-App::$strings["Could not access contact record."] = "Не удалось получить доступ к записи контакта.";
+App::$strings["Select a bookmark folder"] = "Выбрать каталог для закладок";
+App::$strings["Save Bookmark"] = "Сохранить закладку";
+App::$strings["URL of bookmark"] = "URL закладки";
+App::$strings["Or enter new bookmark folder name"] = "или введите новое имя каталога закладок";
+App::$strings["Connection added."] = "Контакт добавлен.";
+App::$strings["Item is not editable"] = "Элемент нельзя редактировать";
App::$strings["Could not locate selected profile."] = "Не удалось обнаружить выбранный профиль.";
App::$strings["Connection updated."] = "Контакты обновлены.";
App::$strings["Failed to update connection record."] = "Не удалось обновить запись контакта.";
@@ -1193,17 +2191,16 @@ App::$strings["Could not access address book record."] = "Не удалось п
App::$strings["Refresh failed - channel is currently unavailable."] = "Обновление невозможно - в настоящее время канал недоступен.";
App::$strings["Unable to set address book parameters."] = "Не удалось получить доступ к параметрам адресной книги.";
App::$strings["Connection has been removed."] = "Контакт был удалён.";
-App::$strings["View Profile"] = "Просмотреть профиль";
App::$strings["View %s's profile"] = "Просмотр %s профиля";
App::$strings["Refresh Permissions"] = "Обновить разрешения";
App::$strings["Fetch updated permissions"] = "Получить обновлённые разрешения";
App::$strings["Refresh Photo"] = "Обновить фотографию";
App::$strings["Fetch updated photo"] = "Получить обновлённую фотографию";
-App::$strings["Recent Activity"] = "Последние действия";
App::$strings["View recent posts and comments"] = "Просмотреть последние публикации и комментарии";
App::$strings["Block (or Unblock) all communications with this connection"] = "Блокировать (или разблокировать) связи с этим контактом";
App::$strings["This connection is blocked!"] = "Этот контакт заблокирован!";
App::$strings["Unignore"] = "Не игнорировать";
+App::$strings["Ignore"] = "Игнорировать";
App::$strings["Ignore (or Unignore) all inbound communications from this connection"] = "Игнорировать (или не игнорировать) все связи для этого контакта";
App::$strings["This connection is ignored!"] = "Этот контакт игнорируется!";
App::$strings["Unarchive"] = "Разархивировать";
@@ -1223,6 +2220,7 @@ App::$strings["Open Set Affinity section by default"] = "Открыть секц
App::$strings["Me"] = "Я";
App::$strings["Family"] = "Семья";
App::$strings["Acquaintances"] = "Знакомые";
+App::$strings["All"] = "Все";
App::$strings["Filter"] = "Фильтр";
App::$strings["Open Custom Filter section by default"] = "Открывать секцию \"Настраиваемый фильтр\" по умолчанию";
App::$strings["Approve this connection"] = "Утвердить этот контакт";
@@ -1234,18 +2232,11 @@ App::$strings["This connection is unreachable from this location."] = "Этот
App::$strings["This connection may be unreachable from other channel locations."] = "Этот контакт может быть недоступен из других мест размещения канала";
App::$strings["Location independence is not supported by their network."] = "Независимое местоположение не поддерживается их сетью.";
App::$strings["This connection is unreachable from this location. Location independence is not supported by their network."] = "Этот контакт недоступен из данного местоположения. Независимое местоположение не поддерживается их сетью.";
-App::$strings["Connection Default Permissions"] = "Разрешения по умолчанию для контакта";
-App::$strings["Connection: %s"] = "Контакт: %s";
-App::$strings["Apply these permissions automatically"] = "Применить эти разрешения автоматически";
App::$strings["Connection requests will be approved without your interaction"] = "Запросы контактов будут одобрены без вашего участия";
-App::$strings["Permission role"] = "Роль разрешения";
-App::$strings["Add permission role"] = "Добавить роль разрешения";
App::$strings["This connection's primary address is"] = "Главный адрес это контакта";
App::$strings["Available locations:"] = "Доступные расположения:";
-App::$strings["The permissions indicated on this page will be applied to all new connections."] = "Разрешения, указанные на этой странице, будут применяться ко всем новым соединениям.";
App::$strings["Connection Tools"] = "Инструменты контактов";
App::$strings["Slide to adjust your degree of friendship"] = "Прокрутить для настройки степени дружбы";
-App::$strings["Rating"] = "Оценка";
App::$strings["Slide to adjust your rating"] = "Прокрутить для настройки оценки";
App::$strings["Optionally explain your rating"] = "Объясните свою оценку (не обязательно)";
App::$strings["Custom Filter"] = "Настраиваемый фильтр";
@@ -1257,99 +2248,14 @@ App::$strings["Please choose the profile you would like to display to %s when vi
App::$strings["Some permissions may be inherited from your channel's <a href=\"settings\"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes."] = "Некоторые разрешения могут быть унаследованы из <a href=\"settings\"><strong>настроек приватности</strong></a> вашего канала, которые могут иметь более высокий приоритет чем индивидуальные. Вы можете изменить эти настройки, однако они не будут применены до изменения переданных по наследству настроек.";
App::$strings["Last update:"] = "Последнее обновление:";
App::$strings["Details"] = "Сведения";
-App::$strings["Chatrooms App"] = "Приложение \"Мои чаты\"";
-App::$strings["Access Controlled Chatrooms"] = "Получить доступ к контролируемым чатам";
-App::$strings["Room not found"] = "Комната не найдена";
-App::$strings["Leave Room"] = "Покинуть комнату";
-App::$strings["Delete Room"] = "Удалить комнату";
-App::$strings["I am away right now"] = "Я сейчас отошёл";
-App::$strings["I am online"] = "Я на связи";
-App::$strings["Bookmark this room"] = "Запомнить эту комнату";
-App::$strings["Please enter a link URL:"] = "Пожалуйста введите URL ссылки:";
-App::$strings["Encrypt text"] = "Зашифровать текст";
-App::$strings["New Chatroom"] = "Новый чат";
-App::$strings["Chatroom name"] = "Название чата";
-App::$strings["Expiration of chats (minutes)"] = "Завершение чатов (минут)";
-App::$strings["%1\$s's Chatrooms"] = "Чаты пользователя %1\$s";
-App::$strings["No chatrooms available"] = "Нет доступных чатов";
-App::$strings["Expiration"] = "Срок действия";
-App::$strings["min"] = "мин.";
-App::$strings["Photos"] = "Фотографии";
-App::$strings["Files"] = "Файлы";
-App::$strings["Unable to update menu."] = "Невозможно обновить меню.";
-App::$strings["Unable to create menu."] = "Невозможно создать меню.";
-App::$strings["Menu Name"] = "Название меню";
-App::$strings["Unique name (not visible on webpage) - required"] = "Уникальное название (не видимо на странице) - требуется";
-App::$strings["Menu Title"] = "Заголовок меню";
-App::$strings["Visible on webpage - leave empty for no title"] = "Видимость на странице - оставьте пустым если не хотите иметь заголовок";
-App::$strings["Allow Bookmarks"] = "Разрешить закладки";
-App::$strings["Menu may be used to store saved bookmarks"] = "Меню может использоваться, чтобы сохранить закладки";
-App::$strings["Submit and proceed"] = "Отправить и обработать";
-App::$strings["Menus"] = "Меню";
-App::$strings["Bookmarks allowed"] = "Закладки разрешены";
-App::$strings["Delete this menu"] = "Удалить это меню";
-App::$strings["Edit menu contents"] = "Редактировать содержание меню";
-App::$strings["Edit this menu"] = "Редактировать это меню";
-App::$strings["Menu could not be deleted."] = "Меню не может быть удалено.";
-App::$strings["Edit Menu"] = "Редактировать меню";
-App::$strings["Add or remove entries to this menu"] = "Добавить или удалить пункты этого меню";
-App::$strings["Menu name"] = "Название меню";
-App::$strings["Must be unique, only seen by you"] = "Должно быть уникальным (видно только вам)";
-App::$strings["Menu title"] = "Заголовок меню";
-App::$strings["Menu title as seen by others"] = "Видимый другими заголовок меню";
-App::$strings["Allow bookmarks"] = "Разрешить закладки";
-App::$strings["Layouts"] = "Шаблоны";
-App::$strings["Help"] = "Помощь";
-App::$strings["Comanche page description language help"] = "Помощь по языку описания страниц Comanche ";
-App::$strings["Layout Description"] = "Описание шаблона";
-App::$strings["Download PDL file"] = "Загрузить PDL файл";
-App::$strings["Notes App"] = "Приложение \"Заметки\"";
-App::$strings["A simple notes app with a widget (note: notes are not encrypted)"] = "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)";
-App::$strings["Not found"] = "Не найдено.";
-App::$strings["Please refresh page"] = "Пожалуйста обновите страницу";
-App::$strings["Unknown error"] = "Неизвестная ошибка";
-App::$strings["Token verification failed."] = "Не удалось выполнить проверку токена.";
-App::$strings["Email Verification Required"] = "Требуется проверка адреса email";
-App::$strings["A verification token was sent to your email address [%s]. Enter that token here to complete the account verification step. Please allow a few minutes for delivery, and check your spam folder if you do not see the message."] = "Проверочный токен был отправлен на ваш адрес электронной почты [%s]. Введите этот токен здесь для завершения этапа проверки учётной записи. Пожалуйста, подождите несколько минут для завершения доставки и проверьте вашу папку \"Спам\" если вы не видите письма.";
-App::$strings["Resend Email"] = "Выслать повторно";
-App::$strings["Validation token"] = "Проверочный токен";
-App::$strings["Post not found."] = "Публикация не найдена";
-App::$strings["post"] = "публикация";
-App::$strings["comment"] = "комментарий";
-App::$strings["%1\$s tagged %2\$s's %3\$s with %4\$s"] = "%1\$s отметил тегом %2\$s %3\$s с %4\$s";
-App::$strings["This setting requires special processing and editing has been blocked."] = "Этот параметр требует специальной обработки и редактирования и был заблокирован.";
-App::$strings["Configuration Editor"] = "Редактор конфигурации";
-App::$strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Предупреждение. Изменение некоторых настроек может привести к неработоспособности вашего канала. Пожалуйста, покиньте эту страницу, если вы точно не значете, как правильно использовать эту функцию.";
-App::$strings["Affinity Tool settings updated."] = "Настройки степени сходства обновлены.";
-App::$strings["This app presents a slider control in your connection editor and also on your network page. The slider represents your degree of friendship (affinity) with each connection. It allows you to zoom in or out and display conversations from only your closest friends or everybody in your stream."] = "Это приложение представляет управление ползунком на странице контактов и сетевом потоке, который позволяет выбирать вашу степень дружбы (сходства). Это позволяет вам увеличивать или уменьшать масштаб и отображать разговоры только от ваших самых близких друзей или всех в вашем потоке.";
-App::$strings["Affinity Tool App"] = "Приложение \"Степень сходства\"";
-App::$strings["The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage."] = "Числа ниже представляют минимальное и максимальное значение по умолчанию для вашей сети / потока в процентах.";
-App::$strings["Default maximum affinity level"] = "Максимальная степень сходства по умолчанию.";
-App::$strings["0-99 default 99"] = "0-99 (по умолчанию 99)";
-App::$strings["Default minimum affinity level"] = "Максимальная степень сходства по умолчанию.";
-App::$strings["0-99 - default 0"] = "0-99 (по умолчанию 0)";
-App::$strings["Persistent affinity levels"] = "Устоявшиеся степени сходства";
-App::$strings["If disabled the max and min levels will be reset to default after page reload"] = "Если этот параметр отключен, максимальный и минимальный уровни будут сброшены к значениям по умолчанию после перезагрузки страницы";
-App::$strings["Affinity Tool Settings"] = "Настройки степени сходства";
-App::$strings["Default Permissions App"] = "Приложение \"Разрешения по умолчанию\"";
-App::$strings["Set custom default permissions for new connections"] = "Настройка пользовательских разрешений по умолчанию для новых подключений ";
-App::$strings["Automatic approval settings"] = "Настройки автоматического одобрения";
-App::$strings["Some individual permissions may have been preset or locked based on your channel type and privacy settings."] = "Некоторые индивидуальные разрешения могут быть предустановлены или заблокированы на основании типа вашего канала и настроек приватности.";
-App::$strings["Unknown App"] = "Неизвестное приложение";
-App::$strings["Authorize"] = "Авторизовать";
-App::$strings["Do you authorize the app %s to access your channel data?"] = "Авторизуете ли вы приложение %s для доступа к данным вашего канала?";
-App::$strings["Allow"] = "Разрешить";
App::$strings["Privacy group created."] = "Группа безопасности создана.";
App::$strings["Could not create privacy group."] = "Не удалось создать группу безопасности.";
-App::$strings["Privacy group not found."] = "Группа безопасности не найдена.";
App::$strings["Privacy group updated."] = "Группа безопасности обновлена.";
App::$strings["Privacy Groups App"] = "Приложение \"Группы безопасности\"";
App::$strings["Management of privacy groups"] = "Управление группами безопасности.";
-App::$strings["Privacy Groups"] = "Группы безопасности";
App::$strings["Add Group"] = "Добавить группу";
App::$strings["Privacy group name"] = "Имя группы безопасности";
App::$strings["Members are visible to other channels"] = "Участники канала видимые для остальных";
-App::$strings["Members"] = "Участники";
App::$strings["Privacy group removed."] = "Группа безопасности удалена.";
App::$strings["Unable to remove privacy group."] = "Ну удалось удалить группу безопасности.";
App::$strings["Privacy Group: %s"] = "Группа безопасности: %s";
@@ -1358,93 +2264,148 @@ App::$strings["Delete Group"] = "Удалить группу";
App::$strings["Group members"] = "Члены группы";
App::$strings["Not in this group"] = "Не в этой группе";
App::$strings["Click a channel to toggle membership"] = "Нажмите на канал для просмотра членства";
-App::$strings["Profile not found."] = "Профиль не найден.";
-App::$strings["Profile deleted."] = "Профиль удален.";
-App::$strings["Profile-"] = "Профиль -";
-App::$strings["New profile created."] = "Новый профиль создан.";
-App::$strings["Profile unavailable to clone."] = "Профиль недоступен для клонирования.";
-App::$strings["Profile unavailable to export."] = "Профиль недоступен для экспорта.";
-App::$strings["Profile Name is required."] = "Требуется имя профиля.";
-App::$strings["Marital Status"] = "Семейное положение";
-App::$strings["Romantic Partner"] = "Романтический партнер";
-App::$strings["Likes"] = "Нравится";
-App::$strings["Dislikes"] = "Не нравится";
-App::$strings["Work/Employment"] = "Работа / Занятость";
-App::$strings["Religion"] = "Религия";
-App::$strings["Political Views"] = "Политические взгляды";
-App::$strings["Gender"] = "Гендер";
-App::$strings["Sexual Preference"] = "Сексуальная ориентация";
-App::$strings["Homepage"] = "Домашняя страница";
-App::$strings["Interests"] = "Интересы";
-App::$strings["Profile updated."] = "Профиль обновлен.";
-App::$strings["Hide your connections list from viewers of this profile"] = "Скрывать от просмотра ваш список контактов в этом профиле";
-App::$strings["Edit Profile Details"] = "Редактирование профиля";
-App::$strings["View this profile"] = "Посмотреть этот профиль";
-App::$strings["Edit visibility"] = "Редактировать видимость";
-App::$strings["Profile Tools"] = "Инструменты профиля";
-App::$strings["Change cover photo"] = "Изменить фотографию обложки";
-App::$strings["Change profile photo"] = "Изменить фотографию профиля";
-App::$strings["Create a new profile using these settings"] = "Создать новый профиль с теми же настройками";
-App::$strings["Clone this profile"] = "Клонировать этот профиль";
-App::$strings["Delete this profile"] = "Удалить этот профиль";
-App::$strings["Add profile things"] = "Добавить в профиль";
-App::$strings["Personal"] = "Личное";
-App::$strings["Relationship"] = "Отношения";
-App::$strings["Miscellaneous"] = "Прочее";
-App::$strings["Import profile from file"] = "Импортировать профиль из файла";
-App::$strings["Export profile to file"] = "Экспортировать профиль в файл";
-App::$strings["Your gender"] = "Ваш пол";
-App::$strings["Marital status"] = "Семейное положение";
-App::$strings["Sexual preference"] = "Сексуальная ориентация";
-App::$strings["Profile name"] = "Имя профиля";
-App::$strings["This is your default profile."] = "Это ваш профиль по умолчанию.";
-App::$strings["Your full name"] = "Ваше полное имя";
-App::$strings["Title/Description"] = "Заголовок / описание";
-App::$strings["Street address"] = "Улица, дом, квартира";
-App::$strings["Locality/City"] = "Населенный пункт / город";
-App::$strings["Region/State"] = "Регион / Область";
-App::$strings["Postal/Zip code"] = "Почтовый индекс";
-App::$strings["Who (if applicable)"] = "Кто (если применимо)";
-App::$strings["Examples: cathy123, Cathy Williams, cathy@example.com"] = "Примеры: ivan1990, Ivan Petrov, ivan@example.com";
-App::$strings["Since (date)"] = "С (дата)";
-App::$strings["Tell us about yourself"] = "Расскажите нам о себе";
-App::$strings["Homepage URL"] = "URL домашней страницы";
-App::$strings["Hometown"] = "Родной город";
-App::$strings["Political views"] = "Политические взгляды";
-App::$strings["Religious views"] = "Религиозные взгляды";
-App::$strings["Keywords used in directory listings"] = "Ключевые слова для участия в каталоге";
-App::$strings["Example: fishing photography software"] = "Например: fishing photography software";
-App::$strings["Musical interests"] = "Музыкальные интересы";
-App::$strings["Books, literature"] = "Книги, литература";
-App::$strings["Television"] = "Телевидение";
-App::$strings["Film/Dance/Culture/Entertainment"] = "Кино / танцы / культура / развлечения";
-App::$strings["Hobbies/Interests"] = "Хобби / интересы";
-App::$strings["Love/Romance"] = "Любовь / романтические отношения";
-App::$strings["School/Education"] = "Школа / образование";
-App::$strings["Contact information and social networks"] = "Информация и социальные сети для связи";
-App::$strings["My other channels"] = "Мои другие контакты";
-App::$strings["Communications"] = "Связи";
-App::$strings["Profile Image"] = "Изображение профиля";
-App::$strings["Edit Profiles"] = "Редактирование профилей";
-App::$strings["This page is available only to site members"] = "Эта страница доступна только для подписчиков сайта";
-App::$strings["Welcome"] = "Добро пожаловать";
-App::$strings["What would you like to do?"] = "Что бы вы хотели сделать?";
-App::$strings["Please bookmark this page if you would like to return to it in the future"] = "Пожалуйста, запомните эту страницу если вы хотите вернуться на неё в будущем";
-App::$strings["Upload a profile photo"] = "Загрузить фотографию профиля";
-App::$strings["Upload a cover photo"] = "Загрузить фотографию обложки";
-App::$strings["Edit your default profile"] = "Редактировать ваш профиль по умолчанию";
-App::$strings["View friend suggestions"] = "Просмотр рекомендуемых друзей";
-App::$strings["View the channel directory"] = "Просмотр каталога каналов";
-App::$strings["View/edit your channel settings"] = "Просмотреть / редактировать настройки вашего канала";
-App::$strings["View the site or project documentation"] = "Просмотр документации сайта / проекта";
-App::$strings["Visit your channel homepage"] = "Посетить страницу вашего канала";
-App::$strings["View your connections and/or add somebody whose address you already know"] = "Просмотреть ваши контакты и / или добавить кого-то чей адрес в уже знаете";
-App::$strings["View your personal stream (this may be empty until you add some connections)"] = "Ваш персональный поток (может быть пуст пока вы не добавите контакты)";
-App::$strings["View the public stream. Warning: this content is not moderated"] = "Просмотр публичного потока. Предупреждение: этот контент не модерируется";
-App::$strings["Page link"] = "Ссылка страницы";
-App::$strings["Edit Webpage"] = "Редактировать веб-страницу";
+App::$strings["Active"] = "Активен";
+App::$strings["Blocked"] = "Заблокирован";
+App::$strings["Ignored"] = "Игнорируется";
+App::$strings["Hidden"] = "Скрыт";
+App::$strings["Archived/Unreachable"] = "Заархивировано / недоступно";
+App::$strings["Active Connections"] = "Активные контакты";
+App::$strings["Show active connections"] = "Показать активные контакты";
+App::$strings["New Connections"] = "Новые контакты";
+App::$strings["Show pending (new) connections"] = "Просмотр (новых) ожидающих контактов";
+App::$strings["Only show blocked connections"] = "Показать только заблокированные контакты";
+App::$strings["Only show ignored connections"] = "Показать только проигнорированные контакты";
+App::$strings["Only show archived/unreachable connections"] = "Показать только заархивированные / недоступные контакты";
+App::$strings["Only show hidden connections"] = "Показать только скрытые контакты";
+App::$strings["Show all connections"] = "Просмотр всех контактов";
+App::$strings["Pending approval"] = "Ожидающие подтверждения";
+App::$strings["Archived"] = "Зархивирован";
+App::$strings["Not connected at this location"] = "Не подключено в этом месте";
+App::$strings["%1\$s [%2\$s]"] = "";
+App::$strings["Edit connection"] = "Редактировать контакт";
+App::$strings["Delete connection"] = "Удалить контакт";
+App::$strings["Channel address"] = "Адрес канала";
+App::$strings["Call"] = "Вызов";
+App::$strings["Status"] = "Статус";
+App::$strings["Connected"] = "Подключено";
+App::$strings["Approve connection"] = "Утвердить контакт";
+App::$strings["Ignore connection"] = "Игнорировать контакт";
+App::$strings["Recent activity"] = "Последние действия";
+App::$strings["Search your connections"] = "Поиск ваших контактов";
+App::$strings["Connections search"] = "Поиск контаков";
+App::$strings["Mood App"] = "Приложение \"Настроение\"";
+App::$strings["Set your current mood and tell your friends"] = "Установить текущее настроение и рассказать друзьям";
+App::$strings["Mood"] = "Настроение";
+App::$strings["Edit Card"] = "Редактировать карточку";
+App::$strings["Edit Article"] = "Редактировать статью";
+App::$strings["Language App"] = "Приложение \"Язык\"";
+App::$strings["Change UI language"] = "Изменить язык интерфейса";
+App::$strings["Block Title"] = "Заблокировать заголовок";
+App::$strings["Random Channel App"] = "Приложение \"Случайный канал\"";
+App::$strings["Visit a random channel in the \$Projectname network"] = "Посещение случайного канала в сети \$Projectname";
+App::$strings["Total invitation limit exceeded."] = "Превышено общее количество приглашений.";
+App::$strings["%s : Not a valid email address."] = "%s : Недействительный адрес электронной почты.";
+App::$strings["Please join us on \$Projectname"] = "Присоединятесь к \$Projectname !";
+App::$strings["Invitation limit exceeded. Please contact your site administrator."] = "Превышен лимит приглашений. Пожалуйста, свяжитесь с администрацией сайта.";
+App::$strings["%s : Message delivery failed."] = "%s : Доставка сообщения не удалась.";
+App::$strings["%d message sent."] = array(
+ 0 => "%d сообщение отправлено.",
+ 1 => "%d сообщения отправлено.",
+ 2 => "%d сообщений отправлено.",
+);
+App::$strings["Invite App"] = "Приложение \"Пригласить\"";
+App::$strings["Send email invitations to join this network"] = "Отправить приглашение присоединиться к этой сети по электронной почте";
+App::$strings["You have no more invitations available"] = "У вас больше нет приглашений";
+App::$strings["Send invitations"] = "Отправить приглашение";
+App::$strings["Enter email addresses, one per line:"] = "Введите адреса электронной почты, по одному в строке:";
+App::$strings["Please join my community on \$Projectname."] = "Присоединятесь к нашему сообществу \$Projectname !";
+App::$strings["You will need to supply this invitation code:"] = "Вам нужно предоставит этот код приглашения:";
+App::$strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Зарегистрируйтесь на любом из серверов \$Projectname";
+App::$strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Введите сетевой адрес \$Projectname в поисковой строке сайта";
+App::$strings["or visit"] = "или посетите";
+App::$strings["3. Click [Connect]"] = "Нажать [Подключиться]";
+App::$strings["Articles App"] = "Приложение \"Статьи\"";
+App::$strings["Create interactive articles"] = "Создать интерактивные статьи";
+App::$strings["Add Article"] = "Добавить статью";
+App::$strings["Continue"] = "Продолжить";
+App::$strings["Premium Channel App"] = "Приложение \"Премиальный канал\"";
+App::$strings["Allows you to set restrictions and terms on those that connect with your channel"] = "Позволяет установить ограничения и условия для подключающихся к вашему каналу";
+App::$strings["Premium Channel Setup"] = "Установка премиального канала";
+App::$strings["Enable premium channel connection restrictions"] = "Включить ограничения для премиального канала";
+App::$strings["Please enter your restrictions or conditions, such as paypal receipt, usage guidelines, etc."] = "Пожалуйста введите ваши ограничения или условия, такие, как оплата PayPal, правила использования и т.п.";
+App::$strings["This channel may require additional steps or acknowledgement of the following conditions prior to connecting:"] = "Этот канал до подключения может требовать дополнительных шагов или подтверждений следующих условий:";
+App::$strings["Potential connections will then see the following text before proceeding:"] = "Потенциальные соединения будут видеть следующий предварительный текст:";
+App::$strings["By continuing, I certify that I have complied with any instructions provided on this page."] = "Продолжая, я подтверждаю что я выполнил все условия представленные на данной странице.";
+App::$strings["(No specific instructions have been provided by the channel owner.)"] = "(Владельцем канала не было представлено никаких специальных инструкций.)";
+App::$strings["Restricted or Premium Channel"] = "Ограниченный или премиальный канал";
+App::$strings["Not found"] = "Не найдено.";
+App::$strings["Please refresh page"] = "Пожалуйста обновите страницу";
+App::$strings["Unknown error"] = "Неизвестная ошибка";
+App::$strings["Layout updated."] = "Шаблон обновлен.";
+App::$strings["PDL Editor App"] = "Приложение \"Редактор PDL\"";
+App::$strings["Provides the ability to edit system page layouts"] = "Предоставляет возможность редактировать макеты системных страниц";
+App::$strings["Edit System Page Description"] = "Редактировать описание системной страницы";
+App::$strings["(modified)"] = "(изменено)";
+App::$strings["Layout not found."] = "Шаблон не найден.";
+App::$strings["Module Name:"] = "Имя модуля:";
+App::$strings["Layout Help"] = "Помощь к шаблону";
+App::$strings["Edit another layout"] = "Редактировать другой шаблон";
+App::$strings["System layout"] = "Системный шаблон";
+App::$strings["Affinity Tool settings updated."] = "Настройки степени сходства обновлены.";
+App::$strings["This app presents a slider control in your connection editor and also on your network page. The slider represents your degree of friendship (affinity) with each connection. It allows you to zoom in or out and display conversations from only your closest friends or everybody in your stream."] = "Это приложение представляет управление ползунком на странице контактов и сетевом потоке, который позволяет выбирать вашу степень дружбы (сходства). Это позволяет вам увеличивать или уменьшать масштаб и отображать разговоры только от ваших самых близких друзей или всех в вашем потоке.";
+App::$strings["Affinity Tool App"] = "Приложение \"Степень сходства\"";
+App::$strings["The numbers below represent the minimum and maximum slider default positions for your network/stream page as a percentage."] = "Числа ниже представляют минимальное и максимальное значение по умолчанию для вашей сети / потока в процентах.";
+App::$strings["Default maximum affinity level"] = "Максимальная степень сходства по умолчанию.";
+App::$strings["0-99 default 99"] = "0-99 (по умолчанию 99)";
+App::$strings["Default minimum affinity level"] = "Максимальная степень сходства по умолчанию.";
+App::$strings["0-99 - default 0"] = "0-99 (по умолчанию 0)";
+App::$strings["Persistent affinity levels"] = "Устоявшиеся степени сходства";
+App::$strings["If disabled the max and min levels will be reset to default after page reload"] = "Если этот параметр отключен, максимальный и минимальный уровни будут сброшены к значениям по умолчанию после перезагрузки страницы";
+App::$strings["Affinity Tool Settings"] = "Настройки степени сходства";
+App::$strings["Profile Unavailable."] = "Профиль недоступен.";
+App::$strings["Wiki App"] = "Приложение \"Wiki\"";
+App::$strings["Provide a wiki for your channel"] = "Предоставьте Wiki для вашего канала";
+App::$strings["Invalid channel"] = "Недействительный канал";
+App::$strings["Error retrieving wiki"] = "Ошибка при получении Wiki";
+App::$strings["Error creating zip file export folder"] = "Ошибка при создании zip-файла при экспорте каталога";
+App::$strings["Error downloading wiki: "] = "Ошибка загрузки Wiki:";
+App::$strings["Download"] = "Загрузить";
+App::$strings["Wiki name"] = "Название Wiki";
+App::$strings["Content type"] = "Тип содержимого";
+App::$strings["Any&nbsp;type"] = "Любой&nbsp;тип";
+App::$strings["Lock content type"] = "Зафиксировать тип содержимого";
+App::$strings["Create a status post for this wiki"] = "Создать публикацию о статусе этой Wiki";
+App::$strings["Edit Wiki Name"] = "Редактировать наименование Wiki";
+App::$strings["Wiki not found"] = "Wiki не найдена";
+App::$strings["Rename page"] = "Переименовать страницу";
+App::$strings["Error retrieving page content"] = "Ошибка при получении содержимого страницы";
+App::$strings["New page"] = "Новая страница";
+App::$strings["Revision Comparison"] = "Сравнение ревизий";
+App::$strings["Revert"] = "Отменить";
+App::$strings["Short description of your changes (optional)"] = "Краткое описание ваших изменений (необязательно)";
+App::$strings["Source"] = "Источник";
+App::$strings["New page name"] = "Новое имя страницы";
+App::$strings["Embed image from photo albums"] = "Встроить изображение из фотоальбома";
+App::$strings["History"] = "История";
+App::$strings["Error creating wiki. Invalid name."] = "Ошибка создания Wiki. Неверное имя.";
+App::$strings["A wiki with this name already exists."] = "Wiki с таким именем уже существует.";
+App::$strings["Wiki created, but error creating Home page."] = "Wiki создана, но возникла ошибка при создании домашней страницы";
+App::$strings["Error creating wiki"] = "Ошибка при создании Wiki";
+App::$strings["Error updating wiki. Invalid name."] = "Ошибка при обновлении Wiki. Неверное имя.";
+App::$strings["Error updating wiki"] = "Ошибка при обновлении Wiki";
+App::$strings["Wiki delete permission denied."] = "Нет прав на удаление Wiki.";
+App::$strings["Error deleting wiki"] = "Ошибка удаления Wiki";
+App::$strings["New page created"] = "Создана новая страница";
+App::$strings["Cannot delete Home"] = "Невозможно удалить домашнюю страницу";
+App::$strings["Current Revision"] = "Текущая ревизия";
+App::$strings["Selected Revision"] = "Выбранная ревизия";
+App::$strings["You must be authenticated."] = "Вы должны быть аутентифицированы.";
+App::$strings["Email verification resent"] = "Сообщение для проверки email отправлено повторно";
+App::$strings["Unable to resend email verification message."] = "Невозможно повторно отправить сообщение для проверки email";
+App::$strings["Enter a folder name"] = "Введите название каталога";
+App::$strings["or select an existing folder (doubleclick)"] = "или выберите существующий каталог (двойной щелчок)";
+App::$strings["Save to Folder"] = "Сохранить в каталог";
App::$strings["Create a new channel"] = "Создать новый канал";
-App::$strings["Channel Manager"] = "Менеджер каналов";
App::$strings["Current Channel"] = "Текущий канал";
App::$strings["Switch to one of your channels by selecting it."] = "Выбрать и переключиться на один из ваших каналов";
App::$strings["Default Channel"] = "Основной канал";
@@ -1452,15 +2413,39 @@ App::$strings["Make Default"] = "Сделать основным";
App::$strings["%d new messages"] = "%d новых сообщений";
App::$strings["%d new introductions"] = "%d новых представлений";
App::$strings["Delegated Channel"] = "Делегированный канал";
-App::$strings["Cards App"] = "Приложение \"Карточки\"";
-App::$strings["Create personal planning cards"] = "Создать личные карточки планирования";
-App::$strings["Add Card"] = "Добавить карточку";
-App::$strings["Cards"] = "Карточки";
-App::$strings["This directory server requires an access token"] = "Для доступа к этому серверу каталогов требуется токен";
+App::$strings["Suggest Channels App"] = "Приложение \"Рекомендуемые каналы\"";
+App::$strings["Suggestions for channels in the \$Projectname network you might be interested in"] = "Предложения по рекомендуемым каналам в сети \$Projectname которые могут вас заинтересовать";
+App::$strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "Нет предложений. Если это новый сайт, повторите попытку через 24 часа.";
+App::$strings["Ignore/Hide"] = "Игнорировать / cкрыть";
+App::$strings["Nothing to import."] = "Ничего импортировать.";
+App::$strings["Unable to download data from old server"] = "Невозможно загрузить данные со старого сервера";
+App::$strings["Imported file is empty."] = "Импортированный файл пуст.";
+App::$strings["Your service plan only allows %d channels."] = "Ваш класс обслуживания разрешает только %d каналов.";
+App::$strings["No channel. Import failed."] = "Канала нет. Импорт невозможен.";
+App::$strings["Import completed."] = "Импорт завершен.";
+App::$strings["You must be logged in to use this feature."] = "Вы должны войти в систему, чтобы использовать эту функцию.";
+App::$strings["Import Channel"] = "Импортировать канал";
+App::$strings["Use this form to import an existing channel from a different server/hub. You may retrieve the channel identity from the old server/hub via the network or provide an export file."] = "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта.";
+App::$strings["File to Upload"] = "Файл для загрузки";
+App::$strings["Or provide the old server/hub details"] = "или предоставьте данные старого сервера";
+App::$strings["Your old identity address (xyz@example.com)"] = "Ваш старый адрес канала (xyz@example.com)";
+App::$strings["Your old login email address"] = "Ваш старый адрес электронной почты";
+App::$strings["Your old login password"] = "Ваш старый пароль";
+App::$strings["Import a few months of posts if possible (limited by available memory"] = "Импортировать несколько месяцев публикаций если возможно (ограничено доступной памятью)";
+App::$strings["For either option, please choose whether to make this hub your new primary address, or whether your old location should continue this role. You will be able to post from either location, but only one can be marked as the primary location for files, photos, and media."] = "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа.";
+App::$strings["Make this hub my primary location"] = "Сделать этот хаб главным";
+App::$strings["Move this channel (disable all previous locations)"] = "Переместить это канал (отключить все предыдущие месторасположения)";
+App::$strings["Use this channel nickname instead of the one provided"] = "Использовать псевдоним этого канала вместо предоставленного";
+App::$strings["Leave blank to keep your existing channel nickname. You will be randomly assigned a similar nickname if either name is already allocated on this site."] = "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте.";
+App::$strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Процесс может занять несколько минут. Пожалуйста, отправьте форму только один раз и оставьте эту страницу открытой до завершения.";
+App::$strings["Hub not found."] = "Узел не найден.";
+App::$strings["Warning: Database versions differ by %1\$d updates."] = "Предупреждение: Версия базы данных отличается от %1\$d обновления.";
+App::$strings["Import completed"] = "Импорт завершён.";
+App::$strings["Import Items"] = "Импортировать объекты";
+App::$strings["Use this form to import existing posts and content from an export file."] = "Используйте эту форму для импорта существующих публикаций и содержимого из файла.";
App::$strings["About this site"] = "Об этом сайте";
App::$strings["Site Name"] = "Название сайта";
App::$strings["Administrator"] = "Администратор";
-App::$strings["Terms of Service"] = "Условия предоставления услуг";
App::$strings["Software and Project information"] = "Информация о программном обеспечении и проекте";
App::$strings["This site is powered by \$Projectname"] = "Этот сайт работает на \$Projectname";
App::$strings["Federated and decentralised networking and identity services provided by Zot"] = "Объединенные и децентрализованные сети и службы идентификациии обеспечиваются Zot";
@@ -1468,402 +2453,209 @@ App::$strings["Additional federated transport protocols:"] = "Дополните
App::$strings["Version %s"] = "Версия %s";
App::$strings["Project homepage"] = "Домашняя страница проекта";
App::$strings["Developer homepage"] = "Домашняя страница разработчика";
-App::$strings["No ratings"] = "Оценок нет";
-App::$strings["Ratings"] = "Оценки";
-App::$strings["Rating: "] = "Оценкa:";
-App::$strings["Website: "] = "Веб-сайт:";
-App::$strings["Description: "] = "Описание:";
-App::$strings["Webpages App"] = "Приложение \"Веб-страницы\"";
-App::$strings["Provide managed web pages on your channel"] = "Предоставлять управляемые веб-страницы на Вашем канале";
-App::$strings["Import Webpage Elements"] = "Импортировать части веб-страницы";
-App::$strings["Import selected"] = "Импортировать выбранное";
-App::$strings["Export Webpage Elements"] = "Экспортировать часть веб-страницы";
-App::$strings["Export selected"] = "Экспортировать выбранное";
-App::$strings["Webpages"] = "Веб-страницы";
-App::$strings["Actions"] = "Действия";
-App::$strings["Page Link"] = "Ссылка страницы";
-App::$strings["Page Title"] = "Заголовок страницы";
-App::$strings["Invalid file type."] = "Неверный тип файла.";
-App::$strings["Error opening zip file"] = "Ошибка открытия ZIP файла";
-App::$strings["Invalid folder path."] = "Неверный путь к каталогу.";
-App::$strings["No webpage elements detected."] = "Не обнаружено частей веб-страницы.";
-App::$strings["Import complete."] = "Импорт завершен.";
-App::$strings["Channel name changes are not allowed within 48 hours of changing the account password."] = "Изменение названия канала не разрешается в течении 48 часов после смены пароля у аккаунта.";
-App::$strings["Reserved nickname. Please choose another."] = "Зарезервированый псевдоним. Пожалуйста, выберите другой.";
-App::$strings["Nickname has unsupported characters or is already being used on this site."] = "Псевдоним имеет недопустимые символы или уже используется на этом сайте.";
-App::$strings["Change channel nickname/address"] = "Изменить псевдоним / адрес канала";
-App::$strings["Any/all connections on other networks will be lost!"] = "Любые / все контакты в других сетях будут утеряны!";
-App::$strings["New channel address"] = "Новый адрес канала";
-App::$strings["Rename Channel"] = "Переименовать канал";
-App::$strings["Item is not editable"] = "Элемент нельзя редактировать";
-App::$strings["Edit post"] = "Редактировать сообщение";
-App::$strings["Invalid message"] = "Неверное сообщение";
-App::$strings["no results"] = "Ничего не найдено.";
-App::$strings["channel sync processed"] = "синхронизация канала завершена";
-App::$strings["queued"] = "в очереди";
-App::$strings["posted"] = "опубликовано";
-App::$strings["accepted for delivery"] = "принято к доставке";
-App::$strings["updated"] = "обновлено";
-App::$strings["update ignored"] = "обновление игнорируется";
-App::$strings["permission denied"] = "доступ запрещен";
-App::$strings["recipient not found"] = "получатель не найден";
-App::$strings["mail recalled"] = "почта отозвана";
-App::$strings["duplicate mail received"] = "получено дублирующее сообщение";
-App::$strings["mail delivered"] = "почта доставлен";
-App::$strings["Delivery report for %1\$s"] = "Отчёт о доставке для %1\$s";
-App::$strings["Options"] = "Параметры";
-App::$strings["Redeliver"] = "Доставить повторно";
-App::$strings["Failed to create source. No channel selected."] = "Не удалось создать источник. Канал не выбран.";
-App::$strings["Source created."] = "Источник создан.";
-App::$strings["Source updated."] = "Источник обновлен.";
-App::$strings["Sources App"] = "Приложение \"Источники канала\"";
-App::$strings["Automatically import channel content from other channels or feeds"] = "Автоматический импорт контента из других каналов или лент";
-App::$strings["*"] = "";
-App::$strings["Channel Sources"] = "Источники канала";
-App::$strings["Manage remote sources of content for your channel."] = "Управление удалённым источниками содержимого для вашего канала";
-App::$strings["New Source"] = "Новый источник";
-App::$strings["Import all or selected content from the following channel into this channel and distribute it according to your channel settings."] = "Импортировать всё или выбранное содержимое из следующего канала в этот канал и распределить его в соответствии с вашими настройками.";
-App::$strings["Only import content with these words (one per line)"] = "Импортировать содержимое только с этим текстом (построчно)";
-App::$strings["Leave blank to import all public content"] = "Оставьте пустым для импорта всего общедоступного содержимого";
-App::$strings["Channel Name"] = "Название канала";
-App::$strings["Add the following categories to posts imported from this source (comma separated)"] = "Добавить следующие категории к импортированным публикациям из этого источника (через запятые)";
-App::$strings["Optional"] = "Необязательно";
-App::$strings["Resend posts with this channel as author"] = "Отправить публикации в этот канал повторно как автор";
-App::$strings["Copyrights may apply"] = "Могут применяться авторские права";
-App::$strings["Source not found."] = "Источник не найден.";
-App::$strings["Edit Source"] = "Редактировать источник";
-App::$strings["Delete Source"] = "Удалить источник";
-App::$strings["Source removed"] = "Источник удален";
-App::$strings["Unable to remove source."] = "Невозможно удалить источник.";
-App::$strings["Like/Dislike"] = "Нравится / не нравится";
-App::$strings["This action is restricted to members."] = "Это действие доступно только участникам.";
-App::$strings["Please <a href=\"rmagic\">login with your \$Projectname ID</a> or <a href=\"register\">register as a new \$Projectname member</a> to continue."] = "Пожалуйста, для продолжения <a href=\"rmagic\"> войдите с вашим \$Projectname ID</a> или <a href=\"register\">зарегистрируйтесь как новый участник \$Projectname</a>.";
-App::$strings["Invalid request."] = "Неверный запрос.";
-App::$strings["channel"] = "канал";
-App::$strings["thing"] = "предмет";
-App::$strings["Channel unavailable."] = "Канал недоступен.";
-App::$strings["Previous action reversed."] = "Предыдущее действие отменено.";
-App::$strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s нравится %3\$s %2\$s";
-App::$strings["%1\$s doesn't like %2\$s's %3\$s"] = "%1\$s не нравится %2\$s %3\$s";
-App::$strings["%1\$s agrees with %2\$s's %3\$s"] = "%1\$s согласен с %2\$s %3\$s";
-App::$strings["%1\$s doesn't agree with %2\$s's %3\$s"] = "%1\$s не согласен с %2\$s %3\$s";
-App::$strings["%1\$s abstains from a decision on %2\$s's %3\$s"] = "%1\$s воздерживается от решения по %2\$s%3\$s";
-App::$strings["%1\$s is attending %2\$s's %3\$s"] = "%1\$s посещает %2\$s%3\$s";
-App::$strings["%1\$s is not attending %2\$s's %3\$s"] = "%1\$s не посещает %2\$s%3\$s";
-App::$strings["%1\$s may attend %2\$s's %3\$s"] = "%1\$s может посетить %2\$s%3\$s";
-App::$strings["Action completed."] = "Действие завершено.";
-App::$strings["Thank you."] = "Спасибо.";
-App::$strings["No default suggestions were found."] = "Предложений по умолчанию не найдено.";
-App::$strings["%d rating"] = array(
- 0 => "%d оценка",
- 1 => "%d оценки",
- 2 => "%d оценок",
-);
-App::$strings["Gender: "] = "Пол:";
-App::$strings["Status: "] = "Статус:";
-App::$strings["Homepage: "] = "Домашняя страница:";
-App::$strings["Age:"] = "Возраст:";
-App::$strings["Location:"] = "Местоположение:";
-App::$strings["Description:"] = "Описание:";
-App::$strings["Hometown:"] = "Родной город:";
-App::$strings["About:"] = "О себе:";
-App::$strings["Connect"] = "Подключить";
-App::$strings["Public Forum:"] = "Публичный форум:";
-App::$strings["Keywords: "] = "Ключевые слова:";
-App::$strings["Don't suggest"] = "Не предлагать";
-App::$strings["Common connections (estimated):"] = "Общие контакты (оценочно):";
-App::$strings["Global Directory"] = "Глобальный каталог";
-App::$strings["Local Directory"] = "Локальный каталог";
-App::$strings["Finding:"] = "Поиск:";
-App::$strings["Channel Suggestions"] = "Рекомендации каналов";
-App::$strings["next page"] = "следующая страница";
-App::$strings["previous page"] = "предыдущая страница";
-App::$strings["Sort options"] = "Параметры сортировки";
-App::$strings["Alphabetic"] = "По алфавиту";
-App::$strings["Reverse Alphabetic"] = "Против алфавита";
-App::$strings["Newest to Oldest"] = "От новых к старым";
-App::$strings["Oldest to Newest"] = "От старых к новым";
-App::$strings["No entries (some entries may be hidden)."] = "Нет записей (некоторые записи могут быть скрыты).";
-App::$strings["Xchan Lookup"] = "Поиск Xchan";
-App::$strings["Lookup xchan beginning with (or webbie): "] = "Запрос Xchan начинается с (или webbie):";
-App::$strings["Suggest Channels App"] = "Приложение \"Рекомендуемые каналы\"";
-App::$strings["Suggestions for channels in the \$Projectname network you might be interested in"] = "Предложения по рекомендуемым каналам в сети \$Projectname которые могут вас заинтересовать";
-App::$strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "Нет предложений. Если это новый сайт, повторите попытку через 24 часа.";
-App::$strings["Ignore/Hide"] = "Игнорировать / cкрыть";
+App::$strings["Cards App"] = "Приложение \"Карточки\"";
+App::$strings["Create personal planning cards"] = "Создать личные карточки планирования";
+App::$strings["Add Card"] = "Добавить карточку";
+App::$strings["Account removals are not allowed within 48 hours of changing the account password."] = "Удаление канала не разрешается в течении 48 часов после смены пароля у аккаунта.";
+App::$strings["Remove This Account"] = "Удалить этот аккаунт";
+App::$strings["This account and all its channels will be completely removed from the network. "] = "Этот аккаунт и все его каналы будут полностью удалены из сети.";
+App::$strings["Remove this account, all its channels and all its channel clones from the network"] = "Удалить этот аккаунт, все его каналы и их клоны из сети.";
+App::$strings["By default only the instances of the channels located on this hub will be removed from the network"] = "По умолчанию только представление канала расположенное на данном хабе будет удалено из сети";
App::$strings["Unable to find your hub."] = "Невозможно найти ваш сервер";
App::$strings["Post successful."] = "Успешно опубликовано.";
-App::$strings["Unable to lookup recipient."] = "Не удалось найти получателя.";
-App::$strings["Unable to communicate with requested channel."] = "Не удалось установить связь с запрашиваемым каналом.";
-App::$strings["Cannot verify requested channel."] = "Не удалось установить подлинность требуемого канала.";
-App::$strings["Selected channel has private message restrictions. Send failed."] = "Выбранный канал ограничивает частные сообщения. Отправка не удалась.";
-App::$strings["Messages"] = "Сообщения";
-App::$strings["message"] = "сообщение";
-App::$strings["Message recalled."] = "Сообщение отозванно.";
-App::$strings["Conversation removed."] = "Беседа удалена.";
-App::$strings["Expires YYYY-MM-DD HH:MM"] = "Истекает YYYY-MM-DD HH:MM";
-App::$strings["Requested channel is not in this network"] = "Запрашиваемый канал не доступен.";
-App::$strings["Send Private Message"] = "Отправить личное сообщение";
-App::$strings["To:"] = "Кому:";
-App::$strings["Subject:"] = "Тема:";
-App::$strings["Attach file"] = "Прикрепить файл";
-App::$strings["Send"] = "Отправить";
-App::$strings["Set expiration date"] = "Установить срок действия";
-App::$strings["Delete message"] = "Удалить сообщение";
-App::$strings["Delivery report"] = "Отчёт о доставке";
-App::$strings["Recall message"] = "Отозвать сообщение";
-App::$strings["Message has been recalled."] = "Сообщение отозванно";
-App::$strings["Delete Conversation"] = "Удалить беседу";
-App::$strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Безопасная связь недоступна. Вы <strong>можете</strong> попытаться ответить со страницы профиля отправителя.";
-App::$strings["Send Reply"] = "Отправить ответ";
-App::$strings["Your message for %s (%s):"] = "Ваше сообщение для %s (%s):";
-App::$strings["Public Hubs"] = "Публичные хабы";
-App::$strings["The listed hubs allow public registration for the \$Projectname network. All hubs in the network are interlinked so membership on any of them conveys membership in the network as a whole. Some hubs may require subscription or provide tiered service plans. The hub itself <strong>may</strong> provide additional details."] = "Указанные хабы разрешают публичную регистрацию для сети \$Projectname. Все хабы в сети взаимосвязаны, поэтому членство в любом из них передает членство во всю сеть. Некоторым хабам может потребоваться подписка или предоставление многоуровневых планов обслуживания. Сам хаб <strong>может</strong> предоставить дополнительные сведения.";
-App::$strings["Hub URL"] = "URL сервера";
-App::$strings["Access Type"] = "Тип доступа";
-App::$strings["Registration Policy"] = "Политика регистрации";
-App::$strings["Stats"] = "Статистика";
-App::$strings["Software"] = "Программное обеспечение";
-App::$strings["Rate"] = "Оценка";
-App::$strings["webpage"] = "веб-страница";
-App::$strings["block"] = "заблокировать";
-App::$strings["layout"] = "шаблон";
-App::$strings["menu"] = "меню";
-App::$strings["%s element installed"] = "%s элемент установлен";
-App::$strings["%s element installation failed"] = "%sустановка элемента неудачна.";
-App::$strings["Select a bookmark folder"] = "Выбрать каталог для закладок";
-App::$strings["Save Bookmark"] = "Сохранить закладку";
-App::$strings["URL of bookmark"] = "URL закладки";
-App::$strings["Or enter new bookmark folder name"] = "или введите новое имя каталога закладок";
-App::$strings["Enter a folder name"] = "Введите название каталога";
-App::$strings["or select an existing folder (doubleclick)"] = "или выберите существующий каталог (двойной щелчок)";
-App::$strings["Save to Folder"] = "Сохранить в каталог";
-App::$strings["Remote Diagnostics App"] = "Приложение \"Удалённая диагностика\"";
-App::$strings["Perform diagnostics on remote channels"] = "Производит диагностику удалённых каналов";
-App::$strings["Maximum daily site registrations exceeded. Please try again tomorrow."] = "Превышено максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра.";
-App::$strings["Please indicate acceptance of the Terms of Service. Registration failed."] = "Пожалуйста, подтвердите согласие с \"Условиями обслуживания\". Регистрация не удалась.";
-App::$strings["Passwords do not match."] = "Пароли не совпадают.";
-App::$strings["Registration successful. Continue to create your first channel..."] = "Регистрация завершена успешно. Для продолжения создайте свой первый канал...";
-App::$strings["Registration successful. Please check your email for validation instructions."] = "Регистрация завершена успешно. Пожалуйста проверьте вашу электронную почту для подтверждения.";
-App::$strings["Your registration is pending approval by the site owner."] = "Ваша регистрация ожидает одобрения администрации сайта.";
-App::$strings["Your registration can not be processed."] = "Ваша регистрация не может быть обработана.";
-App::$strings["Registration on this hub is disabled."] = "Регистрация на этом хабе отключена.";
-App::$strings["Registration on this hub is by approval only."] = "Регистрация на этом хабе только по утверждению.";
-App::$strings["<a href=\"pubsites\">Register at another affiliated hub.</a>"] = "<a href=\"pubsites\">Зарегистрироваться на другом хабе.</a>";
-App::$strings["Registration on this hub is by invitation only."] = "Регистрация на этом хабе доступна только по приглашениям.";
-App::$strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Этот сайт превысил максимальное количество регистраций на сегодня. Пожалуйста, попробуйте снова завтра. ";
-App::$strings["I accept the %s for this website"] = "Я принимаю %s для этого веб-сайта.";
-App::$strings["I am over %s years of age and accept the %s for this website"] = "Мой возраст превышает %s лет и я принимаю %s для этого веб-сайта.";
-App::$strings["Your email address"] = "Ваш адрес электронной почты";
-App::$strings["Choose a password"] = "Выберите пароль";
-App::$strings["Please re-enter your password"] = "Пожалуйста, введите пароль еще раз";
-App::$strings["Please enter your invitation code"] = "Пожалуйста, введите Ваш код приглашения";
-App::$strings["Your Name"] = "Ваше имя";
-App::$strings["Real names are preferred."] = "Предпочтительны реальные имена.";
-App::$strings["Your nickname will be used to create an easy to remember channel address e.g. nickname%s"] = "Ваш псевдоним будет использован для создания легко запоминаемого адреса канала, напр. nickname %s";
-App::$strings["Select a channel permission role for your usage needs and privacy requirements."] = "Выберите разрешения для канала в зависимости от ваших потребностей и требований приватности.";
-App::$strings["no"] = "нет";
-App::$strings["yes"] = "да";
-App::$strings["Register"] = "Регистрация";
-App::$strings["This site requires email verification. After completing this form, please check your email for further instructions."] = "Этот сайт требует проверку адреса электронной почты. После заполнения этой формы, пожалуйста, проверьте ваш почтовый ящик для дальнейших инструкций.";
-App::$strings["Cover Photos"] = "Фотографии обложки";
-App::$strings["female"] = "женщина";
-App::$strings["%1\$s updated her %2\$s"] = "%1\$s обновила её %2\$s";
-App::$strings["male"] = "мужчина";
-App::$strings["%1\$s updated his %2\$s"] = "%1\$s обновил его %2\$s";
-App::$strings["%1\$s updated their %2\$s"] = "%1\$s обновили их %2\$s";
-App::$strings["cover photo"] = "фотография обложки";
-App::$strings["Your cover photo may be visible to anybody on the internet"] = "Фотография вашей обложки может быть видна всем в Интернете";
-App::$strings["Change Cover Photo"] = "Изменить фотографию обложки";
-App::$strings["Documentation Search"] = "Поиск документации";
-App::$strings["About"] = "О себе";
-App::$strings["Administrators"] = "Администраторы";
-App::$strings["Developers"] = "Разработчики";
-App::$strings["Tutorials"] = "Руководства";
-App::$strings["\$Projectname Documentation"] = "\$Projectname Документация";
-App::$strings["Contents"] = "Содержимое";
-App::$strings["Article"] = "Статья";
-App::$strings["Item has been removed."] = "Элемент был удалён.";
-App::$strings["Tag removed"] = "Тег удалён";
-App::$strings["Remove Item Tag"] = "Удалить тег элемента";
-App::$strings["Select a tag to remove: "] = "Выбрать тег для удаления:";
-App::$strings["No such group"] = "Нет такой группы";
-App::$strings["No such channel"] = "Нет такого канала";
-App::$strings["Privacy group is empty"] = "Группа безопасности пуста";
-App::$strings["Privacy group: "] = "Группа безопасности: ";
-App::$strings["Invalid channel."] = "Недействительный канал.";
-App::$strings["network"] = "сеть";
-App::$strings["\$Projectname"] = "";
-App::$strings["Welcome to %s"] = "Добро пожаловать в %s";
-App::$strings["Permission Denied."] = "Доступ запрещен.";
-App::$strings["File not found."] = "Файл не найден.";
-App::$strings["Edit file permissions"] = "Редактировать разрешения файла";
-App::$strings["Set/edit permissions"] = "Редактировать разрешения";
-App::$strings["Include all files and sub folders"] = "Включить все файлы и подкаталоги";
-App::$strings["Return to file list"] = "Вернутся к списку файлов";
-App::$strings["Copy/paste this code to attach file to a post"] = "Копировать / вставить этот код для прикрепления файла к публикации";
-App::$strings["Copy/paste this URL to link file from a web page"] = "Копировать / вставить эту URL для ссылки на файл со страницы";
-App::$strings["Share this file"] = "Поделиться этим файлом";
-App::$strings["Show URL to this file"] = "Показать URL этого файла";
-App::$strings["Show in your contacts shared folder"] = "Показать общий каталог в ваших контактах";
-App::$strings["No channel."] = "Канала нет.";
-App::$strings["No connections in common."] = "Общих контактов нет.";
-App::$strings["View Common Connections"] = "Просмотр общий контактов";
-App::$strings["Email verification resent"] = "Сообщение для проверки email отправлено повторно";
-App::$strings["Unable to resend email verification message."] = "Невозможно повторно отправить сообщение для проверки email";
-App::$strings["No connections."] = "Контактов нет.";
-App::$strings["Visit %s's profile [%s]"] = "Посетить %s ​​профиль [%s]";
-App::$strings["View Connections"] = "Просмотр контактов";
-App::$strings["Blocked accounts"] = "Заблокированные аккаунты";
-App::$strings["Expired accounts"] = "Просроченные аккаунты";
-App::$strings["Expiring accounts"] = "Близкие к просрочке аккаунты";
-App::$strings["Message queues"] = "Очередь сообщений";
-App::$strings["Your software should be updated"] = "Ваше программное обеспечение должно быть обновлено";
-App::$strings["Summary"] = "Резюме";
-App::$strings["Registered accounts"] = "Зарегистрированные аккаунты";
-App::$strings["Pending registrations"] = "Ждут утверждения";
-App::$strings["Registered channels"] = "Зарегистрированные каналы";
-App::$strings["Active addons"] = "Активные расширения";
-App::$strings["Version"] = "Версия системы";
-App::$strings["Repository version (master)"] = "Версия репозитория (master)";
-App::$strings["Repository version (dev)"] = "Версия репозитория (dev)";
-App::$strings["No service class restrictions found."] = "Ограничений класса обслуживание не найдено.";
-App::$strings["Website:"] = "Веб-сайт:";
-App::$strings["Remote Channel [%s] (not yet known on this site)"] = "Удалённый канал [%s] (пока неизвестен на этом сайте)";
-App::$strings["Rating (this information is public)"] = "Оценка (эта информация общедоступна)";
-App::$strings["Optionally explain your rating (this information is public)"] = "Объясните свою оценку (необязательно; эта информация общедоступна)";
-App::$strings["Edit Card"] = "Редактировать карточку";
-App::$strings["No valid account found."] = "Действительный аккаунт не найден.";
-App::$strings["Password reset request issued. Check your email."] = "Запрос на сброс пароля отправлен. Проверьте вашу электронную почту.";
-App::$strings["Site Member (%s)"] = "Участник сайта (%s)";
-App::$strings["Password reset requested at %s"] = "Запрошен сброс пароля на %s";
-App::$strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "Запрос не может быть проверен. (Вы могли отправить его раньше). Сброс пароля не возможен.";
-App::$strings["Password Reset"] = "Сбросить пароль";
-App::$strings["Your password has been reset as requested."] = "Ваш пароль в соответствии с просьбой сброшен.";
-App::$strings["Your new password is"] = "Ваш новый пароль";
-App::$strings["Save or copy your new password - and then"] = "Сохраните ваш новый пароль и затем";
-App::$strings["click here to login"] = "нажмите здесь чтобы войти";
-App::$strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Ваш пароль может быть изменён на странице <em>Настройки</em> после успешного входа.";
-App::$strings["Your password has changed at %s"] = "Пароль был изменен на %s";
-App::$strings["Forgot your Password?"] = "Забыли ваш пароль?";
-App::$strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Введите ваш адрес электронной почты и нажмите отправить чтобы сбросить пароль. Затем проверьте ваш почтовый ящик для дальнейших инструкций. ";
-App::$strings["Email Address"] = "Адрес электронной почты";
-App::$strings["Name is required"] = "Необходимо имя";
-App::$strings["Key and Secret are required"] = "Требуются ключ и код";
-App::$strings["OAuth Apps Manager App"] = "Приложение \"Менеджер Oauth\"";
-App::$strings["OAuth authentication tokens for mobile and remote apps"] = "Токены аутентификации OAuth для мобильный и удалённых приложений";
-App::$strings["Consumer Key"] = "Ключ клиента";
-App::$strings["Icon url"] = "URL значка";
-App::$strings["Application not found."] = "Приложение не найдено.";
-App::$strings["Connected OAuth Apps"] = "Подключенные приложения OAuth";
-App::$strings["Mark all seen"] = "Отметить как просмотренное";
-App::$strings["Likes %1\$s's %2\$s"] = "Нравится %1\$s %2\$s";
-App::$strings["Doesn't like %1\$s's %2\$s"] = "Не нравится %1\$s %2\$s";
-App::$strings["Will attend %1\$s's %2\$s"] = "Примет участие %1\$s %2\$s";
-App::$strings["Will not attend %1\$s's %2\$s"] = "Не примет участие %1\$s %2\$s";
-App::$strings["May attend %1\$s's %2\$s"] = "Возможно примет участие %1\$s %2\$s";
-App::$strings["ActivityPub"] = "";
-App::$strings["0. Beginner/Basic"] = "Начинающий / Базовый";
-App::$strings["1. Novice - not skilled but willing to learn"] = "1. Новичок - не опытный, но желающий учиться";
-App::$strings["2. Intermediate - somewhat comfortable"] = "2. Промежуточный - более удобный";
-App::$strings["3. Advanced - very comfortable"] = "3. Продвинутый - очень удобный";
-App::$strings["4. Expert - I can write computer code"] = "4. Эксперт - я умею программировать";
-App::$strings["5. Wizard - I probably know more than you do"] = "5. Волшебник - возможно я знаю больше чем ты";
-App::$strings["Unable to verify channel signature"] = "Невозможно проверить подпись канала";
-App::$strings["Apps"] = "Приложения";
-App::$strings["Affinity Tool"] = "Степень сходства";
-App::$strings["Site Admin"] = "Администратор сайта";
-App::$strings["Report Bug"] = "Сообщить об ошибке";
-App::$strings["Bookmarks"] = "Закладки";
-App::$strings["Chatrooms"] = "Чаты";
-App::$strings["Remote Diagnostics"] = "Удалённая диагностика";
-App::$strings["Suggest Channels"] = "Предлагаемые каналы";
-App::$strings["Login"] = "Войти";
-App::$strings["Stream"] = "Поток";
-App::$strings["Wiki"] = "";
-App::$strings["Channel Home"] = "Главная канала";
-App::$strings["Events"] = "События";
-App::$strings["Directory"] = "Каталог";
-App::$strings["Mail"] = "Переписка";
-App::$strings["Chat"] = "Чат";
-App::$strings["Probe"] = "Проба";
-App::$strings["Suggest"] = "Предложить";
-App::$strings["Random Channel"] = "Случайный канал";
-App::$strings["Invite"] = "Пригласить";
-App::$strings["Features"] = "Функции";
-App::$strings["Language"] = "Язык";
-App::$strings["Post"] = "Публикация";
-App::$strings["Profile Photo"] = "Фотография профиля";
-App::$strings["Profiles"] = "Редактировать профиль";
-App::$strings["Notifications"] = "Оповещения";
-App::$strings["Order Apps"] = "Порядок приложений";
-App::$strings["CalDAV"] = "";
-App::$strings["CardDAV"] = "";
-App::$strings["Guest Access"] = "Гостевой доступ";
+App::$strings["Authentication failed."] = "Ошибка аутентификации.";
+App::$strings["Comanche page description language help"] = "Помощь по языку описания страниц Comanche ";
+App::$strings["Layout Description"] = "Описание шаблона";
+App::$strings["Download PDL file"] = "Загрузить PDL файл";
+App::$strings["This page is available only to site members"] = "Эта страница доступна только для подписчиков сайта";
+App::$strings["Welcome"] = "Добро пожаловать";
+App::$strings["What would you like to do?"] = "Что бы вы хотели сделать?";
+App::$strings["Please bookmark this page if you would like to return to it in the future"] = "Пожалуйста, запомните эту страницу если вы хотите вернуться на неё в будущем";
+App::$strings["Upload a profile photo"] = "Загрузить фотографию профиля";
+App::$strings["Upload a cover photo"] = "Загрузить фотографию обложки";
+App::$strings["Edit your default profile"] = "Редактировать ваш профиль по умолчанию";
+App::$strings["View friend suggestions"] = "Просмотр рекомендуемых друзей";
+App::$strings["View the channel directory"] = "Просмотр каталога каналов";
+App::$strings["View/edit your channel settings"] = "Просмотреть / редактировать настройки вашего канала";
+App::$strings["View the site or project documentation"] = "Просмотр документации сайта / проекта";
+App::$strings["Visit your channel homepage"] = "Посетить страницу вашего канала";
+App::$strings["View your connections and/or add somebody whose address you already know"] = "Просмотреть ваши контакты и / или добавить кого-то чей адрес в уже знаете";
+App::$strings["View your personal stream (this may be empty until you add some connections)"] = "Ваш персональный поток (может быть пуст пока вы не добавите контакты)";
+App::$strings["View the public stream. Warning: this content is not moderated"] = "Просмотр публичного потока. Предупреждение: этот контент не модерируется";
+App::$strings["Forums"] = "Форумы";
App::$strings["Notes"] = "Заметки";
-App::$strings["OAuth Apps Manager"] = "Менеджер OAuth";
-App::$strings["OAuth2 Apps Manager"] = "Менеджер OAuth2";
-App::$strings["PDL Editor"] = "Редактор PDL";
-App::$strings["Premium Channel"] = "Премиальный канал";
-App::$strings["My Chatrooms"] = "Мои чаты";
-App::$strings["Channel Export"] = "Экспорт канала";
-App::$strings["Purchase"] = "Купить";
-App::$strings["Undelete"] = "Восстановить";
-App::$strings["Add to app-tray"] = "Добавить в app-tray";
-App::$strings["Remove from app-tray"] = "Удалить из app-tray";
-App::$strings["Pin to navbar"] = "Добавить на панель навигации";
-App::$strings["Unpin from navbar"] = "Удалить с панели навигации";
-App::$strings["__ctx:permcat__ default"] = "по умолчанию";
-App::$strings["__ctx:permcat__ follower"] = "поклонник";
-App::$strings["__ctx:permcat__ contributor"] = "участник";
-App::$strings["__ctx:permcat__ publisher"] = "издатель";
-App::$strings["(No Title)"] = "(нет заголовка)";
-App::$strings["Wiki page create failed."] = "Не удалось создать страницу Wiki.";
-App::$strings["Wiki not found."] = "Wiki не найдена.";
-App::$strings["Destination name already exists"] = "Имя назначения уже существует";
-App::$strings["Page not found"] = "Страница не найдена.";
-App::$strings["Error reading page content"] = "Ошибка чтения содержимого страницы";
-App::$strings["Error reading wiki"] = "Ошибка чтения Wiki";
-App::$strings["Page update failed."] = "Не удалось обновить страницу.";
-App::$strings["Nothing deleted"] = "Ничего не удалено";
-App::$strings["Compare: object not found."] = "Сравнение: объект не найден.";
-App::$strings["Page updated"] = "Страница обновлена";
-App::$strings["Untitled"] = "Не озаглавлено";
-App::$strings["Wiki resource_id required for git commit"] = "Требуется resource_id Wiki для отправки в Git";
+App::$strings["Suggestions"] = "Рекомендации";
+App::$strings["See more..."] = "Просмотреть больше...";
+App::$strings["New Network Activity"] = "Новая сетевая активность";
+App::$strings["New Network Activity Notifications"] = "Новые уведомления о сетевой активности";
+App::$strings["View your network activity"] = "Просмотреть вашу сетевую активность";
+App::$strings["Mark all notifications read"] = "Пометить уведомления как прочитанные";
+App::$strings["Show new posts only"] = "Показывать только новые публикации";
+App::$strings["Filter by name or address"] = "Фильтровать по имени или адресу";
+App::$strings["New Home Activity"] = "Новая локальная активность";
+App::$strings["New Home Activity Notifications"] = "Новые уведомления локальной активности";
+App::$strings["View your home activity"] = "Просмотреть локальную активность";
+App::$strings["Mark all notifications seen"] = "Пометить уведомления как просмотренные";
+App::$strings["New Mails"] = "Новая переписка";
+App::$strings["New Mails Notifications"] = "Уведомления о новой переписке";
+App::$strings["View your private mails"] = "Просмотреть вашу личную переписку";
+App::$strings["Mark all messages seen"] = "Пометить сообщения как просмотренные";
+App::$strings["New Events"] = "Новые события";
+App::$strings["New Events Notifications"] = "Уведомления о новых событиях";
+App::$strings["View events"] = "Просмотреть события";
+App::$strings["Mark all events seen"] = "Пометить все события как просмотренные";
+App::$strings["New Connections Notifications"] = "Уведомления о новых контактах";
+App::$strings["View all connections"] = "Просмотр всех контактов";
+App::$strings["New Files"] = "Новые файлы";
+App::$strings["New Files Notifications"] = "Уведомления о новых файлах";
+App::$strings["Notices"] = "Оповещения";
+App::$strings["View all notices"] = "Просмотреть все оповещения";
+App::$strings["Mark all notices seen"] = "Пометить все оповещения как просмотренные";
+App::$strings["New Registrations"] = "Новые регистрации";
+App::$strings["New Registrations Notifications"] = "Уведомления о новых регистрациях";
+App::$strings["Public Stream Notifications"] = "Уведомления публичного потока";
+App::$strings["View the public stream"] = "Просмотреть публичный поток";
+App::$strings["Sorry, you have got no notifications at the moment"] = "Извините, но сейчас у вас нет уведомлений";
+App::$strings["Tasks"] = "Задачи";
+App::$strings["photo/image"] = "фотография / изображение";
+App::$strings["Select Channel"] = "Выбрать канал";
+App::$strings["Read-write"] = "Чтение-запись";
+App::$strings["Read-only"] = "Только чтение";
+App::$strings["My Calendars"] = "Мои календари";
+App::$strings["Shared Calendars"] = "Общие календари";
+App::$strings["Share this calendar"] = "Поделиться этим календарём";
+App::$strings["Calendar name and color"] = "Имя и цвет календаря";
+App::$strings["Create new calendar"] = "Создать новый календарь";
+App::$strings["Calendar Name"] = "Имя календаря";
+App::$strings["Calendar Tools"] = "Инструменты календаря";
+App::$strings["Import calendar"] = "Импортировать календарь";
+App::$strings["Select a calendar to import to"] = "Выбрать календарь для импорта в";
+App::$strings["Addressbooks"] = "Адресные книги";
+App::$strings["Addressbook name"] = "Имя адресной книги";
+App::$strings["Create new addressbook"] = "Создать новую адресную книгу";
+App::$strings["Addressbook Name"] = "Имя адресной книги";
+App::$strings["Addressbook Tools"] = "Инструменты адресной книги";
+App::$strings["Import addressbook"] = "Импортировать адресную книгу";
+App::$strings["Select an addressbook to import to"] = "Выбрать адресную книгу для импорта в";
+App::$strings["__ctx:widget__ Activity"] = "Активность";
+App::$strings["HQ Control Panel"] = "Панель управления HQ";
+App::$strings["Create a new post"] = "Создать новую публикацию";
+App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "У вас есть %1$.0f из %2$.0f разрешенных контактов.";
+App::$strings["Add New Connection"] = "Добавить новый контакт";
+App::$strings["Enter channel address"] = "Введите адрес канала";
+App::$strings["Examples: bob@example.com, https://example.com/barbara"] = "Пример: ivan@example.com, http://example.com/ivan";
+App::$strings["Archives"] = "Архивы";
+App::$strings["Suggested Chatrooms"] = "Рекомендуемые чаты";
+App::$strings["Rating Tools"] = "Инструменты оценки";
+App::$strings["Rate Me"] = "Оценить меня";
+App::$strings["View Ratings"] = "Просмотр оценок";
+App::$strings["Profile Creation"] = "Создание профиля";
+App::$strings["Upload profile photo"] = "Загрузить фотографию профиля";
+App::$strings["Upload cover photo"] = "Загрузить фотографию обложки";
+App::$strings["Find and Connect with others"] = "Найти и вступить в контакт";
+App::$strings["View the directory"] = "Просмотреть каталог";
+App::$strings["Manage your connections"] = "Управление вашими контактами";
+App::$strings["Communicate"] = "Связаться";
+App::$strings["View your channel homepage"] = "Домашняя страница канала";
+App::$strings["View your network stream"] = "Просмотреть ваш сетевой поток";
+App::$strings["Documentation"] = "Документация";
+App::$strings["Missing Features?"] = "Отсутствует функция?";
+App::$strings["Pin apps to navigation bar"] = "Прикрепить приложение к панели";
+App::$strings["Install more apps"] = "Установить больше приложений";
+App::$strings["View public stream"] = "Просмотреть публичный поток";
+App::$strings["Private Mail Menu"] = "Меню личной переписки";
+App::$strings["Combined View"] = "Комбинированный вид";
+App::$strings["Inbox"] = "Входящие";
+App::$strings["Outbox"] = "Исходящие";
+App::$strings["New Message"] = "Новое сообщение";
+App::$strings["Add new page"] = "Добавить новую страницу";
+App::$strings["Wiki Pages"] = "Wiki страницы";
+App::$strings["Page name"] = "Название страницы";
+App::$strings["Events Tools"] = "Инструменты для событий";
+App::$strings["Export Calendar"] = "Экспортировать календарь";
+App::$strings["Import Calendar"] = "Импортировать календарь";
+App::$strings["Overview"] = "Обзор";
+App::$strings["Account settings"] = "Настройки аккаунта";
+App::$strings["Channel settings"] = "Настройки канала";
+App::$strings["Display settings"] = "Настройки отображения";
+App::$strings["Manage locations"] = "Управление местоположением";
+App::$strings["Member registrations waiting for confirmation"] = "Регистрации участников, ожидающие подверждения";
+App::$strings["Features"] = "Функции";
+App::$strings["Inspect queue"] = "Просмотр очереди";
+App::$strings["DB updates"] = "Обновление базы данных";
+App::$strings["Addon Features"] = "Настройки расширений";
+App::$strings["App Collections"] = "Коллекции приложений";
+App::$strings["Installed apps"] = "Установленные приложения";
+App::$strings["Remove term"] = "Удалить термин";
+App::$strings["Show posts related to the %s privacy group"] = "Показывать публикации относящиеся к группе безопасности %s";
+App::$strings["Show my privacy groups"] = "Показывать мои группы безопасности";
+App::$strings["Show posts to this forum"] = "Показывать публикации этого форума";
+App::$strings["Show forums"] = "Показывать форумы";
+App::$strings["Starred Posts"] = "Отмеченные публикации";
+App::$strings["Show posts that I have starred"] = "Показывать публикации которые я отметил";
+App::$strings["Personal Posts"] = "Личные публикации";
+App::$strings["Show posts that mention or involve me"] = "Показывать публикации где вы были упомянуты или привлечены";
+App::$strings["Show posts that I have filed to %s"] = "Показывать публикации которые я добавил в %s";
+App::$strings["Show filed post categories"] = "Показывать категории добавленных публикаций";
+App::$strings["Panel search"] = "Панель поиска";
+App::$strings["Filter by name"] = "Отфильтровать по имени";
+App::$strings["Remove active filter"] = "Удалить активный фильтр";
+App::$strings["Stream Filters"] = "Фильтры потока";
+App::$strings["Chat Members"] = "Участники чата";
+App::$strings["Click to show more"] = "Нажмите чтобы показать больше";
+App::$strings["Refresh"] = "Обновить";
+App::$strings["Commented Date"] = "По комментариям";
+App::$strings["Order by last commented date"] = "Сортировка по дате последнего комментария";
+App::$strings["Posted Date"] = "По публикациям";
+App::$strings["Order by last posted date"] = "Сортировка по дате последней публикации";
+App::$strings["Date Unthreaded"] = "По порядку";
+App::$strings["Order unthreaded by date"] = "Сортировка в порядке поступления";
+App::$strings["Stream Order"] = "Упорядочить поток";
+App::$strings["Bookmarked Chatrooms"] = "Закладки чатов";
+App::$strings["Received Messages"] = "Полученные сообщения";
+App::$strings["Sent Messages"] = "Отправленные сообщения";
+App::$strings["Conversations"] = "Беседы";
+App::$strings["No messages."] = "Сообщений нет.";
+App::$strings["Delete conversation"] = "Удалить беседу";
App::$strings["__ctx:wiki_history__ Message"] = "Сообщение";
App::$strings["Date"] = "Дата";
App::$strings["Compare"] = "Сравнить";
-App::$strings["Different viewers will see this text differently"] = "Различные зрители увидят этот текст по-разному";
-App::$strings["Visible to your default audience"] = "Видно вашей аудитории по умолчанию.";
-App::$strings["Only me"] = "Только мне";
-App::$strings["Public"] = "Общедоступно";
-App::$strings["Anybody in the \$Projectname network"] = "Любому в сети \$Projectname";
-App::$strings["Any account on %s"] = "Любой аккаунт в %s";
-App::$strings["Any of my connections"] = "Любой из моих контактов";
-App::$strings["Only connections I specifically allow"] = "Только те контакты, кому я дам разрешение";
-App::$strings["Anybody authenticated (could include visitors from other networks)"] = "Любой аутентифицированный (может включать посетителей их других сетей)";
-App::$strings["Any connections including those who haven't yet been approved"] = "Любые контакты включая те, которые вы ещё не одобрили";
-App::$strings["This is your default setting for the audience of your normal stream, and posts."] = "Это настройка по умолчанию для аудитории ваших обычных потоков и публикаций";
-App::$strings["This is your default setting for who can view your default channel profile"] = "Это настройка по умолчанию для тех, кто может просматривать профиль вашего основного канала";
-App::$strings["This is your default setting for who can view your connections"] = "Это настройка по умолчанию для тех, кто может просматривать ваши контакты";
-App::$strings["This is your default setting for who can view your file storage and photos"] = "Это настройка по умолчанию для тех, кто может просматривать ваше хранилище файлов и фотографий";
-App::$strings["This is your default setting for the audience of your webpages"] = "Это настройка по умолчанию для аудитории ваших веб-страниц";
-App::$strings["Directory Options"] = "Параметры каталога";
-App::$strings["Safe Mode"] = "Безопасный режим";
-App::$strings["Public Forums Only"] = "Только публичные форумы";
-App::$strings["This Website Only"] = "Только этот веб-сайт";
-App::$strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Удаленная группа с этим названием была восстановлена. Существующие разрешения пункт <strong>могут</strong> применяться к этой группе и к её будущих участников. Если это не то, чего вы хотели, пожалуйста, создайте другую группу с другим именем.";
-App::$strings["Add new connections to this privacy group"] = "Добавить новые контакты в группу безопасности";
-App::$strings["edit"] = "редактировать";
-App::$strings["Edit group"] = "Редактировать группу";
-App::$strings["Add privacy group"] = "Добавить группу безопасности";
-App::$strings["Channels not in any privacy group"] = "Каналы не включены ни в одну группу безопасности";
-App::$strings["add"] = "добавить";
-App::$strings["Missing room name"] = "Отсутствует название комнаты";
-App::$strings["Duplicate room name"] = "Название комнаты дублируется";
-App::$strings["Invalid room specifier."] = "Неверный указатель комнаты.";
-App::$strings["Room not found."] = "Комната не найдена.";
-App::$strings["Room is full"] = "Комната переполнена";
-App::$strings["Unable to verify site signature for %s"] = "Невозможно проверить подпись сайта %s";
+App::$strings["Can view my channel stream and posts"] = "Может просматривать мой поток и сообщения";
+App::$strings["Can send me their channel stream and posts"] = "Может присылать мне свои потоки и сообщения";
+App::$strings["Can view my default channel profile"] = "Может просматривать мой стандартный профиль канала";
+App::$strings["Can view my connections"] = "Может просматривать мои контакты";
+App::$strings["Can view my file storage and photos"] = "Может просматривать мое хранилище файлов";
+App::$strings["Can upload/modify my file storage and photos"] = "Может загружать/изменять мои файлы и фотографии в хранилище";
+App::$strings["Can view my channel webpages"] = "Может просматривать мои веб-страницы";
+App::$strings["Can view my wiki pages"] = "Может просматривать мои вики-страницы";
+App::$strings["Can create/edit my channel webpages"] = "Может редактировать мои веб-страницы";
+App::$strings["Can write to my wiki pages"] = "Может редактировать мои вики-страницы";
+App::$strings["Can post on my channel (wall) page"] = "Может публиковать на моей странице канала";
+App::$strings["Can comment on or like my posts"] = "Может прокомментировать или отмечать как понравившиеся мои публикации";
+App::$strings["Can send me private mail messages"] = "Может отправлять мне личные сообщения по эл. почте";
+App::$strings["Can like/dislike profiles and profile things"] = "Может комментировать или отмечать как нравится/ненравится мой профиль";
+App::$strings["Can forward to all my channel connections via ! mentions in posts"] = "Может пересылать всем подписчикам моего канала используя ! в публикациях";
+App::$strings["Can chat with me"] = "Может общаться со мной в чате";
+App::$strings["Can source my public posts in derived channels"] = "Может использовать мои публичные сообщения в клонированных лентах сообщений";
+App::$strings["Can administer my channel"] = "Может администрировать мой канал";
+App::$strings["Social Networking"] = "Социальная Сеть";
+App::$strings["Social - Federation"] = "Социальная - Федерация";
+App::$strings["Social - Mostly Public"] = "Социальная - В основном общественный";
+App::$strings["Social - Restricted"] = "Социальная - Ограниченный";
+App::$strings["Social - Private"] = "Социальная - Частный";
+App::$strings["Community Forum"] = "Форум сообщества";
+App::$strings["Forum - Mostly Public"] = "Форум - В основном общественный";
+App::$strings["Forum - Restricted"] = "Форум - Ограниченный";
+App::$strings["Forum - Private"] = "Форум - Частный";
+App::$strings["Feed Republish"] = "Публиковать ленты новостей";
+App::$strings["Feed - Mostly Public"] = "Ленты новостей - В основном общественный";
+App::$strings["Feed - Restricted"] = "Ленты новостей - Ограниченный";
+App::$strings["Special Purpose"] = "Спец. назначение";
+App::$strings["Special - Celebrity/Soapbox"] = "Спец. назначение - Знаменитость/Soapbox";
+App::$strings["Special - Group Repository"] = "Спец. назначение - Групповой репозиторий";
+App::$strings["Custom/Expert Mode"] = "Экспертный режим";
+App::$strings["Update Error at %s"] = "Ошибка обновления на %s";
+App::$strings["Update %s failed. See error logs."] = "Выполнение %s неудачно. Проверьте системный журнал.";
App::$strings["\$Projectname Notification"] = "Оповещение \$Projectname ";
App::$strings["\$projectname"] = "";
App::$strings["Thank You,"] = "Спасибо,";
@@ -1919,27 +2711,65 @@ App::$strings["created a new post"] = "создал новую публикац
App::$strings["commented on %s's post"] = "прокомментировал публикацию %s";
App::$strings["edited a post dated %s"] = "отредактировал публикацию датированную %s";
App::$strings["edited a comment dated %s"] = "отредактировал комментарий датированный %s";
-App::$strings["Wiki updated successfully"] = "Wiki успешно обновлена";
-App::$strings["Wiki files deleted successfully"] = "Wiki успешно удалена";
-App::$strings["Update Error at %s"] = "Ошибка обновления на %s";
-App::$strings["Update %s failed. See error logs."] = "Выполнение %s неудачно. Проверьте системный журнал.";
-App::$strings["Private Message"] = "Личное сообщение";
+App::$strings["(No Title)"] = "(нет заголовка)";
+App::$strings["Wiki page create failed."] = "Не удалось создать страницу Wiki.";
+App::$strings["Wiki not found."] = "Wiki не найдена.";
+App::$strings["Destination name already exists"] = "Имя назначения уже существует";
+App::$strings["Page not found"] = "Страница не найдена.";
+App::$strings["Error reading page content"] = "Ошибка чтения содержимого страницы";
+App::$strings["Error reading wiki"] = "Ошибка чтения Wiki";
+App::$strings["Page update failed."] = "Не удалось обновить страницу.";
+App::$strings["Nothing deleted"] = "Ничего не удалено";
+App::$strings["Compare: object not found."] = "Сравнение: объект не найден.";
+App::$strings["Page updated"] = "Страница обновлена";
+App::$strings["Untitled"] = "Не озаглавлено";
+App::$strings["Wiki resource_id required for git commit"] = "Требуется resource_id Wiki для отправки в Git";
+App::$strings["__ctx:permcat__ default"] = "по умолчанию";
+App::$strings["__ctx:permcat__ follower"] = "поклонник";
+App::$strings["__ctx:permcat__ contributor"] = "участник";
+App::$strings["__ctx:permcat__ publisher"] = "издатель";
+App::$strings["Apps"] = "Приложения";
+App::$strings["Affinity Tool"] = "Степень сходства";
+App::$strings["Site Admin"] = "Администратор сайта";
+App::$strings["Report Bug"] = "Сообщить об ошибке";
+App::$strings["Content Filter"] = "Фильтр содержимого";
+App::$strings["Content Import"] = "Импорт содержимого";
+App::$strings["Remote Diagnostics"] = "Удалённая диагностика";
+App::$strings["Suggest Channels"] = "Предлагаемые каналы";
+App::$strings["Stream"] = "Поток";
+App::$strings["Mail"] = "Переписка";
+App::$strings["Chat"] = "Чат";
+App::$strings["Probe"] = "Проба";
+App::$strings["Suggest"] = "Предложить";
+App::$strings["Random Channel"] = "Случайный канал";
+App::$strings["Invite"] = "Пригласить";
+App::$strings["Language"] = "Язык";
+App::$strings["Post"] = "Публикация";
+App::$strings["Profile Photo"] = "Фотография профиля";
+App::$strings["Notifications"] = "Оповещения";
+App::$strings["Order Apps"] = "Порядок приложений";
+App::$strings["CardDAV"] = "";
+App::$strings["Guest Access"] = "Гостевой доступ";
+App::$strings["OAuth Apps Manager"] = "Менеджер OAuth";
+App::$strings["OAuth2 Apps Manager"] = "Менеджер OAuth2";
+App::$strings["PDL Editor"] = "Редактор PDL";
+App::$strings["Premium Channel"] = "Премиальный канал";
+App::$strings["My Chatrooms"] = "Мои чаты";
+App::$strings["Channel Export"] = "Экспорт канала";
+App::$strings["Purchase"] = "Купить";
+App::$strings["Undelete"] = "Восстановить";
+App::$strings["Add to app-tray"] = "Добавить в app-tray";
+App::$strings["Remove from app-tray"] = "Удалить из app-tray";
+App::$strings["Pin to navbar"] = "Добавить на панель навигации";
+App::$strings["Unpin from navbar"] = "Удалить с панели навигации";
App::$strings["Privacy conflict. Discretion advised."] = "Конфиликт настроек конфиденциальности.";
-App::$strings["Admin Delete"] = "Удалено администратором";
-App::$strings["Select"] = "Выбрать";
App::$strings["I will attend"] = "Я буду участвовать";
App::$strings["I will not attend"] = "Я не буду участвовать";
App::$strings["I might attend"] = "Я возможно буду присутствовать";
App::$strings["I agree"] = "Я согласен";
App::$strings["I disagree"] = "Я не согласен";
App::$strings["I abstain"] = "Я воздержался";
-App::$strings["Toggle Star Status"] = "Переключить статус пометки";
-App::$strings["Message signature validated"] = "Подпись сообщения проверена";
-App::$strings["Message signature incorrect"] = "Подпись сообщения неверная";
App::$strings["Add Tag"] = "Добавить тег";
-App::$strings["Conversation Tools"] = "Инструменты общения";
-App::$strings["like"] = "нравится";
-App::$strings["dislike"] = "не нравится";
App::$strings["Share This"] = "Поделиться этим";
App::$strings["share"] = "поделиться";
App::$strings["Delivery Report"] = "Отчёт о доставке";
@@ -1953,230 +2783,257 @@ App::$strings["to"] = "к";
App::$strings["via"] = "через";
App::$strings["Wall-to-Wall"] = "Стена-к-Стене";
App::$strings["via Wall-To-Wall:"] = "через Стена-к-Стене:";
-App::$strings["from %s"] = "от %s";
-App::$strings["last edited: %s"] = "последнее редактирование: %s";
-App::$strings["Expires: %s"] = "Срок действия: %s";
App::$strings["Attend"] = "Посетить";
App::$strings["Attendance Options"] = "Параметры посещаемости";
App::$strings["Vote"] = "Голосовать";
App::$strings["Voting Options"] = "Параметры голосования";
App::$strings["Save Bookmarks"] = "Сохранить закладки";
App::$strings["Add to Calendar"] = "Добавить в календарь";
-App::$strings["This is an unsaved preview"] = "Это несохранённый просмотр";
-App::$strings["%s show all"] = "%s показать всё";
-App::$strings["Bold"] = "Жирный";
-App::$strings["Italic"] = "Курсив";
-App::$strings["Underline"] = "Подчеркнутый";
-App::$strings["Quote"] = "Цитата";
-App::$strings["Code"] = "Код";
App::$strings["Image"] = "Изображение";
-App::$strings["Attach/Upload file"] = "Прикрепить/загрузить файл";
App::$strings["Insert Link"] = "Вставить ссылку";
App::$strings["Video"] = "Видео";
App::$strings["Your full name (required)"] = "Ваше полное имя (требуется)";
App::$strings["Your email address (required)"] = "Ваш адрес электронной почты (требуется)";
App::$strings["Your website URL (optional)"] = "URL вашего вебсайта (необязательно)";
-App::$strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "Удалённая аутентификация заблокирована. Вы вошли на этот сайт локально. Пожалуйста, выйдите и попробуйте ещё раз.";
-App::$strings["Welcome %s. Remote authentication successful."] = "Добро пожаловать %s. Удаленная аутентификация успешно завершена.";
-App::$strings["parent"] = "источник";
-App::$strings["Collection"] = "Коллекция";
-App::$strings["Principal"] = "Субъект";
-App::$strings["Addressbook"] = "Адресная книга";
-App::$strings["Calendar"] = "Календарь";
-App::$strings["Schedule Inbox"] = "План занятий входящий";
-App::$strings["Schedule Outbox"] = "План занятий исходящий";
-App::$strings["Total"] = "Всего";
-App::$strings["Shared"] = "Общие";
-App::$strings["Add Files"] = "Добавить файлы";
-App::$strings["You are using %1\$s of your available file storage."] = "Вы используете %1\$s из доступного вам хранилища файлов.";
-App::$strings["You are using %1\$s of %2\$s available file storage. (%3\$s&#37;)"] = "Вы используете %1\$s из %2\$s доступного хранилища файлов (%3\$s&#37;).";
-App::$strings["WARNING:"] = "Предупреждение:";
-App::$strings["Create new folder"] = "Создать новую папку";
-App::$strings["Upload file"] = "Загрузить файл";
-App::$strings["Drop files here to immediately upload"] = "Поместите файлы сюда для немедленной загрузки";
-App::$strings["Forums"] = "Форумы";
-App::$strings["Select Channel"] = "Выбрать канал";
-App::$strings["Read-write"] = "Чтение-запись";
-App::$strings["Read-only"] = "Только чтение";
-App::$strings["My Calendars"] = "Мои календари";
-App::$strings["Shared Calendars"] = "Общие календари";
-App::$strings["Share this calendar"] = "Поделиться этим календарём";
-App::$strings["Calendar name and color"] = "Имя и цвет календаря";
-App::$strings["Create new calendar"] = "Создать новый календарь";
-App::$strings["Calendar Name"] = "Имя календаря";
-App::$strings["Calendar Tools"] = "Инструменты календаря";
-App::$strings["Import calendar"] = "Импортировать календарь";
-App::$strings["Select a calendar to import to"] = "Выбрать календарь для импорта в";
-App::$strings["Addressbooks"] = "Адресные книги";
-App::$strings["Addressbook name"] = "Имя адресной книги";
-App::$strings["Create new addressbook"] = "Создать новую адресную книгу";
-App::$strings["Addressbook Name"] = "Имя адресной книги";
-App::$strings["Addressbook Tools"] = "Инструменты адресной книги";
-App::$strings["Import addressbook"] = "Импортировать адресную книгу";
-App::$strings["Select an addressbook to import to"] = "Выбрать адресную книгу для импорта в";
-App::$strings["Categories"] = "Категории";
-App::$strings["Everything"] = "Всё";
-App::$strings["Events Tools"] = "Инструменты для событий";
-App::$strings["Export Calendar"] = "Экспортировать календарь";
-App::$strings["Import Calendar"] = "Импортировать календарь";
-App::$strings["Suggested Chatrooms"] = "Рекомендуемые чаты";
-App::$strings["HQ Control Panel"] = "Панель управления HQ";
-App::$strings["Create a new post"] = "Создать новую публикацию";
-App::$strings["Private Mail Menu"] = "Меню личной переписки";
-App::$strings["Combined View"] = "Комбинированный вид";
-App::$strings["Inbox"] = "Входящие";
-App::$strings["Outbox"] = "Исходящие";
-App::$strings["New Message"] = "Новое сообщение";
-App::$strings["Overview"] = "Обзор";
-App::$strings["Rating Tools"] = "Инструменты оценки";
-App::$strings["Rate Me"] = "Оценить меня";
-App::$strings["View Ratings"] = "Просмотр оценок";
-App::$strings["__ctx:widget__ Activity"] = "Активность";
-App::$strings["Show posts related to the %s privacy group"] = "Показывать публикации относящиеся к группе безопасности %s";
-App::$strings["Show my privacy groups"] = "Показывать мои группы безопасности";
-App::$strings["Show posts to this forum"] = "Показывать публикации этого форума";
-App::$strings["Show forums"] = "Показывать форумы";
-App::$strings["Starred Posts"] = "Отмеченные публикации";
-App::$strings["Show posts that I have starred"] = "Показывать публикации которые я отметил";
-App::$strings["Personal Posts"] = "Личные публикации";
-App::$strings["Show posts that mention or involve me"] = "Показывать публикации где вы были упомянуты или привлечены";
-App::$strings["Show posts that I have filed to %s"] = "Показывать публикации которые я добавил в %s";
-App::$strings["Saved Folders"] = "Сохранённые каталоги";
-App::$strings["Show filed post categories"] = "Показывать категории добавленных публикаций";
-App::$strings["Panel search"] = "Панель поиска";
-App::$strings["Filter by name"] = "Отфильтровать по имени";
-App::$strings["Remove active filter"] = "Удалить активный фильтр";
-App::$strings["Stream Filters"] = "Фильтры потока";
-App::$strings["You have %1$.0f of %2$.0f allowed connections."] = "У вас есть %1$.0f из %2$.0f разрешенных контактов.";
-App::$strings["Add New Connection"] = "Добавить новый контакт";
-App::$strings["Enter channel address"] = "Введите адрес канала";
-App::$strings["Examples: bob@example.com, https://example.com/barbara"] = "Пример: ivan@example.com, http://example.com/ivan";
-App::$strings["Archives"] = "Архивы";
-App::$strings["Received Messages"] = "Полученные сообщения";
-App::$strings["Sent Messages"] = "Отправленные сообщения";
-App::$strings["Conversations"] = "Беседы";
-App::$strings["No messages."] = "Сообщений нет.";
-App::$strings["Delete conversation"] = "Удалить беседу";
-App::$strings["Chat Members"] = "Участники чата";
-App::$strings["photo/image"] = "фотография / изображение";
-App::$strings["Remove term"] = "Удалить термин";
-App::$strings["Saved Searches"] = "Сохранённые поиски";
-App::$strings["Add new page"] = "Добавить новую страницу";
-App::$strings["Wiki Pages"] = "Wiki страницы";
-App::$strings["Page name"] = "Название страницы";
-App::$strings["Refresh"] = "Обновить";
-App::$strings["Tasks"] = "Задачи";
-App::$strings["Suggestions"] = "Рекомендации";
-App::$strings["See more..."] = "Просмотреть больше...";
-App::$strings["Commented Date"] = "По комментариям";
-App::$strings["Order by last commented date"] = "Сортировка по дате последнего комментария";
-App::$strings["Posted Date"] = "По публикациям";
-App::$strings["Order by last posted date"] = "Сортировка по дате последней публикации";
-App::$strings["Date Unthreaded"] = "По порядку";
-App::$strings["Order unthreaded by date"] = "Сортировка в порядке поступления";
-App::$strings["Stream Order"] = "Упорядочить поток";
-App::$strings["Click to show more"] = "Нажмите чтобы показать больше";
-App::$strings["Tags"] = "Теги";
-App::$strings["App Collections"] = "Коллекции приложений";
-App::$strings["Installed apps"] = "Установленные приложения";
-App::$strings["Profile Creation"] = "Создание профиля";
-App::$strings["Upload profile photo"] = "Загрузить фотографию профиля";
-App::$strings["Upload cover photo"] = "Загрузить фотографию обложки";
-App::$strings["Edit your profile"] = "Редактировать профиль";
-App::$strings["Find and Connect with others"] = "Найти и вступить в контакт";
-App::$strings["View the directory"] = "Просмотреть каталог";
-App::$strings["Manage your connections"] = "Управление вашими контактами";
-App::$strings["Communicate"] = "Связаться";
-App::$strings["View your channel homepage"] = "Домашняя страница канала";
-App::$strings["View your network stream"] = "Просмотреть ваш сетевой поток";
-App::$strings["Documentation"] = "Документация";
-App::$strings["Missing Features?"] = "Отсутствует функция?";
-App::$strings["Pin apps to navigation bar"] = "Прикрепить приложение к панели";
-App::$strings["Install more apps"] = "Установить больше приложений";
-App::$strings["View public stream"] = "Просмотреть публичный поток";
-App::$strings["Member registrations waiting for confirmation"] = "Регистрации участников, ожидающие подверждения";
-App::$strings["Inspect queue"] = "Просмотр очереди";
-App::$strings["DB updates"] = "Обновление базы данных";
-App::$strings["Admin"] = "Администрирование";
-App::$strings["Addon Features"] = "Настройки расширений";
-App::$strings["Account settings"] = "Настройки аккаунта";
-App::$strings["Channel settings"] = "Настройки канала";
-App::$strings["Display settings"] = "Настройки отображения";
-App::$strings["Manage locations"] = "Управление местоположением";
-App::$strings["Bookmarked Chatrooms"] = "Закладки чатов";
-App::$strings["New Network Activity"] = "Новая сетевая активность";
-App::$strings["New Network Activity Notifications"] = "Новые уведомления о сетевой активности";
-App::$strings["View your network activity"] = "Просмотреть вашу сетевую активность";
-App::$strings["Mark all notifications read"] = "Пометить уведомления как прочитанные";
-App::$strings["Show new posts only"] = "Показывать только новые публикации";
-App::$strings["Filter by name or address"] = "Фильтровать по имени или адресу";
-App::$strings["New Home Activity"] = "Новая локальная активность";
-App::$strings["New Home Activity Notifications"] = "Новые уведомления локальной активности";
-App::$strings["View your home activity"] = "Просмотреть локальную активность";
-App::$strings["Mark all notifications seen"] = "Пометить уведомления как просмотренные";
-App::$strings["New Mails"] = "Новая переписка";
-App::$strings["New Mails Notifications"] = "Уведомления о новой переписке";
-App::$strings["View your private mails"] = "Просмотреть вашу личную переписку";
-App::$strings["Mark all messages seen"] = "Пометить сообщения как просмотренные";
-App::$strings["New Events"] = "Новые события";
-App::$strings["New Events Notifications"] = "Уведомления о новых событиях";
-App::$strings["View events"] = "Просмотреть события";
-App::$strings["Mark all events seen"] = "Пометить все события как просмотренные";
-App::$strings["New Connections Notifications"] = "Уведомления о новых контактах";
-App::$strings["View all connections"] = "Просмотр всех контактов";
-App::$strings["New Files"] = "Новые файлы";
-App::$strings["New Files Notifications"] = "Уведомления о новых файлах";
-App::$strings["Notices"] = "Оповещения";
-App::$strings["View all notices"] = "Просмотреть все оповещения";
-App::$strings["Mark all notices seen"] = "Пометить все оповещения как просмотренные";
-App::$strings["New Registrations"] = "Новые регистрации";
-App::$strings["New Registrations Notifications"] = "Уведомления о новых регистрациях";
-App::$strings["Public Stream Notifications"] = "Уведомления публичного потока";
-App::$strings["View the public stream"] = "Просмотреть публичный поток";
-App::$strings["Sorry, you have got no notifications at the moment"] = "Извините, но сейчас у вас нет уведомлений";
-App::$strings["Source channel not found."] = "Канал-источник не найден.";
-App::$strings["Network/Protocol"] = "Сеть / протокол";
-App::$strings["Zot"] = "";
-App::$strings["Diaspora"] = "";
-App::$strings["Friendica"] = "";
-App::$strings["OStatus"] = "";
-App::$strings["Create an account to access services and applications"] = "Создайте аккаунт для доступа к службам и приложениям";
-App::$strings["Logout"] = "Выход";
-App::$strings["Login/Email"] = "Пользователь / email";
-App::$strings["Password"] = "Пароль";
-App::$strings["Remember me"] = "Запомнить меня";
-App::$strings["Forgot your password?"] = "Забыли пароль или логин?";
-App::$strings["[\$Projectname] Website SSL error for %s"] = "[\$Projectname] Ошибка SSL/TLS веб-сайта для %s";
-App::$strings["Website SSL certificate is not valid. Please correct."] = "SSL/TLS сертификат веб-сайт недействителен. Исправьте это.";
-App::$strings["[\$Projectname] Cron tasks not running on %s"] = "[\$Projectname] Задания Cron не запущены на %s";
-App::$strings["Cron/Scheduled tasks not running."] = "Задания Cron / планировщика не запущены.";
-App::$strings["never"] = "никогда";
-App::$strings["Focus (Hubzilla default)"] = "Фокус (по умолчанию Hubzilla)";
-App::$strings["Theme settings"] = "Настройки темы";
-App::$strings["Narrow navbar"] = "Узкая панель навигации";
-App::$strings["Navigation bar background color"] = "Панель навигации, цвет фона";
-App::$strings["Navigation bar icon color "] = "Панель навигации, цвет значков";
-App::$strings["Navigation bar active icon color "] = "Панель навигации, цвет активного значка";
-App::$strings["Link color"] = "Цвет ссылок";
-App::$strings["Set font-color for banner"] = "Цвет текста в шапке";
-App::$strings["Set the background color"] = "Цвет фона";
-App::$strings["Set the background image"] = "Фоновое изображение";
-App::$strings["Set the background color of items"] = "Цвет фона элементов";
-App::$strings["Set the background color of comments"] = "Цвет фона комментариев";
-App::$strings["Set font-size for the entire application"] = "Установить системный размер шрифта";
-App::$strings["Examples: 1rem, 100%, 16px"] = "Например: 1rem, 100%, 16px";
-App::$strings["Set font-color for posts and comments"] = "Цвет шрифта для публикаций и комментариев";
-App::$strings["Set radius of corners"] = "Радиус скруглений";
-App::$strings["Example: 4px"] = "Например: 4px";
-App::$strings["Set shadow depth of photos"] = "Глубина теней фотографий";
-App::$strings["Set maximum width of content region in pixel"] = "Максимальная ширина содержания региона (в пикселях)";
-App::$strings["Leave empty for default width"] = "Оставьте пустым для ширины по умолчанию";
-App::$strings["Left align page content"] = "Выровнять содержимое страницы по левому краю";
-App::$strings["Set size of conversation author photo"] = "Размер фотографии автора беседы";
-App::$strings["Set size of followup author photos"] = "Размер фотографий подписчиков";
-App::$strings["Show advanced settings"] = "Показать расширенные настройки";
-App::$strings["Errors encountered deleting database table "] = "Возникшие при удалении таблицы базы данных ошибки";
+App::$strings["Missing room name"] = "Отсутствует название комнаты";
+App::$strings["Duplicate room name"] = "Название комнаты дублируется";
+App::$strings["Invalid room specifier."] = "Неверный указатель комнаты.";
+App::$strings["Room not found."] = "Комната не найдена.";
+App::$strings["Room is full"] = "Комната переполнена";
+App::$strings["Public"] = "Общедоступно";
+App::$strings["Anybody in the \$Projectname network"] = "Любому в сети \$Projectname";
+App::$strings["Any account on %s"] = "Любой аккаунт в %s";
+App::$strings["Any of my connections"] = "Любой из моих контактов";
+App::$strings["Only connections I specifically allow"] = "Только те контакты, кому я дам разрешение";
+App::$strings["Anybody authenticated (could include visitors from other networks)"] = "Любой аутентифицированный (может включать посетителей их других сетей)";
+App::$strings["Any connections including those who haven't yet been approved"] = "Любые контакты включая те, которые вы ещё не одобрили";
+App::$strings["This is your default setting for the audience of your normal stream, and posts."] = "Это настройка по умолчанию для аудитории ваших обычных потоков и публикаций";
+App::$strings["This is your default setting for who can view your default channel profile"] = "Это настройка по умолчанию для тех, кто может просматривать профиль вашего основного канала";
+App::$strings["This is your default setting for who can view your connections"] = "Это настройка по умолчанию для тех, кто может просматривать ваши контакты";
+App::$strings["This is your default setting for who can view your file storage and photos"] = "Это настройка по умолчанию для тех, кто может просматривать ваше хранилище файлов и фотографий";
+App::$strings["This is your default setting for the audience of your webpages"] = "Это настройка по умолчанию для аудитории ваших веб-страниц";
+App::$strings["Likes %1\$s's %2\$s"] = "Нравится %1\$s %2\$s";
+App::$strings["Doesn't like %1\$s's %2\$s"] = "Не нравится %1\$s %2\$s";
+App::$strings["Will attend %1\$s's %2\$s"] = "Примет участие %1\$s %2\$s";
+App::$strings["Will not attend %1\$s's %2\$s"] = "Не примет участие %1\$s %2\$s";
+App::$strings["May attend %1\$s's %2\$s"] = "Возможно примет участие %1\$s %2\$s";
+App::$strings["0. Beginner/Basic"] = "Начинающий / Базовый";
+App::$strings["1. Novice - not skilled but willing to learn"] = "1. Новичок - не опытный, но желающий учиться";
+App::$strings["2. Intermediate - somewhat comfortable"] = "2. Промежуточный - более удобный";
+App::$strings["3. Advanced - very comfortable"] = "3. Продвинутый - очень удобный";
+App::$strings["4. Expert - I can write computer code"] = "4. Эксперт - я умею программировать";
+App::$strings["5. Wizard - I probably know more than you do"] = "5. Волшебник - возможно я знаю больше чем ты";
+App::$strings["Wiki updated successfully"] = "Wiki успешно обновлена";
+App::$strings["Wiki files deleted successfully"] = "Wiki успешно удалена";
+App::$strings["Use markdown for editing posts"] = "Использовать язык разметки Markdown для редактирования публикаций";
+App::$strings["Post to Dreamwidth"] = "Публиковать в Dreamwidth";
+App::$strings["Dreamwidth Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Dreamwidth сохранены.";
+App::$strings["Dreamwidth Crosspost Connector App"] = "Приложение \"Публикация в Dreamwidth\"";
+App::$strings["Relay public postings to Dreamwidth"] = "Пересылает общедоступные публикации в Dreamwidth";
+App::$strings["Dreamwidth username"] = "Имя пользователя Dreamwidth";
+App::$strings["Dreamwidth password"] = "Пароль Dreamwidth";
+App::$strings["Post to Dreamwidth by default"] = "Публиковать в Dreamwidth по умолчанию";
+App::$strings["Dreamwidth Crosspost Connector"] = "Публикация в Dreamwidth";
+App::$strings["Project Servers and Resources"] = "Серверы и ресурсы проекта";
+App::$strings["Project Creator and Tech Lead"] = "Создатель проекта и технический руководитель";
+App::$strings["And the hundreds of other people and organisations who helped make the Hubzilla possible."] = "И сотни других людей и организаций которые помогали в создании Hubzilla.";
+App::$strings["The Redmatrix/Hubzilla projects are provided primarily by volunteers giving their time and expertise - and often paying out of pocket for services they share with others."] = "Проекты Redmatrix / Hubzilla предоставляются, в основном, добровольцами, которые предоставляют свое время и опыт и, часто, оплачивают из своего кармана услуги, которыми они делятся с другими.";
+App::$strings["There is no corporate funding and no ads, and we do not collect and sell your personal information. (We don't control your personal information - <strong>you do</strong>.)"] = "Здесь нет корпоративного финансирования и рекламы, мы не собираем и не продаем вашу личную информацию. (Мы не контролируем вашу личную информацию - <strong>это делаете вы</strong>.)";
+App::$strings["Help support our ground-breaking work in decentralisation, web identity, and privacy."] = "Помогите поддержать нашу новаторскую работу в областях децентрализации, веб-идентификации и конфиденциальности.";
+App::$strings["Your donations keep servers and services running and also helps us to provide innovative new features and continued development."] = "В ваших пожертвованиях поддерживают серверы и службы, а также помогают нам предоставлять новые возможности и продолжать развитие.";
+App::$strings["Donate"] = "Пожертвовать";
+App::$strings["Choose a project, developer, or public hub to support with a one-time donation"] = "Выберите проект, разработчика или общедоступный узел для поддержки в форме единоразового пожертвования";
+App::$strings["Donate Now"] = "Пожертвовать сейчас";
+App::$strings["<strong><em>Or</em></strong> become a project sponsor (Hubzilla Project only)"] = "<strong><em>или</em></strong> станьте спонсором проекта (только для Hubzilla)";
+App::$strings["Please indicate if you would like your first name or full name (or nothing) to appear in our sponsor listing"] = "Пожалуйста, если желаете, укажите ваше имя для отображения в списке спонсоров.";
+App::$strings["Sponsor"] = "Спонсор";
+App::$strings["Special thanks to: "] = "Особые благодарности:";
+App::$strings["Fuzzloc Settings updated."] = "Настройки примерного положения обновлены.";
+App::$strings["Fuzzy Location App"] = "Приложение \"Примерное положение\"";
+App::$strings["Blur your precise location if your channel uses browser location mapping"] = "Размывает вашего точное местоположение в случае если ваш канал использует отображение местоположения из браузера";
+App::$strings["Minimum offset in meters"] = "Минимальное смещение в метрах";
+App::$strings["Maximum offset in meters"] = "Максимальное смещение в метрах";
+App::$strings["Fuzzy Location"] = "Примерное положение";
+App::$strings["Allow magic authentication only to websites of your immediate connections"] = "Разрешить волшебную аутентификацию только на сайтах ваших непосредственных соединений";
+App::$strings["Authchoose App"] = "Приложение Authchoose";
+App::$strings["Installed"] = "Установлено";
+App::$strings["Authchoose"] = "";
+App::$strings["Photos imported"] = "Фотографии импортированы";
+App::$strings["Redmatrix Photo Album Import"] = "Импортировать альбом фотографий Redmatrix";
+App::$strings["This will import all your Redmatrix photo albums to this channel."] = "Это позволит импортировать все ваши альбомы фотографий Redmatrix в этот канал.";
+App::$strings["Redmatrix Server base URL"] = "Базовый URL сервера Redmatrix";
+App::$strings["Redmatrix Login Username"] = "Имя пользователя Redmatrix";
+App::$strings["Redmatrix Login Password"] = "Пароль Redmatrix";
+App::$strings["Import just this album"] = "Импортировать только этот альбом";
+App::$strings["Leave blank to import all albums"] = "Оставьте пустым для импорта всех альбомов";
+App::$strings["Maximum count to import"] = "Максимальное количество для импорта";
+App::$strings["0 or blank to import all available"] = "0 или пусто для импорта всех доступных";
+App::$strings["Gallery App"] = "Приложение \"Галерея\"";
+App::$strings["A simple gallery for your photo albums"] = "Простая галлерея для ваших фотоальбомов";
+App::$strings["Gallery"] = "Галерея";
+App::$strings["Photo Gallery"] = "Фотогалерея";
+App::$strings["Friendica Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Friendica сохранены.";
+App::$strings["Friendica Crosspost Connector App"] = "Приложение \"Публикация в Friendica\"";
+App::$strings["Relay public postings to a connected Friendica account"] = "Пересылает общедоступные публикации на подключённую учётную запись Friendica";
+App::$strings["Send public postings to Friendica by default"] = "Отправлять общедоступные публикации во Friendica по умолчанию";
+App::$strings["Friendica API Path"] = "Путь к Friendica API";
+App::$strings["https://{sitename}/api"] = "";
+App::$strings["Friendica login name"] = "Имя входа Friendica";
+App::$strings["Friendica password"] = "Пароль Friendica";
+App::$strings["Friendica Crosspost Connector"] = "Публикация в Friendica";
+App::$strings["Post to Friendica"] = "Опубликовать в Friendica";
+App::$strings["An account has been created for you."] = "Учётная запись, которая была для вас создана.";
+App::$strings["Authentication successful but rejected: account creation is disabled."] = "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено.";
+App::$strings["Post to Insane Journal"] = "Опубликовать в Insane Journal";
+App::$strings["Insane Journal Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Insane Journal сохранены.";
+App::$strings["Insane Journal Crosspost Connector App"] = "Приложение \"Публикация в Insane Journal\"";
+App::$strings["Relay public postings to Insane Journal"] = "Пересылает общедоступные публикации в Insane Journal";
+App::$strings["InsaneJournal username"] = "Имя пользователя Insane Journal";
+App::$strings["InsaneJournal password"] = "Пароль Insane Journal";
+App::$strings["Post to InsaneJournal by default"] = "Публиковать в Insane Journal по умолчанию";
+App::$strings["Insane Journal Crosspost Connector"] = "Публикация в Insane Journal";
+App::$strings["Your account on %s will expire in a few days."] = "Ваш аккаунт на %s перестанет работать через несколько дней.";
+App::$strings["Your $Productname test account is about to expire."] = "Ваш тестовый аккаунт в $Productname близок к окончанию срока действия.";
+App::$strings["Redmatrix File Storage Import"] = "Импорт файлового хранилища Redmatrix";
+App::$strings["This will import all your Redmatrix cloud files to this channel."] = "Это позволит импортировать все ваши файлы в Redmatrix в этот канал.";
+App::$strings["file"] = "файл";
+App::$strings["Post to Twitter"] = "Опубликовать в Twitter";
App::$strings["Submit Settings"] = "Отправить настройки";
+App::$strings["Twitter settings updated."] = "Настройки Twitter обновлены";
+App::$strings["Twitter Crosspost Connector App"] = "Приложение \"Публикация в Twitter\"";
+App::$strings["Relay public posts to Twitter"] = "Пересылает общедоступные публикации в Twitter";
+App::$strings["No consumer key pair for Twitter found. Please contact your site administrator."] = "Не найдено пары ключей для Twitter. Пожалуйста, свяжитесь с администратором сайта.";
+App::$strings["At this Hubzilla instance the Twitter plugin was enabled but you have not yet connected your account to your Twitter account. To do so click the button below to get a PIN from Twitter which you have to copy into the input box below and submit the form. Only your <strong>public</strong> posts will be posted to Twitter."] = "В этой установке Hubzilla плагин Twitter был включён, однако пока он не подключён к вашему аккаунту в Twitter. Для этого нажмите на кнопку ниже для получения PIN-кода от Twitter который нужно скопировать в поле ввода и отправить форму. Только ваши <strong>общедоступные</strong> публикации будут опубликованы в Twitter.";
+App::$strings["Log in with Twitter"] = "Войти в Twitter";
+App::$strings["Copy the PIN from Twitter here"] = "Скопируйте PIN-код из Twitter здесь";
+App::$strings["Currently connected to: "] = "В настоящее время подключён к:";
+App::$strings["<strong>Note:</strong> Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to Twitter will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в Twitter, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен.";
+App::$strings["Twitter post length"] = "Длина публикации Twitter";
+App::$strings["Maximum tweet length"] = "Максимальная длина твита";
+App::$strings["Send public postings to Twitter by default"] = "Отправлять общедоступные публикации в Twitter по умолчанию";
+App::$strings["If enabled your public postings will be posted to the associated Twitter account by default"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи Twitter по умолчанию";
+App::$strings["Clear OAuth configuration"] = "Очистить конфигурацию OAuth";
+App::$strings["Twitter Crosspost Connector"] = "Публикация в Twitter";
+App::$strings["Edit your profile and change settings."] = "Отредактировать ваш профиль и изменить настройки.";
+App::$strings["Click here to see activity from your connections."] = "Нажмите сюда для отображения активности ваши контактов.";
+App::$strings["Click here to see your channel home."] = "Нажмите сюда чтобы увидеть главную страницу вашего канала.";
+App::$strings["You can access your private messages from here."] = "Вы можете получить доступ с личной переписке здесь.";
+App::$strings["Create new events here."] = "Создать новое событие здесь.";
+App::$strings["You can accept new connections and change permissions for existing ones here. You can also e.g. create groups of contacts."] = "Вы можете подключать новые контакты и менять разрешения для существующих здесь. Также вы можете создавать их группы.";
+App::$strings["System notifications will arrive here"] = "Системные оповещения будут показываться здесь";
+App::$strings["Search for content and users"] = "Поиск пользователей и содержимого";
+App::$strings["Browse for new contacts"] = "Поиск новых контактов";
+App::$strings["Launch installed apps"] = "Запустить установленные приложения";
+App::$strings["Looking for help? Click here."] = "Нужна помощь? Нажмите сюда.";
+App::$strings["New events have occurred in your network. Click here to see what has happened!"] = "Новые события произошли в вашей сети. Нажмите здесь для того, чтобы знать что случилось!";
+App::$strings["You have received a new private message. Click here to see from who!"] = "Вы получили новое личное сообщение. Нажмите чтобы увидеть от кого!";
+App::$strings["There are events this week. Click here too see which!"] = "На этой неделе есть события. Нажмите здесь чтобы увидеть какие!";
+App::$strings["You have received a new introduction. Click here to see who!"] = "Вы были представлены. Нажмите чтобы увидеть кому!";
+App::$strings["There is a new system notification. Click here to see what has happened!"] = "Это новое системное уведомление. Нажмите чтобы посмотреть что случилось!";
+App::$strings["Click here to share text, images, videos and sound."] = "Нажмите сюда чтобы поделиться текстом, изображениями, видео или треком.";
+App::$strings["You can write an optional title for your update (good for long posts)."] = "Вы можете написать необязательный заголовок для вашей публикации (желательно для больших публикаций).";
+App::$strings["Entering some categories here makes it easier to find your post later."] = "Введите категории здесь чтобы было проще найти вашу публикацию позднее.";
+App::$strings["Share photos, links, location, etc."] = "Поделиться фотографией, ссылками, местоположение и т.п.";
+App::$strings["Only want to share content for a while? Make it expire at a certain date."] = "Хотите только поделиться временным содержимым? Установите срок его действия.";
+App::$strings["You can password protect content."] = "Вы можете защитить содержимое паролем.";
+App::$strings["Choose who you share with."] = "Выбрать с кем поделиться.";
+App::$strings["Click here when you are done."] = "Нажмите здесь когда закончите.";
+App::$strings["Adjust from which channels posts should be displayed."] = "Настройте из каких каналов должны отображаться публикации.";
+App::$strings["Only show posts from channels in the specified privacy group."] = "Показывать только публикации из определённой группы безопасности.";
+App::$strings["Easily find posts containing tags (keywords preceded by the \"#\" symbol)."] = "Лёгкий поиск сообщения, содержащего теги (ключевые слова, которым предшествует символ #).";
+App::$strings["Easily find posts in given category."] = "Лёгкий поиск публикаций в данной категории.";
+App::$strings["Easily find posts by date."] = "Лёгкий поиск публикаций по дате.";
+App::$strings["Suggested users who have volounteered to be shown as suggestions, and who we think you might find interesting."] = "Рекомендуемые пользователи, которые были представлены в качестве предложений, и которые, по нашему мнению, могут оказаться интересными.";
+App::$strings["Here you see channels you have connected to."] = "Здесь вы видите каналы, к которым вы подключились.";
+App::$strings["Save your search so you can repeat it at a later date."] = "Сохраните ваш поиск с тем, чтобы повторить его позже.";
+App::$strings["If you see this icon you can be sure that the sender is who it say it is. It is normal that it is not always possible to verify the sender, so the icon will be missing sometimes. There is usually no need to worry about that."] = "Если вы видите этот значок, вы можете быть уверены, что отправитель - это тот, кто это говорит. Это нормально, что не всегда можно проверить отправителя, поэтому значок иногда будет отсутствовать. Обычно об этом не нужно беспокоиться.";
+App::$strings["Danger! It seems someone tried to forge a message! This message is not necessarily from who it says it is from!"] = "Опасность! Кажется, кто-то пытался подделать сообщение! Это сообщение не обязательно от того, от кого оно значится!";
+App::$strings["Welcome to Hubzilla! Would you like to see a tour of the UI?</p> <p>You can pause it at any time and continue where you left off by reloading the page, or navigting to another page.</p><p>You can also advance by pressing the return key"] = "Добро пожаловать в Hubzilla! Желаете получить обзор пользовательского интерфейса?</p> <p>Вы можете его приостановаить и в любое время перезагрузив страницу или перейдя на другую.</p><p>Также вы можете нажать клавишу \"Назад\"";
+App::$strings["Block Completely"] = "Заблокировать полностью";
+App::$strings["Superblock App"] = "Приложение Superblock";
+App::$strings["Block channels"] = "Заблокировать каналы";
+App::$strings["superblock settings updated"] = "Настройки Superblock обновлены.";
+App::$strings["Currently blocked"] = "В настоящее время заблокирован";
+App::$strings["No channels currently blocked"] = "В настоящее время никакие каналы не блокируются";
+App::$strings["bitchslap"] = "дал леща";
+App::$strings["bitchslapped"] = "получил леща";
+App::$strings["shag"] = "вздрючил";
+App::$strings["shagged"] = "вздрюченный";
+App::$strings["patent"] = "";
+App::$strings["patented"] = "";
+App::$strings["hug"] = "обнял";
+App::$strings["hugged"] = "обнятый";
+App::$strings["murder"] = "убил";
+App::$strings["murdered"] = "убитый";
+App::$strings["worship"] = "почитает";
+App::$strings["worshipped"] = "почитаемый";
+App::$strings["kiss"] = "поцеловал";
+App::$strings["kissed"] = "поцелованный";
+App::$strings["tempt"] = "искушает";
+App::$strings["tempted"] = "искушённый";
+App::$strings["raise eyebrows at"] = "поднял брови";
+App::$strings["raised their eyebrows at"] = "поднял брови";
+App::$strings["insult"] = "оскорбил";
+App::$strings["insulted"] = "оскорблённый";
+App::$strings["praise"] = "похвалил";
+App::$strings["praised"] = "похваленный";
+App::$strings["be dubious of"] = "сомневается";
+App::$strings["was dubious of"] = "усомнился";
+App::$strings["eat"] = "ест";
+App::$strings["ate"] = "съел";
+App::$strings["giggle and fawn at"] = "";
+App::$strings["giggled and fawned at"] = "";
+App::$strings["doubt"] = "сомневается";
+App::$strings["doubted"] = "усомнился";
+App::$strings["glare"] = "";
+App::$strings["glared at"] = "";
+App::$strings["fuck"] = "трахает";
+App::$strings["fucked"] = "трахнул";
+App::$strings["bonk"] = "";
+App::$strings["bonked"] = "";
+App::$strings["declare undying love for"] = "признаётся в любви к";
+App::$strings["declared undying love for"] = "признался в любви к";
+App::$strings["Logfile archive directory"] = "Каталог архивирования журнала";
+App::$strings["Directory to store rotated logs"] = "Каталог для хранения заархивированных журналов";
+App::$strings["Logfile size in bytes before rotating"] = "Размер файла журнала в байтах для архивирования";
+App::$strings["Number of logfiles to retain"] = "Количество сохраняемых файлов журналов";
+App::$strings["Your Webbie:"] = "Ваш Webbie:";
+App::$strings["Fontsize (px):"] = "Размер шрифта (px):";
+App::$strings["Link:"] = "Ссылка:";
+App::$strings["Like us on Hubzilla"] = "Нравится на Hubzilla";
+App::$strings["Embed:"] = "Встроить:";
+App::$strings["QR code"] = "QR-код";
+App::$strings["QR Generator"] = "Генератор QR-кодов";
+App::$strings["Enter some text"] = "Введите любой текст";
+App::$strings["View Larger"] = "Увеличить";
+App::$strings["Tile Server URL"] = "URL сервера Tile";
+App::$strings["A list of <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">public tile servers</a>"] = "Список <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">общедоступных серверов</a>";
+App::$strings["Nominatim (reverse geocoding) Server URL"] = "URL сервера Nominatim (обратное геокодирование)";
+App::$strings["A list of <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">Nominatim servers</a>"] = "Список <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">серверов Nominatim</a>";
+App::$strings["Default zoom"] = "Масштаб по умолчанию";
+App::$strings["The default zoom level. (1:world, 18:highest, also depends on tile server)"] = "Уровень размера по умолчанию (1 - весь мир, 18 - максимальный; зависит от сервера).";
+App::$strings["Include marker on map"] = "Включите маркер на карте";
+App::$strings["Include a marker on the map."] = "Включить маркер на карте";
+App::$strings["Photo Cache settings saved."] = "Настройки кэширования изображений сохранены.";
+App::$strings["Photo Cache addon saves a copy of images from external sites locally to increase your anonymity in the web."] = "Приложение \"Кэшировние изображений\" сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет.";
+App::$strings["Photo Cache App"] = "Приложение \"Кэширование изображений\"";
+App::$strings["Minimal photo size for caching"] = "Минимальный размер изображений для кэширования";
+App::$strings["In pixels. From 1 up to 1024, 0 will be replaced with system default."] = "В пикселях. От 1 до 1024, 0 будет заменён значением по умолчанию.";
+App::$strings["Photo Cache"] = "Кэширование изображений";
+App::$strings["Jappixmini App"] = "Приложение Jappix Mini";
+App::$strings["Provides a Facebook-like chat using Jappix Mini"] = "Предоставляет Facebook-подобный чат с использованием Jappix Mini";
+App::$strings["Hide Jappixmini Chat-Widget from the webinterface"] = "Скрыть виджет чата Jappix Mini из веб-интерфейса";
+App::$strings["Jabber username"] = "Имя пользователя Jabber";
+App::$strings["Jabber server"] = "Сервер Jabber";
+App::$strings["Jabber BOSH host URL"] = "URL узла Jabber BOSH";
+App::$strings["Jabber password"] = "Пароль Jabber";
+App::$strings["Encrypt Jabber password with Hubzilla password"] = "Зашифровать пароль Jabber с помощью пароля Hubzilla";
+App::$strings["Hubzilla password"] = "Пароль Hubzilla";
+App::$strings["Approve subscription requests from Hubzilla contacts automatically"] = "Утверждать запросы на подписку от контактов Hubzilla автоматически";
+App::$strings["Purge internal list of jabber addresses of contacts"] = "Очистить внутренний список адресов контактов Jabber";
+App::$strings["Configuration Help"] = "Помощь по конфигурации";
+App::$strings["Jappixmini Settings"] = "Настройки Jappix Мini";
+App::$strings["Errors encountered deleting database table "] = "Возникшие при удалении таблицы базы данных ошибки";
App::$strings["Drop tables when uninstalling?"] = "Удалить таблицы при деинсталляции?";
App::$strings["If checked, the Rendezvous database tables will be deleted when the plugin is uninstalled."] = "Если включено, то таблицы базы данных Rendezvous будут удалены при удалении плагина.";
App::$strings["Mapbox Access Token"] = "Токен доступа к Mapbox";
@@ -2202,19 +3059,43 @@ App::$strings["Enter a note to be displayed when you are within the specified pr
App::$strings["Add new rendezvous"] = "Добавить новое Rendezvous.";
App::$strings["Create a new rendezvous and share the access link with those you wish to invite to the group. Those who open the link become members of the rendezvous. They can view other member locations, add markers to the map, or share their own locations with the group."] = "Создайте новое Rendezvous и поделитесь ссылкой доступа с теми, кого вы хотите пригласить в группу. Тот, кто откроет эту ссылку, станет её участником. Участники могут видеть местоположение, добавлять маркеры на карту или делится своим собственным местоположением с группой.";
App::$strings["You have no rendezvous. Press the button above to create a rendezvous!"] = "У вас нет Rendezvous. Нажмите на кнопку ниже чтобы создать его!";
-App::$strings["Skeleton App"] = "Приложение \"Скелет\"";
-App::$strings["A skeleton for addons, you can copy/paste"] = "Скелет для приложений. Вы можете использовать copy/paste";
-App::$strings["Some setting"] = "Некоторые настройки";
-App::$strings["A setting"] = "Настройка";
-App::$strings["Skeleton Settings"] = "Настройки скелета";
-App::$strings["The GNU-Social protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол GNU-Social не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
-App::$strings["GNU-Social Protocol App"] = "Приложение \"Протокол GNU-Social\"";
-App::$strings["GNU-Social Protocol"] = "Протокол GNU-Social";
-App::$strings["Follow"] = "Отслеживать";
-App::$strings["%1\$s is now following %2\$s"] = "%1\$s сейчас отслеживает %2\$s";
-App::$strings["Random Planet App"] = "Приложение \"Случайная планета\"";
-App::$strings["Installed"] = "Установлено";
-App::$strings["Set a random planet from the Star Wars Empire as your location when posting"] = "Установить случайную планету из Империи Звездных Войн в качестве вашего местоположения при публикации";
+App::$strings["This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> analytics tool."] = "Этот сайт отслеживается с помощью инструментов аналитики <a href='http://www.piwik.org'>Piwik</a>.";
+App::$strings["If you do not want that your visits are logged this way you <a href='%s'>can set a cookie to prevent Piwik from tracking further visits of the site</a> (opt-out)."] = "Если вы не хотите, чтобы ваши визиты регистрировались таким образом, вы <a href='%s'>можете отключить cookie с тем, чтобы Piwik не отслеживал дальнейшие посещения сайта</a>.";
+App::$strings["Piwik Base URL"] = "Базовый URL Piwik";
+App::$strings["Absolute path to your Piwik installation. (without protocol (http/s), with trailing slash)"] = "Абсолютный путь к вашей установке Piwik (без типа протокола, с начальным слэшем)";
+App::$strings["Site ID"] = "ID сайта";
+App::$strings["Show opt-out cookie link?"] = "Показывать ссылку на отказ от использования cookies?";
+App::$strings["Asynchronous tracking"] = "Асинхронное отслеживание";
+App::$strings["Enable frontend JavaScript error tracking"] = "Включить отслеживание ошибок JavaScript на фронтенде.";
+App::$strings["This feature requires Piwik >= 2.2.0"] = "Эта функция требует версию Piwik >= 2.2.0";
+App::$strings["Pump.io Settings saved."] = "Настройки Pump.io сохранены.";
+App::$strings["Pump.io Crosspost Connector App"] = "Приложение \"Публикация в Pump.io\"";
+App::$strings["Relay public posts to pump.io"] = "Пересылает общедоступные публикации в Pump.io";
+App::$strings["Pump.io servername"] = "Имя сервера Pump.io";
+App::$strings["Without \"http://\" or \"https://\""] = "Без \"http://\" или \"https://\"";
+App::$strings["Pump.io username"] = "Имя пользователя Pump.io";
+App::$strings["Without the servername"] = "без имени сервера";
+App::$strings["You are not authenticated to pumpio"] = "Вы не аутентифицированы на Pump.io";
+App::$strings["(Re-)Authenticate your pump.io connection"] = "Аутентифицировать (повторно) ваше соединение с Pump.io";
+App::$strings["Post to pump.io by default"] = "Публиковать в Pump.io по умолчанию";
+App::$strings["Should posts be public"] = "Публикации должны быть общедоступными";
+App::$strings["Mirror all public posts"] = "Отображать все общедоступные публикации";
+App::$strings["Pump.io Crosspost Connector"] = "Публикация в Pump.io";
+App::$strings["You are now authenticated to pumpio."] = "Вы аутентифицированы в Pump.io";
+App::$strings["return to the featured settings page"] = "Вернутся к странице настроек";
+App::$strings["Post to Pump.io"] = "Опубликовать в Pump.io";
+App::$strings["NSA Bait App"] = "Приложение NSA Bait";
+App::$strings["Make yourself a political target"] = "Сделать себя политической мишенью";
+App::$strings["Send test email"] = "Отправить тестовый email";
+App::$strings["No recipients found."] = "Получателей не найдено.";
+App::$strings["Mail sent."] = "Сообщение отправлено";
+App::$strings["Sending of mail failed."] = "Не удалось отправить сообщение.";
+App::$strings["Mail Test"] = "Тестовое сообщение";
+App::$strings["Message subject"] = "Тема сообщения";
+App::$strings["You're welcome."] = "Пожалуйста.";
+App::$strings["Ah shucks..."] = "О, чёрт...";
+App::$strings["Don't mention it."] = "Не стоит благодарности.";
+App::$strings["&lt;blush&gt;"] = "&lt;краснею&gt;";
App::$strings["System defaults:"] = "Системные по умолчанию:";
App::$strings["Preferred Clipart IDs"] = "Предпочитаемый Clipart ID";
App::$strings["List of preferred clipart ids. These will be shown first."] = "Список предпочитаемых Clipart ID. Эти будут показаны первыми.";
@@ -2222,7 +3103,6 @@ App::$strings["Default Search Term"] = "Условие поиска по умо
App::$strings["The default search term. These will be shown second."] = "Условие поиска по умолчанию. Показываются во вторую очередь.";
App::$strings["Return After"] = "Вернуться после";
App::$strings["Page to load after image selection."] = "Страница для загрузки после выбора изображения.";
-App::$strings["Edit Profile"] = "Редактировать профиль";
App::$strings["Profile List"] = "Список профилей";
App::$strings["Order of Preferred"] = "Порядок предпочтения";
App::$strings["Sort order of preferred clipart ids."] = "Порядок сортировки предпочитаемых Clipart ID. ";
@@ -2241,118 +3121,61 @@ App::$strings["Or select from a free OpenClipart.org image:"] = "Или выбе
App::$strings["Search Term"] = "Условие поиска";
App::$strings["Unknown error. Please try again later."] = "Неизвестная ошибка. Пожалуйста, повторите попытку позже.";
App::$strings["Profile photo updated successfully."] = "Фотография профиля обновлена успешно.";
-App::$strings["Flag Adult Photos"] = "Пометка фотографий для взрослых";
-App::$strings["Provide photo edit option to hide inappropriate photos from default album view"] = "Предоставьте возможность редактирования фотографий, чтобы скрыть неприемлемые фотографии из альбома по умолчанию";
-App::$strings["You haven't set a TOTP secret yet.\nPlease click the button below to generate one and register this site\nwith your preferred authenticator app."] = "Вы еще не установили секретный код TOTP. Пожалуйста, нажмите на кнопку ниже, чтобы сгенерировать его и зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации.";
-App::$strings["Your TOTP secret is"] = "Ваш секретный код TOTP";
-App::$strings["Be sure to save it somewhere in case you lose or replace your mobile device.\nUse your mobile device to scan the QR code below to register this site\nwith your preferred authenticator app."] = "Обязательно сохраните его где-нибудь на случай потери или замены мобильного устройства. С помощью мобильного устройства отсканируйте приведенный ниже QR-код, чтобы зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации.";
-App::$strings["Test"] = "Тест";
-App::$strings["Generate New Secret"] = "Сгенерировать новый секретный код";
-App::$strings["Go"] = "Вперёд";
-App::$strings["Enter your password"] = "Введите ваш пароль";
-App::$strings["enter TOTP code from your device"] = "введите код TOTP из вашего устройства";
-App::$strings["Pass!"] = "Принято!";
-App::$strings["Fail"] = "Отказано";
-App::$strings["Incorrect password, try again."] = "Неверный пароль, попробуйте снова.";
-App::$strings["Record your new TOTP secret and rescan the QR code above."] = "Запишите ваш секретный код TOTP и повторно отсканируйте приведенный ниже QR-код.";
-App::$strings["TOTP Settings"] = "Настройки TOTP";
-App::$strings["TOTP Two-Step Verification"] = "Двухэтапная верификация TOTP";
-App::$strings["Enter the 2-step verification generated by your authenticator app:"] = "Введите код проверки, созданный вашим приложением для аутентификации";
-App::$strings["Success!"] = "Успех!";
-App::$strings["Invalid code, please try again."] = "Неверный код. Пожалуйста, попробуйте ещё раз.";
-App::$strings["Too many invalid codes..."] = "Слишком много неверных кодов...";
-App::$strings["Verify"] = "Проверить";
-App::$strings["Wordpress Settings saved."] = "Настройки WordPress сохранены.";
-App::$strings["Wordpress Post App"] = "Приложение \"Публикация в Wordpress\"";
-App::$strings["Post to WordPress or anything else which uses the wordpress XMLRPC API"] = "Опубликовать в WordPress или в чём-то ещё, поддерживающем wordpress XMLRPC API";
-App::$strings["WordPress username"] = "Имя пользователя WordPress";
-App::$strings["WordPress password"] = "Пароль WordPress";
-App::$strings["WordPress API URL"] = "URL API WordPress";
-App::$strings["Typically https://your-blog.tld/xmlrpc.php"] = "Обычно https://your-blog.tld/xmlrpc.php";
-App::$strings["WordPress blogid"] = "";
-App::$strings["For multi-user sites such as wordpress.com, otherwise leave blank"] = "Для многопользовательских сайтов, таких, как wordpress.com. В противном случае оставьте пустым";
-App::$strings["Post to WordPress by default"] = "Публиковать в WordPress по умолчанию";
-App::$strings["Forward comments (requires hubzilla_wp plugin)"] = "Пересылать комментарии (требуется плагин hubzilla_wp)";
-App::$strings["Wordpress Post"] = "Публикация в WordPress";
-App::$strings["Post to WordPress"] = "Опубликовать в WordPress";
-App::$strings["Possible adult content"] = "Возможно содержимое для взрослых";
-App::$strings["%s - view"] = "%s - просмотр";
-App::$strings["NSFW Settings saved."] = "Настройки NSFW сохранены.";
-App::$strings["NSFW App"] = "Приложение NSFW";
-App::$strings["Collapse content that contains predefined words"] = "Свернуть содержимое, содержащее предопределенные слова";
-App::$strings["This app looks in posts for the words/text you specify below, and collapses any content containing those keywords so it is not displayed at inappropriate times, such as sexual innuendo that may be improper in a work setting. It is polite and recommended to tag any content containing nudity with #NSFW. This filter can also match any other word/text you specify, and can thereby be used as a general purpose content filter."] = "Это приложение просматривает публикации для слов / текста, которые вы указываете ниже, и сворачивает любой контент, содержащий эти ключевые слова, поэтому он не отображается в неподходящее время, например, сексуальные инсинуации, которые могут быть неправильными в настройке работы. Например, мы рекомендуем отмечать любой контент, содержащий наготу, тегом #NSFW. Этот фильтр также способен реагировать на любое другое указанное вами слово / текст и может использоваться в качестве фильтра содержимого общего назначения.";
-App::$strings["Comma separated list of keywords to hide"] = "Список ключевых слов для скрытия, через запятую";
-App::$strings["Word, /regular-expression/, lang=xx, lang!=xx"] = "слово, /регулярное_выражение/, lang=xx, lang!=xx";
-App::$strings["NSFW"] = "";
-App::$strings["Max queueworker threads"] = "Макс. количество обработчиков очереди";
-App::$strings["Assume workers dead after ___ seconds"] = "Считать обработчики неактивными через секунд";
-App::$strings["Queueworker Settings"] = "Настройки обработчика очереди";
-App::$strings["Insane Journal Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Insane Journal сохранены.";
-App::$strings["Insane Journal Crosspost Connector App"] = "Приложение \"Пересылка публикаций Insane Journal\"";
-App::$strings["Relay public postings to Insane Journal"] = "Пересылает общедоступные публикации в Insane Journal";
-App::$strings["InsaneJournal username"] = "Имя пользователя Insane Journal";
-App::$strings["InsaneJournal password"] = "Пароль Insane Journal";
-App::$strings["Post to InsaneJournal by default"] = "Публиковать в Insane Journal по умолчанию";
-App::$strings["Insane Journal Crosspost Connector"] = "Пересылка публикаций Insane Journal";
-App::$strings["Post to Insane Journal"] = "Опубликовать в Insane Journal";
-App::$strings["Post to Dreamwidth"] = "Публиковать в Dreamwidth";
-App::$strings["Dreamwidth Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Dreamwidth сохранены.";
-App::$strings["Dreamwidth Crosspost Connector App"] = "Приложение \"Пересылка публикаций Dreamwidth\"";
-App::$strings["Relay public postings to Dreamwidth"] = "Пересылает общедоступные публикации в Dreamwidth";
-App::$strings["Dreamwidth username"] = "Имя пользователя Dreamwidth";
-App::$strings["Dreamwidth password"] = "Пароль Dreamwidth";
-App::$strings["Post to Dreamwidth by default"] = "Публиковать в Dreamwidth по умолчанию";
-App::$strings["Dreamwidth Crosspost Connector"] = "Пересылка публикаций Dreamwidth";
-App::$strings["New registration"] = "Новая регистрация";
-App::$strings["Message sent to %s. New account registration: %s"] = "Сообщение отправлено в %s. Регистрация нового аккаунта: %s";
-App::$strings["Hubzilla Directory Stats"] = "Каталог статистики Hubzilla";
-App::$strings["Total Hubs"] = "Всего хабов";
-App::$strings["Hubzilla Hubs"] = "Хабы Hubzilla";
-App::$strings["Friendica Hubs"] = "Хабы Friendica";
-App::$strings["Diaspora Pods"] = "Стручки Diaspora";
-App::$strings["Hubzilla Channels"] = "Каналы Hubzilla";
-App::$strings["Friendica Channels"] = "Каналы Friendica";
-App::$strings["Diaspora Channels"] = "Каналы Diaspora";
-App::$strings["Aged 35 and above"] = "Возраст 35 и выше";
-App::$strings["Aged 34 and under"] = "Возраст 34 и ниже";
-App::$strings["Average Age"] = "Средний возраст";
-App::$strings["Known Chatrooms"] = "Известные чаты";
-App::$strings["Known Tags"] = "Известные теги";
-App::$strings["Please note Diaspora and Friendica statistics are merely those **this directory** is aware of, and not all those known in the network. This also applies to chatrooms,"] = "Обратите внимание, что статистика Diaspora и Friendica это только те, о которых ** этот каталог ** знает, а не все известные в сети. Это также относится и к чатам.";
-App::$strings["Your Webbie:"] = "Ваш Webbie:";
-App::$strings["Fontsize (px):"] = "Размер шрифта (px):";
-App::$strings["Link:"] = "Ссылка:";
-App::$strings["Like us on Hubzilla"] = "Нравится на Hubzilla";
-App::$strings["Embed:"] = "Встроить:";
-App::$strings["Photos imported"] = "Фотографии импортированы";
-App::$strings["Redmatrix Photo Album Import"] = "Импортировать альбом фотографий Redmatrix";
-App::$strings["This will import all your Redmatrix photo albums to this channel."] = "Это позволит импортировать все ваши альбомы фотографий Redmatrix в этот канал.";
-App::$strings["Redmatrix Server base URL"] = "Базовый URL сервера Redmatrix";
-App::$strings["Redmatrix Login Username"] = "Имя пользователя Redmatrix";
-App::$strings["Redmatrix Login Password"] = "Пароль Redmatrix";
-App::$strings["Import just this album"] = "Импортировать только этот альбом";
-App::$strings["Leave blank to import all albums"] = "Оставьте пустым для импорта всех альбомов";
-App::$strings["Maximum count to import"] = "Максимальное количество для импорта";
-App::$strings["0 or blank to import all available"] = "0 или пусто для импорта всех доступных";
-App::$strings["Popular Channels"] = "Популярные каналы";
-App::$strings["Channels to auto connect"] = "Каналы для автоматического подключения";
-App::$strings["Comma separated list"] = "Список, разделённый запятыми";
-App::$strings["IRC Settings"] = "Настройки IRC";
-App::$strings["IRC settings saved."] = "Настройки IRC сохранены";
-App::$strings["IRC Chatroom"] = "Чат IRC";
-App::$strings["Gallery"] = "Галерея";
-App::$strings["Photo Gallery"] = "Фотогалерея";
-App::$strings["Gallery App"] = "Приложение \"Галерея\"";
-App::$strings["A simple gallery for your photo albums"] = "Простая галлерея для ваших фотоальбомов";
-App::$strings["Livejournal Crosspost Connector App"] = "Приложение \"Пересылка публикаций Livejournal\"";
+App::$strings["Hubzilla File Storage Import"] = "Импорт файлового хранилища Hubzilla";
+App::$strings["This will import all your cloud files from another server."] = "Это позволит импортировать все ваши файлы с другого сервера.";
+App::$strings["Hubzilla Server base URL"] = "Базовый URL сервера Hubzilla";
+App::$strings["Since modified date yyyy-mm-dd"] = "Начиная с даты изменений yyyy-mm-dd";
+App::$strings["Until modified date yyyy-mm-dd"] = "Заканчивая датой изменений yyyy-mm-dd";
+App::$strings["Post to Livejournal"] = "Опубликовать в Livejournal";
+App::$strings["Livejournal Crosspost Connector App"] = "Приложение \"Публикация в Livejournal\"";
App::$strings["Relay public posts to Livejournal"] = "Пересылает общедоступные публикации в Livejournal";
App::$strings["Livejournal username"] = "Имя пользователя Livejournal";
App::$strings["Livejournal password"] = "Пароль Livejournal";
App::$strings["Post to Livejournal by default"] = "Публиковать в Livejournal по умолчанию";
-App::$strings["Livejournal Crosspost Connector"] = "Пересылка публикаций Livejournal";
-App::$strings["Post to Livejournal"] = "Опубликовать в Livejournal";
-App::$strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Мы столкнулись с проблемой входа с предоставленным вами OpenID. Пожалуйста, проверьте корректность его написания.";
-App::$strings["The error message was:"] = "Сообщение об ошибке было:";
+App::$strings["Livejournal Crosspost Connector"] = "Публикация в Livejournal";
+App::$strings["Please contact your site administrator.<br />The provided API URL is not valid."] = "Пожалуйста свяжитесь с администратором сайта. <br />Предоставленный URL API недействителен.";
+App::$strings["We could not contact the GNU social API with the Path you entered."] = "Нам не удалось установить контакт с GNU Social API по введённому вами пути";
+App::$strings["GNU social settings updated."] = "Настройки GNU Social обновлены.";
+App::$strings["Hubzilla Crosspost Connector App"] = "Приложение \"Пересылка публикаций Hubzilla\"";
+App::$strings["Relay public postings to a connected GNU social account (formerly StatusNet)"] = "Пересылает общедоступные публикации на подключённую учётную запись GNU social (бывшая StatusNet)";
+App::$strings["Globally Available GNU social OAuthKeys"] = "Глобально доступные ключи OAuthKeys GNU Social";
+App::$strings["There are preconfigured OAuth key pairs for some GNU social servers available. If you are using one of them, please use these credentials.<br />If not feel free to connect to any other GNU social instance (see below)."] = "Существуют предварительно настроенные пары ключей OAuth для некоторых доступных серверов GNU social. Если вы используете один из них, используйте эти учетные данные. <br />Если вы не хотите подключаться к какому-либо другому серверу GNU social (см. ниже).";
+App::$strings["Provide your own OAuth Credentials"] = "Предоставьте ваши собственные регистрационные данные OAuth";
+App::$strings["No consumer key pair for GNU social found. Register your Hubzilla Account as an desktop client on your GNU social account, copy the consumer key pair here and enter the API base root.<br />Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Hubzilla installation at your favourite GNU social installation."] = "Не найдена пользовательская пара ключей для GNU social. Зарегистрируйте свою учетную запись Hubzilla в качестве настольного клиента в своей учетной записи GNU social, скопируйте cюда пару ключей пользователя и введите корневой каталог базы API. <br />Прежде чем регистрировать свою собственную пару ключей OAuth, спросите администратора, если ли уже пара ключей для этой установки Hubzilla в вашем GNU social.";
+App::$strings["OAuth Consumer Key"] = "Ключ клиента OAuth";
+App::$strings["OAuth Consumer Secret"] = "Пароль клиента OAuth";
+App::$strings["Base API Path"] = "Основной путь к API";
+App::$strings["Remember the trailing /"] = "Запомнить закрывающий /";
+App::$strings["GNU social application name"] = "Имя приложения GNU social";
+App::$strings["To connect to your GNU social account click the button below to get a security code from GNU social which you have to copy into the input box below and submit the form. Only your <strong>public</strong> posts will be posted to GNU social."] = "Чтобы подключиться к вашей учетной записи GNU social нажмите кнопку ниже для получения кода безопасности из GNU social, который вы должны скопировать в поле ввода ниже и отправить форму. Только ваши общедоступные сообщения будут опубликованы в GNU social.";
+App::$strings["Log in with GNU social"] = "Войти с GNU social";
+App::$strings["Copy the security code from GNU social here"] = "Скопируйте код безопасности GNU social здесь";
+App::$strings["Cancel Connection Process"] = "Отменить процесс подключения";
+App::$strings["Current GNU social API is"] = "Текущий GNU social API";
+App::$strings["Cancel GNU social Connection"] = "Отменить подключение с GNU social";
+App::$strings["<strong>Note</strong>: Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to GNU social will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в GNU social, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен.";
+App::$strings["Post to GNU social by default"] = "Публиковать в GNU social по умолчанию";
+App::$strings["If enabled your public postings will be posted to the associated GNU-social account by default"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social по умолчанию";
+App::$strings["GNU-Social Crosspost Connector"] = "Подключение пересылки публикаций GNU Social";
+App::$strings["Post to GNU social"] = "Опубликовать в GNU Social";
+App::$strings["API URL"] = "";
+App::$strings["Application name"] = "Название приложения";
+App::$strings["Access Denied"] = "Доступ запрещён";
+App::$strings["Enable Community Moderation"] = "Включить модерацию сообщества";
+App::$strings["Reputation automatically given to new members"] = "Репутация автоматически предоставляемая новым участникам";
+App::$strings["Reputation will never fall below this value"] = "Репутация никогда не упадёт ниже этого значения";
+App::$strings["Minimum reputation before posting is allowed"] = "Минимальная репутация для разрешения возможности размещать публикации";
+App::$strings["Minimum reputation before commenting is allowed"] = "Минимальная репутация для разрешения комментирования";
+App::$strings["Minimum reputation before a member is able to moderate other posts"] = "Минимальная репутация для возможности модерирования участником чужих публикаций";
+App::$strings["Max ratio of moderator's reputation that can be added to/deducted from reputation of person being moderated"] = "Максимальное соотношение репутации модератора, которое может быть добавлено / вычтено из репутации модерируемого участника";
+App::$strings["Reputation \"cost\" to post"] = "\"Стоимость\" репутации для публикации";
+App::$strings["Reputation \"cost\" to comment"] = "\"Стоимость\" репутации для комментирования";
+App::$strings["Reputation automatically recovers at this rate per hour until it reaches minimum_to_post"] = "Репутация автоматически восстанавливается с этой скоростью в час пока не достигает значения minimum_to_post";
+App::$strings["When minimum_to_moderate > reputation > minimum_to_post reputation recovers at this rate per hour"] = "При minimum_to_moderate > репутация > minimum_to_post репутация восстанавливается с этой скоростью в час";
+App::$strings["Community Moderation Settings"] = "Настройки модерирования сообщества";
+App::$strings["Can moderate reputation on my channel."] = "Может модерировать репутацию на моём канале";
+App::$strings["Flag Adult Photos"] = "Пометка фотографий для взрослых";
+App::$strings["Provide photo edit option to hide inappropriate photos from default album view"] = "Предоставьте возможность редактирования фотографий, чтобы скрыть неприемлемые фотографии из альбома по умолчанию";
App::$strings["First Name"] = "Имя";
App::$strings["Last Name"] = "Фамилия";
App::$strings["Nickname"] = "Псевдоним";
@@ -2368,83 +3191,99 @@ App::$strings["Birth Year"] = "Год рождения";
App::$strings["Birth Month"] = "Месяц рождения";
App::$strings["Birth Day"] = "День рождения";
App::$strings["Birthdate"] = "Дата рождения";
+App::$strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Мы столкнулись с проблемой входа с предоставленным вами OpenID. Пожалуйста, проверьте корректность его написания.";
+App::$strings["The error message was:"] = "Сообщение об ошибке было:";
App::$strings["OpenID protocol error. No ID returned."] = "Ошибка протокола OpenID. Идентификатор не возвращён.";
-App::$strings["Login failed."] = "Не удалось войти.";
-App::$strings["Male"] = "Мужчина";
-App::$strings["Female"] = "Женщина";
-App::$strings["You're welcome."] = "Пожалуйста.";
-App::$strings["Ah shucks..."] = "О, чёрт...";
-App::$strings["Don't mention it."] = "Не стоит благодарности.";
-App::$strings["&lt;blush&gt;"] = "&lt;краснею&gt;";
App::$strings["Startpage App"] = "Приложение \"Стартовая страница\"";
App::$strings["Set a preferred page to load on login from home page"] = "Устанавливает предпочтительную страницу для загрузки при входе с домашней страницы";
App::$strings["Page to load after login"] = "Страница для загрузки после входа";
App::$strings["Examples: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy collection), &quot;channel&quot; or &quot;notifications/system&quot; (leave blank for default network page (grid)."] = "Примеры: &quot;apps&quot;, &quot;network?f=&gid=37&quot; (privacy collection), &quot;channel&quot; or &quot;notifications/system&quot; (оставьте пустым для для страницы сети по умолчанию).";
App::$strings["Startpage"] = "Стартовая страница";
-App::$strings["bitchslap"] = "дать леща";
-App::$strings["bitchslapped"] = "получил леща";
-App::$strings["shag"] = "вздрючить";
-App::$strings["shagged"] = "вздрюченный";
-App::$strings["patent"] = "";
-App::$strings["patented"] = "";
-App::$strings["hug"] = "обнять";
-App::$strings["hugged"] = "обнятый";
-App::$strings["murder"] = "убить";
-App::$strings["murdered"] = "убитый";
-App::$strings["worship"] = "почитать";
-App::$strings["worshipped"] = "почитаемый";
-App::$strings["kiss"] = "целовать";
-App::$strings["kissed"] = "поцелованный";
-App::$strings["tempt"] = "искушать";
-App::$strings["tempted"] = "искушённый";
-App::$strings["raise eyebrows at"] = "поднять брови";
-App::$strings["raised their eyebrows at"] = "поднял брови";
-App::$strings["insult"] = "оскорбить";
-App::$strings["insulted"] = "оскорблённый";
-App::$strings["praise"] = "хвалить";
-App::$strings["praised"] = "похваленный";
-App::$strings["be dubious of"] = "усомниться";
-App::$strings["was dubious of"] = "усомнился";
-App::$strings["eat"] = "есть";
-App::$strings["ate"] = "съел";
-App::$strings["giggle and fawn at"] = "";
-App::$strings["giggled and fawned at"] = "";
-App::$strings["doubt"] = "сомневаться";
-App::$strings["doubted"] = "сомневался";
-App::$strings["glare"] = "";
-App::$strings["glared at"] = "";
-App::$strings["fuck"] = "трахнуть";
-App::$strings["fucked"] = "трахнул";
-App::$strings["bonk"] = "";
-App::$strings["bonked"] = "";
-App::$strings["declare undying love for"] = "признаться в любви к";
-App::$strings["declared undying love for"] = "признался в любви к";
-App::$strings["%1\$s dislikes %2\$s's %3\$s"] = "%1\$s не нравится %2\$s's %3\$s";
-App::$strings["Diaspora Protocol Settings updated."] = "Настройки протокола Diaspora обновлены.";
-App::$strings["The diaspora protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол Diaspora не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
-App::$strings["Diaspora Protocol App"] = "Приложение \"Протокол Diaspora\"";
-App::$strings["Allow any Diaspora member to comment on your public posts"] = "Разрешить любому участнику Diaspora комментировать ваши общедоступные публикации";
-App::$strings["Prevent your hashtags from being redirected to other sites"] = "Предотвратить перенаправление тегов на другие сайты";
-App::$strings["Sign and forward posts and comments with no existing Diaspora signature"] = "Подписывать и отправлять публикации и комментарии с несуществующей подписью Diaspora";
-App::$strings["Followed hashtags (comma separated, do not include the #)"] = "Отслеживаемые теги (через запятую, исключая #)";
-App::$strings["Diaspora Protocol"] = "Протокол Diaspora";
-App::$strings["No username found in import file."] = "Имя пользователя не найдено в файле для импорта.";
-App::$strings["Unable to create a unique channel address. Import failed."] = "Не удалось создать уникальный адрес канала. Импорт не завершен.";
-App::$strings["Photo Cache settings saved."] = "Настройки кэширования изображений сохранены.";
-App::$strings["Photo Cache addon saves a copy of images from external sites locally to increase your anonymity in the web."] = "Приложение \"Кэшировние изображений\" сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет.";
-App::$strings["Photo Cache App"] = "Приложение \"Кэширование изображений\"";
-App::$strings["Minimal photo size for caching"] = "Минимальный размер изображений для кэширования";
-App::$strings["In pixels. From 1 up to 1024, 0 will be replaced with system default."] = "В пикселях. От 1 до 1024, 0 будет заменён значением по умолчанию.";
-App::$strings["Photo Cache"] = "Кэширование изображений";
-App::$strings["Your account on %s will expire in a few days."] = "Ваш аккаунт на %s перестанет работать через несколько дней.";
-App::$strings["Your $Productname test account is about to expire."] = "Ваш тестовый аккаунт в $Productname близок к окончанию срока действия.";
-App::$strings["Add some colour to tag clouds"] = "Добавить немного цвета для облака тегов";
-App::$strings["Rainbow Tag App"] = "Приложение \"Радуга тегов\"";
-App::$strings["Rainbow Tag"] = "Радуга тегов";
-App::$strings["Show Upload Limits"] = "Показать ограничения на загрузку";
-App::$strings["Hubzilla configured maximum size: "] = "Максимальный размер настроенный в Hubzilla:";
-App::$strings["PHP upload_max_filesize: "] = "";
-App::$strings["PHP post_max_size (must be larger than upload_max_filesize): "] = "PHP post_max_size (должен быть больше чем upload_max_filesize): ";
+App::$strings["Hubzilla Directory Stats"] = "Каталог статистики Hubzilla";
+App::$strings["Total Hubs"] = "Всего хабов";
+App::$strings["Hubzilla Hubs"] = "Хабы Hubzilla";
+App::$strings["Friendica Hubs"] = "Хабы Friendica";
+App::$strings["Diaspora Pods"] = "Стручки Diaspora";
+App::$strings["Hubzilla Channels"] = "Каналы Hubzilla";
+App::$strings["Friendica Channels"] = "Каналы Friendica";
+App::$strings["Diaspora Channels"] = "Каналы Diaspora";
+App::$strings["Aged 35 and above"] = "Возраст 35 и выше";
+App::$strings["Aged 34 and under"] = "Возраст 34 и ниже";
+App::$strings["Average Age"] = "Средний возраст";
+App::$strings["Known Chatrooms"] = "Известные чаты";
+App::$strings["Known Tags"] = "Известные теги";
+App::$strings["Please note Diaspora and Friendica statistics are merely those **this directory** is aware of, and not all those known in the network. This also applies to chatrooms,"] = "Обратите внимание, что статистика Diaspora и Friendica это только те, о которых ** этот каталог ** знает, а не все известные в сети. Это также относится и к чатам.";
+App::$strings["Enable Test Catalog"] = "Включить тестовый каталог";
+App::$strings["Enable Manual Payments"] = "Включить ручные платежи";
+App::$strings["Base Merchant Currency"] = "Основная торговая валюта";
+App::$strings["Cart Settings"] = "Настройки карточек";
+App::$strings["Enable Subscription Management Module"] = "Включить модуль управления подписками";
+App::$strings["Cannot include subscription items with different terms in the same order."] = "Нельзя включать элементы подписки с разными условиями в том же заказе.";
+App::$strings["Select Subscription to Edit"] = "Выбрать подписку для редактирования";
+App::$strings["Edit Subscriptions"] = "Редактировать подписки";
+App::$strings["Subscription SKU"] = "Код подписки";
+App::$strings["Catalog Description"] = "Описание каталога";
+App::$strings["Subscription available for purchase."] = "Подписка доступна для покупки.";
+App::$strings["Maximum active subscriptions to this item per account."] = "Максимальное количество подписок на аккаунт для этой позиции";
+App::$strings["Subscription price."] = "Цена подписки.";
+App::$strings["Quantity"] = "Количество";
+App::$strings["Term"] = "Условия";
+App::$strings["Enable Hubzilla Services Module"] = "Включить модуль сервиса Hubzilla";
+App::$strings["New Sku"] = "Новый код";
+App::$strings["Cannot save edits to locked item."] = "Невозможно сохранить изменения заблокированной позиции.";
+App::$strings["SKU not found."] = "Код не найден.";
+App::$strings["Invalid Activation Directive."] = "Недействительная директива активации.";
+App::$strings["Invalid Deactivation Directive."] = "Недействительная директива деактивации";
+App::$strings["Add to this privacy group"] = "Добавить в эту группу безопасности";
+App::$strings["Set user service class"] = "Установить класс обслуживания пользователя";
+App::$strings["You must be using a local account to purchase this service."] = "Вы должны использовать локальную учётноую запись для покупки этого сервиса.";
+App::$strings["Changes Locked"] = "Изменения заблокированы";
+App::$strings["Item available for purchase."] = "Позиция доступна для приобретения.";
+App::$strings["Price"] = "Цена";
+App::$strings["Add buyer to privacy group"] = "Добавить покупателя в группу безопасности";
+App::$strings["Add buyer as connection"] = "Добавить покупателя как контакт";
+App::$strings["Set Service Class"] = "Установить класс обслуживания";
+App::$strings["Enable Paypal Button Module"] = "Включить модуль кнопки Paypal";
+App::$strings["Use Production Key"] = "Использовать ключ Production";
+App::$strings["Paypal Sandbox Client Key"] = "Ключ клиента Paypal Sandbox";
+App::$strings["Paypal Sandbox Secret Key"] = "Секретный ключ Paypal Sandbox";
+App::$strings["Paypal Production Client Key"] = "Ключ клиента Paypal Production";
+App::$strings["Paypal Production Secret Key"] = "Секретный ключ Paypal Production";
+App::$strings["Paypal button payments are not enabled."] = "Кнопка Paypal для платежей не включена.";
+App::$strings["Paypal button payments are not properly configured. Please choose another payment option."] = "Кнопка Paypal для платежей настроена неправильно. Пожалуйста, используйте другой вариант оплаты.";
+App::$strings["Order not found."] = "Заказ не найден.";
+App::$strings["Enable Manual Cart Module"] = "Включить модуль ручного управления карточками";
+App::$strings["Access Denied."] = "Доступ запрещён.";
+App::$strings["Order Not Found"] = "Заказ не найден";
+App::$strings["Invalid Item"] = "Недействительный элемент";
+App::$strings["Error: order mismatch. Please try again."] = "Ошибка: несоответствие заказа. Пожалуйста, попробуйте ещё раз";
+App::$strings["Manual payments are not enabled."] = "Ручные платежи не подключены.";
+App::$strings["Finished"] = "Завершено";
+App::$strings["DB Cleanup Failure"] = "Сбой очистки базы данных";
+App::$strings["[cart] Item Added"] = "[cart] Элемент добавлен";
+App::$strings["Order already checked out."] = "Заказ уже проверен.";
+App::$strings["Drop database tables when uninstalling."] = "Сбросить таблицы базы данных при деинсталляции";
+App::$strings["Shop"] = "Магазин";
+App::$strings["Cart utilities for orders and payments"] = "Утилиты карточек для заказов и платежей";
+App::$strings["You must be logged into the Grid to shop."] = "Вы должны быть в сети для доступа к магазину";
+App::$strings["Access denied."] = "Доступ запрещён.";
+App::$strings["No Order Found"] = "Нет найденных заказов";
+App::$strings["An unknown error has occurred Please start again."] = "Произошла неизвестная ошибка. Пожалуйста, начните снова.";
+App::$strings["Invalid Payment Type. Please start again."] = "Недействительный тип платежа. Пожалуйста, начните снова.";
+App::$strings["Order not found"] = "Заказ не найден";
+App::$strings["Federate"] = "Федерировать";
+App::$strings["nofed Settings saved."] = "Настройки nofed сохранены.";
+App::$strings["No Federation App"] = "Приложение No Federation";
+App::$strings["Prevent posting from being federated to anybody. It will exist only on your channel page."] = "Запрещает федеративные функций для публикаций. Они будут существовать только на странице вашего канала.";
+App::$strings["Federate posts by default"] = "Разрешить федерацию публикаций по умолчанию";
+App::$strings["No Federation"] = "Отключить Federation";
+App::$strings["Your channel has been upgraded to the latest \$Projectname version."] = "Ваш канал был обновлён на последнюю версию \$Projectname.";
+App::$strings["To improve usability, we have converted some features into installable stand-alone apps."] = "Чтобы улучшить удобство использования, некоторые функции теперь доступны в виде устанавливаемых автономных приложений.";
+App::$strings["Please visit the \$Projectname"] = "Пожалуйста, посетите \$Projectname";
+App::$strings["app store"] = "раздел \"Приложения\"";
+App::$strings["and install possibly missing apps."] = "и установите необходимые вам.";
+App::$strings["Upgrade Info"] = "Сведения об обновлении";
+App::$strings["Do not show this again"] = "Больше не показывать";
App::$strings["generic profile image"] = "Стандартное изображение профиля";
App::$strings["random geometric pattern"] = "Случайный геометрический рисунок";
App::$strings["monster face"] = "Лицо чудовища";
@@ -2459,174 +3298,81 @@ App::$strings["Select default avatar image if none was found at Gravatar. See RE
App::$strings["Rating of images"] = "Оценки изображений";
App::$strings["Select the appropriate avatar rating for your site. See README"] = "Выберите подходящую оценку аватара для вашего сайта (см. README).";
App::$strings["Gravatar settings updated."] = "Настройки Gravatar обновлены.";
-App::$strings["Hubzilla File Storage Import"] = "Импорт файлового хранилища Hubzilla";
-App::$strings["This will import all your cloud files from another server."] = "Это позволит импортировать все ваши файлы с другого сервера.";
-App::$strings["Hubzilla Server base URL"] = "Базовый URL сервера Hubzilla";
-App::$strings["Since modified date yyyy-mm-dd"] = "Начиная с даты изменений yyyy-mm-dd";
-App::$strings["Until modified date yyyy-mm-dd"] = "Заканчивая датой изменений yyyy-mm-dd";
-App::$strings["Who viewed my channel/profile"] = "Кто смотрел мой канал / профиль";
-App::$strings["Recent Channel/Profile Viewers"] = "Последние просмотры канала / профиля";
-App::$strings["No entries."] = "Нет записей.";
-App::$strings["NSA Bait App"] = "Приложение NSA Bait";
-App::$strings["Make yourself a political target"] = "Сделать себя политической мишенью";
-App::$strings["Send test email"] = "Отправить тестовый email";
-App::$strings["No recipients found."] = "Получателей не найдено.";
-App::$strings["Mail sent."] = "Сообщение отправлено";
-App::$strings["Sending of mail failed."] = "Не удалось отправить сообщение.";
-App::$strings["Mail Test"] = "Тестовое сообщение";
-App::$strings["Message subject"] = "Тема сообщения";
-App::$strings["Use markdown for editing posts"] = "Использовать язык разметки Markdown для редактирования публикаций";
-App::$strings["View Larger"] = "Увеличить";
-App::$strings["Tile Server URL"] = "URL сервера Tile";
-App::$strings["A list of <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">public tile servers</a>"] = "Список <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">общедоступных серверов</a>";
-App::$strings["Nominatim (reverse geocoding) Server URL"] = "URL сервера Nominatim (обратное геокодирование)";
-App::$strings["A list of <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">Nominatim servers</a>"] = "Список <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">серверов Nominatim</a>";
-App::$strings["Default zoom"] = "Масштаб по умолчанию";
-App::$strings["The default zoom level. (1:world, 18:highest, also depends on tile server)"] = "Уровень размера по умолчанию (1 - весь мир, 18 - максимальный; зависит от сервера).";
-App::$strings["Include marker on map"] = "Включите маркер на карте";
-App::$strings["Include a marker on the map."] = "Включить маркер на карте";
+App::$strings["WYSIWYG status editor"] = "WYSIWYG редактор статуса ";
+App::$strings["WYSIWYG Status App"] = "Приложение \"WYSIWYG статус\"";
+App::$strings["WYSIWYG Status"] = "WYSIWYG статус";
+App::$strings["No server specified"] = "Сервер не указан";
+App::$strings["Posts imported"] = "Публикации импортированы";
+App::$strings["Files imported"] = "Файлы импортированы";
+App::$strings["This addon app copies existing content and file storage to a cloned/copied channel. Once the app is installed, visit the newly installed app. This will allow you to set the location of your original channel and an optional date range of files/conversations to copy."] = "Это дополнительное приложение копирует существующее содержимое и хранилище файлов в клонированный / скопированный канал. После того, как приложение установлено, посетите его страницу. Это позволит вам задать местоположение вашего исходного канала и диапазон дат файлов / бесед для копирования.";
+App::$strings["This will import all your conversations and cloud files from a cloned channel on another server. This may take a while if you have lots of posts and or files."] = "Импортировать все ваши разговоры и хранилище файлов из клонируемого канала на другом сервере. Это может занять некоторое время, если у вас много публикаций и / или файлов.";
+App::$strings["Include posts"] = "Включая публикации";
+App::$strings["Conversations, Articles, Cards, and other posted content"] = "Беседы, Статьи, Карточки и другое опубликованное содержимое";
+App::$strings["Include files"] = "Включая файлы";
+App::$strings["Files, Photos and other cloud storage"] = "Файлы, Фотографии и прочее из хранилища";
+App::$strings["Original Server base URL"] = "Базовый URL сервера-источника";
+App::$strings["Random Planet App"] = "Приложение \"Случайная планета\"";
+App::$strings["Set a random planet from the Star Wars Empire as your location when posting"] = "Установить случайную планету из Империи Звездных Войн в качестве вашего местоположения при публикации";
+App::$strings["Add some colour to tag clouds"] = "Добавить немного цвета для облака тегов";
+App::$strings["Rainbow Tag App"] = "Приложение \"Радуга тегов\"";
+App::$strings["Rainbow Tag"] = "Радуга тегов";
+App::$strings["Invalid game."] = "Недействительная игра.";
+App::$strings["You are not a player in this game."] = "Вы не играете в эту игру.";
+App::$strings["You must be a local channel to create a game."] = "Ваш канал должен быть локальным чтобы создать игру.";
+App::$strings["You must select one opponent that is not yourself."] = "Вы должны выбрать противника который не является вами.";
+App::$strings["Random color chosen."] = "Выбран случайный цвет.";
+App::$strings["Error creating new game."] = "Ошибка создания новой игры.";
+App::$strings["Chess not installed."] = "Шахматы не установлены.";
+App::$strings["You must select a local channel /chess/channelname"] = "Вы должны выбрать локальный канал /chess/channelname";
+App::$strings["Enable notifications"] = "Включить оповещения";
+App::$strings["Follow"] = "Отслеживать";
+App::$strings["%1\$s is now following %2\$s"] = "%1\$s сейчас отслеживает %2\$s";
+App::$strings["The GNU-Social protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол GNU-Social не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
+App::$strings["GNU-Social Protocol App"] = "Приложение \"Протокол GNU-Social\"";
+App::$strings["GNU-Social Protocol"] = "Протокол GNU-Social";
+App::$strings["TOTP Two-Step Verification"] = "Двухэтапная верификация TOTP";
+App::$strings["Enter the 2-step verification generated by your authenticator app:"] = "Введите код проверки, созданный вашим приложением для аутентификации";
+App::$strings["Success!"] = "Успех!";
+App::$strings["Invalid code, please try again."] = "Неверный код. Пожалуйста, попробуйте ещё раз.";
+App::$strings["Too many invalid codes..."] = "Слишком много неверных кодов...";
+App::$strings["Verify"] = "Проверить";
+App::$strings["You haven't set a TOTP secret yet.\nPlease click the button below to generate one and register this site\nwith your preferred authenticator app."] = "Вы еще не установили секретный код TOTP. Пожалуйста, нажмите на кнопку ниже, чтобы сгенерировать его и зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации.";
+App::$strings["Your TOTP secret is"] = "Ваш секретный код TOTP";
+App::$strings["Be sure to save it somewhere in case you lose or replace your mobile device.\nUse your mobile device to scan the QR code below to register this site\nwith your preferred authenticator app."] = "Обязательно сохраните его где-нибудь на случай потери или замены мобильного устройства. С помощью мобильного устройства отсканируйте приведенный ниже QR-код, чтобы зарегистрировать этот сайт в предпочитаемом вами приложении для аутентификации.";
+App::$strings["Test"] = "Тест";
+App::$strings["Generate New Secret"] = "Сгенерировать новый код";
+App::$strings["Go"] = "Вперёд";
+App::$strings["Enter your password"] = "Введите ваш пароль";
+App::$strings["enter TOTP code from your device"] = "введите код TOTP из вашего устройства";
+App::$strings["Pass!"] = "Принято!";
+App::$strings["Fail"] = "Отказано";
+App::$strings["Incorrect password, try again."] = "Неверный пароль, попробуйте снова.";
+App::$strings["Record your new TOTP secret and rescan the QR code above."] = "Запишите ваш секретный код TOTP и повторно отсканируйте приведенный ниже QR-код.";
+App::$strings["TOTP Settings"] = "Настройки TOTP";
+App::$strings["pageheader Settings saved."] = "Настройки шапки страницы сохранены.";
+App::$strings["Page Header App"] = "Приложение \"Заголовок страницы\"";
+App::$strings["Inserts a page header"] = "Вставляет заголовок страницы";
+App::$strings["Message to display on every page on this server"] = "Отображаемое сообщение на каждой странице на этом сервере.";
+App::$strings["Page Header"] = "Заголовок страницы";
App::$strings["text to include in all outgoing posts from this site"] = "текст, который будет добавлен во все исходящие публикации с этого сайта";
-App::$strings["Fuzzloc Settings updated."] = "Настройки примерного положения обновлены.";
-App::$strings["Fuzzy Location App"] = "Приложение \"Примерное положение\"";
-App::$strings["Blur your precise location if your channel uses browser location mapping"] = "Размывает вашего точное местоположение в случае если ваш канал использует отображение местоположения из браузера";
-App::$strings["Minimum offset in meters"] = "Минимальное смещение в метрах";
-App::$strings["Maximum offset in meters"] = "Максимальное смещение в метрах";
-App::$strings["Fuzzy Location"] = "Примерное положение";
-App::$strings["Post to Friendica"] = "Опубликовать в Friendica";
-App::$strings["Friendica Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Friendica сохранены.";
-App::$strings["Friendica Crosspost Connector App"] = "Приложение \"Пересылка публикаций Friendica\"";
-App::$strings["Relay public postings to a connected Friendica account"] = "Пересылает общедоступные публикации на подключённую учётную запись Friendica";
-App::$strings["Send public postings to Friendica by default"] = "Отправлять общедоступные публикации во Friendica по умолчанию";
-App::$strings["Friendica API Path"] = "Путь к Friendica API";
-App::$strings["https://{sitename}/api"] = "";
-App::$strings["Friendica login name"] = "Имя входа Friendica";
-App::$strings["Friendica password"] = "Пароль Friendica";
-App::$strings["Friendica Crosspost Connector"] = "Пересылка публикаций Friendica";
-App::$strings["Jappixmini App"] = "Приложение Jappix Mini";
-App::$strings["Provides a Facebook-like chat using Jappix Mini"] = "Предоставляет Facebook-подобный чат с использованием Jappix Mini";
-App::$strings["Status:"] = "Статус:";
-App::$strings["Hide Jappixmini Chat-Widget from the webinterface"] = "Скрыть виджет чата Jappix Mini из веб-интерфейса";
-App::$strings["Jabber username"] = "Имя пользователя Jabber";
-App::$strings["Jabber server"] = "Сервер Jabber";
-App::$strings["Jabber BOSH host URL"] = "URL узла Jabber BOSH";
-App::$strings["Jabber password"] = "Пароль Jabber";
-App::$strings["Encrypt Jabber password with Hubzilla password"] = "Зашифровать пароль Jabber с помощью пароля Hubzilla";
-App::$strings["Hubzilla password"] = "Пароль Hubzilla";
-App::$strings["Approve subscription requests from Hubzilla contacts automatically"] = "Утверждать запросы на подписку от контактов Hubzilla автоматически";
-App::$strings["Purge internal list of jabber addresses of contacts"] = "Очистить внутренний список адресов контактов Jabber";
-App::$strings["Configuration Help"] = "Помощь по конфигурации";
-App::$strings["Jappixmini Settings"] = "Настройки Jappix Мini";
-App::$strings["Your channel has been upgraded to the latest \$Projectname version."] = "Ваш канал был обновлён на последнюю версию \$Projectname.";
-App::$strings["To improve usability, we have converted some features into installable stand-alone apps."] = "Чтобы улучшить удобство использования, некоторые функции теперь доступны в виде устанавливаемых автономных приложений.";
-App::$strings["Please visit the \$Projectname"] = "Пожалуйста, посетите \$Projectname";
-App::$strings["app store"] = "раздел \"Приложения\"";
-App::$strings["and install possibly missing apps."] = "и установите необходимые вам.";
-App::$strings["Upgrade Info"] = "Сведения об обновлении";
-App::$strings["Do not show this again"] = "Больше не показывать";
-App::$strings["Access Denied"] = "Доступ запрещён";
-App::$strings["Enable Community Moderation"] = "Включить модерацию сообщества";
-App::$strings["Reputation automatically given to new members"] = "Репутация автоматически предоставляемая новым участникам";
-App::$strings["Reputation will never fall below this value"] = "Репутация никогда не упадёт ниже этого значения";
-App::$strings["Minimum reputation before posting is allowed"] = "Минимальная репутация для разрешения возможности размещать публикации";
-App::$strings["Minimum reputation before commenting is allowed"] = "Минимальная репутация для разрешения комментирования";
-App::$strings["Minimum reputation before a member is able to moderate other posts"] = "Минимальная репутация для возможности модерирования участником чужих публикаций";
-App::$strings["Max ratio of moderator's reputation that can be added to/deducted from reputation of person being moderated"] = "Максимальное соотношение репутации модератора, которое может быть добавлено / вычтено из репутации модерируемого участника";
-App::$strings["Reputation \"cost\" to post"] = "\"Стоимость\" репутации для публикации";
-App::$strings["Reputation \"cost\" to comment"] = "\"Стоимость\" репутации для комментирования";
-App::$strings["Reputation automatically recovers at this rate per hour until it reaches minimum_to_post"] = "Репутация автоматически восстанавливается с этой скоростью в час пока не достигает значения minimum_to_post";
-App::$strings["When minimum_to_moderate > reputation > minimum_to_post reputation recovers at this rate per hour"] = "При minimum_to_moderate > репутация > minimum_to_post репутация восстанавливается с этой скоростью в час";
-App::$strings["Community Moderation Settings"] = "Настройки модерирования сообщества";
-App::$strings["Can moderate reputation on my channel."] = "Может модерировать репутацию на моём канале";
-App::$strings["Channel Reputation"] = "Репутация канала";
-App::$strings["Block Completely"] = "Заблокировать полностью";
-App::$strings["Superblock App"] = "Приложение Superblock";
-App::$strings["Block channels"] = "Заблокировать каналы";
-App::$strings["superblock settings updated"] = "Настройки Superblock обновлены.";
-App::$strings["Currently blocked"] = "В настоящее время заблокирован";
-App::$strings["No channels currently blocked"] = "В настоящее время никакие каналы не блокируются";
-App::$strings["nofed Settings saved."] = "Настройки nofed сохранены.";
-App::$strings["No Federation App"] = "Приложение No Federation";
-App::$strings["Prevent posting from being federated to anybody. It will exist only on your channel page."] = "Запрещает федеративные функций для публикаций. Они будут существовать только на странице вашего канала.";
-App::$strings["Federate posts by default"] = "Разрешить федерацию публикаций по умолчанию";
-App::$strings["No Federation"] = "Отключить Federation";
-App::$strings["Federate"] = "Федерировать";
-App::$strings["Channel is required."] = "Необходим канал.";
-App::$strings["Hubzilla Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Hubzilla сохранены.";
-App::$strings["Hubzilla Crosspost Connector App"] = "Приложение \"Пересылка публикаций Hubzilla\"";
-App::$strings["Relay public postings to another Hubzilla channel"] = "Пересылает общедоступные публикации в другой канал Hubzilla";
-App::$strings["Send public postings to Hubzilla channel by default"] = "Отправлять общедоступные публикации в канал Hubzilla по умолчанию";
-App::$strings["Hubzilla API Path"] = "Путь к Hubzilla API";
-App::$strings["Hubzilla login name"] = "Имя входа Hubzilla";
-App::$strings["Hubzilla channel name"] = "Название канала Hubzilla";
-App::$strings["Hubzilla Crosspost Connector"] = "Пересылка публикаций Hubzilla";
-App::$strings["Post to Hubzilla"] = "Опубликовать в Hubzilla";
-App::$strings["Logfile archive directory"] = "Каталог архивирования журнала";
-App::$strings["Directory to store rotated logs"] = "Каталог для хранения заархивированных журналов";
-App::$strings["Logfile size in bytes before rotating"] = "Размер файла журнала в байтах для архивирования";
-App::$strings["Number of logfiles to retain"] = "Количество сохраняемых файлов журналов";
+App::$strings["Send email to all members"] = "Отправить email всем участникам";
+App::$strings["%1\$d of %2\$d messages sent."] = "%1\$d из %2\$d сообщений отправлено.";
+App::$strings["Send email to all hub members."] = "Отправить email всем участникам узла.";
+App::$strings["Sender Email address"] = "Адрес электронной почты отправителя";
+App::$strings["Test mode (only send to hub administrator)"] = "Тестовый режим (отправка только администратору узла)";
+App::$strings["Smileybutton App"] = "Приложение \"Кнопка со смайликам\"";
+App::$strings["Adds a smileybutton to the jot editor"] = "Добавлять кнопку со смайликами в редактор Jot";
+App::$strings["Hide the button and show the smilies directly."] = "Скрыть кнопку и сразу показывать смайлики.";
+App::$strings["Smileybutton Settings"] = "Настройки кнопки со смайликами";
App::$strings["Friendica Photo Album Import"] = "Импортировать альбом фотографий Friendica";
App::$strings["This will import all your Friendica photo albums to this Red channel."] = "Это позволит импортировать все ваши альбомы фотографий Friendica в этот канал.";
App::$strings["Friendica Server base URL"] = "Базовый URL сервера Friendica";
App::$strings["Friendica Login Username"] = "Имя пользователя для входа Friendica";
App::$strings["Friendica Login Password"] = "Пароль для входа Firendica";
-App::$strings["WYSIWYG status editor"] = "WYSIWYG редактор статуса ";
-App::$strings["WYSIWYG Status App"] = "Приложение \"WYSIWYG статус\"";
-App::$strings["WYSIWYG Status"] = "WYSIWYG статус";
-App::$strings["Set your location"] = "Задать своё местоположение";
-App::$strings["Clear browser location"] = "Очистить местоположение из браузера";
-App::$strings["Embed (existing) photo from your photo albums"] = "Встроить (существующее) фото из вашего фотоальбома";
-App::$strings["Tag term:"] = "Теги:";
-App::$strings["Where are you right now?"] = "Где вы сейчас?";
-App::$strings["Choose a different album..."] = "Выбрать другой альбом...";
-App::$strings["Comments enabled"] = "Комментарии включены";
-App::$strings["Comments disabled"] = "Комментарии отключены";
-App::$strings["Page link name"] = "Название ссылки на страницу ";
-App::$strings["Post as"] = "Опубликовать как";
-App::$strings["Toggle voting"] = "Подключить голосование";
-App::$strings["Disable comments"] = "Отключить комментарии";
-App::$strings["Toggle comments"] = "Переключить комментарии";
-App::$strings["Categories (optional, comma-separated list)"] = "Категории (необязательно, список через запятую)";
-App::$strings["Other networks and post services"] = "Другие сети и службы публикаций";
-App::$strings["Set publish date"] = "Установить дату публикации";
-App::$strings["ActivityPub Protocol Settings updated."] = "Настройки протокола ActivityPub обновлены.";
-App::$strings["The activitypub protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол ActivityPub не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
-App::$strings["Activitypub Protocol App"] = "Приложение \"Протокол ActivityPub\"";
-App::$strings["Deliver to ActivityPub recipients in privacy groups"] = "Доставить получателям ActivityPub в группах безопасности";
-App::$strings["May result in a large number of mentions and expose all the members of your privacy group"] = "Может привести к большому количеству упоминаний и раскрытию участников группы безопасности";
-App::$strings["Send multi-media HTML articles"] = "Отправить HTML статьи с мультимедиа";
-App::$strings["Not supported by some microblog services such as Mastodon"] = "Не поддерживается некоторыми микроблогами, например Mastodon";
-App::$strings["Activitypub Protocol"] = "Протокол ActivityPub";
-App::$strings["Project Servers and Resources"] = "Серверы и ресурсы проекта";
-App::$strings["Project Creator and Tech Lead"] = "Создатель проекта и технический руководитель";
-App::$strings["And the hundreds of other people and organisations who helped make the Hubzilla possible."] = "И сотни других людей и организаций которые помогали в создании Hubzilla.";
-App::$strings["The Redmatrix/Hubzilla projects are provided primarily by volunteers giving their time and expertise - and often paying out of pocket for services they share with others."] = "Проекты Redmatrix / Hubzilla предоставляются, в основном, добровольцами, которые предоставляют свое время и опыт и, часто, оплачивают из своего кармана услуги, которыми они делятся с другими.";
-App::$strings["There is no corporate funding and no ads, and we do not collect and sell your personal information. (We don't control your personal information - <strong>you do</strong>.)"] = "Здесь нет корпоративного финансирования и рекламы, мы не собираем и не продаем вашу личную информацию. (Мы не контролируем вашу личную информацию - <strong>это делаете вы</strong>.)";
-App::$strings["Help support our ground-breaking work in decentralisation, web identity, and privacy."] = "Помогите поддержать нашу новаторскую работу в областях децентрализации, веб-идентификации и конфиденциальности.";
-App::$strings["Your donations keep servers and services running and also helps us to provide innovative new features and continued development."] = "В ваших пожертвованиях поддерживают серверы и службы, а также помогают нам предоставлять новые возможности и продолжать развитие.";
-App::$strings["Donate"] = "Пожертвовать";
-App::$strings["Choose a project, developer, or public hub to support with a one-time donation"] = "Выберите проект, разработчика или общедоступный узел для поддержки в форме единоразового пожертвования";
-App::$strings["Donate Now"] = "Пожертвовать сейчас";
-App::$strings["<strong><em>Or</em></strong> become a project sponsor (Hubzilla Project only)"] = "<strong><em>или</em></strong> станьте спонсором проекта (только для Hubzilla)";
-App::$strings["Please indicate if you would like your first name or full name (or nothing) to appear in our sponsor listing"] = "Пожалуйста, если желаете, укажите ваше имя для отображения в списке спонсоров.";
-App::$strings["Sponsor"] = "Спонсор";
-App::$strings["Special thanks to: "] = "Особые благодарности:";
-App::$strings["This is a fairly comprehensive and complete guitar chord dictionary which will list most of the available ways to play a certain chord, starting from the base of the fingerboard up to a few frets beyond the twelfth fret (beyond which everything repeats). A couple of non-standard tunings are provided for the benefit of slide players, etc."] = "";
-App::$strings["Chord names start with a root note (A-G) and may include sharps (#) and flats (b). This software will parse most of the standard naming conventions such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."] = "";
-App::$strings["Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ..."] = "Примеры действительных включают A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ...";
-App::$strings["Guitar Chords"] = "Гитарные аккорды";
-App::$strings["The complete online chord dictionary"] = "Полный онлайн словарь аккордов";
-App::$strings["Tuning"] = "Настройка";
-App::$strings["Chord name: example: Em7"] = "Наименование аккорда - example: Em7";
-App::$strings["Show for left handed stringing"] = "Показывать струны для левшей";
-App::$strings["Quick Reference"] = "Быстрая ссылка";
-App::$strings["Post to Libertree"] = "Опубликовать в Libertree";
-App::$strings["Libertree Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Libertree сохранены.";
-App::$strings["Libertree Crosspost Connector App"] = "Приложение \"Пересылка публикаций Libertree\"";
-App::$strings["Relay public posts to Libertree"] = "Пересылает общедоступные публикации в Libertree";
-App::$strings["Libertree API token"] = "Токен Libertree API";
-App::$strings["Libertree site URL"] = "URL сайта Libertree";
-App::$strings["Post to Libertree by default"] = "Публиковать в Libertree по умолчанию";
-App::$strings["Libertree Crosspost Connector"] = "Пересылка публикаций Libertree";
+App::$strings["Show Upload Limits"] = "Показать ограничения на загрузку";
+App::$strings["Hubzilla configured maximum size: "] = "Максимальный размер настроенный в Hubzilla:";
+App::$strings["PHP upload_max_filesize: "] = "";
+App::$strings["PHP post_max_size (must be larger than upload_max_filesize): "] = "PHP post_max_size (должен быть больше чем upload_max_filesize): ";
App::$strings["Flattr widget settings updated."] = "Настройки виджета Flattr обновлены.";
App::$strings["Flattr Widget App"] = "Приложение \"Виджет Flattr\"";
App::$strings["Add a Flattr button to your channel page"] = "Добавить кнопку Flattr на страницу вашего канала";
@@ -2643,170 +3389,6 @@ App::$strings["left"] = "слева";
App::$strings["right"] = "справа";
App::$strings["Flattr Widget"] = "Виджет Flattr";
App::$strings["Flattr this!"] = "Flattr это!";
-App::$strings["Please contact your site administrator.<br />The provided API URL is not valid."] = "Пожалуйста свяжитесь с администратором сайта. <br />Предоставленный URL API недействителен.";
-App::$strings["We could not contact the GNU social API with the Path you entered."] = "Нам не удалось установить контакт с GNU Social API по введённому вами пути";
-App::$strings["GNU social settings updated."] = "Настройки GNU Social обновлены.";
-App::$strings["Relay public postings to a connected GNU social account (formerly StatusNet)"] = "Пересылает общедоступные публикации на подключённую учётную запись GNU social (бывшая StatusNet)";
-App::$strings["Globally Available GNU social OAuthKeys"] = "Глобально доступные ключи OAuthKeys GNU Social";
-App::$strings["There are preconfigured OAuth key pairs for some GNU social servers available. If you are using one of them, please use these credentials.<br />If not feel free to connect to any other GNU social instance (see below)."] = "Существуют предварительно настроенные пары ключей OAuth для некоторых доступных серверов GNU social. Если вы используете один из них, используйте эти учетные данные. <br />Если вы не хотите подключаться к какому-либо другому серверу GNU social (см. ниже).";
-App::$strings["Provide your own OAuth Credentials"] = "Предоставьте ваши собственные регистрационные данные OAuth";
-App::$strings["No consumer key pair for GNU social found. Register your Hubzilla Account as an desktop client on your GNU social account, copy the consumer key pair here and enter the API base root.<br />Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Hubzilla installation at your favourite GNU social installation."] = "Не найдена пользовательская пара ключей для GNU social. Зарегистрируйте свою учетную запись Hubzilla в качестве настольного клиента в своей учетной записи GNU social, скопируйте cюда пару ключей пользователя и введите корневой каталог базы API. <br />Прежде чем регистрировать свою собственную пару ключей OAuth, спросите администратора, если ли уже пара ключей для этой установки Hubzilla в вашем GNU social.";
-App::$strings["OAuth Consumer Key"] = "Ключ клиента OAuth";
-App::$strings["OAuth Consumer Secret"] = "Пароль клиента OAuth";
-App::$strings["Base API Path"] = "Основной путь к API";
-App::$strings["Remember the trailing /"] = "Запомнить закрывающий /";
-App::$strings["GNU social application name"] = "Имя приложения GNU social";
-App::$strings["To connect to your GNU social account click the button below to get a security code from GNU social which you have to copy into the input box below and submit the form. Only your <strong>public</strong> posts will be posted to GNU social."] = "Чтобы подключиться к вашей учетной записи GNU social нажмите кнопку ниже для получения кода безопасности из GNU social, который вы должны скопировать в поле ввода ниже и отправить форму. Только ваши общедоступные сообщения будут опубликованы в GNU social.";
-App::$strings["Log in with GNU social"] = "Войти с GNU social";
-App::$strings["Copy the security code from GNU social here"] = "Скопируйте код безопасности GNU social здесь";
-App::$strings["Cancel Connection Process"] = "Отменить процесс подключения";
-App::$strings["Current GNU social API is"] = "Текущий GNU social API";
-App::$strings["Cancel GNU social Connection"] = "Отменить подключение с GNU social";
-App::$strings["Currently connected to: "] = "В настоящее время подключён к:";
-App::$strings["<strong>Note</strong>: Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to GNU social will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в GNU social, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен.";
-App::$strings["Post to GNU social by default"] = "Публиковать в GNU social по умолчанию";
-App::$strings["If enabled your public postings will be posted to the associated GNU-social account by default"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social по умолчанию";
-App::$strings["Clear OAuth configuration"] = "Очистить конфигурацию OAuth";
-App::$strings["GNU-Social Crosspost Connector"] = "Подключение пересылки публикаций GNU Social";
-App::$strings["Post to GNU social"] = "Опубликовать в GNU Social";
-App::$strings["API URL"] = "";
-App::$strings["Application name"] = "Название приложения";
-App::$strings["QR code"] = "QR-код";
-App::$strings["QR Generator"] = "Генератор QR-кодов";
-App::$strings["Enter some text"] = "Введите любой текст";
-App::$strings["Invalid game."] = "Недействительная игра.";
-App::$strings["You are not a player in this game."] = "Вы не играете в эту игру.";
-App::$strings["You must be a local channel to create a game."] = "Ваш канал должен быть локальным чтобы создать игру.";
-App::$strings["You must select one opponent that is not yourself."] = "Вы должны выбрать противника который не является вами.";
-App::$strings["Random color chosen."] = "Выбран случайный цвет.";
-App::$strings["Error creating new game."] = "Ошибка создания новой игры.";
-App::$strings["Requested channel is not available."] = "Запрошенный канал не доступен.";
-App::$strings["Chess not installed."] = "Шахматы не установлены.";
-App::$strings["You must select a local channel /chess/channelname"] = "Вы должны выбрать локальный канал /chess/channelname";
-App::$strings["Enable notifications"] = "Включить оповещения";
-App::$strings["Twitter settings updated."] = "Настройки Twitter обновлены";
-App::$strings["Twitter Crosspost Connector App"] = "Приложение \"Пересылка публикаций Twitter\"";
-App::$strings["Relay public posts to Twitter"] = "Пересылает общедоступные публикации в Twitter";
-App::$strings["No consumer key pair for Twitter found. Please contact your site administrator."] = "Не найдено пары ключей для Twitter. Пожалуйста, свяжитесь с администратором сайта.";
-App::$strings["At this Hubzilla instance the Twitter plugin was enabled but you have not yet connected your account to your Twitter account. To do so click the button below to get a PIN from Twitter which you have to copy into the input box below and submit the form. Only your <strong>public</strong> posts will be posted to Twitter."] = "В этой установке Hubzilla плагин Twitter был включён, однако пока он не подключён к вашему аккаунту в Twitter. Для этого нажмите на кнопку ниже для получения PIN-кода от Twitter который нужно скопировать в поле ввода и отправить форму. Только ваши <strong>общедоступные</strong> публикации будут опубликованы в Twitter.";
-App::$strings["Log in with Twitter"] = "Войти в Twitter";
-App::$strings["Copy the PIN from Twitter here"] = "Скопируйте PIN-код из Twitter здесь";
-App::$strings["<strong>Note:</strong> Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to Twitter will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в Twitter, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен.";
-App::$strings["Twitter post length"] = "Длина публикации Twitter";
-App::$strings["Maximum tweet length"] = "Максимальная длина твита";
-App::$strings["Send public postings to Twitter by default"] = "Отправлять общедоступные публикации в Twitter по умолчанию";
-App::$strings["If enabled your public postings will be posted to the associated Twitter account by default"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи Twitter по умолчанию";
-App::$strings["Twitter Crosspost Connector"] = "Пересылка публикаций Twitter";
-App::$strings["Post to Twitter"] = "Опубликовать в Twitter";
-App::$strings["Smileybutton App"] = "Приложение \"Кнопка со смайликам\"";
-App::$strings["Adds a smileybutton to the jot editor"] = "Добавлять кнопку со смайликами в редактор Jot";
-App::$strings["Hide the button and show the smilies directly."] = "Скрыть кнопку и сразу показывать смайлики.";
-App::$strings["Smileybutton Settings"] = "Настройки кнопки со смайликами";
-App::$strings["Enable Test Catalog"] = "Включить тестовый каталог";
-App::$strings["Enable Manual Payments"] = "Включить ручные платежи";
-App::$strings["Base Merchant Currency"] = "Основная торговая валюта";
-App::$strings["Cart Settings"] = "Настройки карточек";
-App::$strings["Access Denied."] = "Доступ запрещён.";
-App::$strings["Order Not Found"] = "Заказ не найден";
-App::$strings["Invalid Item"] = "Недействительный элемент";
-App::$strings["DB Cleanup Failure"] = "Сбой очистки базы данных";
-App::$strings["[cart] Item Added"] = "[cart] Элемент добавлен";
-App::$strings["Order already checked out."] = "Заказ уже проверен.";
-App::$strings["Drop database tables when uninstalling."] = "Сбросить таблицы базы данных при деинсталляции";
-App::$strings["Shop"] = "Магазин";
-App::$strings["Cart utilities for orders and payments"] = "Утилиты карточек для заказов и платежей";
-App::$strings["You must be logged into the Grid to shop."] = "Вы должны быть в сети для доступа к магазину";
-App::$strings["Order not found."] = "Заказ не найден.";
-App::$strings["Access denied."] = "Доступ запрещён.";
-App::$strings["No Order Found"] = "Нет найденных заказов";
-App::$strings["An unknown error has occurred Please start again."] = "Произошла неизвестная ошибка. Пожалуйста, начните снова.";
-App::$strings["Invalid Payment Type. Please start again."] = "Недействительный тип платежа. Пожалуйста, начните снова.";
-App::$strings["Order not found"] = "Заказ не найден";
-App::$strings["Enable Paypal Button Module"] = "Включить модуль кнопки Paypal";
-App::$strings["Use Production Key"] = "Использовать ключ Production";
-App::$strings["Paypal Sandbox Client Key"] = "Ключ клиента Paypal Sandbox";
-App::$strings["Paypal Sandbox Secret Key"] = "Секретный ключ Paypal Sandbox";
-App::$strings["Paypal Production Client Key"] = "Ключ клиента Paypal Production";
-App::$strings["Paypal Production Secret Key"] = "Секретный ключ Paypal Production";
-App::$strings["Paypal button payments are not enabled."] = "Кнопка Paypal для платежей не включена.";
-App::$strings["Paypal button payments are not properly configured. Please choose another payment option."] = "Кнопка Paypal для платежей настроена неправильно. Пожалуйста, используйте другой вариант оплаты.";
-App::$strings["Enable Manual Cart Module"] = "Включить модуль ручного управления карточками";
-App::$strings["New Sku"] = "Новый код";
-App::$strings["Cannot save edits to locked item."] = "Невозможно сохранить изменения заблокированной позиции.";
-App::$strings["Changes Locked"] = "Изменения заблокированы";
-App::$strings["Item available for purchase."] = "Позиция доступна для приобретения.";
-App::$strings["Price"] = "Цена";
-App::$strings["Enable Hubzilla Services Module"] = "Включить модуль сервиса Hubzilla";
-App::$strings["SKU not found."] = "Код не найден.";
-App::$strings["Invalid Activation Directive."] = "Недействительная директива активации.";
-App::$strings["Invalid Deactivation Directive."] = "Недействительная директива деактивации";
-App::$strings["Add to this privacy group"] = "Добавить в эту группу безопасности";
-App::$strings["Set user service class"] = "Установить класс обслуживания пользователя";
-App::$strings["You must be using a local account to purchase this service."] = "Вы должны использовать локальную учётноую запись для покупки этого сервиса.";
-App::$strings["Add buyer to privacy group"] = "Добавить покупателя в группу безопасности";
-App::$strings["Add buyer as connection"] = "Добавить покупателя как контакт";
-App::$strings["Set Service Class"] = "Установить класс обслуживания";
-App::$strings["Enable Subscription Management Module"] = "Включить модуль управления подписками";
-App::$strings["Cannot include subscription items with different terms in the same order."] = "Нельзя включать элементы подписки с разными условиями в том же заказе.";
-App::$strings["Select Subscription to Edit"] = "Выбрать подписку для редактирования";
-App::$strings["Edit Subscriptions"] = "Редактировать подписки";
-App::$strings["Subscription SKU"] = "Код подписки";
-App::$strings["Catalog Description"] = "Описание каталога";
-App::$strings["Subscription available for purchase."] = "Подписка доступна для покупки.";
-App::$strings["Maximum active subscriptions to this item per account."] = "Максимальное количество подписок на аккаунт для этой позиции";
-App::$strings["Subscription price."] = "Цена подписки.";
-App::$strings["Quantity"] = "Количество";
-App::$strings["Term"] = "Условия";
-App::$strings["Error: order mismatch. Please try again."] = "Ошибка: несоответствие заказа. Пожалуйста, попробуйте ещё раз";
-App::$strings["Manual payments are not enabled."] = "Ручные платежи не подключены.";
-App::$strings["Finished"] = "Завершено";
-App::$strings["This website is tracked using the <a href='http://www.piwik.org'>Piwik</a> analytics tool."] = "Этот сайт отслеживается с помощью инструментов аналитики <a href='http://www.piwik.org'>Piwik</a>.";
-App::$strings["If you do not want that your visits are logged this way you <a href='%s'>can set a cookie to prevent Piwik from tracking further visits of the site</a> (opt-out)."] = "Если вы не хотите, чтобы ваши визиты регистрировались таким образом, вы <a href='%s'>можете отключить cookie с тем, чтобы Piwik не отслеживал дальнейшие посещения сайта</a>.";
-App::$strings["Piwik Base URL"] = "Базовый URL Piwik";
-App::$strings["Absolute path to your Piwik installation. (without protocol (http/s), with trailing slash)"] = "Абсолютный путь к вашей установке Piwik (без типа протокола, с начальным слэшем)";
-App::$strings["Site ID"] = "ID сайта";
-App::$strings["Show opt-out cookie link?"] = "Показывать ссылку на отказ от использования cookies?";
-App::$strings["Asynchronous tracking"] = "Асинхронное отслеживание";
-App::$strings["Enable frontend JavaScript error tracking"] = "Включить отслеживание ошибок JavaScript на фронтенде.";
-App::$strings["This feature requires Piwik >= 2.2.0"] = "Эта функция требует версию Piwik >= 2.2.0";
-App::$strings["Edit your profile and change settings."] = "Отредактировать ваш профиль и изменить настройки.";
-App::$strings["Click here to see activity from your connections."] = "Нажмите сюда для отображения активности ваши контактов.";
-App::$strings["Click here to see your channel home."] = "Нажмите сюда чтобы увидеть главную страницу вашего канала.";
-App::$strings["You can access your private messages from here."] = "Вы можете получить доступ с личной переписке здесь.";
-App::$strings["Create new events here."] = "Создать новое событие здесь.";
-App::$strings["You can accept new connections and change permissions for existing ones here. You can also e.g. create groups of contacts."] = "Вы можете подключать новые контакты и менять разрешения для существующих здесь. Также вы можете создавать их группы.";
-App::$strings["System notifications will arrive here"] = "Системные оповещения будут показываться здесь";
-App::$strings["Search for content and users"] = "Поиск пользователей и содержимого";
-App::$strings["Browse for new contacts"] = "Поиск новых контактов";
-App::$strings["Launch installed apps"] = "Запустить установленные приложения";
-App::$strings["Looking for help? Click here."] = "Нужна помощь? Нажмите сюда.";
-App::$strings["New events have occurred in your network. Click here to see what has happened!"] = "Новые события произошли в вашей сети. Нажмите здесь для того, чтобы знать что случилось!";
-App::$strings["You have received a new private message. Click here to see from who!"] = "Вы получили новое личное сообщение. Нажмите чтобы увидеть от кого!";
-App::$strings["There are events this week. Click here too see which!"] = "На этой неделе есть события. Нажмите здесь чтобы увидеть какие!";
-App::$strings["You have received a new introduction. Click here to see who!"] = "Вы были представлены. Нажмите чтобы увидеть кому!";
-App::$strings["There is a new system notification. Click here to see what has happened!"] = "Это новое системное уведомление. Нажмите чтобы посмотреть что случилось!";
-App::$strings["Click here to share text, images, videos and sound."] = "Нажмите сюда чтобы поделиться текстом, изображениями, видео или треком.";
-App::$strings["You can write an optional title for your update (good for long posts)."] = "Вы можете написать необязательный заголовок для вашей публикации (желательно для больших публикаций).";
-App::$strings["Entering some categories here makes it easier to find your post later."] = "Введите категории здесь чтобы было проще найти вашу публикацию позднее.";
-App::$strings["Share photos, links, location, etc."] = "Поделиться фотографией, ссылками, местоположение и т.п.";
-App::$strings["Only want to share content for a while? Make it expire at a certain date."] = "Хотите только поделиться временным содержимым? Установите срок его действия.";
-App::$strings["You can password protect content."] = "Вы можете защитить содержимое паролем.";
-App::$strings["Choose who you share with."] = "Выбрать с кем поделиться.";
-App::$strings["Click here when you are done."] = "Нажмите здесь когда закончите.";
-App::$strings["Adjust from which channels posts should be displayed."] = "Настройте из каких каналов должны отображаться публикации.";
-App::$strings["Only show posts from channels in the specified privacy group."] = "Показывать только публикации из определённой группы безопасности.";
-App::$strings["Easily find posts containing tags (keywords preceded by the \"#\" symbol)."] = "Лёгкий поиск сообщения, содержащего теги (ключевые слова, которым предшествует символ #).";
-App::$strings["Easily find posts in given category."] = "Лёгкий поиск публикаций в данной категории.";
-App::$strings["Easily find posts by date."] = "Лёгкий поиск публикаций по дате.";
-App::$strings["Suggested users who have volounteered to be shown as suggestions, and who we think you might find interesting."] = "Рекомендуемые пользователи, которые были представлены в качестве предложений, и которые, по нашему мнению, могут оказаться интересными.";
-App::$strings["Here you see channels you have connected to."] = "Здесь вы видите каналы, к которым вы подключились.";
-App::$strings["Save your search so you can repeat it at a later date."] = "Сохраните ваш поиск с тем, чтобы повторить его позже.";
-App::$strings["If you see this icon you can be sure that the sender is who it say it is. It is normal that it is not always possible to verify the sender, so the icon will be missing sometimes. There is usually no need to worry about that."] = "Если вы видите этот значок, вы можете быть уверены, что отправитель - это тот, кто это говорит. Это нормально, что не всегда можно проверить отправителя, поэтому значок иногда будет отсутствовать. Обычно об этом не нужно беспокоиться.";
-App::$strings["Danger! It seems someone tried to forge a message! This message is not necessarily from who it says it is from!"] = "Опасность! Кажется, кто-то пытался подделать сообщение! Это сообщение не обязательно от того, от кого оно значится!";
-App::$strings["Welcome to Hubzilla! Would you like to see a tour of the UI?</p> <p>You can pause it at any time and continue where you left off by reloading the page, or navigting to another page.</p><p>You can also advance by pressing the return key"] = "Добро пожаловать в Hubzilla! Желаете получить обзор пользовательского интерфейса?</p> <p>Вы можете его приостановаить и в любое время перезагрузив страницу или перейдя на другую.</p><p>Также вы можете нажать клавишу \"Назад\"";
-App::$strings["Send your identity to all websites"] = "Отправить ваши данные на все веб-сайты";
-App::$strings["Sendzid App"] = "Приложение \"Отправить ZID\"";
-App::$strings["Send ZID"] = "Отправить ZID";
App::$strings["Three Dimensional Tic-Tac-Toe"] = "Tic-Tac-Toe в трёх измерениях";
App::$strings["3D Tic-Tac-Toe"] = "";
App::$strings["New game"] = "Новая игра";
@@ -2819,14 +3401,24 @@ App::$strings["I'm going first this time..."] = "На этот раз начин
App::$strings["You won!"] = "Вы выиграли!";
App::$strings["\"Cat\" game!"] = "Ничья!";
App::$strings["I won!"] = "Я выиграл!";
-App::$strings["pageheader Settings saved."] = "Настройки шапки страницы сохранены.";
-App::$strings["Page Header App"] = "Приложение \"Заголовок страницы\"";
-App::$strings["Inserts a page header"] = "Вставляет заголовок страницы";
-App::$strings["Message to display on every page on this server"] = "Отображаемое сообщение на каждой странице на этом сервере.";
-App::$strings["Page Header"] = "Заголовок страницы";
-App::$strings["Allow magic authentication only to websites of your immediate connections"] = "Разрешить волшебную аутентификацию только на сайтах ваших непосредственных соединений";
-App::$strings["Authchoose App"] = "Приложение Authchoose";
-App::$strings["Authchoose"] = "";
+App::$strings["Jabber BOSH host"] = "Узел Jabber BOSH";
+App::$strings["Use central userbase"] = "Использовать центральную базу данных";
+App::$strings["If enabled, members will automatically login to an ejabberd server that has to be installed on this machine with synchronized credentials via the \"auth_ejabberd.php\" script."] = "Если включено, участники автоматически войдут на сервер ejabberd, который должен быть установлен на этом компьютере с синхронизированными учетными данными через скрипт \"auth_ejabberd.php\".";
+App::$strings["XMPP settings updated."] = "Настройки XMPP обновлены.";
+App::$strings["XMPP App"] = "Приложение XMPP";
+App::$strings["Embedded XMPP (Jabber) client"] = "Встренный клиент XMPP (Jabber)";
+App::$strings["Individual credentials"] = "Индивидуальные разрешения";
+App::$strings["Jabber BOSH server"] = "Сервер Jabber BOSH";
+App::$strings["XMPP Settings"] = "Настройки XMPP";
+App::$strings["New registration"] = "Новая регистрация";
+App::$strings["Message sent to %s. New account registration: %s"] = "Сообщение отправлено в %s. Регистрация нового аккаунта: %s";
+App::$strings["Send your identity to all websites"] = "Отправить ваши данные на все веб-сайты";
+App::$strings["Sendzid App"] = "Приложение \"Отправить ZID\"";
+App::$strings["Send ZID"] = "Отправить ZID";
+App::$strings["Who likes me?"] = "Кому я нравлюсь?";
+App::$strings["Max queueworker threads"] = "Макс. количество обработчиков очереди";
+App::$strings["Assume workers dead after ___ seconds"] = "Считать обработчики неактивными через секунд";
+App::$strings["Queueworker Settings"] = "Настройки обработчика очереди";
App::$strings["lonely"] = "одинокий";
App::$strings["drunk"] = "пьяный";
App::$strings["horny"] = "возбуждённый";
@@ -2849,671 +3441,86 @@ App::$strings["victorious"] = "победивший";
App::$strings["defeated"] = "проигравший";
App::$strings["envious"] = "завидует";
App::$strings["jealous"] = "ревнует";
-App::$strings["XMPP settings updated."] = "Настройки XMPP обновлены.";
-App::$strings["XMPP App"] = "Приложение XMPP";
-App::$strings["Embedded XMPP (Jabber) client"] = "Встренный клиент XMPP (Jabber)";
-App::$strings["Individual credentials"] = "Индивидуальные разрешения";
-App::$strings["Jabber BOSH server"] = "Сервер Jabber BOSH";
-App::$strings["XMPP Settings"] = "Настройки XMPP";
-App::$strings["Jabber BOSH host"] = "Узел Jabber BOSH";
-App::$strings["Use central userbase"] = "Использовать центральную базу данных";
-App::$strings["If enabled, members will automatically login to an ejabberd server that has to be installed on this machine with synchronized credentials via the \"auth_ejabberd.php\" script."] = "Если включено, участники автоматически войдут на сервер ejabberd, который должен быть установлен на этом компьютере с синхронизированными учетными данными через скрипт \"auth_ejabberd.php\".";
-App::$strings["Who likes me?"] = "Кому я нравлюсь?";
-App::$strings["Pump.io Settings saved."] = "Настройки Pump.io сохранены.";
-App::$strings["Pump.io Crosspost Connector App"] = "Приложение \"Пересылка публикаций Pump.io\"";
-App::$strings["Relay public posts to pump.io"] = "Пересылает общедоступные публикации в Pump.io";
-App::$strings["Pump.io servername"] = "Имя сервера Pump.io";
-App::$strings["Without \"http://\" or \"https://\""] = "Без \"http://\" или \"https://\"";
-App::$strings["Pump.io username"] = "Имя пользователя Pump.io";
-App::$strings["Without the servername"] = "без имени сервера";
-App::$strings["You are not authenticated to pumpio"] = "Вы не аутентифицированы на Pump.io";
-App::$strings["(Re-)Authenticate your pump.io connection"] = "Аутентифицировать (повторно) ваше соединение с Pump.io";
-App::$strings["Post to pump.io by default"] = "Публиковать в Pump.io по умолчанию";
-App::$strings["Should posts be public"] = "Публикации должны быть общедоступными";
-App::$strings["Mirror all public posts"] = "Отображать все общедоступные публикации";
-App::$strings["Pump.io Crosspost Connector"] = "Пересылка публикаций Pump.io";
-App::$strings["You are now authenticated to pumpio."] = "Вы аутентифицированы в Pump.io";
-App::$strings["return to the featured settings page"] = "Вернутся к странице настроек";
-App::$strings["Post to Pump.io"] = "Опубликовать в Pump.io";
-App::$strings["An account has been created for you."] = "Учётная запись, которая была для вас создана.";
-App::$strings["Authentication successful but rejected: account creation is disabled."] = "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено.";
+App::$strings["Who viewed my channel/profile"] = "Кто смотрел мой канал / профиль";
+App::$strings["Recent Channel/Profile Viewers"] = "Последние просмотры канала / профиля";
+App::$strings["No entries."] = "Нет записей.";
+App::$strings["Channels to auto connect"] = "Каналы для автоматического подключения";
+App::$strings["Comma separated list"] = "Список, разделённый запятыми";
+App::$strings["Popular Channels"] = "Популярные каналы";
+App::$strings["IRC Settings"] = "Настройки IRC";
+App::$strings["IRC settings saved."] = "Настройки IRC сохранены";
+App::$strings["IRC Chatroom"] = "Чат IRC";
+App::$strings["This is a fairly comprehensive and complete guitar chord dictionary which will list most of the available ways to play a certain chord, starting from the base of the fingerboard up to a few frets beyond the twelfth fret (beyond which everything repeats). A couple of non-standard tunings are provided for the benefit of slide players, etc."] = "";
+App::$strings["Chord names start with a root note (A-G) and may include sharps (#) and flats (b). This software will parse most of the standard naming conventions such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."] = "";
+App::$strings["Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ..."] = "Примеры действительных включают A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, E7b13b11 ...";
+App::$strings["Guitar Chords"] = "Гитарные аккорды";
+App::$strings["The complete online chord dictionary"] = "Полный онлайн словарь аккордов";
+App::$strings["Tuning"] = "Настройка";
+App::$strings["Chord name: example: Em7"] = "Наименование аккорда - example: Em7";
+App::$strings["Show for left handed stringing"] = "Показывать струны для левшей";
+App::$strings["Quick Reference"] = "Быстрая ссылка";
+App::$strings["Post to Libertree"] = "Опубликовать в Libertree";
+App::$strings["Libertree Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Libertree сохранены.";
+App::$strings["Libertree Crosspost Connector App"] = "Приложение \"Пересылка публикаций Libertree\"";
+App::$strings["Relay public posts to Libertree"] = "Пересылает общедоступные публикации в Libertree";
+App::$strings["Libertree API token"] = "Токен Libertree API";
+App::$strings["Libertree site URL"] = "URL сайта Libertree";
+App::$strings["Post to Libertree by default"] = "Публиковать в Libertree по умолчанию";
+App::$strings["Libertree Crosspost Connector"] = "Пересылка публикаций Libertree";
+App::$strings["Channel is required."] = "Необходим канал.";
+App::$strings["Hubzilla Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Hubzilla сохранены.";
+App::$strings["Relay public postings to another Hubzilla channel"] = "Пересылает общедоступные публикации в другой канал Hubzilla";
+App::$strings["Send public postings to Hubzilla channel by default"] = "Отправлять общедоступные публикации в канал Hubzilla по умолчанию";
+App::$strings["Hubzilla API Path"] = "Путь к Hubzilla API";
+App::$strings["Hubzilla login name"] = "Имя входа Hubzilla";
+App::$strings["Hubzilla channel name"] = "Название канала Hubzilla";
+App::$strings["Hubzilla Crosspost Connector"] = "Пересылка публикаций Hubzilla";
+App::$strings["Post to Hubzilla"] = "Опубликовать в Hubzilla";
+App::$strings["ActivityPub Protocol Settings updated."] = "Настройки протокола ActivityPub обновлены.";
+App::$strings["The activitypub protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол ActivityPub не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
+App::$strings["Activitypub Protocol App"] = "Приложение \"Протокол ActivityPub\"";
+App::$strings["Deliver to ActivityPub recipients in privacy groups"] = "Доставить получателям ActivityPub в группах безопасности";
+App::$strings["May result in a large number of mentions and expose all the members of your privacy group"] = "Может привести к большому количеству упоминаний и раскрытию участников группы безопасности";
+App::$strings["Send multi-media HTML articles"] = "Отправить HTML статьи с мультимедиа";
+App::$strings["Not supported by some microblog services such as Mastodon"] = "Не поддерживается некоторыми микроблогами, например Mastodon";
+App::$strings["Activitypub Protocol"] = "Протокол ActivityPub";
+App::$strings["No username found in import file."] = "Имя пользователя не найдено в файле для импорта.";
+App::$strings["Diaspora Protocol Settings updated."] = "Настройки протокола Diaspora обновлены.";
+App::$strings["The diaspora protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол Diaspora не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
+App::$strings["Diaspora Protocol App"] = "Приложение \"Протокол Diaspora\"";
+App::$strings["Allow any Diaspora member to comment on your public posts"] = "Разрешить любому участнику Diaspora комментировать ваши общедоступные публикации";
+App::$strings["Prevent your hashtags from being redirected to other sites"] = "Предотвратить перенаправление тегов на другие сайты";
+App::$strings["Sign and forward posts and comments with no existing Diaspora signature"] = "Подписывать и отправлять публикации и комментарии с несуществующей подписью Diaspora";
+App::$strings["Followed hashtags (comma separated, do not include the #)"] = "Отслеживаемые теги (через запятую, исключая #)";
+App::$strings["Diaspora Protocol"] = "Протокол Diaspora";
+App::$strings["%1\$s dislikes %2\$s's %3\$s"] = "%1\$s не нравится %2\$s's %3\$s";
+App::$strings["Post to WordPress"] = "Опубликовать в WordPress";
+App::$strings["Wordpress Settings saved."] = "Настройки WordPress сохранены.";
+App::$strings["Wordpress Post App"] = "Приложение \"Публикация в Wordpress\"";
+App::$strings["Post to WordPress or anything else which uses the wordpress XMLRPC API"] = "Опубликовать в WordPress или в чём-то ещё, поддерживающем wordpress XMLRPC API";
+App::$strings["WordPress username"] = "Имя пользователя WordPress";
+App::$strings["WordPress password"] = "Пароль WordPress";
+App::$strings["WordPress API URL"] = "URL API WordPress";
+App::$strings["Typically https://your-blog.tld/xmlrpc.php"] = "Обычно https://your-blog.tld/xmlrpc.php";
+App::$strings["WordPress blogid"] = "";
+App::$strings["For multi-user sites such as wordpress.com, otherwise leave blank"] = "Для многопользовательских сайтов, таких, как wordpress.com. В противном случае оставьте пустым";
+App::$strings["Post to WordPress by default"] = "Публиковать в WordPress по умолчанию";
+App::$strings["Forward comments (requires hubzilla_wp plugin)"] = "Пересылать комментарии (требуется плагин hubzilla_wp)";
+App::$strings["Wordpress Post"] = "Публикация в WordPress";
+App::$strings["Possible adult content"] = "Возможно содержимое для взрослых";
+App::$strings["%s - view"] = "%s - просмотр";
+App::$strings["NSFW Settings saved."] = "Настройки NSFW сохранены.";
+App::$strings["NSFW App"] = "Приложение NSFW";
+App::$strings["Collapse content that contains predefined words"] = "Свернуть содержимое, содержащее предопределенные слова";
+App::$strings["This app looks in posts for the words/text you specify below, and collapses any content containing those keywords so it is not displayed at inappropriate times, such as sexual innuendo that may be improper in a work setting. It is polite and recommended to tag any content containing nudity with #NSFW. This filter can also match any other word/text you specify, and can thereby be used as a general purpose content filter."] = "Это приложение просматривает публикации для слов / текста, которые вы указываете ниже, и сворачивает любой контент, содержащий эти ключевые слова, поэтому он не отображается в неподходящее время, например, сексуальные инсинуации, которые могут быть неправильными в настройке работы. Например, мы рекомендуем отмечать любой контент, содержащий наготу, тегом #NSFW. Этот фильтр также способен реагировать на любое другое указанное вами слово / текст и может использоваться в качестве фильтра содержимого общего назначения.";
+App::$strings["Comma separated list of keywords to hide"] = "Список ключевых слов для скрытия, через запятую";
+App::$strings["Word, /regular-expression/, lang=xx, lang!=xx"] = "слово, /регулярное_выражение/, lang=xx, lang!=xx";
+App::$strings["NSFW"] = "";
+App::$strings["Skeleton App"] = "Приложение \"Скелет\"";
+App::$strings["A skeleton for addons, you can copy/paste"] = "Скелет для приложений. Вы можете использовать copy/paste";
+App::$strings["Some setting"] = "Некоторые настройки";
+App::$strings["A setting"] = "Настройка";
+App::$strings["Skeleton Settings"] = "Настройки скелета";
App::$strings["__ctx:opensearch__ Search %1\$s (%2\$s)"] = "Искать %1\$s (%2\$s)";
App::$strings["__ctx:opensearch__ \$Projectname"] = "";
App::$strings["Search \$Projectname"] = "Поиск \$Projectname";
-App::$strings["Redmatrix File Storage Import"] = "Импорт файлового хранилища Redmatrix";
-App::$strings["This will import all your Redmatrix cloud files to this channel."] = "Это позволит импортировать все ваши файлы в Redmatrix в этот канал.";
-App::$strings["file"] = "файл";
-App::$strings["Send email to all members"] = "Отправить email всем участникам";
-App::$strings["%1\$d of %2\$d messages sent."] = "%1\$d из %2\$d сообщений отправлено.";
-App::$strings["Send email to all hub members."] = "Отправить email всем участникам узла.";
-App::$strings["Sender Email address"] = "Адрес электронной почты отправителя";
-App::$strings["Test mode (only send to hub administrator)"] = "Тестовый режим (отправка только администратору узла)";
-App::$strings["Profile to assign new connections"] = "Назначить профиль для новых контактов";
-App::$strings["Frequently"] = "Часто";
-App::$strings["Hourly"] = "Ежечасно";
-App::$strings["Twice daily"] = "Дважды в день";
-App::$strings["Daily"] = "Ежедневно";
-App::$strings["Weekly"] = "Еженедельно";
-App::$strings["Monthly"] = "Ежемесячно";
-App::$strings["Currently Male"] = "В настоящее время мужской";
-App::$strings["Currently Female"] = "В настоящее время женский";
-App::$strings["Mostly Male"] = "В основном мужской";
-App::$strings["Mostly Female"] = "В основном женский";
-App::$strings["Transgender"] = "Трансгендер";
-App::$strings["Intersex"] = "Интерсексуал";
-App::$strings["Transsexual"] = "Транссексуал";
-App::$strings["Hermaphrodite"] = "Гермафродит";
-App::$strings["Neuter"] = "Среднего рода";
-App::$strings["Non-specific"] = "Неспецифический";
-App::$strings["Undecided"] = "Не решил";
-App::$strings["Males"] = "Мужчины";
-App::$strings["Females"] = "Женщины";
-App::$strings["Gay"] = "Гей";
-App::$strings["Lesbian"] = "Лесбиянка";
-App::$strings["No Preference"] = "Без предпочтений";
-App::$strings["Bisexual"] = "Бисексуал";
-App::$strings["Autosexual"] = "Автосексуал";
-App::$strings["Abstinent"] = "Воздержание";
-App::$strings["Virgin"] = "Девственник";
-App::$strings["Deviant"] = "Отклоняющийся от нормы";
-App::$strings["Fetish"] = "Фетишист";
-App::$strings["Oodles"] = "Множественный";
-App::$strings["Nonsexual"] = "Асексуал";
-App::$strings["Single"] = "Одиночка";
-App::$strings["Lonely"] = "Одинокий";
-App::$strings["Available"] = "Свободен";
-App::$strings["Unavailable"] = "Занят";
-App::$strings["Has crush"] = "Влюблён";
-App::$strings["Infatuated"] = "без ума";
-App::$strings["Dating"] = "Встречаюсь";
-App::$strings["Unfaithful"] = "Неверный";
-App::$strings["Sex Addict"] = "Эротоман";
-App::$strings["Friends/Benefits"] = "Друзья / Выгоды";
-App::$strings["Casual"] = "Легкомысленный";
-App::$strings["Engaged"] = "Помолвлен";
-App::$strings["Married"] = "В браке";
-App::$strings["Imaginarily married"] = "В воображаемом браке";
-App::$strings["Partners"] = "Партнёрство";
-App::$strings["Cohabiting"] = "Сожительствующие";
-App::$strings["Common law"] = "Гражданский брак";
-App::$strings["Happy"] = "Счастлив";
-App::$strings["Not looking"] = "Не нуждаюсь";
-App::$strings["Swinger"] = "Свингер";
-App::$strings["Betrayed"] = "Предан";
-App::$strings["Separated"] = "Разделён";
-App::$strings["Unstable"] = "Нестабильно";
-App::$strings["Divorced"] = "В разводе";
-App::$strings["Imaginarily divorced"] = "В воображаемом разводе";
-App::$strings["Widowed"] = "Вдовец / вдова";
-App::$strings["Uncertain"] = "Неопределенный";
-App::$strings["It's complicated"] = "Это сложно";
-App::$strings["Don't care"] = "Всё равно";
-App::$strings["Ask me"] = "Спроси меня";
-App::$strings["likes %1\$s's %2\$s"] = "Нравится %1\$s %2\$s";
-App::$strings["doesn't like %1\$s's %2\$s"] = "Не нравится %1\$s %2\$s";
-App::$strings["%1\$s is now connected with %2\$s"] = "%1\$s теперь в контакте с %2\$s";
-App::$strings["%1\$s poked %2\$s"] = "%1\$s ткнул %2\$s";
-App::$strings["poked"] = "ткнут";
-App::$strings["View %s's profile @ %s"] = "Просмотреть профиль %s @ %s";
-App::$strings["Categories:"] = "Категории:";
-App::$strings["Filed under:"] = "Хранить под:";
-App::$strings["View in context"] = "Показать в контексте";
-App::$strings["remove"] = "удалить";
-App::$strings["Loading..."] = "Загрузка...";
-App::$strings["Delete Selected Items"] = "Удалить выбранные элементы";
-App::$strings["View Source"] = "Просмотреть источник";
-App::$strings["Follow Thread"] = "Следить за темой";
-App::$strings["Unfollow Thread"] = "Прекратить отслеживать тему";
-App::$strings["Edit Connection"] = "Редактировать контакт";
-App::$strings["Message"] = "Сообщение";
-App::$strings["%s likes this."] = "%s нравится это.";
-App::$strings["%s doesn't like this."] = "%s не нравится это.";
-App::$strings["<span %1\$s>%2\$d people</span> like this."] = array(
- 0 => "<span %1\$s>%2\$d человеку</span> это нравится.",
- 1 => "<span %1\$s>%2\$d человекам</span> это нравится.",
- 2 => "<span %1\$s>%2\$d человекам</span> это нравится.",
-);
-App::$strings["<span %1\$s>%2\$d people</span> don't like this."] = array(
- 0 => "<span %1\$s>%2\$d человеку</span> это не нравится.",
- 1 => "<span %1\$s>%2\$d человекам</span> это не нравится.",
- 2 => "<span %1\$s>%2\$d человекам</span> это не нравится.",
-);
-App::$strings["and"] = "и";
-App::$strings[", and %d other people"] = array(
- 0 => ", и ещё %d человеку",
- 1 => ", и ещё %d человекам",
- 2 => ", и ещё %d человекам",
-);
-App::$strings["%s like this."] = "%s нравится это.";
-App::$strings["%s don't like this."] = "%s не нравится это.";
-App::$strings["__ctx:noun__ Attending"] = array(
- 0 => "Посетит",
- 1 => "Посетят",
- 2 => "Посетят",
-);
-App::$strings["__ctx:noun__ Not Attending"] = array(
- 0 => "Не посетит",
- 1 => "Не посетят",
- 2 => "Не посетят",
-);
-App::$strings["__ctx:noun__ Undecided"] = "Не решил";
-App::$strings["__ctx:noun__ Agree"] = array(
- 0 => "Согласен",
- 1 => "Согласны",
- 2 => "Согласны",
-);
-App::$strings["__ctx:noun__ Disagree"] = array(
- 0 => "Не согласен",
- 1 => "Не согласны",
- 2 => "Не согласны",
-);
-App::$strings["__ctx:noun__ Abstain"] = array(
- 0 => "Воздержался",
- 1 => "Воздержались",
- 2 => "Воздержались",
-);
-App::$strings["%1\$s's bookmarks"] = "Закладки пользователя %1\$s";
-App::$strings["Unable to import a removed channel."] = "Невозможно импортировать удалённый канал.";
-App::$strings["Cannot create a duplicate channel identifier on this system. Import failed."] = "Не удалось создать дублирующийся идентификатор канала. Импорт невозможен.";
-App::$strings["Cloned channel not found. Import failed."] = "Клон канала не найден. Импорт невозможен.";
-App::$strings["prev"] = "предыдущий";
-App::$strings["first"] = "первый";
-App::$strings["last"] = "последний";
-App::$strings["next"] = "следующий";
-App::$strings["older"] = "старше";
-App::$strings["newer"] = "новее";
-App::$strings["No connections"] = "Нет контактов";
-App::$strings["View all %s connections"] = "Просмотреть все %s контактов";
-App::$strings["Network: %s"] = "Сеть: %s";
-App::$strings["poke"] = "Ткнуть";
-App::$strings["ping"] = "Пингануть";
-App::$strings["pinged"] = "Отпингован";
-App::$strings["prod"] = "Подтолкнуть";
-App::$strings["prodded"] = "Подтолкнут";
-App::$strings["slap"] = "Шлёпнуть";
-App::$strings["slapped"] = "Шлёпнут";
-App::$strings["finger"] = "Указать";
-App::$strings["fingered"] = "Указан";
-App::$strings["rebuff"] = "Дать отпор";
-App::$strings["rebuffed"] = "Дан отпор";
-App::$strings["happy"] = "счастливый";
-App::$strings["sad"] = "грустный";
-App::$strings["mellow"] = "спокойный";
-App::$strings["tired"] = "усталый";
-App::$strings["perky"] = "весёлый";
-App::$strings["angry"] = "сердитый";
-App::$strings["stupefied"] = "отупевший";
-App::$strings["puzzled"] = "недоумевающий";
-App::$strings["interested"] = "заинтересованный";
-App::$strings["bitter"] = "едкий";
-App::$strings["cheerful"] = "бодрый";
-App::$strings["alive"] = "энергичный";
-App::$strings["annoyed"] = "раздражённый";
-App::$strings["anxious"] = "обеспокоенный";
-App::$strings["cranky"] = "капризный";
-App::$strings["disturbed"] = "встревоженный";
-App::$strings["frustrated"] = "разочарованный";
-App::$strings["depressed"] = "подавленный";
-App::$strings["motivated"] = "мотивированный";
-App::$strings["relaxed"] = "расслабленный";
-App::$strings["surprised"] = "удивленный";
-App::$strings["Monday"] = "Понедельник";
-App::$strings["Tuesday"] = "Вторник";
-App::$strings["Wednesday"] = "Среда";
-App::$strings["Thursday"] = "Четверг";
-App::$strings["Friday"] = "Пятница";
-App::$strings["Saturday"] = "Суббота";
-App::$strings["Sunday"] = "Воскресенье";
-App::$strings["January"] = "Январь";
-App::$strings["February"] = "Февраль";
-App::$strings["March"] = "Март";
-App::$strings["April"] = "Апрель";
-App::$strings["May"] = "Май";
-App::$strings["June"] = "Июнь";
-App::$strings["July"] = "Июль";
-App::$strings["August"] = "Август";
-App::$strings["September"] = "Сентябрь";
-App::$strings["October"] = "Октябрь";
-App::$strings["November"] = "Ноябрь";
-App::$strings["December"] = "Декабрь";
-App::$strings["Unknown Attachment"] = "Неизвестное вложение";
-App::$strings["unknown"] = "неизвестный";
-App::$strings["remove category"] = "удалить категорию";
-App::$strings["remove from file"] = "удалить из файла";
-App::$strings["Download binary/encrypted content"] = "Загрузить двоичное / зашифрованное содержимое";
-App::$strings["default"] = "по умолчанию";
-App::$strings["Page layout"] = "Шаблон страницы";
-App::$strings["You can create your own with the layouts tool"] = "Вы можете создать свой собственный с помощью инструмента шаблонов";
-App::$strings["HTML"] = "";
-App::$strings["Comanche Layout"] = "Шаблон Comanche";
-App::$strings["PHP"] = "";
-App::$strings["Page content type"] = "Тип содержимого страницы";
-App::$strings["activity"] = "активность";
-App::$strings["a-z, 0-9, -, and _ only"] = "Только a-z, 0-9, -, и _";
-App::$strings["Design Tools"] = "Инструменты дизайна";
-App::$strings["Pages"] = "Страницы";
-App::$strings["Import website..."] = "Импорт веб-сайта...";
-App::$strings["Select folder to import"] = "Выбрать каталог для импорта";
-App::$strings["Import from a zipped folder:"] = "Импортировать из каталога в zip-архиве:";
-App::$strings["Import from cloud files:"] = "Импортировать из сетевых файлов:";
-App::$strings["/cloud/channel/path/to/folder"] = "";
-App::$strings["Enter path to website files"] = "Введите путь к файлам веб-сайта";
-App::$strings["Select folder"] = "Выбрать каталог";
-App::$strings["Export website..."] = "Экспорт веб-сайта...";
-App::$strings["Export to a zip file"] = "Экспортировать в ZIP файл.";
-App::$strings["website.zip"] = "";
-App::$strings["Enter a name for the zip file."] = "Введите имя для ZIP файла.";
-App::$strings["Export to cloud files"] = "Эскпортировать в сетевые файлы:";
-App::$strings["/path/to/export/folder"] = "";
-App::$strings["Enter a path to a cloud files destination."] = "Введите путь к расположению сетевых файлов.";
-App::$strings["Specify folder"] = "Указать каталог";
-App::$strings["%d invitation available"] = array(
- 0 => "доступно %d приглашение",
- 1 => "доступны %d приглашения",
- 2 => "доступны %d приглашений",
-);
-App::$strings["Find Channels"] = "Поиск каналов";
-App::$strings["Enter name or interest"] = "Впишите имя или интерес";
-App::$strings["Connect/Follow"] = "Подключить / отслеживать";
-App::$strings["Examples: Robert Morgenstein, Fishing"] = "Примеры: Владимир Ильич, Революционер";
-App::$strings["Random Profile"] = "Случайный профиль";
-App::$strings["Invite Friends"] = "Пригласить друзей";
-App::$strings["Advanced example: name=fred and country=iceland"] = "Расширенный пример: name=ivan and country=russia";
-App::$strings["Common Connections"] = "Общие контакты";
-App::$strings["View all %d common connections"] = "Просмотреть все %d общих контактов";
-App::$strings["%1\$s wrote the following %2\$s %3\$s"] = "%1\$s была создана %2\$s %3\$s";
-App::$strings["Channel is blocked on this site."] = "Канал блокируется на этом сайте.";
-App::$strings["Channel location missing."] = "Местоположение канала отсутствует.";
-App::$strings["Response from remote channel was incomplete."] = "Ответ удаленного канала неполный.";
-App::$strings["Premium channel - please visit:"] = "Премимум-канал - пожалуйста посетите:";
-App::$strings["Channel was deleted and no longer exists."] = "Канал удален и больше не существует.";
-App::$strings["Remote channel or protocol unavailable."] = "Удалённый канал или протокол недоступен.";
-App::$strings["Channel discovery failed."] = "Не удалось обнаружить канал.";
-App::$strings["Protocol disabled."] = "Протокол отключен.";
-App::$strings["Cannot connect to yourself."] = "Нельзя подключиться к самому себе.";
-App::$strings["Delete this item?"] = "Удалить этот элемент?";
-App::$strings["%s show less"] = "%s показать меньше";
-App::$strings["%s expand"] = "%s развернуть";
-App::$strings["%s collapse"] = "%s свернуть";
-App::$strings["Password too short"] = "Пароль слишком короткий";
-App::$strings["Passwords do not match"] = "Пароли не совпадают";
-App::$strings["everybody"] = "все";
-App::$strings["Secret Passphrase"] = "Тайный пароль";
-App::$strings["Passphrase hint"] = "Подсказка для пароля";
-App::$strings["Notice: Permissions have changed but have not yet been submitted."] = "Уведомление: Права доступа изменились, но до сих пор не сохранены.";
-App::$strings["close all"] = "закрыть все";
-App::$strings["Nothing new here"] = "Здесь нет ничего нового";
-App::$strings["Rate This Channel (this is public)"] = "Оценкa этoго канала (общедоступно)";
-App::$strings["Describe (optional)"] = "Охарактеризовать (необязательно)";
-App::$strings["Please enter a link URL"] = "Пожалуйста, введите URL ссылки";
-App::$strings["Unsaved changes. Are you sure you wish to leave this page?"] = "Есть несохраненные изменения. Вы уверены, что хотите покинуть эту страницу?";
-App::$strings["lovely"] = "прекрасно";
-App::$strings["wonderful"] = "замечательно";
-App::$strings["fantastic"] = "фантастично";
-App::$strings["great"] = "отлично";
-App::$strings["Your chosen nickname was either already taken or not valid. Please use our suggestion ("] = "Выбранный вами псевдоним уже используется или недействителен. Попробуйте использовать наше предложение (";
-App::$strings[") or enter a new one."] = ") или введите новый.";
-App::$strings["Thank you, this nickname is valid."] = "Спасибо, этот псевдоним может быть использован.";
-App::$strings["A channel name is required."] = "Требуется название канала.";
-App::$strings["This is a "] = "Это ";
-App::$strings[" channel name"] = " название канала";
-App::$strings["%d minutes"] = array(
- 0 => "%d минуту",
- 1 => "%d минуты",
- 2 => "%d минут",
-);
-App::$strings["about %d hours"] = array(
- 0 => "около %d часa",
- 1 => "около %d часов",
- 2 => "около %d часов",
-);
-App::$strings["%d days"] = array(
- 0 => "%d день",
- 1 => "%d дня",
- 2 => "%d дней",
-);
-App::$strings["%d months"] = array(
- 0 => "%d месяц",
- 1 => "%d месяца",
- 2 => "%d месяцев",
-);
-App::$strings["%d years"] = array(
- 0 => "%d год",
- 1 => "%d года",
- 2 => "%d лет",
-);
-App::$strings["timeago.prefixAgo"] = "";
-App::$strings["timeago.prefixFromNow"] = "через";
-App::$strings["timeago.suffixAgo"] = "назад";
-App::$strings["timeago.suffixFromNow"] = "";
-App::$strings["less than a minute"] = "менее чем одну минуту";
-App::$strings["about a minute"] = "около минуты";
-App::$strings["about an hour"] = "около часа";
-App::$strings["a day"] = "день";
-App::$strings["about a month"] = "около месяца";
-App::$strings["about a year"] = "около года";
-App::$strings[" "] = " ";
-App::$strings["timeago.numbers"] = "";
-App::$strings["__ctx:long__ May"] = "Май";
-App::$strings["Jan"] = "Янв";
-App::$strings["Feb"] = "Фев";
-App::$strings["Mar"] = "Мар";
-App::$strings["Apr"] = "Апр";
-App::$strings["__ctx:short__ May"] = "Май";
-App::$strings["Jun"] = "Июн";
-App::$strings["Jul"] = "Июл";
-App::$strings["Aug"] = "Авг";
-App::$strings["Sep"] = "Сен";
-App::$strings["Oct"] = "Окт";
-App::$strings["Nov"] = "Ноя";
-App::$strings["Dec"] = "Дек";
-App::$strings["Sun"] = "Вск";
-App::$strings["Mon"] = "Пон";
-App::$strings["Tue"] = "Вт";
-App::$strings["Wed"] = "Ср";
-App::$strings["Thu"] = "Чет";
-App::$strings["Fri"] = "Пят";
-App::$strings["Sat"] = "Суб";
-App::$strings["__ctx:calendar__ today"] = "сегодня";
-App::$strings["__ctx:calendar__ month"] = "месяц";
-App::$strings["__ctx:calendar__ week"] = "неделя";
-App::$strings["__ctx:calendar__ day"] = "день";
-App::$strings["__ctx:calendar__ All day"] = "Весь день";
-App::$strings["Unable to determine sender."] = "Невозможно определить отправителя.";
-App::$strings["No recipient provided."] = "Получатель не предоставлен.";
-App::$strings["[no subject]"] = "[без темы]";
-App::$strings["Stored post could not be verified."] = "Сохранённая публикация не может быть проверена.";
-App::$strings[" and "] = " и ";
-App::$strings["public profile"] = "общедоступный профиль";
-App::$strings["%1\$s changed %2\$s to &ldquo;%3\$s&rdquo;"] = "%1\$s изменил %2\$s на &ldquo;%3\$s&rdquo;";
-App::$strings["Visit %1\$s's %2\$s"] = "Посетить %1\$s %2\$s";
-App::$strings["%1\$s has an updated %2\$s, changing %3\$s."] = "%1\$s обновлено %2\$s, изменено %3\$s.";
-App::$strings["Item was not found."] = "Элемент не найден.";
-App::$strings["Unknown error."] = "Неизвестная ошибка.";
-App::$strings["No source file."] = "Нет исходного файла.";
-App::$strings["Cannot locate file to replace"] = "Не удается найти файл для замены";
-App::$strings["Cannot locate file to revise/update"] = "Не удается найти файл для пересмотра / обновления";
-App::$strings["File exceeds size limit of %d"] = "Файл превышает предельный размер %d";
-App::$strings["You have reached your limit of %1$.0f Mbytes attachment storage."] = "Вы достигли предела %1$.0f Мбайт для хранения вложений.";
-App::$strings["File upload failed. Possible system limit or action terminated."] = "Загрузка файла не удалась. Возможно система перегружена или попытка прекращена.";
-App::$strings["Stored file could not be verified. Upload failed."] = "Файл для сохранения не может быть проверен. Загрузка не удалась.";
-App::$strings["Path not available."] = "Путь недоступен.";
-App::$strings["Empty pathname"] = "Пустое имя пути";
-App::$strings["duplicate filename or path"] = "дублирующееся имя файла или пути";
-App::$strings["Path not found."] = "Путь не найден.";
-App::$strings["mkdir failed."] = "mkdir не удался";
-App::$strings["database storage failed."] = "ошибка при записи базы данных.";
-App::$strings["Empty path"] = "Пустое имя пути";
-App::$strings["The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."] = "Не верный токен безопасности для формы. Вероятно, это произошло потому, что форма была открыта слишком долго (> 3-х часов) перед его отправкой.";
-App::$strings["(Unknown)"] = "(Неизвестный)";
-App::$strings["Visible to anybody on the internet."] = "Виден всем в интернете.";
-App::$strings["Visible to you only."] = "Видно только вам.";
-App::$strings["Visible to anybody in this network."] = "Видно всем в этой сети.";
-App::$strings["Visible to anybody authenticated."] = "Видно всем аутентифицированным.";
-App::$strings["Visible to anybody on %s."] = "Видно всем в %s.";
-App::$strings["Visible to all connections."] = "Видно всем контактам.";
-App::$strings["Visible to approved connections."] = "Видно только одобренным контактам.";
-App::$strings["Visible to specific connections."] = "Видно указанным контактам.";
-App::$strings["Privacy group is empty."] = "Группа безопасности пуста";
-App::$strings["Privacy group: %s"] = "Группа безопасности: %s";
-App::$strings["Connection not found."] = "Контакт не найден.";
-App::$strings["profile photo"] = "Фотография профиля";
-App::$strings["[Edited %s]"] = "[Отредактировано %s]";
-App::$strings["__ctx:edit_activity__ Post"] = "Публикация";
-App::$strings["__ctx:edit_activity__ Comment"] = "Комментарий";
-App::$strings["Unable to obtain identity information from database"] = "Невозможно получить идентификационную информацию из базы данных";
-App::$strings["Empty name"] = "Пустое имя";
-App::$strings["Name too long"] = "Слишком длинное имя";
-App::$strings["No account identifier"] = "Идентификатор аккаунта отсутствует";
-App::$strings["Nickname is required."] = "Требуется псевдоним.";
-App::$strings["Unable to retrieve created identity"] = "Не удается получить созданный идентификатор";
-App::$strings["Default Profile"] = "Профиль по умолчанию";
-App::$strings["Unable to retrieve modified identity"] = "Не удается найти изменённый идентификатор";
-App::$strings["Create New Profile"] = "Создать новый профиль";
-App::$strings["Visible to everybody"] = "Видно всем";
-App::$strings["Gender:"] = "Пол:";
-App::$strings["Homepage:"] = "Домашняя страница:";
-App::$strings["Online Now"] = "Сейчас в сети";
-App::$strings["Change your profile photo"] = "Изменить фотографию вашего профиля";
-App::$strings["Trans"] = "Трансексуал";
-App::$strings["Like this channel"] = "нравится этот канал";
-App::$strings["j F, Y"] = "";
-App::$strings["j F"] = "";
-App::$strings["Birthday:"] = "День рождения:";
-App::$strings["for %1\$d %2\$s"] = "для %1\$d %2\$s";
-App::$strings["Tags:"] = "Теги:";
-App::$strings["Sexual Preference:"] = "Сексуальные предпочтения:";
-App::$strings["Political Views:"] = "Политические взгляды:";
-App::$strings["Religion:"] = "Религия:";
-App::$strings["Hobbies/Interests:"] = "Хобби / интересы:";
-App::$strings["Likes:"] = "Что вам нравится:";
-App::$strings["Dislikes:"] = "Что вам не нравится:";
-App::$strings["Contact information and Social Networks:"] = "Контактная информация и социальные сети:";
-App::$strings["My other channels:"] = "Мои другие каналы:";
-App::$strings["Musical interests:"] = "Музыкальные интересы:";
-App::$strings["Books, literature:"] = "Книги, литература:";
-App::$strings["Television:"] = "Телевидение:";
-App::$strings["Film/dance/culture/entertainment:"] = "Кино / танцы / культура / развлечения:";
-App::$strings["Love/Romance:"] = "Любовь / романтика:";
-App::$strings["Work/employment:"] = "Работа / занятость:";
-App::$strings["School/education:"] = "Школа / образование:";
-App::$strings["Like this thing"] = "нравится этo";
-App::$strings["l F d, Y \\@ g:i A"] = "";
-App::$strings["Starts:"] = "Начало:";
-App::$strings["Finishes:"] = "Окончание:";
-App::$strings["This event has been added to your calendar."] = "Это событие было добавлено в ваш календарь.";
-App::$strings["Not specified"] = "Не указано";
-App::$strings["Needs Action"] = "Требует действия";
-App::$strings["Completed"] = "Завершено";
-App::$strings["In Process"] = "В процессе";
-App::$strings["Cancelled"] = "Отменено";
-App::$strings["Home, Voice"] = "Дом, голос";
-App::$strings["Home, Fax"] = "Дом, факс";
-App::$strings["Work, Voice"] = "Работа, голос";
-App::$strings["Work, Fax"] = "Работа, факс";
-App::$strings["GNU-Social"] = "";
-App::$strings["RSS/Atom"] = "";
-App::$strings["Facebook"] = "";
-App::$strings["LinkedIn"] = "";
-App::$strings["XMPP/IM"] = "";
-App::$strings["MySpace"] = "";
-App::$strings["Select an alternate language"] = "Выбор дополнительного языка";
-App::$strings["Who can see this?"] = "Кто может это видеть?";
-App::$strings["Custom selection"] = "Настраиваемый выбор";
-App::$strings["Select \"Show\" to allow viewing. \"Don't show\" lets you override and limit the scope of \"Show\"."] = "Нажмите \"Показать\" чтобы разрешить просмотр. \"Не показывать\" позволит вам переопределить и ограничить область показа.";
-App::$strings["Show"] = "Показать";
-App::$strings["Don't show"] = "Не показывать";
-App::$strings["Post permissions %s cannot be changed %s after a post is shared.</br />These permissions set who is allowed to view the post."] = "Разрешения публикации %s не могут быть изменены %s после того, как ею поделились. Эти разрешения устанавливают кому разрешено просматривать эту публикацию.";
-App::$strings["Image/photo"] = "Изображение / фотография";
-App::$strings["Encrypted content"] = "Зашифрованное содержание";
-App::$strings["Install %1\$s element %2\$s"] = "Установить %1\$s элемент %2\$s";
-App::$strings["This post contains an installable %s element, however you lack permissions to install it on this site."] = "Эта публикация содержит устанавливаемый %s элемент, однако у вас нет разрешений для его установки на этом сайте.";
-App::$strings["card"] = "карточка";
-App::$strings["article"] = "статья";
-App::$strings["Click to open/close"] = "Нажмите, чтобы открыть/закрыть";
-App::$strings["spoiler"] = "спойлер";
-App::$strings["View article"] = "Просмотр статьи";
-App::$strings["View summary"] = "Просмотр резюме";
-App::$strings["$1 wrote:"] = "$1 писал:";
-App::$strings["View PDF"] = "Просмотреть PDF";
-App::$strings[" by "] = " по ";
-App::$strings[" on "] = " на ";
-App::$strings["Embedded content"] = "Встроенное содержимое";
-App::$strings["Embedding disabled"] = "Встраивание отключено";
-App::$strings["OpenWebAuth: %1\$s welcomes %2\$s"] = "OpenWebAuth: %1\$s приветствует %2\$s";
-App::$strings["Start calendar week on Monday"] = "Начинать календарную неделю с понедельника";
-App::$strings["Default is Sunday"] = "По умолчанию - воскресенье";
-App::$strings["Search by Date"] = "Поиск по дате";
-App::$strings["Ability to select posts by date ranges"] = "Возможность выбора сообщений по диапазонам дат";
-App::$strings["Tag Cloud"] = "Облако тегов";
-App::$strings["Provide a personal tag cloud on your channel page"] = "Показывает личное облако тегов на странице канала";
-App::$strings["Use blog/list mode"] = "Использовать режим блога / списка";
-App::$strings["Comments will be displayed separately"] = "Комментарии будут отображаться отдельно";
-App::$strings["Connection Filtering"] = "Фильтрация контактов";
-App::$strings["Filter incoming posts from connections based on keywords/content"] = "Фильтр входящих сообщений от контактов на основе ключевых слов / контента";
-App::$strings["Conversation"] = "Диалоги";
-App::$strings["Community Tagging"] = "Отметки сообщества";
-App::$strings["Ability to tag existing posts"] = "Возможность помечать тегами существующие публикации";
-App::$strings["Emoji Reactions"] = "Реакции Emoji";
-App::$strings["Add emoji reaction ability to posts"] = "Возможность добавлять реакции Emoji к публикациям";
-App::$strings["Dislike Posts"] = "Не нравящиеся публикации";
-App::$strings["Ability to dislike posts/comments"] = "Возможность отмечать не нравящиеся публикации / комментарии";
-App::$strings["Star Posts"] = "Помечать сообщения";
-App::$strings["Ability to mark special posts with a star indicator"] = "Возможность отметить специальные сообщения индикатором-звёздочкой";
-App::$strings["Advanced Directory Search"] = "Расширенный поиск в каталоге";
-App::$strings["Allows creation of complex directory search queries"] = "Позволяет создание сложных поисковых запросов в каталоге";
-App::$strings["Editor"] = "Редактор";
-App::$strings["Post Categories"] = "Категории публикаций";
-App::$strings["Add categories to your posts"] = "Добавить категории для ваших публикаций";
-App::$strings["Large Photos"] = "Большие фотографии";
-App::$strings["Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails"] = "Включить большие (1024px) миниатюры изображений в публикациях. Если не включено, использовать маленькие (640px) миниатюры.";
-App::$strings["Even More Encryption"] = "Еще больше шифрования";
-App::$strings["Allow optional encryption of content end-to-end with a shared secret key"] = "Разрешить дополнительное end-to-end шифрование содержимого с общим секретным ключом";
-App::$strings["Enable Voting Tools"] = "Включить инструменты голосования";
-App::$strings["Provide a class of post which others can vote on"] = "Предоставь класс публикаций с возможностью голосования";
-App::$strings["Disable Comments"] = "Отключить комментарии";
-App::$strings["Provide the option to disable comments for a post"] = "Предоставить возможность отключать комментарии для публикаций";
-App::$strings["Delayed Posting"] = "Задержанная публикация";
-App::$strings["Allow posts to be published at a later date"] = "Разрешить размешать публикации следующими датами";
-App::$strings["Content Expiration"] = "Истечение срока действия содержимого";
-App::$strings["Remove posts/comments and/or private messages at a future time"] = "Удалять публикации / комментарии и / или личные сообщения";
-App::$strings["Suppress Duplicate Posts/Comments"] = "Подавлять дублирующие публикации / комментарии";
-App::$strings["Prevent posts with identical content to be published with less than two minutes in between submissions."] = "Предотвращает появление публикаций с одинаковым содержимым если интервал между ними менее 2 минут";
-App::$strings["Auto-save drafts of posts and comments"] = "Автоматически сохранять черновики публикаций и комментариев";
-App::$strings["Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions"] = "Автоматически сохраняет черновики публикаций и комментариев в локальном хранилище браузера для предотвращения их случайной утраты";
-App::$strings["Smart Birthdays"] = "\"Умные\" Дни рождений";
-App::$strings["Make birthday events timezone aware in case your friends are scattered across the planet."] = "Сделать уведомления о днях рождения зависимыми от часового пояса в том случае, если ваши друзья разбросаны по планете.";
-App::$strings["Event Timezone Selection"] = "Выбор часового пояса события";
-App::$strings["Allow event creation in timezones other than your own."] = "Разрешить создание события в часовой зоне отличной от вашей";
-App::$strings["Manage"] = "Управление";
-App::$strings["Navigation Channel Select"] = "Выбор канала навигации";
-App::$strings["Change channels directly from within the navigation dropdown menu"] = "Изменить канал напрямую из выпадающего меню";
-App::$strings["Save search terms for re-use"] = "Сохранять результаты поиска для повторного использования";
-App::$strings["Ability to file posts under folders"] = "Возможность размещать публикации в каталогах";
-App::$strings["Alternate Stream Order"] = "Отображение потока";
-App::$strings["Ability to order the stream by last post date, last comment date or unthreaded activities"] = "Возможность показывать поток по дате последнего сообщения, последнего комментария или в порядке поступления";
-App::$strings["Contact Filter"] = "Фильтр контактов";
-App::$strings["Ability to display only posts of a selected contact"] = "Возможность показа публикаций только от выбранных контактов";
-App::$strings["Forum Filter"] = "Фильтр по форумам";
-App::$strings["Ability to display only posts of a specific forum"] = "Возможность показа публикаций только определённого форума";
-App::$strings["Personal Posts Filter"] = "Персональный фильтр публикаций";
-App::$strings["Ability to display only posts that you've interacted on"] = "Возможность показа только тех публикаций с которыми вы взаимодействовали";
-App::$strings["Show friend and connection suggestions"] = "Показать предложения в друзья";
-App::$strings["Photo Location"] = "Местоположение фотографии";
-App::$strings["If location data is available on uploaded photos, link this to a map."] = "Если данные о местоположении доступны на загруженных фотографий, связать их с картой.";
-App::$strings["Advanced Profiles"] = "Расширенные профили";
-App::$strings["Additional profile sections and selections"] = "Дополнительные секции и выборы профиля";
-App::$strings["Profile Import/Export"] = "Импорт / экспорт профиля";
-App::$strings["Save and load profile details across sites/channels"] = "Сохранение и загрузка настроек профиля на всех сайтах / каналах";
-App::$strings["Multiple Profiles"] = "Несколько профилей";
-App::$strings["Ability to create multiple profiles"] = "Возможность создания нескольких профилей";
-App::$strings["Trending"] = "В тренде";
-App::$strings["Keywords"] = "Ключевые слова";
-App::$strings["have"] = "иметь";
-App::$strings["has"] = "есть";
-App::$strings["want"] = "хотеть";
-App::$strings["wants"] = "хотеть";
-App::$strings["likes"] = "нравится";
-App::$strings["dislikes"] = "не нравится";
-App::$strings["Not a valid email address"] = "Недействительный адрес электронной почты";
-App::$strings["Your email domain is not among those allowed on this site"] = "Домен электронной почты не входит в число тех, которые разрешены на этом сайте";
-App::$strings["Your email address is already registered at this site."] = "Ваш адрес электронной почты уже зарегистрирован на этом сайте.";
-App::$strings["An invitation is required."] = "Требуется приглашение.";
-App::$strings["Invitation could not be verified."] = "Не удалось проверить приглашение.";
-App::$strings["Please enter the required information."] = "Пожалуйста, введите необходимую информацию.";
-App::$strings["Failed to store account information."] = "Не удалось сохранить информацию аккаунта.";
-App::$strings["Registration confirmation for %s"] = "Подтверждение регистрации на %s";
-App::$strings["Registration request at %s"] = "Запрос регистрации на %s";
-App::$strings["your registration password"] = "ваш пароль регистрации";
-App::$strings["Registration details for %s"] = "Регистрационные данные для %s";
-App::$strings["Account approved."] = "Аккаунт утвержден.";
-App::$strings["Registration revoked for %s"] = "Регистрация отозвана для %s";
-App::$strings["Click here to upgrade."] = "Нажмите здесь для обновления.";
-App::$strings["This action exceeds the limits set by your subscription plan."] = "Это действие превышает ограничения, установленные в вашем плане.";
-App::$strings["This action is not available under your subscription plan."] = "Это действие невозможно из-за ограничений в вашем плане.";
-App::$strings["Birthday"] = "День рождения";
-App::$strings["Age: "] = "Возраст:";
-App::$strings["YYYY-MM-DD or MM-DD"] = "YYYY-MM-DD или MM-DD";
-App::$strings["less than a second ago"] = "менее чем одну секунду";
-App::$strings["__ctx:e.g. 22 hours ago, 1 minute ago__ %1\$d %2\$s ago"] = "%1\$d %2\$s назад";
-App::$strings["__ctx:relative_date__ year"] = array(
- 0 => "год",
- 1 => "года",
- 2 => "лет",
-);
-App::$strings["__ctx:relative_date__ month"] = array(
- 0 => "месяц",
- 1 => "месяца",
- 2 => "месяцев",
-);
-App::$strings["__ctx:relative_date__ week"] = array(
- 0 => "неделю",
- 1 => "недели",
- 2 => "недель",
-);
-App::$strings["__ctx:relative_date__ day"] = array(
- 0 => "день",
- 1 => "дня",
- 2 => "дней",
-);
-App::$strings["__ctx:relative_date__ hour"] = array(
- 0 => "час",
- 1 => "часа",
- 2 => "часов",
-);
-App::$strings["__ctx:relative_date__ minute"] = array(
- 0 => "минуту",
- 1 => "минуты",
- 2 => "минут",
-);
-App::$strings["__ctx:relative_date__ second"] = array(
- 0 => "секунду",
- 1 => "секунды",
- 2 => "секунд",
-);
-App::$strings["%1\$s's birthday"] = "У %1\$s День рождения";
-App::$strings["Happy Birthday %1\$s"] = "С Днем рождения %1\$s !";
-App::$strings["Remote authentication"] = "Удаленная аутентификация";
-App::$strings["Click to authenticate to your home hub"] = "Нажмите, чтобы аутентифицировать себя на домашнем узле";
-App::$strings["Manage your channels"] = "Управление вашими каналами";
-App::$strings["Manage your privacy groups"] = "Управление вашим группами безопасности";
-App::$strings["Account/Channel Settings"] = "Настройки аккаунта / канала";
-App::$strings["End this session"] = "Закончить эту сессию";
-App::$strings["Your profile page"] = "Страницa вашего профиля";
-App::$strings["Manage/Edit profiles"] = "Управление / редактирование профилей";
-App::$strings["Sign in"] = "Войти";
-App::$strings["Take me home"] = "Домой";
-App::$strings["Log me out of this site"] = "Выйти с этого сайта";
-App::$strings["Create an account"] = "Создать аккаунт";
-App::$strings["Help and documentation"] = "Справочная информация и документация";
-App::$strings["Search site @name, !forum, #tag, ?docs, content"] = "Искать на сайте @имя, !форум, #тег, ?документ, содержимое";
-App::$strings["Site Setup and Configuration"] = "Установка и конфигурация сайта";
-App::$strings["@name, !forum, #tag, ?doc, content"] = "@имя, !форум, #тег, ?документ, содержимое";
-App::$strings["Please wait..."] = "Подождите пожалуйста ...";
-App::$strings["Add Apps"] = "Добавить приложения";
-App::$strings["Arrange Apps"] = "Упорядочить приложения";
-App::$strings["Toggle System Apps"] = "Показать системные приложения";
-App::$strings["Status Messages and Posts"] = "Статусы и публикации";
-App::$strings["Profile Details"] = "Информация о профиле";
-App::$strings["Photo Albums"] = "Фотоальбомы";
-App::$strings["Files and Storage"] = "Файлы и хранилище";
-App::$strings["Saved Bookmarks"] = "Сохранённые закладки";
-App::$strings["View Cards"] = "Просмотреть карточки";
-App::$strings["View Articles"] = "Просмотр статей";
-App::$strings["View Webpages"] = "Просмотр веб-страниц";
-App::$strings["Image exceeds website size limit of %lu bytes"] = "Файл превышает предельный размер для сайта в %lu байт";
-App::$strings["Image file is empty."] = "Файл изображения пуст.";
-App::$strings["Photo storage failed."] = "Ошибка хранилища фотографий.";
-App::$strings["a new photo"] = "новая фотография";
-App::$strings["__ctx:photo_upload__ %1\$s posted %2\$s to %3\$s"] = "%1\$s опубликовал %2\$s в %3\$s";
-App::$strings["Upload New Photos"] = "Загрузить новые фотографии";
-App::$strings["Invalid data packet"] = "Неверный пакет данных";
-App::$strings["invalid target signature"] = "недопустимая целевая подпись";
-App::$strings["New window"] = "Новое окно";
-App::$strings["Open the selected location in a different window or browser tab"] = "Открыть выбранное местоположение в другом окне или вкладке браузера";
-App::$strings["Delegation session ended."] = "Делегированная сессия завершена.";
-App::$strings["Logged out."] = "Вышел из системы.";
-App::$strings["Email validation is incomplete. Please check your email."] = "Проверка email не завершена. Пожалуйста, проверьте вашу почту.";
-App::$strings["Failed authentication"] = "Ошибка аутентификации";
-App::$strings["Help:"] = "Помощь:";
-App::$strings["Not Found"] = "Не найдено";
diff --git a/view/tpl/cdav_calendar.tpl b/view/tpl/cdav_calendar.tpl
index b0245e853..a577e3120 100644
--- a/view/tpl/cdav_calendar.tpl
+++ b/view/tpl/cdav_calendar.tpl
@@ -1,17 +1,24 @@
<script>
-
-var new_event = [];
+var calendar;
+var new_event = {};
var new_event_id = Math.random().toString(36).substring(7);
-var views = {'month' : '{{$month}}', 'agendaWeek' : '{{$week}}', 'agendaDay' : '{{$day}}', 'listMonth' : '{{$list_month}}', 'listWeek' : '{{$list_week}}', 'listDay' : '{{$list_day}}'};
+var views = {'dayGridMonth' : '{{$month}}', 'timeGridWeek' : '{{$week}}', 'timeGridDay' : '{{$day}}', 'listMonth' : '{{$list_month}}', 'listWeek' : '{{$list_week}}', 'listDay' : '{{$list_day}}'};
$(document).ready(function() {
- $('#calendar').fullCalendar({
+ var calendarEl = document.getElementById('calendar');
+ calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
eventSources: [ {{$sources}} ],
+
+ timeZone: '{{$timezone}}',
- header: false,
- eventTextColor: 'white',
+ locale: '{{$lang}}',
- lang: '{{$lang}}',
+ eventTextColor: 'white',
+ header: false,
+
+ height: 'auto',
+
firstDay: {{$first_day}},
monthNames: aStr['monthNames'],
@@ -20,34 +27,45 @@ $(document).ready(function() {
dayNamesShort: aStr['dayNamesShort'],
allDayText: aStr['allday'],
- timeFormat: 'HH:mm',
- timezone: 'local',
-
defaultTimedEventDuration: '01:00:00',
snapDuration: '00:15:00',
+
+ dateClick: function(info) {
+ if(new_event.id) {
+ var event_poi = calendar.getEventById(new_event.id);
+ event_poi.remove();
+ new_event = {};
+ }
- dayClick: function(date, jsEvent, view) {
-
- if(new_event.length)
- $('#calendar').fullCalendar( 'removeEventSource', new_event);
+ var dtend = new Date(info.date.toUTCString());
+ if(info.view.type == 'dayGridMonth') {
+ dtend.setDate(dtend.getDate() + 1);
+ }
+ else{
+ dtend.setHours(dtend.getHours() + 1);
+ }
$('#event_uri').val('');
$('#id_title').val('New event');
$('#calendar_select').val($("#calendar_select option:first").val()).attr('disabled', false);
- $('#id_dtstart').val(date.format());
- $('#id_dtend').val(date.hasTime() ? date.add(1, 'hours').format() : date.add(1, 'days').format());
+ $('#id_dtstart').val(info.date.toUTCString());
+ $('#id_dtend').val(dtend ? dtend.toUTCString() : '');
$('#id_description').val('');
$('#id_location').val('');
$('#event_submit').val('create_event').html('Create');
$('#event_delete').hide();
- new_event = [{ id: new_event_id, title : 'New event', start: $('#id_dtstart').val(), end: $('#id_dtend').val(), editable: true, color: '#bbb' }]
- $('#calendar').fullCalendar( 'addEventSource', new_event);
+ new_event = { id: new_event_id, title : 'New event', start: $('#id_dtstart').val(), end: $('#id_dtend').val(), editable: true, color: '#bbb' };
+ calendar.addEvent(new_event);
},
-
- eventClick: function(event, jsEvent, view) {
-
- if(event.id == new_event_id) {
+
+ eventClick: function(info) {
+
+ var event = info.event._def;
+ var dtstart = new Date(info.event._instance.range.start);
+ var dtend = new Date(info.event._instance.range.end);
+
+ if(event.publicId == new_event_id) {
$(window).scrollTop(0);
$('.section-content-tools-wrapper, #event_form_wrapper').show();
$('#recurrence_warning').hide();
@@ -55,79 +73,96 @@ $(document).ready(function() {
return false;
}
- if($('main').hasClass('fullscreen') && view.type !== 'month' && event.rw)
- $('#calendar').fullCalendar('option', 'height', 'auto');
-
- if(new_event.length && event.rw) {
- $('#calendar').fullCalendar( 'removeEventSource', new_event);
+ if(new_event.id && event.extendedProps.rw) {
+ var event_poi = calendar.getEventById(new_event.id);
+ event_poi.remove();
+ new_event = {};
}
-
- if(!event.recurrent && event.rw) {
- var start_clone = moment(event.start);
- var noend_allday = start_clone.add(1, 'day').format('YYYY-MM-DD');
-
+
+ if(!event.extendedProps.recurrent) {
$(window).scrollTop(0);
$('.section-content-tools-wrapper, #event_form_wrapper').show();
$('#recurrence_warning').hide();
- $('#id_title').focus();
-
- $('#event_uri').val(event.uri);
+ $('#event_uri').val(event.extendedProps.uri);
$('#id_title').val(event.title);
- $('#calendar_select').val(event.calendar_id[0] + ':' + event.calendar_id[1]).attr('disabled', true);
- $('#id_dtstart').val(event.start.format());
- $('#id_dtend').val(event.end ? event.end.format() : event.start.hasTime() ? '' : noend_allday);
- $('#id_description').val(event.description);
- $('#id_location').val(event.location);
+ $('#calendar_select').val(event.extendedProps.calendar_id[0] + ':' + event.extendedProps.calendar_id[1]).attr('disabled', true);
+ $('#id_dtstart').val(dtstart.toUTCString());
+ $('#id_dtend').val(dtend.toUTCString());
+ $('#id_description').val(event.extendedProps.description);
+ $('#id_location').val(event.extendedProps.location);
$('#event_submit').val('update_event').html('Update');
- $('#event_delete').show();
+ if(event.extendedProps.rw) {
+ $('#event_delete').show();
+ $('#event_submit').show();
+ $('#id_title').focus();
+ $('#id_title').attr('disabled', false);
+ $('#id_dtstart').attr('disabled', false);
+ $('#id_dtend').attr('disabled', false);
+ $('#id_description').attr('disabled', false);
+ $('#id_location').attr('disabled', false);
+ }
+ else {
+ $('#event_submit').hide();
+ $('#event_delete').hide();
+ $('#id_title').attr('disabled', true);
+ $('#id_dtstart').attr('disabled', true);
+ $('#id_dtend').attr('disabled', true);
+ $('#id_description').attr('disabled', true);
+ $('#id_location').attr('disabled', true);
+ }
}
- else if(event.recurrent && event.rw) {
+ else if(event.extendedProps.recurrent && event.extendedProps.rw) {
$('.section-content-tools-wrapper, #recurrence_warning').show();
$('#event_form_wrapper').hide();
- $('#event_uri').val(event.uri);
- $('#calendar_select').val(event.calendar_id[0] + ':' + event.calendar_id[1]).attr('disabled', true);
+ $('#event_uri').val(event.extendedProps.uri);
+ $('#calendar_select').val(event.extendedProps.calendar_id[0] + ':' + event.extendedProps.calendar_id[1]).attr('disabled', true);
}
},
-
- eventResize: function(event, delta, revertFunc) {
-
+
+ eventResize: function(info) {
+
+ var event = info.event._def;
+ var dtstart = new Date(info.event._instance.range.start);
+ var dtend = new Date(info.event._instance.range.end);
+
$('#id_title').val(event.title);
- $('#id_dtstart').val(event.start.format());
- $('#id_dtend').val(event.end.format());
+ $('#id_dtstart').val(dtstart.toUTCString());
+ $('#id_dtend').val(dtend.toUTCString());
$.post( 'cdav/calendar', {
'update': 'resize',
- 'id[]': event.calendar_id,
- 'uri': event.uri,
- 'dtstart': event.start ? event.start.format() : '',
- 'dtend': event.end ? event.end.format() : ''
+ 'id[]': event.extendedProps.calendar_id,
+ 'uri': event.extendedProps.uri,
+ 'dtstart': dtstart ? dtstart.toUTCString() : '',
+ 'dtend': dtend ? dtend.toUTCString() : ''
})
.fail(function() {
- revertFunc();
+ info.revert();
});
},
+
+ eventDrop: function(info) {
- eventDrop: function(event, delta, revertFunc) {
-
- var start_clone = moment(event.start);
- var noend_allday = start_clone.add(1, 'day').format('YYYY-MM-DD');
-
+ var event = info.event._def;
+ var dtstart = new Date(info.event._instance.range.start);
+ var dtend = new Date(info.event._instance.range.end);
+
$('#id_title').val(event.title);
- $('#id_dtstart').val(event.start.format());
- $('#id_dtend').val(event.end ? event.end.format() : event.start.hasTime() ? '' : noend_allday);
-
+ $('#id_dtstart').val(dtstart.toUTCString());
+ $('#id_dtend').val(dtend.toUTCString());
+
$.post( 'cdav/calendar', {
'update': 'drop',
- 'id[]': event.calendar_id,
- 'uri': event.uri,
- 'dtstart': event.start ? event.start.format() : '',
- 'dtend': event.end ? event.end.format() : event.start.hasTime() ? '' : noend_allday
+ 'id[]': event.extendedProps.calendar_id,
+ 'uri': event.extendedProps.uri,
+ 'dtstart': dtstart ? dtstart.toUTCString() : '',
+ 'dtend': dtend ? dtend.toUTCString() : ''
})
.fail(function() {
- revertFunc();
+ info.revert();
});
},
-
+
loading: function(isLoading, view) {
$('#events-spinner').show();
$('#today-btn > i').hide();
@@ -136,82 +171,79 @@ $(document).ready(function() {
$('#today-btn > i').show();
}
}
+
});
-
- // echo the title
- var view = $('#calendar').fullCalendar('getView');
-
- $('#title').text(view.title);
-
- $('#view_selector').html(views[view.name]);
-
+
+ calendar.render();
+
+ $('#title').text(calendar.view.title);
+ $('#view_selector').html(views[calendar.view.type]);
+
+ $('#today-btn').on('click', function() {
+ calendar.today();
+ $('#title').text(calendar.view.title);
+ });
+
+ $('#prev-btn').on('click', function() {
+ calendar.prev();
+ $('#title').text(calendar.view.title);
+ });
+
+ $('#next-btn').on('click', function() {
+ calendar.next();
+ $('#title').text(calendar.view.title);
+ });
+
$('.color-edit').colorpicker({ input: '.color-edit-input' });
- $(document).on('click','#fullscreen-btn', on_fullscreen);
- $(document).on('click','#inline-btn', on_inline);
-
+ $(document).on('click','#fullscreen-btn', updateSize);
+ $(document).on('click','#inline-btn', updateSize);
$(document).on('click','#event_submit', on_submit);
$(document).on('click','#event_more', on_more);
$(document).on('click','#event_cancel, #event_cancel_recurrent', reset_form);
$(document).on('click','#event_delete, #event_delete_recurrent', on_delete);
-
});
-function changeView(action, viewName) {
- $('#calendar').fullCalendar(action, viewName);
- var view = $('#calendar').fullCalendar('getView');
-
- if($('main').hasClass('fullscreen'))
- if(view.name !== 'month')
- $('.section-content-tools-wrapper').css('display') === 'none' ? on_fullscreen() : on_inline() ;
- else
- on_fullscreen();
- else
- on_inline();
- $('#title').text(view.title);
- $('#view_selector').html(views[view.name]);
+function changeView(action, viewName) {
+ calendar.changeView(viewName);
+ $('#title').text(calendar.view.title);
+ $('#view_selector').html(views[calendar.view.type]);
+ return;
}
function add_remove_json_source(source, color, editable, status) {
+ var parts = source.split('/');
+ var id = parts[4];
+
+ var eventSource = calendar.getEventSourceById(id);
+ var selector = '#calendar-btn-' + id;
if(status === undefined)
status = 'fa-calendar-check-o';
if(status === 'drop') {
+ eventSource.remove();
reset_form();
- $('#calendar').fullCalendar( 'removeEventSource', source );
return;
}
- var parts = source.split('/');
- var id = parts[4];
-
- var selector = '#calendar-btn-' + id;
-
if($(selector).hasClass('fa-calendar-o')) {
- $('#calendar').fullCalendar( 'addEventSource', { url: source, color: color, editable: editable });
+ calendar.addEventSource({ id: id, url: source, color: color, editable: editable });
$(selector).removeClass('fa-calendar-o');
$(selector).addClass(status);
$.get('/cdav/calendar/switch/' + id + '/1');
}
else {
- $('#calendar').fullCalendar( 'removeEventSource', source );
+ eventSource.remove();
$(selector).removeClass(status);
$(selector).addClass('fa-calendar-o');
$.get('/cdav/calendar/switch/' + id + '/0');
}
}
-function on_fullscreen() {
- var view = $('#calendar').fullCalendar('getView');
- if(($('.section-content-tools-wrapper').css('display') === 'none') || ($('.section-content-tools-wrapper').css('display') !== 'none' && view.type === 'month'))
- $('#calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (.generic-content-wrapper top and bottom) of .generic-content-wrapper
-}
-
-function on_inline() {
- var view = $('#calendar').fullCalendar('getView');
- ((view.type === 'month') ? $('#calendar').fullCalendar('option', 'height', '') : $('#calendar').fullCalendar('option', 'height', 'auto'));
+function updateSize() {
+ calendar.updateSize();
}
function on_submit() {
@@ -226,8 +258,11 @@ function on_submit() {
'location': $('#id_location').val()
})
.done(function() {
- $('#calendar').fullCalendar( 'refetchEventSources', [ {{$sources}} ] );
+ var parts = $('#calendar_select').val().split(':');
+ var eventSource = calendar.getEventSourceById(parts[0]);
+ eventSource.refetch();
reset_form();
+
});
}
@@ -238,7 +273,9 @@ function on_delete() {
'uri': $('#event_uri').val(),
})
.done(function() {
- $('#calendar').fullCalendar( 'refetchEventSources', [ {{$sources}} ] );
+ var parts = $('#calendar_select').val().split(':');
+ var eventSource = calendar.getEventSourceById(parts[0]);
+ eventSource.refetch();
reset_form();
});
}
@@ -253,14 +290,14 @@ function reset_form() {
$('#id_dtstart').val('');
$('#id_dtend').val('');
- if(new_event.length)
- $('#calendar').fullCalendar( 'removeEventSource', new_event);
-
+ if(new_event.id) {
+ var event_poi = calendar.getEventById(new_event.id);
+ event_poi.remove();
+ new_event = {};
+ }
+
if($('#more_block').hasClass('open'))
on_more();
-
- if($('main').hasClass('fullscreen'))
- on_fullscreen();
}
function on_more() {
@@ -282,18 +319,18 @@ function on_more() {
<div class="dropdown">
<button id="view_selector" type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown"></button>
<div class="dropdown-menu">
- <a class="dropdown-item" href="#" onclick="changeView('changeView', 'month'); return false;">{{$month}}</a></li>
- <a class="dropdown-item" href="#" onclick="changeView('changeView', 'agendaWeek'); return false;">{{$week}}</a></li>
- <a class="dropdown-item" href="#" onclick="changeView('changeView', 'agendaDay'); return false;">{{$day}}</a></li>
+ <a class="dropdown-item" href="#" onclick="changeView('changeView', 'dayGridMonth'); return false;">{{$month}}</a></li>
+ <a class="dropdown-item" href="#" onclick="changeView('changeView', 'timeGridWeek'); return false;">{{$week}}</a></li>
+ <a class="dropdown-item" href="#" onclick="changeView('changeView', 'timeGridDay'); return false;">{{$day}}</a></li>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" onclick="changeView('changeView', 'listMonth'); return false;">{{$list_month}}</a></li>
<a class="dropdown-item" href="#" onclick="changeView('changeView', 'listWeek'); return false;">{{$list_week}}</a></li>
<a class="dropdown-item" href="#" onclick="changeView('changeView', 'listDay'); return false;">{{$list_day}}</a></li>
</div>
<div class="btn-group">
- <button class="btn btn-outline-secondary btn-sm" onclick="changeView('prev', false);" title="{{$prev}}"><i class="fa fa-backward"></i></button>
- <button id="today-btn" class="btn btn-outline-secondary btn-sm" onclick="changeView('today', false);" title="{{$today}}"><div id="events-spinner" class="spinner s"></div><i class="fa fa-bullseye" style="display: none; width: 1rem;"></i></button>
- <button class="btn btn-outline-secondary btn-sm" onclick="changeView('next', false);" title="{{$next}}"><i class="fa fa-forward"></i></button>
+ <button id="prev-btn" class="btn btn-outline-secondary btn-sm" title="{{$prev}}"><i class="fa fa-backward"></i></button>
+ <button id="today-btn" class="btn btn-outline-secondary btn-sm" title="{{$today}}"><div id="events-spinner" class="spinner s"></div><i class="fa fa-bullseye" style="display: none; width: 1rem;"></i></button>
+ <button id="next-btn" class="btn btn-outline-secondary btn-sm" title="{{$next}}"><i class="fa fa-forward"></i></button>
</div>
<button id="fullscreen-btn" type="button" class="btn btn-outline-secondary btn-sm" onclick="makeFullScreen();"><i class="fa fa-expand"></i></button>
<button id="inline-btn" type="button" class="btn btn-outline-secondary btn-sm" onclick="makeFullScreen(false);"><i class="fa fa-compress"></i></button>
diff --git a/view/tpl/event_head.tpl b/view/tpl/event_head.tpl
index 2f440e826..0e6f7523c 100755
--- a/view/tpl/event_head.tpl
+++ b/view/tpl/event_head.tpl
@@ -1,7 +1,7 @@
-<link rel='stylesheet' type='text/css' href='{{$baseurl}}/library/fullcalendar/fullcalendar.css' />
+<link rel='stylesheet' type='text/css' href='{{$baseurl}}/library/fullcalendar.old/fullcalendar.css' />
<script language="javascript" type="text/javascript" src="{{$baseurl}}/library/moment/moment.min.js"></script>
-<script language="javascript" type="text/javascript" src="{{$baseurl}}/library/fullcalendar/fullcalendar.min.js"></script>
-<script language="javascript" type="text/javascript" src="{{$baseurl}}/library/fullcalendar/locale-all.js"></script>
+<script language="javascript" type="text/javascript" src="{{$baseurl}}/library/fullcalendar.old/fullcalendar.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{$baseurl}}/library/fullcalendar.old/locale-all.js"></script>
<script>
function showEvent(eventid) {