diff --git a/404.html b/404.html index 021938bb7..07657a026 100644 --- a/404.html +++ b/404.html @@ -13,7 +13,7 @@ - + diff --git a/assets/js/427b2579.a8a4ec71.js b/assets/js/427b2579.a8a4ec71.js new file mode 100644 index 000000000..f3d31a3bf --- /dev/null +++ b/assets/js/427b2579.a8a4ec71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuppy_io=self.webpackChunkuppy_io||[]).push([[7873],{41649:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var r=n(74848),o=n(28453);const s={slug:"/reactrouter"},a="React Router",i={id:"framework-integrations/react-router",title:"React Router",description:"Integration guide for the React components for the Uppy UI plugins and",source:"@site/docs/framework-integrations/react-router.mdx",sourceDirName:"framework-integrations",slug:"/reactrouter",permalink:"/docs/reactrouter",draft:!1,unlisted:!1,editUrl:"https://github.com/transloadit/uppy.io/blob/main/docs/framework-integrations/react-router.mdx",tags:[],version:"current",frontMatter:{slug:"/reactrouter"},sidebar:"tutorialSidebar",previous:{title:"Next.js",permalink:"/docs/nextjs"},next:{title:"React",permalink:"/docs/react"}},c={},u=[{value:"Install",id:"install",level:2},{value:"Tus",id:"tus",level:2},{value:"Transloadit",id:"transloadit",level:2},{value:"HTTP uploads to your backend",id:"http-uploads-to-your-backend",level:2},{value:"Next steps",id:"next-steps",level:2}];function p(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"react-router",children:"React Router"}),"\n",(0,r.jsxs)(t.p,{children:["Integration guide for the ",(0,r.jsx)(t.a,{href:"https://facebook.github.io/react",children:"React"})," components for the Uppy UI plugins and\nhooks."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["Uppy also has hooks and more React examples in the ",(0,r.jsx)(t.a,{href:"/docs/react",children:"React docs"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"install",children:"Install"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-shell",children:"npm install @uppy/core @uppy/dashboard @uppy/react\n"})}),"\n",(0,r.jsx)(t.h2,{id:"tus",children:"Tus"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://tus.io/",children:"Tus"})," is an open protocol for resumable uploads built on HTTP. This means\naccidentally closing your tab or losing connection lets you continue, for\ninstance, your 10GB upload instead of starting all over."]}),"\n",(0,r.jsxs)(t.p,{children:["Tus supports any language, any platform, and any network. It requires a client\nand server integration to work. We will be using ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:"tus Node.js"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Checkout the ",(0,r.jsxs)(t.a,{href:"/docs/tus",children:[(0,r.jsx)(t.code,{children:"@uppy/tus"})," docs"]})," for more information."]}),"\n",(0,r.jsx)(t.p,{children:"Create a route where you want to handle uploads:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",children:"import { useEffect, useState } from 'react';\nimport Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Tus from '@uppy/tus';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Tus, { endpoint: '/api/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\treturn ;\n}\n"})}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:(0,r.jsx)(t.code,{children:"@tus/server"})})," does not support react router resource routes yet,\nwhich is based on the fetch ",(0,r.jsx)(t.code,{children:"Request"})," API instead of ",(0,r.jsx)(t.code,{children:"http.IncomingMessage"})," and\n",(0,r.jsx)(t.code,{children:"http.ServerResponse"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["However we can workaround it by using a custom server, which is a common pattern\nwith React Router. The ",(0,r.jsx)(t.a,{href:"https://remix.run/docs/en/main/other-api/adapter",children:"docs"}),"\nfor this are still on the Remix site, but the same packages exist under the\n",(0,r.jsx)(t.code,{children:"@react-router/*"})," scope."]}),"\n",(0,r.jsxs)(t.p,{children:["The exact code to integrate ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:"tus Node.js"})," in your custom server depends on the\nframework you choose. Head over to the ",(0,r.jsx)(t.code,{children:"@tus/server"})," ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server/tree/main/packages/server#examples",children:"examples for the most popular Node.js servers"}),"\nto find the one that works for you."]}),"\n",(0,r.jsx)(t.h2,{id:"transloadit",children:"Transloadit"}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["Before continuing you should have a ",(0,r.jsx)(t.a,{href:"https://transloadit.com",children:"Transloadit"}),"\naccount and a\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/getting-started/my-first-app/",children:"template"})," setup."]})}),"\n",(0,r.jsxs)(t.p,{children:["Transloadit\u2019s strength is versatility. By doing video, audio, images, documents,\nand more, you only need one vendor for ",(0,r.jsx)(t.a,{href:"https://transloadit.com/services/",children:"all your file processing\nneeds"}),". The ",(0,r.jsx)(t.a,{href:"/docs/transloadit",children:(0,r.jsx)(t.code,{children:"@uppy/transloadit"})}),"\nplugin directly uploads to Transloadit so you only have to worry about creating\na ",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/getting-started/concepts/",children:"template"}),". It uses ",(0,r.jsx)(t.a,{href:"#tus",children:"Tus"})," under the hood so you\ndon\u2019t have to sacrifice reliable, resumable uploads for convenience."]}),"\n",(0,r.jsxs)(t.p,{children:["When you go to production always make sure to set the ",(0,r.jsx)(t.code,{children:"signature"}),". ",(0,r.jsxs)(t.strong,{children:["Not using\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/topics/signature-authentication/",children:"Signature Authentication"}),"\ncan be a security risk"]}),". Signature Authentication is a security measure that\ncan prevent outsiders from tampering with your Assembly Instructions."]}),"\n",(0,r.jsx)(t.p,{children:"Generating a signature should be done on the server to avoid leaking secrets."}),"\n",(0,r.jsxs)(t.p,{children:["Start by creating a\n",(0,r.jsx)(t.a,{href:"https://reactrouter.com/how-to/resource-routes",children:"resource route"})," to generate the\nsignature and params:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { data } from 'react-router';\nimport type { ActionFunction } from 'react-router';\nimport crypto from 'crypto';\n\nfunction utcDateString(ms: number): string {\n\treturn new Date(ms)\n\t\t.toISOString()\n\t\t.replace(/-/g, '/')\n\t\t.replace(/T/, ' ')\n\t\t.replace(/\\.\\d+Z$/, '+00:00');\n}\n\nexport const action: ActionFunction = async ({ request }) => {\n\t// expire 1 hour from now (this must be milliseconds)\n\tconst expires = utcDateString(Date.now() + 1 * 60 * 60 * 1000);\n\tconst authKey = process.env.TRANSLOADIT_KEY;\n\tconst authSecret = process.env.TRANSLOADIT_SECRET;\n\tconst templateId = process.env.TRANSLOADIT_TEMPLATE_ID;\n\n\tif (!authKey || !authSecret || !templateId) {\n\t\tthrow data({ error: 'Missing Transloadit credentials' }, { status: 500 });\n\t}\n\n\tconst body = await request.json();\n\tconst params = JSON.stringify({\n\t\tauth: {\n\t\t\tkey: authKey,\n\t\t\texpires,\n\t\t},\n\t\ttemplate_id: templateId,\n\t\tfields: {\n\t\t\t// You can use this in your template.\n\t\t\tcustomValue: body.customValue,\n\t\t},\n\t\t// your other params like notify_url, etc.\n\t});\n\n\tconst signatureBytes = crypto\n\t\t.createHmac('sha384', authSecret)\n\t\t.update(Buffer.from(params, 'utf-8'));\n\t// The final signature needs the hash name in front, so\n\t// the hashing algorithm can be updated in a backwards-compatible\n\t// way when old algorithms become insecure.\n\tconst signature = `sha384:${signatureBytes.digest('hex')}`;\n\n\treturn data({ expires, signature, params });\n};\n"})}),"\n",(0,r.jsxs)(t.p,{children:["On the client we want to fetch the signature and params from the server. You may\nwant to send values from React state along to your endpoint, for instance to add\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/topics/assembly-variables/",children:(0,r.jsx)(t.code,{children:"fields"})})," which you\ncan use in your template as global variables."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-js",children:"// app/routes/upload-transloadit.tsx\nimport { Transloadit } from '@uppy/transloadit';\n\nfunction createUppy() {\n\tconst uppy = new Uppy();\n\tuppy.use(Transloadit, {\n\t\tasync assemblyOptions() {\n\t\t\t// You can send meta data along for use in your template.\n\t\t\t// https://transloadit.com/docs/topics/assembly-instructions/#form-fields-in-instructions\n\t\t\tconst { meta } = uppy.getState();\n\t\t\tconst body = JSON.stringify({ customValue: meta.customValue });\n\t\t\tconst res = await fetch('/transloadit-params', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody,\n\t\t\t});\n\t\t\treturn res.json();\n\t\t},\n\t});\n\treturn uppy;\n}\n\nfunction Component({ customValue }) {\n\t// IMPORTANT: passing an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\tuseEffect(() => {\n\t\tif (customValue) {\n\t\t\tuppy.setOptions({ meta: { customValue } });\n\t\t}\n\t}, [uppy, customValue]);\n}\n"})}),"\n",(0,r.jsx)(t.h2,{id:"http-uploads-to-your-backend",children:"HTTP uploads to your backend"}),"\n",(0,r.jsxs)(t.p,{children:["If you want to handle uploads yourself, you can use\n",(0,r.jsx)(t.a,{href:"/docs/xhr-upload",children:(0,r.jsx)(t.code,{children:"@uppy/xhr-upload"})}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Create a ",(0,r.jsx)(t.a,{href:"https://reactrouter.com/how-to/resource-routes",children:"resource route"}),", such\nas ",(0,r.jsx)(t.code,{children:"app/routes/upload/route.ts"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { LocalFileStorage } from '@mjackson/file-storage/local';\nimport { type FileUpload, parseFormData } from '@mjackson/form-data-parser';\nimport { type ActionFunctionArgs } from 'react-router';\n\nconst fileStorage = new LocalFileStorage('./uploads');\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tconst user = requireUser(request); // your optional logic\n\tconst uploadHandler = async (fileUpload: FileUpload) => {\n\t\tconst storageKey = `user-${user.id}-avatar`;\n\t\tawait fileStorage.set(storageKey, fileUpload);\n\t\treturn fileStorage.get(storageKey);\n\t};\n\tconst formData = await parseFormData(request, uploadHandler);\n\tfor (const [key, value] of formData.entries()) {\n\t\tconsole.log(key, value);\n\t}\n\treturn Response.json(null);\n}\n"})}),"\n",(0,r.jsx)(t.p,{children:"Create a page with your Uppy instance:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",children:"import Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Xhr from '@uppy/xhr-upload';\nimport { useState } from 'react';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Xhr, { endpoint: '/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\treturn ;\n}\n"})}),"\n",(0,r.jsxs)(t.p,{children:["If you want to send along other form fields with your upload, you can use\n",(0,r.jsx)(t.a,{href:"/docs/form",children:(0,r.jsx)(t.code,{children:"@uppy/form"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",metastring:"{4,20-23,26-30}",children:"import Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Xhr from '@uppy/xhr-upload';\nimport Form from '@uppy/form';\nimport { useEffect, useState } from 'react';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Xhr, { endpoint: '/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\t// @uppy/form is client-side only so we need to install it\n\t// when the component is mounted.\n\tuseEffect(() => {\n\t\tuppy.use(Form, { target: '#form' });\n\t\treturn () => uppy.removePlugin(uppy.getPlugin('Form')!);\n\t}, [uppy]);\n\n\treturn (\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t;\n\t\t\n\t);\n}\n"})}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Add client-side file ",(0,r.jsx)(t.a,{href:"/docs/uppy/#restrictions",children:"restrictions"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Upload files together with other form fields with ",(0,r.jsx)(t.a,{href:"/docs/form",children:(0,r.jsx)(t.code,{children:"@uppy/form"})}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Use your ",(0,r.jsx)(t.a,{href:"/docs/locales",children:"language of choice"})," instead of English."]}),"\n",(0,r.jsxs)(t.li,{children:["Add an ",(0,r.jsx)(t.a,{href:"docs/image-editor",children:"image editor"})," for cropping and resizing images."]}),"\n",(0,r.jsxs)(t.li,{children:["Download files from remote sources, such as ",(0,r.jsx)(t.a,{href:"docs/google-drive",children:"Google Drive"}),"\nand ",(0,r.jsx)(t.a,{href:"docs/dropbox",children:"Dropbox"}),", with ",(0,r.jsx)(t.a,{href:"/docs/companion",children:"Companion"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Add ",(0,r.jsx)(t.a,{href:"/docs/golden-retriever",children:"Golden Retriever"})," to save selected files in your\nbrowser cache, so that if the browser crashes, or the user accidentally closes\nthe tab, Uppy can restore everything and continue uploading as if nothing\nhappened."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/427b2579.b63f7ca1.js b/assets/js/427b2579.b63f7ca1.js deleted file mode 100644 index 869a944ca..000000000 --- a/assets/js/427b2579.b63f7ca1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkuppy_io=self.webpackChunkuppy_io||[]).push([[7873],{41649:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var r=n(74848),o=n(28453);const s={slug:"/reactrouter"},a="React Router",i={id:"framework-integrations/react-router",title:"React Router",description:"Integration guide for the React components for the Uppy UI plugins and",source:"@site/docs/framework-integrations/react-router.mdx",sourceDirName:"framework-integrations",slug:"/reactrouter",permalink:"/docs/reactrouter",draft:!1,unlisted:!1,editUrl:"https://github.com/transloadit/uppy.io/blob/main/docs/framework-integrations/react-router.mdx",tags:[],version:"current",frontMatter:{slug:"/reactrouter"},sidebar:"tutorialSidebar",previous:{title:"Next.js",permalink:"/docs/nextjs"},next:{title:"React",permalink:"/docs/react"}},c={},u=[{value:"Install",id:"install",level:2},{value:"Tus",id:"tus",level:2},{value:"Transloadit",id:"transloadit",level:2},{value:"HTTP uploads to your backend",id:"http-uploads-to-your-backend",level:2},{value:"Next steps",id:"next-steps",level:2}];function p(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"react-router",children:"React Router"}),"\n",(0,r.jsxs)(t.p,{children:["Integration guide for the ",(0,r.jsx)(t.a,{href:"https://facebook.github.io/react",children:"React"})," components for the Uppy UI plugins and\nhooks."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["Uppy also has hooks and more React examples in the ",(0,r.jsx)(t.a,{href:"/docs/react",children:"React docs"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"install",children:"Install"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-shell",children:"npm install @uppy/core @uppy/dashboard @uppy/react\n"})}),"\n",(0,r.jsx)(t.h2,{id:"tus",children:"Tus"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://tus.io/",children:"Tus"})," is an open protocol for resumable uploads built on HTTP. This means\naccidentally closing your tab or losing connection lets you continue, for\ninstance, your 10GB upload instead of starting all over."]}),"\n",(0,r.jsxs)(t.p,{children:["Tus supports any language, any platform, and any network. It requires a client\nand server integration to work. We will be using ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:"tus Node.js"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Checkout the ",(0,r.jsxs)(t.a,{href:"/docs/tus",children:[(0,r.jsx)(t.code,{children:"@uppy/tus"})," docs"]})," for more information."]}),"\n",(0,r.jsx)(t.p,{children:"Create a route where you want to handle uploads:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",children:"import { useEffect, useState } from 'react';\nimport Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Tus from '@uppy/tus';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Tus, { endpoint: '/api/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\treturn ;\n}\n"})}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:(0,r.jsx)(t.code,{children:"@tus/server"})})," does not support react router resource routes yet,\nwhich is based on the fetch ",(0,r.jsx)(t.code,{children:"Request"})," API instead of ",(0,r.jsx)(t.code,{children:"http.IncomingMessage"})," and\n",(0,r.jsx)(t.code,{children:"http.ServerResponse"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["However we can workaround it by using a custom server, which is a common pattern\nwith React Router. The ",(0,r.jsx)(t.a,{href:"https://remix.run/docs/en/main/other-api/adapter",children:"docs"}),"\nfor this are still on the Remix site, but the same packages exist under the\n",(0,r.jsx)(t.code,{children:"@react-router/*"})," scope."]}),"\n",(0,r.jsxs)(t.p,{children:["The exact code to integrate ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server",children:"tus Node.js"})," in your custom server depends on the\nframework you choose. Head over to the ",(0,r.jsx)(t.code,{children:"@tus/server"})," ",(0,r.jsx)(t.a,{href:"https://github.com/tus/tus-node-server/tree/main/packages/server#examples",children:"examples for the most popular Node.js servers"}),"\nto find the one that works for you."]}),"\n",(0,r.jsx)(t.h2,{id:"transloadit",children:"Transloadit"}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["Before continuing you should have a ",(0,r.jsx)(t.a,{href:"https://transloadit.com",children:"Transloadit"}),"\naccount and a\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/getting-started/my-first-app/",children:"template"})," setup."]})}),"\n",(0,r.jsxs)(t.p,{children:["Transloadit\u2019s strength is versatility. By doing video, audio, images, documents,\nand more, you only need one vendor for ",(0,r.jsx)(t.a,{href:"https://transloadit.com/services/",children:"all your file processing\nneeds"}),". The ",(0,r.jsx)(t.a,{href:"/docs/transloadit",children:(0,r.jsx)(t.code,{children:"@uppy/transloadit"})}),"\nplugin directly uploads to Transloadit so you only have to worry about creating\na ",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/getting-started/concepts/",children:"template"}),". It uses ",(0,r.jsx)(t.a,{href:"#tus",children:"Tus"})," under the hood so you\ndon\u2019t have to sacrifice reliable, resumable uploads for convenience."]}),"\n",(0,r.jsxs)(t.p,{children:["When you go to production always make sure to set the ",(0,r.jsx)(t.code,{children:"signature"}),". ",(0,r.jsxs)(t.strong,{children:["Not using\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/topics/signature-authentication/",children:"Signature Authentication"}),"\ncan be a security risk"]}),". Signature Authentication is a security measure that\ncan prevent outsiders from tampering with your Assembly Instructions."]}),"\n",(0,r.jsx)(t.p,{children:"Generating a signature should be done on the server to avoid leaking secrets."}),"\n",(0,r.jsxs)(t.p,{children:["Start by creating a\n",(0,r.jsx)(t.a,{href:"https://reactrouter.com/how-to/resource-routes",children:"resource route"})," to generate the\nsignature and params:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { data } from 'react-router';\nimport type { ActionFunction } from 'rea';\nimport crypto from 'crypto';\n\nfunction utcDateString(ms: number): string {\n\treturn new Date(ms)\n\t\t.toISOString()\n\t\t.replace(/-/g, '/')\n\t\t.replace(/T/, ' ')\n\t\t.replace(/\\.\\d+Z$/, '+00:00');\n}\n\nexport const action: ActionFunction = async ({ request }) => {\n\t// expire 1 hour from now (this must be milliseconds)\n\tconst expires = utcDateString(Date.now() + 1 * 60 * 60 * 1000);\n\tconst authKey = process.env.TRANSLOADIT_KEY;\n\tconst authSecret = process.env.TRANSLOADIT_SECRET;\n\tconst templateId = process.env.TRANSLOADIT_TEMPLATE_ID;\n\n\tif (!authKey || !authSecret || !templateId) {\n\t\tthrow data({ error: 'Missing Transloadit credentials' }, { status: 500 });\n\t}\n\n\tconst body = await request.json();\n\tconst params = JSON.stringify({\n\t\tauth: {\n\t\t\tkey: authKey,\n\t\t\texpires,\n\t\t},\n\t\ttemplate_id: templateId,\n\t\tfields: {\n\t\t\t// You can use this in your template.\n\t\t\tcustomValue: body.customValue,\n\t\t},\n\t\t// your other params like notify_url, etc.\n\t});\n\n\tconst signatureBytes = crypto\n\t\t.createHmac('sha384', authSecret)\n\t\t.update(Buffer.from(params, 'utf-8'));\n\t// The final signature needs the hash name in front, so\n\t// the hashing algorithm can be updated in a backwards-compatible\n\t// way when old algorithms become insecure.\n\tconst signature = `sha384:${signatureBytes.digest('hex')}`;\n\n\treturn data({ expires, signature, params });\n};\n"})}),"\n",(0,r.jsxs)(t.p,{children:["On the client we want to fetch the signature and params from the server. You may\nwant to send values from React state along to your endpoint, for instance to add\n",(0,r.jsx)(t.a,{href:"https://transloadit.com/docs/topics/assembly-variables/",children:(0,r.jsx)(t.code,{children:"fields"})})," which you\ncan use in your template as global variables."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-js",children:"// app/routes/upload-transloadit.tsx\nimport { Transloadit } from '@uppy/transloadit';\n\nfunction createUppy() {\n\tconst uppy = new Uppy();\n\tuppy.use(Transloadit, {\n\t\tasync assemblyOptions() {\n\t\t\t// You can send meta data along for use in your template.\n\t\t\t// https://transloadit.com/docs/topics/assembly-instructions/#form-fields-in-instructions\n\t\t\tconst { meta } = uppy.getState();\n\t\t\tconst body = JSON.stringify({ customValue: meta.customValue });\n\t\t\tconst res = await fetch('/transloadit-params', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody,\n\t\t\t});\n\t\t\treturn res.json();\n\t\t},\n\t});\n\treturn uppy;\n}\n\nfunction Component({ customValue }) {\n\t// IMPORTANT: passing an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\tuseEffect(() => {\n\t\tif (customValue) {\n\t\t\tuppy.setOptions({ meta: { customValue } });\n\t\t}\n\t}, [uppy, customValue]);\n}\n"})}),"\n",(0,r.jsx)(t.h2,{id:"http-uploads-to-your-backend",children:"HTTP uploads to your backend"}),"\n",(0,r.jsxs)(t.p,{children:["If you want to handle uploads yourself, you can use\n",(0,r.jsx)(t.a,{href:"/docs/xhr-upload",children:(0,r.jsx)(t.code,{children:"@uppy/xhr-upload"})}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Create a ",(0,r.jsx)(t.a,{href:"https://reactrouter.com/how-to/resource-routes",children:"resource route"}),", such\nas ",(0,r.jsx)(t.code,{children:"app/routes/upload/route.ts"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-ts",children:"import { LocalFileStorage } from '@mjackson/file-storage/local';\nimport { type FileUpload, parseFormData } from '@mjackson/form-data-parser';\nimport { type ActionFunctionArgs } from 'react-router';\n\nconst fileStorage = new LocalFileStorage('./uploads');\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tconst user = requireUser(request); // your optional logic\n\tconst uploadHandler = async (fileUpload: FileUpload) => {\n\t\tconst storageKey = `user-${user.id}-avatar`;\n\t\tawait fileStorage.set(storageKey, fileUpload);\n\t\treturn fileStorage.get(storageKey);\n\t};\n\tconst formData = await parseFormData(request, uploadHandler);\n\tfor (const [key, value] of formData.entries()) {\n\t\tconsole.log(key, value);\n\t}\n\treturn Response.json(null);\n}\n"})}),"\n",(0,r.jsx)(t.p,{children:"Create a page with your Uppy instance:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",children:"import Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Xhr from '@uppy/xhr-upload';\nimport { useState } from 'react';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Xhr, { endpoint: '/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\treturn ;\n}\n"})}),"\n",(0,r.jsxs)(t.p,{children:["If you want to send along other form fields with your upload, you can use\n",(0,r.jsx)(t.a,{href:"/docs/form",children:(0,r.jsx)(t.code,{children:"@uppy/form"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-tsx",metastring:"{4,20-23,26-30}",children:"import Uppy from '@uppy/core';\nimport Dashboard from '@uppy/react/lib/Dashboard';\nimport Xhr from '@uppy/xhr-upload';\nimport Form from '@uppy/form';\nimport { useEffect, useState } from 'react';\n\nimport '@uppy/core/dist/style.min.css';\nimport '@uppy/dashboard/dist/style.min.css';\n\nfunction createUppy() {\n\treturn new Uppy().use(Xhr, { endpoint: '/upload' });\n}\n\nexport default function UppyDashboard() {\n\t// Important: use an initializer function to prevent the state from recreating.\n\tconst [uppy] = useState(createUppy);\n\n\t// @uppy/form is client-side only so we need to install it\n\t// when the component is mounted.\n\tuseEffect(() => {\n\t\tuppy.use(Form, { target: '#form' });\n\t\treturn () => uppy.removePlugin(uppy.getPlugin('Form')!);\n\t}, [uppy]);\n\n\treturn (\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t;\n\t\t\n\t);\n}\n"})}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Add client-side file ",(0,r.jsx)(t.a,{href:"/docs/uppy/#restrictions",children:"restrictions"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Upload files together with other form fields with ",(0,r.jsx)(t.a,{href:"/docs/form",children:(0,r.jsx)(t.code,{children:"@uppy/form"})}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Use your ",(0,r.jsx)(t.a,{href:"/docs/locales",children:"language of choice"})," instead of English."]}),"\n",(0,r.jsxs)(t.li,{children:["Add an ",(0,r.jsx)(t.a,{href:"docs/image-editor",children:"image editor"})," for cropping and resizing images."]}),"\n",(0,r.jsxs)(t.li,{children:["Download files from remote sources, such as ",(0,r.jsx)(t.a,{href:"docs/google-drive",children:"Google Drive"}),"\nand ",(0,r.jsx)(t.a,{href:"docs/dropbox",children:"Dropbox"}),", with ",(0,r.jsx)(t.a,{href:"/docs/companion",children:"Companion"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Add ",(0,r.jsx)(t.a,{href:"/docs/golden-retriever",children:"Golden Retriever"})," to save selected files in your\nbrowser cache, so that if the browser crashes, or the user accidentally closes\nthe tab, Uppy can restore everything and continue uploading as if nothing\nhappened."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.e875f297.js b/assets/js/runtime~main.980a1ce9.js similarity index 99% rename from assets/js/runtime~main.e875f297.js rename to assets/js/runtime~main.980a1ce9.js index 63b5c5882..d232667c2 100644 --- a/assets/js/runtime~main.e875f297.js +++ b/assets/js/runtime~main.980a1ce9.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,c,f,d,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,f,d)=>{if(!c){var b=1/0;for(i=0;i=d)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[c,f,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&f&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(d,b),d},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({12:"ffea83a1",26:"a7d6c011",46:"92eedc5f",119:"58cdabb1",261:"e108da56",453:"c13a9e13",497:"b2cf008e",504:"aba21aa0",511:"4a1c7000",529:"08af526d",581:"38a4880d",610:"f19dbf9b",651:"679445d3",700:"5c0f72ee",713:"f367a1d7",784:"47c9df64",812:"f883ecfd",920:"fc9c14b7",957:"c141421f",990:"ff925353",999:"4155716e",1014:"94a42638",1017:"136bbe0e",1109:"5e02ed38",1110:"c179f821",1235:"a7456010",1248:"b901d2a0",1311:"fe71c34a",1404:"e78b2ea9",1447:"f45d457e",1564:"d63f7a55",1565:"229d3faa",1577:"31f69cfd",1630:"bfe76410",1655:"a6bc873f",1690:"a36e5e0d",1692:"586a3e7f",1707:"a208b9fd",1728:"d064fb9b",1814:"93f1c623",1832:"092ec695",1903:"acecf23e",2017:"622513a6",2066:"e2a7e47b",2081:"babb88a2",2089:"3de23f1f",2112:"d2f14b9c",2138:"1a4e3797",2142:"8976754c",2163:"3575701f",2178:"8602fdcb",2214:"afcca1ce",2241:"fa5069d2",2245:"18dd2876",2256:"11b43341",2278:"23374ca6",2299:"c9552808",2463:"21909a15",2519:"babf1f42",2539:"9c6f140c",2546:"142d54c6",2580:"1c7f3fba",2703:"394fccd8",2711:"9e4087bc",2738:"6c99beda",2757:"16110bbe",2758:"b777471b",2786:"88189fcb",2797:"a3c98257",2834:"fdfa6430",2936:"83d8911e",2955:"a6676653",2962:"c61c7ede",3009:"cb30cc5e",3010:"4f4468bc",3019:"e5b49aa5",3078:"08f3f4cc",3094:"5dc9ee6b",3227:"da2a9aff",3249:"ccc49370",3325:"566d3703",3327:"f198285e",3340:"20b91070",3345:"8d2431f2",3361:"283c52f1",3363:"235669fe",3382:"7aafb598",3411:"664edd56",3465:"af99cef3",3734:"67d28ee8",3786:"a3648137",3894:"7d82e5a3",3902:"a34a8390",3904:"930a7630",3954:"98f1a71b",3973:"cfbb06c6",3981:"d4aacb72",4015:"9a10854d",4026:"f069645e",4036:"16276fe8",4127:"a6c1aad8",4131:"d5df2672",4194:"f44ccb4c",4228:"9cbd58cc",4257:"685a80c7",4273:"8f5850f6",4389:"24cffed0",4439:"07a179bc",4453:"e23e9156",4471:"e1402893",4473:"ede3a78e",4496:"704a58f6",4518:"942d65cb",4583:"1df93b7f",4622:"027f10dc",4637:"531c790f",4720:"c40b145d",4791:"5ecd4de8",4817:"94e211f4",4864:"661d1245",4899:"5efe782f",4933:"b5ec05bf",4965:"1eb44bce",4999:"a9dc9ea4",5005:"aa07e3ed",5028:"336693bc",5030:"c2213c69",5071:"a7fcf76b",5175:"9e4b1a4f",5262:"e30c1ee3",5336:"82786208",5350:"79b7d2c3",5440:"adfd48ae",5474:"e3e0b956",5502:"76d294c2",5510:"9ea63edf",5582:"a2ca7bed",5631:"bdca9dbc",5725:"00131434",5728:"82dbecdc",5742:"9b3ad4cf",5771:"30a09441",5879:"797e654c",5886:"56e9c01d",5951:"93f2bd64",5958:"d1481296",5960:"7e0de64b",6006:"8f6bf6d7",6056:"fa683b78",6061:"1f391b9e",6118:"a6d3376c",6162:"306acb7a",6181:"a3cf064c",6226:"4d21f97d",6351:"ea70c07d",6355:"0e9f4299",6356:"3d548997",6469:"da46342b",6508:"529c1948",6642:"413ee6da",6687:"abdc1bd7",6713:"e5a8ecbe",6732:"fc5fe36a",6770:"0a352486",6815:"0ffee8d2",6843:"7c1978de",6916:"89efc8e9",6939:"09c861ad",6948:"1a8bd058",6974:"14cd82f7",7027:"00a490d4",7098:"a7bd4aaa",7175:"46630559",7267:"ed57f728",7472:"814f3328",7512:"b30a8cb2",7518:"36fd68db",7519:"248951eb",7575:"6b053967",7578:"2d6773bb",7602:"c650178e",7624:"2721a29c",7637:"ea6c816f",7643:"a6aa9e1f",7652:"cb24fa34",7723:"d72f40f1",7789:"2e5b31a7",7794:"ec9fe4b1",7824:"544d2727",7873:"427b2579",7876:"d7f1db9b",7886:"1ca424ca",7939:"a101b52f",7985:"df8c2009",8027:"71014034",8106:"69e2f2ac",8114:"3bd4e7aa",8171:"cb2f5e3d",8198:"a399eef3",8277:"3cfde66e",8304:"eb1e735e",8305:"78eda74d",8343:"343a9a0c",8367:"6db5f955",8375:"c473cf04",8401:"17896441",8564:"73cccce6",8577:"8bb87326",8595:"0777732e",8612:"f4f832a3",8658:"0f506598",8706:"70f6adf5",8732:"42ede607",8749:"dbfc4782",8778:"b36db3f9",8791:"6c298c4e",8938:"446ac78d",8958:"84218266",9037:"8d1bbdd9",9048:"a94703ab",9068:"ba9b88b0",9079:"6ed66133",9167:"97fdc0cf",9299:"872c7f2c",9455:"3caa9f12",9462:"52511c5a",9525:"abefdedc",9563:"6e519bfb",9586:"4af0a23b",9592:"9c2555a5",9610:"c6b4ecbb",9647:"5e95c892",9671:"65a2dd4f",9703:"05fe4297",9707:"685abe07",9726:"b6163ed4",9740:"8b6df184",9777:"f686e2b7",9803:"5477a271",9818:"993f0a5f",9821:"77b28703",9858:"36994c47",9871:"c4f9047c",9945:"6d7ff45f",9948:"bdc617d6",9957:"a370eb5e"}[e]||e)+"."+{12:"12a5ce36",26:"a5e27f1a",46:"ed21d261",119:"f24e4b68",250:"83bf524f",261:"9611d142",416:"e761701a",453:"73c8adc2",497:"f1687f35",504:"172df169",511:"4455e117",529:"06642de0",581:"5e6e13a2",610:"01e364f3",651:"426db116",700:"0e684bf5",713:"4ec195b3",784:"1acd5aa5",812:"43e88361",920:"1386ab08",957:"e3218c1c",990:"72c08614",999:"3ad1d483",1014:"64df9ad1",1017:"50e84f8e",1109:"b14fc775",1110:"98525310",1235:"a2a82f76",1248:"789d06cf",1311:"c530da9e",1404:"d97fb5d2",1432:"773c2c55",1447:"901f6d55",1564:"77467d65",1565:"ff367af5",1577:"aaac887e",1630:"0c3db016",1655:"976f0acb",1690:"1ea01cdd",1692:"5bcaa0f8",1707:"5d63105c",1728:"bf11e2b7",1814:"ae8b065e",1832:"9562cf1f",1903:"98e9216d",2017:"1f07d09e",2057:"92f2f7fe",2066:"b83fe571",2081:"2464c870",2089:"9396ddd8",2112:"2bad4e23",2138:"b6c097e1",2142:"e5e2e27c",2163:"d73bc300",2178:"be96437a",2214:"83a5bf44",2237:"15e72f0c",2241:"b77224ca",2245:"c2f318ad",2256:"e15d67ce",2278:"2bff34e1",2299:"b38e7521",2463:"be8c11cc",2519:"24e6d7f8",2539:"dc034041",2546:"842fb0ed",2580:"7a35ba98",2703:"d090de55",2711:"3d58a0a4",2738:"0c2c5fa1",2757:"afec1442",2758:"2dc21ae4",2786:"5a18ea19",2797:"72964219",2834:"d06dc452",2936:"7cf776cc",2955:"3c894728",2962:"42fb9725",3009:"365ed2f3",3010:"ee9028dd",3019:"4d6f85d2",3078:"2d5ccf73",3094:"51d37553",3176:"ee5bfc49",3227:"54c8b8b2",3249:"3064de3f",3325:"d9bebec6",3327:"0b642938",3340:"9206dcfc",3345:"6f7e0d86",3361:"672ba39f",3363:"91afc4bb",3382:"43833c44",3411:"fc8da29f",3465:"d46c4c55",3734:"53938e20",3786:"eb8e787d",3894:"6cd5959a",3902:"a2775c04",3904:"06a10bb6",3954:"0fc78076",3973:"cb9dbb2d",3981:"f218fc61",4015:"25854ed2",4026:"34684326",4036:"356a0173",4127:"3d72e869",4131:"c3afe358",4194:"53dd69d1",4228:"90052eb5",4257:"c9eb85a2",4273:"09d0eca4",4389:"60ce781b",4439:"a7dce6a1",4453:"4e2b02bc",4471:"fc359f76",4473:"6bd85ec6",4496:"f5ad67c0",4518:"09e854a1",4539:"38d09035",4583:"95e93f49",4622:"2cf1c160",4637:"83e2e0be",4720:"edd730ea",4791:"a4d308d4",4817:"8a835bec",4864:"ce5f5a1a",4899:"d165fab3",4933:"582c0b98",4965:"1e6de9af",4999:"9b385fd9",5005:"149aaeb6",5028:"dda751c7",5030:"c4f16674",5071:"e78cb8fa",5175:"78cf4e58",5262:"d016101e",5336:"4647aa77",5350:"e3c9d126",5440:"2ef7b302",5474:"6ce99c59",5502:"948abcd0",5510:"1ae29420",5582:"be9a05ac",5631:"896e2e77",5725:"f3546669",5728:"bd31e9cb",5742:"50505ba8",5771:"7ff22039",5879:"e430a8c1",5886:"7a2b2ab8",5951:"5fd87514",5958:"6288beab",5960:"dba739f8",6006:"ef19e9e9",6056:"84fe70e0",6061:"62b3241d",6118:"bffe4f7c",6162:"bcddc219",6181:"3457c8e6",6226:"17a13a84",6351:"4c779984",6355:"0633b908",6356:"0945b993",6469:"cf940da7",6508:"1b18852b",6642:"6202eb3f",6687:"33a6b8fd",6713:"abd0a76a",6732:"e28b84ec",6770:"f42c6a0b",6815:"15a368a7",6843:"d5ab8100",6916:"59dcbe36",6939:"d39956b7",6948:"840657b5",6974:"dabf9392",7027:"f634732a",7081:"fec715a0",7098:"159ff897",7175:"40a4d67f",7267:"be0baa93",7472:"21967dac",7512:"c77a57ce",7518:"9ccad758",7519:"bc65b230",7575:"a0871bf2",7578:"71839ee8",7602:"d1b81cef",7624:"9b30c2a7",7637:"4add7155",7643:"0453e963",7652:"33cb6c28",7723:"f2c88bde",7789:"942566bd",7794:"5da763be",7824:"b39f90dd",7873:"b63f7ca1",7876:"578ea7a8",7886:"f237911c",7939:"02fe9c7c",7985:"6671a18f",8027:"1f8f6d89",8106:"17a7331f",8114:"8d53e537",8157:"7ba53bea",8171:"fde4fcb2",8198:"8a86c6f8",8277:"3b41491b",8304:"34462480",8305:"57540627",8343:"cc86dde0",8367:"16ac7270",8375:"3a1d2b46",8401:"e468c417",8564:"59c17760",8577:"6447e7a3",8595:"d743c11d",8612:"2866c094",8658:"d030ec2a",8706:"f5d577cd",8732:"40b5db97",8749:"8ed8c75d",8778:"7890ca5d",8791:"590790db",8913:"d4751005",8938:"8ec34546",8958:"9d51fd2a",9037:"c9f112d3",9048:"b70ccac4",9068:"9a61cde2",9079:"13a25d34",9167:"4e28143a",9299:"c5a1e838",9455:"751be3f4",9462:"48f8f126",9525:"1c3c5d39",9563:"dc09942f",9586:"537de0bb",9592:"3d5966be",9610:"bb3c9623",9647:"940ba550",9671:"70f3409b",9703:"caa993f9",9707:"ff56963f",9726:"41453e82",9740:"e70b319e",9777:"a78fd27d",9803:"000e6abb",9818:"e7af4f09",9821:"22154af2",9858:"901d74aa",9871:"ab37fbe9",9945:"df14887d",9948:"b8ab2bff",9957:"ee606e88"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="uppy-io:",r.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",46630559:"7175",71014034:"8027",82786208:"5336",84218266:"8958",ffea83a1:"12",a7d6c011:"26","92eedc5f":"46","58cdabb1":"119",e108da56:"261",c13a9e13:"453",b2cf008e:"497",aba21aa0:"504","4a1c7000":"511","08af526d":"529","38a4880d":"581",f19dbf9b:"610","679445d3":"651","5c0f72ee":"700",f367a1d7:"713","47c9df64":"784",f883ecfd:"812",fc9c14b7:"920",c141421f:"957",ff925353:"990","4155716e":"999","94a42638":"1014","136bbe0e":"1017","5e02ed38":"1109",c179f821:"1110",a7456010:"1235",b901d2a0:"1248",fe71c34a:"1311",e78b2ea9:"1404",f45d457e:"1447",d63f7a55:"1564","229d3faa":"1565","31f69cfd":"1577",bfe76410:"1630",a6bc873f:"1655",a36e5e0d:"1690","586a3e7f":"1692",a208b9fd:"1707",d064fb9b:"1728","93f1c623":"1814","092ec695":"1832",acecf23e:"1903","622513a6":"2017",e2a7e47b:"2066",babb88a2:"2081","3de23f1f":"2089",d2f14b9c:"2112","1a4e3797":"2138","8976754c":"2142","3575701f":"2163","8602fdcb":"2178",afcca1ce:"2214",fa5069d2:"2241","18dd2876":"2245","11b43341":"2256","23374ca6":"2278",c9552808:"2299","21909a15":"2463",babf1f42:"2519","9c6f140c":"2539","142d54c6":"2546","1c7f3fba":"2580","394fccd8":"2703","9e4087bc":"2711","6c99beda":"2738","16110bbe":"2757",b777471b:"2758","88189fcb":"2786",a3c98257:"2797",fdfa6430:"2834","83d8911e":"2936",a6676653:"2955",c61c7ede:"2962",cb30cc5e:"3009","4f4468bc":"3010",e5b49aa5:"3019","08f3f4cc":"3078","5dc9ee6b":"3094",da2a9aff:"3227",ccc49370:"3249","566d3703":"3325",f198285e:"3327","20b91070":"3340","8d2431f2":"3345","283c52f1":"3361","235669fe":"3363","7aafb598":"3382","664edd56":"3411",af99cef3:"3465","67d28ee8":"3734",a3648137:"3786","7d82e5a3":"3894",a34a8390:"3902","930a7630":"3904","98f1a71b":"3954",cfbb06c6:"3973",d4aacb72:"3981","9a10854d":"4015",f069645e:"4026","16276fe8":"4036",a6c1aad8:"4127",d5df2672:"4131",f44ccb4c:"4194","9cbd58cc":"4228","685a80c7":"4257","8f5850f6":"4273","24cffed0":"4389","07a179bc":"4439",e23e9156:"4453",e1402893:"4471",ede3a78e:"4473","704a58f6":"4496","942d65cb":"4518","1df93b7f":"4583","027f10dc":"4622","531c790f":"4637",c40b145d:"4720","5ecd4de8":"4791","94e211f4":"4817","661d1245":"4864","5efe782f":"4899",b5ec05bf:"4933","1eb44bce":"4965",a9dc9ea4:"4999",aa07e3ed:"5005","336693bc":"5028",c2213c69:"5030",a7fcf76b:"5071","9e4b1a4f":"5175",e30c1ee3:"5262","79b7d2c3":"5350",adfd48ae:"5440",e3e0b956:"5474","76d294c2":"5502","9ea63edf":"5510",a2ca7bed:"5582",bdca9dbc:"5631","00131434":"5725","82dbecdc":"5728","9b3ad4cf":"5742","30a09441":"5771","797e654c":"5879","56e9c01d":"5886","93f2bd64":"5951",d1481296:"5958","7e0de64b":"5960","8f6bf6d7":"6006",fa683b78:"6056","1f391b9e":"6061",a6d3376c:"6118","306acb7a":"6162",a3cf064c:"6181","4d21f97d":"6226",ea70c07d:"6351","0e9f4299":"6355","3d548997":"6356",da46342b:"6469","529c1948":"6508","413ee6da":"6642",abdc1bd7:"6687",e5a8ecbe:"6713",fc5fe36a:"6732","0a352486":"6770","0ffee8d2":"6815","7c1978de":"6843","89efc8e9":"6916","09c861ad":"6939","1a8bd058":"6948","14cd82f7":"6974","00a490d4":"7027",a7bd4aaa:"7098",ed57f728:"7267","814f3328":"7472",b30a8cb2:"7512","36fd68db":"7518","248951eb":"7519","6b053967":"7575","2d6773bb":"7578",c650178e:"7602","2721a29c":"7624",ea6c816f:"7637",a6aa9e1f:"7643",cb24fa34:"7652",d72f40f1:"7723","2e5b31a7":"7789",ec9fe4b1:"7794","544d2727":"7824","427b2579":"7873",d7f1db9b:"7876","1ca424ca":"7886",a101b52f:"7939",df8c2009:"7985","69e2f2ac":"8106","3bd4e7aa":"8114",cb2f5e3d:"8171",a399eef3:"8198","3cfde66e":"8277",eb1e735e:"8304","78eda74d":"8305","343a9a0c":"8343","6db5f955":"8367",c473cf04:"8375","73cccce6":"8564","8bb87326":"8577","0777732e":"8595",f4f832a3:"8612","0f506598":"8658","70f6adf5":"8706","42ede607":"8732",dbfc4782:"8749",b36db3f9:"8778","6c298c4e":"8791","446ac78d":"8938","8d1bbdd9":"9037",a94703ab:"9048",ba9b88b0:"9068","6ed66133":"9079","97fdc0cf":"9167","872c7f2c":"9299","3caa9f12":"9455","52511c5a":"9462",abefdedc:"9525","6e519bfb":"9563","4af0a23b":"9586","9c2555a5":"9592",c6b4ecbb:"9610","5e95c892":"9647","65a2dd4f":"9671","05fe4297":"9703","685abe07":"9707",b6163ed4:"9726","8b6df184":"9740",f686e2b7:"9777","5477a271":"9803","993f0a5f":"9818","77b28703":"9821","36994c47":"9858",c4f9047c:"9871","6d7ff45f":"9945",bdc617d6:"9948",a370eb5e:"9957"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,c)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,f[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(a&&a(c);n{"use strict";var e,a,c,f,d,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,f,d)=>{if(!c){var b=1/0;for(i=0;i=d)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[c,f,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&f&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(d,b),d},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({12:"ffea83a1",26:"a7d6c011",46:"92eedc5f",119:"58cdabb1",261:"e108da56",453:"c13a9e13",497:"b2cf008e",504:"aba21aa0",511:"4a1c7000",529:"08af526d",581:"38a4880d",610:"f19dbf9b",651:"679445d3",700:"5c0f72ee",713:"f367a1d7",784:"47c9df64",812:"f883ecfd",920:"fc9c14b7",957:"c141421f",990:"ff925353",999:"4155716e",1014:"94a42638",1017:"136bbe0e",1109:"5e02ed38",1110:"c179f821",1235:"a7456010",1248:"b901d2a0",1311:"fe71c34a",1404:"e78b2ea9",1447:"f45d457e",1564:"d63f7a55",1565:"229d3faa",1577:"31f69cfd",1630:"bfe76410",1655:"a6bc873f",1690:"a36e5e0d",1692:"586a3e7f",1707:"a208b9fd",1728:"d064fb9b",1814:"93f1c623",1832:"092ec695",1903:"acecf23e",2017:"622513a6",2066:"e2a7e47b",2081:"babb88a2",2089:"3de23f1f",2112:"d2f14b9c",2138:"1a4e3797",2142:"8976754c",2163:"3575701f",2178:"8602fdcb",2214:"afcca1ce",2241:"fa5069d2",2245:"18dd2876",2256:"11b43341",2278:"23374ca6",2299:"c9552808",2463:"21909a15",2519:"babf1f42",2539:"9c6f140c",2546:"142d54c6",2580:"1c7f3fba",2703:"394fccd8",2711:"9e4087bc",2738:"6c99beda",2757:"16110bbe",2758:"b777471b",2786:"88189fcb",2797:"a3c98257",2834:"fdfa6430",2936:"83d8911e",2955:"a6676653",2962:"c61c7ede",3009:"cb30cc5e",3010:"4f4468bc",3019:"e5b49aa5",3078:"08f3f4cc",3094:"5dc9ee6b",3227:"da2a9aff",3249:"ccc49370",3325:"566d3703",3327:"f198285e",3340:"20b91070",3345:"8d2431f2",3361:"283c52f1",3363:"235669fe",3382:"7aafb598",3411:"664edd56",3465:"af99cef3",3734:"67d28ee8",3786:"a3648137",3894:"7d82e5a3",3902:"a34a8390",3904:"930a7630",3954:"98f1a71b",3973:"cfbb06c6",3981:"d4aacb72",4015:"9a10854d",4026:"f069645e",4036:"16276fe8",4127:"a6c1aad8",4131:"d5df2672",4194:"f44ccb4c",4228:"9cbd58cc",4257:"685a80c7",4273:"8f5850f6",4389:"24cffed0",4439:"07a179bc",4453:"e23e9156",4471:"e1402893",4473:"ede3a78e",4496:"704a58f6",4518:"942d65cb",4583:"1df93b7f",4622:"027f10dc",4637:"531c790f",4720:"c40b145d",4791:"5ecd4de8",4817:"94e211f4",4864:"661d1245",4899:"5efe782f",4933:"b5ec05bf",4965:"1eb44bce",4999:"a9dc9ea4",5005:"aa07e3ed",5028:"336693bc",5030:"c2213c69",5071:"a7fcf76b",5175:"9e4b1a4f",5262:"e30c1ee3",5336:"82786208",5350:"79b7d2c3",5440:"adfd48ae",5474:"e3e0b956",5502:"76d294c2",5510:"9ea63edf",5582:"a2ca7bed",5631:"bdca9dbc",5725:"00131434",5728:"82dbecdc",5742:"9b3ad4cf",5771:"30a09441",5879:"797e654c",5886:"56e9c01d",5951:"93f2bd64",5958:"d1481296",5960:"7e0de64b",6006:"8f6bf6d7",6056:"fa683b78",6061:"1f391b9e",6118:"a6d3376c",6162:"306acb7a",6181:"a3cf064c",6226:"4d21f97d",6351:"ea70c07d",6355:"0e9f4299",6356:"3d548997",6469:"da46342b",6508:"529c1948",6642:"413ee6da",6687:"abdc1bd7",6713:"e5a8ecbe",6732:"fc5fe36a",6770:"0a352486",6815:"0ffee8d2",6843:"7c1978de",6916:"89efc8e9",6939:"09c861ad",6948:"1a8bd058",6974:"14cd82f7",7027:"00a490d4",7098:"a7bd4aaa",7175:"46630559",7267:"ed57f728",7472:"814f3328",7512:"b30a8cb2",7518:"36fd68db",7519:"248951eb",7575:"6b053967",7578:"2d6773bb",7602:"c650178e",7624:"2721a29c",7637:"ea6c816f",7643:"a6aa9e1f",7652:"cb24fa34",7723:"d72f40f1",7789:"2e5b31a7",7794:"ec9fe4b1",7824:"544d2727",7873:"427b2579",7876:"d7f1db9b",7886:"1ca424ca",7939:"a101b52f",7985:"df8c2009",8027:"71014034",8106:"69e2f2ac",8114:"3bd4e7aa",8171:"cb2f5e3d",8198:"a399eef3",8277:"3cfde66e",8304:"eb1e735e",8305:"78eda74d",8343:"343a9a0c",8367:"6db5f955",8375:"c473cf04",8401:"17896441",8564:"73cccce6",8577:"8bb87326",8595:"0777732e",8612:"f4f832a3",8658:"0f506598",8706:"70f6adf5",8732:"42ede607",8749:"dbfc4782",8778:"b36db3f9",8791:"6c298c4e",8938:"446ac78d",8958:"84218266",9037:"8d1bbdd9",9048:"a94703ab",9068:"ba9b88b0",9079:"6ed66133",9167:"97fdc0cf",9299:"872c7f2c",9455:"3caa9f12",9462:"52511c5a",9525:"abefdedc",9563:"6e519bfb",9586:"4af0a23b",9592:"9c2555a5",9610:"c6b4ecbb",9647:"5e95c892",9671:"65a2dd4f",9703:"05fe4297",9707:"685abe07",9726:"b6163ed4",9740:"8b6df184",9777:"f686e2b7",9803:"5477a271",9818:"993f0a5f",9821:"77b28703",9858:"36994c47",9871:"c4f9047c",9945:"6d7ff45f",9948:"bdc617d6",9957:"a370eb5e"}[e]||e)+"."+{12:"12a5ce36",26:"a5e27f1a",46:"ed21d261",119:"f24e4b68",250:"83bf524f",261:"9611d142",416:"e761701a",453:"73c8adc2",497:"f1687f35",504:"172df169",511:"4455e117",529:"06642de0",581:"5e6e13a2",610:"01e364f3",651:"426db116",700:"0e684bf5",713:"4ec195b3",784:"1acd5aa5",812:"43e88361",920:"1386ab08",957:"e3218c1c",990:"72c08614",999:"3ad1d483",1014:"64df9ad1",1017:"50e84f8e",1109:"b14fc775",1110:"98525310",1235:"a2a82f76",1248:"789d06cf",1311:"c530da9e",1404:"d97fb5d2",1432:"773c2c55",1447:"901f6d55",1564:"77467d65",1565:"ff367af5",1577:"aaac887e",1630:"0c3db016",1655:"976f0acb",1690:"1ea01cdd",1692:"5bcaa0f8",1707:"5d63105c",1728:"bf11e2b7",1814:"ae8b065e",1832:"9562cf1f",1903:"98e9216d",2017:"1f07d09e",2057:"92f2f7fe",2066:"b83fe571",2081:"2464c870",2089:"9396ddd8",2112:"2bad4e23",2138:"b6c097e1",2142:"e5e2e27c",2163:"d73bc300",2178:"be96437a",2214:"83a5bf44",2237:"15e72f0c",2241:"b77224ca",2245:"c2f318ad",2256:"e15d67ce",2278:"2bff34e1",2299:"b38e7521",2463:"be8c11cc",2519:"24e6d7f8",2539:"dc034041",2546:"842fb0ed",2580:"7a35ba98",2703:"d090de55",2711:"3d58a0a4",2738:"0c2c5fa1",2757:"afec1442",2758:"2dc21ae4",2786:"5a18ea19",2797:"72964219",2834:"d06dc452",2936:"7cf776cc",2955:"3c894728",2962:"42fb9725",3009:"365ed2f3",3010:"ee9028dd",3019:"4d6f85d2",3078:"2d5ccf73",3094:"51d37553",3176:"ee5bfc49",3227:"54c8b8b2",3249:"3064de3f",3325:"d9bebec6",3327:"0b642938",3340:"9206dcfc",3345:"6f7e0d86",3361:"672ba39f",3363:"91afc4bb",3382:"43833c44",3411:"fc8da29f",3465:"d46c4c55",3734:"53938e20",3786:"eb8e787d",3894:"6cd5959a",3902:"a2775c04",3904:"06a10bb6",3954:"0fc78076",3973:"cb9dbb2d",3981:"f218fc61",4015:"25854ed2",4026:"34684326",4036:"356a0173",4127:"3d72e869",4131:"c3afe358",4194:"53dd69d1",4228:"90052eb5",4257:"c9eb85a2",4273:"09d0eca4",4389:"60ce781b",4439:"a7dce6a1",4453:"4e2b02bc",4471:"fc359f76",4473:"6bd85ec6",4496:"f5ad67c0",4518:"09e854a1",4539:"38d09035",4583:"95e93f49",4622:"2cf1c160",4637:"83e2e0be",4720:"edd730ea",4791:"a4d308d4",4817:"8a835bec",4864:"ce5f5a1a",4899:"d165fab3",4933:"582c0b98",4965:"1e6de9af",4999:"9b385fd9",5005:"149aaeb6",5028:"dda751c7",5030:"c4f16674",5071:"e78cb8fa",5175:"78cf4e58",5262:"d016101e",5336:"4647aa77",5350:"e3c9d126",5440:"2ef7b302",5474:"6ce99c59",5502:"948abcd0",5510:"1ae29420",5582:"be9a05ac",5631:"896e2e77",5725:"f3546669",5728:"bd31e9cb",5742:"50505ba8",5771:"7ff22039",5879:"e430a8c1",5886:"7a2b2ab8",5951:"5fd87514",5958:"6288beab",5960:"dba739f8",6006:"ef19e9e9",6056:"84fe70e0",6061:"62b3241d",6118:"bffe4f7c",6162:"bcddc219",6181:"3457c8e6",6226:"17a13a84",6351:"4c779984",6355:"0633b908",6356:"0945b993",6469:"cf940da7",6508:"1b18852b",6642:"6202eb3f",6687:"33a6b8fd",6713:"abd0a76a",6732:"e28b84ec",6770:"f42c6a0b",6815:"15a368a7",6843:"d5ab8100",6916:"59dcbe36",6939:"d39956b7",6948:"840657b5",6974:"dabf9392",7027:"f634732a",7081:"fec715a0",7098:"159ff897",7175:"40a4d67f",7267:"be0baa93",7472:"21967dac",7512:"c77a57ce",7518:"9ccad758",7519:"bc65b230",7575:"a0871bf2",7578:"71839ee8",7602:"d1b81cef",7624:"9b30c2a7",7637:"4add7155",7643:"0453e963",7652:"33cb6c28",7723:"f2c88bde",7789:"942566bd",7794:"5da763be",7824:"b39f90dd",7873:"a8a4ec71",7876:"578ea7a8",7886:"f237911c",7939:"02fe9c7c",7985:"6671a18f",8027:"1f8f6d89",8106:"17a7331f",8114:"8d53e537",8157:"7ba53bea",8171:"fde4fcb2",8198:"8a86c6f8",8277:"3b41491b",8304:"34462480",8305:"57540627",8343:"cc86dde0",8367:"16ac7270",8375:"3a1d2b46",8401:"e468c417",8564:"59c17760",8577:"6447e7a3",8595:"d743c11d",8612:"2866c094",8658:"d030ec2a",8706:"f5d577cd",8732:"40b5db97",8749:"8ed8c75d",8778:"7890ca5d",8791:"590790db",8913:"d4751005",8938:"8ec34546",8958:"9d51fd2a",9037:"c9f112d3",9048:"b70ccac4",9068:"9a61cde2",9079:"13a25d34",9167:"4e28143a",9299:"c5a1e838",9455:"751be3f4",9462:"48f8f126",9525:"1c3c5d39",9563:"dc09942f",9586:"537de0bb",9592:"3d5966be",9610:"bb3c9623",9647:"940ba550",9671:"70f3409b",9703:"caa993f9",9707:"ff56963f",9726:"41453e82",9740:"e70b319e",9777:"a78fd27d",9803:"000e6abb",9818:"e7af4f09",9821:"22154af2",9858:"901d74aa",9871:"ab37fbe9",9945:"df14887d",9948:"b8ab2bff",9957:"ee606e88"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="uppy-io:",r.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{t.onerror=t.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",46630559:"7175",71014034:"8027",82786208:"5336",84218266:"8958",ffea83a1:"12",a7d6c011:"26","92eedc5f":"46","58cdabb1":"119",e108da56:"261",c13a9e13:"453",b2cf008e:"497",aba21aa0:"504","4a1c7000":"511","08af526d":"529","38a4880d":"581",f19dbf9b:"610","679445d3":"651","5c0f72ee":"700",f367a1d7:"713","47c9df64":"784",f883ecfd:"812",fc9c14b7:"920",c141421f:"957",ff925353:"990","4155716e":"999","94a42638":"1014","136bbe0e":"1017","5e02ed38":"1109",c179f821:"1110",a7456010:"1235",b901d2a0:"1248",fe71c34a:"1311",e78b2ea9:"1404",f45d457e:"1447",d63f7a55:"1564","229d3faa":"1565","31f69cfd":"1577",bfe76410:"1630",a6bc873f:"1655",a36e5e0d:"1690","586a3e7f":"1692",a208b9fd:"1707",d064fb9b:"1728","93f1c623":"1814","092ec695":"1832",acecf23e:"1903","622513a6":"2017",e2a7e47b:"2066",babb88a2:"2081","3de23f1f":"2089",d2f14b9c:"2112","1a4e3797":"2138","8976754c":"2142","3575701f":"2163","8602fdcb":"2178",afcca1ce:"2214",fa5069d2:"2241","18dd2876":"2245","11b43341":"2256","23374ca6":"2278",c9552808:"2299","21909a15":"2463",babf1f42:"2519","9c6f140c":"2539","142d54c6":"2546","1c7f3fba":"2580","394fccd8":"2703","9e4087bc":"2711","6c99beda":"2738","16110bbe":"2757",b777471b:"2758","88189fcb":"2786",a3c98257:"2797",fdfa6430:"2834","83d8911e":"2936",a6676653:"2955",c61c7ede:"2962",cb30cc5e:"3009","4f4468bc":"3010",e5b49aa5:"3019","08f3f4cc":"3078","5dc9ee6b":"3094",da2a9aff:"3227",ccc49370:"3249","566d3703":"3325",f198285e:"3327","20b91070":"3340","8d2431f2":"3345","283c52f1":"3361","235669fe":"3363","7aafb598":"3382","664edd56":"3411",af99cef3:"3465","67d28ee8":"3734",a3648137:"3786","7d82e5a3":"3894",a34a8390:"3902","930a7630":"3904","98f1a71b":"3954",cfbb06c6:"3973",d4aacb72:"3981","9a10854d":"4015",f069645e:"4026","16276fe8":"4036",a6c1aad8:"4127",d5df2672:"4131",f44ccb4c:"4194","9cbd58cc":"4228","685a80c7":"4257","8f5850f6":"4273","24cffed0":"4389","07a179bc":"4439",e23e9156:"4453",e1402893:"4471",ede3a78e:"4473","704a58f6":"4496","942d65cb":"4518","1df93b7f":"4583","027f10dc":"4622","531c790f":"4637",c40b145d:"4720","5ecd4de8":"4791","94e211f4":"4817","661d1245":"4864","5efe782f":"4899",b5ec05bf:"4933","1eb44bce":"4965",a9dc9ea4:"4999",aa07e3ed:"5005","336693bc":"5028",c2213c69:"5030",a7fcf76b:"5071","9e4b1a4f":"5175",e30c1ee3:"5262","79b7d2c3":"5350",adfd48ae:"5440",e3e0b956:"5474","76d294c2":"5502","9ea63edf":"5510",a2ca7bed:"5582",bdca9dbc:"5631","00131434":"5725","82dbecdc":"5728","9b3ad4cf":"5742","30a09441":"5771","797e654c":"5879","56e9c01d":"5886","93f2bd64":"5951",d1481296:"5958","7e0de64b":"5960","8f6bf6d7":"6006",fa683b78:"6056","1f391b9e":"6061",a6d3376c:"6118","306acb7a":"6162",a3cf064c:"6181","4d21f97d":"6226",ea70c07d:"6351","0e9f4299":"6355","3d548997":"6356",da46342b:"6469","529c1948":"6508","413ee6da":"6642",abdc1bd7:"6687",e5a8ecbe:"6713",fc5fe36a:"6732","0a352486":"6770","0ffee8d2":"6815","7c1978de":"6843","89efc8e9":"6916","09c861ad":"6939","1a8bd058":"6948","14cd82f7":"6974","00a490d4":"7027",a7bd4aaa:"7098",ed57f728:"7267","814f3328":"7472",b30a8cb2:"7512","36fd68db":"7518","248951eb":"7519","6b053967":"7575","2d6773bb":"7578",c650178e:"7602","2721a29c":"7624",ea6c816f:"7637",a6aa9e1f:"7643",cb24fa34:"7652",d72f40f1:"7723","2e5b31a7":"7789",ec9fe4b1:"7794","544d2727":"7824","427b2579":"7873",d7f1db9b:"7876","1ca424ca":"7886",a101b52f:"7939",df8c2009:"7985","69e2f2ac":"8106","3bd4e7aa":"8114",cb2f5e3d:"8171",a399eef3:"8198","3cfde66e":"8277",eb1e735e:"8304","78eda74d":"8305","343a9a0c":"8343","6db5f955":"8367",c473cf04:"8375","73cccce6":"8564","8bb87326":"8577","0777732e":"8595",f4f832a3:"8612","0f506598":"8658","70f6adf5":"8706","42ede607":"8732",dbfc4782:"8749",b36db3f9:"8778","6c298c4e":"8791","446ac78d":"8938","8d1bbdd9":"9037",a94703ab:"9048",ba9b88b0:"9068","6ed66133":"9079","97fdc0cf":"9167","872c7f2c":"9299","3caa9f12":"9455","52511c5a":"9462",abefdedc:"9525","6e519bfb":"9563","4af0a23b":"9586","9c2555a5":"9592",c6b4ecbb:"9610","5e95c892":"9647","65a2dd4f":"9671","05fe4297":"9703","685abe07":"9707",b6163ed4:"9726","8b6df184":"9740",f686e2b7:"9777","5477a271":"9803","993f0a5f":"9818","77b28703":"9821","36994c47":"9858",c4f9047c:"9871","6d7ff45f":"9945",bdc617d6:"9948",a370eb5e:"9957"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,c)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,f[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(a&&a(c);n - + diff --git a/blog/2016/08/0.8.0/index.html b/blog/2016/08/0.8.0/index.html index d1eaa87df..30bb84e4c 100644 --- a/blog/2016/08/0.8.0/index.html +++ b/blog/2016/08/0.8.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2016/08/0.9.0/index.html b/blog/2016/08/0.9.0/index.html index 8d5c779c9..55eb1b3fa 100644 --- a/blog/2016/08/0.9.0/index.html +++ b/blog/2016/08/0.9.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2016/09/0.10/index.html b/blog/2016/09/0.10/index.html index 3ca535515..34ad1ef59 100644 --- a/blog/2016/09/0.10/index.html +++ b/blog/2016/09/0.10/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2016/11/0.11/index.html b/blog/2016/11/0.11/index.html index 226b32581..c7a95967c 100644 --- a/blog/2016/11/0.11/index.html +++ b/blog/2016/11/0.11/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2016/12/0.12/index.html b/blog/2016/12/0.12/index.html index 2dd91ac95..63bcb7708 100644 --- a/blog/2016/12/0.12/index.html +++ b/blog/2016/12/0.12/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/02/0.14/index.html b/blog/2017/02/0.14/index.html index 727f225bd..34f6104fb 100644 --- a/blog/2017/02/0.14/index.html +++ b/blog/2017/02/0.14/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/03/0.15/index.html b/blog/2017/03/0.15/index.html index fa9d88adb..670f4916f 100644 --- a/blog/2017/03/0.15/index.html +++ b/blog/2017/03/0.15/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/05/0.16/index.html b/blog/2017/05/0.16/index.html index 172ddd20c..06094d000 100644 --- a/blog/2017/05/0.16/index.html +++ b/blog/2017/05/0.16/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/05/0.17/index.html b/blog/2017/05/0.17/index.html index b8b8a1f6a..46931dff4 100644 --- a/blog/2017/05/0.17/index.html +++ b/blog/2017/05/0.17/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/07/golden-retriever/index.html b/blog/2017/07/golden-retriever/index.html index 3c0cffc26..72616ee82 100644 --- a/blog/2017/07/golden-retriever/index.html +++ b/blog/2017/07/golden-retriever/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/08/0.18/index.html b/blog/2017/08/0.18/index.html index 455a263bb..2ca5c8a92 100644 --- a/blog/2017/08/0.18/index.html +++ b/blog/2017/08/0.18/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/09/0.19/index.html b/blog/2017/09/0.19/index.html index 662138215..6134a6622 100644 --- a/blog/2017/09/0.19/index.html +++ b/blog/2017/09/0.19/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/10/0.20/index.html b/blog/2017/10/0.20/index.html index aee386a15..814597b07 100644 --- a/blog/2017/10/0.20/index.html +++ b/blog/2017/10/0.20/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/10/0.21/index.html b/blog/2017/10/0.21/index.html index 7dd4db143..2351e319a 100644 --- a/blog/2017/10/0.21/index.html +++ b/blog/2017/10/0.21/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2017/12/0.22/index.html b/blog/2017/12/0.22/index.html index 6c8b9397a..14724035e 100644 --- a/blog/2017/12/0.22/index.html +++ b/blog/2017/12/0.22/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/02/0.23/index.html b/blog/2018/02/0.23/index.html index 81ba91712..493d941e5 100644 --- a/blog/2018/02/0.23/index.html +++ b/blog/2018/02/0.23/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/04/0.24/index.html b/blog/2018/04/0.24/index.html index 71884a722..14b40db05 100644 --- a/blog/2018/04/0.24/index.html +++ b/blog/2018/04/0.24/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/06/0.25/index.html b/blog/2018/06/0.25/index.html index 949a0f09b..94352c867 100644 --- a/blog/2018/06/0.25/index.html +++ b/blog/2018/06/0.25/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/07/0.26/index.html b/blog/2018/07/0.26/index.html index 78bfe2c6c..ced5a7cf7 100644 --- a/blog/2018/07/0.26/index.html +++ b/blog/2018/07/0.26/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/08/0.27/index.html b/blog/2018/08/0.27/index.html index 239797831..08de48304 100644 --- a/blog/2018/08/0.27/index.html +++ b/blog/2018/08/0.27/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/10/0.28/index.html b/blog/2018/10/0.28/index.html index 8bbfd952c..e7eef8f8d 100644 --- a/blog/2018/10/0.28/index.html +++ b/blog/2018/10/0.28/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2018/12/0.29/index.html b/blog/2018/12/0.29/index.html index 17b6a17ae..bf16ff0ce 100644 --- a/blog/2018/12/0.29/index.html +++ b/blog/2018/12/0.29/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/0.30/index.html b/blog/2019/03/0.30/index.html index b12cbec80..ad86d7077 100644 --- a/blog/2019/03/0.30/index.html +++ b/blog/2019/03/0.30/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-01/index.html b/blog/2019/03/liftoff-01/index.html index 52078f3c4..68a5a15bc 100644 --- a/blog/2019/03/liftoff-01/index.html +++ b/blog/2019/03/liftoff-01/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-02/index.html b/blog/2019/03/liftoff-02/index.html index 39b1026a5..b07a6d902 100644 --- a/blog/2019/03/liftoff-02/index.html +++ b/blog/2019/03/liftoff-02/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-03/index.html b/blog/2019/03/liftoff-03/index.html index 6e24c6a97..da4bb806f 100644 --- a/blog/2019/03/liftoff-03/index.html +++ b/blog/2019/03/liftoff-03/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-04/index.html b/blog/2019/03/liftoff-04/index.html index 5a9685bcf..77dcde72f 100644 --- a/blog/2019/03/liftoff-04/index.html +++ b/blog/2019/03/liftoff-04/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-05/index.html b/blog/2019/03/liftoff-05/index.html index f5695486f..46b95d043 100644 --- a/blog/2019/03/liftoff-05/index.html +++ b/blog/2019/03/liftoff-05/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/03/liftoff-06/index.html b/blog/2019/03/liftoff-06/index.html index fc3b8e5fa..3119ab5cb 100644 --- a/blog/2019/03/liftoff-06/index.html +++ b/blog/2019/03/liftoff-06/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/1.0/index.html b/blog/2019/04/1.0/index.html index a70ae0759..80d35cc69 100644 --- a/blog/2019/04/1.0/index.html +++ b/blog/2019/04/1.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-07/index.html b/blog/2019/04/liftoff-07/index.html index ebb8fa9d4..c23b6edcc 100644 --- a/blog/2019/04/liftoff-07/index.html +++ b/blog/2019/04/liftoff-07/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-08/index.html b/blog/2019/04/liftoff-08/index.html index 0585a5090..9d8dee0f9 100644 --- a/blog/2019/04/liftoff-08/index.html +++ b/blog/2019/04/liftoff-08/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-09/index.html b/blog/2019/04/liftoff-09/index.html index 2cd7c9c67..03f02b9d4 100644 --- a/blog/2019/04/liftoff-09/index.html +++ b/blog/2019/04/liftoff-09/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-10/index.html b/blog/2019/04/liftoff-10/index.html index a3ef1ff72..4fd8d620a 100644 --- a/blog/2019/04/liftoff-10/index.html +++ b/blog/2019/04/liftoff-10/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-11/index.html b/blog/2019/04/liftoff-11/index.html index a8da1ce5b..8ba083418 100644 --- a/blog/2019/04/liftoff-11/index.html +++ b/blog/2019/04/liftoff-11/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-12/index.html b/blog/2019/04/liftoff-12/index.html index 6b1ef56cc..0eeb68797 100644 --- a/blog/2019/04/liftoff-12/index.html +++ b/blog/2019/04/liftoff-12/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-13/index.html b/blog/2019/04/liftoff-13/index.html index ca043ccc1..93659a633 100644 --- a/blog/2019/04/liftoff-13/index.html +++ b/blog/2019/04/liftoff-13/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-14/index.html b/blog/2019/04/liftoff-14/index.html index ff7ce40b9..65972d27c 100644 --- a/blog/2019/04/liftoff-14/index.html +++ b/blog/2019/04/liftoff-14/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-15/index.html b/blog/2019/04/liftoff-15/index.html index 16a952ab2..330216c23 100644 --- a/blog/2019/04/liftoff-15/index.html +++ b/blog/2019/04/liftoff-15/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-16/index.html b/blog/2019/04/liftoff-16/index.html index 73b2d6e8c..dbb967fc7 100644 --- a/blog/2019/04/liftoff-16/index.html +++ b/blog/2019/04/liftoff-16/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-17/index.html b/blog/2019/04/liftoff-17/index.html index 7eba2262e..141811b3a 100644 --- a/blog/2019/04/liftoff-17/index.html +++ b/blog/2019/04/liftoff-17/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-18/index.html b/blog/2019/04/liftoff-18/index.html index 5b72cf344..ccd712663 100644 --- a/blog/2019/04/liftoff-18/index.html +++ b/blog/2019/04/liftoff-18/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-19/index.html b/blog/2019/04/liftoff-19/index.html index e8c7e05bb..226828738 100644 --- a/blog/2019/04/liftoff-19/index.html +++ b/blog/2019/04/liftoff-19/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-20/index.html b/blog/2019/04/liftoff-20/index.html index 02b062483..072718ea4 100644 --- a/blog/2019/04/liftoff-20/index.html +++ b/blog/2019/04/liftoff-20/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-21/index.html b/blog/2019/04/liftoff-21/index.html index 2f2e87da3..84d3389f4 100644 --- a/blog/2019/04/liftoff-21/index.html +++ b/blog/2019/04/liftoff-21/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-22/index.html b/blog/2019/04/liftoff-22/index.html index 0aeca0205..9150ae32c 100644 --- a/blog/2019/04/liftoff-22/index.html +++ b/blog/2019/04/liftoff-22/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-23/index.html b/blog/2019/04/liftoff-23/index.html index 254a680a2..91ed674ba 100644 --- a/blog/2019/04/liftoff-23/index.html +++ b/blog/2019/04/liftoff-23/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-24/index.html b/blog/2019/04/liftoff-24/index.html index d4c7610c6..8f6ac4237 100644 --- a/blog/2019/04/liftoff-24/index.html +++ b/blog/2019/04/liftoff-24/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-25/index.html b/blog/2019/04/liftoff-25/index.html index fea346cac..53de88d5f 100644 --- a/blog/2019/04/liftoff-25/index.html +++ b/blog/2019/04/liftoff-25/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-26/index.html b/blog/2019/04/liftoff-26/index.html index 121109cad..ee9a1ac9f 100644 --- a/blog/2019/04/liftoff-26/index.html +++ b/blog/2019/04/liftoff-26/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-27/index.html b/blog/2019/04/liftoff-27/index.html index 398af9aa0..d88384fe0 100644 --- a/blog/2019/04/liftoff-27/index.html +++ b/blog/2019/04/liftoff-27/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-28/index.html b/blog/2019/04/liftoff-28/index.html index 59a6e03d8..df406edc8 100644 --- a/blog/2019/04/liftoff-28/index.html +++ b/blog/2019/04/liftoff-28/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-29/index.html b/blog/2019/04/liftoff-29/index.html index 0d7988058..7fe23354c 100644 --- a/blog/2019/04/liftoff-29/index.html +++ b/blog/2019/04/liftoff-29/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/04/liftoff-30/index.html b/blog/2019/04/liftoff-30/index.html index a4cbfc7ac..a1dbf5239 100644 --- a/blog/2019/04/liftoff-30/index.html +++ b/blog/2019/04/liftoff-30/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/08/1.3/index.html b/blog/2019/08/1.3/index.html index e2e1c23ec..af734d156 100644 --- a/blog/2019/08/1.3/index.html +++ b/blog/2019/08/1.3/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/10/1.5/index.html b/blog/2019/10/1.5/index.html index 0aa1c2676..1cf2922f3 100644 --- a/blog/2019/10/1.5/index.html +++ b/blog/2019/10/1.5/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/11/1.6/index.html b/blog/2019/11/1.6/index.html index dd0e0d607..360ca2a14 100644 --- a/blog/2019/11/1.6/index.html +++ b/blog/2019/11/1.6/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2019/12/1.7/index.html b/blog/2019/12/1.7/index.html index 5eb49a7ec..0c6206f59 100644 --- a/blog/2019/12/1.7/index.html +++ b/blog/2019/12/1.7/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/03/1.9/index.html b/blog/2020/03/1.9/index.html index 76c869213..538541e6e 100644 --- a/blog/2020/03/1.9/index.html +++ b/blog/2020/03/1.9/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/03/custom-providers/index.html b/blog/2020/03/custom-providers/index.html index cba811a07..c3feb26f8 100644 --- a/blog/2020/03/custom-providers/index.html +++ b/blog/2020/03/custom-providers/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/04/1.10/index.html b/blog/2020/04/1.10/index.html index 88086f83b..495c5f1ac 100644 --- a/blog/2020/04/1.10/index.html +++ b/blog/2020/04/1.10/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/04/1.13/index.html b/blog/2020/04/1.13/index.html index bd9269126..861d6de97 100644 --- a/blog/2020/04/1.13/index.html +++ b/blog/2020/04/1.13/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/07/1.18-image-editor/index.html b/blog/2020/07/1.18-image-editor/index.html index d0566ce97..b6430151b 100644 --- a/blog/2020/07/1.18-image-editor/index.html +++ b/blog/2020/07/1.18-image-editor/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/09/companion-2.0/index.html b/blog/2020/09/companion-2.0/index.html index 63b03fa2c..cb740d1da 100644 --- a/blog/2020/09/companion-2.0/index.html +++ b/blog/2020/09/companion-2.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/10/1.22/index.html b/blog/2020/10/1.22/index.html index 96d9abdaf..9791d87aa 100644 --- a/blog/2020/10/1.22/index.html +++ b/blog/2020/10/1.22/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/11/1.23/index.html b/blog/2020/11/1.23/index.html index c01c0e0cc..85aa30d0e 100644 --- a/blog/2020/11/1.23/index.html +++ b/blog/2020/11/1.23/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2020/12/1.24/index.html b/blog/2020/12/1.24/index.html index 9d64f0254..688053063 100644 --- a/blog/2020/12/1.24/index.html +++ b/blog/2020/12/1.24/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/01/1.25/index.html b/blog/2021/01/1.25/index.html index 87bd8c91c..d6bb86e63 100644 --- a/blog/2021/01/1.25/index.html +++ b/blog/2021/01/1.25/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/02/1.26/index.html b/blog/2021/02/1.26/index.html index fbdd12c72..9cdd09c0d 100644 --- a/blog/2021/02/1.26/index.html +++ b/blog/2021/02/1.26/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/04/1.27/index.html b/blog/2021/04/1.27/index.html index 8a1641454..467ed3f25 100644 --- a/blog/2021/04/1.27/index.html +++ b/blog/2021/04/1.27/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/05/1.29/index.html b/blog/2021/05/1.29/index.html index 64ae2accd..c2b9b4db8 100644 --- a/blog/2021/05/1.29/index.html +++ b/blog/2021/05/1.29/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/07/1.30/index.html b/blog/2021/07/1.30/index.html index a115ed46e..64a795d36 100644 --- a/blog/2021/07/1.30/index.html +++ b/blog/2021/07/1.30/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/08/2.0/index.html b/blog/2021/08/2.0/index.html index 046d0aca9..cfb478b8d 100644 --- a/blog/2021/08/2.0/index.html +++ b/blog/2021/08/2.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2021/12/2.1-2.3/index.html b/blog/2021/12/2.1-2.3/index.html index 3bc890152..b36ff81a9 100644 --- a/blog/2021/12/2.1-2.3/index.html +++ b/blog/2021/12/2.1-2.3/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2022/03/2.4-2.7/index.html b/blog/2022/03/2.4-2.7/index.html index c1a737e22..ee3d63e32 100644 --- a/blog/2022/03/2.4-2.7/index.html +++ b/blog/2022/03/2.4-2.7/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2022/09/3.0/index.html b/blog/2022/09/3.0/index.html index 2fc971dfe..75e5782ae 100644 --- a/blog/2022/09/3.0/index.html +++ b/blog/2022/09/3.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2022/12/3.3/index.html b/blog/2022/12/3.3/index.html index 1b3f3f57c..699fc06f9 100644 --- a/blog/2022/12/3.3/index.html +++ b/blog/2022/12/3.3/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2023-05-new-website/index.html b/blog/2023-05-new-website/index.html index 733eea94c..edf90aebb 100644 --- a/blog/2023-05-new-website/index.html +++ b/blog/2023-05-new-website/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2023-10-25-image-editor/index.html b/blog/2023-10-25-image-editor/index.html index 3449683a6..8ee6ffdf9 100644 --- a/blog/2023-10-25-image-editor/index.html +++ b/blog/2023-10-25-image-editor/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2023/07/3.13-3.21/index.html b/blog/2023/07/3.13-3.21/index.html index 347dc81c5..4f12a56b6 100644 --- a/blog/2023/07/3.13-3.21/index.html +++ b/blog/2023/07/3.13-3.21/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/2023/07/3.3-3.13/index.html b/blog/2023/07/3.3-3.13/index.html index d7f5361ff..566859fc3 100644 --- a/blog/2023/07/3.3-3.13/index.html +++ b/blog/2023/07/3.3-3.13/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/archive/index.html b/blog/archive/index.html index db1143354..e788668d7 100644 --- a/blog/archive/index.html +++ b/blog/archive/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/index.html b/blog/index.html index b3f66f5c5..8ffbc3179 100644 --- a/blog/index.html +++ b/blog/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/2/index.html b/blog/page/2/index.html index d98416ba2..7ef811daa 100644 --- a/blog/page/2/index.html +++ b/blog/page/2/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/3/index.html b/blog/page/3/index.html index d2ff58576..942502c87 100644 --- a/blog/page/3/index.html +++ b/blog/page/3/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/4/index.html b/blog/page/4/index.html index 0d766f5f7..145ad5b54 100644 --- a/blog/page/4/index.html +++ b/blog/page/4/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/5/index.html b/blog/page/5/index.html index c719f54ce..276e6aa72 100644 --- a/blog/page/5/index.html +++ b/blog/page/5/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/6/index.html b/blog/page/6/index.html index 7469fff22..b243851a3 100644 --- a/blog/page/6/index.html +++ b/blog/page/6/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/7/index.html b/blog/page/7/index.html index 68af62210..a449f2a7c 100644 --- a/blog/page/7/index.html +++ b/blog/page/7/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/8/index.html b/blog/page/8/index.html index 1d6a0cff0..d9f58d179 100644 --- a/blog/page/8/index.html +++ b/blog/page/8/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/page/9/index.html b/blog/page/9/index.html index 1b9d28ef6..941eb5ff1 100644 --- a/blog/page/9/index.html +++ b/blog/page/9/index.html @@ -13,7 +13,7 @@ - + diff --git a/blog/uppy-4.0/index.html b/blog/uppy-4.0/index.html index 577ddbe7f..e754ced57 100644 --- a/blog/uppy-4.0/index.html +++ b/blog/uppy-4.0/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/angular/index.html b/docs/angular/index.html index d299f26e4..b2c9d99db 100644 --- a/docs/angular/index.html +++ b/docs/angular/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/audio/index.html b/docs/audio/index.html index 67e6903d6..b0e79367c 100644 --- a/docs/audio/index.html +++ b/docs/audio/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/aws-s3/index.html b/docs/aws-s3/index.html index 02fcb7c8e..f462e3bb0 100644 --- a/docs/aws-s3/index.html +++ b/docs/aws-s3/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/box/index.html b/docs/box/index.html index b25dab4d3..01d07e941 100644 --- a/docs/box/index.html +++ b/docs/box/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/companion/index.html b/docs/companion/index.html index e009657c4..338667ef6 100644 --- a/docs/companion/index.html +++ b/docs/companion/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/compressor/index.html b/docs/compressor/index.html index 1afa17a90..c725e610c 100644 --- a/docs/compressor/index.html +++ b/docs/compressor/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/dashboard/index.html b/docs/dashboard/index.html index 9d037d3d3..63ea1715c 100644 --- a/docs/dashboard/index.html +++ b/docs/dashboard/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/drag-drop/index.html b/docs/drag-drop/index.html index 523fb254c..a812df847 100644 --- a/docs/drag-drop/index.html +++ b/docs/drag-drop/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/drop-target/index.html b/docs/drop-target/index.html index 69eedc434..81be8acba 100644 --- a/docs/drop-target/index.html +++ b/docs/drop-target/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/dropbox/index.html b/docs/dropbox/index.html index db81dd13c..c35678371 100644 --- a/docs/dropbox/index.html +++ b/docs/dropbox/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/facebook/index.html b/docs/facebook/index.html index 4de8a4f19..bcebf9a71 100644 --- a/docs/facebook/index.html +++ b/docs/facebook/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/file-input/index.html b/docs/file-input/index.html index b247e73e6..f5f6d875a 100644 --- a/docs/file-input/index.html +++ b/docs/file-input/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/form/index.html b/docs/form/index.html index 0bbb2c6a4..ef84e709f 100644 --- a/docs/form/index.html +++ b/docs/form/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/golden-retriever/index.html b/docs/golden-retriever/index.html index eb388b791..4876dedef 100644 --- a/docs/golden-retriever/index.html +++ b/docs/golden-retriever/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/google-drive-picker/index.html b/docs/google-drive-picker/index.html index 8cac1b4df..5d25475a8 100644 --- a/docs/google-drive-picker/index.html +++ b/docs/google-drive-picker/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/google-drive/index.html b/docs/google-drive/index.html index 19eabb63f..b73e81e0a 100644 --- a/docs/google-drive/index.html +++ b/docs/google-drive/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/google-photos-picker/index.html b/docs/google-photos-picker/index.html index 29d6d70ff..21f0483a5 100644 --- a/docs/google-photos-picker/index.html +++ b/docs/google-photos-picker/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/google-photos/index.html b/docs/google-photos/index.html index 84d90180d..c9c3d4e0f 100644 --- a/docs/google-photos/index.html +++ b/docs/google-photos/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/browser-support/index.html b/docs/guides/browser-support/index.html index 439f0ba5c..ba4bfefad 100644 --- a/docs/guides/browser-support/index.html +++ b/docs/guides/browser-support/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/building-plugins/index.html b/docs/guides/building-plugins/index.html index 90713de1b..fbf169da4 100644 --- a/docs/guides/building-plugins/index.html +++ b/docs/guides/building-plugins/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/building-your-own-ui-with-uppy/index.html b/docs/guides/building-your-own-ui-with-uppy/index.html index 1c40734b2..d228bafd9 100644 --- a/docs/guides/building-your-own-ui-with-uppy/index.html +++ b/docs/guides/building-your-own-ui-with-uppy/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/choosing-uploader/index.html b/docs/guides/choosing-uploader/index.html index 708ac69e5..69d0a183d 100644 --- a/docs/guides/choosing-uploader/index.html +++ b/docs/guides/choosing-uploader/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/custom-stores/index.html b/docs/guides/custom-stores/index.html index 1731e68be..3ea7a0f3c 100644 --- a/docs/guides/custom-stores/index.html +++ b/docs/guides/custom-stores/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/guides/migration-guides/index.html b/docs/guides/migration-guides/index.html index 21e966306..caed93a4c 100644 --- a/docs/guides/migration-guides/index.html +++ b/docs/guides/migration-guides/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/image-editor/index.html b/docs/image-editor/index.html index b346e700c..1123c79bb 100644 --- a/docs/image-editor/index.html +++ b/docs/image-editor/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/index.html b/docs/index.html index 8c51e4e2d..f47201fed 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/informer/index.html b/docs/informer/index.html index d3e7a62bf..2b5c13bec 100644 --- a/docs/informer/index.html +++ b/docs/informer/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/instagram/index.html b/docs/instagram/index.html index 1e7aef359..24ebab07d 100644 --- a/docs/instagram/index.html +++ b/docs/instagram/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/locales/index.html b/docs/locales/index.html index 978480dcd..44216c9a3 100644 --- a/docs/locales/index.html +++ b/docs/locales/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/nextjs/index.html b/docs/nextjs/index.html index 1de6dc778..a9f10e076 100644 --- a/docs/nextjs/index.html +++ b/docs/nextjs/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/onedrive/index.html b/docs/onedrive/index.html index 3df30f5ce..3c55138c5 100644 --- a/docs/onedrive/index.html +++ b/docs/onedrive/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/progress-bar/index.html b/docs/progress-bar/index.html index 8695e75e6..4612e041c 100644 --- a/docs/progress-bar/index.html +++ b/docs/progress-bar/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/quick-start/index.html b/docs/quick-start/index.html index 326874aa4..5f574c210 100644 --- a/docs/quick-start/index.html +++ b/docs/quick-start/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/react/index.html b/docs/react/index.html index 35a2261e6..9a76088b8 100644 --- a/docs/react/index.html +++ b/docs/react/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/reactrouter/index.html b/docs/reactrouter/index.html index 1ae1221a8..0e81bfdbe 100644 --- a/docs/reactrouter/index.html +++ b/docs/reactrouter/index.html @@ -13,7 +13,7 @@ - + @@ -60,7 +60,7 @@

TransloaditStart by creating a resource route to generate the signature and params:

-
import { data } from 'react-router';
import type { ActionFunction } from 'rea';
import crypto from 'crypto';

function utcDateString(ms: number): string {
return new Date(ms)
.toISOString()
.replace(/-/g, '/')
.replace(/T/, ' ')
.replace(/\.\d+Z$/, '+00:00');
}

export const action: ActionFunction = async ({ request }) => {
// expire 1 hour from now (this must be milliseconds)
const expires = utcDateString(Date.now() + 1 * 60 * 60 * 1000);
const authKey = process.env.TRANSLOADIT_KEY;
const authSecret = process.env.TRANSLOADIT_SECRET;
const templateId = process.env.TRANSLOADIT_TEMPLATE_ID;

if (!authKey || !authSecret || !templateId) {
throw data({ error: 'Missing Transloadit credentials' }, { status: 500 });
}

const body = await request.json();
const params = JSON.stringify({
auth: {
key: authKey,
expires,
},
template_id: templateId,
fields: {
// You can use this in your template.
customValue: body.customValue,
},
// your other params like notify_url, etc.
});

const signatureBytes = crypto
.createHmac('sha384', authSecret)
.update(Buffer.from(params, 'utf-8'));
// The final signature needs the hash name in front, so
// the hashing algorithm can be updated in a backwards-compatible
// way when old algorithms become insecure.
const signature = `sha384:${signatureBytes.digest('hex')}`;

return data({ expires, signature, params });
};
+
import { data } from 'react-router';
import type { ActionFunction } from 'react-router';
import crypto from 'crypto';

function utcDateString(ms: number): string {
return new Date(ms)
.toISOString()
.replace(/-/g, '/')
.replace(/T/, ' ')
.replace(/\.\d+Z$/, '+00:00');
}

export const action: ActionFunction = async ({ request }) => {
// expire 1 hour from now (this must be milliseconds)
const expires = utcDateString(Date.now() + 1 * 60 * 60 * 1000);
const authKey = process.env.TRANSLOADIT_KEY;
const authSecret = process.env.TRANSLOADIT_SECRET;
const templateId = process.env.TRANSLOADIT_TEMPLATE_ID;

if (!authKey || !authSecret || !templateId) {
throw data({ error: 'Missing Transloadit credentials' }, { status: 500 });
}

const body = await request.json();
const params = JSON.stringify({
auth: {
key: authKey,
expires,
},
template_id: templateId,
fields: {
// You can use this in your template.
customValue: body.customValue,
},
// your other params like notify_url, etc.
});

const signatureBytes = crypto
.createHmac('sha384', authSecret)
.update(Buffer.from(params, 'utf-8'));
// The final signature needs the hash name in front, so
// the hashing algorithm can be updated in a backwards-compatible
// way when old algorithms become insecure.
const signature = `sha384:${signatureBytes.digest('hex')}`;

return data({ expires, signature, params });
};

On the client we want to fetch the signature and params from the server. You may want to send values from React state along to your endpoint, for instance to add fields which you diff --git a/docs/remote-sources/index.html b/docs/remote-sources/index.html index a3ecfd97f..a15e14f62 100644 --- a/docs/remote-sources/index.html +++ b/docs/remote-sources/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/screen-capture/index.html b/docs/screen-capture/index.html index 8750df707..bdac7d80a 100644 --- a/docs/screen-capture/index.html +++ b/docs/screen-capture/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/status-bar/index.html b/docs/status-bar/index.html index c7f0f294b..9616840b9 100644 --- a/docs/status-bar/index.html +++ b/docs/status-bar/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/svelte/index.html b/docs/svelte/index.html index b3f24b600..14353ff7f 100644 --- a/docs/svelte/index.html +++ b/docs/svelte/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/sveltekit/index.html b/docs/sveltekit/index.html index f7cc53bc4..a1f6aec18 100644 --- a/docs/sveltekit/index.html +++ b/docs/sveltekit/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/thumbnail-generator/index.html b/docs/thumbnail-generator/index.html index 070800961..553a8be7b 100644 --- a/docs/thumbnail-generator/index.html +++ b/docs/thumbnail-generator/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/transloadit/index.html b/docs/transloadit/index.html index bde1b9e25..02a5c65ff 100644 --- a/docs/transloadit/index.html +++ b/docs/transloadit/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/tus/index.html b/docs/tus/index.html index f0cdac1ba..4278c29f6 100644 --- a/docs/tus/index.html +++ b/docs/tus/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/unsplash/index.html b/docs/unsplash/index.html index f8d5beeba..54173f6a8 100644 --- a/docs/unsplash/index.html +++ b/docs/unsplash/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/uppy/index.html b/docs/uppy/index.html index 624c65153..72262e1c1 100644 --- a/docs/uppy/index.html +++ b/docs/uppy/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/url/index.html b/docs/url/index.html index 07cf862a1..8e72b10a2 100644 --- a/docs/url/index.html +++ b/docs/url/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/vue/index.html b/docs/vue/index.html index f0506961c..23edadc66 100644 --- a/docs/vue/index.html +++ b/docs/vue/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/webcam/index.html b/docs/webcam/index.html index aecff81ac..1671b74ab 100644 --- a/docs/webcam/index.html +++ b/docs/webcam/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/webdav/index.html b/docs/webdav/index.html index 981075e30..b968a05f1 100644 --- a/docs/webdav/index.html +++ b/docs/webdav/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/xhr-upload/index.html b/docs/xhr-upload/index.html index befd02fb7..a6e31e000 100644 --- a/docs/xhr-upload/index.html +++ b/docs/xhr-upload/index.html @@ -13,7 +13,7 @@ - + diff --git a/docs/zoom/index.html b/docs/zoom/index.html index cac106929..f175f317a 100644 --- a/docs/zoom/index.html +++ b/docs/zoom/index.html @@ -13,7 +13,7 @@ - + diff --git a/examples/index.html b/examples/index.html index 5df13f6a7..84bfa3c16 100644 --- a/examples/index.html +++ b/examples/index.html @@ -13,7 +13,7 @@ - + diff --git a/index.html b/index.html index 2cb7e79bb..cc802004b 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ - + diff --git a/privacy-policy/index.html b/privacy-policy/index.html index 0a5f77643..41177a9ed 100644 --- a/privacy-policy/index.html +++ b/privacy-policy/index.html @@ -13,7 +13,7 @@ - + diff --git a/search/index.html b/search/index.html index f9d575acb..43d310778 100644 --- a/search/index.html +++ b/search/index.html @@ -13,7 +13,7 @@ - +