Files
nuqloud-ai/js/appIconRuntime-ltIyK5iP.chunk.mjs.map
T
Pascal Kienast 0739d3da6a Initial open-source release of Talk AI
Talk AI is a multi-bot AI assistant manager for Nextcloud Talk:
per-bot prompts and models, agentic tool calling (MCP + built-in
tools), RAG over Nextcloud files, room-document search, vision and
speech-to-text attachments, persistent bot wikis, approval workflows,
rate limiting, and multi-provider LLM support (any OpenAI-compatible
endpoint).

Developed within EDUC - the European Digital UniverCity
(https://educalliance.eu), where it runs as the 'EDUC AI' assistant on
the alliance-wide Nextcloud portal. This public repository is the
upstream point of truth; deployment-specific tools plug in via the
tool-provider extension point (docs/TOOL_PROVIDERS.md).

License: AGPL-3.0-or-later.
2026-07-08 21:13:13 +02:00

1 line
11 KiB
Plaintext

{"version":3,"file":"appIconRuntime-ltIyK5iP.chunk.mjs","sources":["../src/utils/ensureOcFilePath.js","../src/utils/appIconRuntime.js"],"sourcesContent":["const ensureOcFilePath = () => {\n\tif (typeof window === 'undefined') {\n\t\treturn\n\t}\n\n\tconst oc = window.OC || (window.OC = {})\n\n\tif (typeof oc.filePath === 'function') {\n\t\treturn\n\t}\n\n\tconst trimSlashes = (value) => value.replace(/^\\/+|\\/+$/g, '')\n\n\tconst ensureLeadingSlash = (value) => {\n\t\tif (value.startsWith('/')) {\n\t\t\treturn value\n\t\t}\n\n\t\treturn `/${value}`\n\t}\n\n\tconst detectWebroot = () => {\n\t\tif (typeof oc.webroot === 'string' && oc.webroot.length > 0) {\n\t\t\treturn oc.webroot\n\t\t}\n\n\t\tconst meta = typeof document !== 'undefined'\n\t\t\t? document.querySelector('meta[name=\"oc:webroot\"]')\n\t\t\t: null\n\n\t\tif (meta && typeof meta.content === 'string') {\n\t\t\treturn meta.content\n\t\t}\n\n\t\treturn ''\n\t}\n\n\tconst joinSegments = (...segments) => {\n\t\tconst filtered = segments.filter((segment) => typeof segment === 'string' && segment.length > 0)\n\t\tif (filtered.length === 0) {\n\t\t\treturn ''\n\t\t}\n\n\t\tconst [first, ...rest] = filtered\n\t\tconst normalized = [first.replace(/\\/+$/g, ''), ...rest.map((segment) => trimSlashes(segment))]\n\t\tconst combined = normalized.filter(Boolean).join('/')\n\t\treturn combined.length > 0 ? ensureLeadingSlash(combined) : combined\n\t}\n\n\toc.filePath = (app, type, file) => {\n\t\tif (!app) {\n\t\t\treturn file || ''\n\t\t}\n\n\t\tconst base = detectWebroot()\n\t\treturn joinSegments(base, 'apps', app, type, file)\n\t}\n}\n\nensureOcFilePath()\n","import axios from '@nextcloud/axios'\nimport { generateUrl, imagePath } from '@nextcloud/router'\n\nconst APP_ID = 'educai'\nconst APP_ROUTE_FRAGMENT = '/apps/educai'\n\nlet currentRuntimeIcons = null\nlet iconObserver = null\nlet patchScheduled = false\n\nexport async function syncEducAiAppIconFromSettings() {\n\ttry {\n\t\tconst response = await axios.get(generateUrl('/apps/educai/api/v1/settings'))\n\t\tapplyEducAiRuntimeIconPayload(response.data)\n\t} catch {\n\t\t// Keep the bundled Nextcloud icon state if settings cannot be loaded.\n\t}\n}\n\nexport function applyEducAiRuntimeIconPayload(payload = {}, options = {}) {\n\tconst runtimeIcons = resolveRuntimeIcons(payload)\n\tapplyEducAiRuntimeIcons(runtimeIcons)\n\n\tif (options.refreshNavigation) {\n\t\trefreshNextcloudNavigation().finally(() => {\n\t\t\tapplyEducAiRuntimeIcons(runtimeIcons)\n\t\t})\n\t}\n}\n\nfunction resolveRuntimeIcons(payload) {\n\tconst runtimeUrls = payload?.app_icon_runtime_urls || {}\n\treturn {\n\t\tblack: normalizeIconUrl(runtimeUrls.black)\n\t\t\t|| resolveConfiguredIconUrl(payload, 'black')\n\t\t\t|| imagePath(APP_ID, 'app-dark.svg'),\n\t\twhite: normalizeIconUrl(runtimeUrls.white)\n\t\t\t|| resolveConfiguredIconUrl(payload, 'white')\n\t\t\t|| imagePath(APP_ID, 'app.svg'),\n\t}\n}\n\nfunction resolveConfiguredIconUrl(payload, variant) {\n\tconst mode = payload?.app_icon_mode === 'custom' || payload?.app_icon_url ? 'custom' : 'default'\n\tif (mode !== 'custom') {\n\t\treturn ''\n\t}\n\n\tconst variantKey = variant === 'white' ? 'app_icon_white_url' : 'app_icon_black_url'\n\tconst source = String(payload?.[variantKey] || payload?.app_icon_url || '').trim()\n\tif (/^educai-upload:\\/\\/(black|white)$/i.test(source)) {\n\t\treturn generateUrl(`/apps/educai/api/v1/app-icon/${variant}`)\n\t}\n\n\treturn normalizeIconUrl(source)\n}\n\nfunction normalizeIconUrl(value) {\n\tconst url = String(value || '').trim()\n\tif (!url) {\n\t\treturn ''\n\t}\n\n\tif (/^https?:\\/\\//i.test(url)) {\n\t\ttry {\n\t\t\tconst parsed = new URL(url)\n\t\t\treturn parsed.protocol === 'http:' || parsed.protocol === 'https:' ? url : ''\n\t\t} catch {\n\t\t\treturn ''\n\t\t}\n\t}\n\n\treturn url.startsWith('/') && !url.startsWith('//') ? url : ''\n}\n\nfunction applyEducAiRuntimeIcons(runtimeIcons) {\n\tcurrentRuntimeIcons = runtimeIcons\n\tpatchEducAiNavigationIcons(runtimeIcons.white || runtimeIcons.black)\n\tpatchEducAiFavicon(runtimeIcons.black || runtimeIcons.white)\n\tstartIconObserver()\n}\n\nfunction patchEducAiNavigationIcons(iconUrl) {\n\tif (!iconUrl || typeof document === 'undefined') {\n\t\treturn\n\t}\n\n\tconst appLinks = document.querySelectorAll(`a[href*=\"${APP_ROUTE_FRAGMENT}\"]`)\n\tfor (const link of appLinks) {\n\t\tconst href = link.getAttribute('href') || ''\n\t\tif (!href.includes(APP_ROUTE_FRAGMENT)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor (const image of link.querySelectorAll('img')) {\n\t\t\tif (image.getAttribute('src') !== iconUrl) {\n\t\t\t\timage.setAttribute('src', iconUrl)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction patchEducAiFavicon(iconUrl) {\n\tif (!iconUrl || typeof document === 'undefined' || !isEducAiSurface()) {\n\t\treturn\n\t}\n\n\tupsertHeadIconLink('favicon', 'icon', iconUrl, {\n\t\ttype: 'image/svg+xml',\n\t})\n\tupsertHeadIconLink('mask', 'mask-icon', iconUrl, {\n\t\tcolor: getComputedStyle(document.documentElement).getPropertyValue('--color-primary-element').trim() || '#000000',\n\t})\n}\n\nfunction upsertHeadIconLink(key, rel, href, attributes = {}) {\n\tlet link = document.head.querySelector(`link[data-educai-runtime-icon=\"${key}\"]`)\n\tif (!link) {\n\t\tlink = document.createElement('link')\n\t\tlink.setAttribute('data-educai-runtime-icon', key)\n\t\tdocument.head.appendChild(link)\n\t}\n\n\tlink.setAttribute('rel', rel)\n\tlink.setAttribute('href', href)\n\tfor (const [name, value] of Object.entries(attributes)) {\n\t\tlink.setAttribute(name, value)\n\t}\n}\n\nfunction startIconObserver() {\n\tif (iconObserver || typeof MutationObserver === 'undefined' || !document.body) {\n\t\treturn\n\t}\n\n\ticonObserver = new MutationObserver(scheduleIconPatch)\n\ticonObserver.observe(document.body, {\n\t\tchildList: true,\n\t\tsubtree: true,\n\t})\n}\n\nfunction scheduleIconPatch() {\n\tif (patchScheduled || !currentRuntimeIcons) {\n\t\treturn\n\t}\n\n\tpatchScheduled = true\n\twindow.requestAnimationFrame(() => {\n\t\tpatchScheduled = false\n\t\tpatchEducAiNavigationIcons(currentRuntimeIcons.white || currentRuntimeIcons.black)\n\t})\n}\n\nasync function refreshNextcloudNavigation() {\n\tif (typeof window === 'undefined') {\n\t\treturn\n\t}\n\n\tconst rebuildNavigation = window.OC?.Settings?.rebuildNavigation\n\tif (typeof rebuildNavigation === 'function') {\n\t\tawait rebuildNavigation()\n\t}\n}\n\nfunction isEducAiSurface() {\n\tif (typeof window === 'undefined') {\n\t\treturn false\n\t}\n\n\tconst path = window.location.pathname\n\treturn path.includes('/apps/educai')\n\t\t|| path.includes('/settings/user/educai')\n\t\t|| path.includes('/settings/admin/educai')\n}\n"],"names":["ensureOcFilePath","oc","trimSlashes","value","ensureLeadingSlash","detectWebroot","meta","joinSegments","segments","filtered","segment","first","rest","combined","app","type","file","base","APP_ID","APP_ROUTE_FRAGMENT","currentRuntimeIcons","iconObserver","patchScheduled","syncEducAiAppIconFromSettings","response","axios","generateUrl","applyEducAiRuntimeIconPayload","payload","options","runtimeIcons","resolveRuntimeIcons","applyEducAiRuntimeIcons","refreshNextcloudNavigation","runtimeUrls","normalizeIconUrl","resolveConfiguredIconUrl","imagePath","variant","source","url","parsed","patchEducAiNavigationIcons","patchEducAiFavicon","startIconObserver","iconUrl","appLinks","link","image","isEducAiSurface","upsertHeadIconLink","key","rel","href","attributes","name","scheduleIconPatch","rebuildNavigation","path"],"mappings":"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"}