├── .eslintignore ├── .markdownlint.json ├── .stylelintignore ├── Gemfile ├── assets ├── javascripts │ ├── .eslintignore │ ├── lightbox.js │ └── glightbox.min.js └── stylesheets │ ├── .stylelintignore │ ├── lightbox.css │ └── glightbox.min.css ├── .markdownlintignore ├── test ├── support │ ├── database.yml │ ├── configuration.yml │ └── gemfile.rb ├── fixtures │ ├── dashboard_roles.yml │ └── dashboards.yml ├── functional │ ├── news_controller_test.rb │ ├── welcome_controller_test.rb │ ├── messages_controller_test.rb │ ├── users_controller_test.rb │ ├── files_controller_test.rb │ ├── documents_controller_test.rb │ ├── projects_controller_test.rb │ ├── wiki_controller_test.rb │ └── issues_controller_test.rb └── test_helper.rb ├── .gitignore ├── .stylelintrc.json ├── package.json ├── lib ├── redmine_lightbox │ └── hooks │ │ ├── model_hook.rb │ │ └── view_hook.rb └── redmine_lightbox.rb ├── .eslintrc.yml ├── init.rb ├── LICENSE ├── .github └── workflows │ ├── linters.yml │ └── tests.yml ├── README.md ├── app └── helpers │ └── lightbox_helper.rb └── .rubocop.yml /.eslintignore: -------------------------------------------------------------------------------- 1 | # eslint ignore file 2 | assets/javascripts/*.min.js 3 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD013": false 4 | } 5 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | # stylelint ignore file 2 | assets/stylesheets/*.min.css 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem 'redmine_plugin_kit' 4 | -------------------------------------------------------------------------------- /assets/javascripts/.eslintignore: -------------------------------------------------------------------------------- 1 | # eslint ignore file 2 | 3 | *.min.js 4 | -------------------------------------------------------------------------------- /assets/stylesheets/.stylelintignore: -------------------------------------------------------------------------------- 1 | # stylelint ignore file 2 | 3 | *.min.css 4 | -------------------------------------------------------------------------------- /.markdownlintignore: -------------------------------------------------------------------------------- 1 | # Ignore virtual environments and dependencies 2 | node_modules/ 3 | coverage/ 4 | -------------------------------------------------------------------------------- /test/support/database.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: postgresql 3 | host: localhost 4 | database: redmine 5 | username: postgres 6 | password: postgres 7 | encoding: utf8 8 | -------------------------------------------------------------------------------- /test/fixtures/dashboard_roles.yml: -------------------------------------------------------------------------------- 1 | dashboard_role1: 2 | dashboard: welcome_for_roles 3 | role_id: 1 4 | 5 | dashboard_role2: 6 | dashboard: welcome_for_roles 7 | role_id: 2 8 | -------------------------------------------------------------------------------- /test/support/configuration.yml: -------------------------------------------------------------------------------- 1 | # = Redmine configuration file 2 | 3 | # default configuration options for all environments 4 | default: 5 | sudo_mode: false 6 | sudo_mode_timeout: 1 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .buildpath 3 | *.gem 4 | .claude/ 5 | CLAUDE.md 6 | coverage/ 7 | tmp/ 8 | Gemfile.lock 9 | .project 10 | .vscode 11 | .bundle 12 | .settings/ 13 | .enable_* 14 | /node_modules 15 | /yarn.lock 16 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "rules": { 4 | "string-quotes": "single", 5 | "selector-nested-pattern": "false", 6 | "declaration-property-unit-disallowed-list": { 7 | "font-size": [ 8 | "px" 9 | ] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "glightbox": "^3.3.1" 4 | }, 5 | "devDependencies": { 6 | "eslint": "^8.0.0", 7 | "eslint-plugin-no-jquery": "^3.0.2", 8 | "markdownlint-cli": "^0.45.0", 9 | "stylelint": "^14.0.0", 10 | "stylelint-config-standard": "^29.0.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/support/gemfile.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | group :test do 6 | gem 'brakeman', require: false 7 | gem 'rubocop', require: false 8 | gem 'rubocop-minitest', require: false 9 | gem 'rubocop-performance', require: false 10 | gem 'rubocop-rails', require: false 11 | end 12 | -------------------------------------------------------------------------------- /lib/redmine_lightbox/hooks/model_hook.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RedmineLightbox 4 | module Hooks 5 | class ModelHook < Redmine::Hook::Listener 6 | def after_plugins_loaded(_context = {}) 7 | return if Rails.version < '6.0' 8 | 9 | RedmineLightbox.setup! 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | browser: true 3 | jquery: true 4 | extends: 5 | - 'eslint:recommended' 6 | - 'plugin:no-jquery/deprecated' 7 | plugins: 8 | - no-jquery 9 | parserOptions: 10 | ecmaVersion: 2019 11 | rules: 12 | indent: 13 | - error 14 | - 2 15 | linebreak-style: 16 | - error 17 | - unix 18 | quotes: 19 | - error 20 | - single 21 | semi: 22 | - error 23 | - always 24 | -------------------------------------------------------------------------------- /init.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | loader = RedminePluginKit::Loader.new plugin_id: 'redmine_lightbox' 4 | 5 | Redmine::Plugin.register :redmine_lightbox do 6 | name 'Lightbox' 7 | author 'AlphaNodes GmbH' 8 | description 'This plugin lets you preview image and pdf attachments in a lightbox.' 9 | version RedmineLightbox::VERSION 10 | url 'https://github.com/alphanodes/redmine_lightbox' 11 | author_url 'https://alphanodes.com' 12 | requires_redmine version_or_higher: '6.1' 13 | end 14 | 15 | RedminePluginKit::Loader.persisting { loader.load_model_hooks! } 16 | -------------------------------------------------------------------------------- /test/functional/news_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class NewsControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, 7 | :enabled_modules, :news, :comments, :user_preferences, 8 | :attachments 9 | 10 | def setup 11 | @request.session[:user_id] = 2 12 | end 13 | 14 | def test_show_fancybox_libs_loaded 15 | get :show, params: { id: 1 } 16 | 17 | assert_response :success 18 | assert_fancybox_libs 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /test/functional/welcome_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class WelcomeControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :news, :users, :members, :roles, :member_roles, :enabled_modules, 7 | :attachments 8 | 9 | fixtures :dashboards, :dashboard_roles if Redmine::Plugin.installed? 'additionals' 10 | 11 | def setup 12 | @request.session[:user_id] = 2 13 | end 14 | 15 | def test_fancybox_libs_not_loaded 16 | get :index 17 | 18 | assert_response :success 19 | assert_not_fancybox_libs 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/functional/messages_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class MessagesControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :users, :email_addresses, :user_preferences, :members, 7 | :member_roles, :roles, :boards, :messages, 8 | :enabled_modules, :watchers, 9 | :attachments 10 | 11 | def setup 12 | @request.session[:user_id] = 2 13 | end 14 | 15 | def test_show_fancybox_libs_loaded 16 | get :show, params: { board_id: 1, id: 1 } 17 | 18 | assert_response :success 19 | assert_fancybox_libs 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /assets/stylesheets/lightbox.css: -------------------------------------------------------------------------------- 1 | /* Redmine Lightbox - Plugin specific styles */ 2 | 3 | /* Lightbox preview thumbnails */ 4 | a.lightbox-preview img { 5 | margin: 0 4px; 6 | width: 18px; 7 | } 8 | 9 | /* GLightbox custom overrides for Redmine integration */ 10 | .glightbox-container .gslide-description { 11 | background: rgb(0 0 0 / 75%); 12 | } 13 | 14 | /* Fix for GLightbox Issue #235: Title blocking iframe content 15 | * https://github.com/biati-digital/glightbox/issues/235 16 | * When iframe has a title, the description blocks the iframe content */ 17 | .glightbox-container .gslide-iframe .gslide-description { 18 | position: absolute; 19 | bottom: 0; 20 | flex: 0 0 auto; 21 | } 22 | -------------------------------------------------------------------------------- /lib/redmine_lightbox/hooks/view_hook.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RedmineLightbox 4 | module Hooks 5 | class ViewHook < Redmine::Hook::ViewListener 6 | def view_layouts_base_html_head(context = {}) 7 | return unless RedmineLightbox.lightbox_controllers.include? context[:controller].class.to_s 8 | 9 | stylesheet_link_tag('glightbox.min.css', plugin: 'redmine_lightbox', media: 'screen') + 10 | stylesheet_link_tag('lightbox.css', plugin: 'redmine_lightbox', media: 'screen') + 11 | javascript_include_tag('glightbox.min.js', plugin: 'redmine_lightbox') + 12 | javascript_include_tag('lightbox.js', plugin: 'redmine_lightbox') 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /test/functional/users_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class UsersControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :users, :groups_users, :email_addresses, :user_preferences, 7 | :roles, :members, :member_roles, 8 | :issues, :issue_statuses, :issue_relations, 9 | :issues, :issue_statuses, :issue_categories, 10 | :versions, :trackers, :enumerations, 11 | :projects, :projects_trackers, :enabled_modules, 12 | :attachments 13 | 14 | def test_fancybox_libs_loaded 15 | get :show, 16 | params: { id: 1 } 17 | 18 | assert_response :success 19 | assert_fancybox_libs 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/functional/files_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class FilesControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :trackers, :issue_statuses, :issues, 7 | :enumerations, :users, 8 | :email_addresses, 9 | :issue_categories, 10 | :projects_trackers, 11 | :roles, :member_roles, :members, :enabled_modules, 12 | :journals, :journal_details, :versions, 13 | :attachments 14 | 15 | def setup 16 | @request.session[:user_id] = 2 17 | end 18 | 19 | def test_index_fancybox_libs_loaded 20 | get :index, params: { project_id: 1 } 21 | 22 | assert_response :success 23 | assert_fancybox_libs 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/functional/documents_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class DocumentsControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, 7 | :enabled_modules, :documents, :enumerations, 8 | :groups_users, :user_preferences, 9 | :attachments 10 | 11 | def setup 12 | @request.session[:user_id] = 2 13 | end 14 | 15 | def test_show_fancybox_libs_loaded 16 | get :show, 17 | params: { id: 1 } 18 | 19 | assert_response :success 20 | assert_fancybox_libs 21 | end 22 | 23 | def test_lightbox_classes 24 | get :show, 25 | params: { id: 1 } 26 | 27 | assert_response :success 28 | assert_select 'a.lightbox.jpg' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/functional/projects_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class ProjectsControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :users, 7 | :roles, :members, :member_roles, 8 | :issues, :issue_statuses, :versions, 9 | :trackers, :projects_trackers, 10 | :issue_categories, :enabled_modules, 11 | :attachments 12 | 13 | fixtures :dashboards, :dashboard_roles if Redmine::Plugin.installed? 'additionals' 14 | 15 | def setup 16 | @request.session[:user_id] = 2 17 | end 18 | 19 | def test_index_fancybox_libs_not_loaded 20 | get :index 21 | 22 | assert_response :success 23 | assert_not_fancybox_libs 24 | end 25 | 26 | def test_show_fancybox_libs_not_loaded 27 | get :show, 28 | params: { id: 1 } 29 | 30 | assert_response :success 31 | assert_not_fancybox_libs 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/functional/wiki_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class WikiControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :projects, :users, :roles, :members, :member_roles, 7 | :trackers, :groups_users, :projects_trackers, 8 | :enabled_modules, :issue_statuses, :issues, 9 | :enumerations, :custom_fields, :custom_values, 10 | :custom_fields_trackers, 11 | :wikis, :wiki_pages, :wiki_contents, 12 | :attachments 13 | 14 | def setup 15 | @request.session[:user_id] = 2 16 | end 17 | 18 | def test_fancybox_libs_loaded 19 | get :show, 20 | params: { project_id: 1, id: 'Another_page' } 21 | 22 | assert_response :success 23 | assert_fancybox_libs 24 | end 25 | 26 | def test_lightbox_classes 27 | get :show, 28 | params: { project_id: 1, id: 'CookBook_documentation' } 29 | 30 | assert_response :success 31 | assert_select 'a.lightbox.pdf' 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Run Linters 2 | on: 3 | push: 4 | pull_request: 5 | 6 | jobs: 7 | test: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v5 12 | 13 | - name: Install package dependencies 14 | run: | 15 | sudo apt-get install --yes --quiet pandoc 16 | 17 | - name: Setup gems 18 | run: | 19 | cp test/support/gemfile.rb Gemfile 20 | 21 | - name: Setup Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: 3.3 25 | bundler-cache: true 26 | 27 | - name: Run bundler 28 | run: | 29 | bundle install --jobs 4 --retry 3 30 | 31 | - name: Run RuboCop 32 | run: | 33 | bundle exec rubocop -S 34 | 35 | - name: Run Brakeman 36 | run: | 37 | bundle exec brakeman -5 38 | 39 | - name: Setup node 40 | uses: actions/setup-node@v3 41 | with: 42 | node-version: '24' 43 | 44 | - run: yarn install 45 | 46 | - name: Run Stylelint 47 | run: node_modules/.bin/stylelint assets/stylesheets/ 48 | 49 | - name: Run ESLint 50 | run: node_modules/.bin/eslint assets/javascripts/ 51 | 52 | - name: Run MarkdownLint 53 | run: node_modules/.bin/markdownlint README.md 54 | -------------------------------------------------------------------------------- /test/functional/issues_controller_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require File.expand_path '../../test_helper', __FILE__ 4 | 5 | class IssuesControllerTest < RedmineLightbox::ControllerTest 6 | fixtures :users, :email_addresses, :roles, 7 | :enumerations, 8 | :projects, :projects_trackers, :enabled_modules, 9 | :members, :member_roles, 10 | :issues, :issue_statuses, :issue_categories, :issue_relations, 11 | :versions, :trackers, :workflows, 12 | :custom_fields, :custom_values, :custom_fields_projects, :custom_fields_trackers, 13 | :time_entries, 14 | :watchers, :journals, :journal_details, 15 | :repositories, :changesets, :queries, 16 | :attachments 17 | 18 | def setup 19 | @request.session[:user_id] = 2 20 | end 21 | 22 | def test_fancybox_libs_loaded 23 | get :show, params: { id: 2 } 24 | 25 | assert_fancybox_libs 26 | end 27 | 28 | def test_lightbox_classes 29 | get :show, 30 | params: { id: 2 } 31 | 32 | assert_response :success 33 | assert_select 'a.lightbox.jpg' 34 | end 35 | 36 | def test_lightbox_classes_with_multiple_files_in_issue 37 | get :show, 38 | params: { id: 14 } 39 | 40 | assert_response :success 41 | assert_select 'a.icon-attachment.lightbox.png', count: 4 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if ENV['COVERAGE'] 4 | require 'simplecov' 5 | SimpleCov.start :rails do 6 | add_filter 'init.rb' 7 | root File.expand_path "#{File.dirname __FILE__}/.." 8 | end 9 | end 10 | 11 | require File.expand_path "#{File.dirname __FILE__}/../../../test/test_helper" 12 | 13 | module RedmineLightbox 14 | module PluginFixturesLoader 15 | def fixtures(*table_names) 16 | dir = "#{File.dirname __FILE__}/fixtures/" 17 | table_names.each do |x| 18 | ActiveRecord::FixtureSet.create_fixtures dir, x if File.exist? "#{dir}/#{x}.yml" 19 | end 20 | super table_names 21 | end 22 | end 23 | 24 | class ControllerTest < Redmine::ControllerTest 25 | def assert_fancybox_libs 26 | assert_select "link:match('href',?)", %r{/glightbox}, count: 1 27 | assert_select "script:match('src',?)", %r{/glightbox.*\.js}, count: 1 28 | end 29 | 30 | def assert_not_fancybox_libs 31 | assert_select "link:match('href',?)", %r{/glightbox}, count: 0 32 | assert_select "script:match('src',?)", %r{/glightbox.*\.js}, count: 0 33 | end 34 | 35 | extend PluginFixturesLoader 36 | end 37 | 38 | class TestCase < ActiveSupport::TestCase 39 | extend PluginFixturesLoader 40 | end 41 | 42 | class IntegrationTest < Redmine::IntegrationTest 43 | extend PluginFixturesLoader 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/redmine_lightbox.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RedmineLightbox 4 | VERSION = '2.0.0' 5 | GLIGHTBOX_VERSION = '3.3.1' 6 | 7 | include RedminePluginKit::PluginBase 8 | 9 | class << self 10 | # list of all controllers for lightbox support 11 | def lightbox_controllers 12 | @lightbox_controllers ||= lightbox_fixed_controllers + lightbox_plugins_controllers 13 | end 14 | 15 | private 16 | 17 | def setup 18 | # load helper for supported controllers 19 | lightbox_controllers.each do |lightbox_controller| 20 | lightbox_controller.constantize.send :helper, LightboxHelper 21 | end 22 | 23 | # Load view hooks 24 | loader.load_view_hooks! 25 | end 26 | 27 | def lightbox_fixed_controllers 28 | %w[IssuesController 29 | WikiController 30 | DocumentsController 31 | FilesController 32 | MessagesController 33 | NewsController 34 | UsersController].freeze 35 | end 36 | 37 | # this controllers have to be checked, 38 | # if plugins are installed 39 | def lightbox_plugins_controllers 40 | controllers = [] 41 | if Redmine::Plugin.installed?('redmine_contacts') || Redmine::Plugin.installed?('redmine_servicedesk') 42 | controllers << 'ContactsController' 43 | end 44 | controllers << 'ArticlesController' if Redmine::Plugin.installed? 'redmine_knowledgebase' 45 | controllers << 'DbEntriesController' if Redmine::Plugin.installed? 'redmine_db' 46 | controllers << 'DmsfController' if Redmine::Plugin.installed? 'redmine_dmsf' 47 | 48 | if Redmine::Plugin.installed?('redmine_contacts_invoices') || Redmine::Plugin.installed?('redmine_servicedesk') 49 | controllers << 'InvoicesController' 50 | end 51 | 52 | controllers << 'PasswordsController' if Redmine::Plugin.installed? 'redmine_passwords' 53 | controllers << 'ReportingFilesController' if Redmine::Plugin.installed? 'redmine_reporting' 54 | 55 | controllers 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Redmine Lightbox 2 | ================ 3 | 4 | [![Run Linters](https://github.com/AlphaNodes/redmine_lightbox/workflows/Run%20Linters/badge.svg)](https://github.com/AlphaNodes/redmine_lightbox/actions/workflows/linters.yml) [![Run Tests](https://github.com/AlphaNodes/redmine_lightbox/workflows/Tests/badge.svg)](https://github.com/AlphaNodes/redmine_lightbox/actions/workflows/tests.yml) 5 | 6 | This plugin lets you preview image (JPG, GIF, PNG, BMP) and PDF attachments in a lightbox based on [GLightbox](https://github.com/biati-digital/glightbox). 7 | 8 | Requirements 9 | ------------ 10 | 11 | - Redmine 6.1 or higher 12 | - Ruby 3.2 or higher 13 | 14 | Installation and Setup 15 | ---------------------- 16 | 17 | For Redmine 6.1 or higher 18 | ------------------------- 19 | 20 | - Clone this repo into your **redmine_root/plugins/** folder 21 | 22 | ```shell 23 | cd redmine 24 | git clone https://github.com/alphanodes/redmine_lightbox.git plugins/redmine_lightbox 25 | bundle config set --local without 'development test' 26 | bundle install 27 | ``` 28 | 29 | - Restart Redmine 30 | 31 | For Redmine versions before 6.1 32 | -------------------------------- 33 | 34 | If you are using Redmine 5.0 - 6.0, install the stable branch which uses Fancybox 3.5.7: 35 | 36 | ```shell 37 | cd redmine 38 | git clone -b stable https://github.com/alphanodes/redmine_lightbox.git plugins/redmine_lightbox 39 | bundle config set --local without 'development test' 40 | bundle install 41 | ``` 42 | 43 | - Restart Redmine 44 | 45 | Contribution and usage 46 | ---------------------- 47 | 48 | If you use our fork and have some improvements for it, please create a PR (we can discuss your changes in it). 49 | 50 | Credits 51 | ------- 52 | 53 | This is a fork of [redmine_lightbox2](https://github.com/paginagmbh/redmine_lightbox2), which was a fork of [redmine_lightbox](https://github.com/zipme/redmine_lightbox) plugin. Credits goes to @tofi86 and @zipme and all other distributors to these forks! 54 | 55 | License 56 | ------- 57 | 58 | *redmine_lightbox* plugin is developed under the [MIT License](LICENSE). 59 | -------------------------------------------------------------------------------- /app/helpers/lightbox_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module LightboxHelper 4 | def link_to_attachment(attachment, **options) 5 | with_lightbox = false 6 | 7 | if options[:class].present? && options[:class].include?('icon-download') 8 | # we don't want lightbox for this link, because this case duplicated entries in image slide 9 | elsif attachment.is_pdf? || attachment.is_image? 10 | with_lightbox = true 11 | options[:class] = lightbox_image_classes attachment, options[:class] 12 | end 13 | 14 | if with_lightbox 15 | options[:download] = true 16 | caption = lightbox_image_caption attachment 17 | 18 | options[:title] ||= "#{l :label_preview}: #{caption}" 19 | options[:rel] ||= 'attachments' 20 | options[:data] = { type: attachment.is_pdf? ? 'iframe' : 'image', 21 | fancybox: options[:rel], 22 | caption: caption } 23 | end 24 | 25 | super 26 | end 27 | 28 | def thumbnail_tag(attachment) 29 | thumbnail_size = Setting.thumbnails_size.to_i 30 | caption = lightbox_image_caption attachment 31 | 32 | options = { title: "#{l :label_preview}: #{caption}", 33 | rel: 'thumbnails', 34 | class: lightbox_image_classes(attachment) } 35 | 36 | options[:data] = { type: attachment.is_pdf? ? 'iframe' : 'image', 37 | fancybox: options[:rel], 38 | caption: caption } 39 | 40 | link_to image_tag(thumbnail_path(attachment), 41 | srcset: "#{thumbnail_path attachment, size: thumbnail_size * 2} 2x", 42 | style: "max-width: #{thumbnail_size}px; max-height: #{thumbnail_size}px;"), 43 | download_named_attachment_path(attachment, filename: attachment.filename), 44 | options 45 | end 46 | 47 | def lightbox_image_caption(attachment) 48 | caption = attachment.filename.dup 49 | caption << " - #{attachment.description}" if attachment.description.present? 50 | 51 | caption 52 | end 53 | 54 | def lightbox_image_classes(attachment, base_classes = '') 55 | classes = [] 56 | classes << base_classes.split if base_classes.present? 57 | 58 | if attachment.is_pdf? 59 | classes << 'lightbox' 60 | classes << 'pdf' 61 | elsif attachment.is_image? 62 | classes << 'lightbox' 63 | classes << attachment.filename.split('.').last.downcase 64 | end 65 | 66 | classes.join ' ' 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - rubocop-performance 3 | - rubocop-rails 4 | - rubocop-minitest 5 | 6 | AllCops: 7 | TargetRubyVersion: 2.7 8 | TargetRailsVersion: 5.2 9 | NewCops: enable 10 | ActiveSupportExtensionsEnabled: true 11 | 12 | Rails: 13 | Enabled: true 14 | 15 | Minitest/MultipleAssertions: 16 | Max: 5 17 | Enabled: true 18 | 19 | Minitest/AssertPredicate: 20 | Enabled: false 21 | 22 | Minitest/TestMethodName: 23 | Enabled: true 24 | Exclude: 25 | - 'test/test_helper.rb' 26 | 27 | Metrics/AbcSize: 28 | Enabled: false 29 | 30 | Metrics/BlockLength: 31 | Enabled: false 32 | 33 | Metrics/ParameterLists: 34 | Enabled: true 35 | CountKeywordArgs: false 36 | 37 | Metrics/ClassLength: 38 | Enabled: false 39 | 40 | Metrics/CyclomaticComplexity: 41 | Max: 25 42 | 43 | Style/HashConversion: 44 | Enabled: true 45 | 46 | Layout/LineLength: 47 | Max: 140 48 | 49 | Metrics/MethodLength: 50 | Max: 60 51 | 52 | Metrics/ModuleLength: 53 | Enabled: false 54 | 55 | Metrics/PerceivedComplexity: 56 | Max: 25 57 | 58 | Rails/ApplicationJob: 59 | Enabled: false 60 | 61 | Rails/ApplicationRecord: 62 | Enabled: false 63 | 64 | Rails/CreateTableWithTimestamps: 65 | Enabled: false 66 | 67 | Rails/HelperInstanceVariable: 68 | Enabled: false 69 | 70 | Rails/SkipsModelValidations: 71 | Enabled: false 72 | 73 | Performance/ChainArrayAllocation: 74 | Enabled: true 75 | 76 | Style/AutoResourceCleanup: 77 | Enabled: true 78 | 79 | Style/ExpandPathArguments: 80 | Enabled: true 81 | Exclude: 82 | - test/**/* 83 | 84 | Style/FrozenStringLiteralComment: 85 | Enabled: true 86 | Exclude: 87 | - '/**/*.rsb' 88 | 89 | Style/OptionHash: 90 | Enabled: true 91 | SuspiciousParamNames: 92 | - options 93 | - api_options 94 | - opts 95 | - args 96 | - params 97 | - parameters 98 | - settings 99 | 100 | Style/ReturnNil: 101 | Enabled: true 102 | 103 | Style/UnlessLogicalOperators: 104 | Enabled: true 105 | 106 | Style/MethodCallWithArgsParentheses: 107 | Enabled: true 108 | AllowParenthesesInMultilineCall: true 109 | AllowParenthesesInChaining: true 110 | EnforcedStyle: omit_parentheses 111 | 112 | Style/SuperWithArgsParentheses: 113 | Enabled: false 114 | 115 | Style/Documentation: 116 | Enabled: false 117 | 118 | Style/HashTransformValues: 119 | Enabled: false 120 | 121 | Naming/VariableNumber: 122 | Enabled: true 123 | Exclude: 124 | - 'test/**/*' 125 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | pull_request: 5 | 6 | jobs: 7 | test: 8 | name: ${{ matrix.redmine }} ruby-${{ matrix.ruby }} 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | ruby: ['3.2', '3.3', '3.4'] 14 | redmine: ['6.1-stable', 'master'] 15 | db: ['postgres', 'mysql'] 16 | fail-fast: false 17 | 18 | services: 19 | postgres: 20 | image: postgres:18 21 | env: 22 | POSTGRES_USER: postgres 23 | POSTGRES_PASSWORD: postgres 24 | ports: 25 | - 5432:5432 26 | 27 | options: >- 28 | --health-cmd pg_isready 29 | --health-interval 10s 30 | --health-timeout 5s 31 | --health-retries 5 32 | 33 | steps: 34 | - name: Checkout Redmine 35 | uses: actions/checkout@v5 36 | with: 37 | repository: redmine/redmine 38 | ref: ${{ matrix.redmine }} 39 | path: redmine 40 | 41 | - name: Checkout redmine_lightbox 42 | uses: actions/checkout@v5 43 | with: 44 | repository: AlphaNodes/redmine_lightbox 45 | path: redmine/plugins/redmine_lightbox 46 | 47 | - name: Update package archives 48 | run: sudo apt-get update --yes --quiet 49 | 50 | - name: Install package dependencies 51 | run: > 52 | sudo apt-get install --yes --quiet 53 | build-essential 54 | cmake 55 | libicu-dev 56 | libpq-dev 57 | 58 | - name: Setup Chrome 59 | uses: browser-actions/setup-chrome@v1 60 | with: 61 | chrome-version: stable 62 | 63 | - name: Verify Chrome installation 64 | run: | 65 | chrome --version 66 | which chrome 67 | 68 | - name: Setup Ruby 69 | uses: ruby/setup-ruby@v1 70 | with: 71 | ruby-version: ${{ matrix.ruby }} 72 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically 73 | 74 | - name: Prepare Redmine source 75 | working-directory: redmine 76 | run: | 77 | cp plugins/redmine_lightbox/test/support/database.yml config/ 78 | cp plugins/redmine_lightbox/test/support/configuration.yml config/ 79 | 80 | - name: Install Ruby dependencies 81 | working-directory: redmine 82 | run: | 83 | bundle config set --local without 'development' 84 | bundle install --jobs=4 --retry=3 85 | 86 | - name: Run Redmine rake tasks 87 | env: 88 | RAILS_ENV: test 89 | working-directory: redmine 90 | run: | 91 | bundle exec rake generate_secret_token 92 | bundle exec rake db:create db:migrate 93 | 94 | - name: Run tests 95 | env: 96 | RAILS_ENV: test 97 | working-directory: redmine 98 | run: bundle exec rake redmine:plugins:test NAME=redmine_lightbox RUBYOPT="-W0" 99 | -------------------------------------------------------------------------------- /test/fixtures/dashboards.yml: -------------------------------------------------------------------------------- 1 | system_default_welcome: 2 | name: Global default dashboard 3 | dashboard_type: <%= DashboardContentWelcome::TYPE_NAME %> 4 | system_default: true 5 | locked: true 6 | enable_sidebar: false 7 | author_id: 1 8 | visibility: 2 9 | options: | 10 | --- 11 | :layout: 12 | top: 13 | - issuequery 14 | - my_spent_time 15 | left: 16 | - text 17 | - text_async 18 | - legacy_left 19 | right: 20 | - text__1 21 | - legacy_right 22 | :layout_settings: 23 | issuequery: 24 | :query_id: '1' 25 | text: 26 | :title: Welcome left 27 | :text: Some example text in left text block 28 | text_async: 29 | :title: Async loaded 30 | :text: Use it for better performance 31 | text__1: 32 | :title: Welcome right 33 | :text: Some example text in right text block 34 | 35 | system_default_project: 36 | name: Project default dashboard 37 | dashboard_type: <%= DashboardContentProject::TYPE_NAME %> 38 | system_default: true 39 | locked: true 40 | enable_sidebar: true 41 | project_id: 42 | author_id: 1 43 | visibility: 2 44 | options: | 45 | --- 46 | :layout: 47 | top: 48 | - issuequery 49 | left: 50 | - text 51 | - legacy_left 52 | right: 53 | - text__1 54 | - legacy_right 55 | :layout_settings: 56 | issuequery: 57 | :query_id: '1' 58 | text: 59 | :title: Project overview left 60 | :text: Some example text in left text block 61 | text__1: 62 | :title: Project overview right 63 | :text: Some example text in right text block 64 | 65 | private_welcome: 66 | name: Only for user 1 67 | dashboard_type: <%= DashboardContentWelcome::TYPE_NAME %> 68 | enable_sidebar: true 69 | author_id: 1 70 | visibility: 0 71 | options: | 72 | --- 73 | :layout: 74 | left: 75 | - legacy_left 76 | right: 77 | - legacy_right 78 | :layout_settings: {} 79 | 80 | private_welcome2: 81 | name: Only for user 2 82 | dashboard_type: <%= DashboardContentWelcome::TYPE_NAME %> 83 | author_id: 2 84 | visibility: 0 85 | options: | 86 | --- 87 | :layout: 88 | left: 89 | - legacy_left 90 | right: 91 | - legacy_right 92 | :layout_settings: {} 93 | 94 | private_project_default: 95 | name: Private project default 96 | dashboard_type: <%= DashboardContentProject::TYPE_NAME %> 97 | project_id: 98 | author_id: 1 99 | visibility: 0 100 | 101 | private_project: 102 | name: Private project for user 1 103 | dashboard_type: <%= DashboardContentProject::TYPE_NAME %> 104 | project_id: 1 105 | author_id: 1 106 | visibility: 0 107 | 108 | private_project2: 109 | name: Private project for user 2 110 | dashboard_type: <%= DashboardContentProject::TYPE_NAME %> 111 | project_id: 1 112 | author_id: 2 113 | visibility: 0 114 | 115 | public_welcome: 116 | name: Public welcome 117 | dashboard_type: <%= DashboardContentWelcome::TYPE_NAME %> 118 | author_id: 1 119 | visibility: 2 120 | 121 | welcome_for_roles: 122 | name: Welcome for roles 123 | dashboard_type: <%= DashboardContentWelcome::TYPE_NAME %> 124 | author_id: 1 125 | visibility: 1 126 | -------------------------------------------------------------------------------- /assets/javascripts/lightbox.js: -------------------------------------------------------------------------------- 1 | /* global GLightbox, Map */ 2 | 3 | (function() { 4 | 'use strict'; 5 | 6 | // File extension regex matching on supported image types 7 | const extensionRegexImage = /\.(png|jpe?g|gif|bmp)$/i; 8 | 9 | // Store lightbox instance globally to destroy and recreate after AJAX 10 | let lightboxInstance = null; 11 | 12 | function initializeLightbox() { 13 | // Collect all lightbox links (images and PDFs) in DOM order for unified slideshow 14 | const allLightboxLinks = []; 15 | const seenHrefs = new Map(); // For deduplication 16 | 17 | // Helper to add link if not duplicate 18 | function addLightboxLink(link) { 19 | const href = link.href; 20 | if (!seenHrefs.has(href)) { 21 | seenHrefs.set(href, true); 22 | allLightboxLinks.push(link); 23 | } 24 | } 25 | 26 | // Collect image links 27 | const imageSelectors = [ 28 | 'div.attachments a.lightbox:not(.pdf)', 29 | 'div.attachments a.lightbox-preview', 30 | 'table.list.files a.icon-magnifier:not([href$=".pdf"])', 31 | '.controller-dmsf #browser a.lightbox', 32 | 'table.list.files td.filename a.lightbox:not(.pdf)' 33 | ]; 34 | 35 | imageSelectors.forEach(function(selector) { 36 | document.querySelectorAll(selector).forEach(addLightboxLink); 37 | }); 38 | 39 | // Add journal detail links that match image regex 40 | document.querySelectorAll('div.journal ul.journal-details a:not(.icon-download)').forEach(function(link) { 41 | const href = link.getAttribute('href'); 42 | if (href && href.match(extensionRegexImage)) { 43 | addLightboxLink(link); 44 | } 45 | }); 46 | 47 | // Add journal thumbnails that are images 48 | document.querySelectorAll('div.journal div.thumbnails a').forEach(function(link) { 49 | const href = link.getAttribute('href'); 50 | if (href && href.match(extensionRegexImage)) { 51 | addLightboxLink(link); 52 | } 53 | }); 54 | 55 | // Add attachment thumbnails that are images (e.g., user files tab) 56 | document.querySelectorAll('div.attachments div.thumbnails a').forEach(function(link) { 57 | const href = link.getAttribute('href'); 58 | if (href && href.match(extensionRegexImage)) { 59 | addLightboxLink(link); 60 | } 61 | }); 62 | 63 | // Add wiki thumbnails that are images 64 | document.querySelectorAll('div.wiki a.thumbnail').forEach(function(link) { 65 | const href = link.getAttribute('href'); 66 | if (href && href.match(extensionRegexImage)) { 67 | addLightboxLink(link); 68 | } 69 | }); 70 | 71 | // Add avatar links (contact photos, user avatars) that point to image attachments 72 | document.querySelectorAll('a[href*="/attachments/"]').forEach(function(link) { 73 | const img = link.querySelector('img.avatar'); 74 | const href = link.getAttribute('href'); 75 | if (img && href && href.match(extensionRegexImage)) { 76 | // Convert /attachments/{id}/{filename} to /attachments/thumbnail/{id}/400 77 | // This handles Contacts plugin avatar links that point to HTML detail pages 78 | const thumbnailMatch = href.match(/\/attachments\/(\d+)\//); 79 | if (thumbnailMatch) { 80 | const attachmentId = thumbnailMatch[1]; 81 | // Rewrite href to use 400px thumbnail instead of detail page 82 | link.href = '/attachments/thumbnail/' + attachmentId + '/400'; 83 | } 84 | addLightboxLink(link); 85 | } 86 | }); 87 | 88 | // Collect PDF links 89 | const pdfSelectors = [ 90 | 'div.attachments a.pdf', 91 | 'table.list.files td.filename a.lightbox.pdf', 92 | 'table.list.files a.icon-magnifier[href$=".pdf"]' 93 | ]; 94 | 95 | pdfSelectors.forEach(function(selector) { 96 | document.querySelectorAll(selector).forEach(addLightboxLink); 97 | }); 98 | 99 | // Add journal detail and thumbnail links that match PDF regex 100 | document.querySelectorAll('div.journal ul.journal-details a:not(.icon-download)').forEach(function(link) { 101 | const href = link.getAttribute('href'); 102 | if (href && href.match(/\.pdf$/i)) { 103 | addLightboxLink(link); 104 | } 105 | }); 106 | 107 | document.querySelectorAll('div.journal div.thumbnails a').forEach(function(link) { 108 | const href = link.getAttribute('href'); 109 | if (href && href.match(/\.pdf$/i)) { 110 | addLightboxLink(link); 111 | } 112 | }); 113 | 114 | // Add attachment thumbnails that are PDFs (e.g., user files tab) 115 | document.querySelectorAll('div.attachments div.thumbnails a').forEach(function(link) { 116 | const href = link.getAttribute('href'); 117 | if (href && href.match(/\.pdf$/i)) { 118 | addLightboxLink(link); 119 | } 120 | }); 121 | 122 | // Build unified elements array for GLightbox 123 | if (allLightboxLinks.length > 0) { 124 | const elements = []; 125 | 126 | allLightboxLinks.forEach(function(link) { 127 | const href = link.href; 128 | const isPdf = href.match(/\.pdf$/i); 129 | 130 | if (isPdf) { 131 | // PDF: use iframe content 132 | elements.push({ 133 | content: '', 134 | width: '90vw', 135 | height: '90vh' 136 | }); 137 | } else { 138 | // Image: use href 139 | elements.push({ 140 | href: href, 141 | type: 'image' 142 | }); 143 | } 144 | }); 145 | 146 | // Destroy previous instance if exists 147 | if (lightboxInstance) { 148 | lightboxInstance.destroy(); 149 | } 150 | 151 | // Create single GLightbox instance for all media 152 | lightboxInstance = GLightbox({ 153 | elements: elements, 154 | touchNavigation: true, 155 | loop: true, 156 | zoomable: true, 157 | draggable: true, 158 | closeOnOutsideClick: true 159 | }); 160 | 161 | // Attach click handlers directly to lightbox links (efficient) 162 | allLightboxLinks.forEach(function(link, index) { 163 | link.addEventListener('click', function(e) { 164 | e.preventDefault(); 165 | lightboxInstance.openAt(index); 166 | }); 167 | }); 168 | 169 | // Handle duplicate links (same href as lightbox link) 170 | // Exclude download links - they should trigger actual download 171 | const allLinks = document.querySelectorAll('a[href]:not(.icon-download)'); 172 | allLinks.forEach(function(link) { 173 | const href = link.href; 174 | // Check if this link is NOT already in allLightboxLinks but has same href 175 | const isInLightboxLinks = allLightboxLinks.some(function(lbLink) { 176 | return lbLink === link; 177 | }); 178 | 179 | if (!isInLightboxLinks) { 180 | // Find index in our unique list 181 | const index = allLightboxLinks.findIndex(function(l) { 182 | return l.href === href; 183 | }); 184 | 185 | if (index !== -1) { 186 | link.addEventListener('click', function(e) { 187 | e.preventDefault(); 188 | lightboxInstance.openAt(index); 189 | }); 190 | } 191 | } 192 | }); 193 | } 194 | } 195 | 196 | // Initialize on DOM ready 197 | document.addEventListener('DOMContentLoaded', initializeLightbox); 198 | 199 | // Re-initialize after AJAX content is loaded (for tabs, etc.) 200 | document.addEventListener('ajax:complete', function() { 201 | // Use setTimeout to ensure DOM is updated before initializing 202 | setTimeout(initializeLightbox, 100); 203 | }); 204 | 205 | // Re-initialize after jQuery UI tabs are activated (Redmine uses jQuery UI tabs) 206 | // Use event delegation on document since tabs might not exist yet 207 | if (typeof jQuery !== 'undefined') { 208 | jQuery(document).on('tabsactivate', function() { 209 | setTimeout(initializeLightbox, 100); 210 | }); 211 | } 212 | 213 | // Fallback: Observe DOM changes for dynamically loaded content 214 | // This catches AJAX-loaded tabs that don't fire proper events 215 | const observer = new MutationObserver(function(mutations) { 216 | mutations.forEach(function(mutation) { 217 | // Check if new nodes were added with lightbox links 218 | if (mutation.addedNodes.length > 0) { 219 | mutation.addedNodes.forEach(function(node) { 220 | if (node.nodeType === 1) { // Element node 221 | const hasLightboxLinks = node.querySelector && node.querySelector('a.lightbox'); 222 | if (hasLightboxLinks) { 223 | setTimeout(initializeLightbox, 100); 224 | } 225 | } 226 | }); 227 | } 228 | }); 229 | }); 230 | 231 | // Observe changes to tab containers (where tabs load content) 232 | document.addEventListener('DOMContentLoaded', function() { 233 | // Issue page uses #history, User page uses #user-history 234 | const containers = ['history', 'user-history']; 235 | containers.forEach(function(id) { 236 | const container = document.getElementById(id); 237 | if (container) { 238 | observer.observe(container, { 239 | childList: true, 240 | subtree: true 241 | }); 242 | } 243 | }); 244 | }); 245 | })(); 246 | -------------------------------------------------------------------------------- /assets/stylesheets/glightbox.min.css: -------------------------------------------------------------------------------- 1 | .glightbox-container{width:100%;height:100%;position:fixed;top:0;left:0;z-index:999999!important;overflow:hidden;-ms-touch-action:none;touch-action:none;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;outline:0}.glightbox-container.inactive{display:none}.glightbox-container .gcontainer{position:relative;width:100%;height:100%;z-index:9999;overflow:hidden}.glightbox-container .gslider{-webkit-transition:-webkit-transform .4s ease;transition:-webkit-transform .4s ease;transition:transform .4s ease;transition:transform .4s ease,-webkit-transform .4s ease;height:100%;left:0;top:0;width:100%;position:relative;overflow:hidden;display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.glightbox-container .gslide{width:100%;position:absolute;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;opacity:0}.glightbox-container .gslide.current{opacity:1;z-index:99999;position:relative}.glightbox-container .gslide.prev{opacity:1;z-index:9999}.glightbox-container .gslide-inner-content{width:100%}.glightbox-container .ginner-container{position:relative;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;margin:auto;height:100vh}.glightbox-container .ginner-container.gvideo-container{width:100%}.glightbox-container .ginner-container.desc-bottom,.glightbox-container .ginner-container.desc-top{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.glightbox-container .ginner-container.desc-left,.glightbox-container .ginner-container.desc-right{max-width:100%!important}.gslide iframe,.gslide video{outline:0!important;border:none;min-height:165px;-webkit-overflow-scrolling:touch;-ms-touch-action:auto;touch-action:auto}.gslide:not(.current){pointer-events:none}.gslide-image{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.gslide-image img{max-height:100vh;display:block;padding:0;float:none;outline:0;border:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;max-width:100vw;width:auto;height:auto;-o-object-fit:cover;object-fit:cover;-ms-touch-action:none;touch-action:none;margin:auto;min-width:200px}.desc-bottom .gslide-image img,.desc-top .gslide-image img{width:auto}.desc-left .gslide-image img,.desc-right .gslide-image img{width:auto;max-width:100%}.gslide-image img.zoomable{position:relative}.gslide-image img.dragging{cursor:-webkit-grabbing!important;cursor:grabbing!important;-webkit-transition:none;transition:none}.gslide-video{position:relative;max-width:100vh;width:100%!important}.gslide-video .plyr__poster-enabled.plyr--loading .plyr__poster{display:none}.gslide-video .gvideo-wrapper{width:100%;margin:auto}.gslide-video::before{content:'';position:absolute;width:100%;height:100%;background:rgba(255,0,0,.34);display:none}.gslide-video.playing::before{display:none}.gslide-video.fullscreen{max-width:100%!important;min-width:100%;height:75vh}.gslide-video.fullscreen video{max-width:100%!important;width:100%!important}.gslide-inline{background:#fff;text-align:left;max-height:calc(100vh - 40px);overflow:auto;max-width:100%;margin:auto}.gslide-inline .ginlined-content{padding:20px;width:100%}.gslide-inline .dragging{cursor:-webkit-grabbing!important;cursor:grabbing!important;-webkit-transition:none;transition:none}.ginlined-content{overflow:auto;display:block!important;opacity:1}.gslide-external{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;min-width:100%;background:#fff;padding:0;overflow:auto;max-height:75vh;height:100%}.gslide-media{display:-webkit-box;display:-ms-flexbox;display:flex;width:auto}.zoomed .gslide-media{-webkit-box-shadow:none!important;box-shadow:none!important}.desc-bottom .gslide-media,.desc-top .gslide-media{margin:0 auto;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.gslide-description{position:relative;-webkit-box-flex:1;-ms-flex:1 0 100%;flex:1 0 100%}.gslide-description.description-left,.gslide-description.description-right{max-width:100%}.gslide-description.description-bottom,.gslide-description.description-top{margin:0 auto;width:100%}.gslide-description p{margin-bottom:12px}.gslide-description p:last-child{margin-bottom:0}.zoomed .gslide-description{display:none}.glightbox-button-hidden{display:none}.glightbox-mobile .glightbox-container .gslide-description{height:auto!important;width:100%;position:absolute;bottom:0;padding:19px 11px;max-width:100vw!important;-webkit-box-ordinal-group:3!important;-ms-flex-order:2!important;order:2!important;max-height:78vh;overflow:auto!important;background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,.75)));background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,.75) 100%);-webkit-transition:opacity .3s linear;transition:opacity .3s linear;padding-bottom:50px}.glightbox-mobile .glightbox-container .gslide-title{color:#fff;font-size:1em}.glightbox-mobile .glightbox-container .gslide-desc{color:#a1a1a1}.glightbox-mobile .glightbox-container .gslide-desc a{color:#fff;font-weight:700}.glightbox-mobile .glightbox-container .gslide-desc *{color:inherit}.glightbox-mobile .glightbox-container .gslide-desc .desc-more{color:#fff;opacity:.4}.gdesc-open .gslide-media{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;opacity:.4}.gdesc-open .gdesc-inner{padding-bottom:30px}.gdesc-closed .gslide-media{-webkit-transition:opacity .5s ease;transition:opacity .5s ease;opacity:1}.greset{-webkit-transition:all .3s ease;transition:all .3s ease}.gabsolute{position:absolute}.grelative{position:relative}.glightbox-desc{display:none!important}.glightbox-open{overflow:hidden}.gloader{height:25px;width:25px;-webkit-animation:lightboxLoader .8s infinite linear;animation:lightboxLoader .8s infinite linear;border:2px solid #fff;border-right-color:transparent;border-radius:50%;position:absolute;display:block;z-index:9999;left:0;right:0;margin:0 auto;top:47%}.goverlay{width:100%;height:calc(100vh + 1px);position:fixed;top:-1px;left:0;background:#000;will-change:opacity}.glightbox-mobile .goverlay{background:#000}.gclose,.gnext,.gprev{z-index:99999;cursor:pointer;width:26px;height:44px;border:none;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.gclose svg,.gnext svg,.gprev svg{display:block;width:25px;height:auto;margin:0;padding:0}.gclose.disabled,.gnext.disabled,.gprev.disabled{opacity:.1}.gclose .garrow,.gnext .garrow,.gprev .garrow{stroke:#fff}.gbtn.focused{outline:2px solid #0f3d81}iframe.wait-autoplay{opacity:0}.glightbox-closing .gclose,.glightbox-closing .gnext,.glightbox-closing .gprev{opacity:0!important}.glightbox-clean .gslide-description{background:#fff}.glightbox-clean .gdesc-inner{padding:22px 20px}.glightbox-clean .gslide-title{font-size:1em;font-weight:400;font-family:arial;color:#000;margin-bottom:19px;line-height:1.4em}.glightbox-clean .gslide-desc{font-size:.86em;margin-bottom:0;font-family:arial;line-height:1.4em}.glightbox-clean .gslide-video{background:#000}.glightbox-clean .gclose,.glightbox-clean .gnext,.glightbox-clean .gprev{background-color:rgba(0,0,0,.75);border-radius:4px}.glightbox-clean .gclose path,.glightbox-clean .gnext path,.glightbox-clean .gprev path{fill:#fff}.glightbox-clean .gprev{position:absolute;top:-100%;left:30px;width:40px;height:50px}.glightbox-clean .gnext{position:absolute;top:-100%;right:30px;width:40px;height:50px}.glightbox-clean .gclose{width:35px;height:35px;top:15px;right:10px;position:absolute}.glightbox-clean .gclose svg{width:18px;height:auto}.glightbox-clean .gclose:hover{opacity:1}.gfadeIn{-webkit-animation:gfadeIn .5s ease;animation:gfadeIn .5s ease}.gfadeOut{-webkit-animation:gfadeOut .5s ease;animation:gfadeOut .5s ease}.gslideOutLeft{-webkit-animation:gslideOutLeft .3s ease;animation:gslideOutLeft .3s ease}.gslideInLeft{-webkit-animation:gslideInLeft .3s ease;animation:gslideInLeft .3s ease}.gslideOutRight{-webkit-animation:gslideOutRight .3s ease;animation:gslideOutRight .3s ease}.gslideInRight{-webkit-animation:gslideInRight .3s ease;animation:gslideInRight .3s ease}.gzoomIn{-webkit-animation:gzoomIn .5s ease;animation:gzoomIn .5s ease}.gzoomOut{-webkit-animation:gzoomOut .5s ease;animation:gzoomOut .5s ease}@-webkit-keyframes lightboxLoader{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes lightboxLoader{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes gfadeIn{from{opacity:0}to{opacity:1}}@keyframes gfadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes gfadeOut{from{opacity:1}to{opacity:0}}@keyframes gfadeOut{from{opacity:1}to{opacity:0}}@-webkit-keyframes gslideInLeft{from{opacity:0;-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0)}to{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes gslideInLeft{from{opacity:0;-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0)}to{visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes gslideOutLeft{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0);opacity:0;visibility:hidden}}@keyframes gslideOutLeft{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-60%,0,0);transform:translate3d(-60%,0,0);opacity:0;visibility:hidden}}@-webkit-keyframes gslideInRight{from{opacity:0;visibility:visible;-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes gslideInRight{from{opacity:0;visibility:visible;-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes gslideOutRight{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0);opacity:0}}@keyframes gslideOutRight{from{opacity:1;visibility:visible;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(60%,0,0);transform:translate3d(60%,0,0);opacity:0}}@-webkit-keyframes gzoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:1}}@keyframes gzoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:1}}@-webkit-keyframes gzoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes gzoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@media (min-width:769px){.glightbox-container .ginner-container{width:auto;height:auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.glightbox-container .ginner-container.desc-top .gslide-description{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.glightbox-container .ginner-container.desc-top .gslide-image,.glightbox-container .ginner-container.desc-top .gslide-image img{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.glightbox-container .ginner-container.desc-left .gslide-description{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.glightbox-container .ginner-container.desc-left .gslide-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.gslide-image img{max-height:97vh;max-width:100%}.gslide-image img.zoomable{cursor:-webkit-zoom-in;cursor:zoom-in}.zoomed .gslide-image img.zoomable{cursor:-webkit-grab;cursor:grab}.gslide-inline{max-height:95vh}.gslide-external{max-height:100vh}.gslide-description.description-left,.gslide-description.description-right{max-width:275px}.glightbox-open{height:auto}.goverlay{background:rgba(0,0,0,.92)}.glightbox-clean .gslide-media{-webkit-box-shadow:1px 2px 9px 0 rgba(0,0,0,.65);box-shadow:1px 2px 9px 0 rgba(0,0,0,.65)}.glightbox-clean .description-left .gdesc-inner,.glightbox-clean .description-right .gdesc-inner{position:absolute;height:100%;overflow-y:auto}.glightbox-clean .gclose,.glightbox-clean .gnext,.glightbox-clean .gprev{background-color:rgba(0,0,0,.32)}.glightbox-clean .gclose:hover,.glightbox-clean .gnext:hover,.glightbox-clean .gprev:hover{background-color:rgba(0,0,0,.7)}.glightbox-clean .gprev{top:45%}.glightbox-clean .gnext{top:45%}}@media (min-width:992px){.glightbox-clean .gclose{opacity:.7;right:20px}}@media screen and (max-height:420px){.goverlay{background:#000}} -------------------------------------------------------------------------------- /assets/javascripts/glightbox.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).GLightbox=t()}(this,(function(){"use strict";function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n=e[l]=e[l]||[],s={all:n,evt:null,found:null};return t&&i&&M(n)>0&&r(n,(function(e,n){if(e.eventName==t&&e.fn.toString()==i.toString())return s.found=!0,s.evt=n,!1})),s}function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.onElement,n=t.withCallback,s=t.avoidDuplicate,l=void 0===s||s,o=t.once,h=void 0!==o&&o,d=t.useCapture,c=void 0!==d&&d,u=arguments.length>2?arguments[2]:void 0,g=i||[];function v(e){C(n)&&n.call(u,e,this),h&&v.destroy()}return k(g)&&(g=document.querySelectorAll(g)),v.destroy=function(){r(g,(function(t){var i=a(t,e,v);i.found&&i.all.splice(i.evt,1),t.removeEventListener&&t.removeEventListener(e,v,c)}))},r(g,(function(t){var i=a(t,e,v);(t.addEventListener&&l&&!i.found||!l)&&(t.addEventListener(e,v,c),i.all.push({eventName:e,fn:v}))})),v}function d(e,t){r(t.split(" "),(function(t){return e.classList.add(t)}))}function c(e,t){r(t.split(" "),(function(t){return e.classList.remove(t)}))}function u(e,t){return e.classList.contains(t)}function g(e,t){for(;e!==document.body;){if(!(e=e.parentElement))return!1;if("function"==typeof e.matches?e.matches(t):e.msMatchesSelector(t))return e}}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!e||""===t)return!1;if("none"===t)return C(i)&&i(),!1;var n=b(),s=t.split(" ");r(s,(function(t){d(e,"g"+t)})),h(n,{onElement:e,avoidDuplicate:!1,once:!0,withCallback:function(e,t){r(s,(function(e){c(t,"g"+e)})),C(i)&&i()}})}function f(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(""===t)return e.style.webkitTransform="",e.style.MozTransform="",e.style.msTransform="",e.style.OTransform="",e.style.transform="",!1;e.style.webkitTransform=t,e.style.MozTransform=t,e.style.msTransform=t,e.style.OTransform=t,e.style.transform=t}function p(e){e.style.display="block"}function m(e){e.style.display="none"}function y(e){var t=document.createDocumentFragment(),i=document.createElement("div");for(i.innerHTML=e;i.firstChild;)t.appendChild(i.firstChild);return t}function x(){return{width:window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,height:window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}}function b(){var e,t=document.createElement("fakeelement"),i={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(e in i)if(void 0!==t.style[e])return i[e]}function S(e,t,i,n){if(e())t();else{var s;i||(i=100);var l=setInterval((function(){e()&&(clearInterval(l),s&&clearTimeout(s),t())}),i);n&&(s=setTimeout((function(){clearInterval(l)}),n))}}function w(e,t,i){if(O(e))console.error("Inject assets error");else if(C(t)&&(i=t,t=!1),k(t)&&t in window)C(i)&&i();else{var n;if(-1!==e.indexOf(".css")){if((n=document.querySelectorAll('link[href="'+e+'"]'))&&n.length>0)return void(C(i)&&i());var s=document.getElementsByTagName("head")[0],l=s.querySelectorAll('link[rel="stylesheet"]'),o=document.createElement("link");return o.rel="stylesheet",o.type="text/css",o.href=e,o.media="all",l?s.insertBefore(o,l[0]):s.appendChild(o),void(C(i)&&i())}if((n=document.querySelectorAll('script[src="'+e+'"]'))&&n.length>0){if(C(i)){if(k(t))return S((function(){return void 0!==window[t]}),(function(){i()})),!1;i()}}else{var r=document.createElement("script");r.type="text/javascript",r.src=e,r.onload=function(){if(C(i)){if(k(t))return S((function(){return void 0!==window[t]}),(function(){i()})),!1;i()}},document.body.appendChild(r)}}}function T(){return"navigator"in window&&window.navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i)}function C(e){return"function"==typeof e}function k(e){return"string"==typeof e}function E(e){return!(!e||!e.nodeType||1!=e.nodeType)}function A(e){return Array.isArray(e)}function L(e){return e&&e.length&&isFinite(e.length)}function I(e){return"object"===s(e)&&null!=e&&!C(e)&&!A(e)}function O(e){return null==e}function P(e,t){return null!==e&&hasOwnProperty.call(e,t)}function M(e){if(I(e)){if(e.keys)return e.keys().length;var t=0;for(var i in e)P(e,i)&&t++;return t}return e.length}function z(e){return!isNaN(parseFloat(e))&&isFinite(e)}function X(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:-1,t=document.querySelectorAll(".gbtn[data-taborder]:not(.disabled)");if(!t.length)return!1;if(1==t.length)return t[0];"string"==typeof e&&(e=parseInt(e));var i=[];r(t,(function(e){i.push(e.getAttribute("data-taborder"))}));var n=Math.max.apply(Math,i.map((function(e){return parseInt(e)}))),s=e<0?1:e+1;s>n&&(s="1");var l=i.filter((function(e){return e>=parseInt(s)})),o=l.sort()[0];return document.querySelector('.gbtn[data-taborder="'.concat(o,'"]'))}function Y(e){if(e.events.hasOwnProperty("keyboard"))return!1;e.events.keyboard=h("keydown",{onElement:window,withCallback:function(t,i){var n=(t=t||window.event).keyCode;if(9==n){var s=document.querySelector(".gbtn.focused");if(!s){var l=!(!document.activeElement||!document.activeElement.nodeName)&&document.activeElement.nodeName.toLocaleLowerCase();if("input"==l||"textarea"==l||"button"==l)return}t.preventDefault();var o=document.querySelectorAll(".gbtn[data-taborder]");if(!o||o.length<=0)return;if(!s){var r=X();return void(r&&(r.focus(),d(r,"focused")))}var a=X(s.getAttribute("data-taborder"));c(s,"focused"),a&&(a.focus(),d(a,"focused"))}39==n&&e.nextSlide(),37==n&&e.prevSlide(),27==n&&e.close()}})}var q=i((function t(i,n){var s=this,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(e(this,t),this.img=i,this.slide=n,this.onclose=l,this.img.setZoomEvents)return!1;this.active=!1,this.zoomedIn=!1,this.dragging=!1,this.currentX=null,this.currentY=null,this.initialX=null,this.initialY=null,this.xOffset=0,this.yOffset=0,this.img.addEventListener("mousedown",(function(e){return s.dragStart(e)}),!1),this.img.addEventListener("mouseup",(function(e){return s.dragEnd(e)}),!1),this.img.addEventListener("mousemove",(function(e){return s.drag(e)}),!1),this.img.addEventListener("click",(function(e){return s.slide.classList.contains("dragging-nav")?(s.zoomOut(),!1):s.zoomedIn?void(s.zoomedIn&&!s.dragging&&s.zoomOut()):s.zoomIn()}),!1),this.img.setZoomEvents=!0}),[{key:"zoomIn",value:function(){var e=this.widowWidth();if(!(this.zoomedIn||e<=768)){var t=this.img;if(t.setAttribute("data-style",t.getAttribute("style")),t.style.maxWidth=t.naturalWidth+"px",t.style.maxHeight=t.naturalHeight+"px",t.naturalWidth>e){var i=e/2-t.naturalWidth/2;this.setTranslate(this.img.parentNode,i,0)}this.slide.classList.add("zoomed"),this.zoomedIn=!0}}},{key:"zoomOut",value:function(){this.img.parentNode.setAttribute("style",""),this.img.setAttribute("style",this.img.getAttribute("data-style")),this.slide.classList.remove("zoomed"),this.zoomedIn=!1,this.currentX=null,this.currentY=null,this.initialX=null,this.initialY=null,this.xOffset=0,this.yOffset=0,this.onclose&&"function"==typeof this.onclose&&this.onclose()}},{key:"dragStart",value:function(e){e.preventDefault(),this.zoomedIn?("touchstart"===e.type?(this.initialX=e.touches[0].clientX-this.xOffset,this.initialY=e.touches[0].clientY-this.yOffset):(this.initialX=e.clientX-this.xOffset,this.initialY=e.clientY-this.yOffset),e.target===this.img&&(this.active=!0,this.img.classList.add("dragging"))):this.active=!1}},{key:"dragEnd",value:function(e){var t=this;e.preventDefault(),this.initialX=this.currentX,this.initialY=this.currentY,this.active=!1,setTimeout((function(){t.dragging=!1,t.img.isDragging=!1,t.img.classList.remove("dragging")}),100)}},{key:"drag",value:function(e){this.active&&(e.preventDefault(),"touchmove"===e.type?(this.currentX=e.touches[0].clientX-this.initialX,this.currentY=e.touches[0].clientY-this.initialY):(this.currentX=e.clientX-this.initialX,this.currentY=e.clientY-this.initialY),this.xOffset=this.currentX,this.yOffset=this.currentY,this.img.isDragging=!0,this.dragging=!0,this.setTranslate(this.img,this.currentX,this.currentY))}},{key:"onMove",value:function(e){if(this.zoomedIn){var t=e.clientX-this.img.naturalWidth/2,i=e.clientY-this.img.naturalHeight/2;this.setTranslate(this.img,t,i)}}},{key:"setTranslate",value:function(e,t,i){e.style.transform="translate3d("+t+"px, "+i+"px, 0)"}},{key:"widowWidth",value:function(){return window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth}}]),N=i((function t(){var i=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t);var s=n.dragEl,l=n.toleranceX,o=void 0===l?40:l,r=n.toleranceY,a=void 0===r?65:r,h=n.slide,d=void 0===h?null:h,c=n.instance,u=void 0===c?null:c;this.el=s,this.active=!1,this.dragging=!1,this.currentX=null,this.currentY=null,this.initialX=null,this.initialY=null,this.xOffset=0,this.yOffset=0,this.direction=null,this.lastDirection=null,this.toleranceX=o,this.toleranceY=a,this.toleranceReached=!1,this.dragContainer=this.el,this.slide=d,this.instance=u,this.el.addEventListener("mousedown",(function(e){return i.dragStart(e)}),!1),this.el.addEventListener("mouseup",(function(e){return i.dragEnd(e)}),!1),this.el.addEventListener("mousemove",(function(e){return i.drag(e)}),!1)}),[{key:"dragStart",value:function(e){if(this.slide.classList.contains("zoomed"))this.active=!1;else{"touchstart"===e.type?(this.initialX=e.touches[0].clientX-this.xOffset,this.initialY=e.touches[0].clientY-this.yOffset):(this.initialX=e.clientX-this.xOffset,this.initialY=e.clientY-this.yOffset);var t=e.target.nodeName.toLowerCase();e.target.classList.contains("nodrag")||g(e.target,".nodrag")||-1!==["input","select","textarea","button","a"].indexOf(t)?this.active=!1:(e.preventDefault(),(e.target===this.el||"img"!==t&&g(e.target,".gslide-inline"))&&(this.active=!0,this.el.classList.add("dragging"),this.dragContainer=g(e.target,".ginner-container")))}}},{key:"dragEnd",value:function(e){var t=this;e&&e.preventDefault(),this.initialX=0,this.initialY=0,this.currentX=null,this.currentY=null,this.initialX=null,this.initialY=null,this.xOffset=0,this.yOffset=0,this.active=!1,this.doSlideChange&&(this.instance.preventOutsideClick=!0,"right"==this.doSlideChange&&this.instance.prevSlide(),"left"==this.doSlideChange&&this.instance.nextSlide()),this.doSlideClose&&this.instance.close(),this.toleranceReached||this.setTranslate(this.dragContainer,0,0,!0),setTimeout((function(){t.instance.preventOutsideClick=!1,t.toleranceReached=!1,t.lastDirection=null,t.dragging=!1,t.el.isDragging=!1,t.el.classList.remove("dragging"),t.slide.classList.remove("dragging-nav"),t.dragContainer.style.transform="",t.dragContainer.style.transition=""}),100)}},{key:"drag",value:function(e){if(this.active){e.preventDefault(),this.slide.classList.add("dragging-nav"),"touchmove"===e.type?(this.currentX=e.touches[0].clientX-this.initialX,this.currentY=e.touches[0].clientY-this.initialY):(this.currentX=e.clientX-this.initialX,this.currentY=e.clientY-this.initialY),this.xOffset=this.currentX,this.yOffset=this.currentY,this.el.isDragging=!0,this.dragging=!0,this.doSlideChange=!1,this.doSlideClose=!1;var t=Math.abs(this.currentX),i=Math.abs(this.currentY);if(t>0&&t>=Math.abs(this.currentY)&&(!this.lastDirection||"x"==this.lastDirection)){this.yOffset=0,this.lastDirection="x",this.setTranslate(this.dragContainer,this.currentX,0);var n=this.shouldChange();if(!this.instance.settings.dragAutoSnap&&n&&(this.doSlideChange=n),this.instance.settings.dragAutoSnap&&n)return this.instance.preventOutsideClick=!0,this.toleranceReached=!0,this.active=!1,this.instance.preventOutsideClick=!0,this.dragEnd(null),"right"==n&&this.instance.prevSlide(),void("left"==n&&this.instance.nextSlide())}if(this.toleranceY>0&&i>0&&i>=t&&(!this.lastDirection||"y"==this.lastDirection)){this.xOffset=0,this.lastDirection="y",this.setTranslate(this.dragContainer,0,this.currentY);var s=this.shouldClose();return!this.instance.settings.dragAutoSnap&&s&&(this.doSlideClose=!0),void(this.instance.settings.dragAutoSnap&&s&&this.instance.close())}}}},{key:"shouldChange",value:function(){var e=!1;if(Math.abs(this.currentX)>=this.toleranceX){var t=this.currentX>0?"right":"left";("left"==t&&this.slide!==this.slide.parentNode.lastChild||"right"==t&&this.slide!==this.slide.parentNode.firstChild)&&(e=t)}return e}},{key:"shouldClose",value:function(){var e=!1;return Math.abs(this.currentY)>=this.toleranceY&&(e=!0),e}},{key:"setTranslate",value:function(e,t,i){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e.style.transition=n?"all .2s ease":"",e.style.transform="translate3d(".concat(t,"px, ").concat(i,"px, 0)")}}]);function D(e,t,i,n){var s=e.querySelector(".gslide-media"),l=new Image,o="gSlideTitle_"+i,r="gSlideDesc_"+i;l.addEventListener("load",(function(){C(n)&&n()}),!1),l.src=t.href,""!=t.sizes&&""!=t.srcset&&(l.sizes=t.sizes,l.srcset=t.srcset),l.alt="",O(t.alt)||""===t.alt||(l.alt=t.alt),""!==t.title&&l.setAttribute("aria-labelledby",o),""!==t.description&&l.setAttribute("aria-describedby",r),t.hasOwnProperty("_hasCustomWidth")&&t._hasCustomWidth&&(l.style.width=t.width),t.hasOwnProperty("_hasCustomHeight")&&t._hasCustomHeight&&(l.style.height=t.height),s.insertBefore(l,s.firstChild)}function _(e,t,i,n){var s=this,l=e.querySelector(".ginner-container"),o="gvideo"+i,r=e.querySelector(".gslide-media"),a=this.getAllPlayers();d(l,"gvideo-container"),r.insertBefore(y('
'),r.firstChild);var h=e.querySelector(".gvideo-wrapper");w(this.settings.plyr.css,"Plyr");var c=t.href,u=null==t?void 0:t.videoProvider,g=!1;r.style.maxWidth=t.width,w(this.settings.plyr.js,"Plyr",(function(){if(!u&&c.match(/vimeo\.com\/([0-9]*)/)&&(u="vimeo"),!u&&(c.match(/(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/)||c.match(/youtu\.be\/([a-zA-Z0-9\-_]+)/)||c.match(/(youtube\.com|youtube-nocookie\.com)\/embed\/([a-zA-Z0-9\-_]+)/)||c.match(/(youtube\.com|youtube-nocookie\.com)\/shorts\/([a-zA-Z0-9\-_]+)/))&&(u="youtube"),"local"===u||!u){u="local";var l='")}var r=g||y('
'));d(h,"".concat(u,"-video gvideo")),h.appendChild(r),h.setAttribute("data-id",o),h.setAttribute("data-index",i);var v=P(s.settings.plyr,"config")?s.settings.plyr.config:{},f=new Plyr("#"+o,v);f.on("ready",(function(e){a[o]=e.detail.plyr,C(n)&&n()})),S((function(){return e.querySelector("iframe")&&"true"==e.querySelector("iframe").dataset.ready}),(function(){s.resize(e)})),f.on("enterfullscreen",W),f.on("exitfullscreen",W)}))}function W(e){var t=g(e.target,".gslide-media");"enterfullscreen"===e.type&&d(t,"fullscreen"),"exitfullscreen"===e.type&&c(t,"fullscreen")}function B(e,t,i,n){var s,l=this,o=e.querySelector(".gslide-media"),r=!(!P(t,"href")||!t.href)&&t.href.split("#").pop().trim(),a=!(!P(t,"content")||!t.content)&&t.content;if(a&&(k(a)&&(s=y('
'.concat(a,"
"))),E(a))){"none"==a.style.display&&(a.style.display="block");var c=document.createElement("div");c.className="ginlined-content",c.appendChild(a),s=c}if(r){var u=document.getElementById(r);if(!u)return!1;var g=u.cloneNode(!0);g.style.height=t.height,g.style.maxWidth=t.width,d(g,"ginlined-content"),s=g}if(!s)return console.error("Unable to append inline slide content",t),!1;o.style.height=t.height,o.style.width=t.width,o.appendChild(s),this.events["inlineclose"+r]=h("click",{onElement:o.querySelectorAll(".gtrigger-close"),withCallback:function(e){e.preventDefault(),l.close()}}),C(n)&&n()}function H(e,t,i,n){var s=e.querySelector(".gslide-media"),l=function(e){var t=e.url,i=e.allow,n=e.callback,s=e.appendTo,l=document.createElement("iframe");return l.className="vimeo-video gvideo",l.src=t,l.style.width="100%",l.style.height="100%",i&&l.setAttribute("allow",i),l.onload=function(){l.onload=null,d(l,"node-ready"),C(n)&&n()},s&&s.appendChild(l),l}({url:t.href,callback:n});s.parentNode.style.maxWidth=t.width,s.parentNode.style.height=t.height,s.appendChild(l)}var j=i((function t(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.defaults={href:"",sizes:"",srcset:"",title:"",type:"",videoProvider:"",description:"",alt:"",descPosition:"bottom",effect:"",width:"",height:"",content:!1,zoomable:!0,draggable:!0},I(i)&&(this.defaults=o(this.defaults,i))}),[{key:"sourceType",value:function(e){var t=e;return null!==(e=e.toLowerCase()).match(/\.(jpeg|jpg|jpe|gif|png|apn|webp|avif|svg)/)?"image":e.match(/(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/)||e.match(/youtu\.be\/([a-zA-Z0-9\-_]+)/)||e.match(/(youtube\.com|youtube-nocookie\.com)\/embed\/([a-zA-Z0-9\-_]+)/)||e.match(/(youtube\.com|youtube-nocookie\.com)\/shorts\/([a-zA-Z0-9\-_]+)/)||e.match(/vimeo\.com\/([0-9]*)/)||null!==e.match(/\.(mp4|ogg|webm|mov)/)?"video":null!==e.match(/\.(mp3|wav|wma|aac|ogg)/)?"audio":e.indexOf("#")>-1&&""!==t.split("#").pop().trim()?"inline":e.indexOf("goajax=true")>-1?"ajax":"external"}},{key:"parseConfig",value:function(e,t){var i=this,n=o({descPosition:t.descPosition},this.defaults);if(I(e)&&!E(e)){P(e,"type")||(P(e,"content")&&e.content?e.type="inline":P(e,"href")&&(e.type=this.sourceType(e.href)));var s=o(n,e);return this.setSize(s,t),s}var l="",a=e.getAttribute("data-glightbox"),h=e.nodeName.toLowerCase();if("a"===h&&(l=e.href),"img"===h&&(l=e.src,n.alt=e.alt),n.href=l,r(n,(function(s,l){P(t,l)&&"width"!==l&&(n[l]=t[l]);var o=e.dataset[l];O(o)||(n[l]=i.sanitizeValue(o))})),n.content&&(n.type="inline"),!n.type&&l&&(n.type=this.sourceType(l)),O(a)){if(!n.title&&"a"==h){var d=e.title;O(d)||""===d||(n.title=d)}if(!n.title&&"img"==h){var c=e.alt;O(c)||""===c||(n.title=c)}}else{var u=[];r(n,(function(e,t){u.push(";\\s?"+t)})),u=u.join("\\s?:|"),""!==a.trim()&&r(n,(function(e,t){var s=a,l=new RegExp("s?"+t+"s?:s?(.*?)("+u+"s?:|$)"),o=s.match(l);if(o&&o.length&&o[1]){var r=o[1].trim().replace(/;\s*$/,"");n[t]=i.sanitizeValue(r)}}))}if(n.description&&"."===n.description.substring(0,1)){var g;try{g=document.querySelector(n.description).innerHTML}catch(e){if(!(e instanceof DOMException))throw e}g&&(n.description=g)}if(!n.description){var v=e.querySelector(".glightbox-desc");v&&(n.description=v.innerHTML)}return this.setSize(n,t,e),this.slideConfig=n,n}},{key:"setSize",value:function(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n="video"==e.type?this.checkSize(t.videosWidth):this.checkSize(t.width),s=this.checkSize(t.height);return e.width=P(e,"width")&&""!==e.width?this.checkSize(e.width):n,e.height=P(e,"height")&&""!==e.height?this.checkSize(e.height):s,i&&"image"==e.type&&(e._hasCustomWidth=!!i.dataset.width,e._hasCustomHeight=!!i.dataset.height),e}},{key:"checkSize",value:function(e){return z(e)?"".concat(e,"px"):e}},{key:"sanitizeValue",value:function(e){return"true"!==e&&"false"!==e?e:"true"===e}}]),V=i((function t(i,n,s){e(this,t),this.element=i,this.instance=n,this.index=s}),[{key:"setContent",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(u(t,"loaded"))return!1;var n=this.instance.settings,s=this.slideConfig,l=T();C(n.beforeSlideLoad)&&n.beforeSlideLoad({index:this.index,slide:t,player:!1});var o=s.type,r=s.descPosition,a=t.querySelector(".gslide-media"),h=t.querySelector(".gslide-title"),c=t.querySelector(".gslide-desc"),g=t.querySelector(".gdesc-inner"),v=i,f="gSlideTitle_"+this.index,p="gSlideDesc_"+this.index;if(C(n.afterSlideLoad)&&(v=function(){C(i)&&i(),n.afterSlideLoad({index:e.index,slide:t,player:e.instance.getSlidePlayerInstance(e.index)})}),""==s.title&&""==s.description?g&&g.parentNode.parentNode.removeChild(g.parentNode):(h&&""!==s.title?(h.id=f,h.innerHTML=s.title):h.parentNode.removeChild(h),c&&""!==s.description?(c.id=p,l&&n.moreLength>0?(s.smallDescription=this.slideShortDesc(s.description,n.moreLength,n.moreText),c.innerHTML=s.smallDescription,this.descriptionEvents(c,s)):c.innerHTML=s.description):c.parentNode.removeChild(c),d(a.parentNode,"desc-".concat(r)),d(g.parentNode,"description-".concat(r))),d(a,"gslide-".concat(o)),d(t,"loaded"),"video"!==o){if("external"!==o)return"inline"===o?(B.apply(this.instance,[t,s,this.index,v]),void(s.draggable&&new N({dragEl:t.querySelector(".gslide-inline"),toleranceX:n.dragToleranceX,toleranceY:n.dragToleranceY,slide:t,instance:this.instance}))):void("image"!==o?C(v)&&v():D(t,s,this.index,(function(){var i=t.querySelector("img");s.draggable&&new N({dragEl:i,toleranceX:n.dragToleranceX,toleranceY:n.dragToleranceY,slide:t,instance:e.instance}),s.zoomable&&i.naturalWidth>i.offsetWidth&&(d(i,"zoomable"),new q(i,t,(function(){e.instance.resize()}))),C(v)&&v()})));H.apply(this,[t,s,this.index,v])}else _.apply(this.instance,[t,s,this.index,v])}},{key:"slideShortDesc",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:50,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=document.createElement("div");n.innerHTML=e;var s=n.innerText,l=i;if((e=s.trim()).length<=t)return e;var o=e.substr(0,t-1);return l?(n=null,o+'... '+i+""):o}},{key:"descriptionEvents",value:function(e,t){var i=this,n=e.querySelector(".desc-more");if(!n)return!1;h("click",{onElement:n,withCallback:function(e,n){e.preventDefault();var s=document.body,l=g(n,".gslide-desc");if(!l)return!1;l.innerHTML=t.description,d(s,"gdesc-open");var o=h("click",{onElement:[s,g(l,".gslide-description")],withCallback:function(e,n){"a"!==e.target.nodeName.toLowerCase()&&(c(s,"gdesc-open"),d(s,"gdesc-closed"),l.innerHTML=t.smallDescription,i.descriptionEvents(l,t),setTimeout((function(){c(s,"gdesc-closed")}),400),o.destroy())}})}})}},{key:"create",value:function(){return y(this.instance.settings.slideHTML)}},{key:"getConfig",value:function(){E(this.element)||this.element.hasOwnProperty("draggable")||(this.element.draggable=this.instance.settings.draggable);var e=new j(this.instance.settings.slideExtraAttributes);return this.slideConfig=e.parseConfig(this.element,this.instance.settings),this.slideConfig}}]);function F(e){return Math.sqrt(e.x*e.x+e.y*e.y)}function R(e,t){var i=function(e,t){var i=F(e)*F(t);if(0===i)return 0;var n=function(e,t){return e.x*t.x+e.y*t.y}(e,t)/i;return n>1&&(n=1),Math.acos(n)}(e,t);return function(e,t){return e.x*t.y-t.x*e.y}(e,t)>0&&(i*=-1),180*i/Math.PI}var G=i((function t(i){e(this,t),this.handlers=[],this.el=i}),[{key:"add",value:function(e){this.handlers.push(e)}},{key:"del",value:function(e){e||(this.handlers=[]);for(var t=this.handlers.length;t>=0;t--)this.handlers[t]===e&&this.handlers.splice(t,1)}},{key:"dispatch",value:function(){for(var e=0,t=this.handlers.length;e=0)console.log("ignore drag for this touched element",e.target.nodeName.toLowerCase());else{this.now=Date.now(),this.x1=e.touches[0].pageX,this.y1=e.touches[0].pageY,this.delta=this.now-(this.last||this.now),this.touchStart.dispatch(e,this.element),null!==this.preTapPosition.x&&(this.isDoubleTap=this.delta>0&&this.delta<=250&&Math.abs(this.preTapPosition.x-this.x1)<30&&Math.abs(this.preTapPosition.y-this.y1)<30,this.isDoubleTap&&clearTimeout(this.singleTapTimeout)),this.preTapPosition.x=this.x1,this.preTapPosition.y=this.y1,this.last=this.now;var t=this.preV;if(e.touches.length>1){this._cancelLongTap(),this._cancelSingleTap();var i={x:e.touches[1].pageX-this.x1,y:e.touches[1].pageY-this.y1};t.x=i.x,t.y=i.y,this.pinchStartLen=F(t),this.multipointStart.dispatch(e,this.element)}this._preventTap=!1,this.longTapTimeout=setTimeout(function(){this.longTap.dispatch(e,this.element),this._preventTap=!0}.bind(this),750)}}},{key:"move",value:function(e){if(e.touches){var t=this.preV,i=e.touches.length,n=e.touches[0].pageX,s=e.touches[0].pageY;if(this.isDoubleTap=!1,i>1){var l=e.touches[1].pageX,o=e.touches[1].pageY,r={x:e.touches[1].pageX-n,y:e.touches[1].pageY-s};null!==t.x&&(this.pinchStartLen>0&&(e.zoom=F(r)/this.pinchStartLen,this.pinch.dispatch(e,this.element)),e.angle=R(r,t),this.rotate.dispatch(e,this.element)),t.x=r.x,t.y=r.y,null!==this.x2&&null!==this.sx2?(e.deltaX=(n-this.x2+l-this.sx2)/2,e.deltaY=(s-this.y2+o-this.sy2)/2):(e.deltaX=0,e.deltaY=0),this.twoFingerPressMove.dispatch(e,this.element),this.sx2=l,this.sy2=o}else{if(null!==this.x2){e.deltaX=n-this.x2,e.deltaY=s-this.y2;var a=Math.abs(this.x1-this.x2),h=Math.abs(this.y1-this.y2);(a>10||h>10)&&(this._preventTap=!0)}else e.deltaX=0,e.deltaY=0;this.pressMove.dispatch(e,this.element)}this.touchMove.dispatch(e,this.element),this._cancelLongTap(),this.x2=n,this.y2=s,i>1&&e.preventDefault()}}},{key:"end",value:function(e){if(e.changedTouches){this._cancelLongTap();var t=this;e.touches.length<2&&(this.multipointEnd.dispatch(e,this.element),this.sx2=this.sy2=null),this.x2&&Math.abs(this.x1-this.x2)>30||this.y2&&Math.abs(this.y1-this.y2)>30?(e.direction=this._swipeDirection(this.x1,this.x2,this.y1,this.y2),this.swipeTimeout=setTimeout((function(){t.swipe.dispatch(e,t.element)}),0)):(this.tapTimeout=setTimeout((function(){t._preventTap||t.tap.dispatch(e,t.element),t.isDoubleTap&&(t.doubleTap.dispatch(e,t.element),t.isDoubleTap=!1)}),0),t.isDoubleTap||(t.singleTapTimeout=setTimeout((function(){t.singleTap.dispatch(e,t.element)}),250))),this.touchEnd.dispatch(e,this.element),this.preV.x=0,this.preV.y=0,this.zoom=1,this.pinchStartLen=null,this.x1=this.x2=this.y1=this.y2=null}}},{key:"cancelAll",value:function(){this._preventTap=!0,clearTimeout(this.singleTapTimeout),clearTimeout(this.tapTimeout),clearTimeout(this.longTapTimeout),clearTimeout(this.swipeTimeout)}},{key:"cancel",value:function(e){this.cancelAll(),this.touchCancel.dispatch(e,this.element)}},{key:"_cancelLongTap",value:function(){clearTimeout(this.longTapTimeout)}},{key:"_cancelSingleTap",value:function(){clearTimeout(this.singleTapTimeout)}},{key:"_swipeDirection",value:function(e,t,i,n){return Math.abs(e-t)>=Math.abs(i-n)?e-t>0?"Left":"Right":i-n>0?"Up":"Down"}},{key:"on",value:function(e,t){this[e]&&this[e].add(t)}},{key:"off",value:function(e,t){this[e]&&this[e].del(t)}},{key:"destroy",value:function(){return this.singleTapTimeout&&clearTimeout(this.singleTapTimeout),this.tapTimeout&&clearTimeout(this.tapTimeout),this.longTapTimeout&&clearTimeout(this.longTapTimeout),this.swipeTimeout&&clearTimeout(this.swipeTimeout),this.element.removeEventListener("touchstart",this.start),this.element.removeEventListener("touchmove",this.move),this.element.removeEventListener("touchend",this.end),this.element.removeEventListener("touchcancel",this.cancel),this.rotate.del(),this.touchStart.del(),this.multipointStart.del(),this.multipointEnd.del(),this.pinch.del(),this.swipe.del(),this.tap.del(),this.doubleTap.del(),this.longTap.del(),this.singleTap.del(),this.pressMove.del(),this.twoFingerPressMove.del(),this.touchMove.del(),this.touchEnd.del(),this.touchCancel.del(),this.preV=this.pinchStartLen=this.zoom=this.isDoubleTap=this.delta=this.last=this.now=this.tapTimeout=this.singleTapTimeout=this.longTapTimeout=this.swipeTimeout=this.x1=this.x2=this.y1=this.y2=this.preTapPosition=this.rotate=this.touchStart=this.multipointStart=this.multipointEnd=this.pinch=this.swipe=this.tap=this.doubleTap=this.longTap=this.singleTap=this.pressMove=this.touchMove=this.touchEnd=this.touchCancel=this.twoFingerPressMove=null,window.removeEventListener("scroll",this._cancelAllHandler),null}}]);function $(e){var t=function(){var e,t=document.createElement("fakeelement"),i={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in i)if(void 0!==t.style[e])return i[e]}(),i=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,n=u(e,"gslide-media")?e:e.querySelector(".gslide-media"),s=g(n,".ginner-container"),l=e.querySelector(".gslide-description");i>769&&(n=s),d(n,"greset"),f(n,"translate3d(0, 0, 0)"),h(t,{onElement:n,once:!0,withCallback:function(e,t){c(n,"greset")}}),n.style.opacity="",l&&(l.style.opacity="")}function J(e){if(e.events.hasOwnProperty("touch"))return!1;var t,i,n,s=x(),l=s.width,o=s.height,r=!1,a=null,h=null,v=null,p=!1,m=1,y=1,b=!1,S=!1,w=null,T=null,C=null,k=null,E=0,A=0,L=!1,I=!1,O={},P={},M=0,z=0,X=document.getElementById("glightbox-slider"),Y=document.querySelector(".goverlay"),q=new U(X,{touchStart:function(t){if(r=!0,(u(t.targetTouches[0].target,"ginner-container")||g(t.targetTouches[0].target,".gslide-desc")||"a"==t.targetTouches[0].target.nodeName.toLowerCase())&&(r=!1),g(t.targetTouches[0].target,".gslide-inline")&&!u(t.targetTouches[0].target.parentNode,"gslide-inline")&&(r=!1),r){if(P=t.targetTouches[0],O.pageX=t.targetTouches[0].pageX,O.pageY=t.targetTouches[0].pageY,M=t.targetTouches[0].clientX,z=t.targetTouches[0].clientY,a=e.activeSlide,h=a.querySelector(".gslide-media"),n=a.querySelector(".gslide-inline"),v=null,u(h,"gslide-image")&&(v=h.querySelector("img")),(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)>769&&(h=a.querySelector(".ginner-container")),c(Y,"greset"),t.pageX>20&&t.pageXo){var a=O.pageX-P.pageX;if(Math.abs(a)<=13)return!1}p=!0;var d,c=s.targetTouches[0].clientX,u=s.targetTouches[0].clientY,g=M-c,m=z-u;if(Math.abs(g)>Math.abs(m)?(L=!1,I=!0):(I=!1,L=!0),t=P.pageX-O.pageX,E=100*t/l,i=P.pageY-O.pageY,A=100*i/o,L&&v&&(d=1-Math.abs(i)/o,Y.style.opacity=d,e.settings.touchFollowAxis&&(E=0)),I&&(d=1-Math.abs(t)/l,h.style.opacity=d,e.settings.touchFollowAxis&&(A=0)),!v)return f(h,"translate3d(".concat(E,"%, 0, 0)"));f(h,"translate3d(".concat(E,"%, ").concat(A,"%, 0)"))}},touchEnd:function(){if(r){if(p=!1,S||b)return C=w,void(k=T);var t=Math.abs(parseInt(A)),i=Math.abs(parseInt(E));if(!(t>29&&v))return t<29&&i<25?(d(Y,"greset"),Y.style.opacity=1,$(h)):void 0;e.close()}},multipointEnd:function(){setTimeout((function(){b=!1}),50)},multipointStart:function(){b=!0,m=y||1},pinch:function(e){if(!v||p)return!1;b=!0,v.scaleX=v.scaleY=m*e.zoom;var t=m*e.zoom;if(S=!0,t<=1)return S=!1,t=1,k=null,C=null,w=null,T=null,void v.setAttribute("style","");t>4.5&&(t=4.5),v.style.transform="scale3d(".concat(t,", ").concat(t,", 1)"),y=t},pressMove:function(e){if(S&&!b){var t=P.pageX-O.pageX,i=P.pageY-O.pageY;C&&(t+=C),k&&(i+=k),w=t,T=i;var n="translate3d(".concat(t,"px, ").concat(i,"px, 0)");y&&(n+=" scale3d(".concat(y,", ").concat(y,", 1)")),f(v,n)}},swipe:function(t){if(!S)if(b)b=!1;else{if("Left"==t.direction){if(e.index==e.elements.length-1)return $(h);e.nextSlide()}if("Right"==t.direction){if(0==e.index)return $(h);e.prevSlide()}}}});e.events.touch=q}var K=T(),Q=null!==T()||void 0!==document.createTouch||"ontouchstart"in window||"onmsgesturechange"in window||navigator.msMaxTouchPoints,ee=document.getElementsByTagName("html")[0],te={selector:".glightbox",elements:null,skin:"clean",theme:"clean",closeButton:!0,startAt:null,autoplayVideos:!0,autofocusVideos:!0,descPosition:"bottom",width:"900px",height:"506px",videosWidth:"960px",beforeSlideChange:null,afterSlideChange:null,beforeSlideLoad:null,afterSlideLoad:null,slideInserted:null,slideRemoved:null,slideExtraAttributes:null,onOpen:null,onClose:null,loop:!1,zoomable:!0,draggable:!0,dragAutoSnap:!1,dragToleranceX:40,dragToleranceY:65,preload:!0,oneSlidePerOpen:!1,touchNavigation:!0,touchFollowAxis:!0,keyboardNavigation:!0,closeOnOutsideClick:!0,plugins:!1,plyr:{css:"https://cdn.plyr.io/3.6.12/plyr.css",js:"https://cdn.plyr.io/3.6.12/plyr.js",config:{ratio:"16:9",fullscreen:{enabled:!0,iosNative:!0},youtube:{noCookie:!0,rel:0,showinfo:0,iv_load_policy:3},vimeo:{byline:!1,portrait:!1,title:!1,transparent:!1}}},openEffect:"zoom",closeEffect:"zoom",slideEffect:"slide",moreText:"See more",moreLength:60,cssEfects:{fade:{in:"fadeIn",out:"fadeOut"},zoom:{in:"zoomIn",out:"zoomOut"},slide:{in:"slideInRight",out:"slideOutLeft"},slideBack:{in:"slideInLeft",out:"slideOutRight"},none:{in:"none",out:"none"}},svg:{close:'',next:' ',prev:''},slideHTML:'
\n
\n
\n
\n
\n
\n
\n

\n
\n
\n
\n
\n
\n
',lightboxHTML:''},ie=i((function t(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.customOptions=i,this.settings=o(te,i),this.effectsClasses=this.getAnimationClasses(),this.videoPlayers={},this.apiEvents=[],this.fullElementsList=!1}),[{key:"init",value:function(){var e=this,t=this.getSelector();t&&(this.baseEvents=h("click",{onElement:t,withCallback:function(t,i){t.preventDefault(),e.open(i)}})),this.elements=this.getElements()}},{key:"open",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(0===this.elements.length)return!1;this.activeSlide=null,this.prevActiveSlideIndex=null,this.prevActiveSlide=null;var i=z(t)?t:this.settings.startAt;if(E(e)){var n=e.getAttribute("data-gallery");n&&(this.fullElementsList=this.elements,this.elements=this.getGalleryElements(this.elements,n)),O(i)&&(i=this.getElementIndex(e))<0&&(i=0)}z(i)||(i=0),this.build(),v(this.overlay,"none"===this.settings.openEffect?"none":this.settings.cssEfects.fade.in);var s=document.body,l=window.innerWidth-document.documentElement.clientWidth;if(l>0){var o=document.createElement("style");o.type="text/css",o.className="gcss-styles",o.innerText=".gscrollbar-fixer {margin-right: ".concat(l,"px}"),document.head.appendChild(o),d(s,"gscrollbar-fixer")}d(s,"glightbox-open"),d(ee,"glightbox-open"),K&&(d(document.body,"glightbox-mobile"),this.settings.slideEffect="slide"),this.showSlide(i,!0),1===this.elements.length?(d(this.prevButton,"glightbox-button-hidden"),d(this.nextButton,"glightbox-button-hidden")):(c(this.prevButton,"glightbox-button-hidden"),c(this.nextButton,"glightbox-button-hidden")),this.lightboxOpen=!0,this.trigger("open"),C(this.settings.onOpen)&&this.settings.onOpen(),Q&&this.settings.touchNavigation&&J(this),this.settings.keyboardNavigation&&Y(this)}},{key:"openAt",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.open(null,e)}},{key:"showSlide",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];p(this.loader),this.index=parseInt(t);var n=this.slidesContainer.querySelector(".current");n&&c(n,"current"),this.slideAnimateOut();var s=this.slidesContainer.querySelectorAll(".gslide")[t];if(u(s,"loaded"))this.slideAnimateIn(s,i),m(this.loader);else{p(this.loader);var l=this.elements[t],o={index:this.index,slide:s,slideNode:s,slideConfig:l.slideConfig,slideIndex:this.index,trigger:l.node,player:null};this.trigger("slide_before_load",o),l.instance.setContent(s,(function(){m(e.loader),e.resize(),e.slideAnimateIn(s,i),e.trigger("slide_after_load",o)}))}this.slideDescription=s.querySelector(".gslide-description"),this.slideDescriptionContained=this.slideDescription&&u(this.slideDescription.parentNode,"gslide-media"),this.settings.preload&&(this.preloadSlide(t+1),this.preloadSlide(t-1)),this.updateNavigationClasses(),this.activeSlide=s}},{key:"preloadSlide",value:function(e){var t=this;if(e<0||e>this.elements.length-1)return!1;if(O(this.elements[e]))return!1;var i=this.slidesContainer.querySelectorAll(".gslide")[e];if(u(i,"loaded"))return!1;var n=this.elements[e],s=n.type,l={index:e,slide:i,slideNode:i,slideConfig:n.slideConfig,slideIndex:e,trigger:n.node,player:null};this.trigger("slide_before_load",l),"video"===s||"external"===s?setTimeout((function(){n.instance.setContent(i,(function(){t.trigger("slide_after_load",l)}))}),200):n.instance.setContent(i,(function(){t.trigger("slide_after_load",l)}))}},{key:"prevSlide",value:function(){this.goToSlide(this.index-1)}},{key:"nextSlide",value:function(){this.goToSlide(this.index+1)}},{key:"goToSlide",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(this.prevActiveSlide=this.activeSlide,this.prevActiveSlideIndex=this.index,!this.loop()&&(e<0||e>this.elements.length-1))return!1;e<0?e=this.elements.length-1:e>=this.elements.length&&(e=0),this.showSlide(e)}},{key:"insertSlide",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;t<0&&(t=this.elements.length);var i=new V(e,this,t),n=i.getConfig(),s=o({},n),l=i.create(),r=this.elements.length-1;s.index=t,s.node=!1,s.instance=i,s.slideConfig=n,this.elements.splice(t,0,s);var a=null,h=null;if(this.slidesContainer){if(t>r)this.slidesContainer.appendChild(l);else{var d=this.slidesContainer.querySelectorAll(".gslide")[t];this.slidesContainer.insertBefore(l,d)}(this.settings.preload&&0==this.index&&0==t||this.index-1==t||this.index+1==t)&&this.preloadSlide(t),0===this.index&&0===t&&(this.index=1),this.updateNavigationClasses(),a=this.slidesContainer.querySelectorAll(".gslide")[t],h=this.getSlidePlayerInstance(t),s.slideNode=a}this.trigger("slide_inserted",{index:t,slide:a,slideNode:a,slideConfig:n,slideIndex:t,trigger:null,player:h}),C(this.settings.slideInserted)&&this.settings.slideInserted({index:t,slide:a,player:h})}},{key:"removeSlide",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:-1;if(e<0||e>this.elements.length-1)return!1;var t=this.slidesContainer&&this.slidesContainer.querySelectorAll(".gslide")[e];t&&(this.getActiveSlideIndex()==e&&(e==this.elements.length-1?this.prevSlide():this.nextSlide()),t.parentNode.removeChild(t)),this.elements.splice(e,1),this.trigger("slide_removed",e),C(this.settings.slideRemoved)&&this.settings.slideRemoved(e)}},{key:"slideAnimateIn",value:function(e,t){var i=this,n=e.querySelector(".gslide-media"),s=e.querySelector(".gslide-description"),l={index:this.prevActiveSlideIndex,slide:this.prevActiveSlide,slideNode:this.prevActiveSlide,slideIndex:this.prevActiveSlide,slideConfig:O(this.prevActiveSlideIndex)?null:this.elements[this.prevActiveSlideIndex].slideConfig,trigger:O(this.prevActiveSlideIndex)?null:this.elements[this.prevActiveSlideIndex].node,player:this.getSlidePlayerInstance(this.prevActiveSlideIndex)},o={index:this.index,slide:this.activeSlide,slideNode:this.activeSlide,slideConfig:this.elements[this.index].slideConfig,slideIndex:this.index,trigger:this.elements[this.index].node,player:this.getSlidePlayerInstance(this.index)};if(n.offsetWidth>0&&s&&(m(s),s.style.display=""),c(e,this.effectsClasses),t)v(e,this.settings.cssEfects[this.settings.openEffect].in,(function(){i.settings.autoplayVideos&&i.slidePlayerPlay(e),i.trigger("slide_changed",{prev:l,current:o}),C(i.settings.afterSlideChange)&&i.settings.afterSlideChange.apply(i,[l,o])}));else{var r=this.settings.slideEffect,a="none"!==r?this.settings.cssEfects[r].in:r;this.prevActiveSlideIndex>this.index&&"slide"==this.settings.slideEffect&&(a=this.settings.cssEfects.slideBack.in),v(e,a,(function(){i.settings.autoplayVideos&&i.slidePlayerPlay(e),i.trigger("slide_changed",{prev:l,current:o}),C(i.settings.afterSlideChange)&&i.settings.afterSlideChange.apply(i,[l,o])}))}setTimeout((function(){i.resize(e)}),100),d(e,"current")}},{key:"slideAnimateOut",value:function(){if(!this.prevActiveSlide)return!1;var e=this.prevActiveSlide;c(e,this.effectsClasses),d(e,"prev");var t=this.settings.slideEffect,i="none"!==t?this.settings.cssEfects[t].out:t;this.slidePlayerPause(e),this.trigger("slide_before_change",{prev:{index:this.prevActiveSlideIndex,slide:this.prevActiveSlide,slideNode:this.prevActiveSlide,slideIndex:this.prevActiveSlideIndex,slideConfig:O(this.prevActiveSlideIndex)?null:this.elements[this.prevActiveSlideIndex].slideConfig,trigger:O(this.prevActiveSlideIndex)?null:this.elements[this.prevActiveSlideIndex].node,player:this.getSlidePlayerInstance(this.prevActiveSlideIndex)},current:{index:this.index,slide:this.activeSlide,slideNode:this.activeSlide,slideIndex:this.index,slideConfig:this.elements[this.index].slideConfig,trigger:this.elements[this.index].node,player:this.getSlidePlayerInstance(this.index)}}),C(this.settings.beforeSlideChange)&&this.settings.beforeSlideChange.apply(this,[{index:this.prevActiveSlideIndex,slide:this.prevActiveSlide,player:this.getSlidePlayerInstance(this.prevActiveSlideIndex)},{index:this.index,slide:this.activeSlide,player:this.getSlidePlayerInstance(this.index)}]),this.prevActiveSlideIndex>this.index&&"slide"==this.settings.slideEffect&&(i=this.settings.cssEfects.slideBack.out),v(e,i,(function(){var t=e.querySelector(".ginner-container"),i=e.querySelector(".gslide-media"),n=e.querySelector(".gslide-description");t.style.transform="",i.style.transform="",c(i,"greset"),i.style.opacity="",n&&(n.style.opacity=""),c(e,"prev")}))}},{key:"getAllPlayers",value:function(){return this.videoPlayers}},{key:"getSlidePlayerInstance",value:function(e){var t="gvideo"+e,i=this.getAllPlayers();return!(!P(i,t)||!i[t])&&i[t]}},{key:"stopSlideVideo",value:function(e){if(E(e)){var t=e.querySelector(".gvideo-wrapper");t&&(e=t.getAttribute("data-index"))}console.log("stopSlideVideo is deprecated, use slidePlayerPause");var i=this.getSlidePlayerInstance(e);i&&i.playing&&i.pause()}},{key:"slidePlayerPause",value:function(e){if(E(e)){var t=e.querySelector(".gvideo-wrapper");t&&(e=t.getAttribute("data-index"))}var i=this.getSlidePlayerInstance(e);i&&i.playing&&i.pause()}},{key:"playSlideVideo",value:function(e){if(E(e)){var t=e.querySelector(".gvideo-wrapper");t&&(e=t.getAttribute("data-index"))}console.log("playSlideVideo is deprecated, use slidePlayerPlay");var i=this.getSlidePlayerInstance(e);i&&!i.playing&&i.play()}},{key:"slidePlayerPlay",value:function(e){var t;if(!K||null!==(t=this.settings.plyr.config)&&void 0!==t&&t.muted){if(E(e)){var i=e.querySelector(".gvideo-wrapper");i&&(e=i.getAttribute("data-index"))}var n=this.getSlidePlayerInstance(e);n&&!n.playing&&(n.play(),this.settings.autofocusVideos&&n.elements.container.focus())}}},{key:"setElements",value:function(e){var t=this;this.settings.elements=!1;var i=[];e&&e.length&&r(e,(function(e,n){var s=new V(e,t,n),l=s.getConfig(),r=o({},l);r.slideConfig=l,r.instance=s,r.index=n,i.push(r)})),this.elements=i,this.lightboxOpen&&(this.slidesContainer.innerHTML="",this.elements.length&&(r(this.elements,(function(){var e=y(t.settings.slideHTML);t.slidesContainer.appendChild(e)})),this.showSlide(0,!0)))}},{key:"getElementIndex",value:function(e){var t=!1;return r(this.elements,(function(i,n){if(P(i,"node")&&i.node==e)return t=n,!0})),t}},{key:"getElements",value:function(){var e=this,t=[];this.elements=this.elements?this.elements:[],!O(this.settings.elements)&&A(this.settings.elements)&&this.settings.elements.length&&r(this.settings.elements,(function(i,n){var s=new V(i,e,n),l=s.getConfig(),r=o({},l);r.node=!1,r.index=n,r.instance=s,r.slideConfig=l,t.push(r)}));var i=!1;return this.getSelector()&&(i=document.querySelectorAll(this.getSelector())),i?(r(i,(function(i,n){var s=new V(i,e,n),l=s.getConfig(),r=o({},l);r.node=i,r.index=n,r.instance=s,r.slideConfig=l,r.gallery=i.getAttribute("data-gallery"),t.push(r)})),t):t}},{key:"getGalleryElements",value:function(e,t){return e.filter((function(e){return e.gallery==t}))}},{key:"getSelector",value:function(){return!this.settings.elements&&(this.settings.selector&&"data-"==this.settings.selector.substring(0,5)?"*[".concat(this.settings.selector,"]"):this.settings.selector)}},{key:"getActiveSlide",value:function(){return this.slidesContainer.querySelectorAll(".gslide")[this.index]}},{key:"getActiveSlideIndex",value:function(){return this.index}},{key:"getAnimationClasses",value:function(){var e=[];for(var t in this.settings.cssEfects)if(this.settings.cssEfects.hasOwnProperty(t)){var i=this.settings.cssEfects[t];e.push("g".concat(i.in)),e.push("g".concat(i.out))}return e.join(" ")}},{key:"build",value:function(){var e=this;if(this.built)return!1;var t=document.body.childNodes,i=[];r(t,(function(e){e.parentNode==document.body&&"#"!==e.nodeName.charAt(0)&&e.hasAttribute&&!e.hasAttribute("aria-hidden")&&(i.push(e),e.setAttribute("aria-hidden","true"))}));var n=P(this.settings.svg,"next")?this.settings.svg.next:"",s=P(this.settings.svg,"prev")?this.settings.svg.prev:"",l=P(this.settings.svg,"close")?this.settings.svg.close:"",o=this.settings.lightboxHTML;o=y(o=(o=(o=o.replace(/{nextSVG}/g,n)).replace(/{prevSVG}/g,s)).replace(/{closeSVG}/g,l)),document.body.appendChild(o);var a=document.getElementById("glightbox-body");this.modal=a;var c=a.querySelector(".gclose");this.prevButton=a.querySelector(".gprev"),this.nextButton=a.querySelector(".gnext"),this.overlay=a.querySelector(".goverlay"),this.loader=a.querySelector(".gloader"),this.slidesContainer=document.getElementById("glightbox-slider"),this.bodyHiddenChildElms=i,this.events={},d(this.modal,"glightbox-"+this.settings.skin),this.settings.closeButton&&c&&(this.events.close=h("click",{onElement:c,withCallback:function(t,i){t.preventDefault(),e.close()}})),c&&!this.settings.closeButton&&c.parentNode.removeChild(c),this.nextButton&&(this.events.next=h("click",{onElement:this.nextButton,withCallback:function(t,i){t.preventDefault(),e.nextSlide()}})),this.prevButton&&(this.events.prev=h("click",{onElement:this.prevButton,withCallback:function(t,i){t.preventDefault(),e.prevSlide()}})),this.settings.closeOnOutsideClick&&(this.events.outClose=h("click",{onElement:a,withCallback:function(t,i){e.preventOutsideClick||u(document.body,"glightbox-mobile")||g(t.target,".ginner-container")||g(t.target,".gbtn")||u(t.target,"gnext")||u(t.target,"gprev")||e.close()}})),r(this.elements,(function(t,i){e.slidesContainer.appendChild(t.instance.create()),t.slideNode=e.slidesContainer.querySelectorAll(".gslide")[i]})),Q&&d(document.body,"glightbox-touch"),this.events.resize=h("resize",{onElement:window,withCallback:function(){e.resize()}}),this.built=!0}},{key:"resize",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if((e=e||this.activeSlide)&&!u(e,"zoomed")){var t=x(),i=e.querySelector(".gvideo-wrapper"),n=e.querySelector(".gslide-image"),s=this.slideDescription,l=t.width,o=t.height;if(l<=768?d(document.body,"glightbox-mobile"):c(document.body,"glightbox-mobile"),i||n){var r=!1;if(s&&(u(s,"description-bottom")||u(s,"description-top"))&&!u(s,"gabsolute")&&(r=!0),n)if(l<=768)n.querySelector("img");else if(r){var a,h,g=s.offsetHeight,v=n.querySelector("img"),f=null===(a=this.elements[this.index])||void 0===a?void 0:a.node,p="100vh";f&&(p=null!==(h=f.getAttribute("data-height"))&&void 0!==h?h:p),v.setAttribute("style","max-height: calc(".concat(p," - ").concat(g,"px)")),s.setAttribute("style","max-width: ".concat(v.offsetWidth,"px;"))}if(i){var m=P(this.settings.plyr.config,"ratio")?this.settings.plyr.config.ratio:"";if(!m){var y=i.clientWidth,b=i.clientHeight,S=y/b;m="".concat(y/S,":").concat(b/S)}var w=m.split(":"),T=this.settings.videosWidth,C=this.settings.videosWidth,k=(C=z(T)||-1!==T.indexOf("px")?parseInt(T):-1!==T.indexOf("vw")?l*parseInt(T)/100:-1!==T.indexOf("vh")?o*parseInt(T)/100:-1!==T.indexOf("%")?l*parseInt(T)/100:parseInt(i.clientWidth))/(parseInt(w[0])/parseInt(w[1]));if(k=Math.floor(k),r&&(o-=s.offsetHeight),C>l||k>o||oC){var E=i.offsetWidth,A=i.offsetHeight,L=o/A,I={width:E*L,height:A*L};i.parentNode.setAttribute("style","max-width: ".concat(I.width,"px")),r&&s.setAttribute("style","max-width: ".concat(I.width,"px;"))}else i.parentNode.style.maxWidth="".concat(T),r&&s.setAttribute("style","max-width: ".concat(T,";"))}}}}},{key:"reload",value:function(){this.init()}},{key:"updateNavigationClasses",value:function(){var e=this.loop();c(this.nextButton,"disabled"),c(this.prevButton,"disabled"),0==this.index&&this.elements.length-1==0?(d(this.prevButton,"disabled"),d(this.nextButton,"disabled")):0!==this.index||e?this.index!==this.elements.length-1||e||d(this.nextButton,"disabled"):d(this.prevButton,"disabled")}},{key:"loop",value:function(){var e=P(this.settings,"loopAtEnd")?this.settings.loopAtEnd:null;return e=P(this.settings,"loop")?this.settings.loop:e,e}},{key:"close",value:function(){var e=this;if(!this.lightboxOpen){if(this.events){for(var t in this.events)this.events.hasOwnProperty(t)&&this.events[t].destroy();this.events=null}return!1}if(this.closing)return!1;this.closing=!0,this.slidePlayerPause(this.activeSlide),this.fullElementsList&&(this.elements=this.fullElementsList),this.bodyHiddenChildElms.length&&r(this.bodyHiddenChildElms,(function(e){e.removeAttribute("aria-hidden")})),d(this.modal,"glightbox-closing"),v(this.overlay,"none"==this.settings.openEffect?"none":this.settings.cssEfects.fade.out),v(this.activeSlide,this.settings.cssEfects[this.settings.closeEffect].out,(function(){if(e.activeSlide=null,e.prevActiveSlideIndex=null,e.prevActiveSlide=null,e.built=!1,e.events){for(var t in e.events)e.events.hasOwnProperty(t)&&e.events[t].destroy();e.events=null}var i=document.body;c(ee,"glightbox-open"),c(i,"glightbox-open touching gdesc-open glightbox-touch glightbox-mobile gscrollbar-fixer"),e.modal.parentNode.removeChild(e.modal),e.trigger("close"),C(e.settings.onClose)&&e.settings.onClose();var n=document.querySelector(".gcss-styles");n&&n.parentNode.removeChild(n),e.lightboxOpen=!1,e.closing=null}))}},{key:"destroy",value:function(){this.close(),this.clearAllEvents(),this.baseEvents&&this.baseEvents.destroy()}},{key:"on",value:function(e,t){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!e||!C(t))throw new TypeError("Event name and callback must be defined");this.apiEvents.push({evt:e,once:i,callback:t})}},{key:"once",value:function(e,t){this.on(e,t,!0)}},{key:"trigger",value:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=[];r(this.apiEvents,(function(t,s){var l=t.evt,o=t.once,r=t.callback;l==e&&(r(i),o&&n.push(s))})),n.length&&r(n,(function(e){return t.apiEvents.splice(e,1)}))}},{key:"clearAllEvents",value:function(){this.apiEvents.splice(0,this.apiEvents.length)}},{key:"version",value:function(){return"3.3.1"}}]);return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=new ie(e);return t.init(),t}})); --------------------------------------------------------------------------------