├── images ├── diary.jpg └── images_view.gif ├── .gitignore ├── public ├── assets │ ├── images │ │ ├── load.gif │ │ ├── icons.png │ │ ├── arrow_top.png │ │ ├── post_icon.png │ │ ├── entry_more.png │ │ ├── head_arrow.png │ │ ├── search_ico.png │ │ ├── video-thumb.jpg │ │ ├── arrow_bottom.png │ │ └── attach_icons.png │ ├── lib │ │ ├── fancybox │ │ │ ├── blank.gif │ │ │ ├── fancybox_sprite.png │ │ │ ├── fancybox_loading.gif │ │ │ ├── fancybox_overlay.png │ │ │ ├── fancybox_sprite@2x.png │ │ │ ├── fancybox_loading@2x.gif │ │ │ ├── jquery.fancybox.css │ │ │ └── jquery.fancybox.pack.js │ │ ├── flowplayer │ │ │ ├── flowplayer.swf │ │ │ ├── flowplayerhls.swf │ │ │ ├── skin │ │ │ │ ├── img │ │ │ │ │ ├── black.png │ │ │ │ │ └── play_black.png │ │ │ │ └── icons │ │ │ │ │ ├── flowplayer.eot │ │ │ │ │ ├── flowplayer.ttf │ │ │ │ │ ├── flowplayer.woff │ │ │ │ │ └── flowplayer.woff2 │ │ │ ├── flowplayer.overlay.fancybox.css │ │ │ ├── index.html │ │ │ ├── flowplayer.overlay.min.js │ │ │ └── flowplayer.overlay.fancybox.js │ │ ├── jquery-ui │ │ │ ├── images │ │ │ │ ├── ui-icons_444444_256x240.png │ │ │ │ ├── ui-icons_555555_256x240.png │ │ │ │ ├── ui-icons_777620_256x240.png │ │ │ │ ├── ui-icons_777777_256x240.png │ │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ ├── jquery-ui.structure.min.css │ │ │ ├── jquery-ui.structure.css │ │ │ ├── jquery-ui.theme.min.css │ │ │ ├── jquery-ui.min.css │ │ │ └── jquery-ui.theme.css │ │ ├── remove-whitespace │ │ │ └── jquery.removeWhitespace.min.js │ │ ├── autosize │ │ │ └── autosize.js │ │ └── jquery-fileupload │ │ │ ├── jquery.iframe-transport.js │ │ │ └── jquery.ui.widget.js │ └── js │ │ ├── collagePlusPlus.js │ │ └── core.js ├── .htaccess └── index.php ├── db.php.sample ├── config.php.sample ├── modules └── App │ └── lib │ ├── App │ ├── Models │ │ ├── User.php │ │ └── Entry.php │ └── Controllers │ │ ├── Admin │ │ ├── Developer.php │ │ └── Users.php │ │ ├── Base.php │ │ ├── Auth.php │ │ ├── Entries.php │ │ ├── Cron.php │ │ └── Attachments.php │ ├── App.php │ └── CloudMailruAPI.php ├── template ├── login.php ├── layout.php └── entries.php ├── LICENSE └── README.md /images/diary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boomyjee/diary/HEAD/images/diary.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db.php 2 | config.php 3 | /cache 4 | /public/cache 5 | /public/entry_attachments -------------------------------------------------------------------------------- /images/images_view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boomyjee/diary/HEAD/images/images_view.gif -------------------------------------------------------------------------------- /public/assets/images/load.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boomyjee/diary/HEAD/public/assets/images/load.gif -------------------------------------------------------------------------------- /public/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boomyjee/diary/HEAD/public/assets/images/icons.png -------------------------------------------------------------------------------- /db.php.sample: -------------------------------------------------------------------------------- 1 | [ 5 | 'login' => 'your_login', 6 | 'password' => 'your_password', 7 | 8 | 'diary_folder' => 'your_folder_in_cloud', 9 | 'texts_file' => 'new_dnev.txt' 10 | ] 11 | ]; 12 | -------------------------------------------------------------------------------- /modules/App/lib/App/Models/User.php: -------------------------------------------------------------------------------- 1 | password = md5($password); 13 | } 14 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Admin/Developer.php: -------------------------------------------------------------------------------- 1 | synced = false; 11 | $e->save(); 12 | _D($e); 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Base.php: -------------------------------------------------------------------------------- 1 | user = $this->data['user'] = \App\Models\User::checkLoggedIn(); 10 | if ($checkUser && !$this->user) 11 | redirect('login'); 12 | } 13 | } -------------------------------------------------------------------------------- /public/assets/lib/flowplayer/flowplayer.overlay.fancybox.css: -------------------------------------------------------------------------------- 1 | .flowplayer.is-overlaid { 2 | display: none; 3 | } 4 | .flowplayer.is-overlaid.is-open { 5 | display: block; 6 | } 7 | 8 | .fancybox-flowplayer { 9 | width: 80% !important; 10 | } 11 | .fancybox-flowplayer .fancybox-inner { 12 | width: 100% !important; 13 | } 14 | .fancybox-flowplayer .flowplayer.is-loading { 15 | background-color: #333; 16 | } -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | # enable the directives - assuming they're not enabled globally 2 | ExpiresActive on 3 | 4 | # send an Expires: header for each of these mimetypes (as defined by server) 5 | ExpiresByType image/png "access plus 1 month" 6 | ExpiresByType image/gif "access plus 1 month" 7 | ExpiresByType image/jpeg "access plus 1 month" 8 | 9 | RewriteEngine on 10 | 11 | RewriteCond %{REQUEST_FILENAME} -f 12 | RewriteRule ^.*$ - [L] 13 | 14 | RewriteRule ^(.*)$ index.php?/$1 [L,QSA] 15 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | run(); -------------------------------------------------------------------------------- /public/assets/lib/flowplayer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /template/login.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |
7 |
8 | findElement('login')->render(); ?> 9 |
10 |
11 | findElement('password')->render(); ?> 12 |
13 | 14 |
15 |
16 |
17 | findElement('remember_me')->render(); ?> 18 |
19 |
20 | 21 |
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /public/assets/lib/flowplayer/flowplayer.overlay.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | Overlay plugin for Flowplayer HTML5 4 | 5 | Copyright (c) 2016, Flowplayer Oy 6 | 7 | Released under the MIT License: https://opensource.org/licenses/MIT 8 | 9 | */ 10 | !function(){var o=function(o){var e=o.common,n=o.bean;o(function(n,a){if(n.conf.overlay){n.conf.splash=n.conf.autoplay=!0,e.addClass(a,"is-overlaid"),e.addClass(a,"is-closeable");var l=n.conf.overlay.vendor||"native";if(!o.overlay[l])throw new Error('Overlay "'+l+'" not implemented');o.overlay[l](n,a)}}),o.overlay={},o.overlay.native=function(o,a){function l(){document.body.appendChild(t),e.addClass(a,"is-open")}function r(){t.parentNode&&document.body.removeChild(t),e.removeClass(a,"is-open")}var d=o.conf.overlay.trigger||o.conf.overlay,t=document.createElement("div");t.className="flowplayer-overlay-mask",t.appendChild(a);var c=function(e){e.preventDefault(),l(),o.load()};d.tagName?n.on(d,"click",c):n.on(document,"click",d,c),o.conf.keyboard&&n.on(document,"keydown",function(e){27===e.keyCode&&o.unload()}),o.on("unload",function(){r()})}};"object"==typeof module&&module.exports?module.exports=o:"function"==typeof flowplayer&&o(window.flowplayer)}(); -------------------------------------------------------------------------------- /public/assets/lib/flowplayer/flowplayer.overlay.fancybox.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | /* global flowplayer */ 3 | 4 | var $ = window.jQuery; 5 | 6 | flowplayer.overlay.fancybox = function(api, root) { 7 | var conf = api.conf.overlay 8 | , trigger = conf.trigger 9 | , closeBtn = conf.closeBtn !== false 10 | , id = $(root).attr('id') 11 | , ctrlHeight = $(root).hasClass('fixed-controls') 12 | ? $('.fp-controls', root).height() 13 | : $(root).hasClass('no-toggle') ? 0 : 4; 14 | 15 | 16 | if (!id) { 17 | id = 'flowplayer-' + Math.random().toString().slice(2); 18 | $(root).attr({id: id}); 19 | } 20 | $(root).css({marginBottom: ctrlHeight}).toggleClass('is-closeable', !closeBtn); 21 | 22 | 23 | $(trigger).fancybox({ 24 | href: '#' + id, 25 | wrapCSS: 'fancybox-flowplayer', 26 | type: 'inline', 27 | closeBtn: closeBtn, 28 | scrolling: 'no', 29 | live: false, 30 | beforeShow: function () { 31 | $(root).addClass('is-open'); 32 | if (conf.maxWidth) { 33 | $(root).closest('.fancybox-flowplayer').css({maxWidth: conf.maxWidth}); 34 | } 35 | api.load(); 36 | }, 37 | afterClose: function () { 38 | api.unload(); 39 | } 40 | }); 41 | 42 | api.on('unload', function () { 43 | $(root).removeClass('is-open'); 44 | if ($(root).parent().hasClass('fancybox-inner')) { 45 | $.fancybox.close(); 46 | } 47 | }); 48 | 49 | }; 50 | })(); 51 | -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Auth.php: -------------------------------------------------------------------------------- 1 | user) redirect('entries'); 12 | 13 | $user = $this->user; 14 | $form = new \Form('post'); 15 | $form->text('login', 'Логин', 'required', false, ['class'=>'form-control']); 16 | $form->password('password', 'Пароль', ['required', function($password) use (&$user) { 17 | $user = \App\Models\User::findOneBy(['login'=> $_POST['login']]); 18 | if ($user) { 19 | $successLogin = \App\Models\User::testLogin($user->login, $password); 20 | if ($successLogin) return $password; 21 | } 22 | throw new \ValidationException(_t('Неверный пароль')); 23 | }],false, ['class'=>'form-control']); 24 | $form->checkbox('remember_me', _t('Запомнить меня'), '', true); 25 | 26 | if ($form->validate()) { 27 | if ($user) { 28 | \App\Models\User::loginUser($user, $form->values['remember_me']); 29 | redirect('entries'); 30 | } 31 | } 32 | 33 | $this->data['login_form'] = $form; 34 | $this->view('login'); 35 | } 36 | 37 | function logout() { 38 | if ($this->user) { 39 | $this->user->logout(); 40 | } 41 | redirect('login'); 42 | } 43 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Diary 3 |

4 | 5 |

6 | license 7 | php 8 | awesome 9 | state 10 |

11 | 12 |

13 | Web application for personal user diaries. 14 |

15 | 16 | ## Description 17 | 18 | The application backs everything up to `cloud.mail.ru` for safety. 19 | 20 | Application supports media layout fine tuning: 21 | 22 | First toolbar to set the first image size. 23 | Second toolbar to set the second image size. 24 | Third toolbar to set number of rows to be shown. 25 | 26 | ![awesome image toolbar demo](images/images_view.gif) 27 | 28 | ## Installation 29 | 30 | - create an empty database 31 | - copy `db.php.sample` into `db.php` and set the database access credentials 32 | - copy `config.php.sample` into `config.php` and set access credentials to the mail.ru storage 33 | - run `/install` and enter password for 'admin' user 34 | - in `/admin` area use "admin" login and password set by you during installation 35 | - go to `/admin/app/user-list` and create a new user 36 | 37 | Now you can log in into the diary 38 | 39 | ### License 40 | 41 | Application is [MIT licensed](./LICENSE). 42 | -------------------------------------------------------------------------------- /public/assets/lib/jquery-ui/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2016-12-29 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none} -------------------------------------------------------------------------------- /template/layout.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Diary 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /modules/App/lib/App.php: -------------------------------------------------------------------------------- 1 | addModelPath(__DIR__."/App/Models"); 10 | 11 | $this->connect("/", ['controller' => 'App\Controllers\Entries', 'action' => 'entries']); 12 | $this->connect("entries", ['controller' => 'App\Controllers\Entries', 'action' => 'entries']); 13 | $this->connect(":action", ['controller' => 'App\Controllers\Auth'], 14 | ['action'=>'(login|logout)'] 15 | ); 16 | $this->connect('attachments/:entry_id/:filename/bitrates.m3u8', ['controller' => 'App\Controllers\Attachments', 'entry_id' => false, 'filename' => false, 'action' => 'video-bitrate-list']); 17 | $this->connect('attachments/:action/:entry_id/:filename', ['controller' => 'App\Controllers\Attachments', 'entry_id' => false, 'filename' => false], 18 | ['action'=>'(upload|download|show-original-image|show-video-thumb|play-video|play-audio)'] 19 | ); 20 | $this->connect('attachments/show-attachment-preview/*any', ['controller' => 'App\Controllers\Attachments', 'action' => 'show-resized-image']); 21 | $this->connect('attachments/show-resized-image/*any', ['controller' => 'App\Controllers\Attachments', 'action' => 'show-resized-image']); 22 | 23 | $this->connect('entry_attachments/:entry_id/video_thumbs/:video_name', ['controller' => 'App\Controllers\Attachments', 'action' => 'show-video-thumb']); 24 | $this->connect('video-part-list/*any', ['controller' => 'App\Controllers\Attachments', 'action' => 'video-part-list']); 25 | $this->connect('play-video/*any', ['controller' => 'App\Controllers\Attachments', 'action' => 'play-video']); 26 | 27 | $this->connect('admin/app/:action/:id', ['controller' => 'App\Controllers\Admin\Users', 'id' => false], 28 | ['action'=>'(user-list|user-edit)'] 29 | ); 30 | $this->connect('admin/developer/:action/:id', ['controller' => 'App\Controllers\Admin\Developer', 'id' => false]); 31 | 32 | $this->connect("developer/:action", ['controller' => 'App\Controllers\Developer']); 33 | $this->connect("sync-entries", ['controller' => 'App\Controllers\Cron', 'action' => 'sync-entries']); 34 | 35 | \Bingo\Action::add('admin_pre_header', 36 | function () { 37 | \Admin::$menu[_t('Дневник')][_t('Пользователи')] = 'admin/app/user-list'; 38 | }, $priority = 1); 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Entries.php: -------------------------------------------------------------------------------- 1 | $this->user, 'id' => $entryId]); 18 | 19 | if ($_POST['action'] == 'edit_entry') { 20 | if (!empty($_POST['text']) || !empty($_POST['attachments'])) { 21 | if (!$entry) $entry = new Entry; 22 | else $entry->updated = new \DateTime('now'); 23 | $entry->text = !empty($_POST['text']) ? strip_tags($_POST['text']) : ''; 24 | $entry->attachments = !empty($_POST['attachments']) ? $_POST['attachments'] : []; 25 | $entry->attachment_preview_settings = [ 26 | 'first_row_height_percent' => isset($_POST['first_row_height_percent']) ? $_POST['first_row_height_percent'] : 20, 27 | 'secondary_rows_height_percent' => isset($_POST['secondary_rows_height_percent']) ? $_POST['secondary_rows_height_percent'] : 10, 28 | 'visible_row_count' => isset($_POST['visible_row_count']) ? $_POST['visible_row_count'] : 2 29 | ]; 30 | $entry->author = $this->user; 31 | $entry->save(); 32 | } 33 | } elseif ($_POST['action'] == 'delete_entry') { 34 | if (!$entry) return; 35 | $entry->deleted = true; 36 | $entry->save(); 37 | $entryId = false; 38 | } 39 | } 40 | 41 | $searchCriteria = !empty($_GET['search']) ? $_GET['search'] : ''; 42 | $searchText = trim(preg_replace("/#[\w|\p{L}]+/u", '', $searchCriteria)); 43 | 44 | $hashTags = []; 45 | preg_match_all("/#([\w|\p{L}]+)/u", $searchCriteria, $matches); 46 | if (!empty($matches[1])) { 47 | $hashTags = $matches[1]; 48 | } 49 | 50 | $limit = 20; 51 | $offset = ($this->getPage() - 1) * $limit; 52 | $query = Entry::getSearchQuery($entryId, $this->user, $searchText, $hashTags); 53 | $entries = $query->setMaxResults($limit)->setFirstResult($offset)->getResult(); 54 | $paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query); 55 | $total = count($paginator); 56 | 57 | $this->data['search_criteria'] = $searchCriteria; 58 | $this->data['show_load_more_button'] = $offset + $limit < $total; 59 | $this->data['current_page'] = $this->getPage(); 60 | $this->data['entries'] = $entries; 61 | $this->view('entries'); 62 | } 63 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Admin/Users.php: -------------------------------------------------------------------------------- 1 | text('id'); 10 | $filterForm->text('login'); 11 | $filterForm->text('email'); 12 | 13 | $criteria = array(); 14 | if ($filterForm->validate()) { 15 | $id = $filterForm->values['id']; 16 | if ($id) $criteria['id'] = $id; 17 | $login = trim($filterForm->values['login']); 18 | if ($login) $criteria['login'] = "LIKE %".$login."%"; 19 | $email = trim($filterForm->values['email']); 20 | if ($email) $criteria['email'] = "LIKE %".$email."%"; 21 | } 22 | 23 | $_GET['sort_by'] = isset($_GET['sort_by']) ? $_GET['sort_by'] : 'id'; 24 | $_GET['sort_order'] = isset($_GET['sort_order']) ? $_GET['sort_order'] : 'DESC'; 25 | $query = \App\Models\User::findByQuery($criteria, $_GET['sort_by']." ".$_GET['sort_order']); 26 | $pagination = new \Bingo\Pagination(20, $this->getPage(), $total = false, $pattern = false, $query); 27 | 28 | $this->data['filter_form'] = $filterForm; 29 | $this->data['pagination'] = $pagination->get(10); 30 | $this->data['list'] = $pagination->result(); 31 | 32 | $this->data['fields']['id'] = _t('ID'); 33 | $this->data['fields']['login'] = _t('Имя'); 34 | $this->data['fields']['email'] = _t('Email'); 35 | 36 | $this->data['sort_fields'] = ['id', 'login', 'email']; 37 | $this->data['page_actions']['admin/app/user-edit'] = _t('Создать нового'); 38 | $this->data['item_actions']['admin/app/user-edit'] = _t('редактировать'); 39 | 40 | $this->data['title'] = _t('Список пользователей'); 41 | $this->view('cms/base-list'); 42 | } 43 | 44 | function user_edit($id) { 45 | $user = \App\Models\User::findOrCreate($id); 46 | 47 | $form = new \Form('post'); 48 | $form->fieldset(_t('Данные пользователя')); 49 | $form->text('login', _t('Логин'), 'required', $user->login); 50 | $form->text('email', _t('Email'), ['required', 'valid_email'], $user->email); 51 | $form->text('new_password', _t('Новый пароль'), false); 52 | $form->submit(_t('Сохранить')); 53 | 54 | if ($form->validate()) { 55 | $form->fill($user); 56 | if ($form->values['new_password']) { 57 | $user->setPassword($form->values['new_password']); 58 | } 59 | $user->save(); 60 | 61 | set_flash('info',_t('Изменения сохранены успешно')); 62 | redirect('admin/app/user-edit/'.$user->id); 63 | } 64 | 65 | $this->data['title'] = _t('Редактирование пользователя'); 66 | $this->data['form'] = $form->get(); 67 | $this->view('cms/base-edit'); 68 | } 69 | } -------------------------------------------------------------------------------- /public/assets/lib/jquery-ui/jquery-ui.structure.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.12.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | .ui-draggable-handle { 12 | -ms-touch-action: none; 13 | touch-action: none; 14 | } 15 | /* Layout helpers 16 | ----------------------------------*/ 17 | .ui-helper-hidden { 18 | display: none; 19 | } 20 | .ui-helper-hidden-accessible { 21 | border: 0; 22 | clip: rect(0 0 0 0); 23 | height: 1px; 24 | margin: -1px; 25 | overflow: hidden; 26 | padding: 0; 27 | position: absolute; 28 | width: 1px; 29 | } 30 | .ui-helper-reset { 31 | margin: 0; 32 | padding: 0; 33 | border: 0; 34 | outline: 0; 35 | line-height: 1.3; 36 | text-decoration: none; 37 | font-size: 100%; 38 | list-style: none; 39 | } 40 | .ui-helper-clearfix:before, 41 | .ui-helper-clearfix:after { 42 | content: ""; 43 | display: table; 44 | border-collapse: collapse; 45 | } 46 | .ui-helper-clearfix:after { 47 | clear: both; 48 | } 49 | .ui-helper-zfix { 50 | width: 100%; 51 | height: 100%; 52 | top: 0; 53 | left: 0; 54 | position: absolute; 55 | opacity: 0; 56 | filter:Alpha(Opacity=0); /* support: IE8 */ 57 | } 58 | 59 | .ui-front { 60 | z-index: 100; 61 | } 62 | 63 | 64 | /* Interaction Cues 65 | ----------------------------------*/ 66 | .ui-state-disabled { 67 | cursor: default !important; 68 | pointer-events: none; 69 | } 70 | 71 | 72 | /* Icons 73 | ----------------------------------*/ 74 | .ui-icon { 75 | display: inline-block; 76 | vertical-align: middle; 77 | margin-top: -.25em; 78 | position: relative; 79 | text-indent: -99999px; 80 | overflow: hidden; 81 | background-repeat: no-repeat; 82 | } 83 | 84 | .ui-widget-icon-block { 85 | left: 50%; 86 | margin-left: -8px; 87 | display: block; 88 | } 89 | 90 | /* Misc visuals 91 | ----------------------------------*/ 92 | 93 | /* Overlays */ 94 | .ui-widget-overlay { 95 | position: fixed; 96 | top: 0; 97 | left: 0; 98 | width: 100%; 99 | height: 100%; 100 | } 101 | .ui-resizable { 102 | position: relative; 103 | } 104 | .ui-resizable-handle { 105 | position: absolute; 106 | font-size: 0.1px; 107 | display: block; 108 | -ms-touch-action: none; 109 | touch-action: none; 110 | } 111 | .ui-resizable-disabled .ui-resizable-handle, 112 | .ui-resizable-autohide .ui-resizable-handle { 113 | display: none; 114 | } 115 | .ui-resizable-n { 116 | cursor: n-resize; 117 | height: 7px; 118 | width: 100%; 119 | top: -5px; 120 | left: 0; 121 | } 122 | .ui-resizable-s { 123 | cursor: s-resize; 124 | height: 7px; 125 | width: 100%; 126 | bottom: -5px; 127 | left: 0; 128 | } 129 | .ui-resizable-e { 130 | cursor: e-resize; 131 | width: 7px; 132 | right: -5px; 133 | top: 0; 134 | height: 100%; 135 | } 136 | .ui-resizable-w { 137 | cursor: w-resize; 138 | width: 7px; 139 | left: -5px; 140 | top: 0; 141 | height: 100%; 142 | } 143 | .ui-resizable-se { 144 | cursor: se-resize; 145 | width: 12px; 146 | height: 12px; 147 | right: 1px; 148 | bottom: 1px; 149 | } 150 | .ui-resizable-sw { 151 | cursor: sw-resize; 152 | width: 9px; 153 | height: 9px; 154 | left: -5px; 155 | bottom: -5px; 156 | } 157 | .ui-resizable-nw { 158 | cursor: nw-resize; 159 | width: 9px; 160 | height: 9px; 161 | left: -5px; 162 | top: -5px; 163 | } 164 | .ui-resizable-ne { 165 | cursor: ne-resize; 166 | width: 9px; 167 | height: 9px; 168 | right: -5px; 169 | top: -5px; 170 | } 171 | .ui-selectable { 172 | -ms-touch-action: none; 173 | touch-action: none; 174 | } 175 | .ui-selectable-helper { 176 | position: absolute; 177 | z-index: 100; 178 | border: 1px dotted black; 179 | } 180 | .ui-sortable-handle { 181 | -ms-touch-action: none; 182 | touch-action: none; 183 | } 184 | -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Cron.php: -------------------------------------------------------------------------------- 1 | false]); 35 | foreach ($entries as $entry) { 36 | $cloudAttachmentsDir = \App\Models\Entry::CLOUD_STORAGE_BASE_FOLDER.'/'.$entry->id; 37 | $localAttachmentsDir = INDEX_DIR.'/entry_attachments/'.$entry->id; 38 | $tmpFilesDir = INDEX_DIR.'/cache/tmp_files'; 39 | $synced = true; 40 | 41 | if (!$entry->deleted) { 42 | $filename = uniqid($entry->id.'_').".txt"; 43 | file_put_contents($tmpFilesDir.'/'.$filename, $entry->text); 44 | $res = $cloudAPI->loadFile($tmpFilesDir.'/'.$filename, \App\Models\Entry::CLOUD_STORAGE_TEXT_FILENAME, $cloudAttachmentsDir); 45 | if ($res === false) $synced = false; 46 | unlink($tmpFilesDir.'/'.$filename); 47 | 48 | $cloudFiles = $cloudAPI->getFiles($cloudAttachmentsDir); 49 | if ($cloudFiles === false) continue; 50 | 51 | $existedAttachments = []; 52 | foreach ($cloudFiles as $file) { 53 | if ($file['name'] == \App\Models\Entry::CLOUD_STORAGE_TEXT_FILENAME) continue; 54 | if (!in_array($file['name'], $entry->attachments)) { 55 | $res = $cloudAPI->removeFile($cloudAttachmentsDir.'/'.$file['name']); 56 | if ($res !== false) @unlink($localAttachmentsDir.'/'.$file['name']); 57 | else $synced = false; 58 | } else { 59 | $existedAttachments[] = $file['name']; 60 | } 61 | } 62 | 63 | foreach ($entry->attachments as $attachment) { 64 | if (in_array($attachment, $existedAttachments) && !file_exists($tmpFilesDir.'/'.$attachment)) continue; 65 | if (!file_exists($tmpFilesDir.'/'.$attachment)) { 66 | trigger_error('Attachment '.$attachment.' was not found in temporary folder'); 67 | continue; 68 | } 69 | 70 | $res = $cloudAPI->loadFile($tmpFilesDir.'/'.$attachment, $attachment, $cloudAttachmentsDir); 71 | if ($res !== false) unlink($tmpFilesDir.'/'.$attachment); 72 | else $synced = false; 73 | } 74 | 75 | if ($synced) { 76 | $entry->synced = true; 77 | $entry->save(); 78 | } 79 | } else { 80 | $res = $cloudAPI->removeFile($cloudAttachmentsDir); 81 | if ($res !== false) { 82 | $entry->delete(); 83 | $removeDir($localAttachmentsDir); 84 | } 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /public/assets/lib/fancybox/jquery.fancybox.css: -------------------------------------------------------------------------------- 1 | /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ 2 | .fancybox-wrap, 3 | .fancybox-skin, 4 | .fancybox-outer, 5 | .fancybox-inner, 6 | .fancybox-image, 7 | .fancybox-wrap iframe, 8 | .fancybox-wrap object, 9 | .fancybox-nav, 10 | .fancybox-nav span, 11 | .fancybox-tmp 12 | { 13 | padding: 0; 14 | margin: 0; 15 | border: 0; 16 | outline: none; 17 | vertical-align: top; 18 | } 19 | 20 | .fancybox-wrap { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | z-index: 8020; 25 | } 26 | 27 | .fancybox-skin { 28 | position: relative; 29 | background: #f9f9f9; 30 | color: #444; 31 | text-shadow: none; 32 | -webkit-border-radius: 4px; 33 | -moz-border-radius: 4px; 34 | border-radius: 4px; 35 | } 36 | 37 | .fancybox-opened { 38 | z-index: 8030; 39 | } 40 | 41 | .fancybox-opened .fancybox-skin { 42 | -webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 43 | -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 44 | box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 45 | } 46 | 47 | .fancybox-outer, .fancybox-inner { 48 | position: relative; 49 | } 50 | 51 | .fancybox-inner { 52 | overflow: hidden; 53 | } 54 | 55 | .fancybox-type-iframe .fancybox-inner { 56 | -webkit-overflow-scrolling: touch; 57 | } 58 | 59 | .fancybox-error { 60 | color: #444; 61 | font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 62 | margin: 0; 63 | padding: 15px; 64 | white-space: nowrap; 65 | } 66 | 67 | .fancybox-image, .fancybox-iframe { 68 | display: block; 69 | width: 100%; 70 | height: 100%; 71 | } 72 | 73 | .fancybox-image { 74 | max-width: 100%; 75 | max-height: 100%; 76 | } 77 | 78 | #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { 79 | background-image: url('fancybox_sprite.png'); 80 | } 81 | 82 | #fancybox-loading { 83 | position: fixed; 84 | top: 50%; 85 | left: 50%; 86 | margin-top: -22px; 87 | margin-left: -22px; 88 | background-position: 0 -108px; 89 | opacity: 0.8; 90 | cursor: pointer; 91 | z-index: 8060; 92 | } 93 | 94 | #fancybox-loading div { 95 | width: 44px; 96 | height: 44px; 97 | background: url('fancybox_loading.gif') center center no-repeat; 98 | } 99 | 100 | .fancybox-close { 101 | position: absolute; 102 | top: -18px; 103 | right: -18px; 104 | width: 36px; 105 | height: 36px; 106 | cursor: pointer; 107 | z-index: 8040; 108 | } 109 | 110 | .fancybox-nav { 111 | position: absolute; 112 | top: 0; 113 | width: 40%; 114 | height: 100%; 115 | cursor: pointer; 116 | text-decoration: none; 117 | background: transparent url('blank.gif'); /* helps IE */ 118 | -webkit-tap-highlight-color: rgba(0,0,0,0); 119 | z-index: 8040; 120 | } 121 | 122 | .fancybox-prev { 123 | left: 0; 124 | } 125 | 126 | .fancybox-next { 127 | right: 0; 128 | } 129 | 130 | .fancybox-nav span { 131 | position: absolute; 132 | top: 50%; 133 | width: 36px; 134 | height: 34px; 135 | margin-top: -18px; 136 | cursor: pointer; 137 | z-index: 8040; 138 | visibility: hidden; 139 | } 140 | 141 | .fancybox-prev span { 142 | left: 10px; 143 | background-position: 0 -36px; 144 | } 145 | 146 | .fancybox-next span { 147 | right: 10px; 148 | background-position: 0 -72px; 149 | } 150 | 151 | .fancybox-nav:hover span { 152 | visibility: visible; 153 | } 154 | 155 | .fancybox-tmp { 156 | position: absolute; 157 | top: -99999px; 158 | left: -99999px; 159 | visibility: hidden; 160 | max-width: 99999px; 161 | max-height: 99999px; 162 | overflow: visible !important; 163 | } 164 | 165 | /* Overlay helper */ 166 | 167 | .fancybox-lock { 168 | overflow: hidden !important; 169 | width: auto; 170 | } 171 | 172 | .fancybox-lock body { 173 | overflow: hidden !important; 174 | } 175 | 176 | .fancybox-lock-test { 177 | overflow-y: hidden !important; 178 | } 179 | 180 | .fancybox-overlay { 181 | position: absolute; 182 | top: 0; 183 | left: 0; 184 | overflow: hidden; 185 | display: none; 186 | z-index: 8010; 187 | background: url('fancybox_overlay.png'); 188 | } 189 | 190 | .fancybox-overlay-fixed { 191 | position: fixed; 192 | bottom: 0; 193 | right: 0; 194 | } 195 | 196 | .fancybox-lock .fancybox-overlay { 197 | overflow: auto; 198 | overflow-y: scroll; 199 | } 200 | 201 | /* Title helper */ 202 | 203 | .fancybox-title { 204 | visibility: hidden; 205 | font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 206 | position: relative; 207 | text-shadow: none; 208 | z-index: 8050; 209 | } 210 | 211 | .fancybox-opened .fancybox-title { 212 | visibility: visible; 213 | } 214 | 215 | .fancybox-title-float-wrap { 216 | position: absolute; 217 | bottom: 0; 218 | right: 50%; 219 | margin-bottom: -35px; 220 | z-index: 8050; 221 | text-align: center; 222 | } 223 | 224 | .fancybox-title-float-wrap .child { 225 | display: inline-block; 226 | margin-right: -100%; 227 | padding: 2px 20px; 228 | background: transparent; /* Fallback for web browsers that doesn't support RGBa */ 229 | background: rgba(0, 0, 0, 0.8); 230 | -webkit-border-radius: 15px; 231 | -moz-border-radius: 15px; 232 | border-radius: 15px; 233 | text-shadow: 0 1px 2px #222; 234 | color: #FFF; 235 | font-weight: bold; 236 | line-height: 24px; 237 | white-space: nowrap; 238 | } 239 | 240 | .fancybox-title-outside-wrap { 241 | position: relative; 242 | margin-top: 10px; 243 | color: #fff; 244 | } 245 | 246 | .fancybox-title-inside-wrap { 247 | padding-top: 10px; 248 | } 249 | 250 | .fancybox-title-over-wrap { 251 | position: absolute; 252 | bottom: 0; 253 | left: 0; 254 | color: #fff; 255 | padding: 10px; 256 | background: #000; 257 | background: rgba(0, 0, 0, .8); 258 | } 259 | 260 | /*Retina graphics!*/ 261 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), 262 | only screen and (min--moz-device-pixel-ratio: 1.5), 263 | only screen and (min-device-pixel-ratio: 1.5){ 264 | 265 | #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { 266 | background-image: url('fancybox_sprite@2x.png'); 267 | background-size: 44px 152px; /*The size of the normal image, half the size of the hi-res image*/ 268 | } 269 | 270 | #fancybox-loading div { 271 | background-image: url('fancybox_loading@2x.gif'); 272 | background-size: 24px 24px; /*The size of the normal image, half the size of the hi-res image*/ 273 | } 274 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Controllers/Attachments.php: -------------------------------------------------------------------------------- 1 | cloudAPI = new \CloudMailruAPI($config['login'], $config['password']); 13 | } 14 | 15 | public function show_original_image($entryId, $filename) { 16 | if (!$entryId || !$filename) return; 17 | $imagePath = Entry::CLOUD_STORAGE_BASE_FOLDER.'/'.$entryId.'/'.$filename; 18 | $ext = strtolower(pathinfo($imagePath, PATHINFO_EXTENSION)); 19 | 20 | switch($ext) { 21 | case "gif": $ctype="image/gif"; break; 22 | case "png": $ctype="image/png"; break; 23 | case "jpeg": 24 | case "jpg": $ctype="image/jpeg"; break; 25 | default: 26 | } 27 | 28 | header('Content-type: '.$ctype); 29 | echo $this->cloudAPI->getFileContent($imagePath); 30 | } 31 | 32 | public function show_video_thumb($entryId, $videoName) { 33 | if (!$entryId || !$videoName) return; 34 | $videoThumbsDir = INDEX_DIR.'/entry_attachments/'.$entryId.'/video_thumbs'; 35 | $videoThumbsPath = $videoThumbsDir.'/'.str_replace('.', '_', $videoName).'.jpg'; 36 | 37 | if (!is_dir($videoThumbsDir)) 38 | mkdir($videoThumbsDir, $mode = 0755, $recursive = true); 39 | 40 | if (!file_exists($videoThumbsPath)) { 41 | $entry = Entry::find($entryId); 42 | if ($entry && $entry->synced) { 43 | $thumbData = $this->cloudAPI->getVideoThumb(Entry::CLOUD_STORAGE_BASE_FOLDER.'/'.$entryId.'/'.$videoName); 44 | if ($thumbData) { 45 | $file = fopen($videoThumbsPath, "w+"); 46 | fwrite($file, $thumbData); 47 | fclose($file); 48 | } 49 | } 50 | } 51 | 52 | if (!file_exists($videoThumbsPath)) { 53 | $videoThumbsPath = INDEX_DIR . '/assets/images/video-thumb.jpg'; 54 | header('Cache-Control: no-cache'); 55 | } else { 56 | header('Cache-Control: max-age=3600'); 57 | } 58 | 59 | $thumbInfo = @getimagesize($videoThumbsPath); 60 | $mimeInfo = isset($thumbInfo['mime']) ? $thumbInfo['mime'] : null; 61 | header("Content-type: $mimeInfo"); 62 | readfile($videoThumbsPath); 63 | } 64 | 65 | public function video_bitrate_list($entryId, $videoName) { 66 | if (!$entryId || !$videoName) return; 67 | header("Content-type: application/x-mpegURL"); 68 | $list = $this->cloudAPI->getVideoBitrates(Entry::CLOUD_STORAGE_BASE_FOLDER.'/'.$entryId.'/'.$videoName); 69 | echo preg_replace('/\/media\//', '//'.$_SERVER['HTTP_HOST'].url('/video-part-list/media/'), $list); 70 | } 71 | 72 | public function video_part_list($videoUrl) { 73 | header("Content-type: application/x-mpegURL"); 74 | $list = $this->cloudAPI->getVideo($videoUrl.'?double_encode=1'); 75 | echo preg_replace('/\/media\//', '//'.$_SERVER['HTTP_HOST'].url('/play-video/media/'), $list); 76 | } 77 | 78 | public function play_video($videoUrl) { 79 | echo $this->cloudAPI->getVideo($videoUrl.'?double_encode=1'); 80 | } 81 | 82 | public function upload() { 83 | $tmpFilesDir = INDEX_DIR.'/cache/tmp_files'; 84 | $tmpImgsPreviewDir = $tmpFilesDir.'/images_preview'; 85 | $tmpResizedImgsDir = $tmpFilesDir.'/resized_images'; 86 | 87 | $removeExpiredFiles = function($dir) { 88 | $tmpFiles = array_diff(scandir($dir), ['.', '..']); 89 | foreach ($tmpFiles as $filename) { 90 | $filetime = @filemtime($dir."/".$filename); 91 | if ($filetime < time() - 86400) 92 | @unlink($dir."/".$filename); 93 | } 94 | }; 95 | 96 | foreach ([$tmpFilesDir, $tmpImgsPreviewDir, $tmpResizedImgsDir] as $dir) { 97 | if (!file_exists($dir)) mkdir($dir, 0755); 98 | $removeExpiredFiles($dir); 99 | } 100 | 101 | if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] == 0) { 102 | $fileinfo = pathinfo(' '.$_FILES['attachment']['name']); 103 | $basename = mb_substr(trim($fileinfo['filename']), 0, 100, 'UTF-8'); 104 | $extension = $fileinfo['extension']; 105 | $filename = $basename.'.'.$extension; 106 | 107 | $counter = 1; 108 | if (file_exists($tmpFilesDir.'/'.$filename)) { 109 | while (file_exists($tmpFilesDir.'/'.$basename.'('.$counter.').'.$extension)) { 110 | $counter++; 111 | } 112 | $filename = $basename.'('.$counter.').'.$extension; 113 | } 114 | move_uploaded_file($_FILES['attachment']['tmp_name'], $tmpFilesDir.'/'.$filename); 115 | 116 | $resizeAttachedImage = function($imagePath, $destinationPath, $width, $height) { 117 | try { 118 | $file = \PhpThumb\Factory::create($imagePath, ['resizeUp' => false]); 119 | $file->resize($width, $height); 120 | $file->save($destinationPath); 121 | } catch (\Exception $e) { 122 | trigger_error($e->getMessage()); 123 | } 124 | }; 125 | 126 | $previewUrl = ''; 127 | $attachmentType = Entry::getAttachmentType($filename); 128 | if ($attachmentType == Entry::ATTACHMENT_TYPE_IMAGE) { 129 | $resizeAttachedImage($tmpFilesDir.'/'.$filename, $tmpImgsPreviewDir.'/'.$filename, 500, 500); //generate preview 130 | $resizeAttachedImage($tmpFilesDir.'/'.$filename, $tmpResizedImgsDir.'/'.$filename, 1920, 1200); //generate resized copy 131 | $previewUrl = url('cache/tmp_files/images_preview/'.rawurlencode($filename)); 132 | } elseif ($attachmentType == Entry::ATTACHMENT_TYPE_VIDEO) { 133 | $previewUrl = url('assets/images/video-thumb.jpg'); 134 | } 135 | 136 | echo json_encode(['status' => 'success', 'filename' => $filename, 'preview_url' => $previewUrl]); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /modules/App/lib/App/Models/Entry.php: -------------------------------------------------------------------------------- 1 | created = new \DateTime('now'); 55 | $this->text = ''; 56 | $this->synced = false; 57 | $this->deleted = false; 58 | $this->attachments = []; 59 | $this->attachment_previews_settings = []; 60 | } 61 | 62 | /** @PreUpdate */ 63 | public function preUpdate(\Doctrine\ORM\Event\PreUpdateEventArgs $event) { 64 | $tmpFilesDir = INDEX_DIR.'/cache/tmp_files'; 65 | foreach ($this->attachments as $attachment) { 66 | if (file_exists($tmpFilesDir.'/'.$attachment)) 67 | $this->synced = false; 68 | } 69 | 70 | if ($event->hasChangedField('attachments') || $event->hasChangedField('text') || $event->hasChangedField('deleted')) 71 | $this->synced = false; 72 | } 73 | 74 | /** @PostPersist @PostUpdate */ 75 | function postPersist() { 76 | preg_match_all("/#([\w|\p{L}]+)/u", $this->text, $matches); 77 | $oldTags = $this->getTags(); 78 | $newTags = !empty($matches[1]) ? $matches[1] : []; 79 | 80 | \Bingo::$em->createQuery("DELETE Meta\Models\Tag t WHERE t.type = :type AND t.owner_id = :owner_id AND t.value IN (:values)") 81 | ->setParameter('type', get_class($this)) 82 | ->setParameter('owner_id', $this->id) 83 | ->setParameter('values', array_diff($oldTags, $newTags)) 84 | ->execute() 85 | ; 86 | 87 | $this->setTags($newTags); 88 | 89 | $tmpFilesDir = INDEX_DIR.'/cache/tmp_files'; 90 | $attachmentsDir = INDEX_DIR.'/entry_attachments/'.$this->id; 91 | 92 | $directories = [ 93 | $tmpFilesDir, 94 | $attachmentsDir, 95 | $attachmentsDir.'/images_preview', 96 | $attachmentsDir.'/resized_images' 97 | ]; 98 | 99 | foreach ($directories as $dir) 100 | if (!file_exists($dir)) mkdir($dir, 0755, true); 101 | 102 | foreach ($this->attachments as $attachment) { 103 | if (!file_exists($tmpFilesDir.'/'.$attachment)) continue; 104 | 105 | $attachmentType = self::getAttachmentType($attachment); 106 | if ($attachmentType == self::ATTACHMENT_TYPE_IMAGE) { 107 | foreach (['images_preview', 'resized_images'] as $subDir) { 108 | if (file_exists($tmpFilesDir.'/'.$subDir)) 109 | @rename($tmpFilesDir.'/'.$subDir.'/'.$attachment, $attachmentsDir.'/'.$subDir.'/'.$attachment); 110 | } 111 | } else if (in_array($attachmentType, [self::ATTACHMENT_TYPE_OTHER, self::ATTACHMENT_TYPE_AUDIO])) { 112 | @copy($tmpFilesDir.'/'.$attachment, $attachmentsDir.'/'.$attachment); 113 | } 114 | } 115 | } 116 | 117 | public static function getSearchQuery($id = false, $author = null, $text = '', $tags = []) { 118 | $qb = \Bingo::$em->createQueryBuilder() 119 | ->select('DISTINCT e') 120 | ->from('App\Models\Entry', 'e') 121 | ->where('e.deleted = false') 122 | ->add('orderBy','e.created DESC, e.id DESC'); 123 | 124 | if ($id) { 125 | $qb->andWhere('e.id = :id'); 126 | $qb->setParameter('id', $id); 127 | } 128 | 129 | if ($author) { 130 | $qb->andWhere('e.author = :author'); 131 | $qb->setParameter('author', $author); 132 | } 133 | 134 | if ($text) { 135 | $qb->andWhere("e.text LIKE :text"); 136 | $qb->setParameter('text', '%'.$text.'%'); 137 | } 138 | 139 | if (count($tags)) { 140 | $qb->addSelect('COUNT(t.id) as HIDDEN tag_count'); 141 | $qb->join('Meta\Models\Tag', 't', 'WITH', 't.owner_id = e.id AND t.type = :tag_type'); 142 | $qb->andWhere('t.value IN (:tags)'); 143 | $qb->groupBy('e.id'); 144 | $qb->having('tag_count = :tag_count'); 145 | $qb->setParameter('tags', $tags); 146 | $qb->setParameter('tag_type', static::class); 147 | $qb->setParameter('tag_count', count($tags)); 148 | } 149 | 150 | return $qb->getQuery(); 151 | } 152 | 153 | public static function getAttachmentType($attachment) { 154 | $extension = strtolower(pathinfo($attachment, PATHINFO_EXTENSION)); 155 | if (in_array($extension, ['png', 'jpeg', 'gif', 'jpg'])) { 156 | return self::ATTACHMENT_TYPE_IMAGE; 157 | } else if (in_array($extension, ['webm', 'mp4', 'ogv', 'avi', 'asf', 'flv'])) { 158 | return self::ATTACHMENT_TYPE_VIDEO; 159 | } else if ($extension == 'mp3') { 160 | return self::ATTACHMENT_TYPE_AUDIO; 161 | } 162 | 163 | return self::ATTACHMENT_TYPE_OTHER; 164 | } 165 | 166 | public function getTags() { 167 | return \Meta\Models\Tag::getTags($this); 168 | } 169 | 170 | public function setTags($tags) { 171 | return \Meta\Models\Tag::setTags($this, $tags); 172 | } 173 | } -------------------------------------------------------------------------------- /public/assets/lib/autosize/autosize.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Autosize 3.0.20 3 | license: MIT 4 | http://www.jacklmoore.com/autosize 5 | */ 6 | (function (global, factory) { 7 | if (typeof define === 'function' && define.amd) { 8 | define(['exports', 'module'], factory); 9 | } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { 10 | factory(exports, module); 11 | } else { 12 | var mod = { 13 | exports: {} 14 | }; 15 | factory(mod.exports, mod); 16 | global.autosize = mod.exports; 17 | } 18 | })(this, function (exports, module) { 19 | 'use strict'; 20 | 21 | var map = typeof Map === "function" ? new Map() : (function () { 22 | var keys = []; 23 | var values = []; 24 | 25 | return { 26 | has: function has(key) { 27 | return keys.indexOf(key) > -1; 28 | }, 29 | get: function get(key) { 30 | return values[keys.indexOf(key)]; 31 | }, 32 | set: function set(key, value) { 33 | if (keys.indexOf(key) === -1) { 34 | keys.push(key); 35 | values.push(value); 36 | } 37 | }, 38 | 'delete': function _delete(key) { 39 | var index = keys.indexOf(key); 40 | if (index > -1) { 41 | keys.splice(index, 1); 42 | values.splice(index, 1); 43 | } 44 | } 45 | }; 46 | })(); 47 | 48 | var createEvent = function createEvent(name) { 49 | return new Event(name, { bubbles: true }); 50 | }; 51 | try { 52 | new Event('test'); 53 | } catch (e) { 54 | // IE does not support `new Event()` 55 | createEvent = function (name) { 56 | var evt = document.createEvent('Event'); 57 | evt.initEvent(name, true, false); 58 | return evt; 59 | }; 60 | } 61 | 62 | function assign(ta) { 63 | if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return; 64 | 65 | var heightOffset = null; 66 | var clientWidth = ta.clientWidth; 67 | var cachedHeight = null; 68 | 69 | function init() { 70 | var style = window.getComputedStyle(ta, null); 71 | 72 | if (style.resize === 'vertical') { 73 | ta.style.resize = 'none'; 74 | } else if (style.resize === 'both') { 75 | ta.style.resize = 'horizontal'; 76 | } 77 | 78 | if (style.boxSizing === 'content-box') { 79 | heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); 80 | } else { 81 | heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); 82 | } 83 | // Fix when a textarea is not on document body and heightOffset is Not a Number 84 | if (isNaN(heightOffset)) { 85 | heightOffset = 0; 86 | } 87 | 88 | update(); 89 | } 90 | 91 | function changeOverflow(value) { 92 | { 93 | // Chrome/Safari-specific fix: 94 | // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space 95 | // made available by removing the scrollbar. The following forces the necessary text reflow. 96 | var width = ta.style.width; 97 | ta.style.width = '0px'; 98 | // Force reflow: 99 | /* jshint ignore:start */ 100 | ta.offsetWidth; 101 | /* jshint ignore:end */ 102 | ta.style.width = width; 103 | } 104 | 105 | ta.style.overflowY = value; 106 | } 107 | 108 | function getParentOverflows(el) { 109 | var arr = []; 110 | 111 | while (el && el.parentNode && el.parentNode instanceof Element) { 112 | if (el.parentNode.scrollTop) { 113 | arr.push({ 114 | node: el.parentNode, 115 | scrollTop: el.parentNode.scrollTop 116 | }); 117 | } 118 | el = el.parentNode; 119 | } 120 | 121 | return arr; 122 | } 123 | 124 | function resize() { 125 | var originalHeight = ta.style.height; 126 | var overflows = getParentOverflows(ta); 127 | var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) 128 | 129 | ta.style.height = 'auto'; 130 | 131 | var endHeight = ta.scrollHeight + heightOffset; 132 | 133 | if (ta.scrollHeight === 0) { 134 | // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. 135 | ta.style.height = originalHeight; 136 | return; 137 | } 138 | 139 | ta.style.height = endHeight + 'px'; 140 | 141 | // used to check if an update is actually necessary on window.resize 142 | clientWidth = ta.clientWidth; 143 | 144 | // prevents scroll-position jumping 145 | overflows.forEach(function (el) { 146 | el.node.scrollTop = el.scrollTop; 147 | }); 148 | 149 | if (docTop) { 150 | document.documentElement.scrollTop = docTop; 151 | } 152 | } 153 | 154 | function update() { 155 | resize(); 156 | 157 | var styleHeight = Math.round(parseFloat(ta.style.height)); 158 | var computed = window.getComputedStyle(ta, null); 159 | var actualHeight = Math.round(parseFloat(computed.height)); 160 | 161 | // The actual height not matching the style height (set via the resize method) indicates that 162 | // the max-height has been exceeded, in which case the overflow should be set to visible. 163 | if (actualHeight !== styleHeight) { 164 | if (computed.overflowY !== 'visible') { 165 | changeOverflow('visible'); 166 | resize(); 167 | actualHeight = Math.round(parseFloat(window.getComputedStyle(ta, null).height)); 168 | } 169 | } else { 170 | // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. 171 | if (computed.overflowY !== 'hidden') { 172 | changeOverflow('hidden'); 173 | resize(); 174 | actualHeight = Math.round(parseFloat(window.getComputedStyle(ta, null).height)); 175 | } 176 | } 177 | 178 | if (cachedHeight !== actualHeight) { 179 | cachedHeight = actualHeight; 180 | var evt = createEvent('autosize:resized'); 181 | try { 182 | ta.dispatchEvent(evt); 183 | } catch (err) { 184 | // Firefox will throw an error on dispatchEvent for a detached element 185 | // https://bugzilla.mozilla.org/show_bug.cgi?id=889376 186 | } 187 | } 188 | } 189 | 190 | var pageResize = function pageResize() { 191 | if (ta.clientWidth !== clientWidth) { 192 | update(); 193 | } 194 | }; 195 | 196 | var destroy = (function (style) { 197 | window.removeEventListener('resize', pageResize, false); 198 | ta.removeEventListener('input', update, false); 199 | ta.removeEventListener('keyup', update, false); 200 | ta.removeEventListener('autosize:destroy', destroy, false); 201 | ta.removeEventListener('autosize:update', update, false); 202 | 203 | Object.keys(style).forEach(function (key) { 204 | ta.style[key] = style[key]; 205 | }); 206 | 207 | map['delete'](ta); 208 | }).bind(ta, { 209 | height: ta.style.height, 210 | resize: ta.style.resize, 211 | overflowY: ta.style.overflowY, 212 | overflowX: ta.style.overflowX, 213 | wordWrap: ta.style.wordWrap 214 | }); 215 | 216 | ta.addEventListener('autosize:destroy', destroy, false); 217 | 218 | // IE9 does not fire onpropertychange or oninput for deletions, 219 | // so binding to onkeyup to catch most of those events. 220 | // There is no way that I know of to detect something like 'cut' in IE9. 221 | if ('onpropertychange' in ta && 'oninput' in ta) { 222 | ta.addEventListener('keyup', update, false); 223 | } 224 | 225 | window.addEventListener('resize', pageResize, false); 226 | ta.addEventListener('input', update, false); 227 | ta.addEventListener('autosize:update', update, false); 228 | ta.style.overflowX = 'hidden'; 229 | ta.style.wordWrap = 'break-word'; 230 | 231 | map.set(ta, { 232 | destroy: destroy, 233 | update: update 234 | }); 235 | 236 | init(); 237 | } 238 | 239 | function destroy(ta) { 240 | var methods = map.get(ta); 241 | if (methods) { 242 | methods.destroy(); 243 | } 244 | } 245 | 246 | function update(ta) { 247 | var methods = map.get(ta); 248 | if (methods) { 249 | methods.update(); 250 | } 251 | } 252 | 253 | var autosize = null; 254 | 255 | // Do nothing in Node.js environment and IE8 (or lower) 256 | if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { 257 | autosize = function (el) { 258 | return el; 259 | }; 260 | autosize.destroy = function (el) { 261 | return el; 262 | }; 263 | autosize.update = function (el) { 264 | return el; 265 | }; 266 | } else { 267 | autosize = function (el, options) { 268 | if (el) { 269 | Array.prototype.forEach.call(el.length ? el : [el], function (x) { 270 | return assign(x, options); 271 | }); 272 | } 273 | return el; 274 | }; 275 | autosize.destroy = function (el) { 276 | if (el) { 277 | Array.prototype.forEach.call(el.length ? el : [el], destroy); 278 | } 279 | return el; 280 | }; 281 | autosize.update = function (el) { 282 | if (el) { 283 | Array.prototype.forEach.call(el.length ? el : [el], update); 284 | } 285 | return el; 286 | }; 287 | } 288 | 289 | module.exports = autosize; 290 | }); -------------------------------------------------------------------------------- /public/assets/lib/jquery-fileupload/jquery.iframe-transport.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Iframe Transport Plugin 1.6.1 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /*jslint unparam: true, nomen: true */ 13 | /*global define, window, document */ 14 | 15 | (function (factory) { 16 | 'use strict'; 17 | if (typeof define === 'function' && define.amd) { 18 | // Register as an anonymous AMD module: 19 | define(['jquery'], factory); 20 | } else { 21 | // Browser globals: 22 | factory(window.jQuery); 23 | } 24 | }(function ($) { 25 | 'use strict'; 26 | 27 | // Helper variable to create unique names for the transport iframes: 28 | var counter = 0; 29 | 30 | // The iframe transport accepts three additional options: 31 | // options.fileInput: a jQuery collection of file input fields 32 | // options.paramName: the parameter name for the file form data, 33 | // overrides the name property of the file input field(s), 34 | // can be a string or an array of strings. 35 | // options.formData: an array of objects with name and value properties, 36 | // equivalent to the return data of .serializeArray(), e.g.: 37 | // [{name: 'a', value: 1}, {name: 'b', value: 2}] 38 | $.ajaxTransport('iframe', function (options) { 39 | if (options.async) { 40 | var form, 41 | iframe, 42 | addParamChar; 43 | return { 44 | send: function (_, completeCallback) { 45 | form = $('
'); 46 | form.attr('accept-charset', options.formAcceptCharset); 47 | addParamChar = /\?/.test(options.url) ? '&' : '?'; 48 | // XDomainRequest only supports GET and POST: 49 | if (options.type === 'DELETE') { 50 | options.url = options.url + addParamChar + '_method=DELETE'; 51 | options.type = 'POST'; 52 | } else if (options.type === 'PUT') { 53 | options.url = options.url + addParamChar + '_method=PUT'; 54 | options.type = 'POST'; 55 | } else if (options.type === 'PATCH') { 56 | options.url = options.url + addParamChar + '_method=PATCH'; 57 | options.type = 'POST'; 58 | } 59 | // javascript:false as initial iframe src 60 | // prevents warning popups on HTTPS in IE6. 61 | // IE versions below IE8 cannot set the name property of 62 | // elements that have already been added to the DOM, 63 | // so we set the name along with the iframe HTML markup: 64 | iframe = $( 65 | '' 67 | ).bind('load', function () { 68 | var fileInputClones, 69 | paramNames = $.isArray(options.paramName) ? 70 | options.paramName : [options.paramName]; 71 | iframe 72 | .unbind('load') 73 | .bind('load', function () { 74 | var response; 75 | // Wrap in a try/catch block to catch exceptions thrown 76 | // when trying to access cross-domain iframe contents: 77 | try { 78 | response = iframe.contents(); 79 | // Google Chrome and Firefox do not throw an 80 | // exception when calling iframe.contents() on 81 | // cross-domain requests, so we unify the response: 82 | if (!response.length || !response[0].firstChild) { 83 | throw new Error(); 84 | } 85 | } catch (e) { 86 | response = undefined; 87 | } 88 | // The complete callback returns the 89 | // iframe content document as response object: 90 | completeCallback( 91 | 200, 92 | 'success', 93 | {'iframe': response} 94 | ); 95 | // Fix for IE endless progress bar activity bug 96 | // (happens on form submits to iframe targets): 97 | $('') 98 | .appendTo(form); 99 | form.remove(); 100 | }); 101 | form 102 | .prop('target', iframe.prop('name')) 103 | .prop('action', options.url) 104 | .prop('method', options.type); 105 | if (options.formData) { 106 | $.each(options.formData, function (index, field) { 107 | $('') 108 | .prop('name', field.name) 109 | .val(field.value) 110 | .appendTo(form); 111 | }); 112 | } 113 | if (options.fileInput && options.fileInput.length && 114 | options.type === 'POST') { 115 | fileInputClones = options.fileInput.clone(); 116 | // Insert a clone for each file input field: 117 | options.fileInput.after(function (index) { 118 | return fileInputClones[index]; 119 | }); 120 | if (options.paramName) { 121 | options.fileInput.each(function (index) { 122 | $(this).prop( 123 | 'name', 124 | paramNames[index] || options.paramName 125 | ); 126 | }); 127 | } 128 | // Appending the file input fields to the hidden form 129 | // removes them from their original location: 130 | form 131 | .append(options.fileInput) 132 | .prop('enctype', 'multipart/form-data') 133 | // enctype must be set as encoding for IE: 134 | .prop('encoding', 'multipart/form-data'); 135 | } 136 | form.submit(); 137 | // Insert the file input fields at their original location 138 | // by replacing the clones with the originals: 139 | if (fileInputClones && fileInputClones.length) { 140 | options.fileInput.each(function (index, input) { 141 | var clone = $(fileInputClones[index]); 142 | $(input).prop('name', clone.prop('name')); 143 | clone.replaceWith(input); 144 | }); 145 | } 146 | }); 147 | form.append(iframe).appendTo(document.body); 148 | }, 149 | abort: function () { 150 | if (iframe) { 151 | // javascript:false as iframe src aborts the request 152 | // and prevents warning popups on HTTPS in IE6. 153 | // concat is used to avoid the "Script URL" JSLint error: 154 | iframe 155 | .unbind('load') 156 | .prop('src', 'javascript'.concat(':false;')); 157 | } 158 | if (form) { 159 | form.remove(); 160 | } 161 | } 162 | }; 163 | } 164 | }); 165 | 166 | // The iframe transport returns the iframe content document as response. 167 | // The following adds converters from iframe to text, json, html, and script: 168 | $.ajaxSetup({ 169 | converters: { 170 | 'iframe text': function (iframe) { 171 | return iframe && $(iframe[0].body).text(); 172 | }, 173 | 'iframe json': function (iframe) { 174 | return iframe && $.parseJSON($(iframe[0].body).text()); 175 | }, 176 | 'iframe html': function (iframe) { 177 | return iframe && $(iframe[0].body).html(); 178 | }, 179 | 'iframe script': function (iframe) { 180 | return iframe && $.globalEval($(iframe[0].body).text()); 181 | } 182 | } 183 | }); 184 | 185 | })); 186 | -------------------------------------------------------------------------------- /modules/App/lib/CloudMailruAPI.php: -------------------------------------------------------------------------------- 1 | login = $login; 16 | $this->password = $password; 17 | $this->curl = curl_init(); 18 | } 19 | 20 | public function getFiles($folder = '') { 21 | $response = $this->executeMethod('folder', 'get', [ 22 | 'home' => '/'.$folder, 23 | 'sort' => '{"type":"mtime","order":"desc"}' 24 | ]); 25 | 26 | $files = []; 27 | if (!empty($response['list'])) { 28 | foreach ($response['list'] as $item) { 29 | if ($item['type'] === 'file') { 30 | $files[] = $item; 31 | } 32 | } 33 | } 34 | return $files; 35 | } 36 | 37 | public function loadFile($filePath, $fileName, $destinationFolder = '') { 38 | $response = $this->request($this->getUploadUrl() . '?' . http_build_query([ 'cloud_domain' => 2, 'fileapi'.time() => '']), [ 39 | 'uploadData' => [ 40 | 'filepath' => $filePath, 41 | 'filename' => $fileName 42 | ] 43 | ]); 44 | 45 | $fileData = explode(';', $response); 46 | return $this->executeMethod('file/add', 'post', [ 47 | 'home' => $destinationFolder.'/'.$fileName, 48 | 'hash' => $fileData[0], 49 | 'size' => intval($fileData[1]), 50 | 'conflict' => 'rewrite', 51 | 'api' => 2 52 | ]); 53 | } 54 | 55 | public function moveFile($filePath, $destinationFolder) { 56 | return $this->executeMethod('file/move', 'post', [ 57 | 'folder' => '/'.$destinationFolder, 58 | 'home' => $filePath, 59 | 'conflict' => 'rename', 60 | 'api' => 2 61 | ]); 62 | } 63 | 64 | public function removeFile($filePath) { 65 | return $this->executeMethod('file/remove', 'post', [ 66 | 'home' => $filePath, 67 | 'api' => 2 68 | ]); 69 | } 70 | 71 | public function getFileContent($filePath) { 72 | $this->authenticate(); 73 | $this->ensureSdcCookie(); 74 | 75 | $maxRedir = 5; $redirCount = 0; 76 | $url = $this->getDownloadUrl().implode('/', array_map('rawurlencode', explode('/', $filePath))); 77 | $response = false; 78 | 79 | $fh = fopen('php://temp', 'w+'); 80 | do { 81 | ftruncate($fh, 0); 82 | rewind($fh); 83 | $response = $this->request($url, ['filehandle' => $fh]); 84 | if (strpos($response, 'redirect') !== false) 85 | $url = str_replace('redirect: ', '', $response); 86 | } while (strpos($response, 'redirect') !== false && ++$redirCount <= $maxRedir); 87 | 88 | rewind($fh); 89 | $result = stream_get_contents($fh); 90 | fclose($fh); 91 | return $result; 92 | } 93 | 94 | public function getVideoBitrates($videoPath) { 95 | $this->authenticate(); 96 | $this->ensureSdcCookie(); 97 | $videoPath = base64_encode(implode('/', array_map('rawurlencode', explode('/', $videoPath)))); 98 | return $this->request($this->getVideoUrl().'0p/'.$videoPath.'.m3u8?double_encode=1'); 99 | } 100 | 101 | public function getVideo($videoPath) { 102 | $this->authenticate(); 103 | $this->ensureSdcCookie(); 104 | return $this->request(str_replace('/video/', '', $this->getVideoUrl()).'/'.$videoPath); 105 | } 106 | 107 | public function getVideoThumb($videoPath) { 108 | $this->authenticate(); 109 | $this->ensureSdcCookie(); 110 | 111 | $fh = fopen('php://temp', 'w+'); 112 | $response = $this->request($this->getVideoThumbUrl().'vxw0/'.implode('/', array_map('rawurlencode', explode('/', $videoPath))), ['filehandle' => $fh]); 113 | rewind($fh); 114 | $result = stream_get_contents($fh); 115 | fclose($fh); 116 | return $result; 117 | } 118 | 119 | 120 | private function executeMethod($method, $requestType = 'get', array $params = []) { 121 | if ($method !== 'tokens/csrf') { 122 | $params['token'] = $this->getToken(); 123 | } 124 | 125 | $url = static::CLOUD_DOMAIN . '/api/v2/' . $method; 126 | if ($requestType == 'get') { 127 | $url .= '?' . http_build_query($params); 128 | $content = $this->request($url); 129 | } else { 130 | $content = $this->request($url, ['postData' => $params]); 131 | } 132 | 133 | $response = json_decode($content, true); 134 | if (!$response && json_last_error() !== JSON_ERROR_NONE) { 135 | trigger_error('Cloud Mailru API response was not parsed'); 136 | return false; 137 | } 138 | 139 | if (!$response) $response = []; 140 | $status = array_key_exists('status', $response) ? (int)$response['status'] : 0; 141 | if (!array_key_exists('body', $response)) { 142 | trigger_error('Empty body in Cloud Mailru API response'); 143 | return false; 144 | } 145 | 146 | $body = $response['body']; 147 | if ($status === 403) { 148 | switch ($body) { 149 | case 'user': 150 | trigger_error('Cloud Mailru API response: authentication required'); 151 | case 'nosdc': 152 | trigger_error('Cloud Mailru API response: no SDC cookie'); 153 | case 'token': 154 | trigger_error('Cloud Mailru API response: invalid token'); 155 | default: 156 | trigger_error('Cloud Mailru API response: '.$body); 157 | } 158 | return false; 159 | } 160 | 161 | return $response['body']; 162 | } 163 | 164 | private function getToken() { 165 | if (!$this->token) { 166 | $this->authenticate(); 167 | $this->ensureSdcCookie(); 168 | $response = $this->executeMethod('tokens/csrf'); 169 | $this->token = isset($response['token']) ? $response['token'] : null; 170 | } 171 | return $this->token; 172 | } 173 | 174 | private function authenticate() { 175 | $response = $this->request(static::AUTH_DOMAIN . '/cgi-bin/auth?from=splash'); 176 | 177 | if ($response != 'redirect: https://e.mail.ru/messages/inbox/') { 178 | $response = $this->request(static::AUTH_DOMAIN . '/cgi-bin/auth?from=splash', [ 179 | 'referer' => 'https://mail.ru/', 180 | 'postData' => [ 181 | 'Domain' => 'mail.ru', 182 | 'Login' => $this->login, 183 | 'Password' => $this->password, 184 | 'new_auth_form' => 1, 185 | 'FromAccount' => 1, 186 | 'saveauth' => 1 187 | ] 188 | ]); 189 | 190 | if (strpos($response, 'https://e.mail.ru/messages') === false) { 191 | trigger_error('Cloud Mailru API: wrong authentication result '.$response); 192 | return false; 193 | } 194 | } 195 | return true; 196 | } 197 | 198 | private function ensureSdcCookie() { 199 | $response = $this->request(static::AUTH_DOMAIN . '/sdc?'.http_build_query(['from' => static::CLOUD_DOMAIN . '/home'])); 200 | if (strpos($response, 'redirect') !== false) 201 | $this->request(str_replace('redirect: ', '', $response)); 202 | } 203 | 204 | private function getDispatcher() { 205 | if (!$this->dispatcher) 206 | $this->dispatcher = $this->executeMethod('dispatcher'); 207 | return $this->dispatcher; 208 | } 209 | 210 | public function getUploadUrl() { 211 | $nodes = array_column($this->getDispatcher()['upload'], 'url'); 212 | return $nodes[mt_rand(0, count($nodes) - 1)]; 213 | } 214 | 215 | public function getDownloadUrl() { 216 | $nodes = array_column($this->getDispatcher()['get'], 'url'); 217 | return $nodes[mt_rand(0, count($nodes) - 1)]; 218 | } 219 | 220 | public function getVideoUrl() { 221 | $nodes = array_column($this->getDispatcher()['video'], 'url'); 222 | return $nodes[mt_rand(0, count($nodes) - 1)]; 223 | } 224 | 225 | public function getVideoThumbUrl() { 226 | $nodes = array_column($this->getDispatcher()['thumbnails'], 'url'); 227 | return $nodes[mt_rand(0, count($nodes) - 1)]; 228 | } 229 | 230 | private function request($url, $options = []) { 231 | curl_reset($this->curl); 232 | 233 | $userAgent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'; 234 | $connectTimeout = isset($options['connectTimeout']) ? $options['connectTimeout'] : 60; 235 | 236 | curl_setopt($this->curl, CURLOPT_URL, $url); 237 | curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); 238 | curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false); 239 | curl_setopt($this->curl, CURLOPT_HEADER, 1); 240 | curl_setopt($this->curl, CURLOPT_USERAGENT, $userAgent); 241 | curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, $connectTimeout); 242 | curl_setopt($this->curl, CURLOPT_TIMEOUT, $connectTimeout); 243 | curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); 244 | 245 | if (isset($options['postData'])) { 246 | curl_setopt($this->curl, CURLOPT_POST, 1); 247 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($options['postData'])); 248 | } else { 249 | curl_setopt($this->curl, CURLOPT_POST, 0); 250 | } 251 | 252 | if (isset($options['uploadData'])) { 253 | $filename = isset($options['uploadData']['filename']) ? $options['uploadData']['filename'] : basename($options['uploadData']['filepath']); 254 | $cFile = new \CURLFile($options['uploadData']['filepath'], '', $filename); 255 | curl_setopt($this->curl, CURLOPT_POST, 1); 256 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, ['file' => $cFile]); 257 | array_merge(isset($options['header']) ? $options['header'] : [], ['Expect:', 'Accept-Encoding:', 'Content-Type: multipart/form-data']); 258 | } 259 | 260 | if (isset($options['referer'])) { 261 | curl_setopt($this->curl, CURLOPT_REFERER, $options['referer']); 262 | } 263 | 264 | if (isset($options['header'])) { 265 | curl_setopt($this->curl, CURLOPT_HTTPHEADER, $options['header']); 266 | } 267 | 268 | if (isset($options['filehandle'])) { 269 | curl_setopt($this->curl, CURLOPT_FILE, $options['filehandle']); 270 | curl_setopt($this->curl, CURLOPT_HEADER, 0); 271 | } 272 | 273 | $cookiePath = APP_DIR . '/cache/temp_cookie.dat'; 274 | if (!file_exists($cookiePath)) file_put_contents($cookiePath, ''); 275 | curl_setopt($this->curl, CURLOPT_COOKIEJAR, $cookiePath); 276 | curl_setopt($this->curl, CURLOPT_COOKIEFILE, $cookiePath); 277 | 278 | $result = curl_exec($this->curl); 279 | $response = curl_getinfo($this->curl); 280 | $error = curl_error($this->curl); 281 | 282 | if ($error) { 283 | trigger_error("Mailru request error: ".$error." in ".$url); 284 | return false; 285 | } 286 | 287 | if (isset($response['http_code']) && ($response['http_code'] == 301 || $response['http_code'] == 302)) { 288 | return'redirect: ' . $response['redirect_url']; 289 | } else { 290 | return substr($result, curl_getinfo($this->curl, CURLINFO_HEADER_SIZE)); 291 | } 292 | } 293 | } -------------------------------------------------------------------------------- /public/assets/js/collagePlusPlus.js: -------------------------------------------------------------------------------- 1 | ;(function( $ ) { 2 | 3 | $.fn.collagePlusPlus = function( options ) { 4 | 5 | return this.each(function() { 6 | 7 | /* 8 | * 9 | * set up vars 10 | * 11 | */ 12 | 13 | // track row width by adding images, padding and css borders etc 14 | var row = 0, 15 | // collect elements to be re-sized in current row 16 | elements = [], 17 | // track the number of rows generated 18 | rownum = 1, 19 | // needed for creating some additional defaults that are actually obtained 20 | // from the dom, which maybe doesn't make them defaults ?! 21 | $this = $(this), 22 | rowOffsetTop = 0; 23 | 24 | 25 | // width of the area the collage will be in 26 | $.fn.collagePlusPlus.defaults.albumWidth = $this.width(); 27 | // padding between the images. Using padding left as we assume padding is even all the way round 28 | $.fn.collagePlusPlus.defaults.padding = parseFloat( $this.css('padding-left') ); 29 | // object that contains the images to collage 30 | $.fn.collagePlusPlus.defaults.images = $this.children(); 31 | 32 | var settings = $.extend({}, $.fn.collagePlusPlus.defaults, options); 33 | 34 | settings.images.each( 35 | function(index){ 36 | 37 | /* 38 | * 39 | * Cache selector 40 | * Even if first child is not an image the whole sizing is based on images 41 | * so where we take measurements, we take them on the images 42 | * 43 | */ 44 | var $this = $(this), 45 | $img = ($this.is("img")) ? $this : $(this).find("img"); 46 | 47 | 48 | 49 | /* 50 | * 51 | * get the current image size. Get image size in this order 52 | * 53 | * 1. from tag 54 | * 2. from data set from initial calculation 55 | * 3. after loading the image and checking it's actual size 56 | * 57 | */ 58 | var w = (typeof $img.data("width") != 'undefined') ? $img.data("width") : $img.width(), 59 | h = (typeof $img.data("height") != 'undefined') ? $img.data("height") : $img.height(); 60 | 61 | 62 | 63 | /* 64 | * 65 | * Get any current additional properties that may affect the width or height 66 | * like css borders for example 67 | * 68 | */ 69 | var imgParams = getImgProperty($img); 70 | 71 | 72 | /* 73 | * 74 | * store the original size for resize events 75 | * 76 | */ 77 | $img.data("width", w); 78 | $img.data("height", h); 79 | 80 | 81 | 82 | /* 83 | * 84 | * calculate the w/h based on target height 85 | * this is our ideal size, but later we'll resize to make it fit 86 | * 87 | */ 88 | var targetHeight = settings.secondaryRowsTargetHeight; 89 | if (settings.firstRowTargetHeight && rownum == 1) { 90 | targetHeight = settings.firstRowTargetHeight; 91 | } 92 | 93 | var nw = Math.ceil(w/h*targetHeight), 94 | nh = Math.ceil(targetHeight); 95 | 96 | /* 97 | * 98 | * Keep track of which images are in our row so far 99 | * 100 | */ 101 | elements.push([this, nw, nh, imgParams['w'], imgParams['h']]); 102 | 103 | /* 104 | * 105 | * calculate the width of the element including extra properties 106 | * like css borders 107 | * 108 | */ 109 | row += nw + imgParams['w'] + settings.padding; 110 | 111 | /* 112 | * 113 | * if the current row width is wider than the parent container 114 | * it's time to make a row out of our images 115 | * 116 | */ 117 | if ( (row > settings.albumWidth || settings.images.length-1 == index) && elements.length != 0 ){ 118 | 119 | // call the method that calculates the final image sizes 120 | resizeRow(elements, row, settings, rownum, rowOffsetTop); 121 | 122 | // reset our row 123 | delete row; 124 | delete elements; 125 | row = 0; 126 | elements = []; 127 | rownum += 1; 128 | rowOffsetTop += $this.is(':visible') ? ($this.height() + settings.padding) : 0; 129 | $this.parent().height(rowOffsetTop - settings.padding); 130 | } 131 | 132 | if (index == settings.images.length - 1) 133 | $this.parent().addClass('inited'); 134 | } 135 | ); 136 | }); 137 | 138 | function resizeRow(obj, row, settings, rownum, rowOffsetTop) { 139 | 140 | /* 141 | * 142 | * How much bigger is this row than the available space? 143 | * At this point we have adjusted the images height to fit our target height 144 | * so the image size will already be different from the original. 145 | * The resizing we're doing here is to adjust it to the album width. 146 | * 147 | * We also need to change the album width (basically available space) by 148 | * the amount of padding and css borders for the images otherwise 149 | * this will skew the result. 150 | * 151 | * This is because padding and borders remain at a fixed size and we only 152 | * need to scale the images. 153 | * 154 | */ 155 | var imageExtras = (settings.padding * (obj.length - 2)) + (obj.length * obj[0][3]), 156 | albumWidthAdjusted = settings.albumWidth - imageExtras, 157 | overPercent = albumWidthAdjusted / (row - imageExtras), 158 | // start tracking our width with know values that will make up the total width 159 | // like borders and padding 160 | trackWidth = imageExtras, 161 | // guess whether this is the last row in a set by checking if the width is less 162 | // than the parent width. 163 | lastRow = (row < settings.albumWidth ? true : false), 164 | imageOffsetLeft = 0; 165 | 166 | /* 167 | * Resize the images by the above % so that they'll fit in the album space 168 | */ 169 | for (var i = 0; i < obj.length; i++) { 170 | 171 | 172 | 173 | var $obj = $(obj[i][0]), 174 | fw = Math.floor(obj[i][1] * overPercent), 175 | fh = Math.floor(obj[i][2] * overPercent), 176 | isNotLast = !!(( i < obj.length - 1 )); 177 | 178 | if (settings.visibleRowCount && rownum > settings.visibleRowCount) { 179 | $obj.parent().addClass('limited'); 180 | $obj.addClass('hidden'); 181 | } else { 182 | $obj.parent().removeClass('limited'); 183 | $obj.removeClass('hidden'); 184 | } 185 | 186 | /* 187 | * Checking if the user wants to not stretch the images of the last row to fit the 188 | * parent element size 189 | */ 190 | if(settings.allowPartialLastRow === true && lastRow === true){ 191 | fw = obj[i][1]; 192 | fh = obj[i][2]; 193 | } 194 | 195 | /* 196 | * 197 | * Because we use % to calculate the widths, it's possible that they are 198 | * a few pixels out in which case we need to track this and adjust the 199 | * last image accordingly 200 | * 201 | */ 202 | trackWidth += fw; 203 | 204 | 205 | /* 206 | * 207 | * here we check if the combined images are exactly the width 208 | * of the parent. If not then we add a few pixels on to make 209 | * up the difference. 210 | * 211 | * This will alter the aspect ratio of the image slightly, but 212 | * by a noticable amount. 213 | * 214 | * If the user doesn't want full width last row, we check for that here 215 | * 216 | */ 217 | if(!isNotLast && trackWidth < settings.albumWidth){ 218 | if(settings.allowPartialLastRow === true && lastRow === true){ 219 | fw = fw; 220 | }else{ 221 | fw = fw + (settings.albumWidth - trackWidth); 222 | } 223 | } 224 | 225 | /* 226 | * 227 | * We'll be doing a few things to the image so here we cache the image selector 228 | * 229 | * 230 | */ 231 | var $img = ( $obj.is("img") ) ? $obj : $obj.find("img"); 232 | 233 | /* 234 | * 235 | * Set the width of the image and parent element 236 | * if the resized element is not an image, we apply it to the child image also 237 | * 238 | * We need to check if it's an image as the css borders are only measured on 239 | * images. If the parent is a div, we need make the contained image smaller 240 | * to accommodate the css image borders. 241 | * 242 | */ 243 | $img.width(fw); 244 | if( !$obj.is("img") ){ 245 | $obj.width(fw + obj[i][3]); 246 | } 247 | 248 | 249 | /* 250 | * 251 | * Set the height of the image 252 | * if the resized element is not an image, we apply it to the child image also 253 | * 254 | */ 255 | $img.height(fh); 256 | if( !$obj.is("img") ){ 257 | $obj.height(fh + obj[i][4]); 258 | } 259 | 260 | 261 | /* 262 | * 263 | * Set image position 264 | * 265 | */ 266 | $obj.css({'top': rowOffsetTop, 'left': imageOffsetLeft, 'visibility': 'visible'}); 267 | imageOffsetLeft += $obj.is(':visible') ? ($obj.width() + settings.padding) : 0; 268 | } 269 | } 270 | 271 | 272 | /* 273 | * 274 | * This private function calculates any extras like padding, border associated 275 | * with the image that will impact on the width calculations 276 | * 277 | */ 278 | function getImgProperty( img ) 279 | { 280 | $img = $(img); 281 | var params = new Array(); 282 | params["w"] = (parseFloat($img.css("border-left-width")) + parseFloat($img.css("border-right-width"))); 283 | params["h"] = (parseFloat($img.css("border-top-width")) + parseFloat($img.css("border-bottom-width"))); 284 | return params; 285 | } 286 | 287 | }; 288 | 289 | $.fn.collagePlusPlus.defaults = { 290 | // the ideal height of images in first row 291 | 'firstRowTargetHeight': 400, 292 | // the ideal height you want your secondary images to be 293 | 'secondaryRowsTargetHeight': 400, 294 | // Sometimes there is just one image on the last row and it gets blown up to a huge size to fit the 295 | // parent div width. To stop this behaviour, set this to true 296 | 'allowPartialLastRow': false, 297 | // Set for visible images limitation 298 | 'visibleRowCount': false 299 | }; 300 | 301 | })( jQuery ); 302 | -------------------------------------------------------------------------------- /public/assets/lib/jquery-ui/jquery-ui.theme.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2016-12-29 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} -------------------------------------------------------------------------------- /template/entries.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 |
21 |
22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | (приложить файлы) 40 | 41 |
42 | 43 |
44 |
45 |
46 | 47 | 48 | 49 |
50 |
51 | 52 |
53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | 63 | attachments as $attachment): ?> 64 | 65 | 66 |
67 | 68 | 69 | 70 |
71 | 72 |
73 | 74 | 75 | 76 |
77 | 78 | 79 | 80 | 81 |
82 |
83 | 84 |
85 |

86 | 87 | 88 |
89 | 90 |
91 |
92 |
93 | (приложить файлы) 94 | 95 | 96 |
97 | 98 | 99 |
100 |
101 | 102 |
103 |
104 |
105 |
    106 |
  • Редактировать запись
  • 107 |
  • Удалить запись
  • 108 |
109 |
110 | #\1', nl2br($entry->text)) ?> 111 | \0', $text) ?> 112 |

113 | attachments)): ?> 114 |
115 |
120 | 121 | attachments as $attachment): ?> 122 | 123 | 124 |
125 | 128 | 129 | 130 |
131 | 132 |
133 | 134 | 135 | 136 |
137 |
138 | 139 | 140 | 141 | 142 |
143 |
144 | 145 | 146 |
147 |
148 | 149 | 150 |
151 | 154 | 155 |
156 | 157 | 158 | 159 | 160 |
161 |
162 | 163 |
164 |
165 |
166 | 167 | 168 |
169 | 170 | Еще записи 171 | 172 |
173 | 174 |
175 |

Записи не найдены

176 |
177 | 178 |
179 |
180 |
181 | 182 | -------------------------------------------------------------------------------- /public/assets/lib/jquery-ui/jquery-ui.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2016-12-29 2 | * http://jqueryui.com 3 | * Includes: draggable.css, core.css, resizable.css, selectable.css, sortable.css, theme.css 4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=base&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=aaaaaa&iconColorError=cc0000&fcError=5f3f3f&borderColorError=f1a899&bgTextureError=flat&bgColorError=fddfdf&iconColorHighlight=777620&fcHighlight=777620&borderColorHighlight=dad55e&bgTextureHighlight=flat&bgColorHighlight=fffa90&iconColorActive=ffffff&fcActive=ffffff&borderColorActive=003eff&bgTextureActive=flat&bgColorActive=007fff&iconColorHover=555555&fcHover=2b2b2b&borderColorHover=cccccc&bgTextureHover=flat&bgColorHover=ededed&iconColorDefault=777777&fcDefault=454545&borderColorDefault=c5c5c5&bgTextureDefault=flat&bgColorDefault=f6f6f6&iconColorContent=444444&fcContent=333333&borderColorContent=dddddd&bgTextureContent=flat&bgColorContent=ffffff&iconColorHeader=444444&fcHeader=333333&borderColorHeader=dddddd&bgTextureHeader=flat&bgColorHeader=e9e9e9&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif 5 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 6 | 7 | .ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} -------------------------------------------------------------------------------- /public/assets/js/core.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | function bindPlugins(elem) { 3 | elem.find('.entry-form .media-prev').sortable({ 4 | placeholder: "preview-placeholder", 5 | stop: function(event, ui) { 6 | var mediaPrevEl = $(ui.item).parent(); 7 | var form = mediaPrevEl.parents('.entry-form'); 8 | collage( 9 | mediaPrevEl, 10 | form.find('input[name=first_row_height_percent]').val(), 11 | form.find('input[name=secondary_rows_height_percent]').val(), 12 | form.find('input[name=visible_row_count]').val() 13 | ); 14 | } 15 | }); 16 | 17 | elem.find('.entry-form .without-prev').sortable(); 18 | 19 | elem.find('.attachment-input').each(function() { 20 | $(this).fileupload({ 21 | url: base_url + 'attachments/upload', 22 | dropZone: $(this).parents('form'), 23 | add: function (e, data) { 24 | var attachmentBlock = $('
', {'class': 'item working'}).append( 25 | $('
', {'class': 'progress'}).append( 26 | $('
', {'class': 'progress-bar progress-bar-striped active', 'role': 'progressbar', 'style': 'width:0%'}) 27 | ), 28 | $('

').text(data.files[0].name), 29 | $('') 30 | ); 31 | 32 | data.context = attachmentBlock.appendTo($(this).parents('.entry-form').find('.upload-statuses')); 33 | attachmentBlock.find('span').click(function() { 34 | if (attachmentBlock.hasClass('working')) { 35 | jqXHR.abort(); 36 | } 37 | attachmentBlock.fadeOut(function() { 38 | attachmentBlock.remove(); 39 | }); 40 | }); 41 | 42 | var jqXHR = data.submit().success(function(result, textStatus, jqXHR) { 43 | result = JSON.parse(result); 44 | if (result.status != 'success') { 45 | data.context.addClass('error'); 46 | } else { 47 | if (result.preview_url) { 48 | var preview = $('', {'src': result.preview_url+'?t='+(new Date()).getTime()}); 49 | $('').load(function() { 50 | attachmentBlock.empty().append($('', {'type': 'hidden', 'name': 'attachments[]', 'value': result.filename})).css({'visibility': 'hidden'}); 51 | var mediaPreviewsBlock = attachmentBlock.parents('.entry-form').find('.media-prev'); 52 | attachmentBlock.append(preview, $('', {'class': 'remove'})); 53 | attachmentBlock.appendTo(mediaPreviewsBlock); 54 | 55 | var form = mediaPreviewsBlock.parents('.entry-form').addClass('media-added'); 56 | collage( 57 | mediaPreviewsBlock, 58 | form.find('input[name=first_row_height_percent]').val(), 59 | form.find('input[name=secondary_rows_height_percent]').val(), 60 | form.find('input[name=visible_row_count]').val() 61 | ); 62 | }).attr('src', preview.attr('src')); 63 | } else { 64 | attachmentBlock.empty().append( 65 | $('', {'type': 'hidden', 'name': 'attachments[]', 'value': result.filename}), 66 | $('

').text(result.filename), 67 | $('', {'class': 'remove'}) 68 | ); 69 | attachmentBlock.appendTo(attachmentBlock.parents('.entry-form').find('.without-prev')); 70 | } 71 | } 72 | }); 73 | }, 74 | done: function(e, data) { 75 | data.context.removeClass('working'); 76 | }, 77 | progress: function(e, data){ 78 | var progress = parseInt(data.loaded / data.total * 100, 10); 79 | data.context.find('.progress-bar').css('width', progress + '%'); 80 | }, 81 | fail: function (e, data) { 82 | data.context.addClass('error'); 83 | } 84 | }); 85 | }); 86 | 87 | elem.find('.fancybox').fancybox({ 88 | afterLoad: function() { 89 | this.title += 'Картинка ' + (this.index + 1) + ' из ' + this.group.length + '
' + 'Открыть оригинал'; 90 | } 91 | }); 92 | 93 | elem.find('.player').each(function() { 94 | $(this).flowplayer({ 95 | tooltip: false, 96 | splash: true, 97 | embed: false, 98 | live: false, 99 | hlsjs: true, 100 | overlay: { 101 | vendor: "fancybox", 102 | trigger: '#' + $(this).attr('data-trigger') 103 | }, 104 | clip: { 105 | sources: [{ 106 | type: "application/x-mpegurl", 107 | src: $(this).attr('data-url') 108 | }] 109 | } 110 | }); 111 | }); 112 | 113 | elem.find('.attachments .media-prev').each(function() { 114 | collage( 115 | $(this), 116 | $(this).attr('data-first-row-height-percent'), 117 | $(this).attr('data-secondary-rows-height-percent'), 118 | $(this).attr('data-visible-row-count') 119 | ); 120 | }); 121 | 122 | elem.find('.media-prev').each(function() { 123 | if ($(this).find('*').length) 124 | $(this).parents('form').addClass('media-added'); 125 | }); 126 | 127 | elem.find('.media-prev, .without-prev, .upload-statuses').removeWhitespace(); 128 | 129 | autosize(elem.find('.entry-form textarea')); 130 | }; 131 | 132 | function collage(elem, firstRowHeightPercent, secondaryRowsHeightPercent, visibleRowCount) { 133 | var container = $(elem); 134 | var imgs = $(elem).find('img'); 135 | var imgCount = imgs.length; 136 | var counter = 0; 137 | 138 | imgs.each(function(i) { 139 | var img = $(this); 140 | $('').load(function() { 141 | if(++counter === imgCount) { 142 | container.collagePlusPlus({ 143 | 'firstRowTargetHeight': firstRowHeightPercent * container.width() / 100, 144 | 'secondaryRowsTargetHeight': secondaryRowsHeightPercent * container.width() / 100, 145 | 'visibleRowCount': visibleRowCount, 146 | 'allowPartialLastRow' : true 147 | }); 148 | } 149 | }).attr('src', img.attr('src')); 150 | }); 151 | } 152 | 153 | bindPlugins($('.entry-list')); 154 | 155 | var resizeTimer = null; 156 | $(window).bind('resize', function() { 157 | if (resizeTimer) clearTimeout(resizeTimer); 158 | resizeTimer = setTimeout(function() { 159 | $('.media-prev:visible').each(function() { 160 | var firstRowHeightPercent = $(this).attr('data-first-row-height-percent'); 161 | var secondaryRowsHeightPercent = $(this).attr('data-secondary-rows-height-percent'); 162 | var visibleRowCount = $(this).siblings('.show-all-attachments').is(':not(.shown)') ? $(this).attr('data-visible-row-count') : false; 163 | 164 | if ($(this).parents('.entry-form').length) { 165 | var form = $(this).parents('.entry-form'); 166 | firstRowHeightPercent = form.find('input[name=first_row_height_percent]').val(); 167 | secondaryRowsHeightPercent = form.find('input[name=secondary_rows_height_percent]').val(); 168 | visibleRowCount = form.find('input[name=visible_row_count]').val(); 169 | } 170 | collage($(this), firstRowHeightPercent, secondaryRowsHeightPercent, visibleRowCount); 171 | }); 172 | }, 50); 173 | }); 174 | 175 | $(document).on('click', '.entry-form .add-attachment', function(e) { 176 | e.preventDefault(); 177 | $(this).parents('.entry-form').find('input[type=file]').click(); 178 | }); 179 | 180 | $(document).on('click', '.entry-form .upload-statuses .remove, .entry-form .without-prev .remove', function(e) { 181 | e.preventDefault(); 182 | $(this).parent().remove(); 183 | }); 184 | 185 | $(document).on('click', '.entry-form .media-prev .remove', function(e) { 186 | e.preventDefault(); 187 | var form = $(this).parents('.entry-form'); 188 | $(this).parent().remove(); 189 | collage( 190 | form.find('.media-prev'), 191 | form.find('input[name=first_row_height_percent]').val(), 192 | form.find('input[name=secondary_rows_height_percent]').val(), 193 | form.find('input[name=visible_row_count]').val() 194 | ); 195 | if (!form.find('.media-prev *').length) 196 | form.removeClass('media-added'); 197 | }); 198 | 199 | $(document).on('click', '.entry .actions .edit', function(e) { 200 | e.preventDefault(); 201 | $('.entry').removeClass('editing'); 202 | $(this).parents('.entry').addClass('editing'); 203 | var form =$(this).parents('.entry').find('.entry-form'); 204 | collage( 205 | form.find('.media-prev'), 206 | form.find('input[name=first_row_height_percent]').val(), 207 | form.find('input[name=secondary_rows_height_percent]').val(), 208 | form.find('input[name=visible_row_count]').val() 209 | ); 210 | autosize.update(form.find('textarea')); 211 | }); 212 | 213 | $(document).on('click', '.entry .cancel', function(e) { 214 | e.preventDefault(); 215 | var entryEl = $(this).parents('.entry').removeClass('editing'); 216 | var mediaPrevEl = entryEl.find('.attachments .media-prev'); 217 | collage( 218 | mediaPrevEl, 219 | mediaPrevEl.attr('data-first-row-height-percent'), 220 | mediaPrevEl.attr('data-secondary-rows-height-percent'), 221 | mediaPrevEl.siblings('.show-all-attachments').is(':not(.shown)') ? mediaPrevEl.attr('data-visible-row-count') : false 222 | ); 223 | }); 224 | 225 | $(document).on('click', '.entry .actions .remove', function(e) { 226 | e.preventDefault(); 227 | 228 | var entryEl = $(this).parents('.entry'); 229 | var entryId = entryEl.find('input[name=entry_id]').val(); 230 | entryEl.remove(); 231 | $.post(location.href, {action: 'delete_entry', entry_id: entryId}, function() { 232 | $.get(base_url + 'sync-entries'); 233 | }); 234 | }); 235 | 236 | $(document).on('submit', '.entry-form', function(e) { 237 | e.preventDefault(); 238 | if (!$(this).find('textarea').val() && !$(this).find('.media-prev div').length && !$(this).find('.without-prev div').length || $(this).find('.upload-statuses div').length) { 239 | return false; 240 | } 241 | 242 | var form = $(this); 243 | var entryId = form.find('input[name=entry_id]').val(); 244 | var postData = $(this).serializeArray(); 245 | form.parent().addClass('loading'); 246 | postData.push({name: 'action', value: 'edit_entry'}); 247 | $.post(location.href, postData, function(html) { 248 | form.parent().removeClass('loading'); 249 | if (!html) return; 250 | if (entryId) { 251 | $('.entry[data-entry-id='+entryId+']').replaceWith($(html).find('.entry[data-entry-id='+entryId+']')); 252 | bindPlugins($('.entry[data-entry-id='+entryId+']')); 253 | } else { 254 | $('.entry-list').replaceWith($(html).find('.entry-list')); 255 | bindPlugins($('.entry-list')); 256 | } 257 | 258 | $.get(base_url + 'sync-entries'); 259 | }); 260 | }); 261 | 262 | var searchTimeout; 263 | $(document).on('input propertychange', '#search input', function() { 264 | var searchCriteria = $(this).val(); 265 | clearTimeout(searchTimeout); 266 | searchTimeout = setTimeout(function() { 267 | $.get(location.pathname, {search: searchCriteria}, (function(requestSearchTimeout) { 268 | return function(html) { 269 | if (requestSearchTimeout != searchTimeout) return; 270 | 271 | $('.entry-list').replaceWith($(html).find('.entry-list')); 272 | bindPlugins($('.entry-list')); 273 | } 274 | })(searchTimeout)); 275 | }, 350); 276 | }); 277 | 278 | $('body').infinitescroll({ 279 | loading: { 280 | finishedMsg: "", 281 | msg: $('', {'class': 'page-loading'}), 282 | msgText: "", 283 | selector: ".entry-list", 284 | finished: null 285 | }, 286 | nextSelector: ".load-more a", 287 | navSelector: ".load-more", 288 | itemSelector : ".entry", 289 | appendCallback: false, 290 | errorCallback: function () { 291 | $("span.page-loading").remove(); 292 | } 293 | }, function(newEntries, opts) { 294 | if (newEntries.length) { 295 | $(newEntries).insertBefore($('.load-more')); 296 | bindPlugins($(newEntries)); 297 | } 298 | }); 299 | 300 | $(document).on('click', '.hash-tag', function(e) { 301 | e.preventDefault(); 302 | $('#search input').val($(this).text()).trigger('input'); 303 | }); 304 | 305 | $(document).on('click', '.show-all-attachments a', function(e) { 306 | e.preventDefault(); 307 | $(this).parent().toggleClass('shown'); 308 | var entryEl = $(this).parents('.entry'); 309 | var mediaPrevEl = entryEl.find('.attachments .media-prev'); 310 | collage( 311 | mediaPrevEl, 312 | mediaPrevEl.attr('data-first-row-height-percent'), 313 | mediaPrevEl.attr('data-secondary-rows-height-percent'), 314 | $(this).is('.show-all') ? false : mediaPrevEl.attr('data-visible-row-count') 315 | ); 316 | }); 317 | 318 | $(document).on('focus', '.add-entry textarea', function() { 319 | $(this).parents('.add-entry').addClass('full'); 320 | }); 321 | 322 | $(document).on('click', '.add-entry', function(e) { 323 | e.stopPropagation(); 324 | }); 325 | 326 | $(document).on('click', function() { 327 | if (!$('.add-entry textarea').val() && !$('.add-entry .media-prev div, .add-entry .upload-statuses div, .add-entry .without-prev div').length) { 328 | $('.add-entry').removeClass('full'); 329 | } 330 | }); 331 | 332 | var resizeTimeout; 333 | $(document).on('input', '.range-control', function(e) { 334 | e.preventDefault(); 335 | var form = $(this).parents('.entry-form'); 336 | clearTimeout(resizeTimeout); 337 | 338 | resizeTimeout = setTimeout(function() { 339 | collage( 340 | form.find('.media-prev'), 341 | form.find('input[name=first_row_height_percent]').val(), 342 | form.find('input[name=secondary_rows_height_percent]').val(), 343 | form.find('input[name=visible_row_count]').val() 344 | ); 345 | }, 10); 346 | }); 347 | }); -------------------------------------------------------------------------------- /public/assets/lib/jquery-fileupload/jquery.ui.widget.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Widget 1.10.1+amd 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013 jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/jQuery.widget/ 10 | */ 11 | 12 | (function (factory) { 13 | if (typeof define === "function" && define.amd) { 14 | // Register as an anonymous AMD module: 15 | define(["jquery"], factory); 16 | } else { 17 | // Browser globals: 18 | factory(jQuery); 19 | } 20 | }(function( $, undefined ) { 21 | 22 | var uuid = 0, 23 | slice = Array.prototype.slice, 24 | _cleanData = $.cleanData; 25 | $.cleanData = function( elems ) { 26 | for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 27 | try { 28 | $( elem ).triggerHandler( "remove" ); 29 | // http://bugs.jquery.com/ticket/8235 30 | } catch( e ) {} 31 | } 32 | _cleanData( elems ); 33 | }; 34 | 35 | $.widget = function( name, base, prototype ) { 36 | var fullName, existingConstructor, constructor, basePrototype, 37 | // proxiedPrototype allows the provided prototype to remain unmodified 38 | // so that it can be used as a mixin for multiple widgets (#8876) 39 | proxiedPrototype = {}, 40 | namespace = name.split( "." )[ 0 ]; 41 | 42 | name = name.split( "." )[ 1 ]; 43 | fullName = namespace + "-" + name; 44 | 45 | if ( !prototype ) { 46 | prototype = base; 47 | base = $.Widget; 48 | } 49 | 50 | // create selector for plugin 51 | $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { 52 | return !!$.data( elem, fullName ); 53 | }; 54 | 55 | $[ namespace ] = $[ namespace ] || {}; 56 | existingConstructor = $[ namespace ][ name ]; 57 | constructor = $[ namespace ][ name ] = function( options, element ) { 58 | // allow instantiation without "new" keyword 59 | if ( !this._createWidget ) { 60 | return new constructor( options, element ); 61 | } 62 | 63 | // allow instantiation without initializing for simple inheritance 64 | // must use "new" keyword (the code above always passes args) 65 | if ( arguments.length ) { 66 | this._createWidget( options, element ); 67 | } 68 | }; 69 | // extend with the existing constructor to carry over any static properties 70 | $.extend( constructor, existingConstructor, { 71 | version: prototype.version, 72 | // copy the object used to create the prototype in case we need to 73 | // redefine the widget later 74 | _proto: $.extend( {}, prototype ), 75 | // track widgets that inherit from this widget in case this widget is 76 | // redefined after a widget inherits from it 77 | _childConstructors: [] 78 | }); 79 | 80 | basePrototype = new base(); 81 | // we need to make the options hash a property directly on the new instance 82 | // otherwise we'll modify the options hash on the prototype that we're 83 | // inheriting from 84 | basePrototype.options = $.widget.extend( {}, basePrototype.options ); 85 | $.each( prototype, function( prop, value ) { 86 | if ( !$.isFunction( value ) ) { 87 | proxiedPrototype[ prop ] = value; 88 | return; 89 | } 90 | proxiedPrototype[ prop ] = (function() { 91 | var _super = function() { 92 | return base.prototype[ prop ].apply( this, arguments ); 93 | }, 94 | _superApply = function( args ) { 95 | return base.prototype[ prop ].apply( this, args ); 96 | }; 97 | return function() { 98 | var __super = this._super, 99 | __superApply = this._superApply, 100 | returnValue; 101 | 102 | this._super = _super; 103 | this._superApply = _superApply; 104 | 105 | returnValue = value.apply( this, arguments ); 106 | 107 | this._super = __super; 108 | this._superApply = __superApply; 109 | 110 | return returnValue; 111 | }; 112 | })(); 113 | }); 114 | constructor.prototype = $.widget.extend( basePrototype, { 115 | // TODO: remove support for widgetEventPrefix 116 | // always use the name + a colon as the prefix, e.g., draggable:start 117 | // don't prefix for widgets that aren't DOM-based 118 | widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name 119 | }, proxiedPrototype, { 120 | constructor: constructor, 121 | namespace: namespace, 122 | widgetName: name, 123 | widgetFullName: fullName 124 | }); 125 | 126 | // If this widget is being redefined then we need to find all widgets that 127 | // are inheriting from it and redefine all of them so that they inherit from 128 | // the new version of this widget. We're essentially trying to replace one 129 | // level in the prototype chain. 130 | if ( existingConstructor ) { 131 | $.each( existingConstructor._childConstructors, function( i, child ) { 132 | var childPrototype = child.prototype; 133 | 134 | // redefine the child widget using the same prototype that was 135 | // originally used, but inherit from the new version of the base 136 | $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); 137 | }); 138 | // remove the list of existing child constructors from the old constructor 139 | // so the old child constructors can be garbage collected 140 | delete existingConstructor._childConstructors; 141 | } else { 142 | base._childConstructors.push( constructor ); 143 | } 144 | 145 | $.widget.bridge( name, constructor ); 146 | }; 147 | 148 | $.widget.extend = function( target ) { 149 | var input = slice.call( arguments, 1 ), 150 | inputIndex = 0, 151 | inputLength = input.length, 152 | key, 153 | value; 154 | for ( ; inputIndex < inputLength; inputIndex++ ) { 155 | for ( key in input[ inputIndex ] ) { 156 | value = input[ inputIndex ][ key ]; 157 | if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { 158 | // Clone objects 159 | if ( $.isPlainObject( value ) ) { 160 | target[ key ] = $.isPlainObject( target[ key ] ) ? 161 | $.widget.extend( {}, target[ key ], value ) : 162 | // Don't extend strings, arrays, etc. with objects 163 | $.widget.extend( {}, value ); 164 | // Copy everything else by reference 165 | } else { 166 | target[ key ] = value; 167 | } 168 | } 169 | } 170 | } 171 | return target; 172 | }; 173 | 174 | $.widget.bridge = function( name, object ) { 175 | var fullName = object.prototype.widgetFullName || name; 176 | $.fn[ name ] = function( options ) { 177 | var isMethodCall = typeof options === "string", 178 | args = slice.call( arguments, 1 ), 179 | returnValue = this; 180 | 181 | // allow multiple hashes to be passed on init 182 | options = !isMethodCall && args.length ? 183 | $.widget.extend.apply( null, [ options ].concat(args) ) : 184 | options; 185 | 186 | if ( isMethodCall ) { 187 | this.each(function() { 188 | var methodValue, 189 | instance = $.data( this, fullName ); 190 | if ( !instance ) { 191 | return $.error( "cannot call methods on " + name + " prior to initialization; " + 192 | "attempted to call method '" + options + "'" ); 193 | } 194 | if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { 195 | return $.error( "no such method '" + options + "' for " + name + " widget instance" ); 196 | } 197 | methodValue = instance[ options ].apply( instance, args ); 198 | if ( methodValue !== instance && methodValue !== undefined ) { 199 | returnValue = methodValue && methodValue.jquery ? 200 | returnValue.pushStack( methodValue.get() ) : 201 | methodValue; 202 | return false; 203 | } 204 | }); 205 | } else { 206 | this.each(function() { 207 | var instance = $.data( this, fullName ); 208 | if ( instance ) { 209 | instance.option( options || {} )._init(); 210 | } else { 211 | $.data( this, fullName, new object( options, this ) ); 212 | } 213 | }); 214 | } 215 | 216 | return returnValue; 217 | }; 218 | }; 219 | 220 | $.Widget = function( /* options, element */ ) {}; 221 | $.Widget._childConstructors = []; 222 | 223 | $.Widget.prototype = { 224 | widgetName: "widget", 225 | widgetEventPrefix: "", 226 | defaultElement: "

", 227 | options: { 228 | disabled: false, 229 | 230 | // callbacks 231 | create: null 232 | }, 233 | _createWidget: function( options, element ) { 234 | element = $( element || this.defaultElement || this )[ 0 ]; 235 | this.element = $( element ); 236 | this.uuid = uuid++; 237 | this.eventNamespace = "." + this.widgetName + this.uuid; 238 | this.options = $.widget.extend( {}, 239 | this.options, 240 | this._getCreateOptions(), 241 | options ); 242 | 243 | this.bindings = $(); 244 | this.hoverable = $(); 245 | this.focusable = $(); 246 | 247 | if ( element !== this ) { 248 | $.data( element, this.widgetFullName, this ); 249 | this._on( true, this.element, { 250 | remove: function( event ) { 251 | if ( event.target === element ) { 252 | this.destroy(); 253 | } 254 | } 255 | }); 256 | this.document = $( element.style ? 257 | // element within the document 258 | element.ownerDocument : 259 | // element is window or document 260 | element.document || element ); 261 | this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); 262 | } 263 | 264 | this._create(); 265 | this._trigger( "create", null, this._getCreateEventData() ); 266 | this._init(); 267 | }, 268 | _getCreateOptions: $.noop, 269 | _getCreateEventData: $.noop, 270 | _create: $.noop, 271 | _init: $.noop, 272 | 273 | destroy: function() { 274 | this._destroy(); 275 | // we can probably remove the unbind calls in 2.0 276 | // all event bindings should go through this._on() 277 | this.element 278 | .unbind( this.eventNamespace ) 279 | // 1.9 BC for #7810 280 | // TODO remove dual storage 281 | .removeData( this.widgetName ) 282 | .removeData( this.widgetFullName ) 283 | // support: jquery <1.6.3 284 | // http://bugs.jquery.com/ticket/9413 285 | .removeData( $.camelCase( this.widgetFullName ) ); 286 | this.widget() 287 | .unbind( this.eventNamespace ) 288 | .removeAttr( "aria-disabled" ) 289 | .removeClass( 290 | this.widgetFullName + "-disabled " + 291 | "ui-state-disabled" ); 292 | 293 | // clean up events and states 294 | this.bindings.unbind( this.eventNamespace ); 295 | this.hoverable.removeClass( "ui-state-hover" ); 296 | this.focusable.removeClass( "ui-state-focus" ); 297 | }, 298 | _destroy: $.noop, 299 | 300 | widget: function() { 301 | return this.element; 302 | }, 303 | 304 | option: function( key, value ) { 305 | var options = key, 306 | parts, 307 | curOption, 308 | i; 309 | 310 | if ( arguments.length === 0 ) { 311 | // don't return a reference to the internal hash 312 | return $.widget.extend( {}, this.options ); 313 | } 314 | 315 | if ( typeof key === "string" ) { 316 | // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 317 | options = {}; 318 | parts = key.split( "." ); 319 | key = parts.shift(); 320 | if ( parts.length ) { 321 | curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 322 | for ( i = 0; i < parts.length - 1; i++ ) { 323 | curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 324 | curOption = curOption[ parts[ i ] ]; 325 | } 326 | key = parts.pop(); 327 | if ( value === undefined ) { 328 | return curOption[ key ] === undefined ? null : curOption[ key ]; 329 | } 330 | curOption[ key ] = value; 331 | } else { 332 | if ( value === undefined ) { 333 | return this.options[ key ] === undefined ? null : this.options[ key ]; 334 | } 335 | options[ key ] = value; 336 | } 337 | } 338 | 339 | this._setOptions( options ); 340 | 341 | return this; 342 | }, 343 | _setOptions: function( options ) { 344 | var key; 345 | 346 | for ( key in options ) { 347 | this._setOption( key, options[ key ] ); 348 | } 349 | 350 | return this; 351 | }, 352 | _setOption: function( key, value ) { 353 | this.options[ key ] = value; 354 | 355 | if ( key === "disabled" ) { 356 | this.widget() 357 | .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) 358 | .attr( "aria-disabled", value ); 359 | this.hoverable.removeClass( "ui-state-hover" ); 360 | this.focusable.removeClass( "ui-state-focus" ); 361 | } 362 | 363 | return this; 364 | }, 365 | 366 | enable: function() { 367 | return this._setOption( "disabled", false ); 368 | }, 369 | disable: function() { 370 | return this._setOption( "disabled", true ); 371 | }, 372 | 373 | _on: function( suppressDisabledCheck, element, handlers ) { 374 | var delegateElement, 375 | instance = this; 376 | 377 | // no suppressDisabledCheck flag, shuffle arguments 378 | if ( typeof suppressDisabledCheck !== "boolean" ) { 379 | handlers = element; 380 | element = suppressDisabledCheck; 381 | suppressDisabledCheck = false; 382 | } 383 | 384 | // no element argument, shuffle and use this.element 385 | if ( !handlers ) { 386 | handlers = element; 387 | element = this.element; 388 | delegateElement = this.widget(); 389 | } else { 390 | // accept selectors, DOM elements 391 | element = delegateElement = $( element ); 392 | this.bindings = this.bindings.add( element ); 393 | } 394 | 395 | $.each( handlers, function( event, handler ) { 396 | function handlerProxy() { 397 | // allow widgets to customize the disabled handling 398 | // - disabled as an array instead of boolean 399 | // - disabled class as method for disabling individual parts 400 | if ( !suppressDisabledCheck && 401 | ( instance.options.disabled === true || 402 | $( this ).hasClass( "ui-state-disabled" ) ) ) { 403 | return; 404 | } 405 | return ( typeof handler === "string" ? instance[ handler ] : handler ) 406 | .apply( instance, arguments ); 407 | } 408 | 409 | // copy the guid so direct unbinding works 410 | if ( typeof handler !== "string" ) { 411 | handlerProxy.guid = handler.guid = 412 | handler.guid || handlerProxy.guid || $.guid++; 413 | } 414 | 415 | var match = event.match( /^(\w+)\s*(.*)$/ ), 416 | eventName = match[1] + instance.eventNamespace, 417 | selector = match[2]; 418 | if ( selector ) { 419 | delegateElement.delegate( selector, eventName, handlerProxy ); 420 | } else { 421 | element.bind( eventName, handlerProxy ); 422 | } 423 | }); 424 | }, 425 | 426 | _off: function( element, eventName ) { 427 | eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; 428 | element.unbind( eventName ).undelegate( eventName ); 429 | }, 430 | 431 | _delay: function( handler, delay ) { 432 | function handlerProxy() { 433 | return ( typeof handler === "string" ? instance[ handler ] : handler ) 434 | .apply( instance, arguments ); 435 | } 436 | var instance = this; 437 | return setTimeout( handlerProxy, delay || 0 ); 438 | }, 439 | 440 | _hoverable: function( element ) { 441 | this.hoverable = this.hoverable.add( element ); 442 | this._on( element, { 443 | mouseenter: function( event ) { 444 | $( event.currentTarget ).addClass( "ui-state-hover" ); 445 | }, 446 | mouseleave: function( event ) { 447 | $( event.currentTarget ).removeClass( "ui-state-hover" ); 448 | } 449 | }); 450 | }, 451 | 452 | _focusable: function( element ) { 453 | this.focusable = this.focusable.add( element ); 454 | this._on( element, { 455 | focusin: function( event ) { 456 | $( event.currentTarget ).addClass( "ui-state-focus" ); 457 | }, 458 | focusout: function( event ) { 459 | $( event.currentTarget ).removeClass( "ui-state-focus" ); 460 | } 461 | }); 462 | }, 463 | 464 | _trigger: function( type, event, data ) { 465 | var prop, orig, 466 | callback = this.options[ type ]; 467 | 468 | data = data || {}; 469 | event = $.Event( event ); 470 | event.type = ( type === this.widgetEventPrefix ? 471 | type : 472 | this.widgetEventPrefix + type ).toLowerCase(); 473 | // the original event may come from any element 474 | // so we need to reset the target on the new event 475 | event.target = this.element[ 0 ]; 476 | 477 | // copy original event properties over to the new event 478 | orig = event.originalEvent; 479 | if ( orig ) { 480 | for ( prop in orig ) { 481 | if ( !( prop in event ) ) { 482 | event[ prop ] = orig[ prop ]; 483 | } 484 | } 485 | } 486 | 487 | this.element.trigger( event, data ); 488 | return !( $.isFunction( callback ) && 489 | callback.apply( this.element[0], [ event ].concat( data ) ) === false || 490 | event.isDefaultPrevented() ); 491 | } 492 | }; 493 | 494 | $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 495 | $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 496 | if ( typeof options === "string" ) { 497 | options = { effect: options }; 498 | } 499 | var hasOptions, 500 | effectName = !options ? 501 | method : 502 | options === true || typeof options === "number" ? 503 | defaultEffect : 504 | options.effect || defaultEffect; 505 | options = options || {}; 506 | if ( typeof options === "number" ) { 507 | options = { duration: options }; 508 | } 509 | hasOptions = !$.isEmptyObject( options ); 510 | options.complete = callback; 511 | if ( options.delay ) { 512 | element.delay( options.delay ); 513 | } 514 | if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 515 | element[ method ]( options ); 516 | } else if ( effectName !== method && element[ effectName ] ) { 517 | element[ effectName ]( options.duration, options.easing, callback ); 518 | } else { 519 | element.queue(function( next ) { 520 | $( this )[ method ](); 521 | if ( callback ) { 522 | callback.call( element[ 0 ] ); 523 | } 524 | next(); 525 | }); 526 | } 527 | }; 528 | }); 529 | 530 | })); 531 | -------------------------------------------------------------------------------- /public/assets/lib/jquery-ui/jquery-ui.theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.12.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | * 11 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=base&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=aaaaaa&iconColorError=cc0000&fcError=5f3f3f&borderColorError=f1a899&bgTextureError=flat&bgColorError=fddfdf&iconColorHighlight=777620&fcHighlight=777620&borderColorHighlight=dad55e&bgTextureHighlight=flat&bgColorHighlight=fffa90&iconColorActive=ffffff&fcActive=ffffff&borderColorActive=003eff&bgTextureActive=flat&bgColorActive=007fff&iconColorHover=555555&fcHover=2b2b2b&borderColorHover=cccccc&bgTextureHover=flat&bgColorHover=ededed&iconColorDefault=777777&fcDefault=454545&borderColorDefault=c5c5c5&bgTextureDefault=flat&bgColorDefault=f6f6f6&iconColorContent=444444&fcContent=333333&borderColorContent=dddddd&bgTextureContent=flat&bgColorContent=ffffff&iconColorHeader=444444&fcHeader=333333&borderColorHeader=dddddd&bgTextureHeader=flat&bgColorHeader=e9e9e9&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif 12 | */ 13 | 14 | 15 | /* Component containers 16 | ----------------------------------*/ 17 | .ui-widget { 18 | font-family: Arial,Helvetica,sans-serif; 19 | font-size: 1em; 20 | } 21 | .ui-widget .ui-widget { 22 | font-size: 1em; 23 | } 24 | .ui-widget input, 25 | .ui-widget select, 26 | .ui-widget textarea, 27 | .ui-widget button { 28 | font-family: Arial,Helvetica,sans-serif; 29 | font-size: 1em; 30 | } 31 | .ui-widget.ui-widget-content { 32 | border: 1px solid #c5c5c5; 33 | } 34 | .ui-widget-content { 35 | border: 1px solid #dddddd; 36 | background: #ffffff; 37 | color: #333333; 38 | } 39 | .ui-widget-content a { 40 | color: #333333; 41 | } 42 | .ui-widget-header { 43 | border: 1px solid #dddddd; 44 | background: #e9e9e9; 45 | color: #333333; 46 | font-weight: bold; 47 | } 48 | .ui-widget-header a { 49 | color: #333333; 50 | } 51 | 52 | /* Interaction states 53 | ----------------------------------*/ 54 | .ui-state-default, 55 | .ui-widget-content .ui-state-default, 56 | .ui-widget-header .ui-state-default, 57 | .ui-button, 58 | 59 | /* We use html here because we need a greater specificity to make sure disabled 60 | works properly when clicked or hovered */ 61 | html .ui-button.ui-state-disabled:hover, 62 | html .ui-button.ui-state-disabled:active { 63 | border: 1px solid #c5c5c5; 64 | background: #f6f6f6; 65 | font-weight: normal; 66 | color: #454545; 67 | } 68 | .ui-state-default a, 69 | .ui-state-default a:link, 70 | .ui-state-default a:visited, 71 | a.ui-button, 72 | a:link.ui-button, 73 | a:visited.ui-button, 74 | .ui-button { 75 | color: #454545; 76 | text-decoration: none; 77 | } 78 | .ui-state-hover, 79 | .ui-widget-content .ui-state-hover, 80 | .ui-widget-header .ui-state-hover, 81 | .ui-state-focus, 82 | .ui-widget-content .ui-state-focus, 83 | .ui-widget-header .ui-state-focus, 84 | .ui-button:hover, 85 | .ui-button:focus { 86 | border: 1px solid #cccccc; 87 | background: #ededed; 88 | font-weight: normal; 89 | color: #2b2b2b; 90 | } 91 | .ui-state-hover a, 92 | .ui-state-hover a:hover, 93 | .ui-state-hover a:link, 94 | .ui-state-hover a:visited, 95 | .ui-state-focus a, 96 | .ui-state-focus a:hover, 97 | .ui-state-focus a:link, 98 | .ui-state-focus a:visited, 99 | a.ui-button:hover, 100 | a.ui-button:focus { 101 | color: #2b2b2b; 102 | text-decoration: none; 103 | } 104 | 105 | .ui-visual-focus { 106 | box-shadow: 0 0 3px 1px rgb(94, 158, 214); 107 | } 108 | .ui-state-active, 109 | .ui-widget-content .ui-state-active, 110 | .ui-widget-header .ui-state-active, 111 | a.ui-button:active, 112 | .ui-button:active, 113 | .ui-button.ui-state-active:hover { 114 | border: 1px solid #003eff; 115 | background: #007fff; 116 | font-weight: normal; 117 | color: #ffffff; 118 | } 119 | .ui-icon-background, 120 | .ui-state-active .ui-icon-background { 121 | border: #003eff; 122 | background-color: #ffffff; 123 | } 124 | .ui-state-active a, 125 | .ui-state-active a:link, 126 | .ui-state-active a:visited { 127 | color: #ffffff; 128 | text-decoration: none; 129 | } 130 | 131 | /* Interaction Cues 132 | ----------------------------------*/ 133 | .ui-state-highlight, 134 | .ui-widget-content .ui-state-highlight, 135 | .ui-widget-header .ui-state-highlight { 136 | border: 1px solid #dad55e; 137 | background: #fffa90; 138 | color: #777620; 139 | } 140 | .ui-state-checked { 141 | border: 1px solid #dad55e; 142 | background: #fffa90; 143 | } 144 | .ui-state-highlight a, 145 | .ui-widget-content .ui-state-highlight a, 146 | .ui-widget-header .ui-state-highlight a { 147 | color: #777620; 148 | } 149 | .ui-state-error, 150 | .ui-widget-content .ui-state-error, 151 | .ui-widget-header .ui-state-error { 152 | border: 1px solid #f1a899; 153 | background: #fddfdf; 154 | color: #5f3f3f; 155 | } 156 | .ui-state-error a, 157 | .ui-widget-content .ui-state-error a, 158 | .ui-widget-header .ui-state-error a { 159 | color: #5f3f3f; 160 | } 161 | .ui-state-error-text, 162 | .ui-widget-content .ui-state-error-text, 163 | .ui-widget-header .ui-state-error-text { 164 | color: #5f3f3f; 165 | } 166 | .ui-priority-primary, 167 | .ui-widget-content .ui-priority-primary, 168 | .ui-widget-header .ui-priority-primary { 169 | font-weight: bold; 170 | } 171 | .ui-priority-secondary, 172 | .ui-widget-content .ui-priority-secondary, 173 | .ui-widget-header .ui-priority-secondary { 174 | opacity: .7; 175 | filter:Alpha(Opacity=70); /* support: IE8 */ 176 | font-weight: normal; 177 | } 178 | .ui-state-disabled, 179 | .ui-widget-content .ui-state-disabled, 180 | .ui-widget-header .ui-state-disabled { 181 | opacity: .35; 182 | filter:Alpha(Opacity=35); /* support: IE8 */ 183 | background-image: none; 184 | } 185 | .ui-state-disabled .ui-icon { 186 | filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ 187 | } 188 | 189 | /* Icons 190 | ----------------------------------*/ 191 | 192 | /* states and images */ 193 | .ui-icon { 194 | width: 16px; 195 | height: 16px; 196 | } 197 | .ui-icon, 198 | .ui-widget-content .ui-icon { 199 | background-image: url("images/ui-icons_444444_256x240.png"); 200 | } 201 | .ui-widget-header .ui-icon { 202 | background-image: url("images/ui-icons_444444_256x240.png"); 203 | } 204 | .ui-state-hover .ui-icon, 205 | .ui-state-focus .ui-icon, 206 | .ui-button:hover .ui-icon, 207 | .ui-button:focus .ui-icon { 208 | background-image: url("images/ui-icons_555555_256x240.png"); 209 | } 210 | .ui-state-active .ui-icon, 211 | .ui-button:active .ui-icon { 212 | background-image: url("images/ui-icons_ffffff_256x240.png"); 213 | } 214 | .ui-state-highlight .ui-icon, 215 | .ui-button .ui-state-highlight.ui-icon { 216 | background-image: url("images/ui-icons_777620_256x240.png"); 217 | } 218 | .ui-state-error .ui-icon, 219 | .ui-state-error-text .ui-icon { 220 | background-image: url("images/ui-icons_cc0000_256x240.png"); 221 | } 222 | .ui-button .ui-icon { 223 | background-image: url("images/ui-icons_777777_256x240.png"); 224 | } 225 | 226 | /* positioning */ 227 | .ui-icon-blank { background-position: 16px 16px; } 228 | .ui-icon-caret-1-n { background-position: 0 0; } 229 | .ui-icon-caret-1-ne { background-position: -16px 0; } 230 | .ui-icon-caret-1-e { background-position: -32px 0; } 231 | .ui-icon-caret-1-se { background-position: -48px 0; } 232 | .ui-icon-caret-1-s { background-position: -65px 0; } 233 | .ui-icon-caret-1-sw { background-position: -80px 0; } 234 | .ui-icon-caret-1-w { background-position: -96px 0; } 235 | .ui-icon-caret-1-nw { background-position: -112px 0; } 236 | .ui-icon-caret-2-n-s { background-position: -128px 0; } 237 | .ui-icon-caret-2-e-w { background-position: -144px 0; } 238 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 239 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 240 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 241 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 242 | .ui-icon-triangle-1-s { background-position: -65px -16px; } 243 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 244 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 245 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 246 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 247 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 248 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 249 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 250 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 251 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 252 | .ui-icon-arrow-1-s { background-position: -65px -32px; } 253 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 254 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 255 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 256 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 257 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 258 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 259 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 260 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 261 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 262 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 263 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 264 | .ui-icon-arrowthick-1-n { background-position: 1px -48px; } 265 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 266 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 267 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 268 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 269 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 270 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 271 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 272 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 273 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 274 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 275 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 276 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 277 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 278 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 279 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 280 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 281 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 282 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 283 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 284 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 285 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 286 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 287 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 288 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 289 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 290 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 291 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 292 | .ui-icon-arrow-4 { background-position: 0 -80px; } 293 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 294 | .ui-icon-extlink { background-position: -32px -80px; } 295 | .ui-icon-newwin { background-position: -48px -80px; } 296 | .ui-icon-refresh { background-position: -64px -80px; } 297 | .ui-icon-shuffle { background-position: -80px -80px; } 298 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 299 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 300 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 301 | .ui-icon-folder-open { background-position: -16px -96px; } 302 | .ui-icon-document { background-position: -32px -96px; } 303 | .ui-icon-document-b { background-position: -48px -96px; } 304 | .ui-icon-note { background-position: -64px -96px; } 305 | .ui-icon-mail-closed { background-position: -80px -96px; } 306 | .ui-icon-mail-open { background-position: -96px -96px; } 307 | .ui-icon-suitcase { background-position: -112px -96px; } 308 | .ui-icon-comment { background-position: -128px -96px; } 309 | .ui-icon-person { background-position: -144px -96px; } 310 | .ui-icon-print { background-position: -160px -96px; } 311 | .ui-icon-trash { background-position: -176px -96px; } 312 | .ui-icon-locked { background-position: -192px -96px; } 313 | .ui-icon-unlocked { background-position: -208px -96px; } 314 | .ui-icon-bookmark { background-position: -224px -96px; } 315 | .ui-icon-tag { background-position: -240px -96px; } 316 | .ui-icon-home { background-position: 0 -112px; } 317 | .ui-icon-flag { background-position: -16px -112px; } 318 | .ui-icon-calendar { background-position: -32px -112px; } 319 | .ui-icon-cart { background-position: -48px -112px; } 320 | .ui-icon-pencil { background-position: -64px -112px; } 321 | .ui-icon-clock { background-position: -80px -112px; } 322 | .ui-icon-disk { background-position: -96px -112px; } 323 | .ui-icon-calculator { background-position: -112px -112px; } 324 | .ui-icon-zoomin { background-position: -128px -112px; } 325 | .ui-icon-zoomout { background-position: -144px -112px; } 326 | .ui-icon-search { background-position: -160px -112px; } 327 | .ui-icon-wrench { background-position: -176px -112px; } 328 | .ui-icon-gear { background-position: -192px -112px; } 329 | .ui-icon-heart { background-position: -208px -112px; } 330 | .ui-icon-star { background-position: -224px -112px; } 331 | .ui-icon-link { background-position: -240px -112px; } 332 | .ui-icon-cancel { background-position: 0 -128px; } 333 | .ui-icon-plus { background-position: -16px -128px; } 334 | .ui-icon-plusthick { background-position: -32px -128px; } 335 | .ui-icon-minus { background-position: -48px -128px; } 336 | .ui-icon-minusthick { background-position: -64px -128px; } 337 | .ui-icon-close { background-position: -80px -128px; } 338 | .ui-icon-closethick { background-position: -96px -128px; } 339 | .ui-icon-key { background-position: -112px -128px; } 340 | .ui-icon-lightbulb { background-position: -128px -128px; } 341 | .ui-icon-scissors { background-position: -144px -128px; } 342 | .ui-icon-clipboard { background-position: -160px -128px; } 343 | .ui-icon-copy { background-position: -176px -128px; } 344 | .ui-icon-contact { background-position: -192px -128px; } 345 | .ui-icon-image { background-position: -208px -128px; } 346 | .ui-icon-video { background-position: -224px -128px; } 347 | .ui-icon-script { background-position: -240px -128px; } 348 | .ui-icon-alert { background-position: 0 -144px; } 349 | .ui-icon-info { background-position: -16px -144px; } 350 | .ui-icon-notice { background-position: -32px -144px; } 351 | .ui-icon-help { background-position: -48px -144px; } 352 | .ui-icon-check { background-position: -64px -144px; } 353 | .ui-icon-bullet { background-position: -80px -144px; } 354 | .ui-icon-radio-on { background-position: -96px -144px; } 355 | .ui-icon-radio-off { background-position: -112px -144px; } 356 | .ui-icon-pin-w { background-position: -128px -144px; } 357 | .ui-icon-pin-s { background-position: -144px -144px; } 358 | .ui-icon-play { background-position: 0 -160px; } 359 | .ui-icon-pause { background-position: -16px -160px; } 360 | .ui-icon-seek-next { background-position: -32px -160px; } 361 | .ui-icon-seek-prev { background-position: -48px -160px; } 362 | .ui-icon-seek-end { background-position: -64px -160px; } 363 | .ui-icon-seek-start { background-position: -80px -160px; } 364 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 365 | .ui-icon-seek-first { background-position: -80px -160px; } 366 | .ui-icon-stop { background-position: -96px -160px; } 367 | .ui-icon-eject { background-position: -112px -160px; } 368 | .ui-icon-volume-off { background-position: -128px -160px; } 369 | .ui-icon-volume-on { background-position: -144px -160px; } 370 | .ui-icon-power { background-position: 0 -176px; } 371 | .ui-icon-signal-diag { background-position: -16px -176px; } 372 | .ui-icon-signal { background-position: -32px -176px; } 373 | .ui-icon-battery-0 { background-position: -48px -176px; } 374 | .ui-icon-battery-1 { background-position: -64px -176px; } 375 | .ui-icon-battery-2 { background-position: -80px -176px; } 376 | .ui-icon-battery-3 { background-position: -96px -176px; } 377 | .ui-icon-circle-plus { background-position: 0 -192px; } 378 | .ui-icon-circle-minus { background-position: -16px -192px; } 379 | .ui-icon-circle-close { background-position: -32px -192px; } 380 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 381 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 382 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 383 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 384 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 385 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 386 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 387 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 388 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 389 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 390 | .ui-icon-circle-check { background-position: -208px -192px; } 391 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 392 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 393 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 394 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 395 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 396 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 397 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 398 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 399 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 400 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 401 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 402 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 403 | 404 | 405 | /* Misc visuals 406 | ----------------------------------*/ 407 | 408 | /* Corner radius */ 409 | .ui-corner-all, 410 | .ui-corner-top, 411 | .ui-corner-left, 412 | .ui-corner-tl { 413 | border-top-left-radius: 3px; 414 | } 415 | .ui-corner-all, 416 | .ui-corner-top, 417 | .ui-corner-right, 418 | .ui-corner-tr { 419 | border-top-right-radius: 3px; 420 | } 421 | .ui-corner-all, 422 | .ui-corner-bottom, 423 | .ui-corner-left, 424 | .ui-corner-bl { 425 | border-bottom-left-radius: 3px; 426 | } 427 | .ui-corner-all, 428 | .ui-corner-bottom, 429 | .ui-corner-right, 430 | .ui-corner-br { 431 | border-bottom-right-radius: 3px; 432 | } 433 | 434 | /* Overlays */ 435 | .ui-widget-overlay { 436 | background: #aaaaaa; 437 | opacity: .3; 438 | filter: Alpha(Opacity=30); /* support: IE8 */ 439 | } 440 | .ui-widget-shadow { 441 | -webkit-box-shadow: 0px 0px 5px #666666; 442 | box-shadow: 0px 0px 5px #666666; 443 | } 444 | -------------------------------------------------------------------------------- /public/assets/lib/fancybox/jquery.fancybox.pack.js: -------------------------------------------------------------------------------- 1 | /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ 2 | (function(r,G,f,v){var J=f("html"),n=f(r),p=f(G),b=f.fancybox=function(){b.open.apply(this,arguments)},I=navigator.userAgent.match(/msie/i),B=null,s=G.createTouch!==v,t=function(a){return a&&a.hasOwnProperty&&a instanceof f},q=function(a){return a&&"string"===f.type(a)},E=function(a){return q(a)&&0
',image:'',iframe:'",error:'

The requested content cannot be loaded.
Please try again later.

',closeBtn:'',next:'',prev:''},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0, 6 | openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1, 7 | isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=t(a)?f(a).get():[a]),f.each(a,function(e,c){var k={},g,h,j,m,l;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),t(c)?(k={href:c.data("fancybox-href")||c.attr("href"),title:c.data("fancybox-title")||c.attr("title"),isDom:!0,element:c},f.metadata&&f.extend(!0,k, 8 | c.metadata())):k=c);g=d.href||k.href||(q(c)?c:null);h=d.title!==v?d.title:k.title||"";m=(j=d.content||k.content)?"html":d.type||k.type;!m&&k.isDom&&(m=c.data("fancybox-type"),m||(m=(m=c.prop("class").match(/fancybox\.(\w+)/))?m[1]:null));q(g)&&(m||(b.isImage(g)?m="image":b.isSWF(g)?m="swf":"#"===g.charAt(0)?m="inline":q(c)&&(m="html",j=c)),"ajax"===m&&(l=g.split(/\s+/,2),g=l.shift(),l=l.shift()));j||("inline"===m?g?j=f(q(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):k.isDom&&(j=c):"html"===m?j=g:!m&&(!g&& 9 | k.isDom)&&(m="inline",j=c));f.extend(k,{href:g,type:m,content:j,title:h,selector:l});a[e]=k}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==v&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1!==b.trigger("onCancel")&&(b.hideLoading(),b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(),b.coming=null,b.current|| 10 | b._afterZoomOut(a))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(!b.isOpen||!0===a?(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut()):(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&&(b.player.timer= 11 | setTimeout(b.next,b.current.playSpeed))},c=function(){d();p.unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};if(!0===a||!b.player.isActive&&!1!==a){if(b.current&&(b.current.loop||b.current.index=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==v&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,k;c&&(k=b._getPosition(d),a&&"scroll"===a.type?(delete k.position,c.stop(!0,!0).animate(k,200)):(c.css(k),e.pos=f.extend({},e.dim,k)))},update:function(a){var d= 13 | a&&a.type,e=!d||"orientationchange"===d;e&&(clearTimeout(B),B=null);b.isOpen&&!B&&(B=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),B=null)},e&&!s?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,s&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"),b.trigger("onUpdate")), 14 | b.update())},hideLoading:function(){p.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('
').click(b.cancel).appendTo("body");p.bind("keydown.loading",function(a){if(27===(a.which||a.keyCode))a.preventDefault(),b.cancel()});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}))},getViewport:function(){var a=b.current&&b.current.locked||!1,d={x:n.scrollLeft(), 15 | y:n.scrollTop()};a?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=s&&r.innerWidth?r.innerWidth:n.width(),d.h=s&&r.innerHeight?r.innerHeight:n.height());return d},unbindEvents:function(){b.wrap&&t(b.wrap)&&b.wrap.unbind(".fb");p.unbind(".fb");n.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(n.bind("orientationchange.fb"+(s?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&p.bind("keydown.fb",function(e){var c=e.which||e.keyCode,k=e.target||e.srcElement; 16 | if(27===c&&b.coming)return!1;!e.ctrlKey&&(!e.altKey&&!e.shiftKey&&!e.metaKey&&(!k||!k.type&&!f(k).is("[contenteditable]")))&&f.each(d,function(d,k){if(1h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();if(0!==c&&!j&&1g||0>k)b.next(0>g?"up":"right");d.preventDefault()}}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d,e){if(e&&b.helpers[d]&&f.isFunction(b.helpers[d][a]))b.helpers[d][a](f.extend(!0, 18 | {},b.helpers[d].defaults,e),c)});p.trigger(a)}},isImage:function(a){return q(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(a){return q(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=l(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&&(d.padding=[c,c,c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1, 19 | mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive=!0;if("image"===c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio= 20 | !0);"iframe"===c&&s&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(s?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,w(d.padding[a]))});b.trigger("onReady");if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href"); 21 | "image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width=this.width/b.opts.pixelRatio;b.coming.height=this.height/b.opts.pixelRatio;b._afterLoad()};a.onerror=function(){this.onload= 22 | this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming,d=f(a.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",s?"auto":a.iframe.scrolling).attr("src",a.href); 23 | f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);s||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload||b._afterLoad()},_preloadImages:function(){var a=b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload, 24 | e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,k,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());b.unbindEvents();e=a.content;c=a.type;k=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin, 25 | outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("
").html(e).find(a.selector):t(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('
').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder",!1)}));break;case "image":e=a.tpl.image.replace("{href}", 26 | g);break;case "swf":e='',h="",f.each(a.swf,function(a,b){e+='';h+=" "+a+'="'+b+'"'}),e+='"}(!t(e)||!e.parent().is(a.inner))&&a.inner.append(e);b.trigger("beforeShow");a.inner.css("overflow","yes"===k?"scroll": 27 | "no"===k?"hidden":k);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(b.isOpened){if(d.prevMethod)b.transitions[d.prevMethod]()}else f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,k=b.skin,g=b.inner,h=b.current,c=h.width,j=h.height,m=h.minWidth,u=h.minHeight,n=h.maxWidth,p=h.maxHeight,s=h.scrolling,q=h.scrollOutside? 28 | h.scrollbarWidth:0,x=h.margin,y=l(x[1]+x[3]),r=l(x[0]+x[2]),v,z,t,C,A,F,B,D,H;e.add(k).add(g).width("auto").height("auto").removeClass("fancybox-tmp");x=l(k.outerWidth(!0)-k.width());v=l(k.outerHeight(!0)-k.height());z=y+x;t=r+v;C=E(c)?(a.w-z)*l(c)/100:c;A=E(j)?(a.h-t)*l(j)/100:j;if("iframe"===h.type){if(H=h.content,h.autoHeight&&1===H.data("ready"))try{H[0].contentWindow.document.location&&(g.width(C).height(9999),F=H.contents().find("body"),q&&F.css("overflow-x","hidden"),A=F.outerHeight(!0))}catch(G){}}else if(h.autoWidth|| 29 | h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(C),h.autoHeight||g.height(A),h.autoWidth&&(C=g.width()),h.autoHeight&&(A=g.height()),g.removeClass("fancybox-tmp");c=l(C);j=l(A);D=C/A;m=l(E(m)?l(m,"w")-z:m);n=l(E(n)?l(n,"w")-z:n);u=l(E(u)?l(u,"h")-t:u);p=l(E(p)?l(p,"h")-t:p);F=n;B=p;h.fitToView&&(n=Math.min(a.w-z,n),p=Math.min(a.h-t,p));z=a.w-y;r=a.h-r;h.aspectRatio?(c>n&&(c=n,j=l(c/D)),j>p&&(j=p,c=l(j*D)),cz||y>r)&&(c>m&&j>u)&&!(19n&&(c=n,j=l(c/D)),g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height();else c=Math.max(m,Math.min(c,c-(a-z))),j=Math.max(u,Math.min(j,j-(y-r)));q&&("auto"===s&&jz||y>r)&&c>m&&j>u;c=h.aspectRatio?cu&&j
').appendTo(b.coming?b.coming.parent:a.parent);this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(n.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay",function(a){if(f(a.target).hasClass("fancybox-overlay"))return b.isActive? 40 | b.close():d.close(),!1});this.overlay.css(a.css).show()},close:function(){var a,b;n.unbind("resize.overlay");this.el.hasClass("fancybox-lock")&&(f(".fancybox-margin").removeClass("fancybox-margin"),a=n.scrollTop(),b=n.scrollLeft(),this.el.removeClass("fancybox-lock"),n.scrollTop(a).scrollLeft(b));f(".fancybox-overlay").remove().hide();f.extend(this,{overlay:null,fixed:!1})},update:function(){var a="100%",b;this.overlay.width(a).height("100%");I?(b=Math.max(G.documentElement.offsetWidth,G.body.offsetWidth), 41 | p.width()>b&&(a=p.width())):p.width()>n.width()&&(a=p.width());this.overlay.width(a).height(p.height())},onReady:function(a,b){var e=this.overlay;f(".fancybox-overlay").stop(!0,!0);e||this.create(a);a.locked&&(this.fixed&&b.fixed)&&(e||(this.margin=p.height()>n.height()?f("html").css("margin-right").replace("px",""):!1),b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){var e,c;b.locked&&(!1!==this.margin&&(f("*").filter(function(){return"fixed"=== 42 | f(this).css("position")&&!f(this).hasClass("fancybox-overlay")&&!f(this).hasClass("fancybox-wrap")}).addClass("fancybox-margin"),this.el.addClass("fancybox-margin")),e=n.scrollTop(),c=n.scrollLeft(),this.el.addClass("fancybox-lock"),n.scrollTop(e).scrollLeft(c));this.open(a)},onUpdate:function(){this.fixed||this.update()},afterClose:function(a){this.overlay&&!b.coming&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(a){var d= 43 | b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(q(e)&&""!==f.trim(e)){d=f('
'+e+"
");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"),I&&d.width(d.width()),d.wrapInner(''),b.current.margin[2]+=Math.abs(l(d.css("margin-bottom")))}d["top"===a.position?"prependTo":"appendTo"](c)}}};f.fn.fancybox=function(a){var d, 44 | e=f(this),c=this.selector||"",k=function(g){var h=f(this).blur(),j=d,k,l;!g.ctrlKey&&(!g.altKey&&!g.shiftKey&&!g.metaKey)&&!h.is(".fancybox-wrap")&&(k=a.groupAttr||"data-fancybox-group",l=h.attr(k),l||(k="rel",l=h.get(0)[k]),l&&(""!==l&&"nofollow"!==l)&&(h=c.length?f(c):e,h=h.filter("["+k+'="'+l+'"]'),j=h.index(this)),a.index=j,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;!c||!1===a.live?e.unbind("click.fb-start").bind("click.fb-start",k):p.undelegate(c,"click.fb-start").delegate(c+ 45 | ":not('.fancybox-item, .fancybox-nav')","click.fb-start",k);this.filter("[data-fancybox-start=1]").trigger("click");return this};p.ready(function(){var a,d;f.scrollbarWidth===v&&(f.scrollbarWidth=function(){var a=f('
').appendTo("body"),b=a.children(),b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});if(f.support.fixedPosition===v){a=f.support;d=f('
').appendTo("body");var e=20=== 46 | d[0].offsetTop||15===d[0].offsetTop;d.remove();a.fixedPosition=e}f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")});a=f(r).width();J.addClass("fancybox-lock-test");d=f(r).width();J.removeClass("fancybox-lock-test");f("").appendTo("head")})})(window,document,jQuery); --------------------------------------------------------------------------------