diff --git a/.eslintrc.json b/.eslintrc.json index b5129e1..8776bde 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,6 +18,8 @@ "error", "prefer-double" ], + "default-param-last": "off", + "class-methods-use-this": "off", "max-lines": [ "warn", { diff --git a/config/low-preview/webpack-demo.config.js b/config/low-preview/webpack-demo.config.js index 880f3a1..f73fa64 100644 --- a/config/low-preview/webpack-demo.config.js +++ b/config/low-preview/webpack-demo.config.js @@ -1,43 +1,52 @@ const path = require('path'); -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + const htmlWebpackPlugin = new HtmlWebpackPlugin({ - template: path.join(__dirname, "../../examples/low-preview/src/index.html"), - filename: "./index.html" + template: path.join(__dirname, '../../examples/low-preview/src/index.html'), + filename: './index.html', }); const miniCssExtractPlugin = new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional - filename: "[name].css", - chunkFilename: "[id].css", -}) + filename: '[name].css', + chunkFilename: '[id].css', +}); module.exports = { - entry: path.resolve(__dirname, "../../examples/low-preview/src/index.js"), + entry: path.resolve(__dirname, '../../examples/low-preview/src/index.js'), output: { - path: path.join(__dirname, "../../examples/low-preview/dist"), - filename: "bundle[hash].js" + path: path.join(__dirname, '../../examples/low-preview/dist'), + filename: 'bundle[hash].js', }, module: { rules: [ { test: /\.(js|jsx)$/, - use: "babel-loader", - exclude: /node_modules/ + use: 'babel-loader', + exclude: /node_modules/, }, { test: /\.css$/, - use: [ MiniCssExtractPlugin.loader, "css-loader" ], + use: [MiniCssExtractPlugin.loader, 'css-loader'], + }, + { + test: /\.(png|jpe?g|gif|svg)$/i, + use: [ + { + loader: 'file-loader', + }, + ], }, - ] + ], }, plugins: [htmlWebpackPlugin, miniCssExtractPlugin], resolve: { - extensions: [".js", ".jsx"] + extensions: ['.js', '.jsx'], }, devServer: { - port: 3001 + port: 3001, }, - devtool: 'source-map' -}; \ No newline at end of file + devtool: 'source-map', +}; diff --git a/config/wp/webpack-demo.config.js b/config/wp/webpack-demo.config.js index 55ba780..e036aeb 100644 --- a/config/wp/webpack-demo.config.js +++ b/config/wp/webpack-demo.config.js @@ -37,7 +37,15 @@ module.exports = { }, "css-loader" ] - } + }, + { + test: /\.(png|jpe?g|gif|svg)$/i, + use: [ + { + loader: 'file-loader', + }, + ], + }, ] }, plugins: [htmlWebpackPlugin, miniCssExtractPlugin], diff --git a/examples/low-preview/src/index.html b/examples/low-preview/src/index.html index bed41b8..a5fd297 100644 --- a/examples/low-preview/src/index.html +++ b/examples/low-preview/src/index.html @@ -342,6 +342,145 @@

Auto Crop

+ +
+

Zoom in Images

+
+ windmill + landscape + port +
+
+ + +
{ if (!canvas && blurHash) { canvas = document.createElement('canvas'); - canvas.setAttribute(canvasAttr, true); + canvas.setAttribute(ATTRIBUTES.CANVAS, true); const pixels = decode(blurHash, 32, 32); canvas.width = 32; canvas.height = 32; diff --git a/src/common/ci.constants.js b/src/common/ci.constants.js index 0f7cc1e..715c7f0 100644 --- a/src/common/ci.constants.js +++ b/src/common/ci.constants.js @@ -1,14 +1,39 @@ -const processedAttr = 'data-ci-processed'; - -const bgContentAttr = 'data-ci-bg-container'; +const loadedImageClassNames = ['ci-image-loaded', 'lazyloaded', 'ci-image']; -const canvasAttr = 'data-ci-canvas'; +const ATTRIBUTES = { + CANVAS: 'data-ci-canvas', + OPTIMIZED_URL: 'ci-optimized-url', + PREVIEW: 'ci-preview', + PROCESSED_GALLERY: 'data-ci-processed-gallery', + ACTIVE_IMAGE_INDEX: 'data-ci-active-image-index', + PROCESSED: 'data-ci-processed', + BG_CONTAINER: 'data-ci-bg-container', + GALLERY: 'data-ci-gallery', + GALLERY_LENGTH: 'data-ci-gallery-length', + GALLERY_INDEX: 'data-ci-gallery-index', + ACTIVE_THUMBNAIL: 'data-active-thumbnail', +}; -const loadedImageClassNames = ['ci-image-loaded', 'lazyloaded', 'ci-image']; +const CLASSNAMES = { + PREVIEW_LOADED: 'ci-preview-loaded', + PREVIEW_MODULE: 'ci-gallery-preview-module', + GALLERY_ANIMATION: 'ci-gallery-animation', + GALLERY_MODAL: 'ci-gallery-modal', + GALLERY_LOADER: 'ci-gallery-loader', + THUMBNAIL_MODULE: 'ci-gallery-thumbnail-module', + THUMBNAIL_CONTAINER: 'ci-gallery-thmbnail-container', + GALLERY_ICON_BUTTON: 'ci-gallery-icon-button', + CLOSE_BUTTON: 'ci-gallery-close-button', + LEFT_ARROW_BUTTON: 'ci-gallery-left-arrow-button', + RIGHT_ARROW_BUTTON: 'ci-gallery-right-arrow-button', + ZOOM_BUTTON: 'ci-gallery-zoom-button', + IMAGE: 'ci-image', + IMAGE_NAME: 'ci-gallery-image-name', + IMAGE_LOADED: 'ci-image-loaded', +}; export { - processedAttr, - bgContentAttr, - canvasAttr, loadedImageClassNames, + ATTRIBUTES, + CLASSNAMES, }; diff --git a/src/common/ci.utils.js b/src/common/ci.utils.js index 1b293ea..44c7245 100644 --- a/src/common/ci.utils.js +++ b/src/common/ci.utils.js @@ -27,14 +27,14 @@ const getSize = (sizes) => { // change single quotes to double quotes temp = temp.replace(/'/g, '"').replace(/-"width":/g, '-width:'); resultSizes = JSON.parse(temp); - } catch (e) {} + } catch (e) { } if (resultSizes) { Object.keys(resultSizes).forEach((key) => { if (typeof resultSizes[key] === 'string') { try { resultSizes[key] = JSON.parse(`{"${decodeURI(resultSizes[key].replace(/&/g, '","').replace(/=/g, '":"'))}"}`); - } catch (e) {} + } catch (e) { } } }); } @@ -49,12 +49,12 @@ const getParams = (params) => { const temp = params.replace(/(\w+:)|(\w+ :)/g, (matchedStr) => `"${matchedStr.substring(0, matchedStr.length - 1)}":`); resultParams = JSON.parse(temp); - } catch (e) {} + } catch (e) { } if (!resultParams) { try { resultParams = JSON.parse(`{"${decodeURI(params.replace(/&/g, '","').replace(/=/g, '":"'))}"}`); - } catch (e) {} + } catch (e) { } } return resultParams; @@ -71,6 +71,10 @@ const getCommonImageProps = (image) => ({ imgNodeHeight: attr(image, 'height'), doNotReplaceImageUrl: isTrue(image, 'ci-do-not-replace-url'), alt: attr(image, 'alt'), + zoom: isTrue(image, 'ci-zoom'), + gallery: attr(image, 'ci-gallery') || undefined, + imageName: attr(image, 'ci-image-name') || undefined, + disableAnimation: isTrue(image, 'disableAnimation'), }); const filterImages = (images, type) => { @@ -92,6 +96,7 @@ const getImageProps = (image, imgSelector) => { const props = { ...getCommonImageProps(image), imgNodeSRC: attr(image, imgSelector) || undefined, + isProcessedByGallery: isTrue(image, 'data-ci-processed-gallery'), }; const params = { @@ -204,19 +209,19 @@ const setAlt = (imgNode, alt) => { imgNode.setAttribute('alt', alt); }; -const removeClassNames = (node, classNames) => { - classNames.forEach((className) => { - if (node.classList.contains(className)) { - node.classList.remove(className); - } +const setOptions = (node, options) => { + Object.entries(options).forEach(([key, value]) => { + node.setAttribute(key, value); }); return node; }; -const setOptions = (node, options) => { - Object.entries(options).forEach(([key, value]) => { - node.setAttribute(key, value); +const removeClassNames = (node, classNames) => { + classNames.forEach((className) => { + if (node.classList.contains(className)) { + node.classList.remove(className); + } }); return node; @@ -227,6 +232,7 @@ export { filterImages, getImageProps, getBackgroundImageProps, + getCommonImageProps, addClass, getWrapper, isLazy, @@ -236,6 +242,6 @@ export { getFreshCIElements, destroyNodeImgSize, setAlt, - removeClassNames, setOptions, + removeClassNames, }; diff --git a/src/low-preview/ci.config.js b/src/low-preview/ci.config.js index 6a2d494..2b00d8f 100644 --- a/src/low-preview/ci.config.js +++ b/src/low-preview/ci.config.js @@ -33,8 +33,7 @@ export const getInitialConfigLowPreview = (config) => { lowQualityPreview: { minImgWidth = 400, } = {}, - - // callback + gallery, onImageLoad = null, } = config; @@ -74,6 +73,23 @@ export const getInitialConfigLowPreview = (config) => { detectImageNodeCSS, processOnlyWidth, onImageLoad, - // isChrome: /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor) + galleryConfigs: { + arrowPrevIcon: null, + arrowNextIcon: null, + closeIcon: null, + modalClassName: '', + previewClassName: '', + thumbnailsClassName: '', + arrowPrev: true, + arrowNext: true, + close: true, + thumbnails: true, + onOpen: null, + onClose: null, + onPrev: null, + onNext: null, + onClickThumbnail: null, + ...gallery, + }, }; }; diff --git a/src/low-preview/ci.service.js b/src/low-preview/ci.service.js index bbf89cf..7d6bff9 100644 --- a/src/low-preview/ci.service.js +++ b/src/low-preview/ci.service.js @@ -13,13 +13,30 @@ import { getFreshCIElements, getImageProps, isLazy, - removeClassNames, setAlt, setBackgroundSrc, setOptions, setSrc, setSrcset, + removeClassNames, + addClass, } from '../common/ci.utils'; +import { + createIcon, + destroyGallery, + createGalleryModal, + getGalleryPreviewModule, + setGalleryIndex, + createGalleryArrows, + getGalleryLengthAndIndex, + createThmbnailsModule, + getGalleryImages, + getZoomImages, + getDimAndFit, + updateOrCreateImageNameWrapper, + swapArrayPositions, + toggleActiveThumbnail, +} from './gallery.utils'; import { getInitialConfigLowPreview } from './ci.config'; import { applyBackgroundStyles, @@ -33,7 +50,13 @@ import { wrapBackgroundContainer, updateSizeWithPixelRatio, } from './ci.utis'; -import { bgContentAttr, loadedImageClassNames, processedAttr } from '../common/ci.constants'; +import { + loadedImageClassNames, ATTRIBUTES, CLASSNAMES, +} from '../common/ci.constants'; +import closeIconSvg from '../public/close-icon.svg'; +import rightArrowSvg from '../public/right-arrow-icon.svg'; +import leftArrowSvg from '../public/left-arrow-icon.svg'; +import zoomIconSvg from '../public/zoom-icon.svg'; export default class CIResponsive { @@ -52,6 +75,26 @@ export default class CIResponsive { this.process(); } + handleModalKeydown(galleryImages, event) { + const { keyCode } = event; + const leftKeyCodes = [37, 40]; // left and down + const rightKeyCodes = [39, 38]; // right and up + + if (galleryImages) { + if (leftKeyCodes.includes(keyCode)) { + this.handleClickArrows(galleryImages, 'left'); + } + + if (rightKeyCodes.includes(keyCode)) { + this.handleClickArrows(galleryImages, 'right'); + } + } + + if (keyCode === 27) { // esc + destroyGallery(); + } + } + onUpdateDimensions() { this.process(true); @@ -67,7 +110,7 @@ export default class CIResponsive { if (images.length > -1) { images.forEach((imgNode) => { - this.getBasicInfo(imgNode, isUpdate, windowScreenBecomesBigger, 'image'); + this.getBasicInfo(imgNode, isUpdate, windowScreenBecomesBigger, 'image', images); }); } @@ -78,7 +121,14 @@ export default class CIResponsive { } } - getBasicInfo = (imgNode, isUpdate, windowScreenBecomesBigger, type) => { + getBasicInfo = ( + imgNode, + isUpdate, + windowScreenBecomesBigger, + type, + images, + isGalleryImg, + ) => { const isImage = type === 'image'; const { config } = this; const { @@ -119,29 +169,257 @@ export default class CIResponsive { [src, isSVG] = getImgSRC(size.params.src, baseURL); } } - } else if (isUpdate && !windowScreenBecomesBigger) return; + } else if (isUpdate && !windowScreenBecomesBigger) { + getDimAndFit(imgNode); + + return; + } const containerProps = determineContainerProps({ ...imgProps, size, imgNode, config, }); const { width } = containerProps; - const isPreview = isLowQualityPreview(isAdaptive, width, isSVG, minLowQualityWidth); + const isPreview = !isGalleryImg && isLowQualityPreview(isAdaptive, width, isSVG, minLowQualityWidth); const generateURLbyDPR = (devicePixelRatio) => generateURL({ src, params, config, containerProps, devicePixelRatio, }); const cloudimageUrl = generateURLbyDPR(); const cloudimageSrcset = devicePixelRatioList.map((dpr) => ({ dpr: dpr.toString(), url: generateURLbyDPR(dpr) })); const props = { - imgNode, isUpdate, imgProps, lazy, isPreview, containerProps, isSVG, cloudimageUrl, src, preserveSize, isAdaptive, alt: alt || generateAlt(src), + imgNode, isUpdate, imgProps, lazy, isPreview, containerProps, isSVG, cloudimageUrl, src, preserveSize, isAdaptive, imgSelector, alt: alt || generateAlt(src), }; if (isImage) { - this.processImage({ ...props, cloudimageUrl: generateURLbyDPR(1), cloudimageSrcset }); + this.processImage({ + ...props, + cloudimageUrl: generateURLbyDPR(1), + cloudimageSrcset, + images, + isGalleryImg, + }); } else { this.processBackgroundImage(props); } }; + getImageIndex(currentIndex, direction, isLoaded = true) { + let nextIndex = currentIndex; + const [length, index] = getGalleryLengthAndIndex(); + const leftDirection = direction === 'left'; + + if (isLoaded) { + nextIndex = +index; + } + + if (leftDirection) { + nextIndex -= 1; + + if (nextIndex < 0) { // reached left-end + nextIndex = length - 1; + } + } else { + nextIndex += 1; + + if (nextIndex === length) { // reached right-end + nextIndex = 0; + } + } + + return nextIndex; + } + + handleClickArrows(galleryImages, direction) { + let index = 0; + index = this.getImageIndex(0, direction); + + const previewImage = galleryImages[index].previousSibling.firstChild; + const isLoaded = previewImage.classList.contains(CLASSNAMES.PREVIEW_LOADED); + + if (!isLoaded) { + index = this.getImageIndex(index, direction, false); + } + + this.processGalleryPreviewImage(galleryImages[index], index, direction); + setGalleryIndex(index); + } + + animatePreviewModule(previewModule, nextIndex, direction) { + const currentIndex = previewModule.getAttribute(ATTRIBUTES.ACTIVE_IMAGE_INDEX); + const leftDirection = direction === 'left'; + let transform = 1000; + let scale = 0.8; + + if (leftDirection || (!direction && nextIndex < currentIndex)) { + transform = -1000; + } + + const scaleAnimation = setInterval(() => { // Scale preview image + scale += 0.01; + + if (scale >= 1) { + clearInterval(scaleAnimation); + } + + previewModule.style.transform = `scale(${scale}) translate(${transform}px)`; + }, 10); + + const transformAnimation = setInterval(() => { // Transform preview image + if (leftDirection || (!direction && nextIndex < currentIndex)) { + transform += 20; + } else { + transform -= 20; + } + + if (transform === 0) { + clearInterval(transformAnimation); + } + + previewModule.style.transform = `scale(${scale}) translate(${transform}px)`; + }, 5); + } + + processZoomPreviewImage(imgNode) { + const _imgNode = imgNode.cloneNode(); + const adaptedImageNode = removeClassNames(_imgNode, loadedImageClassNames); + const previewModule = getGalleryPreviewModule(); + + adaptedImageNode.style = {}; + adaptedImageNode.setAttribute(ATTRIBUTES.PROCESSED_GALLERY, true); + previewModule.innerHTML = ''; + previewModule.appendChild(adaptedImageNode); + + this.getBasicInfo(adaptedImageNode, false, false, 'image', undefined, true); + } + + processGalleryPreviewImage(imgNode, imageIndex, direction, intial) { + const { imgSelector } = this.config; + const { imageName, alt } = getImageProps(imgNode, imgSelector); + const galleryModal = document.querySelector(`.${CLASSNAMES.GALLERY_MODAL}`); + const thumbnailsModule = galleryModal.querySelector(`.${CLASSNAMES.THUMBNAIL_MODULE}`); + const _imgNode = imgNode.cloneNode(); + const adaptedImageNode = removeClassNames(_imgNode, loadedImageClassNames); + const previewModule = getGalleryPreviewModule(); + const _imageName = imageName || alt || generateAlt(alt); + + updateOrCreateImageNameWrapper(_imageName, galleryModal); + toggleActiveThumbnail(galleryModal, imageIndex); + adaptedImageNode.style = {}; + adaptedImageNode.setAttribute(ATTRIBUTES.PROCESSED_GALLERY, true); + previewModule.setAttribute(ATTRIBUTES.ACTIVE_IMAGE_INDEX, imageIndex); + previewModule.innerHTML = ''; + previewModule.appendChild(adaptedImageNode); + + if (thumbnailsModule.scrollWidth > thumbnailsModule.clientWidth) { + thumbnailsModule.style.justifyContent = 'left'; + } + + if (!intial) { + this.animatePreviewModule(previewModule, imageIndex, direction); + } + + this.getBasicInfo(adaptedImageNode, false, false, 'image', undefined, true); + } + + handleClickThumbnail(galleryImages, event) { + const thumbnail = event.currentTarget; + const thumbnailIndex = thumbnail.getAttribute(ATTRIBUTES.GALLERY_INDEX); + const [, index] = getGalleryLengthAndIndex(); + + if (thumbnailIndex !== index) { + setGalleryIndex(thumbnailIndex); + this.processGalleryPreviewImage(galleryImages[thumbnailIndex], thumbnailIndex); + } + } + + createGallery(imgProps, images, event) { + const { + gallery, zoom, isProcessedByGallery, + } = imgProps; + if (isProcessedByGallery) return; + + const galleryImages = getGalleryImages(images, gallery); + + if (gallery && galleryImages) { + const { galleryConfigs } = this.config; + const { + thumbnails, arrowPrev, arrowNext, onOpen, onClickThumbnail, + } = galleryConfigs; + + if (typeof onOpen === 'function') { + onOpen(event); + } + + const clickedImage = event.currentTarget.lastChild; + const clickedImageIndex = galleryImages.indexOf(clickedImage); + const orderedImages = swapArrayPositions(galleryImages, clickedImageIndex, 0) + .filter((image) => image.classList.contains(CLASSNAMES.IMAGE_LOADED)); + const galleryModal = createGalleryModal(closeIconSvg, galleryConfigs, orderedImages.length, true); + + if (thumbnails && orderedImages.length > 1) { + const thumbnailsModule = createThmbnailsModule( + orderedImages, + galleryModal, + onClickThumbnail, + this.handleClickThumbnail.bind(this, orderedImages), + ); + + galleryModal.appendChild(thumbnailsModule); + } + + if (orderedImages.length > 1) { + const [leftArrow, rightArrow] = createGalleryArrows( + leftArrowSvg, + rightArrowSvg, + galleryConfigs, + this.handleClickArrows.bind(this, orderedImages), + ); + + if (arrowPrev) { + galleryModal.append(leftArrow); + } + + if (arrowNext) { + galleryModal.append(rightArrow); + } + + galleryModal.onkeydown = debounce(250, this.handleModalKeydown.bind(this, orderedImages)); + } + + document.body.appendChild(galleryModal); + + const [, orderedClickedImage] = getGalleryLengthAndIndex(); + + galleryModal.focus(); + this.processGalleryPreviewImage(orderedImages[orderedClickedImage], orderedClickedImage, undefined, true); + setGalleryIndex(orderedClickedImage); + } + + if (zoom && !gallery) { + const clickedImage = event.currentTarget.querySelector('img[ci-src]'); + const zoomImages = getZoomImages(images); + const clickedImageIndex = zoomImages.indexOf(clickedImage); + + const galleryModal = createGalleryModal(closeIconSvg); + const previewModule = galleryModal.querySelector(`.${CLASSNAMES.PREVIEW_MODULE}`); + + galleryModal.tabIndex = 0; + galleryModal.appendChild(previewModule); + galleryModal.onkeydown = debounce(50, this.handleModalKeydown.bind(this, undefined)); + + document.body.appendChild(galleryModal); + galleryModal.focus(); + this.processZoomPreviewImage(zoomImages[clickedImageIndex]); + } + } + + handleClickWrapper(imgProps, images, event) { + const { gallery, zoom, isProcessedByGallery } = imgProps; + + if ((gallery || zoom) && !isProcessedByGallery) { + this.createGallery(imgProps, images, event); + } + } + processImage(props) { const { imgNode, @@ -156,17 +434,30 @@ export default class CIResponsive { preserveSize, cloudimageSrcset, isAdaptive, + images, alt, + isGalleryImg, } = props; - const { params } = imgProps; + + const { + params, zoom, gallery, disableAnimation, isProcessedByGallery, + } = imgProps; const { width, ratio } = containerProps; const { config } = this; const { dataSrcAttr, placeholderBackground } = config; - const { wrapper, previewImgNode, previewWrapper } = applyOrUpdateWrapper( - { - isUpdate, imgNode, ratio, lazy, placeholderBackground, preserveSize, isPreview, ...imgProps, alt, - }, - ); + + const { wrapper, previewImgNode, previewWrapper } = applyOrUpdateWrapper({ + isUpdate, + imgNode, + ratio, + lazy, + placeholderBackground, + preserveSize, + isPreview, + isGalleryImg, + ...imgProps, + alt, + }); if (!isUpdate) { initImageClasses({ imgNode, lazy }); @@ -185,16 +476,41 @@ export default class CIResponsive { setSrc(previewImgNode, previewImgURL, 'data-src', lazy, src, isSVG, dataSrcAttr); previewImgNode.onload = () => { + addClass(previewImgNode, CLASSNAMES.PREVIEW_LOADED); onPreviewImageLoad(wrapper, previewImgNode, ratio, preserveSize); }; } } + getDimAndFit(imgNode); + + if ((gallery || zoom) && !isProcessedByGallery) { + wrapper.style.cursor = 'pointer'; + + if (gallery && !disableAnimation) { + addClass(wrapper, CLASSNAMES.GALLERY_ANIMATION); + } else if (zoom && !gallery) { + const zoomIcon = createIcon(zoomIconSvg, CLASSNAMES.ZOOM_BUTTON); + wrapper.append(zoomIcon); + } + } + imgNode.onload = () => { + const loader = document.querySelector(`.${CLASSNAMES.GALLERY_LOADER}`); + + if (loader) { + loader.parentElement.removeChild(loader); + } + if (config.onImageLoad && typeof config.onImageLoad === 'function') { config.onImageLoad(imgNode); } - onImageLoad(wrapper, previewImgNode, imgNode, ratio, preserveSize, isAdaptive); + + if (!isProcessedByGallery) { + onImageLoad(wrapper, previewImgNode, imgNode, ratio, preserveSize, isAdaptive); + } + + wrapper.onclick = this.handleClickWrapper.bind(this, imgProps, images); }; setSrcset(imgNode, cloudimageSrcset, 'data-srcset', lazy, src, isSVG, dataSrcAttr); @@ -211,7 +527,7 @@ export default class CIResponsive { const { dataSrcAttr } = config; if (!isUpdate) { - imgNode.setAttribute(processedAttr, true); + imgNode.setAttribute(ATTRIBUTES.PROCESSED, true); if (isPreview) { const previewImgURL = getPreviewSRC({ @@ -224,7 +540,7 @@ export default class CIResponsive { }); if (lazy) { - imgNode.setAttribute('ci-optimized-url', cloudimageUrl); + imgNode.setAttribute(ATTRIBUTES.OPTIMIZED_URL, cloudimageUrl); setBackgroundSrc(previewBox, previewImgURL, lazy, src, isSVG, dataSrcAttr); } else { @@ -253,7 +569,7 @@ export default class CIResponsive { } if (isImage) { - const isProcessed = node.classList.contains('ci-image'); + const isProcessed = node.classList.contains(CLASSNAMES.IMAGE); if (src) { node.setAttribute(imgSelector, src); @@ -267,7 +583,7 @@ export default class CIResponsive { } if (isBackground) { - const isProcessed = node.getAttribute(processedAttr); + const isProcessed = node.getAttribute(ATTRIBUTES.PROCESSED); const oldNode = node; if (src) { @@ -275,11 +591,11 @@ export default class CIResponsive { } if (isProcessed) { - const contentBox = node.querySelector(`[${bgContentAttr}]`); + const contentBox = node.querySelector(`[${ATTRIBUTES.BG_CONTAINER}]`); if (contentBox) { const contentBoxInner = contentBox.firstChild; - node.removeAttribute(processedAttr); + node.removeAttribute(ATTRIBUTES.PROCESSED); node.innerHTML = ''; node.appendChild(contentBoxInner); } else { diff --git a/src/low-preview/ci.styles.css b/src/low-preview/ci.styles.css index afbeb00..f8d8b7a 100644 --- a/src/low-preview/ci.styles.css +++ b/src/low-preview/ci.styles.css @@ -23,10 +23,6 @@ img.ci-image-loaded { opacity: 1; } -img.ci-image-ratio.ci-image-preview { - height: 100%; -} - .ci-bg { position: relative; } @@ -50,3 +46,246 @@ img.ci-image-ratio.ci-image-preview { .ci-bg.ci-bg-animation:before { filter: blur(10px); } + +.ci-gallery-modal { + display: block; + top: 0; + height: 100%; + width: 100%; + left: 0; + position: fixed; + visibility: visible; + opacity: 1; + background-color: rgba(1, 1, 1, 1); + text-align: center; + clear: both; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; + animation: slideVertical 400ms cubic-bezier(0.075, 0.42, 0.165, 1); + z-index: 200; +} + +.ci-gallery-modal:focus, +.ci-gallery-modal:focus-within { + outline: 0; +} + +.ci-gallery-preview-module { + height: 100%; + position: relative; +} + +.ci-gallery-preview-module img.ci-image { + display: block; + width: 100%; + height: 100%; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); +} + +.ci-gallery-preview-module img.ci-image-preview { + width: 100%; + height: 100%; +} + +.ci-gallery-preview-module img[ci-src] { + background-color: black; +} + +.ci-gallery-image-name { + position: absolute; + top: 15px; + left: 15px; + color: #FFF; + text-shadow: -1px -1px 0 #444, 1px -1px 0 #444, -1px 1px 0 #444, 1px 1px 0 #444; + padding: 0; + font-size: 1.2em; + max-width: 60vw; + text-overflow: ellipsis; + vertical-align: middle; + overflow: hidden; +} + +.ci-gallery-thumbnail-module { + margin: 0% 5%; + display: flex; + position: absolute; + align-items: center; + justify-content: center; + overflow: auto; + white-space: nowrap; + width: 90%; + height: fit-content; + bottom: 10px; + left: 0; + animation: slideHorizontal 400ms cubic-bezier(0.075, 0.42, 0.165, 1); +} + +.ci-gallery-thumbnail-module::-webkit-scrollbar { + height: 5px; +} + +.ci-gallery-thumbnail-module::-webkit-scrollbar-track { + background-color: rgb(129, 126, 126); + border-radius: 100px; +} + +.ci-gallery-thumbnail-module::-webkit-scrollbar-thumb { + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); + border-radius: 100px; +} + +.ci-gallery-thmbnail-container { + position: relative; + width: 40px; + height: 40px; + min-width: 40px; + min-height: 40px; + border: 1px solid #888; + background-color: black; + cursor: pointer; +} + +.ci-gallery-animation { + transition: transform 0.5s ease-in-out; +} + +.ci-gallery-animation:hover { + transform: scale(1.05); + z-index: 2; +} + +.ci-gallery-thmbnail-container img { + position: absolute; + top: 50%; + left: 50%; + height: auto; + transform: translate(-50%, -50%); +} + +.ci-gallery-thmbnail-container[data-active-thumbnail] { + border: 2px solid #FFF; + animation: borderFade 250ms ease-in-out; +} + +.ci-gallery-close-button { + width: 23px; + height: 23px; + top: 15px; + right: 15px; + border-radius: 50%; +} + +.ci-gallery-right-arrow-button { + width: 25px; + height: 25px; + top: 50%; + right: 15px; + border-radius: 50%; +} + +.ci-gallery-left-arrow-button { + width: 25px; + height: 25px; + top: 50%; + left: 15px; + border-radius: 50%; +} + +.ci-gallery-icon-button { + display: flex; + justify-content: center; + align-items: center; + position: absolute; + cursor: pointer; + z-index: 111; + background-color: rgba(255,255,255,0.5); +} + +.ci-gallery-close-button img, +.ci-gallery-right-arrow-button img, +.ci-gallery-left-arrow-button img { + width: 15px; + height: 15px; +} + +.ci-gallery-close-button:hover, +.ci-gallery-right-arrow-button:hover, +.ci-gallery-left-arrow-button:hover { + background-color: rgba(255,255,255,0.8); +} + +.ci-image-wrapper:hover > .ci-gallery-zoom-button { + transform: translateY(0); +} + +.ci-gallery-zoom-button { + width: 100%; + height: 100%; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + transform: translateY(1000px); + background-color: rgba(255, 255, 255, 0.5); + transition: transform 300ms ease-in-out; +} + +.ci-gallery-zoom-button img { + width: 35px; + height: 35px; +} + +.ci-gallery-loader { + border: 3px solid #3498db; + border-top: 3px solid white; + border-radius: 50%; + width: 30px; + height: 30px; + position: absolute; + top: 50%; + left: 50%; + animation: spin 2s linear infinite; + z-index: -1; +} + +@media (max-width: 400px){ + .ci-gallery-zoom-button img { + width: 15px; + height: 15px; + } +} + +@media (max-width: 600px){ + .ci-gallery-zoom-button img { + width: 25px; + height: 25px; + } +} + +@keyframes slideVertical { + 0% { transform: translateY(1000px); } + 100% { transform: translateY(0); } +} + +@keyframes slideHorizontal { + 0% { transform: translateX(-2000px); } + 100% { transform: translateX(0); } +} + +@keyframes borderFade { + 0% { border: 2px solid transparent } + 0% { transform: 2px solid #FFF } +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/src/low-preview/ci.utis.js b/src/low-preview/ci.utis.js index 7ae57e3..4033883 100644 --- a/src/low-preview/ci.utis.js +++ b/src/low-preview/ci.utis.js @@ -1,4 +1,4 @@ -import { bgContentAttr } from '../common/ci.constants'; +import { ATTRIBUTES } from '../common/ci.constants'; import { addClass, getWrapper } from '../common/ci.utils'; @@ -39,10 +39,10 @@ export const applyBackgroundStyles = ({ imgNode.style.position = 'relative'; contentBox.style.position = 'relative'; - contentBox.setAttribute(bgContentAttr, true); + contentBox.setAttribute(ATTRIBUTES.BG_CONTAINER, true); previewBox.className = `${imgNode.className}${lazy ? ' lazyload' : ''}`; - previewBox.setAttribute('ci-preview', true); + previewBox.setAttribute(ATTRIBUTES.PREVIEW, true); previewBox.style.background = 'inherit'; previewBox.style.position = 'absolute'; previewBox.style.left = '0'; @@ -150,13 +150,14 @@ export const onLazyBeforeUnveil = (event) => { export const wrapImage = (props) => { const { - imgNode, ratio, imgNodeWidth, imgNodeHeight, preserveSize, placeholderBackground, + imgNode, ratio, imgNodeWidth, imgNodeHeight, preserveSize, placeholderBackground, isGalleryImg, } = props; let { wrapper } = props; wrapper = wrapper || document.createElement('div'); addClass(wrapper, 'ci-image-wrapper'); + wrapper.style.background = placeholderBackground; wrapper.style.display = 'block'; wrapper.style.width = preserveSize ? imgNodeWidth : '100%'; @@ -164,7 +165,10 @@ export const wrapImage = (props) => { wrapper.style.overflow = 'hidden'; wrapper.style.position = 'relative'; - if (ratio) { + if (isGalleryImg) { + wrapper.style.height = '100%'; + wrapper.style.background = ''; + } else if (ratio) { wrapper.style.paddingBottom = preserveSize ? 'none' : `${100 / ratio}%`; } diff --git a/src/low-preview/gallery.utils.js b/src/low-preview/gallery.utils.js new file mode 100644 index 0000000..fd219a6 --- /dev/null +++ b/src/low-preview/gallery.utils.js @@ -0,0 +1,293 @@ +import { getCommonImageProps, addClass } from '../common/ci.utils'; +import { ATTRIBUTES, CLASSNAMES } from '../common/ci.constants'; + + +const createIcon = (iconSrc, className) => { + const iconWrapper = document.createElement('div'); + + const icon = new Image(); + icon.src = iconSrc; + + iconWrapper.classList.add(className, CLASSNAMES.GALLERY_ICON_BUTTON); + + iconWrapper.appendChild(icon); + + return iconWrapper; +}; + +const destroyGallery = (onClose, event) => { + if (typeof onClose === 'function') { + onClose(event); + } + + const galleryModal = document.querySelector(`.${CLASSNAMES.GALLERY_MODAL}`); + + if (galleryModal) { + galleryModal.parentElement.removeChild(galleryModal); + } +}; + +const createGalleryModal = (closeIconSrc, galleryConfigs, galleryLength, isGallery) => { + const galleryModal = document.createElement('div'); + const previewModule = document.createElement('div'); + const loader = document.createElement('div'); + + galleryModal.tabIndex = 0; + addClass(galleryModal, CLASSNAMES.GALLERY_MODAL); + addClass(previewModule, CLASSNAMES.PREVIEW_MODULE); + galleryModal.setAttribute(ATTRIBUTES.GALLERY, true); + addClass(loader, CLASSNAMES.GALLERY_LOADER); + galleryModal.append(previewModule); + galleryModal.append(loader); + + if (isGallery) { + const { + modalClassName, previewClassName, thumbnailsClassName, closeIcon, close, onClose, + } = galleryConfigs; + + const thumbnailsModule = document.createElement('div'); + + if (close) { + let _closeIcon = closeIcon || closeIconSrc; + + if (typeof _closeIcon === 'string') { + _closeIcon = createIcon(_closeIcon, CLASSNAMES.CLOSE_BUTTON); + } + + _closeIcon.onclick = destroyGallery.bind(this, onClose); + galleryModal.append(_closeIcon); + } + + addClass(galleryModal, modalClassName); + addClass(previewModule, previewClassName); + addClass(thumbnailsModule, CLASSNAMES.THUMBNAIL_MODULE); + addClass(thumbnailsModule, thumbnailsClassName); + + galleryModal.setAttribute(ATTRIBUTES.GALLERY_LENGTH, galleryLength); + galleryModal.setAttribute(ATTRIBUTES.GALLERY_INDEX, 0); + galleryModal.append(thumbnailsModule); + } else { + const closeIcon = createIcon(closeIconSrc, CLASSNAMES.CLOSE_BUTTON); + closeIcon.onclick = destroyGallery.bind(this); + galleryModal.append(closeIcon); + } + + return galleryModal; +}; + +const createImageNameWrapper = (imageName, galleryModal) => { + const imageNameContainer = document.createElement('p'); + + imageNameContainer.innerHTML = imageName; + addClass(imageNameContainer, CLASSNAMES.IMAGE_NAME); + + galleryModal.appendChild(imageNameContainer); +}; + +const updateOrCreateImageNameWrapper = (imageName, galleryModal) => { + const imageNameContainer = galleryModal.querySelector(`.${CLASSNAMES.IMAGE_NAME}`); + + if (imageNameContainer) { + imageNameContainer.innerHTML = imageName; + } else { + createImageNameWrapper(imageName, galleryModal); + } +}; + +const toggleActiveThumbnail = (galleryModal, imageIndex) => { + const thumbnailsModule = galleryModal.querySelector(`.${CLASSNAMES.THUMBNAIL_MODULE}`); + + [...thumbnailsModule.children].forEach((thumbnailContainer) => { + thumbnailContainer.removeAttribute(ATTRIBUTES.ACTIVE_THUMBNAIL); + const thumbnailContainerIndex = thumbnailContainer.getAttribute(ATTRIBUTES.GALLERY_INDEX); + + if (+imageIndex === +thumbnailContainerIndex) { + thumbnailContainer.setAttribute(ATTRIBUTES.ACTIVE_THUMBNAIL, true); + thumbnailContainer.scrollIntoView({ + behavior: 'smooth', + }); + } + }); +}; + +const getGalleryPreviewModule = () => { + const galleryModal = document.body.querySelector(`[${ATTRIBUTES.GALLERY}]`); + + return galleryModal.querySelector(`.${CLASSNAMES.PREVIEW_MODULE}`); +}; + +const setGalleryIndex = (index) => { + const galleryModal = document.body.querySelector(`[${ATTRIBUTES.GALLERY}]`); + + galleryModal.setAttribute(ATTRIBUTES.GALLERY_INDEX, index); +}; + +const createGalleryArrows = (leftArrowIcon, rightArrowIcon, galleryConfigs, onClick) => { + const { + arrowPrevIcon, arrowNextIcon, onPrev, onNext, + } = galleryConfigs; + + let leftArrow = arrowPrevIcon || leftArrowIcon; + if (typeof leftArrow === 'string') { + leftArrow = createIcon(leftArrow, CLASSNAMES.LEFT_ARROW_BUTTON); + } + + let rightArrow = arrowNextIcon || rightArrowIcon; + if (typeof rightArrow === 'string') { + rightArrow = createIcon(rightArrow, CLASSNAMES.RIGHT_ARROW_BUTTON); + } + + + if (onClick) { + leftArrow.onclick = onClick.bind(this, 'left'); + rightArrow.onclick = onClick.bind(this, 'right'); + } + + if (typeof onPrev === 'function') { + leftArrow.onclick = onPrev.bind(this); + } + + if (typeof onNext === 'function') { + rightArrow.onclick = onNext.bind(this); + } + + return [leftArrow, rightArrow]; +}; + +const getGalleryLengthAndIndex = () => { + const galleryModal = document.body.querySelector(`[${ATTRIBUTES.GALLERY}]`); + const galleryLength = galleryModal.getAttribute(ATTRIBUTES.GALLERY_LENGTH); + const galleryIndex = galleryModal.getAttribute(ATTRIBUTES.GALLERY_INDEX); + + return [+galleryLength, galleryIndex]; +}; + +const swapArrayPositions = (array = [], a = 0, b = 0) => { + const clonedArray = [...array]; + if (clonedArray[a] && clonedArray[b]) { + [clonedArray[a], clonedArray[b]] = [clonedArray[b], clonedArray[a]]; + } + + return clonedArray; +}; + +const getImageFitStyles = (naturalWidth, naturalHeight) => { + let shouldFitHorizontally; + const imageStyles = {}; + const previewModule = document.body.querySelector(`.${CLASSNAMES.PREVIEW_MODULE}`); + + if (naturalWidth && previewModule) { + const imageAspectRatio = naturalWidth / naturalHeight; + const renderWidth = previewModule.offsetHeight * imageAspectRatio; + shouldFitHorizontally = (imageAspectRatio >= 1) + && (renderWidth < previewModule.offsetWidth); + } + + if (shouldFitHorizontally) { + imageStyles.width = 'auto'; + imageStyles.height = '100%'; + } else { + imageStyles.width = '100%'; + imageStyles.height = 'auto'; + } + + return imageStyles; +}; + +const adaptGalleryThumbnails = (images = [], onClickThumbnail, onClick) => { + const lowPreviewImages = images.map((image) => ( + image.previousSibling ? image.previousSibling.firstChild : image + )); + + return lowPreviewImages.map((thumbnail, index) => { + const thmbnailContainer = document.createElement('div'); + const imageFitStyles = getImageFitStyles(thumbnail.naturalWidth, thumbnail.naturalHeight); + const image = thumbnail.cloneNode(); + + image.classList.remove(CLASSNAMES.IMAGE); + image.style = {}; + image.style.width = imageFitStyles.width; + image.style.height = imageFitStyles.height; + + addClass(thmbnailContainer, CLASSNAMES.THUMBNAIL_CONTAINER); + thmbnailContainer.setAttribute(ATTRIBUTES.GALLERY_INDEX, index); + thmbnailContainer.append(image); + + if (onClick) { + thmbnailContainer.onclick = onClick; + } + + if (typeof onClickThumbnail === 'function') { + thmbnailContainer.onclick = onClickThumbnail.bind(this); + } + + return thmbnailContainer; + }); +}; + +const appendGalleryThumbnails = (thumbnails = [], thumbnailsContainer) => { + thumbnails.forEach((thumbnail) => { + thumbnailsContainer.append(thumbnail); + }); +}; + +const createThmbnailsModule = (images, galleryModal, onClickThumbnail, onClick) => { + const thumbnailsModule = galleryModal.querySelector(`.${CLASSNAMES.THUMBNAIL_MODULE}`); + const adaptedGalleryThumbnails = adaptGalleryThumbnails(images, onClickThumbnail, onClick); + + appendGalleryThumbnails(adaptedGalleryThumbnails, thumbnailsModule); + + return thumbnailsModule; +}; + +const getGalleryImages = (images, galleryName) => [...images].filter((image) => { + const { gallery } = getCommonImageProps(image); + + return gallery === galleryName; +}); + +const getZoomImages = (images) => [...images].filter((image) => { + const { zoom } = getCommonImageProps(image); + + return zoom; +}); + +const galleryPreviewImage = (imgSelector, imgNodeSRC) => { + const image = new Image(); + + image.setAttribute(imgSelector, imgNodeSRC); + + return image; +}; + +const getDimAndFit = (imgNode) => { + const dimInterval = setInterval(() => { + if (imgNode.naturalWidth) { + clearInterval(dimInterval); + const imageFitStyles = getImageFitStyles(imgNode.naturalWidth, imgNode.naturalHeight); + + imgNode.style.width = imageFitStyles.width; + imgNode.style.height = imageFitStyles.height; + imgNode.style.opacity = 1; + } + }, 10); +}; + +export { + createIcon, + createGalleryModal, + destroyGallery, + updateOrCreateImageNameWrapper, + getGalleryPreviewModule, + setGalleryIndex, + createGalleryArrows, + getGalleryLengthAndIndex, + createThmbnailsModule, + getGalleryImages, + getZoomImages, + getImageFitStyles, + galleryPreviewImage, + getDimAndFit, + swapArrayPositions, + toggleActiveThumbnail, +}; diff --git a/src/plain/ci.service.js b/src/plain/ci.service.js index 5f0ed40..e23defd 100644 --- a/src/plain/ci.service.js +++ b/src/plain/ci.service.js @@ -21,7 +21,7 @@ import { setSrc, setSrcset, } from '../common/ci.utils'; -import { loadedImageClassNames, processedAttr } from '../common/ci.constants'; +import { loadedImageClassNames, ATTRIBUTES } from '../common/ci.constants'; export default class CIResponsive { @@ -175,7 +175,7 @@ export default class CIResponsive { if (!isUpdate) { imgNode.className = `${imgNode.className}${lazy ? ' lazyload' : ''}`; - imgNode.setAttribute(processedAttr, true); + imgNode.setAttribute(ATTRIBUTES.PROCESSED, true); } setBackgroundSrc(imgNode, cloudimageUrl, lazy, src, isSVG, dataSrcAttr); @@ -208,7 +208,7 @@ export default class CIResponsive { } if (isBackground) { - const isProcessed = node.getAttribute(processedAttr); + const isProcessed = node.getAttribute(ATTRIBUTES.PROCESSED); if (src) { node.setAttribute(bgSelector, src); diff --git a/src/public/close-icon.svg b/src/public/close-icon.svg new file mode 100644 index 0000000..093b80a --- /dev/null +++ b/src/public/close-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/left-arrow-icon.svg b/src/public/left-arrow-icon.svg new file mode 100644 index 0000000..b6ba7c7 --- /dev/null +++ b/src/public/left-arrow-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/right-arrow-icon.svg b/src/public/right-arrow-icon.svg new file mode 100644 index 0000000..4bccdcc --- /dev/null +++ b/src/public/right-arrow-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/zoom-icon.svg b/src/public/zoom-icon.svg new file mode 100644 index 0000000..c8f2eab --- /dev/null +++ b/src/public/zoom-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index ad12d26..c66e653 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,37 +34,37 @@ "@babel/highlight" "^7.18.6" "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" - integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.13.tgz#6aff7b350a1e8c3e40b029e46cbe78e24a913483" + integrity sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw== "@babel/core@^7.0.0": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" - integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.13.tgz#9be8c44512751b05094a4d3ab05fc53a47ce00ac" + integrity sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.10" + "@babel/generator" "^7.18.13" "@babel/helper-compilation-targets" "^7.18.9" "@babel/helper-module-transforms" "^7.18.9" "@babel/helpers" "^7.18.9" - "@babel/parser" "^7.18.10" + "@babel/parser" "^7.18.13" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.18.10" - "@babel/types" "^7.18.10" + "@babel/traverse" "^7.18.13" + "@babel/types" "^7.18.13" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.18.10": - version "7.18.12" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4" - integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg== +"@babel/generator@^7.18.13": + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.13.tgz#59550cbb9ae79b8def15587bdfbaa388c4abf212" + integrity sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ== dependencies: - "@babel/types" "^7.18.10" + "@babel/types" "^7.18.13" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -94,9 +94,9 @@ semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" - integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.13.tgz#63e771187bd06d234f95fdf8bd5f8b6429de6298" + integrity sha512-hDvXp+QYxSRL+23mpAlSGxHMDyIGChm0/AwTfTAAK5Ufe40nCsyNdaYCGuK91phn/fVu9kqayImRDkvNAgdrsA== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" @@ -278,10 +278,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.18.10", "@babel/parser@^7.18.11": - version "7.18.11" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" - integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== +"@babel/parser@^7.18.10", "@babel/parser@^7.18.13": + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4" + integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -641,9 +641,9 @@ "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-destructuring@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" - integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" + integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== dependencies: "@babel/helper-plugin-utils" "^7.18.9" @@ -949,26 +949,26 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.11", "@babel/traverse@^7.18.9": - version "7.18.11" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f" - integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ== +"@babel/traverse@^7.18.11", "@babel/traverse@^7.18.13", "@babel/traverse@^7.18.9": + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.13.tgz#5ab59ef51a997b3f10c4587d648b9696b6cb1a68" + integrity sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.10" + "@babel/generator" "^7.18.13" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.18.9" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.11" - "@babel/types" "^7.18.10" + "@babel/parser" "^7.18.13" + "@babel/types" "^7.18.13" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.4.4": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" - integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== +"@babel/types@^7.18.10", "@babel/types@^7.18.13", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.4.4": + version "7.18.13" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.13.tgz#30aeb9e514f4100f7c1cb6e5ba472b30e48f519a" + integrity sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ== dependencies: "@babel/helper-string-parser" "^7.18.10" "@babel/helper-validator-identifier" "^7.18.6" @@ -979,14 +979,14 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@eslint/eslintrc@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d" + integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" + espree "^9.4.0" globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1013,6 +1013,11 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -1058,10 +1063,10 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.14" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" - integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -1152,9 +1157,9 @@ "@types/estree" "*" "@types/eslint@*": - version "8.4.5" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.5.tgz#acdfb7dd36b91cc5d812d7c093811a8f3d9b31e4" - integrity sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ== + version "8.4.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" + integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1216,9 +1221,9 @@ integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== "@types/node@*": - version "18.6.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39" - integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg== + version "18.7.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.14.tgz#0fe081752a3333392d00586d815485a17c2cf3c9" + integrity sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA== "@types/q@^1.5.1": version "1.5.5" @@ -1950,9 +1955,9 @@ body-parser@1.20.0: unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.0.13" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" - integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== + version "1.0.14" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" + integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== dependencies: array-flatten "^2.1.2" dns-equal "^1.0.0" @@ -2105,9 +2110,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370: - version "1.0.30001374" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz#3dab138e3f5485ba2e74bd13eca7fe1037ce6f57" - integrity sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw== + version "1.0.30001388" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001388.tgz#88e01f4591cbd81f9f665f3f078c66b509fbe55d" + integrity sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ== chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" @@ -2377,17 +2382,17 @@ copy-concurrently@^1.0.0: run-queue "^1.0.0" core-js-compat@^3.21.0, core-js-compat@^3.22.1: - version "3.24.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.1.tgz#d1af84a17e18dfdd401ee39da9996f9a7ba887de" - integrity sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw== + version "3.25.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.0.tgz#489affbfbf9cb3fa56192fe2dd9ebaee985a66c5" + integrity sha512-extKQM0g8/3GjFx9US12FAgx8KJawB7RCQ5y8ipYLbmfzEzmFRWdDjIlxDx82g7ygcNG85qMVUSRyABouELdow== dependencies: browserslist "^4.21.3" semver "7.0.0" core-js@^3.15.2: - version "3.24.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f" - integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== + version "3.25.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.0.tgz#be71d9e0dd648ffd70c44a7ec2319d039357eceb" + integrity sha512-CVU1xvJEfJGhyCpBrzzzU1kjCfgsGUxhEvwUV2e/cOedYWHdmluamx+knDnmhqALddMG16fZvIqvs9aijsHHaA== core-util-is@~1.0.0: version "1.0.3" @@ -2783,9 +2788,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.202: - version "1.4.211" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.211.tgz#afaa8b58313807501312d598d99b953568d60f91" - integrity sha512-BZSbMpyFQU0KBJ1JG26XGeFI3i4op+qOYGxftmZXFZoHkhLgsSv4DHDJfl8ogII3hIuzGt51PaZ195OVu0yJ9A== + version "1.4.241" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.241.tgz#5aa03ab94db590d8269f4518157c24b1efad34d6" + integrity sha512-e7Wsh4ilaioBZ5bMm6+F4V5c11dh56/5Jwz7Hl5Tu1J7cnB+Pqx5qIF2iC7HPpfyQMqGSvvLP5bBAIDd2gAtGw== email-addresses@^3.0.1: version "3.1.0" @@ -2847,15 +2852,15 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" - integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + version "1.20.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3" + integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.1" + get-intrinsic "^1.1.2" get-symbol-description "^1.0.0" has "^1.0.3" has-property-descriptors "^1.0.0" @@ -2867,9 +2872,9 @@ es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19 is-shared-array-buffer "^1.0.2" is-string "^1.0.7" is-weakref "^1.0.2" - object-inspect "^1.12.0" + object-inspect "^1.12.2" object-keys "^1.1.1" - object.assign "^4.1.2" + object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" string.prototype.trimend "^1.0.5" string.prototype.trimstart "^1.0.5" @@ -2999,13 +3004,14 @@ eslint-visitor-keys@^3.3.0: integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== "eslint@^7.32.0 || ^8.2.0": - version "8.22.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48" - integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA== + version "8.23.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040" + integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA== dependencies: - "@eslint/eslintrc" "^1.3.0" + "@eslint/eslintrc" "^1.3.1" "@humanwhocodes/config-array" "^0.10.4" "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -3015,7 +3021,7 @@ eslint-visitor-keys@^3.3.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.3" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -3041,12 +3047,11 @@ eslint-visitor-keys@^3.3.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2, espree@^9.3.3: - version "9.3.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" - integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: acorn "^8.8.0" acorn-jsx "^5.3.2" @@ -3237,6 +3242,14 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + filename-reserved-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" @@ -3440,7 +3453,7 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== @@ -4576,7 +4589,7 @@ object-assign@^4.0.1, object-assign@^4.1.0: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.12.0, object-inspect@^1.9.0: +object-inspect@^1.12.2, object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== @@ -4586,10 +4599,10 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.0, object.assign@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f" - integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA== +object.assign@^4.1.0, object.assign@^4.1.2, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" @@ -5995,20 +6008,20 @@ tar@^6.0.2: yallist "^4.0.0" terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" - integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + version "5.3.6" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" + integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.14" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.0" - terser "^5.7.2" + terser "^5.14.1" -terser@^5.10.0, terser@^5.7.2: - version "5.14.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" - integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== +terser@^5.10.0, terser@^5.14.1: + version "5.15.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" + integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -6118,9 +6131,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== uglify-js@^3.6.0: - version "3.16.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d" - integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw== + version "3.17.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85" + integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg== uglifyjs-webpack-plugin@^2.2.0: version "2.2.0" @@ -6210,9 +6223,9 @@ unquote@~1.1.1: integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + version "1.0.7" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz#16279639cff1d0f800b14792de43d97df2d11b7d" + integrity sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -6254,11 +6267,6 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -6326,9 +6334,9 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-server@^4.9.3: - version "4.9.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" - integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== + version "4.10.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.10.1.tgz#124ac9ac261e75303d74d95ab6712b4aec3e12ed" + integrity sha512-FIzMq3jbBarz3ld9l7rbM7m6Rj1lOsgq/DyLGMX/fPEB1UBUPtf5iL/4eNfhx8YYJTRlzfv107UfWSWcBK5Odw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5"