diff --git a/.drone.yml b/.drone.yml index 65f87b442..fbd0049ff 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,7 +5,7 @@ clone: pipeline: signed-off-check: - image: nextcloudci/php7.0:php7.0-2 + image: nextcloudci/php7.1:php7.1-16 environment: - APP_NAME=gallery - CORE_BRANCH=master diff --git a/.travis.yml b/.travis.yml index cec169f31..de27b2c2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: php php: - - 7.0 - 7.1 - 7.2 - 7.3 diff --git a/appinfo/info.xml b/appinfo/info.xml index 21b3d3a98..d01d375a2 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -55,4 +55,3 @@ https://github.com/nextcloud/gallery/wiki - diff --git a/js/merged.json b/js/merged.json index 68bc5c3db..0eba06436 100644 --- a/js/merged.json +++ b/js/merged.json @@ -1,6 +1,7 @@ [ "upload-helper.js", "vendor/bigshot/bigshot-compressed.js", + "vendor/livephotoskit/livephotoskit.js", "vendor/jquery-touch-events/src/1.0.8/jquery.mobile-events.min.js", "vendor/jquery.ui.touch-punch-custom.js", "vendor/modified-eventsource-polyfill/eventsource-polyfill.js", @@ -22,6 +23,7 @@ "slideshow.js", "slideshowcontrols.js", "slideshowzoomablepreview.js", + "slideshowlivephotos.js", "vendor/nextcloud/newfilemenu.js", "newfilemenuplugins.js", "app.js" diff --git a/js/slideshow.js b/js/slideshow.js index 576ce70be..20941a132 100644 --- a/js/slideshow.js +++ b/js/slideshow.js @@ -20,6 +20,20 @@ var SlideShow = function () { }; + var LivePreview = function() { + }; + + LivePreview.prototype = { + reset: function() {}, + startLivePreview: function() { + var defer = $.Deferred(); + defer.reject(); + return defer.promise(); + } + }; + + SlideShow.LivePreview = LivePreview; + SlideShow.prototype = { slideshowTemplate: null, container: null, @@ -55,6 +69,7 @@ this.container = $('#slideshow'); this.zoomablePreviewContainer = this.container.find('.bigshotContainer'); this.zoomablePreview = new SlideShow.ZoomablePreview(this.container); + this.livePhotoPreview = new SlideShow.LivePreview(this.container); this.controls = new SlideShow.Controls( this, @@ -137,6 +152,8 @@ show: function (index) { this.hideErrorNotification(); this.active = true; + // Clean any live photo container + this.livePhotoPreview.reset(); this.container.show(); this.hideContent(); this.container.css('background-position', 'center'); @@ -148,21 +165,24 @@ // check if we moved along while we were loading if (currentImageId === index) { + this.zoomablePreviewContainer.css('display', 'none'); var image = this.images[index]; var transparent = this._isTransparent(image.mimeType); this.controls.showActionButtons(transparent, Gallery.token, image.permissions); this.errorLoadingImage = false; this.currentImage = img; - img.setAttribute('alt', image.name); - $(img).css('position', 'absolute'); - $(img).css('background-color', image.backgroundColour); - if (transparent && this.backgroundToggle === true) { - var $border = 30 / window.devicePixelRatio; - $(img).css('outline', $border + 'px solid ' + image.backgroundColour); - } - - this.zoomablePreview.startBigshot(img, this.currentImage, image.mimeType); + $.when(this.livePhotoPreview.startLivePreview(image, this.currentImage)).fail(function() { + this.zoomablePreviewContainer.css('display', 'block'); + img.setAttribute('alt', image.name); + $(img).css('position', 'absolute'); + $(img).css('background-color', image.backgroundColour); + if (transparent && this.backgroundToggle === true) { + var $border = 30 / window.devicePixelRatio; + $(img).css('outline', $border + 'px solid ' + image.backgroundColour); + } + this.zoomablePreview.startBigshot(img, this.currentImage, image.mimeType); + }.bind(this)); this._setUrl(image.path); this.controls.show(currentImageId); this.container.find('.icon-loading-dark').hide(); diff --git a/js/slideshowlivephotos.js b/js/slideshowlivephotos.js new file mode 100644 index 000000000..efaf125dc --- /dev/null +++ b/js/slideshowlivephotos.js @@ -0,0 +1,208 @@ +/** + * Nextcloud - Gallery + * + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author François Sylvestre + * + * @copyright François Sylvestre 2017 + */ +/* global SlideShow, LivePhotosKit*/ +(function ($, SlideShow, LivePhotosKit, OC) { + "use strict"; + /** + * Creates a zoomable preview + * + * @param {*} container + * @constructor + */ + var LivePreview = function (container) { + this.container = container; + this.element = this.container.get(0); + this.livePhotoContainer = container.find('.livePhotoContainer'); + this.livePhotoContainer.css({display: 'block', width: '1px', height: '1px'}); + this.player = LivePhotosKit.createPlayer(); + + this.livePhotoContainer.append(this.player); + // this.livePhotoContainer.css('display', 'none'); + + this._detectFullscreen(); + this._setupControls(); + + // Reset image position and size on orientation change + var self = this; + $(window).bind('orientationchange resize', function () { + self._resetView(); + }); + }; + + LivePreview.prototype = { + container: null, + element: null, + fullScreen: null, + currentImage: null, + mimeType: null, + smallImageDimension: 200 / window.devicePixelRatio, + smallImageScale: 2, + + /** + * Launches the Bigshot zoomable preview + * + * @param {*} image + * @param {number} currentImage + * @param {string} mimeType + */ + startLivePreview: function (image, currentImage) { + var defer = $.Deferred(); + if (image.mimeType === "image/jpeg" && image.name.toLowerCase().indexOf('.jpg') === image.name.length - 4) { + var videoExt = '.mov'; + if (image.name.substr(-4) === '.JPG') { + videoExt = '.MOV'; + } + var videoUrl = OC.generateUrl(['../remote.php/webdav/', + encodeURI(image.path.substr(0, image.path.length - 4) + videoExt) + ].join('') + ); + $.ajax({ + url: videoUrl, + type: 'HEAD', + success: function() { + this.livePhotoContainer.css({display: 'block'}); + this.currentImage = currentImage; + this.mimeType = image.mimeType; + + this._resetView(); + + this.player.photoSrc = this.currentImage.src; + this.player.videoSrc = videoUrl; + defer.resolve(); + }.bind(this), + error: function() { + this.livePhotoContainer.css('display', 'none'); + defer.reject(); + }.bind(this) + }); + } else { + defer.reject(); + } + return defer.promise(); + }, + + /** + * Resets the element for the next image to be displayed + */ + reset: function () { + this.livePhotoContainer.css('display', 'none'); + this.player.photoSrc = null; + this.player.videoSrc = null; + }, + + /** + * Throws away the zoomable preview + */ + stop: function () { + if (this.fullScreen !== null) { + this._fullScreenExit(); + } + }, + + /** + * Launches fullscreen mode if the browser supports it + */ + fullScreenToggle: function () { + if (this.zoomable === null) { + return; + } + if (this.fullScreen !== null) { + this._fullScreenExit(); + } else { + this._fullScreenStart(); + } + }, + + /** + * Detect fullscreen capability + * @private + */ + _detectFullscreen: function () { + this.canFullScreen = this.element.requestFullscreen !== undefined || + this.element.mozRequestFullScreen !== undefined || + this.element.webkitRequestFullscreen !== undefined || + this.element.msRequestFullscreen !== undefined; + }, + + /** + * Makes UI controls work on touchscreens. Pinch only works on iOS + * @private + */ + _setupControls: function () { + this.player.playbackStyle = LivePhotosKit.PlaybackStyle.FULL; + }, + + /** + * Resets the image to its original zoomed size + * + * @private + */ + _resetView: function () { + var imgWidth = this.currentImage.naturalWidth / window.devicePixelRatio; + var imgHeight = this.currentImage.naturalHeight / window.devicePixelRatio; + + var origSizeW = imgWidth; + var origSizeH = imgHeight; + var ratioVt=(origSizeW/origSizeH); + var ratioHz=(origSizeH/origSizeW); + var winW = $(window).width(); + var winH = $(window).height(); + var screenSizeW=Math.round(winW); + var screenSizeH=Math.round(winH); + var wantedWidth, wantedHeight, wantedLeft, wantedTop; + + if (origSizeW>=origSizeH) { + var newHeight = Math.round(screenSizeW*ratioHz); + if (newHeight <= screenSizeH){ + wantedHeight = newHeight; + wantedWidth = screenSizeW; + } else{ + wantedHeight = screenSizeH; + wantedWidth = Math.round(screenSizeH*ratioVt); + } + } else{ + wantedHeight = screenSizeH; + wantedWidth = Math.round(screenSizeH*ratioVt); + } + wantedLeft = Math.round((screenSizeW - wantedWidth) / 2); + wantedTop = Math.round((screenSizeH - wantedHeight) / 2); + + $(this.livePhotoContainer.children().get(0)) + .css({ + 'width': wantedWidth + 'px', + 'height': wantedHeight + 'px', + 'top': wantedTop + 'px', + 'left': wantedLeft + 'px' + }); + }, + + /** + * Starts the fullscreen previews + * + * @private + */ + _fullScreenStart: function () { + this._resetView(); + }, + + /** + * Stops the fullscreen previews + * + * @private + */ + _fullScreenExit: function () { + this._resetView(); + } + }; + + SlideShow.LivePreview = LivePreview; +})(jQuery, SlideShow, LivePhotosKit, OC); diff --git a/js/vendor/livephotoskit/CHANGELOG.md b/js/vendor/livephotoskit/CHANGELOG.md new file mode 100644 index 000000000..18ceb92bb --- /dev/null +++ b/js/vendor/livephotoskit/CHANGELOG.md @@ -0,0 +1,58 @@ +# Change Log + +## v1.5.4 (2018-03-29) + +- Included better accessibility support for LivePhotosKit JS via a number of `aria-label` and `role` attributes. +- Added a `caption` API which gives developers the ability to add accessibile descriptions to their images. + +## v1.5.2 (2017-10-19) + +- Fixed a rare unhandled exception in Safari. +- Added a `LivePhotosKit.MASTERING_NUMBER` property which indicates precisely which build version is being used. + +## v1.5.1 (2017-09-12) + +- Bugfixes for badge re-drawing. + +## v1.5.0 (2017-09-12) + +- New `createPlayer` and `augmentElementAsPlayer` methods. +- Added support for new iOS 11 Live Photo Effects: Loop, Bounce, and Long Exposure. +- Added support for graceful HTML `img` tag fallback with NoScript clients. + +## v1.4.11 (2017-07-20) + +- Laid groundwork for localizing badge strings. +- No longer check for `photoTime` unless playing back a Live Photo `hint`. +- Improved a number of type checks. + +## v1.4.10 (2017-06-05) + +- Fixed intermittent playback issues in Mozilla Firefox and Internet Explorer 11. +- Updated Live Photo playback to match new playback style introduced in iOS 10.3.1. + +## v1.4.9 (2017-05-01) + +- Live Photo player is no longer selectable. This addresses the issue where a selection + bubble would appear on iOS Safari during a long press. +- Fixed an intermittent memory exhaustion crash. + +## v1.4.8 (2017-04-22) + +- When a `Player` has a zero width, height or both, a warning is emitted to the console. +- Corrected `Player.updateSize()` function declaration. +- Reduced size of `livephotoskit.js` distributable. +- Moved documentation links to be more prominent in `README.md`. + +## v1.4.6 (2017-04-20) + +- Changed home page URL. +- Added reference to home page in `README.md`. + +## v1.4.5 (2017-04-20) + +- Fixed mangled copyright symbol. + +## v1.4.4 (2017-04-20) + +- Initial release. diff --git a/js/vendor/livephotoskit/LICENSE.md b/js/vendor/livephotoskit/LICENSE.md new file mode 100644 index 000000000..35a1fc1f1 --- /dev/null +++ b/js/vendor/livephotoskit/LICENSE.md @@ -0,0 +1,56 @@ +Copyright (c) 2017 Apple Inc. All rights reserved. + +# LivePhotosKit JS License + +**IMPORTANT:** This Apple LivePhotosKit software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following terms, and +your use, reproduction, or installation of this Apple software constitutes +acceptance of these terms. If you do not agree with these terms, please do not +use, reproduce or install this Apple software. + +This Apple LivePhotosKit software is supplied to you by Apple Inc. ("Apple") in +consideration of your agreement to the following terms, and your use, +reproduction, or installation of this Apple software constitutes acceptance of +these terms. If you do not agree with these terms, please do not use, reproduce +or install this Apple software. + +This software is licensed to you only for use with LivePhotos that you are +authorized or legally permitted to embed or display on your website. + +The LivePhotosKit Software is only licensed and intended for the purposes set +forth above and may not be used for other purposes or in other contexts without +Apple's prior written permission. For the sake of clarity, you may not and +agree not to or enable others to, modify or create derivative works of the +LivePhotosKit Software. + +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products, services without specific prior written +permission from Apple. Except as expressly stated in this notice, no other +rights or licenses, express or implied, are granted by Apple herein. + +The LivePhotosKit Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE, REGARDING THE LIVEPHOTOSKIT SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS, SYSTEMS, OR SERVICES. +APPLE DOES NOT WARRANT THAT THE LIVEPHOTOSKIT SOFTWARE WILL MEET YOUR +REQUIREMENTS, THAT THE OPERATION OF THE LIVEPHOTOSKIT SOFTWARE WILL BE +UNINTERRUPTED OR ERROR-FREE, THAT DEFECTS IN THE LIVEPHOTOSKIT SOFTWARE WILL BE +CORRECTED, OR THAT THE LIVEPHOTOSKIT SOFTWARE WILL BE COMPATIBLE WITH FUTURE +APPLE PRODUCTS, SOFTWARE OR SERVICES. NO ORAL OR WRITTEN INFORMATION OR ADVICE +GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE WILL CREATE A WARRANTY. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) RELATING TO OR ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +OR INSTALLATION, OF THE LIVEPHOTOSKIT SOFTWARE BY YOU OR OTHERS, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT +LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY FOR +PERSONAL INJURY, OR OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION +MAY NOT APPLY TO YOU. In no event shall Apple's total liability to you for all +damages (other than as may be required by applicable law in cases involving +personal injury) exceed the amount of fifty dollars ($50.00). The foregoing +limitations will apply even if the above stated remedy fails of its essential +purpose. diff --git a/js/vendor/livephotoskit/README.md b/js/vendor/livephotoskit/README.md new file mode 100644 index 000000000..534150d98 --- /dev/null +++ b/js/vendor/livephotoskit/README.md @@ -0,0 +1,63 @@ +# LivePhotosKit JS + +Use the LivePhotosKit JS library to play Live Photos on your web pages. + +## Overview + +The JavaScript API presents the player in the form of a DOM element, much +like an `image` or `video` tag, which can be configured with photo and video +resources and other options, and have its playback controlled either +programmatically by the consuming developer, or via pre-provided controls +by the browsing end-user. + +## Documentation + +For more detailed documentation, see +https://developer.apple.com/reference/livephotoskitjs + +For information about Live Photos for developers, see https://developer.apple.com/live-photos + +## Installation + +### Using npm + +Install and save LivePhotosKit JS: +```bash +npm install --save livephotoskit +``` + +Import LivePhotosKit JS (ES6/TypeScript): + +```javascript +import * as LivePhotosKit from 'livephotoskit'; +``` + +A [TypeScript](https://www.typescriptlang.org) type definition file is included in the +distribution and will automatically be picked up by the TypeScript compiler. + +### Using the Apple CDN + +```html + +``` + +A [TypeScript](https://www.typescriptlang.org) type definition file is available at +```html +https://cdn.apple-livephotoskit.com/lpk/1/livephotoskit.d.ts +``` + +> Note +> +> The LivePhotosKit JS version number is in the URL. For example, 1 specifies LivePhotosKit JS 1.x.x. + +You will then be able to access LivePhotosKit JS via `window.LivePhotosKit`. + + +## Browser Compatibility + +The LivePhotosKit JS player supports the following browsers: + +- On macOS: Safari, Chrome, Firefox +- On iOS: Safari, Chrome +- On Windows: Chrome, Firefox, Edge, Internet Explorer 11 +- On Android: Chrome (Performance depends on device) diff --git a/js/vendor/livephotoskit/acknowledgements.txt b/js/vendor/livephotoskit/acknowledgements.txt new file mode 100644 index 000000000..e52a3bcbd --- /dev/null +++ b/js/vendor/livephotoskit/acknowledgements.txt @@ -0,0 +1,206 @@ +Acknowledgements +Portions of this Apple Software may utilize the following copyrighted material, the use of which is hereby acknowledged. + +============================================================================ +================================== BABEL =================================== +============================================================================ + +Copyright (c) 2014-2016 Sebastian McKenzie + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================ +=============================== BABEL-LOADER =============================== +============================================================================ + +Copyright (c) 2014-2016 Luís Couto + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================ +============================= BROADWAY (mp4.js) ============================ +============================================================================ + +Copyright (c) 2011, Project Authors (see AUTHORS section below) +All rights reserved. + +AUTHORS: The following authors have all licensed their contributions to the project +under the licensing terms detailed in this license. + + Michael Bebenita + Alon Zakai + Andreas Gal + Mathieu 'p01' Henri + Matthias 'soliton4' Behrens + Sam Leitch @oneam - provided the webgl canvas + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the names of the Project Authors nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-- + +The 3-clause BSD above applies to the contents of mp4.js, and no other source file within LivePhotosKit.js + +============================================================================ +================================ TS-LOADER ================================= +============================================================================ + +The MIT License (MIT) + +Copyright (c) 2015 TypeStrong + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +============================================================================ +================================ TYPESCRIPT ================================ +============================================================================ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +============================================================================ +================================= WEBPACK ================================== +============================================================================ + +(The MIT License) + +Copyright (c) 2012-2016 Tobias Koppers + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +============================================================================ +============================================================================ +============================================================================ + +Rev. 111416 (LivePhotosKit.js) diff --git a/js/vendor/livephotoskit/index.d.ts b/js/vendor/livephotoskit/index.d.ts new file mode 100644 index 000000000..d85adb07e --- /dev/null +++ b/js/vendor/livephotoskit/index.d.ts @@ -0,0 +1,723 @@ +/* +Copyright (c) 2017 Apple Inc. All rights reserved. + +# LivePhotosKit JS License + +**IMPORTANT:** This Apple LivePhotosKit software is supplied to you by Apple +Inc. ("Apple") in consideration of your agreement to the following terms, and +your use, reproduction, or installation of this Apple software constitutes +acceptance of these terms. If you do not agree with these terms, please do not +use, reproduce or install this Apple software. + +This Apple LivePhotosKit software is supplied to you by Apple Inc. ("Apple") in +consideration of your agreement to the following terms, and your use, +reproduction, or installation of this Apple software constitutes acceptance of +these terms. If you do not agree with these terms, please do not use, reproduce +or install this Apple software. + +This software is licensed to you only for use with LivePhotos that you are +authorized or legally permitted to embed or display on your website. + +The LivePhotosKit Software is only licensed and intended for the purposes set +forth above and may not be used for other purposes or in other contexts without +Apple's prior written permission. For the sake of clarity, you may not and +agree not to or enable others to, modify or create derivative works of the +LivePhotosKit Software. + +Neither the name, trademarks, service marks or logos of Apple Inc. may be used +to endorse or promote products, services without specific prior written +permission from Apple. Except as expressly stated in this notice, no other +rights or licenses, express or implied, are granted by Apple herein. + +The LivePhotosKit Software is provided by Apple on an "AS IS" basis. APPLE +MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE +IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE, REGARDING THE LIVEPHOTOSKIT SOFTWARE OR ITS USE AND +OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS, SYSTEMS, OR SERVICES. +APPLE DOES NOT WARRANT THAT THE LIVEPHOTOSKIT SOFTWARE WILL MEET YOUR +REQUIREMENTS, THAT THE OPERATION OF THE LIVEPHOTOSKIT SOFTWARE WILL BE +UNINTERRUPTED OR ERROR-FREE, THAT DEFECTS IN THE LIVEPHOTOSKIT SOFTWARE WILL BE +CORRECTED, OR THAT THE LIVEPHOTOSKIT SOFTWARE WILL BE COMPATIBLE WITH FUTURE +APPLE PRODUCTS, SOFTWARE OR SERVICES. NO ORAL OR WRITTEN INFORMATION OR ADVICE +GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE WILL CREATE A WARRANTY. + +IN NO EVENT SHALL APPLE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) RELATING TO OR ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +OR INSTALLATION, OF THE LIVEPHOTOSKIT SOFTWARE BY YOU OR OTHERS, HOWEVER CAUSED +AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT +LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY FOR +PERSONAL INJURY, OR OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION +MAY NOT APPLY TO YOU. In no event shall Apple's total liability to you for all +damages (other than as may be required by applicable law in cases involving +personal injury) exceed the amount of fifty dollars ($50.00). The foregoing +limitations will apply even if the above stated remedy fails of its essential +purpose. + + +**ACKNOWLEDGEMENTS:** +https://cdn.apple-livephotoskit.com/lpk/1/acknowledgements.txt + +v1.5.4 +*/ + + +/** + * The LivePhotosKit JS build number. + */ +export declare const BUILD_NUMBER: string; + +/** + * The version of LivePhotosKit JS. + */ +export declare const VERSION: string; + +/** + * An event that is fired when LivePhotosKit JS is loaded. Used when `livephotoskit.js` is loaded asynchronously. + * It will always have the value `livephotoskitloaded`. + * @example + * document.addEventListener('livephotoskitloaded', function(ev: Event): void { + * console.log('Loaded LivePhotosKit JS'); + * }); + */ +export declare const LIVEPHOTOSKIT_LOADED: string; + +export interface PlaybackStyle { + /** + * Default fallback value. + */ + 'default': PlaybackStyleLiteral; + /** + * Plays back the entire motion content of the Live Photo, including + * transition effects at the start and end. + * @const {String} LivePhotosKit.PlaybackStyle.FULL + */ + FULL: PlaybackStyleLiteral; + /** + * Plays back only a brief section of the motion content of the Live Photo. + * @const {String} LivePhotosKit.PlaybackStyle.HINT + */ + HINT: PlaybackStyleLiteral; + /** + * + * @const {String} LivePhotosKit.PlaybackStyle.LOOP + */ + LOOP: PlaybackStyleLiteral; +} +/** + * Playback options for Live Photos. + * + * @class LivePhotosKit.PlaybackStyle + * @enumlike + * @private + */ +export declare const PlaybackStyle: PlaybackStyle; +/** + * Playback option type for Live Photos. + */ +export declare type PlaybackStyleLiteral = 'full' | 'hint' | 'loop'; + +export interface EffectType { + /** + * Default fallback value. Maps to the "LIVE" EffectType. + * @const {Object} LivePhotosKit.EffectType.default + */ + readonly 'default': EffectTypeLiteral; + /** + * The "BOUNCE" effect type which plays a looping effect forward and + * backward smoothly. Will play/loop automatically. + * @const {String} LivePhotosKit.EffectType.BOUNCE + */ + readonly BOUNCE: EffectTypeLiteral; + /** + * The "EXPOSURE" effect type plays like a typical "LIVE" Live Photo. + * However, the keyframe is taken from a composite of frames to form a + * long-exposure-esque blurred image. + * @const {String} LivePhotosKit.EffectType.EXPOSURE + */ + readonly EXPOSURE: EffectTypeLiteral; + /** + * The traditional "LIVE" Live Photo effect. A still keyframe with a video + * that plays back when the badge is interacted with. + * @const {String} LivePhotosKit.EffectType.LIVE + */ + readonly LIVE: EffectTypeLiteral; + /** + * The "LOOP" effect type which plays a looping video. Will play/loop + * automatically. + * @const {String} LivePhotosKit.EffectType.LOOP + */ + readonly LOOP: EffectTypeLiteral; +} + +export interface EffectTypePrivate { + readonly _mappingToLocalizedStrings: { + readonly live: string; + readonly bounce: string; + readonly exposure: string; + readonly loop: string; + }; + readonly _mappingToPlaybackStyle: { + readonly bounce: PlaybackStyleLiteral; + readonly exposure: PlaybackStyleLiteral; + readonly live: PlaybackStyleLiteral; + readonly loop: PlaybackStyleLiteral; + }; + toBadgeText(effectType: EffectTypeLiteral): string; + toLocalizedString(effectType: EffectTypeLiteral): string; + toPlaybackStyle(effectType: EffectTypeLiteral): PlaybackStyleLiteral; +} + +/** + * Effect types for Live Photos. + * + * @class LivePhotosKit.EffectType + * @enumlike + * @private + */ +export declare const EffectType: EffectType & EffectTypePrivate; + +/** + * Valid values for the type of Live Photo effect that is being used. + */ +export declare type EffectTypeLiteral = 'bounce' | 'exposure' | 'live' | 'loop'; + +/** + * Error codes. + */ +export declare enum Errors { + /** + * Internal use only. + */ + FAILED_TO_DOWNLOAD_RESOURCE = 0, + /** + * Error code for when the photo component of the Live Photo is unable to be loaded. This could be due to + * network conditions or an inability to decode the image. + * @const {number} LivePhotosKit.Errors.PHOTO_FAILED_TO_LOAD + */ + PHOTO_FAILED_TO_LOAD = 1, + /** + * Error code for when the video component of the Live Photo is unable to be loaded. This could be due to + * network conditions or an inability to decode the video. + * @const {number} LivePhotosKit.Errors.VIDEO_FAILED_TO_LOAD + */ + VIDEO_FAILED_TO_LOAD = 2, +} + +export declare interface PlayerProps { + /** + * The current timestamp, as a floating-point number of seconds from the beginning + * of the animation, to display on the screen. + */ + currentTime: number; + /** + * When working with a looping Live Photo (of the "bounce" or "loop" + * variety), determines whether the asset should begin looping immediately + * upon entering a playable state. When applied to non-looping assets this + * property will have no effect. + */ + autoplay: boolean; + /** + * The type of Live Photo effect currently being used. This can be + * defined up-front from one of the following 4 values: + * - `{@link LivePhotosKit~EffectType.LIVE LivePhotosKit.EffectType.LIVE}` + * - `{@link LivePhotosKit~EffectType.EXPOSURE LivePhotosKit.EffectType.EXPOSURE}` + * - `{@link LivePhotosKit~EffectType.LOOP LivePhotosKit.EffectType.LOOP}` + * - `{@link LivePhotosKit~EffectType.BOUNCE LivePhotosKit.EffectType.BOUNCE}` + * + * `LIVE` refers to the traditional Live Photo and leverages the "full" + * playback recipe. + * + * `EXPOSURE` plays just like a traditional Live Photo and leverages the + * "full" playback recipe. However, the keyframe for the photo is a + * composite of the video frames used to create a blurred "long exposure" + * like effect. + * + * `LOOP` refers to a Live Photo which continuously loops and fades into + * itself creating a seamless effect. + * + * `BOUNCE` refers to a Live Photo which continuously loops and plays both + * forward and backward seamlessly. + */ + effectType: EffectTypeLiteral; + /** + * The style of playback to determine the nature of the animation. + */ + playbackStyle: PlaybackStyleLiteral; + /** + * Whether or not the Player will download the bytes at the provided `videoSrc` + * prior to the user or developer attempting to begin playback. + */ + proactivelyLoadsVideo: boolean; + /** + * The source of the photo component of the Live Photo. + */ + photoSrc: string | ArrayBuffer | null | undefined; + /** + * The MIME type of the photo asset, either as detected from the network request for it + * (if it was provided as a URL on `photoSrc`) or + * as provided by the developer prior to assigning a pre-prepared `ArrayBuffer` to `photoSrc`. + */ + photoMimeType: string; + /** + * The source of the video component of the Live Photo. + * + * Set this one of three types of value: + * - A string URL + * - An `ArrayBuffer` instance that may already be available + * - `null` (to clear the Player's video) + */ + videoSrc: string | ArrayBuffer | null | undefined; + /** + * The MIME type of the video asset, either as detected from the network request for it + * (if it was provided as a URL on `videoSrc`) or + * as provided by the developer prior to assigning a pre-prepared `ArrayBuffer` to + * `videoSrc`. + */ + videoMimeType: string | null; + /** + * In the event that you have one version of the video asset you'd like to use with the + * `videoSrc` for the Player, but that video asset + * (whether due to format or transcoding or any other reason) doesn't include readable + * `photoTime` and/or `frameTimes` + * values, you may set this property to a string URL or `ArrayBuffer` featuring the + * original QuickTime MOV file that was captured by iPhone. That file will be + * parsed (in the same manner as those loaded via `videoSrc`) in order to serve as an + * alternate source for the `photoTime` and `frameTimes` properties if they are not + * otherwise available. + */ + metadataVideoSrc: string | ArrayBuffer | null | undefined; + /** + * This is the actual renderable image-bearing DOM element (either an image or a + * canvas) that the Player will consume in order to render itself to the screen. + */ + photo: HTMLImageElement | HTMLCanvasElement | null | undefined; + /** + * This is the actual playable `HTMLVideoElement` that the Player will consume in + * order to obtain video frame data to render to the screen while animating the + * Live Photo. + */ + video: HTMLVideoElement | null | undefined; + /** + * This is the timestamp, in seconds from the beginning of the provided video asset, + * at which the still photo was captured. + */ + photoTime: number | null | undefined; + /** + * This is an array of timestamps, each in seconds from the beginning of the + * provided video asset, at which the individual video frames reside in the + * video. This allows the Player to crossfade between video frames during + * playback. + */ + frameTimes: number[] | string | null | undefined; + /** + * This property takes on a value of either 0, 90, 180, or 270, and is + * automatically determined as part of the video loading process. + */ + videoRotation: number; + /** + * Whether or not the Apple-provided playback controls are enabled for the user. + */ + showsNativeControls: boolean; +} + +export interface PlayerPropsPrivate { + preloadedEffectType: EffectTypeLiteral; +} + +/** + * Attach a LivePhotosKit instance to an existing DOM element. + * + * This instance provides a default native control allowing users to playback + * Live Photos. The native control works as follows: + * + * On a desktop browser, when the user hovers the pointer over the native + * control badge, the video starts playing until the user stops hovering or the + * video ends. If the user moves the pointer before the video ends, the video + * stops smoothly. + * + * On a mobile browser, when the user presses the Live Photo, the video starts + * playing until the user stops pressing or the video ends. Similarly to a + * computer, when the user stops pressing, the video stops smoothly. + * + * In the case of a "loop" style asset, the video will load and auto-play by + * default. In this scenario interacting with the badge will not affect + * playback. However, if the "autoplay" attribute is explicitly set to "false", + * ineracting with the controls will play/pause the loop, similar to the above. + * + * @function LivePhotosKit~augmentElementAsPlayer + * @augments HTMLElement + * + * @param The target DOM element to be decorated + * with additional properties and methods that allow it to act as the Player + * of Live Photos. + * + * @param An object containing keys and values for any subset + * of the public writable properties of Player. If provided, the values + * provided in this object will be used instead of the default values for + * those Player properties. + * + * @return The target element passed in, modified with additional properties and + * methods to allow it to act as a Live Photo player. If no target element + * was provided, then a new `HTMLDivElement` will be created and returned + * with Live Photo player functionality. + */ + +export declare const augmentElementAsPlayer: (targetElement: HTMLElement, options?: Partial) => Player; + +/** + * Create a new DOM element and augment it with a Player instance. + * + * Leverages the {@link LivePhotosKit~augmentElementAsPlayer} function to + * augment the new element. + * + * @function LivePhotosKit~createPlayer + * @augments HTMLElement + * + * @param An object containing keys and values for any subset + * of the public writable properties of Player. If provided, the values + * provided in this object will be used instead of the default values for + * those Player properties. + * + * @return The target element passed in, modified with additional properties and + * methods to allow it to act as a Live Photo player. If no target element + * was provided, then a new `HTMLDivElement` will be created and returned + * with Live Photo player functionality. + */ +export declare const createPlayer: (options?: Partial) => Player; + +/** + * @deprecated This function will be deprecated in an upcoming release. + * Use {@link LivePhotosKit~augmentElementAsPlayer} or {@link LivePhotosKit~createPlayer} instead. + * + * A function used to augment the target HTML element as a Live Photo player. + * + * @param The target DOM element to be decorated with additional properties and methods + * that allow it to act as the Player of Live Photos. + * If a target element is not passed, an `HTMLDivElement` will be created and used instead. + * + * @param An object containing keys and values for any subset of the public writable + * properties of Player. If provided, the values provided in this object will be used instead of the + * default values for those Player properties. + * + * @return The target element passed in, modified with additional properties and methods to allow it to act + * as a Live Photo player. If no target element was provided, then a new `HTMLDivElement` will be created and + * returned with Live Photo player functionality. + */ +export declare const Player: (targetElement?: HTMLElement, options?: Partial) => Player; + +/** + * The interface for an HTMLElement that has been augmented to play Live Photos. + */ +export declare interface Player extends HTMLElement, PlayerProps, PlayerPropsPrivate { + /** + * A value that indicates whether this is a Live Photo player. + */ + readonly __isLPKPlayer__: boolean; + /** + * Plays the Live Photo animation using the `playbackStyle`. + */ + play(): boolean; + /** + * Pauses the Live Photo animation at its current time. + */ + pause(): void; + /** + * Stops playback entirely, and rewinds `currentTime` to zero. + */ + stop(): void; + /** + * Toggles whether the Player is playing. + */ + toggle(): void; + /** + * Update our Player's configuration/state. + */ + setProperties(options: Partial): void; + /** + * When the Player is playing, this changes the duration such that the + * playback will end prematurely. Playback will continue for a short + * time while the animation gracefully winds down, but will take the + * same or less time than it would have had this method not been invoked. + */ + beginFinishingPlaybackEarly(): void; + /** + * Whether or not the Player is currently playing. + */ + readonly isPlaying: boolean; + /** + * Whether the Player has been instructed to play. + */ + readonly wantsToPlay: boolean; + /** + * The current timestamp, as a floating-point number of seconds from the beginning + * of the animation, that is truly displayed on the screen. + */ + readonly renderedTime: number; + /** + * The duration of the animation as a floating-point number of seconds, as determined + * by the playbackStyle and the actual duration of the user-provided underlying video. + */ + readonly duration: number; + /** + * Updates the internal layout of the rendered Live Photo to fit inside the + * bounds of the Player's element. While this runs automatically as a result + * of the window size changing, any time the Player element's size is changed + * for any other reason (i.e. other DOM changes elsewhere in the page, with + * dependent layout implications), this must be invoked in order to continue + * to ensure the Live Photo's layout is correct. + */ + updateSize(force: boolean): boolean; + updateSize(displayWidth: number, displayHeight: number): boolean; + updateSize(displayWidthOrForce?: number | boolean, displayHeight?: number): boolean; + /** + * The width, in pixels, of the underlying photo asset provided to the Player. + */ + readonly photoWidth: number; + /** + * The height, in pixels, of the underlying photo asset provided to the Player. + */ + readonly photoHeight: number; + /** + * The width, in pixels, of the underlying video asset provided to the Player. + */ + readonly videoWidth: number; + /** + * The height, in pixels, of the underlying video asset provided to the Player. + */ + readonly videoHeight: number; + /** + * This property denotes whether the Player is immediately able to begin + * playback. + */ + readonly canPlay: boolean; + /** + * A number between 0 and 1 that denotes the loading progress until it is + * possible to start playback without any more delay. + */ + readonly loadProgress: number; + /** + * If an error occurs while attempting to load required resources, or play + * the Live Photo, the Error instance will land here at this property and + * remain until the Player is given new resources or given the information + * it lacked, and played again. + */ + readonly errors: Error[]; + /** + * Update properties on the player. + * + * @param options The options hash being passed through, from which to update our player. + * @return Returns the newly updated options. + */ + setProperties(options?: Partial): void; +} + +export declare interface LivePhotoBadgeProps { + /** + * Reference to the canvas element backing the badge, can be passed in if + * needed. + * @type {HTMLCanvasElement} + */ + element: HTMLCanvasElement; + + /** + * Label text. Starts off as an empty string until we have loaded our video + * resource and read the correct label from the metadata. + * @type {String} + */ + label: string; + + /** + * Padding around the label. + * @type {number} + */ + labelPadding: number; + + /** + * Padding between left edge and the circles. + * @type {number} + */ + leftPadding: number; + + /** + * Desired height of the badge. + * @type {number} + */ + height: number; + + /** + * CSS color string to represent the background of the badge. + * @type {String} + */ + backgroundColor: string; + + /** + * CSS color string to represent the items draw onto the badge. + * @type {String} + */ + itemColor: string; + + /** + * Desired font size in PTs. + * @type {number} + */ + fontSize: number; + + /** + * Border radius of the badge background. + * @type {number} + */ + borderRadius: number; + + /** + * Border radius of the badge background. + * @type {number} + */ + dottedRadius: number; + + /** + * Border radius of the badge background. + * @type {number} + */ + innerRadius: number; + + /** + * Z index order for this badge + * @type {number} + */ + zIndex: number; + + /** + * Toggle to determine whether or not to animate the progress ring. + * @type {boolean} + */ + shouldAnimateProgressRing: boolean; + + /** + * Time to take to animate the progress ring from 0 to 1 in milliseconds. + * @type {number} + */ + progressRingAnimationSpeed: number; + + /** + * Should user event listeners for enter/leave of the badge (play/stop)? + * @type {Boolean} + */ + shouldAddEventListeners: boolean; + + /** + * The effect type. + */ + effectType: EffectTypeLiteral; + + /** + * The playback style. + */ + playbackStyle: PlaybackStyleLiteral; + + /** + * The callback to invoke to play. + */ + configurePlayAction: (callbackOrArg?: any) => void; + + /** + * The callback to invoke to stop. + */ + configureStopAction: (callbackOrArg?: any) => void; +} + +export declare interface LivePhotoBadge extends LivePhotoBadgeProps {} +export declare class LivePhotoBadge implements LivePhotoBadgeProps { + private _width; + private _textMetrics; + private _context; + private _previousProgress; + private _progress; + private _shouldShowError; + + /** + * The defaults for the values indicated in LivePhotoBadgeProps. + */ + defaultProps: LivePhotoBadgeProps; + + /** + * Create a new badge for the live photo. + * @param opts Dictionary of options to set as instance props + */ + constructor(opts?: Partial); + + /** + * Calculated width of the badge. + */ + readonly width: number; + /** + * String defining the font rendering. + */ + readonly fontStyle: string; + /** + * Determine the horizontal center of the circles. + */ + readonly x0: number; + /** + * Determine the vertical center of the circles. + */ + readonly y0: number; + /** + * Number of dots to render in the outer circle. + */ + static readonly numberOfDots: number; + /** + * Set/Get the progress value which will result in a progress ring being + * drawn in the arc where the outer dots are. Value is 0 - 1, where 0 or 1 + * will reset the badge to the default state (dots on outer ring). + */ + progress: number; + /** + * This shouldShowError determines whether the progress ring is instead + * drawn as a slashed-out error circle (the universal "no" symbol). + * + * Assigning this value will redraw the badge. + */ + shouldShowError: boolean; + + /** + * Draw the badge, with either dots or progress ring. + */ + redraw(): void; + + /** + * Sugar for adding the badge to the DOM. + * @param {HTMLElement} parentElement Element in DOM to attach badge to + */ + appendTo(parentElement: HTMLElement): void; + + private _createCanvas(); + + private _setCanvasSize(); + + private _setInstanceProps(opts); + + private _redraw(progress?); + + private _drawBackground(); + + private _drawDottedCircle(); + + private _drawDot(x, y); + + private _drawInnerCircle(); + + private _drawPlayArrow(); + + private _drawLabel(); + + private _drawProgressRing(progress); + + private _drawErrorSlash(); + + private _animateProgressRing(); + + private _addEventListeners(); +} diff --git a/js/vendor/livephotoskit/livephotoskit.js b/js/vendor/livephotoskit/livephotoskit.js new file mode 100644 index 000000000..5a7593923 --- /dev/null +++ b/js/vendor/livephotoskit/livephotoskit.js @@ -0,0 +1,66 @@ +/*! + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * # LivePhotosKit JS License + * + * **IMPORTANT:** This Apple LivePhotosKit software is supplied to you by Apple + * Inc. ("Apple") in consideration of your agreement to the following terms, and + * your use, reproduction, or installation of this Apple software constitutes + * acceptance of these terms. If you do not agree with these terms, please do not + * use, reproduce or install this Apple software. + * + * This Apple LivePhotosKit software is supplied to you by Apple Inc. ("Apple") in + * consideration of your agreement to the following terms, and your use, + * reproduction, or installation of this Apple software constitutes acceptance of + * these terms. If you do not agree with these terms, please do not use, reproduce + * or install this Apple software. + * + * This software is licensed to you only for use with LivePhotos that you are + * authorized or legally permitted to embed or display on your website. + * + * The LivePhotosKit Software is only licensed and intended for the purposes set + * forth above and may not be used for other purposes or in other contexts without + * Apple's prior written permission. For the sake of clarity, you may not and + * agree not to or enable others to, modify or create derivative works of the + * LivePhotosKit Software. + * + * Neither the name, trademarks, service marks or logos of Apple Inc. may be used + * to endorse or promote products, services without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other + * rights or licenses, express or implied, are granted by Apple herein. + * + * The LivePhotosKit Software is provided by Apple on an "AS IS" basis. APPLE + * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE + * IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE, REGARDING THE LIVEPHOTOSKIT SOFTWARE OR ITS USE AND + * OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS, SYSTEMS, OR SERVICES. + * APPLE DOES NOT WARRANT THAT THE LIVEPHOTOSKIT SOFTWARE WILL MEET YOUR + * REQUIREMENTS, THAT THE OPERATION OF THE LIVEPHOTOSKIT SOFTWARE WILL BE + * UNINTERRUPTED OR ERROR-FREE, THAT DEFECTS IN THE LIVEPHOTOSKIT SOFTWARE WILL BE + * CORRECTED, OR THAT THE LIVEPHOTOSKIT SOFTWARE WILL BE COMPATIBLE WITH FUTURE + * APPLE PRODUCTS, SOFTWARE OR SERVICES. NO ORAL OR WRITTEN INFORMATION OR ADVICE + * GIVEN BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE WILL CREATE A WARRANTY. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) RELATING TO OR ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + * OR INSTALLATION, OF THE LIVEPHOTOSKIT SOFTWARE BY YOU OR OTHERS, HOWEVER CAUSED + * AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT + * LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY FOR + * PERSONAL INJURY, OR OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION + * MAY NOT APPLY TO YOU. In no event shall Apple's total liability to you for all + * damages (other than as may be required by applicable law in cases involving + * personal injury) exceed the amount of fifty dollars ($50.00). The foregoing + * limitations will apply even if the above stated remedy fails of its essential + * purpose. + * + * + * **ACKNOWLEDGEMENTS:** + * https://cdn.apple-livephotoskit.com/lpk/1/acknowledgements.txt + * + * v1.5.4 + */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.LivePhotosKit=t():e.LivePhotosKit=t()}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,i){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=25)}([function(e,t,r){"use strict";function i(e){if(e){var t=e.staticMembers;t&&n.call(this,t),n.call(this.prototype,e)}}function n(e){for(var t in e)if(e.hasOwnProperty(t)&&"staticMembers"!==t){var r=Object.getOwnPropertyDescriptor(e,t);r.get||r.set?Object.defineProperty(this,t,r):a.call(this,t,e[t])}}function a(e,t){var r=this[e];return r instanceof Function&&t instanceof Function?o.call(this,e,t,r):C.instanceOrKindOf(t,C.Metadata)?s.call(this,e,t):void(this[e]=t)}function o(e,t,r){this[e]=function(){var e=this._super;this._super=r;var i=t.apply(this,arguments);return this._super=e,i}}function s(e,t){this.hasOwnProperty("_metadatas")||(this._metadatas=Object.create(this._metadatas)),(t.isLPKClass?t.sharedInstance:t).registerOnDefinition(this,e)}function u(e){var t=this["_callbacksFor_"+e];if(t){var r=void 0;if(arguments.length>1){r=C.arrayPool.get();for(var i=1,n=arguments.length;i1)for(var i=0;i1?t-1:0),i=1;i1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),n=1;n1?t-1:0),i=1;i1?t-1:0),i=1;i0&&void 0!==arguments[0]?arguments[0]:{};d.a&&!e.videoSrc&&e.photoSrc?s.a.warn("Changing a `photoSrc` independent of its `videoSrc` can result in unexpected behavior"):d.a&&e.videoSrc&&!e.photoSrc&&s.a.warn("Changing a `videoSrc` independent of its `photoSrc` can result in unexpected behavior");var t=C?{photoSrc:C.photo,videoSrc:C.videoSrc,effectType:C.effectType,autoplay:C.autoplay,proactivelyLoadsVideo:C.proactivelyLoadsVideo}:{},r=c({},t,e),i=(r.photoSrc,r.videoSrc,r.effectType),n=r.autoplay,f=r.proactivelyLoadsVideo;F=o.a.objectPool.get(),r.preloadedEffectType=i,r.autoplay=!1!==n;var v=i||l.a.default;l.a.toPlaybackStyle(v)===u.a.LOOP&&r.autoplay&&(d.a&&!f&&s.a.warn("When using a looping asset you should set `proactivelyLoadsVideo` to `true` unless `autoplay` is also set to `false`"),r.proactivelyLoadsVideo=!0);for(var y in r)Object.prototype.hasOwnProperty.call(r,y)&&(p[y]===h?F[y]=r[y]:s.a.warn("LivePhotosKit.Player: Initial configuration for `"+y+"` was ignored, because the property is not a writable property."));if(C)for(var m in F){var g=F[m];C[m]=g}else C=a.a.create(R,F);o.a.objectPool.ret(F),F=null};R.setProperties=L,R.setProperties(t);for(var E,I,A=0;(E=f[A])&&(I=m[A]);A++)!function(e,t,r){"method"===r?(g.value=C[t].bind(C),Object.defineProperty(R,t,g)):(b.set=r===h?function(e){C[t]=e}:function(){},b.get=function(){return C[t]},Object.defineProperty(R,t,b))}(0,E,I);g.value=function(){var e=arguments.length,t=arguments[e-1];if(e<1||!(t instanceof Function))throw new Error("Invalid arguments passed to `observe`. Form: key, [key, …], callback.");for(var r=o.a.arrayPool.get(),i=0,n=e;i=3||"string"==typeof arguments[0]&&"string"==typeof arguments[1])throw new Error("LivePhotosKit.Player: Creating a new Player using arguments of the form 'photoSrc, videoSrc, [targetElement, [options]]' is no longer supported. Instead, use the new signature, '[targetElement, [options]]");return s.a.warn("The `LivePhotosKit.Player` method will be deprecated in an upcoming release. Please use the `LivePhotosKit.augementElementAsPlayer` or `LivePhotosKit.createPlayer` methods, instead."),e?_(e,t):P(t)},T=function e(t,r){i(this,e),this.fire=function(){r[t.keyOnObject]()},this.disconnect=function(){t.unregisterFromDefinition(r)},this.connect=function(){t.registerOnDefinition(r)}}},function(e,t,r){"use strict";var i=/_lpk_debug=true/i;t.a=i.test(window.location.search)||i.test(window.location.hash)},function(e,t,r){"use strict";var i={setUpForRender:function(){this.attachInto(this.renderer)},tearDownFromRender:function(){this.detach(),this._super()},renderStyles:function(e){for(var t,r=this.element,i=r.style,n=0;t=e[n];n++){var a=t,o=a.styleKey,s=a.value;i[o]!==s&&(i[o]=s)}}};t.a=i},function(e,t,r){"use strict";var i=r(55),n=r(56),a=r(57);t.a={APP_NAME:"LivePhotosKit",BUILD_NUMBER:i.a,MASTERING_NUMBER:n.a,FEEDBACK_URL_PREFIX:"https://feedbackws.icloud.com",LIVEPHOTOSKIT_LOADED:"livephotoskitloaded",URL_PREFIX:"https://cdn.apple-livephotoskit.com",VERSION:a.a}},function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var n=r(3),a=r(50),o=r(18),s=r(10),u=r(1);r.d(t,"a",function(){return c});var l=function(){function e(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};i(this,e),this._setInstanceProps(r),this._createCanvas(),this.redraw(),this._addEventListeners(),s.a.observe("locale",function(){return t.updateBadgeText()})}return l(e,[{key:"attachPlayerInstance",value:function(e){e.attachBadgeView(this),this.updateBadgeText(e.effectType)}},{key:"redraw",value:function(){var e=this.progress;e>0&&this.shouldAnimateProgressRing?this._animateProgressRing():this._redraw(e)}},{key:"reset",value:function(){var e=this._requestedFrame;e&&cancelAnimationFrame(e),this._progress=0,this._previousProgress=0,this.redraw()}},{key:"appendTo",value:function(e){e.appendChild(this.element)}},{key:"updateAriaLabel",value:function(){var e=n.a.toLocalizedString(this.effectType),t=s.a.getString("VideoEffects.Badge");this.element.setAttribute("aria-label",t+": "+e)}},{key:"updateBadgeText",value:function(e){e?this.effectType=e:e=this.effectType,this.label=e?n.a.toBadgeText(e):"",this.playbackStyle=n.a.toPlaybackStyle(e),this.updateAriaLabel(),this._redraw()}},{key:"_createCanvas",value:function(){var e=this.element;if(e){if("canvas"!==e.tagName.toLowerCase())throw new Error("Backing element for LivePhotoBadge needs to be an HTMLCanvasElement.")}else e=this.element=document.createElement("canvas");e.setAttribute("role","button"),this.updateAriaLabel(),e.classList.add("lpk-badge"),this._context=e.getContext("2d")}},{key:"_setCanvasSize",value:function(){var e=this.element,t=o.a(),r=this.height,i=this.width;e.height=r*t,e.width=i*t,e.style.height=r+"px",e.style.width=i+"px"}},{key:"_setInstanceProps",value:function(e){var t={};for(var r in d)t.hasOwnProperty.call(d,r)&&(this[r]=e.hasOwnProperty(r)?e[r]:d[r]);this.defaultProps=d}},{key:"_redraw",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=(this.element,this.label),r=t.toLowerCase()||n.a.default;this._setCanvasSize(),this._context.clearRect(0,0,this.width,this.height),this._drawBackground(),this._drawLabel(),this.shouldShowError||(this._drawInnerCircle(),n.a.toPlaybackStyle(r)!==u.a.LOOP?this._drawPlayArrow():this._drawLoopCircle()),this.shouldShowError?(this._drawProgressRing(1),this._drawErrorSlash()):this.progress>0?this._drawProgressRing(e):this._drawDottedCircle()}},{key:"_drawBackground",value:function(){var e=o.a(),t=this._context,r=this.borderRadius*e,i=this.width*e,n=this.height*e;t.beginPath(),t.moveTo(r,0),t.lineTo(i-r,0),t.quadraticCurveTo(i,0,i,r),t.lineTo(i,n-r),t.quadraticCurveTo(i,n,i-r,n),t.lineTo(r,n),t.quadraticCurveTo(0,n,0,n-r),t.lineTo(0,r),t.quadraticCurveTo(0,0,r,0),t.closePath(),t.fillStyle=this.backgroundColor,t.fill()}},{key:"_drawDottedCircle",value:function(){for(var t=e.numberOfDots,r=this.dottedRadius*o.a(),i=0;i0?s.width:0;return this._width=(u>2?a:-2)+2*t+2*n+Math.ceil(u/o.a())}},{key:"fontStyle",get:function(){return this.fontSize*o.a()+'pt/1 system, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica'}},{key:"x0",get:function(){return(this.dottedRadius+this.leftPadding)*o.a()}},{key:"y0",get:function(){return this.height/2*o.a()}},{key:"progress",set:function(e){"number"==typeof e&&(this._previousProgress=this._progress,this._progress=e,this.redraw())},get:function(){return this._progress}},{key:"shouldShowError",set:function(e){this._shouldShowError=!!e,this._redraw(this.progress)},get:function(){return this._shouldShowError}}],[{key:"numberOfDots",get:function(){return 1===o.a()?17:26}}]),e}()},function(e,t,r){"use strict";var i=r(30),n=r(0),a=r(6),o=i.a.extend({mimeType:n.a.observableProperty({dependencies:["_mimeTypeFromXHR"],get:function(e){return this._mimeTypeFromXHR||e||null}}),_mimeTypeFromXHR:n.a.observableProperty(),requiresMimeTypeForRawArrayBufferSrc:!0,exposedMimeTypeKeyForErrorStrings:"mimeType",exposedSrcKeyForErrorStrings:"src",abortCurrentLoad:function(){this.__xhr&&(this._detachXHR(),this._xhr.abort()),this._mimeTypeFromXHR=null,this.abortCurrentSecondaryLoad()},loadSrc:function(e){if("string"==typeof e){this._mimeTypeFromXHR=null,this._attachXHR();var t=this._xhr;t.open("GET",e),t.responseType="arraybuffer",t.send(null)}else if(e instanceof ArrayBuffer){if(!this.mimeType&&this.requiresMimeTypeForRawArrayBufferSrc)throw new Error("MIME Type must be assigned to `"+this.exposedMimeTypeKeyForErrorStrings+"` prior to assigning a raw ArrayBuffer to `"+this.exposedSrcKeyForErrorStrings+"`.");this.beginSecondaryLoad(e,this.mimeType)}},get _xhr(){var e=this.__xhr;return e||(e=this.__xhr=new XMLHttpRequest),e},_detachXHR:function(){var e=this._xhr;e.removeEventListener("progress",this._xhrProgress),e.removeEventListener("readystatechange",this._xhrReadyStateChanged)},_attachXHR:function(){var e=this._xhr;e.addEventListener("progress",this._xhrProgress),e.addEventListener("readystatechange",this._xhrReadyStateChanged)},_xhrReadyStateChanged:function(){if("loading"===this.state){if(this._xhr.readyState>=2&&200!==this._xhr.status){var e=new Error("Failed to download resource from URL assigned to '"+this.exposedSrcKeyForErrorStrings+"'.");return e.errCode=a.a.FAILED_TO_DOWNLOAD_RESOURCE,this.loadDidFail(e)}return 4===this._xhr.readyState&&200===this._xhr.status?this._xhrLoadDidFinish():void 0}},_xhrProgress:function(e){if(e&&e.total){var t=(+e.loaded||0)/e.total;+t===t&&(this.progress=Math.max(0,Math.min(1,t)))}},_xhrLoadDidFinish:function(){this._mimeTypeFromXHR=this._xhr.getResponseHeader("Content-Type"),this.beginSecondaryLoad(this._xhr.response,this.mimeType)},beginSecondaryLoad:function(e,t){this._defaultSecondaryLoadTimeout=setTimeout(this.loadDidSucceed.bind(this,e),0)},abortCurrentSecondaryLoad:function(){this._defaultSecondaryLoadTimeout&&(clearTimeout(this._defaultSecondaryLoadTimeout),this._defaultSecondaryLoadTimeout=null)},init:function(){this._xhrReadyStateChanged=this._xhrReadyStateChanged.bind(this),this._xhrProgress=this._xhrProgress.bind(this),this._super()}});t.a=o},function(e,t,r){"use strict";var i=r(2);t.a=i.a.isEdge||i.a.isIE},function(e,t,r){"use strict";function i(){u.forEach(function(e){return e()})}function n(e){u.push(e)}function a(){return window.devicePixelRatio}function o(){return Math.ceil(a())}t.b=n,t.a=o;var s=void 0,u=[];!function(){window.matchMedia&&(s=window.matchMedia("only screen and (-webkit-min-device-pixel-ratio:1.3),only screen and (-o-min-device-pixel-ratio:13/10),only screen and (min-resolution:120dpi)"),s.addListener(i))}()},function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var n=function(){function e(e,t){for(var r=0;r0&&(this._k.length=0,this._v.length=0)}}]),e}();t.a=a},function(e,t,r){"use strict";function i(e){if(null===e)return"_null";if(void 0===e)return"_undefined";if(e.hasOwnProperty("_LPKGUID"))return e._LPKGUID;var t=void 0===e?"undefined":n(e);switch(t){case"number":Object.is(e,-0)&&(e="-0");case"string":case"boolean":return t+e;case"object":case"function":o++;var r=t+o;return a.value=r,Object.defineProperty(e,"_LPKGUID",a),r;default:throw"unrecognized object type"}}t.a=i;var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a={value:"",enumerable:!1,writable:!1,configurable:!1},o=0},function(e,t,r){function i(e){return r(n(e))}function n(e){var t=a[e];if(!(t+1))throw new Error("Cannot find module '"+e+"'.");return t}var a={"./en-us.lproj/strings.json":22};i.keys=function(){return Object.keys(a)},i.resolve=n,e.exports=i,i.id=21},function(e,t){e.exports={"VideoEffects.Badge":"Badge","VideoEffects.Badge.Title.Loop":"Loop","VideoEffects.Badge.Title.Bounce":"Bounce","VideoEffects.Badge.Title.LongExposure":"Long Exposure"}},function(e,t,r){"use strict";var i=r(28),n=r(32),a=r(34),o=r(37),s=r(35),u=r(4),l=r(0),d=r(8),c=r(5),h=r(1);a.a.register(),o.a.register(),s.a.register();var p=d.a.extend({approach:"",autoplay:!0,caption:"",_hasInitialized:!1,_lastRecipe:null,recipe:l.a.observableProperty({get:function(){var e=u.a.getRecipeFromPlaybackStyle(this.playbackStyle);return this._setRecipe(e),e},set:function(e){this._setRecipe(e)}}),_setRecipe:function(e){e&&e!==this._lastRecipe&&(this._lastRecipe=e,this.setUpRenderLayers())},requestMoreCompatibleRecipe:function(){this.recipe=this.recipe.requestMoreCompatibleRecipe()},duration:l.a.observableProperty({dependencies:["recipe","provider.videoDuration","provider.photoTime"],get:function(e){var t=this.recipe,r=this.provider,i=r.photoTime,n=r.videoDuration;return t?t.calculateAnimationDuration(e,n,i):0}}),displayWidth:0,displayHeight:0,get backingWidth(){return Math.round(this.displayWidth*devicePixelRatio)},get backingHeight(){return Math.round(this.displayHeight*devicePixelRatio)},get renderLayerWidth(){return this.displayWidth},get renderLayerHeight(){return this.displayHeight},get videoWidth(){return this.videoDecoder.videoWidth},get videoHeight(){return this.videoDecoder.videoHeight},photoWidth:l.a.proxyProperty("photo.width"),photoHeight:l.a.proxyProperty("photo.height"),photo:l.a.proxyProperty("provider.photo"),video:l.a.proxyProperty("provider.video"),photoTime:l.a.proxyProperty("provider.photoTime"),frameTimes:l.a.proxyProperty("provider.frameTimes"),effectType:l.a.proxyProperty("provider.effectType"),preloadedEffectType:l.a.proxyProperty("provider.preloadedEffectType"),playbackStyle:l.a.proxyProperty("provider.playbackStyle"),currentTime:l.a.observableProperty({defaultValue:0,dependencies:["duration"],get:function(e){return Math.min(this.duration||0,Math.max(0,e||0))},didChange:function(e){this.prepareToRenderAtTime(e)}}),canRenderCurrentTime:l.a.observableProperty({readOnly:!0,dependencies:["currentTime"],get:function(){return this.canRenderAtTime(this.currentTime)}}),_currentTimeRenderObserver:l.a.observer("currentTime","canRenderCurrentTime",function(e,t){t&&(this.renderedTime=e)}),renderedTime:l.a.observableProperty({defaultValue:0,didChange:function(e){this.renderAtTime(e),this.currentTime=e}}),areAllRenderLayersPrepared:l.a.observableProperty({defaultValue:!1}),isFullyPreparedForPlayback:l.a.observableProperty({readOnly:!0,dependencies:["video","areAllRenderLayersPrepared","photoTime","frameTimes","playbackStyle"],get:function(){return Boolean(this.video&&this.areAllRenderLayersPrepared&&(this.photoTime||this.playbackStyle!==h.a.HINT)&&Array.isArray(this.frameTimes))}}),cannotRenderDueToMissingPhotoTimeOrFrameTimes:l.a.observableProperty({readOnly:!0,dependencies:["video","areAllRenderLayersPrepared","photoTime","frameTimes","playbackStyle"],get:function(){return Boolean(this.video&&this.areAllRenderLayersPrepared&&(!this.photoTime&&this.playbackStyle===h.a.HINT||!Array.isArray(this.frameTimes)))}}),renderLayers:l.a.property(function(){return[]}),videoDecoder:l.a.observableProperty(function(){return this._videoDecoderClass.create({owner:this})}),_videoDecoderClass:i.a.extend({owner:l.a.observableProperty(),provider:l.a.proxyProperty("owner.provider")}),provider:l.a.observableProperty(function(){return n.a.create()}),init:function(){this._super(),this.element.className=((this.element.className||"")+" lpk-live-photo-renderer").trim(),this.element.style.position="absolute",this.element.style.overflow="hidden",this.element.style.textAlign="left"},updateSize:function(e,t){if(!arguments.length)return void(this.displayWidth&&this.displayHeight&&this.updateSize(this.displayWidth,this.displayHeight));this.displayWidth=e=Math.round(e),this.displayHeight=t=Math.round(t),this.element.style.width=e+"px",this.element.style.height=t+"px";for(var r,i=0;r=this.renderLayers[i];i++)r.updateSize(this.renderLayerWidth,this.renderLayerHeight)},_imageOrVideoDidEnterOrLeave:l.a.observer("videoDecoder.canProvideFrames","photo",function(){this.prepareToRenderAtTime(this.currentTime)}),prepareToRenderAtTime:l.a.boundFunction(function(e){this.propertyChanged("canRenderCurrentTime");for(var t,r=!0,i=0;t=this.renderLayers[i];i++)r=t.prepareToRenderAtTime(e)&&r;this.areAllRenderLayersPrepared=r}),canRenderAtTime:function(e){if(0===e)return!0;if(!this.duration&&e)return!1;for(var t,r=!0,i="",n=0;t=this.renderLayers[n];n++)t.canRenderAtTime(e)||(r=!1,i+=(i?", ":"Cannot render; waiting for ")+t.layerName);return i&&c.a.log(i+"."),r},renderAtTime:function(e){if(this.duration)for(var t,r=0;t=this.renderLayers[r];r++)t.renderAtTime(e)},getNewRenderLayers:function(){return this.recipe.getRenderLayers(this)},setUpRenderLayers:function(){var e=this.renderLayers;e&&this._cleanUpRenderLayers(e),this.renderLayers=this.getNewRenderLayers(),this.updateSize(),this.currentTime=0,this.prepareToRenderAtTime(0)},_cleanUpRenderLayers:function(e){for(var t,r=0;t=e[r];r++)t.dispose(),t.tearDownFromRender()},reduceMemoryFootprint:function(){for(var e,t=0;e=this.renderLayers[t];t++)e.reduceMemoryFootprint()},_clearRetainedFramesWhenNecessary:l.a.observer("provider.videoRotation","provider.frameTimes",function(){this.reduceMemoryFootprint(),this.prepareToRenderAtTime(this.currentTime)})});t.a=p},function(e,t,r){"use strict";var i=r(23),n=i.a.extend({approach:"dom"});t.a=n},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=r(14),n=r(9),a=r(10),o=r(11);r.d(t,"augmentElementAsPlayer",function(){return o.a}),r.d(t,"createPlayer",function(){return o.b}),r.d(t,"Player",function(){return o.c});var s=r(6);r.d(t,"Errors",function(){return s.a});var u=r(15);r.d(t,"LivePhotoBadge",function(){return u.a});var l=r(1);r.d(t,"PlaybackStyle",function(){return l.a}),r.d(t,"Localization",function(){return d}),r.d(t,"BUILD_NUMBER",function(){return c}),r.d(t,"MASTERING_NUMBER",function(){return h}),r.d(t,"VERSION",function(){return p}),r.d(t,"LIVEPHOTOSKIT_LOADED",function(){return f});var d={get locale(){return a.a.locale},set locale(e){a.a.locale=e}},c=i.a.BUILD_NUMBER,h=i.a.MASTERING_NUMBER,p=i.a.VERSION,f=i.a.LIVEPHOTOSKIT_LOADED,v="undefined"!=typeof window&&"undefined"!=typeof document;if(v){var y=window.document;setTimeout(function(){return y.dispatchEvent(r.i(n.a)())});if(y.styleSheets&&document.head){for(var m=null,g=null,b=0;b0)}),init:function(){this._super.apply(this,arguments),e.attachBadgeView(this.badgeView)}}).create()):null},didChange:function(e){this._nativeControls_previousValue&&this._nativeControls_previousValue.detach(),this._nativeControls_previousValue=e,e&&e.attachInto(this)}}),init:function(e,t){var i=this;if(e&&!n(e))throw"Any pre-existing element provided for use as a LivePhotosKit.Player must be able to append child DOM nodes.";e&&e.childNodes.length&&(e.innerHTML="");for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(this[a]=t[a]);this._super(e);switch(this.element.className.indexOf("lpk-live-photo-player")<0&&(this.element.className=this.element.className+" lpk-live-photo-player"),this.element.setAttribute("role","image"),r.i(c.a)(this.element,"position")||this.element.style.position){case"absolute":case"fixed":case"relative":break;default:this.element.style.position="relative"}switch(r.i(c.a)(this.element,"display")||this.element.style.display){case"block":case"inline-block":case"table":case"table-caption":case"table-column-group":case"table-header-group":case"table-footer-group":case"table-row-group":case"table-cell":case"table-column":case"table-row":break;default:this.element.style.display="inline-block"}this.renderer.attachInto(this),this.renderer.eventDispatchingElement=this.element,window.addEventListener("resize",this.updateSize),"ontouchstart"in document.documentElement&&(this.addEventListener("touchstart",function(){return i.play()},!1),this.addEventListener("touchend",function(){return i.beginFinishingPlaybackEarly()},!1))},play:function(){if(!this.isPlaying){var e=this.provider;e.video||(e.needsLoadedVideoForPlayback=!0),this.wantsToPlay=!0,this.canPlay&&(this.isPlaying=!0,this._lastFrameNow=Date.now(),this._nextFrame())}return this.isPlaying},pause:function(){this.isPlaying=!1,this.wantsToPlay=!1,this._cancelNextFrame()},stop:function(){this.pause(),this.currentTime=0,this.renderer.duration=NaN},toggle:function(){this.wantsToPlay?this.pause():this.play()},beginFinishingPlaybackEarly:function(){this.recipe.beginFinishingPlaybackEarly(this)},_stopWhenAnotherPlayerStarts:l.a.observer("_constructor.activeInstance",function(e){e&&e!==this&&(this.stop(),this.renderer.reduceMemoryFootprint())}),_constructor:l.a.observableProperty(function(){return p}),_stopPlaybackWhenItemsLoadOrUnload:l.a.observer("video","photo",function(){!this.isPlaying||this.playbackStyle===h.a.LOOP&&this.autoplay||this.stop()}),addEventListener:function(e,t,r){var i=this.element;i.addEventListener.call(i,e,t,r)},removeEventListener:function(e,t,r){var i=this.element;i.removeEventListener.call(i,e,t,r)},_nextFrame:function(){var e=Date.now(),t=(e-this._lastFrameNow)*this.playbackRate;this._lastFrameNow=e,this.currentTime===this.renderedTime&&(this.currentTime+=t/1e3),this.recipe&&this.recipe.continuePlayback(this)},_cancelNextFrame:function(){cancelAnimationFrame(this._rafID)},updateSize:l.a.boundFunction(function(e,t){if(this.photoWidth&&this.photoHeight){var i=!0===e?void 0:e,n=!0===e?e:void 0;if(isNaN(i)||isNaN(t)?(i=this.element.offsetWidth,t=this.element.offsetHeight):(i=Math.round(i),t=Math.round(t),this.element.style.width=i+"px",this.element.style.height=t+"px"),i&&t){if(!(this._lastUpdateChangeToken!==(this._lastUpdateChangeToken=i+":"+t))&&!n)return!1;var a=r.i(u.a)(this.photoWidth,this.photoHeight,i,t),o=Math.ceil(a.height),s=Math.ceil(a.width),l=Math.floor(i/2-s/2),d=Math.round(t/2-o/2),c=this.renderer;c.element.style.top=d+"px",c.element.style.left=l+"px",c.updateSize(s,o),this.displayWidth=i,this.displayHeight=t,this.nativeControls&&this.nativeControls.updateToRendererLayout(l,d,s,o)}}}),_dispatchPhotoLoadEventOnNewPhoto:l.a.observer("photo",function(e){e&&this.dispatchEvent(r.i(d.c)())}),_dispatchVideoLoadEventOnNewVideo:l.a.observer("video",function(e){e&&this.dispatchEvent(r.i(d.d)())}),throwError:function(e){this.dispatchEvent(r.i(d.e)({error:e,errorCode:e.errCode}))}}),f=document.createElement("div");t.a=p},function(e,t,r){"use strict";function i(){f=!1}function n(){}function a(e,t){return-(e.importance-t.importance)||e.number-t.number}function o(e,t){for(var r=0,i=e.length,n=0;n=this.frameTimes.length)return this.duration;var t=0|e,r=Math.ceil(e);if(t===r)return this.frameTimes[t];var i=this.frameTimes[t],n=r=u&&l.numberr&&c.number<=r+2&&f;if(h||(p=!1),p){if(!this._isPlaying){this._isPlaying=!0;try{var v=this.video.play();v&&v.then instanceof Function&&v.then(n,i)}catch(e){f=!1}}this._expectedNextSeenFrameNumber=c.number,this._scheduleArtificialSeek()}else this._isPlaying&&(this._isPlaying=!1,this.video.pause()),this._expectedNextSeenFrameNumber=NaN,this.video.currentTime=c.time+1e-4,this._isSeeking=!0}}),_frameWillDispose:function(e){this._removePendingFrame(e)},_removePendingFrame:function(e){o(this._pendingFrames,e),this._pendingFrames.length||this._unscheduleArtificialSeek()}});t.a=v},function(e,t,r){"use strict";function i(e){e.container=document.createElement("div"),e.container.frame=e,e.container.innerHTML='
',e.textBox=e.container.lastChild,e.container.insertBefore(e.image,e.textBox),e.image.style.position="absolute",e.container.style.cssText="position:relative; display:inline-block; border: 1px solid black;";var t=e._debug_aspect||(e._debug_aspect=e.videoDecoder&&(e.videoDecoder.videoWidth>e.videoDecoder.videoHeight?"landscape":"portrait"));e.container.style.width=e.image.style.width="landscape"===t?"40px":"30px",e.container.style.height=e.image.style.height="landscape"===t?"30px":"40px",document.body.appendChild(e.container)}var n=r(12),a=r(48),o=r(5),s=r(0),u=r(46),l=r(2);r.d(t,"a",function(){return d});var d=s.a.Object.extend(u.a,a.a,{staticMembers:{getPoolingCacheKey:function(e,t){return"f"+t+"_in_"+e.id}},container:null,image:null,_context:null,number:-1,time:-1,importance:0,videoDecoder:null,readyState:0,_poolingCacheKey:null,_debugShowInDOM:n.a,lacksOwnPixelData:!1,_postDispose:function(){this.image.width=this.image.height=0},get backingFrame(){return this.lacksOwnPixelData?this.videoDecoder.getNearestDecodedFrame(this.number)||this:this},init:function(){this._postDispose=this._postDispose.bind(this);var e=this.image=document.createElement("canvas");this._context=this.image.getContext("2d"),this._super(),this._debugShowInDOM?i(this):h&&(h.appendChild(e),e.style.cssText="position: absolute; top: 0px; width:1px; height: 1px; display: inline-block;",e.style.left=c+++"px")},initFromPool:function(e,t){clearTimeout(this._postDisposalTimeout),this.videoDecoder=e,this.number=t,this.time=e.frameTimes[t],this._debugShowInDOM&&(this.textBox.innerHTML=this.number)},dispose:function(){this.resetReadiness(),this.videoDecoder._frameWillDispose(this),this.number=this.time=-1,this.importance=0,this.videoDecoder=null,this.readyState=0,this.lacksOwnPixelData=!1,this._postDisposalTimeout=setTimeout(this._postDispose,3e3),this.constructor._disposeInstance(this),this._debugShowInDOM&&(this.textBox.innerHTML="x",this.textBox.style.color="#FF0000",this._context.clearRect(0,0,this.image.width,this.image.height))},didPend:function(){this.readyState=1,this._debugShowInDOM&&(this.textBox.style.color="#FF8800")},didDecode:function(){this.obtainPixelData(),this.readyState=2,this.resolveReadiness(this),this._debugShowInDOM&&(this.textBox.style.color="#00FF00")},obtainPixelData:function(){var e=this.image,t=this._context,r=this.videoDecoder,i=r.videoRotation,n=r.videoWidth,a=r.videoHeight,o=i%180==0?n:a,s=i%180==0?a:n;e.width===n&&e.height===a||(e.width=n,e.height=a),l.a.isFirefox&&t.getImageData(0,0,1,1);for(var u=0;u=2,a=0,o=e.length;a0)switch(t.metaData.values.items[b]){case 1:_=d.a.LOOP;break;case 2:_=d.a.BOUNCE;break;case 3:_=d.a.EXPOSURE}this.effectType=_}}),f=[" 0 1 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 1 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 64 0 0 0"," 0 0 0 0 | 0 1 0 0 | 0 0 0 0 | 255 255 0 0 | 0 0 0 0 | 0 0 0 0 | 4 56 0 0 | 0 0 0 0 | 64 0 0 0","255 255 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 255 255 0 0 | 0 0 0 0 | 5 160 0 0 | 4 56 0 0 | 64 0 0 0"," 0 0 0 0 | 255 255 0 0 | 0 0 0 0 | 0 1 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 5 160 0 0 | 64 0 0 0"].map(function(e){return e.replace(/\|/g,"").trim().split(/\s+/g).map(parseFloat)});t.a=p},function(e,t,r){"use strict";var i=r(4),n=r(1),a=r(2),o=a.a.isSafari,s=i.a.create({correspondingPlaybackStyle:n.a.FULL,get minimumShortenedDuration(){return this.enterDuration+this.exitDuration+.01},get spontaneousFinishDuration(){return this.exitDuration},enterDuration:1/3,exitDuration:.5,videoBeginTime:.15,zoomScaleFactor:1.075,blurRadius:5,blurRadiusStep:.2,requiresInterpolation:!0,quantizeRadius:function(e){return this.blurRadiusStep?Math.round(e/this.blurRadiusStep)*this.blurRadiusStep:e},easeInOut:function(e){return e<0?0:e>1?1:.5-.5*Math.cos(e*Math.PI)},calculateAnimationDuration:function(e,t,r){var i=t?t+this.videoBeginTime+this.exitDuration:0;return Math.max(0,Math.min(e||1/0,i))},getEntranceExitParameter:function(e,t){return Math.min(Math.max(0,Math.min(1,1-this.easeInOut((e-(t-this.exitDuration))/this.exitDuration))),1-Math.max(0,Math.min(1,1-this.easeInOut(e/this.enterDuration))))||0},getTransform:function(e,t,r,i){var n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1,o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:1,s=1+(this.zoomScaleFactor-1)*this.getEntranceExitParameter(e,t),u=-(s-1)/2*r,l=-(s-1)/2*i,d=Math.round(u*devicePixelRatio)/devicePixelRatio,c=Math.round(l*devicePixelRatio)/devicePixelRatio;return Math.abs(s-n)<1e-5?"translate3d("+d+"px, "+c+"px, 0) scale3d("+a+", "+o+", 1)":u||l||s?"translate3d("+u+"px, "+l+"px, 0) scale3d("+s+", "+s+", 1)":"translate3d(0, 0, 0)"},photo:i.a.PhotoIngredient.create({opacity:i.a.computedStyle(function(e){if(ethis.recipe.enterDuration&&e1?1:.5-.5*Math.cos(e*Math.PI)},calculateAnimationDuration:function(e,t,r){var i=t?t-r+this.exitBlurDuration:0;return Math.max(0,Math.min(e||1/0,i))},photo:i.a.PhotoIngredient.create({hideDuration:.06,get returnDuration(){return this.recipe.exitBlurDuration},opacity:i.a.computedStyle(function(e){if(ethis.hideDuration&&e0?"none":""})}),video:i.a.InterpolatedVideoIngredient.create({lookaheadTime:.01+7/15,videoTimeAtTime:function(e){return e%this.renderer.duration},prepareVideoFramesFromTime:function(e){this.retainFramesForTime(e,e+this.lookaheadTime)},display:i.a.computedStyle(function(e){return""})}),beginFinishingPlaybackEarly:function(e){e.autoplay||(e.isPlaying?e.pause():e.wantsToPlay=!1)},continuePlayback:function(e){var t=e.currentTime,r=e.duration;t>=r&&(e.currentTime=t%r),e._rafID=requestAnimationFrame(e._nextFrame.bind(e))}}));t.a=a},function(e,t,r){"use strict";var i=r(4),n=r(36),a=r(1);n.a.register();var o=i.a.create({correspondingPlaybackStyle:a.a.LOOP,photo:i.a.PhotoIngredient.create({display:i.a.computedStyle(function(e){return this.isPlaying||e>0?"none":""})}),video:i.a.VideoIngredient.create({display:i.a.computedStyle(function(e){return""})}),beginFinishingPlaybackEarly:function(e){e.autoplay||(e.isPlaying?e.pause():e.wantsToPlay=!1)},continuePlayback:function(e){var t=e.currentTime,r=e.duration;t>=r&&(e.currentTime=t%r),e._rafID=requestAnimationFrame(e._nextFrame.bind(e))},requestMoreCompatibleRecipe:function(e){return i.a.registerRecipeWithPlaybackStyle(n.a,this.correspondingPlaybackStyle),n.a}});t.a=o},function(e,t,r){"use strict";var i=r(0),n=r(41),a=r(1),o=r(13),s=n.a.extend(o.a,{_loCanvas:null,_hiCanvas:null,backingScaleFactor:1,setUpForRender:function(){var e=this.element,t=(this.isPlaying,this.renderer),r=t.autoplay,n=t.parentView,o=t.playbackStyle,s=t.video;if(!this._loCanvas||!this._hiCanvas){e.innerHTML&&(e.innerHTML="");var u=this._loCanvas=i.a.canvasPool.get(),l=this._hiCanvas=i.a.canvasPool.get();u._context=u.getContext("2d"),l._context=l.getContext("2d"),u.style.cssText=l.style.cssText="position: absolute; left: 0; top: 0; width: 100%; height: 100%; transform: translateZ(0);",e.appendChild(u),e.appendChild(l),this._swapCanvases()}e.className="lpk-render-layer lpk-video",e.style.position="absolute",e.style.transformOrigin="0 0",e.style.zIndex=1,this._super(),o===a.a.LOOP&&(this.shouldLoop=!0),this.shouldLoop&&requestAnimationFrame(function(){s.currentTime=-1,r&&n.play()}),window.test=this},updateSize:function(e,t){if(!arguments.length)return this._super();this._super(e,t);var r=Math.ceil(e*this.backingScaleFactor),i=Math.ceil(t*this.backingScaleFactor);this.backingScaleX=r/e,this.backingScaleY=i/t,this.element.style.width=r+"px",this.element.style.height=i+"px",this._loCanvas&&this._hiCanvas&&(this._loCanvas.width=this._hiCanvas.width=r*devicePixelRatio,this._loCanvas.height=this._hiCanvas.height=i*devicePixelRatio,this._loCanvas._drawnFrameNumber=this._hiCanvas._drawnFrameNumber=-1,this.renderAtTime())},renderAtTime:function(e){if(!arguments.length)return this._super();this._super(e);var t=this.backingScaleX,r=this.backingScaleY;1===t&&1===r||(this.element.style.transform+=" scale3d("+1/t+", "+1/r+", 1)")},renderFramePair:function(e,t,r){(e&&this._hiCanvas._drawnFrameNumber===e.number||t&&this._loCanvas._drawnFrameNumber===t.number)&&this._swapCanvases(),this._putFrameInCanvasIfNeeded(e,this._loCanvas),this._putFrameInCanvasIfNeeded(t,this._hiCanvas),t&&(this._hiCanvas.style.opacity=r)},_swapCanvases:function(){var e=this._hiCanvas;this._hiCanvas=this._loCanvas,this._loCanvas=e,this._loCanvas.style.opacity="",this._loCanvas.style.zIndex=1,this._hiCanvas.style.zIndex=2},_putFrameInCanvasIfNeeded:function(e,t){t._drawnFrameNumber!==(t._drawnFrameNumber=e?e.number:-1)&&(t.setAttribute("data-frame-number",t._drawnFrameNumber.toString()),e?t._context.drawImage(e.image,0,0,t.width,t.height):t._context.clearRect(0,0,t.width,t.height))},dispose:function(){this._super(),this._loCanvas&&i.a.canvasPool.ret(this._loCanvas),this._hiCanvas&&i.a.canvasPool.ret(this._hiCanvas)},tearDownFromRender:function(){var e=this.renderer,t=e.parentView;this.shouldLoop=!1,t&&t.stop(),this._clearAllRetainedFrames(),this._super()}});t.a=s},function(e,t,r){"use strict";var i=r(42),n=r(13),a=r(49),o=i.a.extend(n.a,{tagName:"canvas",get _canvas(){return this.element},get _context(){return this.__context||(this.__context=this._canvas.getContext("2d"))},init:function(){this._super.apply(this,arguments),this.element.className="lpk-render-layer lpk-photo",this.element.style.position="absolute",this.element.style.width=this.element.style.height="100%",this.element.style.transformOrigin="0 0",this.element.style.zIndex=2},tearDownFromRender:function(){this._super(),this._canvas.width=this._canvas.height=0},updateSize:function(e,t){if(!arguments.length)return this._super();this._super(e,t);var i=Math.ceil(e*devicePixelRatio),n=Math.ceil(t*devicePixelRatio),o=this.photo,s=this._canvas;this._lastPhoto===(this._lastPhoto=o)&&s.width===i&&s.height===n||(s.width=i,s.height=n,o&&r.i(a.a)(this._context,o,0,0,i,n))}});t.a=o},function(e,t,r){"use strict";var i=r(0),n=r(2),a=r(13),o=r(43),s=o.a.extend(a.a,{_isPlayingChanged:i.a.observer("isPlaying",function(e){this._video&&(e?(this.duration=1/0,this.play()):this.pause())}),_isVisible:!1,applyStyles:function(){var e=this.element,t=this.video,r=this.videoRotation,i=t.videoHeight,n=t.videoWidth,a=1;[90,270].indexOf(r)>=0&&(a=n/i);var o="\n height: 100%;\n position: absolute;\n width: 100%;\n -moz-transform: scale("+a+") rotate("+r+"deg);\n -webkit-transform: scale("+a+") rotate("+r+"deg);\n -o-transform: scale("+a+") rotate("+r+"deg);\n -ms-transform: scale("+a+") rotate("+r+"deg);\n transform: scale("+a+") rotate("+r+"deg);\n z-index: 1;\n ";e.setAttribute("style",o),e.className="lpk-render-layer lpk-video",t.style.height="100%",t.style.width="100%"},cleanupElement:function(){var e=this.element,t=this.renderer,r=this._video,i=t.parentView;e.innerHtml&&(e.innerHtml=""),r&&(r.loop=!1,r.muted=!1,r.removeEventListener("pause",this.playIfPlaying)),i&&i.stop(),delete this._video},pause:function(){var e=this._isVisible,t=this._video;e&&t.pause()},play:function(){if(this._isVisible){var e=this._video,t=e.play();t?t.catch(this._handlePlayFailure):n.a.isIE||n.a.isEdge||(e.pause(),setTimeout(this._handlePlayFailure))}},_handlePlayFailure:i.a.boundFunction(function(){this.renderer.requestMoreCompatibleRecipe()}),playIfPlaying:i.a.boundFunction(function(){var e=this.isPlaying,t=this._video;if(e&&t.paused){var r=t.play();r&&r.catch(function(){})}}),setUpForRender:function(){var e=this.element,t=(this.isPlaying,this.renderer),r=t.autoplay,i=t.parentView,n=t.video;this.cleanupElement(),e.appendChild(n),this.applyStyles(),n.loop=!0,n.muted=!0,this._video=n,this._isVisible=!0,this._super(),r&&(n.addEventListener("pause",this.playIfPlaying),i.play())},tearDownFromRender:function(){this.cleanupElement(),this._isVisible=!1,this._super()}});t.a=s},function(e,t,r){"use strict";function i(e){e.retain()}function n(e){e.release()}var a=r(0),o=r(7),s=r(17),u=o.a.extend({videoDecoder:a.a.proxyProperty("renderer.videoDecoder"),videoDuration:a.a.proxyProperty("videoDecoder.duration"),canRender:a.a.proxyProperty({readOnly:!0,proxyPath:"videoDecoder.canProvideFrames"}),init:function(){this._super.apply(this,arguments);var e=this.layerName,t=this.recipe;this._framePrepIDKey=t.name+"_"+e+"_framePrepID"},videoTimeAtTime:function(e){return e},_videoTimeAtTime:function(e){return isNaN(e)?e:this.videoTimeAtTime(e)},prepareToRenderAtTime:function(e){var t=this._currentPrepID=++l;if(!this.canRender)return!1;this.prepareVideoFramesFromTime(e);for(var r,i=this._retainedFrames,n=0,a=0;r=i[a];a++)2!==r.readyState&&(r[this._framePrepIDKey]=t,r.onReadyOrFail(this._frameDidPrepare),n++);return this._preppingFrameCount=n,!n},reduceMemoryFootprint:function(){this._super(),this._clearAllRetainedFrames()},_clearAllRetainedFrames:function(){this._clearExtraRetainedFrames(),this._clearRetainedInstantaneousFrames()},_clearExtraRetainedFrames:function(){var e=this._retainedFrames;e&&(e.forEach(n),e.length=0)},_clearRetainedInstantaneousFrames:function(){this._retainedLoFrame&&this._retainedLoFrame.release(),this._retainedHiFrame&&this._retainedHiFrame.release(),this._retainedLoFrame=this._retainedHiFrame=null},_frameDidPrepare:a.a.boundFunction(function(e){e[this._framePrepIDKey]===this._currentPrepID&&(e[this._framePrepIDKey]=void 0,--this._preppingFrameCount||this.renderer.prepareToRenderAtTime(this.renderer.currentTime))}),prepareVideoFramesFromTime:function(e){this.retainFramesForTime(e)},canRenderAtTime:function(e){if("none"===this.display(e))return!0;if(!this.canRender)return!1;for(var t,r=!0,i=this.requiredFramesForTime(e),n=0;t=i[n];n++)r=r&&2===t.readyState,t.retain().release();return r},renderAtTime:function(e){if(!arguments.length)return this._super();if("none"===this.display(e))return this._clearRetainedInstantaneousFrames(),this._super(e);var t=this._videoTimeAtTime(e),r=this.requiredFramesForVideoTime(t),i=r[0]||null,n=r[1]||null;if(i&&i.retain(),n&&n.retain(),this._clearRetainedInstantaneousFrames(),this._retainedLoFrame=i,this._retainedHiFrame=n,i&&(i=i.backingFrame),n&&(n=n.backingFrame),i&&n&&i.number>n.number){var a=i;n=i,i=a}i===n&&(n=null);var o=!i||n?this.videoDecoder.fractionalIndexForTime(t):i.frameNumber,s=o-(0|o);this.renderFramePair(i,n,s),this._super(e)},renderFramePair:function(){},requiredFramesForVideoTime:function(e,t,r){isNaN(t)&&(t=e);var i=this.videoDecoder,n=this.videoDuration,a=i.frameCount,o=d;if(o.length=0,t<0||e>n||isNaN(e)||isNaN(t))return o;var u=Math.max(0,Math.floor(i.fractionalIndexForTime(e))),l=Math.min(i.frameCount,Math.ceil(i.fractionalIndexForTime(t))),c=l=0;l--){var d=u[l],c=d.time;(!o||c>a/2)&&(n(d),u.splice(l,1))}u.push.apply(u,s)},retainFramesForTime:function(e,t,r){return this.retainFramesForVideoTime(this._videoTimeAtTime(e),this._videoTimeAtTime(t),r)},dispose:function(){this.retainFramesForVideoTime(NaN),this._super()}}),l=1,d=[];t.a=u},function(e,t,r){"use strict";var i=r(7),n=r(0),a=i.a.extend({isPlaying:n.a.proxyProperty({readOnly:!0,proxyPath:"renderer.parentView.isPlaying"}),photo:n.a.proxyProperty({readOnly:!0,proxyPath:"renderer.photo"}),canRender:n.a.proxyProperty("photo"),canRenderAtTime:function(e){var t=this.photo;return!("none"!==this.display(e)&&(!t||t instanceof Image&&!t.complete))}});t.a=a},function(e,t,r){"use strict";var i=r(7),n=r(0),a=i.a.extend({canRender:n.a.proxyProperty({readOnly:!0,proxyPath:"video"}),isPlaying:n.a.proxyProperty({readOnly:!0,proxyPath:"renderer.parentView.isPlaying"}),video:n.a.proxyProperty({readOnly:!0,proxyPath:"renderer.video"}),videoRotation:n.a.proxyProperty({readOnly:!0,proxyPath:"renderer.provider.videoRotation"})});t.a=a},function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e){var t=r.i(o.a)(e),i=l.get(t);if(i)return i;var n=e.map(function(e){if("i"===e[0]&&h(e[1]))return"I"+e.substring(1)});return e=e.concat(n.filter(function(e){return!!e})),i=new RegExp(e.join("|"),"g"),l.set(t,i),i}function a(e,t){var r=e.charCodeAt(0),i=t.charCodeAt(0),n=new Map;return function(e){var t=n.get(e);if(void 0!==t)return t;var a=e.charCodeAt(0);return t=a>=r&&a<=i,n.set(e,t),t}}var o=r(20),s=function(){function e(e,t){for(var r=0;r>>1,this.h>>>1)}},{key:"length",value:function(){return this.w*this.h}}])}(),function(){function e(t,r,n){i(this,e),this.bytes=new Uint8Array(t),this.start=r||0,this.pos=this.start,this.end=r+n||this.bytes.length}return s(e,[{key:"readU8Array",value:function(e){if(this.pos>this.end-e)return null;var t=this.bytes.subarray(this.pos,this.pos+e);return this.pos+=e,t}},{key:"readU32Array",value:function(e,t,r){if(t=t||1,this.pos>this.end-e*t*4)return null;if(1===t){for(var i=new Uint32Array(e),n=0;n>24}},{key:"readU8",value:function(){return this.pos>=this.end?null:this.bytes[this.pos++]}},{key:"read16",value:function(){return this.readU16()<<16>>16}},{key:"readU16",value:function(){if(this.pos>=this.end-1)return null;var e=this.bytes[this.pos+0]<<8|this.bytes[this.pos+1];return this.pos+=2,e}},{key:"read24",value:function(){return this.readU24()<<8>>8}},{key:"readU24",value:function(){var e=this.pos,t=this.bytes;if(e>this.end-3)return null;var r=t[e+0]<<16|t[e+1]<<8|t[e+2];return this.pos+=3,r}},{key:"peek32",value:function(e){var t=this.pos,r=this.bytes;if(t>this.end-4)return null;var i=r[t+0]<<24|r[t+1]<<16|r[t+2]<<8|r[t+3];return e&&(this.pos+=4),i}},{key:"read32",value:function(){return this.peek32(!0)}},{key:"readU32",value:function(){return this.peek32(!0)>>>0}},{key:"read4CC",value:function(){var e=this.pos;if(e>this.end-4)return null;for(var t="",r=0;r<4;r++)t+=String.fromCharCode(this.bytes[e+r]);return this.pos+=4,t}},{key:"readFP16",value:function(){return this.read32()/65536}},{key:"readFP8",value:function(){return this.read16()/256}},{key:"readISO639",value:function(){for(var e=this.readU16(),t="",r=0;r<3;r++){var i=e>>>5*(2-r)&31;t+=String.fromCharCode(i+96)}return t}},{key:"readUTF8",value:function(e){for(var t="",r=0;rthis.end)&&a("Index out of bounds (bounds: [0, "+this.end+"], index: "+e+")."),this.pos=e}},{key:"subStream",value:function(t,r){return new e(this.bytes.buffer,t,r)}},{key:"uint",value:function(e){for(var t=this.position,r=t+e,i=0,n=t;n0&&(T.name=e.readUTF8(l));break;case"minf":o.name="Media Information Box",a();break;case"stbl":o.name="Sample Table Box",a();break;case"stsd":var x=o;x.name="Sample Description Box",t(),x.sd=[],e.readU32(),a();break;case"avc1":var S=o;e.reserved(6,0),S.dataReferenceIndex=e.readU16(),n(0==e.readU16()),n(0==e.readU16()),e.readU32(),e.readU32(),e.readU32(),S.width=e.readU16(),S.height=e.readU16(),S.horizontalResolution=e.readFP16(),S.verticalResolution=e.readFP16(),n(0==e.readU32()),S.frameCount=e.readU16(),S.compressorName=e.readPString(32),S.depth=e.readU16(),n(65535==e.readU16()),a();break;case"mp4a":var O=o;if(e.reserved(6,0),O.dataReferenceIndex=e.readU16(),O.version=e.readU16(),0!==O.version){i();break}e.skip(2),e.skip(4),O.channelCount=e.readU16(),O.sampleSize=e.readU16(),O.compressionId=e.readU16(),O.packetSize=e.readU16(),O.sampleRate=e.readU32()>>>16,a();break;case"esds":o.name="Elementary Stream Descriptor",t(),i();break;case"avcC":var w=o;w.name="AVC Configuration Box",w.configurationVersion=e.readU8(),w.avcProfileIndicaation=e.readU8(),w.profileCompatibility=e.readU8(),w.avcLevelIndication=e.readU8(),w.lengthSizeMinusOne=3&e.readU8(),n(3==w.lengthSizeMinusOne,"TODO"),u=31&e.readU8(),w.sps=[];for(var F=0;F=8,"Cannot parse large media data yet."),j.data=e.readU8Array(r());break;case"mebx":o.name="Mebx",a();break;case"meta":o.name="Metadata",a();break;case"keys":var U=o;U.name="Metadata Item Keys",t();var V=U.keyCount=e.read32(),N=U.offset-U.size;U.keyList=new Map;for(var B=1;B<=V;B++){var z=e.read32()-8;z<1||z>N||(e.skip(4),U.keyList.set(e.readUTF8(z),B))}this.metaData.keys=U;break;case"ilst":var H=o;H.name="Metadata Item List",H.items=[];for(var K=H.offset+H.size;e.position0){var s=t[a-1],u=o.firstChunk-s.firstChunk,l=s.samplesPerChunk*u;if(!(e>=l))return{index:i+Math.floor(e/s.samplesPerChunk),offset:e%s.samplesPerChunk};if(e-=l,a===t.length-1)return{index:i+u+Math.floor(e/o.samplesPerChunk),offset:e%o.samplesPerChunk};i+=u}}n(!1)}},{key:"chunkToOffset",value:function(e){return this.trak.mdia.minf.stbl.stco.table[e]}},{key:"sampleToOffset",value:function(e){var t=this.sampleToChunk(e);return this.chunkToOffset(t.index)+this.sampleToSize(e-t.offset,t.offset)}},{key:"timeToSample",value:function(e){for(var t=this.trak.mdia.minf.stbl.stts.table,r=0,i=0;i=n))return r+Math.floor(e/t[i].delta);e-=n,r+=t[i].count}}},{key:"sampleToTime",value:function(e){for(var t=this.trak.mdia.minf.stbl.stts.table,r=0,i=0,n=0;n0;){var a=new u(t.buffer,r).readU32();n.push(t.subarray(r+4,r+a+4)),r=r+a+4}return n}}]),e}()},function(e,t,r){"use strict";var i={staticMembers:{_pool:null,_cache:null,init:function(){this._pool=[],this._cache={},this._super()},getPoolingCacheKey:function(){throw"Must implement `getPoolingCacheKey` to use PoolCaching."},getCached:function(){var e=this.getPoolingCacheKey.apply(this,arguments),t=this._cache[e];return t||(t=this._cache[e]=this._pool.pop()||this.create(),t._poolingCacheKey=e,t.initFromPool.apply(t,arguments)),t},peekCached:function(){var e=this.getPoolingCacheKey.apply(this,arguments);return this._cache[e]||null},_disposeInstance:function(e){delete this._cache[e._poolingCacheKey],e._poolingCacheKey=void 0,e._poolingLifecycleCount=1+(0|e._poolingLifecycleCount),this._pool.push(e)}},dispose:function(){},_poolingCacheKey:null,initFromPool:function(){},_retainCount:0,retain:function(){return this._retainCount++,this},release:function(){return this._retainCount--,this._retainCount||this.dispose(),this}};t.a=i},function(e,t,r){"use strict";function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function n(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=r(19);r.d(t,"a",function(){return d}),r.d(t,"b",function(){return h}),r.d(t,"c",function(){return f}),r.d(t,"d",function(){return y});var s=function(){function e(e,t){for(var r=0;r2?r-2:0),p=2;p=1)return e.drawImage.apply(e,i.apply(h,arguments)),!0;var R=void 0;if(f){R="_cachedSmoothDownsample_from"+g+","+b+","+_+","+P+"@"+C+"x";var L=t[R];if(L)return e.drawImage(L,0,0,L.width,L.height,k,T,x,S),!0}if(v)return e.drawImage.apply(e,i.apply(h,arguments)),!1;var E=1,I=_,A=P,D=Math.max(Math.pow(2,Math.ceil(Math.log(I)/Math.log(2))),a.width),M=Math.max(Math.pow(2,Math.ceil(Math.log(A)/Math.log(2))),a.height);for(a.width===D&&a.height===M||(a.width=s.width=D,a.height=s.height=M),o.drawImage(t,g,b,_,P,0,0,_,P);E>C;){u.drawImage(a,0,0,I,A,0,0,I=Math.ceil(I/2),A=Math.ceil(A/2)),o.clearRect(0,0,I,A);var j=a;a=s,s=j;var U=o;o=u,u=U,E/=2}if(f){var V=document.createElement("canvas");V.width=I,V.height=A,V.getContext("2d").drawImage(a,0,0),t[R]=V}return e.drawImage(a,0,0,I,A,k,T,x,S),o.clearRect(0,0,_,P),u.clearRect(0,0,_,P),!0}};c.usingCache=function(){return l=!0,this},c.avoidingWorkIf=function(e){return d=e,this};var h=[];t.a=c},function(e,t,r){"use strict";function i(){var e="_callbacksForEventHandler"+ ++n;return function(t){var r=this[e]||(this[e]=[]);if("function"==typeof t)return r.push(t);if(r)for(var i=0,n=r.length;ig;return f=f||{},f.width=b?h:p*m,f.height=b?h/m:p,f}function n(e,t,r,n,a){return i(!1,e,t,r,n,a,arguments.length)}t.a=n},function(e,t,r){"use strict";t.a="current"},function(e,t,r){"use strict";t.a="Mcurrent"},function(e,t,r){"use strict";t.a="1.5.4"}])}); +//# sourceMappingURL=resources/livephotoskit.js.map \ No newline at end of file diff --git a/js/vendor/livephotoskit/package.json b/js/vendor/livephotoskit/package.json new file mode 100644 index 000000000..675ccb6ff --- /dev/null +++ b/js/vendor/livephotoskit/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "livephotoskit", + "scope": null, + "escapedName": "livephotoskit", + "name": "livephotoskit", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "/home/fefe" + ] + ], + "_from": "livephotoskit@latest", + "_id": "livephotoskit@1.5.4", + "_inCache": true, + "_location": "/livephotoskit", + "_nodeVersion": "6.11.0", + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/livephotoskit_1.5.4_1522348009850_0.36032340106104677" + }, + "_npmUser": { + "name": "maxwellc_shay", + "email": "maxwellc_shay@apple.com" + }, + "_npmVersion": "3.10.10", + "_phantomChildren": {}, + "_requested": { + "raw": "livephotoskit", + "scope": null, + "escapedName": "livephotoskit", + "name": "livephotoskit", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/livephotoskit/-/livephotoskit-1.5.4.tgz", + "_shasum": "00c7f41c9c305d2d727ccc218a735f94fd17f83a", + "_shrinkwrap": null, + "_spec": "livephotoskit", + "_where": "/home/fefe", + "author": { + "name": "Apple Inc.", + "email": "npmjs@apple.com" + }, + "dependencies": {}, + "description": "Play Live Photos on the web", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "00c7f41c9c305d2d727ccc218a735f94fd17f83a", + "tarball": "https://registry.npmjs.org/livephotoskit/-/livephotoskit-1.5.4.tgz", + "fileCount": 7, + "unpackedSize": 178965 + }, + "files": [ + "acknowledgements.txt", + "CHANGELOG.md", + "index.d.ts", + "LICENSE.md", + "livephotoskit.js" + ], + "homepage": "https://developer.apple.com/live-photos", + "keywords": [ + "apple", + "image", + "kit", + "live", + "live photo", + "live photos", + "live photos kit", + "livephotoskit", + "livephotoskit js", + "livephotoskitjs", + "photo", + "picture", + "video" + ], + "license": "SEE LICENSE IN LICENSE.md", + "main": "livephotoskit.js", + "maintainers": [ + { + "name": "apple", + "email": "npmjs@apple.com" + }, + { + "name": "maxwellc_shay", + "email": "maxwellc_shay@apple.com" + } + ], + "name": "livephotoskit", + "optionalDependencies": {}, + "publishConfig": { + "registry": "https://registry.npmjs.org" + }, + "readme": "# LivePhotosKit JS\n\nUse the LivePhotosKit JS library to play Live Photos on your web pages.\n\n## Overview\n\nThe JavaScript API presents the player in the form of a DOM element, much\nlike an `image` or `video` tag, which can be configured with photo and video\nresources and other options, and have its playback controlled either\nprogrammatically by the consuming developer, or via pre-provided controls\nby the browsing end-user.\n\n## Documentation\n\nFor more detailed documentation, see\nhttps://developer.apple.com/reference/livephotoskitjs\n\nFor information about Live Photos for developers, see https://developer.apple.com/live-photos\n\n## Installation\n\n### Using npm\n\nInstall and save LivePhotosKit JS:\n```bash\nnpm install --save livephotoskit\n```\n\nImport LivePhotosKit JS (ES6/TypeScript):\n\n```javascript\nimport * as LivePhotosKit from 'livephotoskit';\n```\n\nA [TypeScript](https://www.typescriptlang.org) type definition file is included in the \ndistribution and will automatically be picked up by the TypeScript compiler.\n\n### Using the Apple CDN\n\n```html\n\n```\n\nA [TypeScript](https://www.typescriptlang.org) type definition file is available at\n```html\nhttps://cdn.apple-livephotoskit.com/lpk/1/livephotoskit.d.ts\n```\n\n> Note\n> \n> The LivePhotosKit JS version number is in the URL. For example, 1 specifies LivePhotosKit JS 1.x.x.\n\nYou will then be able to access LivePhotosKit JS via `window.LivePhotosKit`.\n\n\n## Browser Compatibility\n\nThe LivePhotosKit JS player supports the following browsers:\n\n- On macOS: Safari, Chrome, Firefox\n- On iOS: Safari, Chrome\n- On Windows: Chrome, Firefox, Edge, Internet Explorer 11\n- On Android: Chrome (Performance depends on device)\n", + "readmeFilename": "README.md", + "scripts": {}, + "types": "index.d.ts", + "version": "1.5.4" +} diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 8b5e61470..5e72e085d 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -174,6 +174,7 @@ public function errorPage($code) { private function addContentSecurityToResponse($response) { $csp = new Http\ContentSecurityPolicy(); $csp->addAllowedFontDomain("data:"); + $csp->addAllowedMediaDomain("blob:"); $response->setContentSecurityPolicy($csp); } diff --git a/templates/slideshow.php b/templates/slideshow.php index 4115cb103..72d45374a 100644 --- a/templates/slideshow.php +++ b/templates/slideshow.php @@ -25,4 +25,5 @@ class="menuItem svg shareImage icon-share icon-shadow icon-white icon-32 hidden"
+