From 8023f34e5b4f53586770d6b3d9ab2bbce621a87a Mon Sep 17 00:00:00 2001 From: Ferris Braatz Date: Fri, 6 Sep 2024 13:59:16 +0200 Subject: [PATCH 1/4] Add Uppy integration into File Upload fields, add FileUploadController --- package.json | 4 + src/controllers/FileUploadController.php | 322 ++++++++++++++++++ .../form-template/fields/file-upload.html | 36 +- .../frontend/dist/js/fields/file-upload.js | 3 +- .../dist/js/fields/file-upload.js.LICENSE.txt | 25 ++ .../frontend/src/js/fields/file-upload.js | 183 +++++++++- 6 files changed, 545 insertions(+), 28 deletions(-) create mode 100644 src/controllers/FileUploadController.php create mode 100644 src/web/assets/frontend/dist/js/fields/file-upload.js.LICENSE.txt diff --git a/package.json b/package.json index e56284f02..6c6d5cb46 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,10 @@ "@tiptap/extension-underline": "^2.0.0-beta.25", "@tiptap/starter-kit": "^2.0.0-beta.191", "@tiptap/vue-3": "^2.0.0-beta.96", + "@uppy/core": "^4.2.0", + "@uppy/dashboard": "^4.1.0", + "@uppy/form": "^4.0.0", + "@uppy/xhr-upload": "^4.1.0", "@yaireo/tagify": "^4.12.0", "click-outside-vue3": "^4.0.1", "expression-language": "^1.1.4", diff --git a/src/controllers/FileUploadController.php b/src/controllers/FileUploadController.php new file mode 100644 index 000000000..0a9a52dda --- /dev/null +++ b/src/controllers/FileUploadController.php @@ -0,0 +1,322 @@ + self::ALLOW_ANONYMOUS_LIVE, + 'remove-file' => self::ALLOW_ANONYMOUS_LIVE, + 'process-file' => self::ALLOW_ANONYMOUS_LIVE, + ]; + + // Private Properties + // ========================================================================= + + private string $_namespace = 'fields'; + + // Public Methods + // ========================================================================= + + /** + * @inheritdoc + */ + public function beforeAction($action): bool + { + return parent::beforeAction($action); + } + + /** + * @return Response + * @throws HttpException + * @throws RangeNotSatisfiableHttpException + */ + public function actionLoadFile(): Response { + $id = $this->request->getParam('id'); + $asset = Asset::find() + ->id($id) + ->one(); + $content = $asset->getContents(); + return $this->response->sendContentAsFile($content, "$asset->title.$asset->extension", [ + 'inline' => true, + 'mimeType' => $asset->mimeType + ]); + } + + /** + * @return Response + * @throws BadRequestHttpException + */ + public function actionRemoveFile(): Response { + $this->requirePostRequest(); + + $handle = $this->_getTypedParam('handle', 'string'); + + /* @var Form $form */ + $form = $this->_getForm($handle); + + if (!$form) { + throw new BadRequestHttpException("No form exists with the handle \"$handle\""); + } + + $removeFile = $this->_getTypedParam('removeFile', 'id'); + + if (!$removeFile) { + throw new BadRequestHttpException("No asset id passed in request."); + } + + $asset = Craft::$app->getAssets()->getAssetById($removeFile); + + if ($asset) { + $this->_deleteAsset($removeFile); + } else { + throw new BadRequestHttpException("No asset exists with the ID: \"$removeFile\""); + } + + + return $this->asRaw(true); + } + + /** + * @return Response + * @throws BadRequestHttpException + * @throws InvalidConfigException + * @throws Throwable + * @throws ElementNotFoundException + * @throws InvalidFieldException + * @throws VolumeException + * @throws Exception + */ + public function actionProcessFile(): Response { + $this->requirePostRequest(); + $handle = $this->_getTypedParam('handle', 'string'); + $submissionId = $this->_getTypedParam('submissionId', 'id'); + + + /* @var Form $form */ + $form = $this->_getForm($handle); + + if (!$form) { + throw new BadRequestHttpException("No form exists with the handle \"$handle\""); + } + + $submission = $this->_populateSubmission($form); + $initiator = $this->_getTypedParam('initiator', 'string'); + $field = $form->getFieldByHandle($initiator); + $volume = Craft::$app->getVolumes()->getVolumeByUid(explode(':', $field->uploadLocationSource)[1]); + $file = UploadedFile::getInstanceByName("file"); + + $filename = Assets::prepareAssetName($file->name); + $folder = Craft::$app->getAssets()->getRootFolderByVolumeId($volume->id); + $subpath = $field->uploadLocationSubpath; + if ($field->uploadLocationSubpath) { + $folder = Craft::$app->getAssets()->ensureFolderByFullPathAndVolume($subpath, $volume); + } + $asset = new Asset(); + $asset->tempFilePath = $file->tempName; + $asset->setFilename($filename); + $asset->newFolderId = $folder->id; + $asset->setVolumeId($volume->id); + $asset->uploaderId = Craft::$app->getUser()->getId(); + $asset->avoidFilenameConflicts = true; + + $asset->setScenario(Asset::SCENARIO_CREATE); + $result = Craft::$app->getElements()->saveElement($asset); + + if ($submissionId) { + $assetIds = $submission->getFieldValue($initiator)->ids(); + $assetIds[] = $asset->id; + $submission->setFieldValue($initiator, $assetIds); + // Save the submission + $success = Craft::$app->getElements()->saveElement($submission, false); + + if ($success) { + return $this->asJson(["id" => $asset->id, "url" => $asset->getUrl(), "submissionId" => $submission->id]); + } else { + throw new BadRequestHttpException("Unable to save Formie submission."); + } + } + + if ($result) { + return $this->asJson(["id" => $asset->id, "url" => $asset->getUrl()]); + } + + throw new BadRequestHttpException("Unable to process upload asset request."); + } + + // Private Methods + // ========================================================================= + + private function _populateSubmission($form, $isIncomplete = true): Submission + { + $request = $this->request; + + // Ensure we validate some params here to prevent potential malicious-ness + $editingSubmission = $this->_getTypedParam('editingSubmission', 'boolean'); + $submissionId = $this->_getTypedParam('submissionId', 'id'); + $siteId = $this->_getTypedParam('siteId', 'id'); + $userParam = $request->getBodyParam('user'); + + if ($submissionId) { + // Allow fetching spammed submissions for multistep forms, where it has been flagged as spam + // already, but we want to complete the form submission. + $submission = Submission::find() + ->id($submissionId) + ->isIncomplete($isIncomplete) + ->isSpam(null) + ->one(); + + if (!$submission) { + throw new BadRequestHttpException("No submission exists with the ID \"$submissionId\""); + } + } else { + $submission = new Submission(); + } + + $submission->setForm($form); + + $siteId = $siteId ?: null; + $submission->siteId = $siteId ?? $submission->siteId ?? Craft::$app->getSites()->getCurrentSite()->id; + + $submission->setFieldValuesFromRequest($this->_namespace); + $submission->setFieldParamNamespace($this->_namespace); + + // Only ever set for a brand-new submission + if (!$submission->id && $form->settings->collectIp) { + $submission->ipAddress = $request->userIP; + } + + if ($form->settings->collectUser) { + if ($user = Craft::$app->getUser()->getIdentity()) { + $submission->setUser($user); + } + + // Allow a `user` override (when editing a submission through the CP) + if ($request->getIsCpRequest() && $userParam) { + $submission->userId = $userParam[0] ?? null; + } + } + + $this->_setTitle($submission, $form); + + // If we're editing a submission, ensure we set our flag + if ($editingSubmission) { + $form->setSubmission($submission); + } + + return $submission; + } + + private function _getTypedParam(string $name, string $type, mixed $default = null, bool $bodyParam = true): mixed + { + $request = $this->request; + + if ($bodyParam) { + $value = $request->getBodyParam($name); + } else { + $value = $request->getParam($name); + } + + // Special case for `submitAction`, where we don't want just anything passed in to change behaviour + if ($name === 'submitAction') { + if (!in_array($value, ['submit', 'back', 'save'])) { + return $default; + } + } + + if ($value !== null) { + // Go case-by-case, so it's easier to handle, and more predictable + if ($type === 'string' && is_string($value)) { + return $value; + } + + if ($type === 'boolean' && is_string($value)) { + return StringHelper::toBoolean($value); + } + + if ($type === 'int' && (is_numeric($value) || $value === '')) { + return (int)$value; + } + + if ($type === 'id' && is_numeric($value) && (int)$value > 0) { + return (int)$value; + } + + throw new BadRequestHttpException('Request has invalid param ' . $name); + } + + return $default; + } + + private function _setTitle($submission, $form): void + { + $submission->title = Variables::getParsedValue($form->settings->submissionTitleFormat, $submission, $form); + + // Set the default title for the submission, so it can save correctly + if (!$submission->title) { + $now = new DateTime('now', new DateTimeZone(Craft::$app->getTimeZone())); + $submission->title = $now->format('D, d M Y H:i:s'); + } + } + + private function _getForm(string $handle): ?Form + { + $form = Form::find()->handle($handle)->one(); + + if ($form) { + if ($sessionKey = $this->_getTypedParam('sessionKey', 'string')) { + $form->setSessionKey($sessionKey); + } + } + + return $form; + } + + private function _deleteAsset($assetId) { + $asset = Craft::$app->getAssets()->getAssetById($assetId); + + if (!$asset) { + throw new BadRequestHttpException("Invalid asset ID: $assetId"); + } + + // Check if it's possible to delete objects in the target volume. + $this->requireVolumePermissionByAsset('deleteAssets', $asset); + $this->requirePeerVolumePermissionByAsset('deletePeerAssets', $asset); + + $success = Craft::$app->getElements()->deleteElement($asset, true); + + if (!$success) { + throw new BadRequestHttpException("Unable to delete asset on disk: $assetId", "Upload"); + } + } +} \ No newline at end of file diff --git a/src/templates/_special/form-template/fields/file-upload.html b/src/templates/_special/form-template/fields/file-upload.html index f9d29115d..dd8134083 100644 --- a/src/templates/_special/form-template/fields/file-upload.html +++ b/src/templates/_special/form-template/fields/file-upload.html @@ -1,31 +1,15 @@ -{# Because of browser limitations, we can't populate a `` field if we are on a #} -{# multi-page, page reload form with already uploaded assets. As such, we'll get an validation #} -{# error when going back to a previous page and submitting again, as the field will be empty #} -{# despite files being uploaded. Here, force the field to be non-required if a value exists. #} +{# If the submission has files submitted already, and we are on a multi-page, page reload form with #} +{# already uploaded assets, we need to delegate this task to a third-party library to handle #} +{# populating the `` field. The data object below provides this, but force #} +{# the field to be non-required if a value exists anyway. #} {% set required = value and value.all() ? false : field.required %} {{ fieldtag('fieldInput', { required: required ? true : false, + data: { + 'field-handle': field.handle, + 'files': value and value.all() ? value.ids(), + 'allowed-kinds': field.restrictFiles ? field.allowedKinds : [], + 'readable-accept': field.accept, + } }) }} - -{% if value %} - {% set elements = value.all() %} - - {% if elements %} - {% fieldtag 'fieldSummary' %} - {% if elements | length == 1 %} -

{{ '{num} file uploaded.' | t('formie', { num: elements | length }) }}

- {% else %} -

{{ '{num} files uploaded.' | t('formie', { num: elements | length }) }}

- {% endif %} - - {% fieldtag 'fieldSummaryContainer' %} - {% for element in elements %} - {% fieldtag 'fieldSummaryItem' %} - {{ element.filename }} - {% endfieldtag %} - {% endfor %} - {% endfieldtag %} - {% endfieldtag %} - {% endif %} -{% endif %} \ No newline at end of file diff --git a/src/web/assets/frontend/dist/js/fields/file-upload.js b/src/web/assets/frontend/dist/js/fields/file-upload.js index ca3295edc..29e85e9aa 100644 --- a/src/web/assets/frontend/dist/js/fields/file-upload.js +++ b/src/web/assets/frontend/dist/js/fields/file-upload.js @@ -1 +1,2 @@ -!function(){var t={3200:function(t,r,n){var e=n(7230),o=n(933),i=n(321),u=e.TypeError;t.exports=function(t){if(o(t))return t;throw u(i(t)+" is not a function")}},4831:function(t,r,n){var e=n(7230),o=n(3538),i=n(321),u=e.TypeError;t.exports=function(t){if(o(t))return t;throw u(i(t)+" is not a constructor")}},8563:function(t,r,n){var e=n(7230),o=n(933),i=e.String,u=e.TypeError;t.exports=function(t){if("object"==typeof t||o(t))return t;throw u("Can't set "+i(t)+" as a prototype")}},186:function(t,r,n){var e=n(7952),o=n(6997),i=n(7108),u=e("unscopables"),c=Array.prototype;null==c[u]&&i.f(c,u,{configurable:!0,value:o(null)}),t.exports=function(t){c[u][t]=!0}},3264:function(t,r,n){"use strict";var e=n(2370).charAt;t.exports=function(t,r,n){return r+(n?e(t,r).length:1)}},5209:function(t,r,n){var e=n(7230),o=n(2346),i=e.TypeError;t.exports=function(t,r){if(o(r,t))return t;throw i("Incorrect invocation")}},3536:function(t,r,n){var e=n(7230),o=n(6913),i=e.String,u=e.TypeError;t.exports=function(t){if(o(t))return t;throw u(i(t)+" is not an object")}},866:function(t,r,n){"use strict";var e=n(1569).forEach,o=n(2245)("forEach");t.exports=o?[].forEach:function(t){return e(this,t,arguments.length>1?arguments[1]:void 0)}},8897:function(t,r,n){"use strict";var e=n(7230),o=n(1248),i=n(4225),u=n(987),c=n(6996),a=n(1855),f=n(3538),s=n(1646),l=n(3859),p=n(9853),v=n(6418),d=e.Array;t.exports=function(t){var r=u(t),n=f(this),e=arguments.length,h=e>1?arguments[1]:void 0,y=void 0!==h;y&&(h=o(h,e>2?arguments[2]:void 0));var g,m,b,x,S,w,O=v(r),j=0;if(!O||this==d&&a(O))for(g=s(r),m=n?new this(g):d(g);g>j;j++)w=y?h(r[j],j):r[j],l(m,j,w);else for(S=(x=p(r,O)).next,m=n?new this:[];!(b=i(S,x)).done;j++)w=y?c(x,h,[b.value,j],!0):b.value,l(m,j,w);return m.length=j,m}},7945:function(t,r,n){var e=n(9164),o=n(2966),i=n(1646),u=function(t){return function(r,n,u){var c,a=e(r),f=i(a),s=o(u,f);if(t&&n!=n){for(;f>s;)if((c=a[s++])!=c)return!0}else for(;f>s;s++)if((t||s in a)&&a[s]===n)return t||s||0;return!t&&-1}};t.exports={includes:u(!0),indexOf:u(!1)}},1569:function(t,r,n){var e=n(1248),o=n(1916),i=n(6801),u=n(987),c=n(1646),a=n(1204),f=o([].push),s=function(t){var r=1==t,n=2==t,o=3==t,s=4==t,l=6==t,p=7==t,v=5==t||l;return function(d,h,y,g){for(var m,b,x=u(d),S=i(x),w=e(h,y),O=c(S),j=0,E=g||a,T=r?E(d,O):n||p?E(d,0):void 0;O>j;j++)if((v||j in S)&&(b=w(m=S[j],j,x),t))if(r)T[j]=b;else if(b)switch(t){case 3:return!0;case 5:return m;case 6:return j;case 2:f(T,m)}else switch(t){case 4:return!1;case 7:f(T,m)}return l?-1:o||s?s:T}};t.exports={forEach:s(0),map:s(1),filter:s(2),some:s(3),every:s(4),find:s(5),findIndex:s(6),filterReject:s(7)}},9321:function(t,r,n){var e=n(3694),o=n(7952),i=n(7806),u=o("species");t.exports=function(t){return i>=51||!e((function(){var r=[];return(r.constructor={})[u]=function(){return{foo:1}},1!==r[t](Boolean).foo}))}},2245:function(t,r,n){"use strict";var e=n(3694);t.exports=function(t,r){var n=[][t];return!!n&&e((function(){n.call(null,r||function(){return 1},1)}))}},696:function(t,r,n){var e=n(7230),o=n(2966),i=n(1646),u=n(3859),c=e.Array,a=Math.max;t.exports=function(t,r,n){for(var e=i(t),f=o(r,e),s=o(void 0===n?e:n,e),l=c(a(s-f,0)),p=0;f0&&e[0]<4?1:+(e[0]+e[1])),!o&&u&&(!(e=u.match(/Edge\/(\d+)/))||e[1]>=74)&&(e=u.match(/Chrome\/(\d+)/))&&(o=+e[1]),t.exports=o},9799:function(t){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},5302:function(t,r,n){var e=n(7230),o=n(5027).f,i=n(5399),u=n(6272),c=n(746),a=n(1831),f=n(4545);t.exports=function(t,r){var n,s,l,p,v,d=t.target,h=t.global,y=t.stat;if(n=h?e:y?e[d]||c(d,{}):(e[d]||{}).prototype)for(s in r){if(p=r[s],l=t.noTargetGet?(v=o(n,s))&&v.value:n[s],!f(h?s:d+(y?".":"#")+s,t.forced)&&void 0!==l){if(typeof p==typeof l)continue;a(p,l)}(t.sham||l&&l.sham)&&i(p,"sham",!0),u(n,s,p,t)}}},3694:function(t){t.exports=function(t){try{return!!t()}catch(t){return!0}}},4430:function(t,r,n){"use strict";n(5098);var e=n(1916),o=n(6272),i=n(9735),u=n(3694),c=n(7952),a=n(5399),f=c("species"),s=RegExp.prototype;t.exports=function(t,r,n,l){var p=c(t),v=!u((function(){var r={};return r[p]=function(){return 7},7!=""[t](r)})),d=v&&!u((function(){var r=!1,n=/a/;return"split"===t&&((n={}).constructor={},n.constructor[f]=function(){return n},n.flags="",n[p]=/./[p]),n.exec=function(){return r=!0,null},n[p](""),!r}));if(!v||!d||n){var h=e(/./[p]),y=r(p,""[t],(function(t,r,n,o,u){var c=e(t),a=r.exec;return a===i||a===s.exec?v&&!u?{done:!0,value:h(r,n,o)}:{done:!0,value:c(n,r,o)}:{done:!1}}));o(String.prototype,t,y[0]),o(s,p,y[1])}l&&a(s[p],"sham",!0)}},251:function(t,r,n){var e=n(592),o=Function.prototype,i=o.apply,u=o.call;t.exports="object"==typeof Reflect&&Reflect.apply||(e?u.bind(i):function(){return u.apply(i,arguments)})},1248:function(t,r,n){var e=n(1916),o=n(3200),i=n(592),u=e(e.bind);t.exports=function(t,r){return o(t),void 0===r?t:i?u(t,r):function(){return t.apply(r,arguments)}}},592:function(t,r,n){var e=n(3694);t.exports=!e((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},4225:function(t,r,n){var e=n(592),o=Function.prototype.call;t.exports=e?o.bind(o):function(){return o.apply(o,arguments)}},567:function(t,r,n){var e=n(6079),o=n(3225),i=Function.prototype,u=e&&Object.getOwnPropertyDescriptor,c=o(i,"name"),a=c&&"something"===function(){}.name,f=c&&(!e||e&&u(i,"name").configurable);t.exports={EXISTS:c,PROPER:a,CONFIGURABLE:f}},1916:function(t,r,n){var e=n(592),o=Function.prototype,i=o.bind,u=o.call,c=e&&i.bind(u,u);t.exports=e?function(t){return t&&c(t)}:function(t){return t&&function(){return u.apply(t,arguments)}}},1223:function(t,r,n){var e=n(7230),o=n(933),i=function(t){return o(t)?t:void 0};t.exports=function(t,r){return arguments.length<2?i(e[t]):e[t]&&e[t][r]}},6418:function(t,r,n){var e=n(996),o=n(5048),i=n(3019),u=n(7952)("iterator");t.exports=function(t){if(null!=t)return o(t,u)||o(t,"@@iterator")||i[e(t)]}},9853:function(t,r,n){var e=n(7230),o=n(4225),i=n(3200),u=n(3536),c=n(321),a=n(6418),f=e.TypeError;t.exports=function(t,r){var n=arguments.length<2?a(t):r;if(i(n))return u(o(n,t));throw f(c(t)+" is not iterable")}},5048:function(t,r,n){var e=n(3200);t.exports=function(t,r){var n=t[r];return null==n?void 0:e(n)}},6968:function(t,r,n){var e=n(1916),o=n(987),i=Math.floor,u=e("".charAt),c=e("".replace),a=e("".slice),f=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,s=/\$([$&'`]|\d{1,2})/g;t.exports=function(t,r,n,e,l,p){var v=n+t.length,d=e.length,h=s;return void 0!==l&&(l=o(l),h=f),c(p,h,(function(o,c){var f;switch(u(c,0)){case"$":return"$";case"&":return t;case"`":return a(r,0,n);case"'":return a(r,v);case"<":f=l[a(c,1,-1)];break;default:var s=+c;if(0===s)return o;if(s>d){var p=i(s/10);return 0===p?o:p<=d?void 0===e[p-1]?u(c,1):e[p-1]+u(c,1):o}f=e[s-1]}return void 0===f?"":f}))}},7230:function(t,r,n){var e=function(t){return t&&t.Math==Math&&t};t.exports=e("object"==typeof globalThis&&globalThis)||e("object"==typeof window&&window)||e("object"==typeof self&&self)||e("object"==typeof n.g&&n.g)||function(){return this}()||Function("return this")()},3225:function(t,r,n){var e=n(1916),o=n(987),i=e({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,r){return i(o(t),r)}},7076:function(t){t.exports={}},5812:function(t,r,n){var e=n(7230);t.exports=function(t,r){var n=e.console;n&&n.error&&(1==arguments.length?n.error(t):n.error(t,r))}},6507:function(t,r,n){var e=n(1223);t.exports=e("document","documentElement")},4253:function(t,r,n){var e=n(6079),o=n(3694),i=n(2200);t.exports=!e&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},6801:function(t,r,n){var e=n(7230),o=n(1916),i=n(3694),u=n(2248),c=e.Object,a=o("".split);t.exports=i((function(){return!c("z").propertyIsEnumerable(0)}))?function(t){return"String"==u(t)?a(t,""):c(t)}:c},4335:function(t,r,n){var e=n(1916),o=n(933),i=n(1393),u=e(Function.toString);o(i.inspectSource)||(i.inspectSource=function(t){return u(t)}),t.exports=i.inspectSource},21:function(t,r,n){var e,o,i,u=n(5506),c=n(7230),a=n(1916),f=n(6913),s=n(5399),l=n(3225),p=n(1393),v=n(375),d=n(7076),h="Object already initialized",y=c.TypeError,g=c.WeakMap;if(u||p.state){var m=p.state||(p.state=new g),b=a(m.get),x=a(m.has),S=a(m.set);e=function(t,r){if(x(m,t))throw new y(h);return r.facade=t,S(m,t,r),r},o=function(t){return b(m,t)||{}},i=function(t){return x(m,t)}}else{var w=v("state");d[w]=!0,e=function(t,r){if(l(t,w))throw new y(h);return r.facade=t,s(t,w,r),r},o=function(t){return l(t,w)?t[w]:{}},i=function(t){return l(t,w)}}t.exports={set:e,get:o,has:i,enforce:function(t){return i(t)?o(t):e(t,{})},getterFor:function(t){return function(r){var n;if(!f(r)||(n=o(r)).type!==t)throw y("Incompatible receiver, "+t+" required");return n}}}},1855:function(t,r,n){var e=n(7952),o=n(3019),i=e("iterator"),u=Array.prototype;t.exports=function(t){return void 0!==t&&(o.Array===t||u[i]===t)}},4893:function(t,r,n){var e=n(2248);t.exports=Array.isArray||function(t){return"Array"==e(t)}},933:function(t){t.exports=function(t){return"function"==typeof t}},3538:function(t,r,n){var e=n(1916),o=n(3694),i=n(933),u=n(996),c=n(1223),a=n(4335),f=function(){},s=[],l=c("Reflect","construct"),p=/^\s*(?:class|function)\b/,v=e(p.exec),d=!p.exec(f),h=function(t){if(!i(t))return!1;try{return l(f,s,t),!0}catch(t){return!1}},y=function(t){if(!i(t))return!1;switch(u(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return d||!!v(p,a(t))}catch(t){return!0}};y.sham=!0,t.exports=!l||o((function(){var t;return h(h.call)||!h(Object)||!h((function(){t=!0}))||t}))?y:h},4545:function(t,r,n){var e=n(3694),o=n(933),i=/#|\.prototype\./,u=function(t,r){var n=a[c(t)];return n==s||n!=f&&(o(r)?e(r):!!r)},c=u.normalize=function(t){return String(t).replace(i,".").toLowerCase()},a=u.data={},f=u.NATIVE="N",s=u.POLYFILL="P";t.exports=u},6913:function(t,r,n){var e=n(933);t.exports=function(t){return"object"==typeof t?null!==t:e(t)}},7442:function(t){t.exports=!1},7581:function(t,r,n){var e=n(7230),o=n(1223),i=n(933),u=n(2346),c=n(9264),a=e.Object;t.exports=c?function(t){return"symbol"==typeof t}:function(t){var r=o("Symbol");return i(r)&&u(r.prototype,a(t))}},5103:function(t,r,n){var e=n(7230),o=n(1248),i=n(4225),u=n(3536),c=n(321),a=n(1855),f=n(1646),s=n(2346),l=n(9853),p=n(6418),v=n(5635),d=e.TypeError,h=function(t,r){this.stopped=t,this.result=r},y=h.prototype;t.exports=function(t,r,n){var e,g,m,b,x,S,w,O=n&&n.that,j=!(!n||!n.AS_ENTRIES),E=!(!n||!n.IS_ITERATOR),T=!(!n||!n.INTERRUPTED),P=o(r,O),A=function(t){return e&&v(e,"normal",t),new h(!0,t)},R=function(t){return j?(u(t),T?P(t[0],t[1],A):P(t[0],t[1])):T?P(t,A):P(t)};if(E)e=t;else{if(!(g=p(t)))throw d(c(t)+" is not iterable");if(a(g)){for(m=0,b=f(t);b>m;m++)if((x=R(t[m]))&&s(y,x))return x;return new h(!1)}e=l(t,g)}for(S=e.next;!(w=i(S,e)).done;){try{x=R(w.value)}catch(t){v(e,"throw",t)}if("object"==typeof x&&x&&s(y,x))return x}return new h(!1)}},5635:function(t,r,n){var e=n(4225),o=n(3536),i=n(5048);t.exports=function(t,r,n){var u,c;o(t);try{if(!(u=i(t,"return"))){if("throw"===r)throw n;return n}u=e(u,t)}catch(t){c=!0,u=t}if("throw"===r)throw n;if(c)throw u;return o(u),n}},7824:function(t,r,n){"use strict";var e,o,i,u=n(3694),c=n(933),a=n(6997),f=n(5024),s=n(6272),l=n(7952),p=n(7442),v=l("iterator"),d=!1;[].keys&&("next"in(i=[].keys())?(o=f(f(i)))!==Object.prototype&&(e=o):d=!0),null==e||u((function(){var t={};return e[v].call(t)!==t}))?e={}:p&&(e=a(e)),c(e[v])||s(e,v,(function(){return this})),t.exports={IteratorPrototype:e,BUGGY_SAFARI_ITERATORS:d}},3019:function(t){t.exports={}},1646:function(t,r,n){var e=n(6092);t.exports=function(t){return e(t.length)}},2484:function(t,r,n){var e=n(3694),o=n(933),i=n(3225),u=n(7108).f,c=n(567).CONFIGURABLE,a=n(4335),f=n(21),s=f.enforce,l=f.get,p=!e((function(){return 8!==u((function(){}),"length",{value:8}).length})),v=String(String).split("String"),d=t.exports=function(t,r,n){"Symbol("===String(r).slice(0,7)&&(r="["+String(r).replace(/^Symbol\(([^)]*)\)/,"$1")+"]"),n&&n.getter&&(r="get "+r),n&&n.setter&&(r="set "+r),(!i(t,"name")||c&&t.name!==r)&&u(t,"name",{value:r,configurable:!0}),p&&n&&i(n,"arity")&&t.length!==n.arity&&u(t,"length",{value:n.arity});var e=s(t);return i(e,"source")||(e.source=v.join("string"==typeof r?r:"")),t};Function.prototype.toString=d((function(){return o(this)&&l(this).source||a(this)}),"toString")},3012:function(t,r,n){var e,o,i,u,c,a,f,s,l=n(7230),p=n(1248),v=n(5027).f,d=n(7823).set,h=n(4619),y=n(4370),g=n(2811),m=n(5009),b=l.MutationObserver||l.WebKitMutationObserver,x=l.document,S=l.process,w=l.Promise,O=v(l,"queueMicrotask"),j=O&&O.value;j||(e=function(){var t,r;for(m&&(t=S.domain)&&t.exit();o;){r=o.fn,o=o.next;try{r()}catch(t){throw o?u():i=void 0,t}}i=void 0,t&&t.enter()},h||m||g||!b||!x?!y&&w&&w.resolve?((f=w.resolve(void 0)).constructor=w,s=p(f.then,f),u=function(){s(e)}):m?u=function(){S.nextTick(e)}:(d=p(d,l),u=function(){d(e)}):(c=!0,a=x.createTextNode(""),new b(e).observe(a,{characterData:!0}),u=function(){a.data=c=!c})),t.exports=j||function(t){var r={fn:t,next:void 0};i&&(i.next=r),o||(o=r,u()),i=r}},61:function(t,r,n){var e=n(8724);t.exports=e&&!!Symbol.for&&!!Symbol.keyFor},8724:function(t,r,n){var e=n(7806),o=n(3694);t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol();return!String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&e&&e<41}))},5506:function(t,r,n){var e=n(7230),o=n(933),i=n(4335),u=e.WeakMap;t.exports=o(u)&&/native code/.test(i(u))},6935:function(t,r,n){"use strict";var e=n(3200),o=function(t){var r,n;this.promise=new t((function(t,e){if(void 0!==r||void 0!==n)throw TypeError("Bad Promise constructor");r=t,n=e})),this.resolve=e(r),this.reject=e(n)};t.exports.f=function(t){return new o(t)}},6997:function(t,r,n){var e,o=n(3536),i=n(7673),u=n(9799),c=n(7076),a=n(6507),f=n(2200),s=n(375),l=s("IE_PROTO"),p=function(){},v=function(t){return"