`; return wrapper.firstElementChild; } async function handleError(err, guid, imgElementId) { updateStatus(`Error: ${err.message}`, true); const imgElement = document.getElementById(imgElementId); if (imgElement && imgElement.parentNode) { const errorSvg = createErrorSvgElement(imgElementId); imgElement.replaceWith(errorSvg); } } function escapeODataString(value) { return value.replace(/'/g, "''"); } async function displayImageSecurely(filename, imgElementId, isProtected = 0) { let guid = null; const safeFilename = escapeODataString(filename); try { // Check access for protected images if (isProtected === 1 && userEmail === "Anonymous User") { const returnUrl = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash); window.location.href = `/signin?returnurl=${returnUrl}`; return; } // Query for existing record const queryUrl = `/_api/dev_imagedownloadses?$select=dev_imagepath,dev_imagedownloadsid&$filter=dev_imagepath eq '${encodeURIComponent(safeFilename)}'`; const getResponse = await safeAjax({ type: "GET", url: queryUrl, contentType: "application/json" }); if (getResponse.value?.length > 0) { guid = getResponse.value[0].dev_imagedownloadsid; } else { // Create new record const postResponse = await safeAjax({ type: "POST", url: "/_api/dev_imagedownloadses", contentType: "application/json", data: JSON.stringify({ dev_imagepath: filename }), success: (res, status, xhr) => { guid = xhr.getResponseHeader("entityid"); } }); if (!guid) { const xhrGuid = postResponse?.getResponseHeader?.("entityid"); if (xhrGuid) guid = xhrGuid; } if (!guid) throw new Error("New GUID not returned after record creation."); } const imgElement = document.getElementById(imgElementId); if (!imgElement) throw new Error(`Image element with ID '${imgElementId}' not found.`); imgElement.src = `${AzureBaseUrl}/api/fetchblobimage?id=${guid}`; imgElement.alt = filename; // imgElement.onerror = () => handleError(new Error(`Failed to load image '${filename}'.`), guid, imgElementId); imgElement.onerror = () => { console.warn(`Image failed: ${filename}`); imgElement.dataset.loadFailed = "true"; imgElement.removeAttribute("src"); const errorSvg = createErrorSvgElement(imgElementId); imgElement.replaceWith(errorSvg); }; const blobUrl = `${AzureBaseUrl}/api/fetchblobimage?id=${guid}`; return blobUrl; } catch (err) { await handleError(err, guid, imgElementId); } } return { displayImageSecurely }; })(); } })();

${block.Paragraph || ""}`; break; case "Link": const isProtected = String(block.IsProtected).toLowerCase() === 'true' ? 1 : 0; const linkAttrs = ` href="#" data-href="${block.Link}" onclick="SecureLinkHandler.handleProtectedNavigation(event, this, ${isProtected})" rel="noopener noreferrer" `; const linkInnerHTML = `${block.LinkTitle || "Click here"} `; if (block.Paragraph) { html = `

${block.Paragraph || ""} ${block.LinkTitle || "Click here"}
`; } else { html = `

${linkInnerHTML}

`; } break; case "File": if (block.Paragraph) { const isProtected = String(block.IsProtected).toLowerCase() === 'true' ? 1 : 0; html = ` `; } else { const isProtected = String(block.IsProtected).toLowerCase() === 'true' ? 1 : 0; html = `

${block.FileName || "Download File"}

`; } break; default: html = `

Unknown block type: ${block.type}

`; } container.insertAdjacentHTML("beforeend", html); }); card.removeAttribute("data-json"); } catch (err) { } }); });

What's ahead

Stay informed with the latest updates, events, and opportunities.

Updates

Stay informed on the latest partner updates.

Microsoft 365 E7, Agent 365 announcements

March 9, 2026

Building a Scalable Copilot + Agents Practice: Practice Development Guide Walkthrough

March 31, 2026

Register

Business Applications Partner Activities Office Hours

April 21, 2026

Register

Grow your business with AI Business Solutions

Use Microsoft guidance and tools to accelerate go to market, expand services, and build agents and solutions that drive customer innovation and success.