photos/js/photos-src_mixins_FetchFile...

1 line
49 KiB
XML

{"version":3,"file":"photos-src_mixins_FetchFilesMixin_js-src_components_Faces_FaceMergeForm_vue.js?v=fd0d2fa58a4cc5054fa0","mappings":"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","sources":["webpack:///photos/src/mixins/FaceCoverMixin.js","webpack:///photos/src/mixins/FetchFacesMixin.js","webpack:///photos/src/mixins/FetchFilesMixin.js","webpack:///photos/src/services/PhotoSearch.js","webpack:///photos/src/components/Faces/FaceCover.vue?vue&type=style&index=0&id=5cb97458&prod&lang=scss&scoped=true","webpack:///photos/src/components/Faces/FaceMergeForm.vue?vue&type=style&index=0&id=33326436&prod&scoped=true&lang=scss","webpack://photos/./src/components/Faces/FaceCover.vue?076a","webpack:///photos/src/components/Faces/FaceCover.vue","webpack:///photos/src/components/Faces/FaceCover.vue?vue&type=script&lang=js","webpack://photos/./src/components/Faces/FaceCover.vue?77ea","webpack://photos/./src/components/Faces/FaceCover.vue?eba5","webpack://photos/./src/components/Faces/FaceMergeForm.vue?d2e1","webpack:///photos/src/components/Faces/FaceMergeForm.vue","webpack:///photos/src/components/Faces/FaceMergeForm.vue?vue&type=script&lang=js","webpack://photos/./src/components/Faces/FaceMergeForm.vue?241f","webpack://photos/./src/components/Faces/FaceMergeForm.vue?2513"],"sourcesContent":["/**\n * @copyright Copyright (c) 2022 Marcel Klehr <mklehr@gmx.net>\n *\n * @author Marcel Klehr <mklehr@gmx.net>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { mapGetters } from 'vuex'\nimport he from 'he'\n\nexport default {\n\tname: 'FaceCoverMixin',\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'faces',\n\t\t\t'facesFiles',\n\t\t\t'files',\n\t\t]),\n\t},\n\n\tmethods: {\n\t\tgetFaceCover(faceName) {\n\t\t\treturn JSON.parse(he.decode(this.faces[faceName].props['face-preview-image'] || '{}'))\n\t\t},\n\n\t\t/**\n\t\t * This will produce an inline style to apply to images\n\t\t * to zoom toward the detected face\n\t\t *\n\t\t * @param faceName\n\t\t * @return {{}|{transform: string, width: string, transformOrigin: string}}\n\t\t */\n\t\tgetCoverStyle(faceName) {\n\t\t\tconst cover = this.getFaceCover(faceName)\n\t\t\tif (!cover || !cover.detection) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst detection = cover.detection\n\n\t\t\t// Zoom into the picture so that the face fills the --photos-face-width box nicely\n\t\t\t// if the face is larger than the image, we don't zoom out (reason for the Math.max)\n\t\t\tconst zoom = Math.max(1, (1 / detection.width) * 0.4)\n\n\t\t\tconst horizontalCenterOfFace = (detection.x + detection.width / 2) * 100\n\t\t\tconst verticalCenterOfFace = (detection.y + detection.height / 2) * 100\n\n\t\t\treturn {\n\t\t\t\t// We assume that the image is inside a div with width: var(--photos-face-width)\n\t\t\t\twidth: '100%',\n\t\t\t\t// we translate the image so that the center of the detected face is in the center of the --photos-face-width box\n\t\t\t\t// and add the zoom\n\t\t\t\ttransform: `translate(calc( var(--photos-face-width)/2 - ${horizontalCenterOfFace}% ), calc( var(--photos-face-width)/2 - ${verticalCenterOfFace}% )) scale(${zoom})`,\n\t\t\t\t// this is necessary for the zoom to zoom toward the center of the face\n\t\t\t\ttransformOrigin: `${horizontalCenterOfFace}% ${verticalCenterOfFace}%`,\n\t\t\t}\n\t\t},\n\t},\n}\n","/**\n * @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { mapActions, mapGetters } from 'vuex'\n\nimport { showError } from '@nextcloud/dialogs'\nimport { getCurrentUser } from '@nextcloud/auth'\n\nimport client from '../services/DavClient.js'\nimport logger from '../services/logger.js'\nimport DavRequest from '../services/DavRequest.js'\nimport { genFileInfo } from '../utils/fileUtils.js'\nimport AbortControllerMixin from './AbortControllerMixin.js'\nimport he from 'he'\n\nexport default {\n\tname: 'FetchFacesMixin',\n\n\tdata() {\n\t\treturn {\n\t\t\terrorFetchingFaces: null,\n\t\t\tloadingFaces: false,\n\t\t\terrorFetchingFiles: null,\n\t\t\tloadingFiles: false,\n\t\t}\n\t},\n\n\tmixins: [\n\t\tAbortControllerMixin,\n\t],\n\n\tasync beforeMount() {\n\t\tthis.fetchFaces()\n\t},\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'faces',\n\t\t]),\n\t},\n\n\tmethods: {\n\t\t...mapActions([\n\t\t\t'appendFiles',\n\t\t]),\n\n\t\tasync fetchFaces() {\n\t\t\tif (this.loadingFaces) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (Object.keys(this.faces).length) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.loadingFaces = true\n\t\t\t\tthis.errorFetchingFaces = null\n\n\t\t\t\tconst { data: faces } = await client.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {\n\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\tdetails: true,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t})\n\t\t\t\tthis.$store.dispatch('addFaces', { faces })\n\t\t\t\tlogger.debug(`[FetchFacesMixin] Fetched ${faces.length} new faces: `, faces)\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response && error.response.status) {\n\t\t\t\t\tif (error.response.status === 404) {\n\t\t\t\t\t\tthis.errorFetchingFaces = 404\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.errorFetchingFaces = error\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlogger.error(t('photos', 'Failed to fetch faces list.'), { error })\n\t\t\t\tshowError(t('photos', 'Failed to fetch faces list.'))\n\t\t\t} finally {\n\t\t\t\tthis.loadingFaces = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchFaceContent(faceName, force) {\n\t\t\tif (this.loadingFiles) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!force && this.facesFiles[faceName] && this.facesFiles[faceName].length) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.errorFetchingFiles = null\n\t\t\t\tthis.loadingFiles = true\n\n\t\t\t\tlet { data: fetchedFiles } = await client.getDirectoryContents(\n\t\t\t\t\t`/recognize/${getCurrentUser()?.uid}/faces/${faceName}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\t\tdetails: true,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tfetchedFiles = fetchedFiles\n\t\t\t\t\t.map(file => genFileInfo(file))\n\t\t\t\t\t.map(file => ({ ...file, filename: he.decode(file.realpath).replace(`/${getCurrentUser().uid}/files`, `/files/${getCurrentUser().uid}`) }))\n\t\t\t\t\t.map(file => ({ ...file, faceDetections: JSON.parse(he.decode(file.faceDetections)) }))\n\n\t\t\t\tconst fileIds = fetchedFiles.map(file => '' + file.fileid)\n\n\t\t\t\tthis.appendFiles(fetchedFiles)\n\n\t\t\t\tif (fetchedFiles.length > 0) {\n\t\t\t\t\tawait this.$store.commit('addFilesToFace', { faceName, fileIdsToAdd: fileIds })\n\t\t\t\t}\n\n\t\t\t\tlogger.debug(`[FetchFacesMixin] Fetched ${fileIds.length} new files: `, fileIds)\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response && error.response.status) {\n\t\t\t\t\tif (error.response.status === 404) {\n\t\t\t\t\t\tthis.errorFetchingFiles = 404\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.errorFetchingFiles = error\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// cancelled request, moving on...\n\t\t\t\tlogger.error('Error fetching face files', { error })\n\t\t\t} finally {\n\t\t\t\tthis.loadingFiles = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchUnassignedFaces(force) {\n\t\t\tif (this.loadingFiles) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!force && this.unassignedFiles && this.unassignedFiles.length) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.errorFetchingFiles = null\n\t\t\t\tthis.loadingFiles = true\n\n\t\t\t\tlet { data: fetchedFiles } = await client.getDirectoryContents(\n\t\t\t\t\t`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\t\tdetails: true,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tfetchedFiles = fetchedFiles\n\t\t\t\t\t.map(file => genFileInfo(file))\n\t\t\t\t\t.map(file => ({ ...file, filename: he.decode(file.realpath).replace(`/${getCurrentUser().uid}/files`, `/files/${getCurrentUser().uid}`) }))\n\t\t\t\t\t.map(file => ({ ...file, faceDetections: JSON.parse(he.decode(file.faceDetections)) }))\n\n\t\t\t\tconst fileIds = fetchedFiles.map(file => '' + file.fileid)\n\n\t\t\t\tthis.appendFiles(fetchedFiles)\n\n\t\t\t\tif (fetchedFiles.length > 0) {\n\t\t\t\t\tawait this.$store.commit('addUnassignedFiles', { fileIdsToAdd: fileIds })\n\t\t\t\t}\n\n\t\t\t\tlogger.debug(`[FetchFacesMixin] Fetched ${fileIds.length} new unassigned files: `, fileIds)\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response && error.response.status) {\n\t\t\t\t\tif (error.response.status === 404) {\n\t\t\t\t\t\tthis.errorFetchingFiles = 404\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.errorFetchingFiles = error\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// cancelled request, moving on...\n\t\t\t\tlogger.error('Error fetching unassigned files', { error })\n\t\t\t} finally {\n\t\t\t\tthis.loadingFiles = false\n\t\t\t}\n\t\t},\n\n\t\tasync fetchUnassignedFacesCount() {\n\t\t\ttry {\n\t\t\t\tconst { data: unassignedFacesRoot } = await client.stat(\n\t\t\t\t\t`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,\n\t\t\t\t\t{\n\t\t\t\t\t\tdata: DavRequest,\n\t\t\t\t\t\tdetails: true,\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst count = Number(unassignedFacesRoot.props.nbItems)\n\n\t\t\t\tawait this.$store.commit('setUnassignedFilesCount', count)\n\n\t\t\t\tlogger.debug('[FetchFacesMixin] Fetched unassigned files count: ', count)\n\t\t\t} catch (error) {\n\t\t\t\t// cancelled request, moving on...\n\t\t\t\tlogger.error('Error fetching unassigned files count', { error })\n\t\t\t}\n\t\t},\n\t},\n}\n","/**\n * @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport logger from '../services/logger.js'\nimport getPhotos from '../services/PhotoSearch.js'\nimport SemaphoreWithPriority from '../utils/semaphoreWithPriority.js'\nimport AbortControllerMixin from './AbortControllerMixin.js'\n\nexport default {\n\tname: 'FetchFilesMixin',\n\n\tmixins: [\n\t\tAbortControllerMixin,\n\t],\n\n\tdata() {\n\t\treturn {\n\t\t\terrorFetchingFiles: null,\n\t\t\tloadingFiles: false,\n\t\t\tdoneFetchingFiles: false,\n\t\t\tfetchSemaphore: new SemaphoreWithPriority(1),\n\t\t\tfetchedFileIds: [],\n\t\t}\n\t},\n\n\twatch: {\n\t\t$route() {\n\t\t\tthis.resetFetchFilesState()\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * @param {string} path - Path to pass to getPhotos.\n\t\t * @param {object} options - Options to pass to getPhotos.\n\t\t * @param {string[]} [blacklist=[]] - Array of ids to filter out.\n\t\t * @param {boolean} [force=false] - Force fetching even if doneFetchingFiles is true\n\t\t * @return {Promise<string[]>} - The next batch of data depending on global offset.\n\t\t */\n\t\tasync fetchFiles(path = '', options = {}, blacklist = [], force = false) {\n\t\t\tif ((this.doneFetchingFiles && !force) || this.loadingFiles) {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\tconst fetchSemaphoreSymbol = await this.fetchSemaphore.acquire()\n\n\t\t\ttry {\n\t\t\t\tthis.errorFetchingFiles = null\n\t\t\t\tthis.loadingFiles = true\n\n\t\t\t\tconst numberOfImagesPerBatch = 200\n\n\t\t\t\t// Load next batch of images\n\t\t\t\tconst fetchedFiles = await getPhotos(path, {\n\t\t\t\t\tfirstResult: this.fetchedFileIds.length,\n\t\t\t\t\tnbResults: numberOfImagesPerBatch,\n\t\t\t\t\t...options,\n\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t})\n\n\t\t\t\t// If we get less files than requested that means we got to the end\n\t\t\t\tif (fetchedFiles.length !== numberOfImagesPerBatch) {\n\t\t\t\t\tthis.doneFetchingFiles = true\n\t\t\t\t}\n\n\t\t\t\tconst fileIds = fetchedFiles\n\t\t\t\t\t.map(file => file.fileid)\n\t\t\t\t\t.filter(fileId => !this.fetchedFileIds.includes(fileId.toString())) // Filter to prevent duplicate fileIds.\n\n\t\t\t\tthis.fetchedFileIds.push(\n\t\t\t\t\t...fileIds\n\t\t\t\t\t\t.map((fileId) => fileId.toString())\n\t\t\t\t\t\t.filter((fileId) => !blacklist.includes(fileId))\n\t\t\t\t)\n\n\t\t\t\tthis.$store.dispatch('appendFiles', fetchedFiles)\n\n\t\t\t\tlogger.debug(`[FetchFilesMixin] Fetched ${fileIds.length} new files: `, fileIds)\n\n\t\t\t\treturn fileIds\n\t\t\t} catch (error) {\n\t\t\t\tif (error.response?.status === 404) {\n\t\t\t\t\tthis.errorFetchingFiles = 404\n\t\t\t\t} else if (error.code === 'ERR_CANCELED') {\n\t\t\t\t\treturn []\n\t\t\t\t} else {\n\t\t\t\t\tthis.errorFetchingFiles = error\n\t\t\t\t}\n\n\t\t\t\t// cancelled request, moving on...\n\t\t\t\tlogger.error('Error fetching files', { error })\n\t\t\t\tconsole.error(error)\n\t\t\t} finally {\n\t\t\t\tthis.loadingFiles = false\n\t\t\t\tthis.fetchSemaphore.release(fetchSemaphoreSymbol)\n\t\t\t}\n\n\t\t\treturn []\n\t\t},\n\n\t\tresetFetchFilesState() {\n\t\t\tthis.doneFetchingFiles = false\n\t\t\tthis.errorFetchingFiles = null\n\t\t\tthis.loadingFiles = false\n\t\t\tthis.fetchedFileIds = []\n\t\t},\n\t},\n}\n","/**\n * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { genFileInfo } from '../utils/fileUtils.js'\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { allMimes } from './AllowedMimes.js'\nimport client from './DavClient.js'\nimport { props } from './DavRequest.js'\nimport moment from '@nextcloud/moment'\n\n/**\n * List files from a folder and filter out unwanted mimes\n *\n * @param {object} path the lookup path\n * @param {object} [options] used for the cancellable requests\n * @param {number} [options.firstResult=0] Index of the first result that we want (starts at 0)\n * @param {number} [options.nbResults=200] The number of file to fetch\n * @param {string[]} [options.mimesType=allMimes] Mime type of the files\n * @param {boolean} [options.full=false] get full data of the files\n * @param {boolean} [options.onThisDay=false] get only items from this day of year\n * @param {boolean} [options.onlyFavorites=false] get only favorite items\n * @return {Promise<object[]>} the file list\n */\nexport default async function(path = '', options = {}) {\n\t// default function options\n\toptions = {\n\t\tfirstResult: 0,\n\t\tnbResults: 200,\n\t\tmimesType: allMimes,\n\t\tonThisDay: false,\n\t\tonlyFavorites: false,\n\t\t...options,\n\t}\n\n\tconst prefixPath = `/files/${getCurrentUser().uid}`\n\n\t// generating the search or condition\n\t// based on the allowed mimetypes\n\tconst orMime = options.mimesType.reduce((str, mime) => `${str}\n\t\t<d:eq>\n\t\t\t<d:prop>\n\t\t\t\t<d:getcontenttype/>\n\t\t\t</d:prop>\n\t\t\t<d:literal>${mime}</d:literal>\n\t\t</d:eq>\n\t`, '')\n\n\tconst eqFavorites = options.onlyFavorites\n\t\t? `<d:eq>\n\t\t\t\t<d:prop>\n\t\t\t\t\t<oc:favorite/>\n\t\t\t\t</d:prop>\n\t\t\t\t<d:literal>1</d:literal>\n\t\t\t</d:eq>`\n\t\t: ''\n\n\tconst onThisDay = options.onThisDay\n\t\t? `<d:or>${Array(20).fill(1)\n\t\t\t.map((_, years) => {\n\t\t\t\tconst start = moment(Date.now()).startOf('day').subtract(3, 'd').subtract(years + 1, 'y')\n\t\t\t\tconst end = moment(Date.now()).endOf('day').add(3, 'd').subtract(years + 1, 'y')\n\t\t\t\treturn `<d:and>\n\t\t\t\t<d:gt>\n\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t<d:getlastmodified />\n\t\t\t\t\t</d:prop>\n\t\t\t\t\t<d:literal>${start.format(moment.defaultFormatUtc)}</d:literal>\n\t\t\t\t</d:gt>\n\t\t\t\t<d:lt>\n\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t<d:getlastmodified />\n\t\t\t\t\t</d:prop>\n\t\t\t\t\t<d:literal>${end.format(moment.defaultFormatUtc)}</d:literal>\n\t\t\t\t</d:lt>\n\t\t\t</d:and>`\n\t\t\t}).join('\\n')}</d:or>`\n\t\t: ''\n\n\toptions = Object.assign({\n\t\tmethod: 'SEARCH',\n\t\theaders: {\n\t\t\t'content-Type': 'text/xml',\n\t\t},\n\t\tdata: `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t\t\t<d:searchrequest xmlns:d=\"DAV:\"\n\t\t\t\txmlns:oc=\"http://owncloud.org/ns\"\n\t\t\t\txmlns:nc=\"http://nextcloud.org/ns\"\n\t\t\t\txmlns:ns=\"https://github.com/icewind1991/SearchDAV/ns\"\n\t\t\t\txmlns:ocs=\"http://open-collaboration-services.org/ns\">\n\t\t\t\t<d:basicsearch>\n\t\t\t\t\t<d:select>\n\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t${props}\n\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t</d:select>\n\t\t\t\t\t<d:from>\n\t\t\t\t\t\t<d:scope>\n\t\t\t\t\t\t\t<d:href>${prefixPath}/${path}</d:href>\n\t\t\t\t\t\t\t<d:depth>infinity</d:depth>\n\t\t\t\t\t\t</d:scope>\n\t\t\t\t\t</d:from>\n\t\t\t\t\t<d:where>\n\t\t\t\t\t\t<d:and>\n\t\t\t\t\t\t\t<d:or>\n\t\t\t\t\t\t\t\t${orMime}\n\t\t\t\t\t\t\t</d:or>\n\t\t\t\t\t\t\t${eqFavorites}\n\t\t\t\t\t\t\t${onThisDay}\n\t\t\t\t\t\t</d:and>\n\t\t\t\t\t</d:where>\n\t\t\t\t\t<d:orderby>\n\t\t\t\t\t\t<d:order>\n\t\t\t\t\t\t\t<d:prop><nc:metadata-photos-original_date_time/></d:prop>\n\t\t\t\t\t\t\t<d:descending/>\n\t\t\t\t\t\t</d:order>\n\t\t\t\t\t</d:orderby>\n\t\t\t\t\t<d:limit>\n\t\t\t\t\t\t<d:nresults>${options.nbResults}</d:nresults>\n\t\t\t\t\t\t<ns:firstresult>${options.firstResult}</ns:firstresult>\n\t\t\t\t\t</d:limit>\n\t\t\t\t</d:basicsearch>\n\t\t\t</d:searchrequest>`,\n\t\tdeep: true,\n\t\tdetails: true,\n\t}, options)\n\n\tconst response = await client.getDirectoryContents('', options)\n\n\treturn response.data.map(data => genFileInfo(data))\n}\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".face-cover[data-v-5cb97458]{display:flex;flex-direction:column;padding:10px;border-radius:var(--border-radius-large)}.face-cover__crop-container[data-v-5cb97458]{overflow:hidden;width:128px;height:128px;border-radius:128px;position:relative;background:var(--color-background-darker);--photos-face-width: 128px}@media only screen and (max-width: 1020px){.face-cover__crop-container[data-v-5cb97458]{width:95px;height:95px;--photos-face-width: 95px}}.face-cover[data-v-5cb97458]:hover,.face-cover[data-v-5cb97458]:focus{background:var(--color-background-hover)}.face-cover__details[data-v-5cb97458]{display:flex;flex-direction:column;width:128px;margin-top:4px;text-align:center}@media only screen and (max-width: 1020px){.face-cover__details[data-v-5cb97458]{width:95px}}.face-cover__details__first-line[data-v-5cb97458]{display:flex;height:2em;overflow:hidden;text-overflow:ellipsis}.face-cover__details__second-line[data-v-5cb97458]{margin-top:6px;color:var(--color-text-maxcontrast)}.face-cover__details__name[data-v-5cb97458]{flex-grow:1;margin:0}.face-cover--small *[data-v-5cb97458]{font-size:15px !important}.face-cover--small .face-cover__details[data-v-5cb97458]{width:60px !important}.face-cover--small .face-cover__crop-container[data-v-5cb97458]{width:60px !important;height:60px !important;--photos-face-width: 60px !important}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/mixins/FaceCover.scss\"],\"names\":[],\"mappings\":\"AAqBA,6BACC,YAAA,CACA,qBAAA,CACA,YAAA,CACA,wCAAA,CAEA,6CACC,eAAA,CACA,WAAA,CACA,YAAA,CACA,mBAAA,CACA,iBAAA,CACA,yCAAA,CACA,0BAAA,CAEA,2CATD,6CAUE,UAAA,CACA,WAAA,CACA,yBAAA,CAAA,CAIF,sEACC,wCAAA,CAGD,sCACC,YAAA,CACA,qBAAA,CACA,WAAA,CACA,cAAA,CACA,iBAAA,CAEA,2CAPD,sCAQE,UAAA,CAAA,CAGD,kDACC,YAAA,CACA,UAAA,CACA,eAAA,CACA,sBAAA,CAGD,mDACC,cAAA,CACA,mCAAA,CAGD,4CACC,WAAA,CACA,QAAA,CAMF,sCACC,yBAAA,CAED,yDACC,qBAAA,CAED,gEACC,qBAAA,CACA,sBAAA,CACA,oCAAA\",\"sourcesContent\":[\"/**\\n * @copyright Copyright (c) 2023 Marcel Klehr <mklehr@gmx.net>\\n *\\n * @author Marcel Klehr <mklehr@gmx.net>\\n *\\n * @license AGPL-3.0-or-later\\n *\\n * This program is free software: you can redistribute it and/or modify\\n * it under the terms of the GNU Affero General Public License as\\n * published by the Free Software Foundation, either version 3 of the\\n * License, or (at your option) any later version.\\n *\\n * This program is distributed in the hope that it will be useful,\\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n * GNU Affero General Public License for more details.\\n *\\n * You should have received a copy of the GNU Affero General Public License\\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\\n *\\n */\\n.face-cover {\\n\\tdisplay: flex;\\n\\tflex-direction: column;\\n\\tpadding: 10px;\\n\\tborder-radius: var(--border-radius-large);\\n\\n\\t&__crop-container {\\n\\t\\toverflow: hidden;\\n\\t\\twidth: 128px;\\n\\t\\theight: 128px;\\n\\t\\tborder-radius: 128px;\\n\\t\\tposition: relative;\\n\\t\\tbackground: var(--color-background-darker);\\n\\t\\t--photos-face-width: 128px;\\n\\n\\t\\t@media only screen and (max-width: 1020px) {\\n\\t\\t\\twidth: 95px;\\n\\t\\t\\theight: 95px;\\n\\t\\t\\t--photos-face-width: 95px;\\n\\t\\t}\\n\\t}\\n\\n\\t&:hover, &:focus {\\n\\t\\tbackground: var(--color-background-hover);\\n\\t}\\n\\n\\t&__details {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\t\\twidth: 128px;\\n\\t\\tmargin-top: 4px;\\n\\t\\ttext-align: center;\\n\\n\\t\\t@media only screen and (max-width: 1020px) {\\n\\t\\t\\twidth: 95px;\\n\\t\\t}\\n\\n\\t\\t&__first-line {\\n\\t\\t\\tdisplay: flex;\\n\\t\\t\\theight: 2em;\\n\\t\\t\\toverflow: hidden;\\n\\t\\t\\ttext-overflow: ellipsis;\\n\\t\\t}\\n\\n\\t\\t&__second-line {\\n\\t\\t\\tmargin-top: 6px;\\n\\t\\t\\tcolor: var(--color-text-maxcontrast);\\n\\t\\t}\\n\\n\\t\\t&__name {\\n\\t\\t\\tflex-grow: 1;\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t}\\n}\\n\\n.face-cover--small {\\n\\t* {\\n\\t\\tfont-size: 15px !important;\\n\\t}\\n\\t.face-cover__details {\\n\\t\\twidth: 60px !important;\\n\\t}\\n\\t.face-cover__crop-container {\\n\\t\\twidth: 60px !important;\\n\\t\\theight: 60px !important;\\n\\t\\t--photos-face-width: 60px !important;\\n\\t}\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".face-list[data-v-33326436]{display:flex;flex-direction:row;height:350px;flex-wrap:wrap;padding:12px}.loader[data-v-33326436]{margin:25% auto}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/Faces/FaceMergeForm.vue\"],\"names\":[],\"mappings\":\"AAEA,4BACC,YAAA,CACA,kBAAA,CACA,YAAA,CACA,cAAA,CACA,YAAA,CAGD,yBACC,eAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.face-list {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\theight: 350px;\\n\\tflex-wrap: wrap;\\n\\tpadding: 12px;\\n}\\n\\n.loader {\\n\\tmargin: 25% auto;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{class:['face-cover', _vm.small && 'face-cover--small'],on:{\"click\":function($event){return _vm.$emit('click')}}},[_c('div',{staticClass:\"face-cover__crop-container\"},[_c('img',{ref:\"image\",staticClass:\"face-cover__image\",style:(_vm.coverDimensions),attrs:{\"src\":_vm.coverUrl}})]),_vm._v(\" \"),_c('div',{staticClass:\"face-cover__details\"},[(!_vm.baseName.match(/^[0-9]+$/))?_c('div',{staticClass:\"face-cover__details__first-line\"},[_c('h2',{staticClass:\"face-cover__details__name\"},[_vm._v(\"\\n\\t\\t\\t\\t\"+_vm._s(_vm.baseName)+\"\\n\\t\\t\\t\")])]):_vm._e(),_vm._v(\" \"),(!_vm.small)?_c('div',{staticClass:\"face-cover__details__second-line\"},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.n('photos', '%n photos', '%n photos', _vm.face.props['nbItems']))+\"\\n\\t\\t\")]):_vm._e()])])\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n - @copyright Copyright (c) 2022 Marcel Klehr <mklehr@gmx.net>\n -\n - @author Louis Chemineau <louis@chmn.me>\n - @author Marcel Klehr <mklehr@gmx.net>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<template>\n\t<div :class=\"['face-cover', small && 'face-cover--small']\" @click=\"$emit('click')\">\n\t\t<div class=\"face-cover__crop-container\">\n\t\t\t<img ref=\"image\"\n\t\t\t\tclass=\"face-cover__image\"\n\t\t\t\t:src=\"coverUrl\"\n\t\t\t\t:style=\"coverDimensions\">\n\t\t</div>\n\t\t<div class=\"face-cover__details\">\n\t\t\t<div v-if=\"!baseName.match(/^[0-9]+$/)\" class=\"face-cover__details__first-line\">\n\t\t\t\t<h2 class=\"face-cover__details__name\">\n\t\t\t\t\t{{ baseName }}\n\t\t\t\t</h2>\n\t\t\t</div>\n\t\t\t<div v-if=\"!small\" class=\"face-cover__details__second-line\">\n\t\t\t\t{{ n('photos', '%n photos', '%n photos', face.props['nbItems']) }}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nimport { generateUrl } from '@nextcloud/router'\nimport FetchFacesMixin from '../../mixins/FetchFacesMixin.js'\nimport FaceCoverMixin from '../../mixins/FaceCoverMixin.js'\n\nexport default {\n\tname: 'FaceCover',\n\n\tmixins: [\n\t\tFetchFacesMixin,\n\t\tFaceCoverMixin,\n\t],\n\n\tprops: {\n\t\tbaseName: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t\tsmall: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tobserver: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'files',\n\t\t\t'faces',\n\t\t\t'facesFiles',\n\t\t]),\n\n\t\t/**\n\t\t * @return {Face}\n\t\t */\n\t\tface() {\n\t\t\treturn this.faces[this.baseName]\n\t\t},\n\n\t\t/**\n\t\t * @return {string}\n\t\t */\n\t\tcoverUrl() {\n\t\t\tif (!this.cover) {\n\t\t\t\treturn ''\n\t\t\t}\n\n\t\t\treturn generateUrl(`/apps/photos/api/v1/preview/${this.cover.fileid}?x=${512}&y=${512}`)\n\t\t},\n\n\t\tcover() {\n\t\t\treturn this.getFaceCover(this.face.basename)\n\t\t},\n\n\t\tcoverDimensions() {\n\t\t\tif (!this.cover) return {}\n\t\t\treturn this.getCoverStyle(this.face.basename)\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../mixins/FaceCover';\n</style>\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=script&lang=js\"","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=style&index=0&id=5cb97458&prod&lang=scss&scoped=true\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceCover.vue?vue&type=style&index=0&id=5cb97458&prod&lang=scss&scoped=true\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./FaceCover.vue?vue&type=template&id=5cb97458&scoped=true\"\nimport script from \"./FaceCover.vue?vue&type=script&lang=js\"\nexport * from \"./FaceCover.vue?vue&type=script&lang=js\"\nimport style0 from \"./FaceCover.vue?vue&type=style&index=0&id=5cb97458&prod&lang=scss&scoped=true\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5cb97458\",\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:\"merge-form face-list\"},_vm._l((_vm.filteredFaces),function(face){return _c('FaceCover',{key:face.basename,attrs:{\"base-name\":face.basename,\"small\":\"\"},on:{\"click\":function($event){return _vm.handleSelect(face.basename)}}})}),1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2022 Marcel Klehr <mklehr@gmx.net>\n -\n - @author Marcel Klehr <mklehr@gmx.net>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n<template>\n\t<div class=\"merge-form face-list\">\n\t\t<FaceCover v-for=\"face in filteredFaces\"\n\t\t\t:key=\"face.basename\"\n\t\t\t:base-name=\"face.basename\"\n\t\t\tsmall\n\t\t\t@click=\"handleSelect(face.basename)\" />\n\t</div>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\n\nimport FaceCoverMixin from '../../mixins/FaceCoverMixin.js'\nimport FetchFacesMixin from '../../mixins/FetchFacesMixin.js'\nimport FaceCover from './FaceCover.vue'\n\nexport default {\n\tname: 'FaceMergeForm',\n\tcomponents: { FaceCover },\n\tmixins: [\n\t\tFaceCoverMixin,\n\t\tFetchFacesMixin,\n\t],\n\tprops: {\n\t\tfirstFace: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tloading: false,\n\t\t}\n\t},\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'files',\n\t\t\t'faces',\n\t\t\t'facesFiles',\n\t\t]),\n\n\t\tfilteredFaces() {\n\t\t\treturn Object.values(this.faces)\n\t\t\t\t.filter(face => face.basename !== this.firstFace)\n\t\t\t\t.sort((a, b) => {\n\t\t\t\t\tif (a.props.nbItems && b.props.nbItems) {\n\t\t\t\t\t\treturn b.props.nbItems - a.props.nbItems\n\t\t\t\t\t}\n\t\t\t\t\tif (!this.facesFiles[b.basename] || !this.facesFiles[a.basename]) {\n\t\t\t\t\t\treturn 0\n\t\t\t\t\t}\n\t\t\t\t\treturn this.facesFiles[b.basename].length - this.facesFiles[a.basename].length\n\t\t\t\t})\n\t\t},\n\t},\n\tmethods: {\n\t\thandleSelect(faceName) {\n\t\t\tthis.$emit('select', faceName)\n\t\t\tthis.loading = true\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.face-list {\n\tdisplay: flex;\n\tflex-direction: row;\n\theight: 350px;\n\tflex-wrap: wrap;\n\tpadding: 12px;\n}\n\n.loader {\n\tmargin: 25% auto;\n}\n</style>\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceMergeForm.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceMergeForm.vue?vue&type=script&lang=js\"","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceMergeForm.vue?vue&type=style&index=0&id=33326436&prod&scoped=true&lang=scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FaceMergeForm.vue?vue&type=style&index=0&id=33326436&prod&scoped=true&lang=scss\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./FaceMergeForm.vue?vue&type=template&id=33326436&scoped=true\"\nimport script from \"./FaceMergeForm.vue?vue&type=script&lang=js\"\nexport * from \"./FaceMergeForm.vue?vue&type=script&lang=js\"\nimport style0 from \"./FaceMergeForm.vue?vue&type=style&index=0&id=33326436&prod&scoped=true&lang=scss\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"33326436\",\n null\n \n)\n\nexport default component.exports"],"names":["name","computed","mapGetters","methods","getFaceCover","faceName","JSON","parse","he","this","faces","props","getCoverStyle","cover","detection","zoom","Math","max","width","horizontalCenterOfFace","x","verticalCenterOfFace","y","height","transform","concat","transformOrigin","data","errorFetchingFaces","loadingFaces","errorFetchingFiles","loadingFiles","mixins","AbortControllerMixin","async","fetchFaces","mapActions","Object","keys","length","_getCurrentUser","client","getCurrentUser","uid","DavRequest","details","signal","abortController","$store","dispatch","logger","error","response","status","t","showError","force","facesFiles","_getCurrentUser2","fetchedFiles","map","file","genFileInfo","filename","realpath","replace","faceDetections","fileIds","fileid","appendFiles","commit","fileIdsToAdd","unassignedFiles","_getCurrentUser3","_getCurrentUser4","unassignedFacesRoot","count","Number","nbItems","doneFetchingFiles","fetchSemaphore","SemaphoreWithPriority","fetchedFileIds","watch","$route","resetFetchFilesState","path","arguments","undefined","options","blacklist","fetchSemaphoreSymbol","acquire","numberOfImagesPerBatch","firstResult","nbResults","mimesType","allMimes","onThisDay","onlyFavorites","prefixPath","orMime","reduce","str","mime","eqFavorites","Array","fill","_","years","start","moment","Date","now","startOf","subtract","end","endOf","add","format","join","assign","method","headers","deep","getPhotos","filter","fileId","includes","toString","push","_error$response","code","console","release","___CSS_LOADER_EXPORT___","module","id","FetchFacesMixin","FaceCoverMixin","baseName","type","String","required","small","Boolean","default","observer","face","coverUrl","generateUrl","basename","coverDimensions","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","_c","_self","class","on","$event","$emit","staticClass","ref","style","attrs","_v","match","_e","_s","n","components","FaceCover","firstFace","loading","filteredFaces","values","sort","a","b","handleSelect","_l","key"],"sourceRoot":""}