{"version":3,"file":"FunctionEditor.B4In5SqS.js","sources":["../../../../../../src/lib/components/workspace/Functions/FunctionEditor.svelte"],"sourcesContent":["<script>\n\timport { getContext, createEventDispatcher, onMount } from 'svelte';\n\timport { goto } from '$app/navigation';\n\n\tconst dispatch = createEventDispatcher();\n\tconst i18n = getContext('i18n');\n\n\timport CodeEditor from '$lib/components/common/CodeEditor.svelte';\n\timport ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';\n\n\tlet formElement = null;\n\tlet loading = false;\n\tlet showConfirm = false;\n\n\texport let edit = false;\n\texport let clone = false;\n\n\texport let id = '';\n\texport let name = '';\n\texport let meta = {\n\t\tdescription: ''\n\t};\n\texport let content = '';\n\n\t$: if (name && !edit && !clone) {\n\t\tid = name.replace(/\\s+/g, '_').toLowerCase();\n\t}\n\n\tlet codeEditor;\n\tlet boilerplate = `\"\"\"\ntitle: Example Filter\nauthor: open-webui\nauthor_url: https://github.com/open-webui\nfunding_url: https://github.com/open-webui\nversion: 0.1\n\"\"\"\n\nfrom pydantic import BaseModel, Field\nfrom typing import Optional\n\n\nclass Filter:\n class Valves(BaseModel):\n priority: int = Field(\n default=0, description=\"Priority level for the filter operations.\"\n )\n max_turns: int = Field(\n default=8, description=\"Maximum allowable conversation turns for a user.\"\n )\n pass\n\n class UserValves(BaseModel):\n max_turns: int = Field(\n default=4, description=\"Maximum allowable conversation turns for a user.\"\n )\n pass\n\n def __init__(self):\n # Indicates custom file handling logic. This flag helps disengage default routines in favor of custom\n # implementations, informing the WebUI to defer file-related operations to designated methods within this class.\n # Alternatively, you can remove the files directly from the body in from the inlet hook\n # self.file_handler = True\n\n # Initialize 'valves' with specific configurations. Using 'Valves' instance helps encapsulate settings,\n # which ensures settings are managed cohesively and not confused with operational flags like 'file_handler'.\n self.valves = self.Valves()\n pass\n\n def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:\n # Modify the request body or validate it before processing by the chat completion API.\n # This function is the pre-processor for the API where various checks on the input can be performed.\n # It can also modify the request before sending it to the API.\n print(f\"inlet:{__name__}\")\n print(f\"inlet:body:{body}\")\n print(f\"inlet:user:{__user__}\")\n\n if __user__.get(\"role\", \"admin\") in [\"user\", \"admin\"]:\n messages = body.get(\"messages\", [])\n\n max_turns = min(__user__[\"valves\"].max_turns, self.valves.max_turns)\n if len(messages) > max_turns:\n raise Exception(\n f\"Conversation turn limit exceeded. Max turns: {max_turns}\"\n )\n\n return body\n\n def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict:\n # Modify or analyze the response body after processing by the API.\n # This function is the post-processor for the API, which can be used to modify the response\n # or perform additional checks and analytics.\n print(f\"outlet:{__name__}\")\n print(f\"outlet:body:{body}\")\n print(f\"outlet:user:{__user__}\")\n\n return body\n`;\n\n\tconst _boilerplate = `from pydantic import BaseModel\nfrom typing import Optional, Union, Generator, Iterator\nfrom open_webui.utils.misc import get_last_user_message\n\nimport os\nimport requests\n\n\n# Filter Class: This class is designed to serve as a pre-processor and post-processor\n# for request and response modifications. It checks and transforms requests and responses\n# to ensure they meet specific criteria before further processing or returning to the user.\nclass Filter:\n class Valves(BaseModel):\n max_turns: int = 4\n pass\n\n def __init__(self):\n # Indicates custom file handling logic. This flag helps disengage default routines in favor of custom\n # implementations, informing the WebUI to defer file-related operations to designated methods within this class.\n # Alternatively, you can remove the files directly from the body in from the inlet hook\n self.file_handler = True\n\n # Initialize 'valves' with specific configurations. Using 'Valves' instance helps encapsulate settings,\n # which ensures settings are managed cohesively and not confused with operational flags like 'file_handler'.\n self.valves = self.Valves(**{\"max_turns\": 2})\n pass\n\n def inlet(self, body: dict, user: Optional[dict] = None) -> dict:\n # Modify the request body or validate it before processing by the chat completion API.\n # This function is the pre-processor for the API where various checks on the input can be performed.\n # It can also modify the request before sending it to the API.\n print(f\"inlet:{__name__}\")\n print(f\"inlet:body:{body}\")\n print(f\"inlet:user:{user}\")\n\n if user.get(\"role\", \"admin\") in [\"user\", \"admin\"]:\n messages = body.get(\"messages\", [])\n if len(messages) > self.valves.max_turns:\n raise Exception(\n f\"Conversation turn limit exceeded. Max turns: {self.valves.max_turns}\"\n )\n\n return body\n\n def outlet(self, body: dict, user: Optional[dict] = None) -> dict:\n # Modify or analyze the response body after processing by the API.\n # This function is the post-processor for the API, which can be used to modify the response\n # or perform additional checks and analytics.\n print(f\"outlet:{__name__}\")\n print(f\"outlet:body:{body}\")\n print(f\"outlet:user:{user}\")\n\n messages = [\n {\n **message,\n \"content\": f\"{message['content']} - @@Modified from Filter Outlet\",\n }\n for message in body.get(\"messages\", [])\n ]\n\n return {\"messages\": messages}\n\n\n\n# Pipe Class: This class functions as a customizable pipeline.\n# It can be adapted to work with any external or internal models,\n# making it versatile for various use cases outside of just OpenAI models.\nclass Pipe:\n class Valves(BaseModel):\n OPENAI_API_BASE_URL: str = \"https://api.openai.com/v1\"\n OPENAI_API_KEY: str = \"your-key\"\n pass\n\n def __init__(self):\n self.type = \"manifold\"\n self.valves = self.Valves()\n self.pipes = self.get_openai_models()\n pass\n\n def get_openai_models(self):\n if self.valves.OPENAI_API_KEY:\n try:\n headers = {}\n headers[\"Authorization\"] = f\"Bearer {self.valves.OPENAI_API_KEY}\"\n headers[\"Content-Type\"] = \"application/json\"\n\n r = requests.get(\n f\"{self.valves.OPENAI_API_BASE_URL}/models\", headers=headers\n )\n\n models = r.json()\n return [\n {\n \"id\": model[\"id\"],\n \"name\": model[\"name\"] if \"name\" in model else model[\"id\"],\n }\n for model in models[\"data\"]\n if \"gpt\" in model[\"id\"]\n ]\n\n except Exception as e:\n\n print(f\"Error: {e}\")\n return [\n {\n \"id\": \"error\",\n \"name\": \"Could not fetch models from OpenAI, please update the API Key in the valves.\",\n },\n ]\n else:\n return []\n\n def pipe(self, body: dict) -> Union[str, Generator, Iterator]:\n # This is where you can add your custom pipelines like RAG.\n print(f\"pipe:{__name__}\")\n\n if \"user\" in body:\n print(body[\"user\"])\n del body[\"user\"]\n\n headers = {}\n headers[\"Authorization\"] = f\"Bearer {self.valves.OPENAI_API_KEY}\"\n headers[\"Content-Type\"] = \"application/json\"\n\n model_id = body[\"model\"][body[\"model\"].find(\".\") + 1 :]\n payload = {**body, \"model\": model_id}\n print(payload)\n\n try:\n r = requests.post(\n url=f\"{self.valves.OPENAI_API_BASE_URL}/chat/completions\",\n json=payload,\n headers=headers,\n stream=True,\n )\n\n r.raise_for_status()\n\n if body[\"stream\"]:\n return r.iter_lines()\n else:\n return r.json()\n except Exception as e:\n return f\"Error: {e}\"\n`;\n\n\tconst saveHandler = async () => {\n\t\tloading = true;\n\t\tdispatch('save', {\n\t\t\tid,\n\t\t\tname,\n\t\t\tmeta,\n\t\t\tcontent\n\t\t});\n\t};\n\n\tconst submitHandler = async () => {\n\t\tif (codeEditor) {\n\t\t\tconst res = await codeEditor.formatPythonCodeHandler();\n\n\t\t\tif (res) {\n\t\t\t\tconsole.log('Code formatted successfully');\n\t\t\t\tsaveHandler();\n\t\t\t}\n\t\t}\n\t};\n</script>\n\n<div class=\" flex flex-col justify-between w-full overflow-y-auto h-full\">\n\t<div class=\"mx-auto w-full md:px-0 h-full\">\n\t\t<form\n\t\t\tbind:this={formElement}\n\t\t\tclass=\" flex flex-col max-h-[100dvh] h-full\"\n\t\t\ton:submit|preventDefault={() => {\n\t\t\t\tif (edit) {\n\t\t\t\t\tsubmitHandler();\n\t\t\t\t} else {\n\t\t\t\t\tshowConfirm = true;\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<div class=\"mb-2.5\">\n\t\t\t\t<button\n\t\t\t\t\tclass=\"flex space-x-1\"\n\t\t\t\t\ton:click={() => {\n\t\t\t\t\t\tgoto('/workspace/functions');\n\t\t\t\t\t}}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<div class=\" self-center\">\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tviewBox=\"0 0 20 20\"\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\tclass=\"w-4 h-4\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\tfill-rule=\"evenodd\"\n\t\t\t\t\t\t\t\td=\"M17 10a.75.75 0 01-.75.75H5.612l4.158 3.96a.75.75 0 11-1.04 1.08l-5.5-5.25a.75.75 0 010-1.08l5.5-5.25a.75.75 0 111.04 1.08L5.612 9.25H16.25A.75.75 0 0117 10z\"\n\t\t\t\t\t\t\t\tclip-rule=\"evenodd\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\" self-center font-medium text-sm\">{$i18n.t('Back')}</div>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"flex flex-col flex-1 overflow-auto h-0 rounded-lg\">\n\t\t\t\t<div class=\"w-full mb-2 flex flex-col gap-1.5\">\n\t\t\t\t\t<div class=\"flex gap-2 w-full\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"w-full px-3 py-2 text-sm font-medium bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none\"\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tplaceholder={$i18n.t('Function Name (e.g. My Filter)')}\n\t\t\t\t\t\t\tbind:value={name}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"w-full px-3 py-2 text-sm font-medium disabled:text-gray-300 dark:disabled:text-gray-700 bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none\"\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tplaceholder={$i18n.t('Function ID (e.g. my_filter)')}\n\t\t\t\t\t\t\tbind:value={id}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\tdisabled={edit}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"w-full px-3 py-2 text-sm font-medium bg-gray-50 dark:bg-gray-850 dark:text-gray-200 rounded-lg outline-none\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tplaceholder={$i18n.t(\n\t\t\t\t\t\t\t'Function Description (e.g. A filter to remove profanity from text)'\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tbind:value={meta.description}\n\t\t\t\t\t\trequired\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"mb-2 flex-1 overflow-auto h-0 rounded-lg\">\n\t\t\t\t\t<CodeEditor\n\t\t\t\t\t\tbind:value={content}\n\t\t\t\t\t\tbind:this={codeEditor}\n\t\t\t\t\t\t{boilerplate}\n\t\t\t\t\t\ton:save={() => {\n\t\t\t\t\t\t\tif (formElement) {\n\t\t\t\t\t\t\t\tformElement.requestSubmit();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"pb-3 flex justify-between\">\n\t\t\t\t\t<div class=\"flex-1 pr-3\">\n\t\t\t\t\t\t<div class=\"text-xs text-gray-500 line-clamp-2\">\n\t\t\t\t\t\t\t<span class=\" font-semibold dark:text-gray-200\">{$i18n.t('Warning:')}</span>\n\t\t\t\t\t\t\t{$i18n.t('Functions allow arbitrary code execution')} <br />—\n\t\t\t\t\t\t\t<span class=\" font-medium dark:text-gray-400\"\n\t\t\t\t\t\t\t\t>{$i18n.t(`don't install random functions from sources you don't trust.`)}</span\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\tclass=\"px-3 py-1.5 text-sm font-medium bg-emerald-600 hover:bg-emerald-700 text-gray-50 transition rounded-lg\"\n\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{$i18n.t('Save')}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</form>\n\t</div>\n</div>\n\n<ConfirmDialog\n\tbind:show={showConfirm}\n\ton:confirm={() => {\n\t\tsubmitHandler();\n\t}}\n>\n\t<div class=\"text-sm text-gray-500\">\n\t\t<div class=\" bg-yellow-500/20 text-yellow-700 dark:text-yellow-200 rounded-lg px-4 py-3\">\n\t\t\t<div>{$i18n.t('Please carefully review the following warnings:')}</div>\n\n\t\t\t<ul class=\" mt-1 list-disc pl-4 text-xs\">\n\t\t\t\t<li>{$i18n.t('Functions allow arbitrary code execution.')}</li>\n\t\t\t\t<li>{$i18n.t('Do not install functions from sources you do not fully trust.')}</li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"my-3\">\n\t\t\t{$i18n.t(\n\t\t\t\t'I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.'\n\t\t\t)}\n\t\t</div>\n\t</div>\n</ConfirmDialog>\n"],"names":["ctx","insert_hydration","target","div3","anchor","append_hydration","div1","div0","ul","li0","li1","div2","set_data","t0","t0_value","t2","t2_value","t4","t4_value","t6","t6_value","t12_value","div11","div10","form","button0","div9","div4","input0","input1","input2","set_input_value","div5","div8","div7","div6","span0","br","span1","button1","t1","t1_value","dirty","t7","t7_value","t9","t9_value","current","t12","t14","t14_value","dispatch","createEventDispatcher","i18n","getContext","formElement","showConfirm","edit","$$props","clone","id","name","meta","content","codeEditor","boilerplate","saveHandler","submitHandler","goto","value","$$value","$$invalidate"],"mappings":"wdA4XSA,EAAK,CAAA,EAAC,EAAE,iDAAiD,EAAA,aAGzDA,EAAK,CAAA,EAAC,EAAE,2CAA2C,EAAA,WACnDA,EAAK,CAAA,EAAC,EAAE,+DAA+D,EAAA,WAK5EA,EAAK,CAAA,EAAC,EACN,wMAAuM,EAAA,ytBAZ1MC,GAeKC,EAAAC,EAAAC,CAAA,EAdJC,EAOKF,EAAAG,CAAA,EANJD,EAAsEC,EAAAC,CAAA,gBAEtEF,EAGIC,EAAAE,CAAA,EAFHH,EAA8DG,EAAAC,CAAA,gBAC9DJ,EAAkFG,EAAAE,CAAA,gBAIpFL,EAIKF,EAAAQ,CAAA,+BAZEX,EAAK,CAAA,EAAC,EAAE,iDAAiD,EAAA,KAAAY,EAAAC,EAAAC,CAAA,gBAGzDd,EAAK,CAAA,EAAC,EAAE,2CAA2C,EAAA,KAAAY,EAAAG,EAAAC,CAAA,gBACnDhB,EAAK,CAAA,EAAC,EAAE,+DAA+D,EAAA,KAAAY,EAAAK,EAAAC,CAAA,gBAK5ElB,EAAK,CAAA,EAAC,EACN,wMAAuM,EAAA,KAAAY,EAAAO,EAAAC,CAAA,yXAzFvJpB,EAAK,CAAA,EAAC,EAAE,MAAM,EAAA,kDAmDVA,EAAK,CAAA,EAAC,EAAE,UAAU,EAAA,YAClEA,EAAK,CAAA,EAAC,EAAE,0CAA0C,EAAA,iBAEhDqB,GAAArB,KAAM,EAAC,8DAAA,EAAA,cASVA,EAAK,CAAA,EAAC,EAAE,MAAM,EAAA,yEA1BHA,EAAO,CAAA,IAAA,kBAAPA,EAAO,CAAA,kKAmCbA,EAAW,CAAA,IAAA,iBAAXA,EAAW,CAAA,6ZApB4C;AAAA,QAC5D,4jCAD4D;AAAA,QAC5D,ilBA3CaA,EAAK,CAAA,EAAC,EAAE,gCAAgC,CAAA,qOAQxCA,EAAK,CAAA,EAAC,EAAE,8BAA8B,CAAA,2BAGzCA,EAAI,CAAA,qMAMFA,EAAK,CAAA,EAAC,EAClB,oEAAmE,CAAA,4sBA/D1EC,GAwGKC,EAAAoB,EAAAlB,CAAA,EAvGJC,EAsGKiB,EAAAC,CAAA,EArGJlB,EAoGMkB,EAAAC,CAAA,EAzFLnB,EAwBKmB,EAAAb,CAAA,EAvBJN,EAsBQM,EAAAc,CAAA,EAfPpB,EAaKoB,EAAAlB,CAAA,SACLF,EAAoEoB,EAAAnB,CAAA,gBAItED,EA8DKmB,EAAAE,CAAA,EA7DJrB,EA4BKqB,EAAAC,CAAA,EA3BJtB,EAiBKsB,EAAAxB,CAAA,EAhBJE,EAMCF,EAAAyB,CAAA,MAFY5B,EAAI,CAAA,CAAA,SAIjBK,EAOCF,EAAA0B,CAAA,MAHY7B,EAAE,CAAA,CAAA,SAKhBK,EAQCsB,EAAAG,CAAA,EAFYC,EAAAD,EAAA9B,KAAK,WAAW,SAK9BK,EAWKqB,EAAAM,CAAA,sBAEL3B,EAiBKqB,EAAAO,CAAA,EAhBJ5B,EAQK4B,EAAAC,CAAA,EAPJ7B,EAMK6B,EAAAC,CAAA,EALJ9B,EAA2E8B,EAAAC,CAAA,kCACrB/B,EAAM8B,EAAAE,EAAA,UAC5DhC,EAEA8B,EAAAG,CAAA,kBAIFjC,EAKQ4B,EAAAM,CAAA,qMAhEuCvC,EAAK,CAAA,EAAC,EAAE,MAAM,EAAA,KAAAY,EAAA4B,EAAAC,CAAA,qBAU9CzC,EAAK,CAAA,EAAC,EAAE,gCAAgC,yCACzCA,EAAI,CAAA,OAAJA,EAAI,CAAA,CAAA,qBAOHA,EAAK,CAAA,EAAC,EAAE,8BAA8B,kDAGzCA,EAAI,CAAA,kBAFFA,EAAE,CAAA,OAAFA,EAAE,CAAA,CAAA,qBAQFA,EAAK,CAAA,EAAC,EAClB,oEAAmE,0BAExD0C,EAAA,GAAAZ,EAAA,QAAA9B,KAAK,aAAL+B,EAAAD,EAAA9B,KAAK,WAAW,sCAOhBA,EAAO,CAAA,iDAc+BA,EAAK,CAAA,EAAC,EAAE,UAAU,EAAA,KAAAY,EAAA+B,GAAAC,EAAA,wBAClE5C,EAAK,CAAA,EAAC,EAAE,0CAA0C,EAAA,KAAAY,EAAAiC,GAAAC,EAAA,GAEhD,CAAAC,GAAAL,EAAA,MAAArB,MAAAA,GAAArB,KAAM,EAAC,8DAAA,EAAA,KAAAY,EAAAoC,GAAA3B,EAAA,wBASVrB,EAAK,CAAA,EAAC,EAAE,MAAM,EAAA,KAAAY,EAAAqC,GAAAC,EAAA,+EASTlD,EAAW,CAAA,0OAjXhB,MAAAmD,EAAWC,KACXC,EAAOC,GAAW,MAAM,sBAK1B,IAAAC,EAAc,KAEdC,EAAc,GAEP,CAAA,KAAAC,EAAO,EAAK,EAAAC,EACZ,CAAA,MAAAC,EAAQ,EAAK,EAAAD,EAEb,CAAA,GAAAE,EAAK,EAAE,EAAAF,EACP,CAAA,KAAAG,EAAO,EAAE,EAAAH,GACT,KAAAI,EAAI,CACd,YAAa,EAAC,CAAA,EAAAJ,EAEJ,CAAA,QAAAK,EAAU,EAAE,EAAAL,EAMnBM,EACAC,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAuNTC,EAAW,SAAA,CAEhBf,EAAS,OACR,CAAA,GAAAS,EACA,KAAAC,EACA,KAAAC,EACA,QAAAC,CAAA,CAAA,GAIII,EAAa,SAAA,CACdH,GACM,MAASA,EAAW,4BAG5B,QAAQ,IAAI,6BAA6B,EACzCE,aAuBEE,GAAK,sBAAsB,gBA6BdP,EAAI,KAAA,0BAQJD,EAAE,KAAA,gDAWHE,EAAK,YAAW,KAAA,2BAOhBC,EAAOM,mDACRL,EAAUM,wBAGhBf,GACHA,EAAY,cAAa,6CA1EnBA,EAAWe,wBAGjBb,EACHU,IAEAI,EAAA,EAAAf,EAAc,EAAI,iBAkGXA,EAAWa,sBAErBF,4NA/VMN,GAAS,CAAAJ,IAASE,OACxBC,EAAKC,EAAK,QAAQ,OAAQ,GAAG,EAAE,YAAW,CAAA"} |