A text-based bookmark manager rendered in a web page
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1867 lines
152 KiB

<!DOCTYPE html>
<html itemscope itemtype="https://schema.org/QAPage" class="html__responsive " lang="en">
<head>
<title>front end - Using sed/awk to bulk generate static HTML pages off of a template - Software Engineering Stack Exchange</title>
<link rel="shortcut icon" href="https://cdn.sstatic.net/Sites/softwareengineering/Img/favicon.ico?v=c4f35a1e3900">
<link rel="apple-touch-icon" href="https://cdn.sstatic.net/Sites/softwareengineering/Img/apple-touch-icon.png?v=5e581fc45e58">
<link rel="image_src" href="https://cdn.sstatic.net/Sites/softwareengineering/Img/apple-touch-icon.png?v=5e581fc45e58">
<link rel="search" type="application/opensearchdescription+xml" title="Software Engineering Stack Exchange" href="/opensearch.xml">
<link rel="canonical" href="https://softwareengineering.stackexchange.com/questions/439871/using-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" />
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0">
<meta property="og:type" content= "website" />
<meta property="og:url" content="https://softwareengineering.stackexchange.com/questions/439871/using-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template"/>
<meta property="og:site_name" content="Software Engineering Stack Exchange" />
<meta property="og:image" itemprop="image primaryImageOfPage" content="https://cdn.sstatic.net/Sites/softwareengineering/Img/apple-touch-icon@2.png?v=1ef7363febba" />
<meta name="twitter:card" content="summary"/>
<meta name="twitter:domain" content="softwareengineering.stackexchange.com"/>
<meta name="twitter:title" property="og:title" itemprop="name" content="Using sed/awk to bulk generate static HTML pages off of a template" />
<meta name="twitter:description" property="og:description" itemprop="description" content="Hypothetically, consider a social photo platform - each pic gets its own url, this page contains the image, text about the image, buttons for the user to click, related pics, and some user-specific " />
<script id="webpack-public-path" type="text/uri-list">https://cdn.sstatic.net/</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<script defer src="https://cdn.sstatic.net/Js/third-party/npm/@stackoverflow/stacks/dist/js/stacks.min.js?v=d5f780ae3281"></script>
<script src="https://cdn.sstatic.net/Js/stub.en.js?v=f346de94a369"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Shared/stacks.css?v=dbee492db9b7">
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/softwareengineering/primary.css?v=cae5ddb9130b">
<link rel="alternate" type="application/atom+xml" title="Feed for question &#x27;Using sed/awk to bulk generate static HTML pages off of a template&#x27;" href="/feeds/question/439871">
<script>
StackExchange.ready(function () {
StackExchange.using("postValidation", function () {
StackExchange.postValidation.initOnBlurAndSubmit($('#post-form'), 2, 'answer');
});
StackExchange.question.init({showAnswerHelp:true,totalCommentCount:2,shownCommentCount:2,enableTables:true,questionId:439871});
styleCode();
StackExchange.realtime.subscribeToQuestion('131', '439871');
StackExchange.using("gps", function () { StackExchange.gps.trackOutboundClicks('#content', '.js-post-body'); });
});
</script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Shared/Channels/channels.css?v=db82e15fc6d3">
<script>
StackExchange.ready(function () {
StackExchange.realtime.init('wss://qa.sockets.stackexchange.com');
StackExchange.realtime.subscribeToReputationNotifications('131');
StackExchange.realtime.subscribeToTopBarNotifications('131');
});
</script>
<script type="application/json" data-role="module-args" data-module-name="Shared/options.mod">{"options":{"locale":"en","serverTime":1709846696,"routeName":"Questions/Show","stackAuthUrl":"https://stackauth.com","networkMetaHostname":"meta.stackexchange.com","site":{"name":"Software Engineering Stack Exchange","description":"Q\u0026A for professionals, academics, and students working within the systems development life cycle","isNoticesTabEnabled":true,"enableNewTagCreationWarning":false,"insertSpaceAfterNameTabCompletion":false,"id":131,"cookieDomain":".stackexchange.com","childUrl":"https://softwareengineering.meta.stackexchange.com","negativeVoteScoreFloor":null,"enableSocialMediaInSharePopup":true,"protocol":"https"},"user":{"fkey":"27b7033a38c9489b51a2db328ed82e00b602b223db5e55f48328eb2bf4b6fccf","tid":"639f289c-ff51-46ae-9708-1bb9513244fc","rep":0,"isAnonymous":true,"isAnonymousNetworkWide":true},"realtime":{"newest":true,"active":true,"tagged":true,"staleDisconnectIntervalInHours":0},"events":{"postType":{"question":1},"postEditionSection":{"title":1,"body":2,"tags":3}}}}</script>
<script type="application/json" data-role="module-args" data-module-name="Shared/settings.mod">{"settings":{"comments":{},"snippets":{"renderDomain":"stacksnippets.net"},"search":{},"elections":{"opaVoteResultsBaseUrl":"https://www.opavote.com/results/"},"mentions":{"maxNumUsersInDropdown":50},"accounts":{"currentPasswordRequiredForChangingStackIdPassword":true},"auth":{},"subscriptions":{"defaultFreemiumMaxTrueUpSeats":50,"defaultMaxTrueUpSeats":1000,"defaultBasicMaxTrueUpSeats":250},"markdown":{"enableTables":true},"site":{"styleCode":true,"enableUserHovercards":true,"allowImageUploads":true,"stacksEditorPreviewEnabled":true,"enableImgurHttps":true,"forceHttpsImages":true},"flags":{"allowRetractingCommentFlags":true,"allowRetractingFlags":true},"tags":{},"userMessaging":{"showNewFeatureNotice":true},"legal":{"oneTrustTCFConfigId":"cb0f3c87-b769-4e66-bbaa-377f9194216d","useCustomConsent":false},"questions":{"maxTitleSize":150,"questionTitleLengthStartLiveWarningChars":50,"enableSavesFeature":true,"enableQuestionTitleLengthLiveWarning":true},"paths":{"jQueryUICSSPath":"https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/themes/smoothness/jquery-ui.css","jQueryUIJSPath":"https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js"},"intercom":{"appId":"inf0secd"}}}</script>
<script>StackExchange.init();</script>
<script>
StackExchange.using.setCacheBreakers({"Js/adops.en.js":"6da43f5e0a84","Js/ask.en.js":"","Js/begin-edit-event.en.js":"20edbaccceae","Js/copy-transpiled.en.js":"d31dc7eba3bc","Js/events.en.js":"","Js/explore-qlist.en.js":"2b1f34938b8b","Js/full-anon.en.js":"338510d8fbb6","Js/full.en.js":"1ae6dd5f6e49","Js/highlightjs-loader.en.js":"510e2f94c2bf","Js/inline-tag-editing.en.js":"3e8cc64ee9d6","Js/keyboard-shortcuts.en.js":"107c2ac31497","Js/markdown-it-loader.en.js":"5818ef89ff9d","Js/mentions-transpiled.en.js":"d398f7c1afbf","Js/moderator.en.js":"b16de1b84586","Js/postCollections-transpiled.en.js":"11a255fe9394","Js/post-validation.en.js":"243bf7d290a3","Js/question-editor.en.js":"","Js/review-v2-transpiled.en.js":"d8246fd945d5","Js/revisions.en.js":"47b4d5ac24c9","Js/stacks-editor.en.js":"58f53e9e8a88","Js/tageditor.en.js":"dc13482a67f8","Js/tageditornew.en.js":"b3d2f0187c1a","Js/tagsuggestions.en.js":"bd6ec908f2a7","Js/unlimited-transpiled.en.js":"f26a1d5f3365","Js/wmd.en.js":"102d8a628997"});
StackExchange.using("gps", function() {
StackExchange.gps.init(false);
});
</script>
<noscript id="noscript-css"><style>body,.s-topbar{margin-top:1.9em}</style></noscript>
</head>
<body class="question-page unified-theme">
<div id="notify-container"></div>
<div id="custom-header"></div>
<header class="s-topbar ps-fixed t0 l0 js-top-bar">
<div class="s-topbar--container">
<a href="#" class="s-topbar--menu-btn js-left-sidebar-toggle" role="menuitem" aria-haspopup="true" aria-controls="left-sidebar" aria-expanded="false"><span></span></a>
<div class="topbar-dialog leftnav-dialog js-leftnav-dialog dno">
<div class="left-sidebar js-unpinned-left-sidebar" data-can-be="left-sidebar" data-is-here-when="sm"></div>
</div>
<a href="#" class="s-topbar--logo network-logo js-gps-track js-network-logo"
data-gps-track="stack_exchange_popup.show" role="menuitem" aria-haspopup="true" aria-controls="topbar-network-logo-dialog" aria-expanded="false">
<svg aria-hidden="true" class="native mtn1 svg-icon iconLogoSEAlternativeSm" width="107" height="15" viewBox="0 0 107 15"><path d="m48.41 11.93-1.96-3.2-1.04 1.16v2.04h-1.42V2.18h1.42v6.01L48.14 5h1.72l-2.44 2.7 2.74 4.22h-1.75Zm-7.06.08c-1.59 0-3.14-.96-3.14-3.56s1.55-3.54 3.14-3.54c.97 0 1.65.27 2.31.97l-.97.93c-.44-.48-.79-.66-1.34-.66s-1 .22-1.3.62c-.31.38-.42.87-.42 1.68 0 .81.1 1.32.41 1.7.3.4.76.62 1.3.62.56 0 .9-.18 1.35-.66l.97.92c-.66.7-1.34.98-2.31.98Zm-5.66-3.15h-1.65c-.83 0-1.26.37-1.26 1s.4.99 1.3.99c.53 0 .93-.04 1.3-.4.22-.2.31-.53.31-1.03v-.56Zm.03 3.07v-.63c-.51.5-1 .71-1.87.71-.87 0-1.46-.2-1.89-.63a2.1 2.1 0 0 1-.55-1.49c0-1.16.82-2 2.42-2h1.86v-.5c0-.87-.44-1.3-1.54-1.3-.77 0-1.15.18-1.54.68l-.92-.86c.66-.77 1.35-1 2.52-1 1.93 0 2.9.8 2.9 2.38v4.64h-1.39Zm-5.9 0c-1.32 0-1.93-.93-1.93-1.93V6.18h-.8V5.1h.8V3h1.41v2.1h1.36v1.07H29.3v3.75c0 .5.25.81.78.81h.58v1.2h-.85Zm-6.33.08c-1.48 0-2.55-.34-3.49-1.28l1-.98c.72.72 1.51.94 2.52.94 1.3 0 2.04-.55 2.04-1.5 0-.42-.13-.78-.39-1.01-.25-.23-.5-.33-1.08-.41l-1.16-.17a3.4 3.4 0 0 1-1.88-.78 2.41 2.41 0 0 1-.72-1.86c0-1.7 1.25-2.86 3.3-2.86 1.3 0 2.22.33 3.07 1.1l-.96.94a2.92 2.92 0 0 0-2.15-.75c-1.16 0-1.8.65-1.8 1.52 0 .35.1.67.37.9.25.22.65.38 1.11.45l1.13.17c.91.13 1.42.35 1.84.72.54.47.8 1.17.8 2 0 1.8-1.48 2.86-3.55 2.86Z" fill="#FEFEFE"/><path d="M104.16 7.09c-.2-.42-.6-.74-1.2-.74s-.99.32-1.18.74c-.1.25-.15.44-.16.75h2.7a2 2 0 0 0-.16-.75Zm-2.54 1.96c0 .9.56 1.57 1.55 1.57.78 0 1.16-.21 1.61-.66l1.08 1.04a3.4 3.4 0 0 1-2.7 1.11c-1.68 0-3.29-.76-3.29-3.62 0-2.3 1.26-3.6 3.1-3.6 1.97 0 3.1 1.44 3.1 3.37v.79h-4.45Zm-5.48-2.57C95.1 6.48 95 7.37 95 8.3c0 .94.1 1.85 1.15 1.85 1.05 0 1.18-.91 1.18-1.85 0-.93-.13-1.82-1.18-1.82Zm-.17 8.22c-1.1 0-1.84-.21-2.58-.92l1.1-1.11c.4.38.8.54 1.4.54 1.06 0 1.43-.74 1.43-1.46v-.72c-.47.51-1 .7-1.7.7-.69 0-1.29-.23-1.68-.62-.67-.66-.73-1.57-.73-2.8 0-1.24.06-2.13.73-2.8.4-.39 1-.62 1.7-.62.75 0 1.24.2 1.73.75v-.67h1.72v6.8c0 1.7-1.21 2.93-3.12 2.93Zm-5.76-2.67V7.76c0-.96-.61-1.28-1.17-1.28-.56 0-1.18.32-1.18 1.28v4.27h-1.78V4.97h1.73v.65a2.44 2.44 0 0 1 1.78-.73c.7 0 1.28.23 1.67.62.58.57.73 1.24.73 2v4.52H90.2Zm-7.1-2.98h-1.4c-.64 0-1 .3-1 .8 0 .49.33.81 1.02.81.5 0 .8-.04 1.12-.34.2-.17.26-.46.26-.89v-.38Zm.04 2.98v-.6c-.48.47-.93.67-1.74.67-.8 0-1.4-.2-1.82-.62-.38-.4-.58-.97-.58-1.59 0-1.12.77-2.05 2.42-2.05h1.68V7.5c0-.77-.38-1.11-1.32-1.11-.68 0-1 .16-1.37.58l-1.13-1.1c.7-.75 1.38-.97 2.57-.97 1.99 0 3.02.84 3.02 2.5v4.64h-1.73Zm-6.93 0v-4.3c0-.94-.6-1.25-1.15-1.25-.56 0-1.15.32-1.15 1.24v4.31h-1.77V2.38h1.77v3.24a2.35 2.35 0 0 1 1.7-.73c1.56 0 2.38 1.08 2.38 2.57v4.57h-1.78Zm-6.96.08c-1.42 0-3.18-.76-3.18-3.62 0-2.85 1.76-3.6 3.18-3.6.98 0 1.72.3 2.34.95l-1.2 1.2c-.36-.4-.68-.56-1.14-.56-.42 0-.75.14-1.01.46-.27.33-.4.8-.4 1.55s.13 1.24.4 1.58c.26.3.59.46 1 .46.47 0 .79-.16 1.15-.56l1.2 1.18c-.62.65-1.36.96-2.34.96Zm-5.53-.08-1.3-2.11-1.3 2.11H59l2.45-3.6-2.35-3.46h2.12L62.42 7l1.21-2.02h2.13L63.4 8.43l2.46 3.6h-2.13Zm-11.75 0V2.06h6.6V3.8h-4.65v2.33h3.96v1.74h-3.96v2.42h4.65v1.74h-6.6Z" fill="#2F96E8"/><path d="M0 3c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2H0Z" fill="#8FD8F7"/><path d="M12 10H0c0 1.1.9 2 2 2h5v3l3-3a2 2 0 0 0 2-2Z" fill="#155397"/><path fill="#46A2D9" d="M0 4h12v2H0z"/><path fill="#2D6DB5" d="M0 7h12v2H0z"/></svg>
</a>
<div class="topbar-dialog network-logo-dialog js-network-logo-dialog dno" id="topbar-network-logo-dialog" role="dialog" aria-labelledby="topbar-network-logo-dialog-title" aria-describedby="topbar-network-logo-dialog-body">
<div class="dialog-content">
<h4 class="bold" id="topbar-network-logo-dialog-title">Stack Exchange Network</h4>
<p id="topbar-network-logo-dialog-body">
Stack Exchange network consists of 183 Q&amp;A communities including <a href="https://stackoverflow.com">Stack Overflow</a>, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
</p>
<a class="s-btn s-btn__filled" href="https://stackexchange.com"
data-gps-track="stack_exchange_popup.click">Visit Stack Exchange</a>
<button class="s-btn s-btn__muted p0 ps-absolute t16 r16 js-close-button" aria-label="Close"><svg aria-hidden="true" class="svg-icon iconClear" width="18" height="18" viewBox="0 0 18 18"><path d="M15 4.41 13.59 3 9 7.59 4.41 3 3 4.41 7.59 9 3 13.59 4.41 15 9 10.41 13.59 15 15 13.59 10.41 9 15 4.41Z"/></svg></button>
</div>
</div>
<form id="search" role="search" action=/search class="s-topbar--searchbar js-searchbar " autocomplete="off">
<div class="s-topbar--searchbar--input-group">
<input name="q"
type="text"
role="combobox"
placeholder="Search on Software Engineering&#x2026;"
value=""
autocomplete="off"
maxlength="240"
class="s-input s-input__search js-search-field "
aria-label="Search"
aria-controls="top-search"
data-controller="s-popover"
data-action="focus->s-popover#show"
data-s-popover-placement="bottom-start" />
<svg aria-hidden="true" class="s-input-icon s-input-icon__search svg-icon iconSearch" width="18" height="18" viewBox="0 0 18 18"><path d="m18 16.5-5.14-5.18h-.35a7 7 0 1 0-1.19 1.19v.35L16.5 18l1.5-1.5ZM12 7A5 5 0 1 1 2 7a5 5 0 0 1 10 0Z"/></svg>
<div class="s-popover p0 wmx100 wmn4 sm:wmn-initial js-top-search-popover" id="top-search" role="menu">
<div class="s-popover--arrow"></div>
<div class="js-spinner p24 d-flex ai-center jc-center d-none">
<div class="s-spinner s-spinner__sm fc-orange-400">
<div class="v-visible-sr">Loading&#x2026;</div>
</div>
</div>
<span class="v-visible-sr js-screen-reader-info"></span>
<div class="js-ac-results overflow-y-auto hmx3 d-none"></div>
<div class="js-search-hints" aria-describedby="Tips for searching"></div>
</div>
</div>
</form>
<nav class="h100 ml-auto overflow-x-auto pr12">
<ol class="s-topbar--content" role="menubar">
<li role="none">
<a href="/help" class="s-topbar--item js-help-button" role="menuitem" title="Help Center and other resources" aria-haspopup="true" aria-controls="topbar-help-dialog"
data-ga="[&quot;top navigation&quot;,&quot;help menu click&quot;,null,null,null]"><svg aria-hidden="true" class="svg-icon iconHelp" width="18" height="18" viewBox="0 0 18 18"><path d="M9 1C4.64 1 1 4.64 1 9c0 4.36 3.64 8 8 8 4.36 0 8-3.64 8-8 0-4.36-3.64-8-8-8Zm.81 12.13c-.02.71-.55 1.15-1.24 1.13-.66-.02-1.17-.49-1.15-1.2.02-.72.56-1.18 1.22-1.16.7.03 1.2.51 1.17 1.23ZM11.77 8c-.59.66-1.78 1.09-2.05 1.97a4 4 0 0 0-.09.75c0 .05-.03.16-.18.16H7.88c-.16 0-.18-.1-.18-.15.06-1.35.66-2.2 1.83-2.88.39-.29.7-.75.7-1.24.01-1.24-1.64-1.82-2.35-.72-.21.33-.18.73-.18 1.1H5.75c0-1.97 1.03-3.26 3.03-3.26 1.75 0 3.47.87 3.47 2.83 0 .57-.2 1.05-.48 1.44Z"/></svg></a>
</li>
<div class="topbar-dialog help-dialog js-help-dialog dno" id="topbar-help-dialog" role="menu">
<div class="modal-content">
<ul>
<li>
<a href="/tour" class="js-gps-track s-block-link" data-gps-track="help_popup.click({ item_type:1 })"
data-ga="[&quot;top navigation&quot;,&quot;tour submenu click&quot;,null,null,null]">
Tour
<span class="item-summary">
Start here for a quick overview of the site
</span>
</a>
</li>
<li>
<a href="/help" class="js-gps-track s-block-link"
data-gps-track="help_popup.click({ item_type:4 })"
data-ga="[&quot;top navigation&quot;,&quot;help center&quot;,null,null,null]">
Help Center
<span class="item-summary">
Detailed answers to any questions you might have
</span>
</a>
</li>
<li>
<a href="https://softwareengineering.meta.stackexchange.com" class="js-gps-track s-block-link" data-gps-track="help_popup.click({ item_type:2 })"
data-ga="[&quot;top navigation&quot;,&quot;meta submenu click&quot;,null,null,null]">
Meta
<span class="item-summary">
Discuss the workings and policies of this site
</span>
</a>
</li>
<li>
<a href="https://stackoverflow.co/" class="js-gps-track s-block-link" data-gps-track="help_popup.click({ item_type:6 })"
data-ga="[&quot;top navigation&quot;,&quot;about us submenu click&quot;,null,null,null]">
About Us
<span class="item-summary">
Learn more about Stack Overflow the company, and our products
</span>
</a>
</li>
</ul>
</div>
</div>
<li role="none">
<a href="https://stackexchange.com" class="s-topbar--item js-site-switcher-button js-gps-track" data-gps-track="site_switcher.show"
aria-label="Site switcher"
role="menuitem"
title="A list of all 183 Stack Exchange sites"
aria-haspopup="true" aria-expanded="false"
data-ga="[&quot;top navigation&quot;,&quot;stack exchange click&quot;,null,null,null]">
<svg aria-hidden="true" class="svg-icon iconStackExchange" width="18" height="18" viewBox="0 0 18 18"><path d="M15 1H3a2 2 0 0 0-2 2v2h16V3a2 2 0 0 0-2-2ZM1 13c0 1.1.9 2 2 2h8v3l3-3h1a2 2 0 0 0 2-2v-2H1v2Zm16-7H1v4h16V6Z"/></svg>
</a>
</li>
<li class="js-topbar-dialog-corral" role="presentation">
<div class="topbar-dialog siteSwitcher-dialog dno" role="menu">
<div class="header fw-wrap">
<h3 class="flex--item">
<a href="https://softwareengineering.stackexchange.com">current community</a>
</h3>
<div class="flex--item fl1">
<div class="ai-center d-flex jc-end">
<button
class="js-close-button s-btn s-btn__muted p0 ml8 d-none sm:d-block"
type="button"
aria-label="Close"
>
<svg aria-hidden="true" class="svg-icon iconClear" width="18" height="18" viewBox="0 0 18 18"><path d="M15 4.41 13.59 3 9 7.59 4.41 3 3 4.41 7.59 9 3 13.59 4.41 15 9 10.41 13.59 15 15 13.59 10.41 9 15 4.41Z"/></svg>
</button>
</div>
</div>
</div>
<div class="modal-content bg-blue-200 current-site-container">
<ul class="current-site">
<li class="d-flex">
<div class="fl1">
<a href="https://softwareengineering.stackexchange.com"
class="current-site-link d-flex gx8 site-link js-gps-track"
data-id="131"
data-gps-track="site_switcher.click({ item_type:3 })">
<div class="favicon favicon-softwareengineering site-icon flex--item" title="Software Engineering"></div>
<span class="flex--item fl1">
Software Engineering
</span>
</a>
</div>
<div class="related-links">
<a href="https://softwareengineering.stackexchange.com/help" class="js-gps-track" data-gps-track="site_switcher.click({ item_type:14 })">help</a>
<a href="https://chat.stackexchange.com?tab=site&amp;host=softwareengineering.stackexchange.com" class="js-gps-track" data-gps-track="site_switcher.click({ item_type:6 })">chat</a>
</div>
</li>
<li class="related-site d-flex">
<div class="L-shaped-icon-container">
<span class="L-shaped-icon"></span>
</div>
<a href="https://softwareengineering.meta.stackexchange.com"
class="s-block-link px16 d-flex gx8 site-link js-gps-track"
data-id="133"
data-gps-track="site.switch({ target_site:133, item_type:3 }),site_switcher.click({ item_type:4 })">
<div class="favicon favicon-softwareengineeringmeta site-icon flex--item" title="Software Engineering Meta"></div>
<span class="flex--item fl1">
Software Engineering Meta
</span>
</a>
</li>
</ul>
</div>
<div class="header" id="your-communities-header">
<h3>
your communities </h3>
</div>
<div class="modal-content" id="your-communities-section">
<div class="call-to-login">
<a href="https://softwareengineering.stackexchange.com/users/signup?ssrc=site_switcher&amp;returnurl=https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" class="login-link js-gps-track" data-gps-track="site_switcher.click({ item_type:10 })">Sign up</a> or <a href="https://softwareengineering.stackexchange.com/users/login?ssrc=site_switcher&amp;returnurl=https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" class="login-link js-gps-track" data-gps-track="site_switcher.click({ item_type:11 })">log in</a> to customize your list. </div>
</div>
<div class="header">
<h3><a href="https://stackexchange.com/sites">more stack exchange communities</a>
</h3>
<a href="https://stackoverflow.blog" class="float-right">company blog</a>
</div>
<div class="modal-content">
<div class="child-content"></div>
</div>
</div>
</li>
<li role="none"><button class="s-topbar--item s-btn s-btn__icon s-btn__muted d-none sm:d-inline-flex js-searchbar-trigger" role="menuitem" aria-label="Search" aria-haspopup="true" aria-controls="search" title="Click to show search"><svg aria-hidden="true" class="svg-icon iconSearch" width="18" height="18" viewBox="0 0 18 18"><path d="m18 16.5-5.14-5.18h-.35a7 7 0 1 0-1.19 1.19v.35L16.5 18l1.5-1.5ZM12 7A5 5 0 1 1 2 7a5 5 0 0 1 10 0Z"/></svg></button></li>
<li role="none">
<a href="https://softwareengineering.stackexchange.com/users/login?ssrc=head&returnurl=https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" class="s-topbar--item s-topbar--item__unset s-btn s-btn__outlined ws-nowrap js-gps-track" role="menuitem" rel="nofollow"
data-gps-track="login.click" data-ga="[&quot;top navigation&quot;,&quot;login button click&quot;,null,null,null]">Log in</a>
</li>
<li role="none"><a href="https://softwareengineering.stackexchange.com/users/signup?ssrc=head&returnurl=https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" class="s-topbar--item s-topbar--item__unset ml4 s-btn s-btn__filled ws-nowrap js-gps-track" role="menuitem" rel="nofollow" data-gps-track="signup.topbar.click" data-ga="[&quot;sign up&quot;,&quot;Sign Up Navigation&quot;,&quot;Header&quot;,null,null]">Sign up</a></li>
</ol>
</nav>
</div>
</header>
<script>
StackExchange.ready(function () { StackExchange.topbar.init(); });
StackExchange.scrollPadding.setPaddingTop(50, 10);
</script>
<div id="top-hero-div">
</div>
<header class="site-header">
<div class="site-header--container">
<a class="site-header--link d-flex ai-center fs-headline1 fw-bold" href="https://softwareengineering.stackexchange.com">
<img class="h-auto wmx100" src="https://cdn.sstatic.net/Sites/softwareengineering/Img/logo.svg?v=e86f7d5306ae" alt="Software Engineering">
</a>
</div>
</header>
<div class="container">
<div id="left-sidebar" data-is-here-when="md lg" class="left-sidebar js-pinned-left-sidebar ps-relative">
<div class="left-sidebar--sticky-container js-sticky-leftnav">
<nav role="navigation">
<ol class="nav-links">
<li>
<ol class="nav-links">
<li class="ps-relative" aria-current="false">
<a
href="/"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: false, location:2, destination:8, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconHome" width="18" height="18" viewBox="0 0 18 18"><path d="M15 10v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5H0l9-9 9 9h-3Zm-8 1v6h4v-6H7Z"/></svg> <span class="-link--channel-name pl6">Home</span>
</div>
</a>
</li>
<li class="ps-relative youarehere" aria-current="true">
<a id="nav-questions"
href="/questions"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: true, location:2, destination:1, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconQuestion" width="18" height="18" viewBox="0 0 18 18"><path d="m4 15-3 3V4c0-1.1.9-2 2-2h12c1.09 0 2 .91 2 2v9c0 1.09-.91 2-2 2H4Zm7.75-3.97c.72-.83.98-1.86.98-2.94 0-1.65-.7-3.22-2.3-3.83a4.41 4.41 0 0 0-3.02 0 3.8 3.8 0 0 0-2.32 3.83c0 1.29.35 2.29 1.03 3a3.8 3.8 0 0 0 2.85 1.07c.62 0 1.2-.11 1.71-.34.65.44 1 .68 1.06.7.23.13.46.23.7.3l.59-1.13a5.2 5.2 0 0 1-1.28-.66Zm-1.27-.9a5.4 5.4 0 0 0-1.5-.8l-.45.9c.33.12.66.29.98.5-.2.07-.42.11-.65.11-.61 0-1.12-.23-1.52-.68-.86-1-.86-3.12 0-4.11.8-.9 2.35-.9 3.15 0 .9 1.01.86 3.03-.01 4.08Z"/></svg> <span class="-link--channel-name pl6">Questions</span>
</div>
</a>
</li>
<li class="ps-relative" aria-current="false">
<a
href="/tags"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: false, location:2, destination:2, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconTags" width="18" height="18" viewBox="0 0 18 18"><path d="M9.24 1a3 3 0 0 0-2.12.88l-5.7 5.7a2 2 0 0 0-.38 2.31 3 3 0 0 1 .67-1.01l6-6A3 3 0 0 1 9.83 2H14a3 3 0 0 1 .79.1A2 2 0 0 0 13 1H9.24Z" opacity=".4"/><path d="M9.83 3a2 2 0 0 0-1.42.59l-6 6a2 2 0 0 0 0 2.82L6.6 16.6a2 2 0 0 0 2.82 0l6-6A2 2 0 0 0 16 9.17V5a2 2 0 0 0-2-2H9.83ZM12 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4Z"/></svg> <span class="-link--channel-name pl6">Tags</span>
</div>
</a>
</li>
<li class="pb24"></li>
<li class="ps-relative" aria-current="false">
<a id="nav-users"
href="/users"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: false, location:2, destination:3, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconPeople" width="18" height="18" viewBox="0 0 18 18"><path d="M17 14c0 .44-.45 1-1 1H9a1 1 0 0 1-1-1H2c-.54 0-1-.56-1-1 0-2.63 3-4 3-4s.23-.4 0-1c-.84-.62-1.06-.59-1-3 .06-2.42 1.37-3 2.5-3s2.44.58 2.5 3c.06 2.41-.16 2.38-1 3-.23.59 0 1 0 1s1.55.71 2.42 2.09c.78-.72 1.58-1.1 1.58-1.1s.23-.4 0-1c-.84-.61-1.06-.58-1-3 .06-2.41 1.37-3 2.5-3s2.44.59 2.5 3c.05 2.42-.16 2.39-1 3-.23.6 0 1 0 1s3 1.38 3 4Z"/></svg> <span class="-link--channel-name pl6">Users</span>
</div>
</a>
</li>
<li class="ps-relative" aria-current="false">
<a id="nav-companies"
href="https://stackoverflow.com/jobs/companies?so_medium=softwareengineering&amp;so_source=SiteNav"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: false, location:2, destination:12, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconBriefcase" width="18" height="18" viewBox="0 0 18 18"><path d="M5 4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v1h1a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2h1V4Zm7 0H6v1h6V4Z"/></svg> <span class="-link--channel-name pl6">Companies</span>
</div>
</a>
</li>
<li class="ps-relative" aria-current="false">
<a id="nav-unanswered"
href="/unanswered"
class="s-block-link pl8 js-gps-track nav-links--link -link__with-icon"
data-gps-track="top_nav.click({is_current: false, location:2, destination:5, has_activity_notification:False})"
aria-controls="" data-controller="" data-s-popover-placement="right"
aria-current="false"
data-s-popover-auto-show="true" data-s-popover-hide-on-outside-click="never"
>
<div class="d-flex ai-center">
<svg aria-hidden="true" class="svg-icon iconAnswer" width="18" height="18" viewBox="0 0 18 18"><path d="M14 15H3c-1.09 0-2-.91-2-2V4c0-1.1.9-2 2-2h12c1.09 0 2 .91 2 2v14l-3-3Zm-1.02-3L9.82 4H8.14l-3.06 8h1.68l.65-1.79h3.15l.69 1.79h1.73Zm-2.93-3.12H7.9l1.06-2.92 1.09 2.92Z"/></svg> <span class="-link--channel-name pl6">Unanswered</span>
</div>
</a>
</li>
</ol>
</li>
<li class="js-freemium-cta ps-relative">
<div class="fs-fine tt-uppercase fc-black-600 fw-bold ml8 mt16 mb8">Teams</div>
<div class="bt bl bb bc-black-200 p12 pb6 fc-black-500 blr-sm overflow-hidden">
<strong class="fc-black-600 mb6">Stack Overflow for Teams</strong>
– Start collaborating and sharing organizational knowledge.
<img class="wmx100 mx-auto my8 h-auto d-block" width="139" height="114" src="https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg?v=47faa659a05e" alt="">
<a href="https://try.stackoverflow.co/why-teams/?utm_source=so-owned&amp;utm_medium=side-bar&amp;utm_campaign=campaign-38&amp;utm_content=cta"
class="w100 s-btn s-btn__filled s-btn__xs bg-orange-400 js-gps-track"
data-gps-track="teams.create.left-sidenav.click({ Action: 6 })"
data-ga="[&quot;teams left navigation - anonymous&quot;,&quot;left nav free cta&quot;,&quot;stackoverflow.com/teams/create/free&quot;,null,null]">Create a free Team</a>
<a href="https://stackoverflow.co/teams/"
class="w100 s-btn s-btn__muted s-btn__xs js-gps-track"
data-gps-track="teams.create.left-sidenav.click({ Action: 5 })"
data-ga="[&quot;teams left navigation - anonymous&quot;,&quot;left nav free cta&quot;,&quot;stackoverflow.com/teams&quot;,null,null]">Why Teams?</a>
</div>
</li>
<li class="d-flex ai-center jc-space-between ml8 mt32 mb8 js-create-team-cta d-none">
<a href="javascript:void(0)"
class="s-link d-flex fl-grow1 fc-black-400 h:fc-black-600 fs-fine js-gps-track"
role="button"
aria-controls="popover-teams-create-cta"
data-controller="s-popover"
data-action="s-popover#toggle"
data-s-popover-placement="bottom-start"
data-s-popover-toggle-class="is-selected"
data-gps-track="teams.create.left-sidenav.click({ Action: ShowInfo })"
data-ga="[&quot;teams left navigation - anonymous&quot;,&quot;left nav show teams info&quot;,null,null,null]"
>
<div class="flex--item fl-grow1 fc-black-600 fw-bold tt-uppercase">Teams</div>
<div class="flex--item px12">
<svg aria-hidden="true" class="svg-icon iconPlusSm" width="14" height="14" viewBox="0 0 14 14"><path d="M8 2H6v4H2v2h4v4h2V8h4V6H8V2Z"/></svg>
</div>
</a>
</li>
<li class="ps-relative js-create-team-cta d-none">
<a href="https://stackoverflowteams.com/teams/create/free/?utm_source=so-owned&amp;utm_medium=side-bar&amp;utm_campaign=campaign-38&amp;utm_content=cta"
class="s-block-link pl8 js-gps-track nav-links--link"
title="Stack Overflow for Teams is a private, secure spot for your organization's questions and answers."
data-gps-track="teams.create.left-sidenav.click({ Action: FreemiumTeamsCreateClick })"
data-ga="[&quot;teams left navigation - anonymous&quot;,&quot;left nav team click&quot;,&quot;stackoverflow.com/teams/create/free&quot;,null,null]">
<div class="d-flex ai-center">
<div class="flex--item s-avatar va-middle bg-orange-400">
<div class="s-avatar--letter mtn1">
<svg aria-hidden="true" class="svg-icon iconBriefcaseSm" width="14" height="14" viewBox="0 0 14 14"><path d="M4 3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v1h.5c.83 0 1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5h-7A1.5 1.5 0 0 1 2 10.5v-5C2 4.67 2.67 4 3.5 4H4V3Zm5 1V3H5v1h4Z"/></svg>
</div>
<svg aria-hidden="true" class="native s-avatar--badge svg-icon iconShieldXSm" width="9" height="10" viewBox="0 0 9 10"><path fill="var(--white)" d="M0 1.84 4.5 0 9 1.84v3.17C9 7.53 6.3 10 4.5 10 2.7 10 0 7.53 0 5.01V1.84Z"/><path fill="var(--black-400)" d="M1 2.5 4.5 1 8 2.5v2.51C8 7.34 5.34 9 4.5 9 3.65 9 1 7.34 1 5.01V2.5Zm2.98 3.02L3.2 7h2.6l-.78-1.48a.4.4 0 0 1 .15-.38c.34-.24.73-.7.73-1.14 0-.71-.5-1.23-1.41-1.23-.92 0-1.39.52-1.39 1.23 0 .44.4.9.73 1.14.12.08.18.23.15.38Z"/></svg>
</div>
<div class="flex--item pl6">
Create free Team
</div>
</div>
</a>
</li>
</ol>
</nav>
</div>
<div class="s-popover ws2"
id="popover-teams-create-cta"
role="menu"
aria-hidden="true">
<div class="s-popover--arrow"></div>
<div class="ps-relative overflow-hidden">
<p class="mb2"><strong>Teams</strong></p>
<p class="mb12 fs-caption fc-black-400">Q&amp;A for work</p>
<p class="mb12 fs-caption fc-black-500">Connect and share knowledge within a single location that is structured and easy to search.</p>
<a href="https://stackoverflow.co/teams/"
class="js-gps-track s-btn s-btn__filled s-btn__xs"
data-gps-track="teams.create.left-sidenav.click({ Action: CtaClick })"
data-ga="[&quot;teams left navigation - anonymous&quot;,&quot;left nav cta&quot;,&quot;stackoverflow.com/teams&quot;,null,null]">
Learn more about Teams
</a>
</div>
<div class="ps-absolute t8 r8">
<svg aria-hidden="true" class="fc-orange-400 svg-spot spotPeople" width="48" height="48" viewBox="0 0 48 48"><path d="M13.5 28a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9ZM7 30a1 1 0 0 1 1-1h11a1 1 0 0 1 1 1v5h11v-5a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v10a2 2 0 0 1-2 2H33v5a1 1 0 0 1-1 1H20a1 1 0 0 1-1-1v-5H8a1 1 0 0 1-1-1V30Zm25-6.5a4.5 4.5 0 1 0 9 0 4.5 4.5 0 0 0-9 0ZM24.5 34a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Z" opacity=".2"/><path d="M16.4 26.08A6 6 0 1 0 7.53 26C5.64 26.06 4 27.52 4 29.45V40a1 1 0 0 0 1 1h9a1 1 0 1 0 0-2h-4v-7a1 1 0 1 0-2 0v7H6v-9.55c0-.73.67-1.45 1.64-1.45H16a1 1 0 0 0 .4-1.92ZM12 18a4 4 0 1 1 0 8 4 4 0 0 1 0-8Zm16.47 14a6 6 0 1 0-8.94 0A3.6 3.6 0 0 0 16 35.5V46a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V35.5c0-1.94-1.64-3.42-3.53-3.5ZM20 28a4 4 0 1 1 8 0 4 4 0 0 1-8 0Zm-.3 6h8.6c1 0 1.7.75 1.7 1.5V45h-2v-7a1 1 0 1 0-2 0v7h-4v-7a1 1 0 1 0-2 0v7h-2v-9.5c0-.75.7-1.5 1.7-1.5ZM42 22c0 1.54-.58 2.94-1.53 4A3.5 3.5 0 0 1 44 29.45V40a1 1 0 0 1-1 1h-9a1 1 0 1 1 0-2h4v-7a1 1 0 1 1 2 0v7h2v-9.55A1.5 1.5 0 0 0 40.48 28H32a1 1 0 0 1-.4-1.92A6 6 0 1 1 42 22Zm-2 0a4 4 0 1 0-8 0 4 4 0 0 0 8 0Z"/><g opacity=".35"><path d="M17 10a1 1 0 011-1h12a1 1 0 110 2H18a1 1 0 01-1-1Zm1-5a1 1 0 100 2h12a1 1 0 100-2H18ZM14 1a1 1 0 00-1 1v12a1 1 0 001 1h5.09l4.2 4.2a1 1 0 001.46-.04l3.7-4.16H34a1 1 0 001-1V2a1 1 0 00-1-1H14Zm1 12V3h18v10h-5a1 1 0 00-.75.34l-3.3 3.7-3.74-3.75a1 1 0 00-.71-.29H15Z"/></g></svg>
</div>
</div>
</div>
<div id="content" class="">
<div itemprop="mainEntity" itemscope itemtype="https://schema.org/Question">
<link itemprop="image" href="https://cdn.sstatic.net/Sites/softwareengineering/Img/apple-touch-icon.png?v=5e581fc45e58">
<div class="inner-content clearfix">
<div id="question-header" class="d-flex sm:fd-column">
<h1 itemprop="name" class="fs-headline1 ow-break-word mb8 flex--item fl1"><a href="/questions/439871/using-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template" class="question-hyperlink">Using sed/awk to bulk generate static HTML pages off of a template</a></h1>
<div class="ml12 aside-cta flex--item print:d-none sm:ml0 sm:mb12 sm:order-first sm:as-end">
<a href="/questions/ask" class="ws-nowrap s-btn s-btn__filled">
Ask Question
</a>
</div>
</div>
<div class="d-flex fw-wrap pb8 mb16 bb bc-black-200">
<div class="flex--item ws-nowrap mr16 mb8" title="2022-07-17 20:28:09Z">
<span class="fc-black-400 mr2">Asked</span>
<time itemprop="dateCreated" datetime="2022-07-17T20:28:09">1 year, 7 months ago</time>
</div>
<div class="flex--item ws-nowrap mr16 mb8">
<span class="fc-black-400 mr2">Modified</span>
<a href="?lastactivity" class="s-link s-link__inherit" title="2022-07-18 06:48:48Z">1 year, 7 months ago</a>
</div>
<div class="flex--item ws-nowrap mb8" title="Viewed 137 times">
<span class="fc-black-400 mr2">Viewed</span>
137 times
</div>
</div>
<div id="mainbar" role="main" aria-label="question and answers">
<div class="question js-question" data-questionid="439871" data-position-on-page="0" data-score="0" id="question">
<style>
</style>
<div class="js-zone-container zone-container-main">
<div id="dfp-tlb" class="everyonelovesstackoverflow everyoneloves__top-leaderboard everyoneloves__leaderboard"></div>
<div class="js-report-ad-button-container " style="width: 728px"></div>
</div>
<div class="post-layout ">
<div class="votecell post-layout--left">
<div class="js-voting-container d-flex jc-center fd-column ai-stretch gs4 fc-black-300" data-post-id="439871" data-referrer="None">
<button class="js-vote-up-btn flex--item s-btn ba bar-pill c-pointer as-center bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
title="This question shows research effort; it is useful and clear"
aria-pressed="false"
aria-label="Up vote"
data-selected-classes="fc-theme-primary-100 bc-theme-primary-500 bg-theme-primary-500"
data-unselected-classes="bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050">
<svg aria-hidden="true" class="svg-icon iconArrowUp" width="18" height="18" viewBox="0 0 18 18"><path d="M1 12h16L9 4l-8 8Z"/></svg>
</button>
<div class="js-vote-count flex--item d-flex fd-column ai-center fc-theme-body-font fw-bold fs-subheading py4"
itemprop="upvoteCount"
data-value="0">
0
</div>
<button class="js-vote-down-btn flex--item mb8 s-btn ba bar-pill c-pointer as-center bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
title="This question does not show any research effort; it is unclear or not useful"
aria-pressed="false"
aria-label="Down vote"
data-selected-classes="fc-theme-primary-100 bc-theme-primary-500 bg-theme-primary-500"
data-unselected-classes="bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050">
<svg aria-hidden="true" class="svg-icon iconArrowDown" width="18" height="18" viewBox="0 0 18 18"><path d="M1 6h16l-8 8-8-8Z"/></svg>
</button>
<button class="js-saves-btn s-btn s-btn__unset c-pointer py4"
type="button"
id="saves-btn-439871"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
data-s-popover-placement=""
title="Save this question."
aria-pressed="false"
data-post-id="439871"
data-post-type-id="1"
data-user-privilege-for-post-click="0"
aria-controls=""
data-s-popover-auto-show="false"
>
<svg aria-hidden="true" class="fc-theme-primary-400 js-saves-btn-selected d-none svg-icon iconBookmark" width="18" height="18" viewBox="0 0 18 18"><path d="M3 17V3c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v14l-6-4-6 4Z"/></svg>
<svg aria-hidden="true" class="js-saves-btn-unselected svg-icon iconBookmarkAlt" width="18" height="18" viewBox="0 0 18 18"><path d="m9 10.6 4 2.66V3H5v10.26l4-2.66ZM3 17V3c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v14l-6-4-6 4Z"/></svg>
</button>
<a class="js-post-issue flex--item s-btn s-btn__unset c-pointer py6 mx-auto" href="/posts/439871/timeline" data-shortcut="T" data-ks-title="timeline" data-controller="s-tooltip" data-s-tooltip-placement="right" title="Show activity on this post." aria-label="Timeline"><svg aria-hidden="true" class="mln2 mr0 svg-icon iconHistory" width="19" height="18" viewBox="0 0 19 18"><path d="M3 9a8 8 0 1 1 3.73 6.77L8.2 14.3A6 6 0 1 0 5 9l3.01-.01-4 4-4-4h3L3 9Zm7-4h1.01L11 9.36l3.22 2.1-.6.93L10 10V5Z"/></svg></a>
</div>
</div>
<div class="postcell post-layout--right">
<div class="s-prose js-post-body" itemprop="text">
<p>Hypothetically, consider a social photo platform - each pic gets its own url, this page contains the image, text about the image, buttons for the user to click, related pics, and some user-specific elements (maybe notifications, etc.).
There are different ways of going about the frontend. In each case, elements specific to the logged-in-user and the related images get fetched via api calls and are rendered client side.</p>
<p>For rendering the rest of the page, couple of distinct possibilities -</p>
<ol>
<li>Everything is rendered client side - one can use a single page application to handle the routing. The page structure stays the same, and new image uri's and the associated content are fetched via api calls.</li>
</ol>
<p>SEO is a priority, so pure client side rendering is suboptimal.</p>
<ol start="2">
<li><p>Server side rendering for each page with NextJS or even Express is another option.</p>
</li>
<li><p>Another way is to do a static export in something like NextJS - which will generate separate html files for each image.</p>
</li>
<li><p>Now my thought is to skip all of that and go old school with sed/awk. We'll have a template file with all the styling elements and placeholders for the image uri and its description, etc. Then a script iterates through a list of values (queried from a database) specific to each image (img source URIs, description text, etc.) and uses sed to replace the placeholders in the template file and output a separate html file.</p>
</li>
</ol>
<p>Each file has the same javascript to load the user-specific components.</p>
<p>Every time someone adds a new image, the script runs with the uri of the image and the description, etc. as the variables passed to it, and adds a new html file in a flat file structure.</p>
<p>These &quot;variables&quot; are stored in a database. So whenever we change the &quot;design&quot; of the page, we repeat the same process again - regenerate each html file.</p>
<p>The flat file structure will run into limitations, which is solvable with a directory structure. Nginx remains performant with large numbers of files.</p>
<p>Right now, we use NextJS with a mix of server side rendering and static pages, so it is all good. But I have been wondering about achieving something similar with more rudimentary (and performant) tools.</p>
<p>There's not too much additional work involved - templatizing the html file is straightforward, and this won't be difficult to script.</p>
<p>What's good and bad about this?</p>
</div>
<div class="mt24 mb12">
<div class="post-taglist d-flex gs4 gsy fd-column">
<div class="d-flex ps-relative fw-wrap">
<ul class='ml0 list-ls-none js-post-tag-list-wrapper d-inline'><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/html" class="post-tag" title="show questions tagged &#39;html&#39;" aria-label="show questions tagged &#39;html&#39;" rel="tag" aria-labelledby="tag-html-tooltip-container">html</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/front-end" class="post-tag" title="show questions tagged &#39;front-end&#39;" aria-label="show questions tagged &#39;front-end&#39;" rel="tag" aria-labelledby="tag-front-end-tooltip-container">front-end</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/scripting" class="post-tag" title="show questions tagged &#39;scripting&#39;" aria-label="show questions tagged &#39;scripting&#39;" rel="tag" aria-labelledby="tag-scripting-tooltip-container">scripting</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/code-generation" class="post-tag" title="show questions tagged &#39;code-generation&#39;" aria-label="show questions tagged &#39;code-generation&#39;" rel="tag" aria-labelledby="tag-code-generation-tooltip-container">code-generation</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/unix" class="post-tag" title="show questions tagged &#39;unix&#39;" aria-label="show questions tagged &#39;unix&#39;" rel="tag" aria-labelledby="tag-unix-tooltip-container">unix</a></li></ul>
</div>
</div>
</div>
<div class="mb0 ">
<div class="mt16 d-flex gs8 gsy fw-wrap jc-end ai-start pt4 mb16">
<div class="flex--item mr16 fl1 w96">
<div class="js-post-menu pt2" data-post-id="439871" data-post-type-id="1">
<div class="d-flex gs8 s-anchors s-anchors__muted fw-wrap">
<div class="flex--item">
<a href="/q/439871"
rel="nofollow"
itemprop="url"
class="js-share-link js-gps-track"
title="Short permalink to this question"
data-gps-track="post.click({ item: 2, priv: 0, post_type: 1 })"
data-controller="se-share-sheet"
data-se-share-sheet-title="Share a link to this question"
data-se-share-sheet-subtitle=""
data-se-share-sheet-post-type="question"
data-se-share-sheet-social="facebook twitter "
data-se-share-sheet-location="1"
data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f4.0%2f"
data-se-share-sheet-license-name="CC BY-SA 4.0"
data-s-popover-placement="bottom-start">Share</a>
</div>
<div class="flex--item">
<a href="/posts/439871/edit" class="js-suggest-edit-post js-gps-track" data-gps-track="post.click({ item: 6, priv: 0, post_type: 1 })" title="">Improve this question</a>
</div>
<div class="flex--item">
<button type="button"
id="btnFollowPost-439871" class="s-btn s-btn__link js-follow-post js-follow-question js-gps-track"
data-gps-track="post.click({ item: 14, priv: 0, post_type: 1 })"
data-controller="s-tooltip " data-s-tooltip-placement="bottom"
data-s-popover-placement="bottom" aria-controls=""
title="Follow this question to receive notifications">
Follow
</button>
</div>
</div>
<div class="js-menu-popup-container"></div>
</div>
</div>
<div class="post-signature owner flex--item">
<div class="user-info user-hover ">
<div class="d-flex ">
<div class="user-action-time fl-grow1">
asked <span title='2022-07-17 20:28:09Z' class='relativetime'>Jul 17, 2022 at 20:28</span>
</div>
</div>
<div class="user-gravatar32">
<a href="/users/198468/ahron"><div class="gravatar-wrapper-32"><img src="https://www.gravatar.com/avatar/839478ae95586357c0ef4d395eb29d8f?s=64&amp;d=identicon&amp;r=PG&amp;f=y&amp;so-version=2" alt="ahron&#39;s user avatar" width="32" height="32" class="bar-sm"></div></a>
</div>
<div class="user-details" itemprop="author" itemscope itemtype="http://schema.org/Person">
<a href="/users/198468/ahron">ahron</a><span class="d-none" itemprop="name">ahron</span>
<div class="-flair">
<span class="reputation-score" title="reputation score " dir="ltr">165</span><span title="6 bronze badges" aria-hidden="true"><span class="badge3"></span><span class="badgecount">6</span></span><span class="v-visible-sr">6 bronze badges</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<span class="d-none" itemprop="commentCount">2</span>
<div class="post-layout--right js-post-comments-component">
<div id="comments-439871" class="comments js-comments-container bt bc-black-200 mt12 " data-post-id="439871" data-min-length="15">
<ul class="comments-list js-comments-list"
data-remaining-comments-count="0"
data-canpost="false"
data-cansee="true"
data-comments-unavailable="false"
data-addlink-disabled="true">
<li id="comment-965547" class="comment js-comment " data-comment-id="965547" data-comment-owner-id="136413" data-comment-score="1">
<div class="js-comment-actions comment-actions">
<div class="comment-score js-comment-score js-comment-edit-hide">
<span title="number of &#x27;useful comment&#x27; votes received"
class="cool">1</span>
</div>
</div>
<div class="comment-text js-comment-text-and-form">
<div class="comment-body js-comment-edit-hide">
<span class="comment-copy">What actual, specific problem with your current system are you trying to solve?</span>
<div class="d-inline-flex ai-center">
&ndash;&nbsp;<a href="/users/136413/philip-kendall"
title="23,950 reputation"
class="comment-user">Philip Kendall</a>
</div>
<span class="comment-date" dir="ltr"><span title='2022-07-17 21:17:53Z, License: CC BY-SA 4.0' class='relativetime-clean'>Jul 17, 2022 at 21:17</span></span>
</div>
</div>
</li>
<li id="comment-965548" class="comment js-comment " data-comment-id="965548" data-comment-owner-id="177980" data-comment-score="1">
<div class="js-comment-actions comment-actions">
<div class="comment-score js-comment-score js-comment-edit-hide">
<span title="number of &#x27;useful comment&#x27; votes received"
class="cool">1</span>
</div>
</div>
<div class="comment-text js-comment-text-and-form">
<div class="comment-body js-comment-edit-hide">
<span class="comment-copy">think it through. How are you going to make a template thats both sed-able and works for multiple users? you are going to have a whole lot of serverside rendering to get a specific to user template which you then awk/sed. Just server side render the page, cache or render it to a static file if performance is an issue</span>
<div class="d-inline-flex ai-center">
&ndash;&nbsp;<a href="/users/177980/ewan"
title="74,676 reputation"
class="comment-user">Ewan</a>
</div>
<span class="comment-date" dir="ltr"><span title='2022-07-17 22:09:51Z, License: CC BY-SA 4.0' class='relativetime-clean'>Jul 17, 2022 at 22:09</span></span>
<span title="this comment was edited 1 time">
<svg aria-hidden="true" class="va-text-bottom o50 svg-icon iconPencilSm" width="14" height="14" viewBox="0 0 14 14"><path fill="#F1B600" d="m2 10.12 6.37-6.43 1.88 1.88L3.88 12H2v-1.88Z"/><path fill="#E87C87" d="m11.1 1.71 1.13 1.12c.2.2.2.51 0 .71L11.1 4.7 9.21 2.86l1.17-1.15c.2-.2.51-.2.71 0Z"/></svg>
</span>
</div>
</div>
</li>
</ul>
</div>
<div id="comments-link-439871" data-rep=50 data-anon=true>
<a class="js-add-link comments-link disabled-link" title="Use comments to ask for more information or suggest improvements. Avoid answering questions in comments." href="#" role="button">Add a comment</a>
<span class="js-link-separator dno">&nbsp;|&nbsp;</span>
<a class="js-show-link comments-link dno" title="Expand to show all comments on this post" href=# onclick="" role="button"></a>
</div>
</div>
</div>
</div>
<div id="answers">
<a name="tab-top"></a>
<div id="answers-header">
<div class="answers-subheader d-flex ai-center mb8">
<div class="flex--item fl1">
<h2 class="mb0" data-answercount="1">
1 Answer
<span style="display:none;" itemprop="answerCount">1</span>
</h2>
</div>
<div class="flex--item">
<div class="d-flex g4 gsx ai-center sm:fd-column sm:ai-start">
<div class="d-flex fd-column ai-end sm:ai-start">
<label class="flex--item fs-caption" for="answer-sort-dropdown-select-menu">
Sorted by:
</label>
<a
class="js-sort-preference-change s-link flex--item fs-fine d-none"
data-value="ScoreDesc"
href="/questions/439871/using-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template?answertab=scoredesc#tab-top"
>
Reset to default
</a>
</div>
<div class="flex--item s-select">
<select id="answer-sort-dropdown-select-menu">
<option
value=scoredesc
selected=selected
>
Highest score (default)
</option>
<option
value=modifieddesc
>
Date modified (newest first)
</option>
<option
value=createdasc
>
Date created (oldest first)
</option>
</select>
</div>
</div>
</div>
</div>
</div>
<a name="439873"></a>
<div id="answer-439873" class="answer js-answer accepted-answer js-accepted-answer" data-answerid="439873" data-parentid="439871" data-score="3" data-position-on-page="1" data-highest-scored="1" data-question-has-accepted-highest-score="1" itemprop="acceptedAnswer" itemscope itemtype="https://schema.org/Answer">
<div class="post-layout">
<div class="votecell post-layout--left">
<div class="js-voting-container d-flex jc-center fd-column ai-stretch gs4 fc-black-300" data-post-id="439873" data-referrer="None">
<button class="js-vote-up-btn flex--item s-btn ba bar-pill c-pointer as-center bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
title="This answer is useful"
aria-pressed="false"
aria-label="Up vote"
data-selected-classes="fc-theme-primary-100 bc-theme-primary-500 bg-theme-primary-500"
data-unselected-classes="bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050">
<svg aria-hidden="true" class="svg-icon iconArrowUp" width="18" height="18" viewBox="0 0 18 18"><path d="M1 12h16L9 4l-8 8Z"/></svg>
</button>
<div class="js-vote-count flex--item d-flex fd-column ai-center fc-theme-body-font fw-bold fs-subheading py4"
itemprop="upvoteCount"
data-value="3">
3
</div>
<button class="js-vote-down-btn flex--item mb8 s-btn ba bar-pill c-pointer as-center bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
title="This answer is not useful"
aria-pressed="false"
aria-label="Down vote"
data-selected-classes="fc-theme-primary-100 bc-theme-primary-500 bg-theme-primary-500"
data-unselected-classes="bc-black-225 fc-black-500 h:bg-theme-primary-200 h:fc-black-500 f:fc-black-050">
<svg aria-hidden="true" class="svg-icon iconArrowDown" width="18" height="18" viewBox="0 0 18 18"><path d="M1 6h16l-8 8-8-8Z"/></svg>
</button>
<button class="js-saves-btn s-btn s-btn__unset c-pointer py4"
type="button"
id="saves-btn-439873"
data-controller="s-tooltip"
data-s-tooltip-placement="right"
data-s-popover-placement=""
title="Save this answer."
aria-pressed="false"
data-post-id="439873"
data-post-type-id="2"
data-user-privilege-for-post-click="0"
aria-controls=""
data-s-popover-auto-show="false"
>
<svg aria-hidden="true" class="fc-theme-primary-400 js-saves-btn-selected d-none svg-icon iconBookmark" width="18" height="18" viewBox="0 0 18 18"><path d="M3 17V3c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v14l-6-4-6 4Z"/></svg>
<svg aria-hidden="true" class="js-saves-btn-unselected svg-icon iconBookmarkAlt" width="18" height="18" viewBox="0 0 18 18"><path d="m9 10.6 4 2.66V3H5v10.26l4-2.66ZM3 17V3c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v14l-6-4-6 4Z"/></svg>
</button>
<div class="js-accepted-answer-indicator flex--item fc-green-400 py6 mtn8" data-s-tooltip-placement="right" title="Loading when this answer was accepted&#x2026;" tabindex="0" role="note" aria-label="Accepted">
<div class="ta-center">
<svg aria-hidden="true" class="svg-icon iconCheckmarkLg" width="36" height="36" viewBox="0 0 36 36"><path d="m6 14 8 8L30 6v8L14 30l-8-8v-8Z"/></svg>
</div>
</div>
<a class="js-post-issue flex--item s-btn s-btn__unset c-pointer py6 mx-auto" href="/posts/439873/timeline" data-shortcut="T" data-ks-title="timeline" data-controller="s-tooltip" data-s-tooltip-placement="right" title="Show activity on this post." aria-label="Timeline"><svg aria-hidden="true" class="mln2 mr0 svg-icon iconHistory" width="19" height="18" viewBox="0 0 19 18"><path d="M3 9a8 8 0 1 1 3.73 6.77L8.2 14.3A6 6 0 1 0 5 9l3.01-.01-4 4-4-4h3L3 9Zm7-4h1.01L11 9.36l3.22 2.1-.6.93L10 10V5Z"/></svg></a>
</div>
</div>
<div class="answercell post-layout--right">
<div class="s-prose js-post-body" itemprop="text">
<p>Yes, you can do that. No, it is not a good idea.</p>
<p>This is roughly how some websites worked in the 90s. That these approaches are problematic has nothing to do with their age, and everything to do with the difficulty of creating a secure website this way.</p>
<p>In particular, real template engines support some degree of auto-escaping. Sed and awk do not. It is also challenging to express all but the most trivial business logic in those languages. For example, how will you query the database? Sed can't do that.</p>
<p>In contrast, generating static sites can be a very good idea – serving static files is very fast, it scales well, and there is a fantastic ecosystem of static site generators. So it's perfectly OK to run some script to generate static HTML files if that is what you want. Just use a real template engine for this, please.</p>
</div>
<div class="mt24">
<div class="d-flex fw-wrap ai-start jc-end gs8 gsy">
<time itemprop="dateCreated" datetime="2022-07-18T06:48:48"></time>
<div class="flex--item mr16" style="flex: 1 1 100px;">
<div class="js-post-menu pt2" data-post-id="439873" data-post-type-id="2">
<div class="d-flex gs8 s-anchors s-anchors__muted fw-wrap">
<div class="flex--item">
<a href="/a/439873"
rel="nofollow"
itemprop="url"
class="js-share-link js-gps-track"
title="Short permalink to this answer"
data-gps-track="post.click({ item: 2, priv: 0, post_type: 2 })"
data-controller="se-share-sheet"
data-se-share-sheet-title="Share a link to this answer"
data-se-share-sheet-subtitle=""
data-se-share-sheet-post-type="answer"
data-se-share-sheet-social="facebook twitter "
data-se-share-sheet-location="2"
data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f4.0%2f"
data-se-share-sheet-license-name="CC BY-SA 4.0"
data-s-popover-placement="bottom-start">Share</a>
</div>
<div class="flex--item">
<a href="/posts/439873/edit" class="js-suggest-edit-post js-gps-track" data-gps-track="post.click({ item: 6, priv: 0, post_type: 2 })" title="">Improve this answer</a>
</div>
<div class="flex--item">
<button type="button"
id="btnFollowPost-439873" class="s-btn s-btn__link js-follow-post js-follow-answer js-gps-track"
data-gps-track="post.click({ item: 14, priv: 0, post_type: 2 })"
data-controller="s-tooltip " data-s-tooltip-placement="bottom"
data-s-popover-placement="bottom" aria-controls=""
title="Follow this answer to receive notifications">
Follow
</button>
</div>
</div>
<div class="js-menu-popup-container"></div>
</div>
</div>
<div class="post-signature flex--item fl0">
<div class="user-info user-hover ">
<div class="d-flex ">
<div class="user-action-time fl-grow1">
answered <span title='2022-07-18 06:48:48Z' class='relativetime'>Jul 18, 2022 at 6:48</span>
</div>
</div>
<div class="user-gravatar32">
<a href="/users/60357/amon"><div class="gravatar-wrapper-32"><img src="https://i.stack.imgur.com/MH7pk.png?s=64&amp;g=1" alt="amon&#39;s user avatar" width="32" height="32" class="bar-sm"></div></a>
</div>
<div class="user-details" itemprop="author" itemscope itemtype="http://schema.org/Person">
<a href="/users/60357/amon">amon</a><span class="d-none" itemprop="name">amon</span>
<div class="-flair">
<span class="reputation-score" title="reputation score 134,002" dir="ltr">134k</span><span title="27 gold badges" aria-hidden="true"><span class="badge1"></span><span class="badgecount">27</span></span><span class="v-visible-sr">27 gold badges</span><span title="283 silver badges" aria-hidden="true"><span class="badge2"></span><span class="badgecount">283</span></span><span class="v-visible-sr">283 silver badges</span><span title="380 bronze badges" aria-hidden="true"><span class="badge3"></span><span class="badgecount">380</span></span><span class="v-visible-sr">380 bronze badges</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<span class="d-none" itemprop="commentCount">0</span>
<div class="post-layout--right js-post-comments-component">
<div id="comments-439873" class="comments js-comments-container bt bc-black-200 mt12 dno" data-post-id="439873" data-min-length="15">
<ul class="comments-list js-comments-list"
data-remaining-comments-count="0"
data-canpost="false"
data-cansee="true"
data-comments-unavailable="false"
data-addlink-disabled="true">
</ul>
</div>
<div id="comments-link-439873" data-rep=50 data-anon=true>
<a class="js-add-link comments-link disabled-link" title="Use comments to ask for more information or suggest improvements. Avoid comments like &#x201C;&#x2B;1&#x201D; or &#x201C;thanks&#x201D;." href="#" role="button">Add a comment</a>
<span class="js-link-separator dno">&nbsp;|&nbsp;</span>
<a class="js-show-link comments-link dno" title="Expand to show all comments on this post" href=# onclick="" role="button"></a>
</div>
</div>
</div>
</div>
<a name='new-answer'></a>
<form id="post-form" action="/questions/439871/answer/submit" method="post" class="js-add-answer-component post-form">
<input type="hidden" id="post-id" value="439871" />
<input type="hidden" id="qualityBanWarningShown" name="qualityBanWarningShown" value="false" />
<input type="hidden" name="referrer" value="" />
<h2 class="space" id="your-answer-header">
Your Answer
</h2>
<script>
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "131"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
useStacksEditor: false,
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by \u003ca href=\"https://imgur.com/\"\u003e\u003csvg class=\"svg-icon\" width=\"50\" height=\"18\" viewBox=\"0 0 50 18\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003ctitle\u003eImgur Logo\u003c/title\u003e\u003cpath d=\"M46.1709 9.17788C46.1709 8.26454 46.2665 7.94324 47.1084 7.58816C47.4091 7.46349 47.7169 7.36433 48.0099 7.26993C48.9099 6.97997 49.672 6.73443 49.672 5.93063C49.672 5.22043 48.9832 4.61182 48.1414 4.61182C47.4335 4.61182 46.7256 4.91628 46.0943 5.50789C45.7307 4.9328 45.2525 4.66231 44.6595 4.66231C43.6264 4.66231 43.1481 5.28821 43.1481 6.59048V11.9512C43.1481 13.2535 43.6264 13.8962 44.6595 13.8962C45.6924 13.8962 46.1709 13.2535 46.1709 11.9512V9.17788Z\"/\u003e\u003cpath d=\"M32.492 10.1419C32.492 12.6954 34.1182 14.0484 37.0451 14.0484C39.9723 14.0484 41.5985 12.6954 41.5985 10.1419V6.59049C41.5985 5.28821 41.1394 4.66232 40.1061 4.66232C39.0732 4.66232 38.5948 5.28821 38.5948 6.59049V9.60062C38.5948 10.8521 38.2696 11.5455 37.0451 11.5455C35.8209 11.5455 35.4954 10.8521 35.4954 9.60062V6.59049C35.4954 5.28821 35.0173 4.66232 34.0034 4.66232C32.9703 4.66232 32.492 5.28821 32.492 6.59049V10.1419Z\" /\u003e\u003cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M25.6622 17.6335C27.8049 17.6335 29.3739 16.9402 30.2537 15.6379C30.8468 14.7755 30.9615 13.5579 30.9615 11.9512V6.59049C30.9615 5.28821 30.4833 4.66231 29.4502 4.66231C28.9913 4.66231 28.4555 4.94978 28.1109 5.50789C27.499 4.86533 26.7335 4.56087 25.7005 4.56087C23.1369 4.56087 21.0134 6.57349 21.0134 9.27932C21.0134 11.9852 23.003 13.913 25.3754 13.913C26.5612 13.913 27.4607 13.4902 28.1109 12.6616C28.1109 12.7229 28.1161 12.7799 28.121 12.8346C28.1256 12.8854 28.1301 12.9342 28.1301 12.983C28.1301 14.4373 27.2502 15.2321 25.777 15.2321C24.8349 15.2321 24.1352 14.9821 23.5661 14.7787C23.176 14.6393 22.8472 14.5218 22.5437 14.5218C21.7977 14.5218 21.2429 15.0123 21.2429 15.6887C21.2429 16.7375 22.9072 17.6335 25.6622 17.6335ZM24.1317 9.27932C24.1317 7.94324 24.9928 7.09766 26.1024 7.09766C27.2119 7.09766 28.0918 7.94324 28.0918 9.27932C28.0918 10.6321 27.2311 11.5116 26.1024 11.5116C24.9737 11.5116 24.1317 10.6491 24.1317 9.27932Z\"/\u003e\u003cpath d=\"M16.8045 11.9512C16.8045 13.2535 17.2637 13.8962 18.2965 13.8962C19.3298 13.8962 19.8079 13.2535 19.8079 11.9512V8.12928C19.8079 5.82936 18.4879 4.62866 16.4027 4.62866C15.1594 4.62866 14.279 4.98375 13.3609 5.88013C12.653 5.05154 11.6581 4.62866 10.3573 4.62866C9.34336 4.62866 8.57809 4.89931 7.9466 5.5079C7.58314 4.9328 7.10506 4.66232 6.51203 4.66232C5.47873 4.66232 5.00066 5.28821 5.00066 6.59049V11.9512C5.00066 13.2535 5.47873 13.8962 6.51203 13.8962C7.54479 13.8962 8.0232 13.2535 8.0232 11.9512V8.90741C8.0232 7.58817 8.44431 6.91179 9.53458 6.91179C10.5104 6.91179 10.893 7.58817 10.893 8.94108V11.9512C10.893 13.2535 11.3711 13.8962 12.4044 13.8962C13.4375 13.8962 13.9157 13.2535 13.9157 11.9512V8.90741C13.9157 7.58817 14.3365 6.91179 15.4269 6.91179C16.4027 6.91179 16.8045 7.58817 16.8045 8.94108V11.9512Z\"/\u003e\u003cpath d=\"M3.31675 6.59049C3.31675 5.28821 2.83866 4.66232 1.82471 4.66232C0.791758 4.66232 0.313354 5.28821 0.313354 6.59049V11.9512C0.313354 13.2535 0.791758 13.8962 1.82471 13.8962C2.85798 13.8962 3.31675 13.2535 3.31675 11.9512V6.59049Z\" /\u003e\u003cpath d=\"M1.87209 0.400291C0.843612 0.400291 0 1.1159 0 1.98861C0 2.87869 0.822846 3.57676 1.87209 3.57676C2.90056 3.57676 3.7234 2.87869 3.7234 1.98861C3.7234 1.1159 2.90056 0.400291 1.87209 0.400291Z\" fill=\"#1BB76E\"/\u003e\u003c/svg\u003e\u003c/a\u003e",
contentPolicyHtml: "User contributions licensed under \u003ca href=\"https://stackoverflow.com/help/licensing\"\u003eCC BY-SA\u003c/a\u003e \u003ca href=\"https://stackoverflow.com/legal/acceptable-use-policy\"\u003e(content policy)\u003c/a\u003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer",
enableTables: true,
isStacksEditorPreviewEnabled: false
,immediatelyShowMarkdownHelp:true,enableTables:true
});
}
});
</script>
<div id="post-editor" class="post-editor js-post-editor">
<div class="ps-relative">
<div class="wmd-container mb8">
<div id="wmd-button-bar" class="wmd-button-bar btr-sm"></div>
<div class="js-stacks-validation">
<div class="ps-relative">
<textarea id="wmd-input"
name="post-text"
class="wmd-input s-input bar0 js-post-body-field"
data-editor-type="wmd"
data-post-type-id="2"
cols="92" rows="15"
aria-labelledby="your-answer-header"
tabindex="101"
data-min-length=""></textarea>
</div>
<div class="s-input-message mt4 d-none js-stacks-validation-message"></div>
</div>
</div>
</div>
<aside class="d-flex ai-start jc-space-between js-answer-help s-notice s-notice__warning pb0 pr4 pt4 mb8 d-none" role="status" aria-hidden="true">
<div class="flex--item pt8">
<p>Thanks for contributing an answer to Software Engineering Stack Exchange!</p><ul><li>Please be sure to <em>answer the question</em>. Provide details and share your research!</li></ul><p>But <em>avoid</em> …</p><ul><li>Asking for help, clarification, or responding to other answers.</li><li>Making statements based on opinion; back them up with references or personal experience.</li></ul><p>To learn more, see our <a href="/help/how-to-answer">tips on writing great answers</a>.</p>
</div>
<button class="flex--item js-answer-help-close-btn s-btn s-btn__muted fc-black-600">
<svg aria-hidden="true" class="svg-icon iconClear" width="18" height="18" viewBox="0 0 18 18"><path d="M15 4.41 13.59 3 9 7.59 4.41 3 3 4.41 7.59 9 3 13.59 4.41 15 9 10.41 13.59 15 15 13.59 10.41 9 15 4.41Z"/></svg>
</button>
</aside>
<div>
<div id="draft-saved" class="fc-success h24" style="display:none;">Draft saved</div>
<div id="draft-discarded" class="fc-error h24" style="display:none;">Draft discarded</div>
</div>
<div id="wmd-preview" class="s-prose mb16 wmd-preview js-wmd-preview"></div>
<div></div>
<div class="edit-block">
<input id="fkey" name="fkey" type="hidden" value="27b7033a38c9489b51a2db328ed82e00b602b223db5e55f48328eb2bf4b6fccf">
<input id="author" name="author" type="text">
</div>
</div>
<div class="ps-relative">
<div class="form-item dno new-post-login p0 my16">
<div class="d-flex gs16 md:fd-column new-login-form">
<div class="d-flex fd-column w50 md:w-auto gsy gs8 jc-space-between new-login-left">
<h3 class="flex--item fs-title">Sign up or <a id="login-link" href="/users/login?ssrc=question_page&returnurl=https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template%23new-answer">log in</a></h3>
<script>
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
</script>
<div class="flex--item s-btn s-btn__muted s-btn__outlined s-btn__icon google-login" data-ga="[&quot;sign up&quot;,&quot;Sign Up Started - Google&quot;,&quot;New Post&quot;,null,null]">
<svg aria-hidden="true" class="native svg-icon iconGoogle" width="18" height="18" viewBox="0 0 18 18"><path fill="#4285F4" d="M16.51 8H8.98v3h4.3c-.18 1-.74 1.48-1.6 2.04v2.01h2.6a7.8 7.8 0 0 0 2.38-5.88c0-.57-.05-.66-.15-1.18Z"/><path fill="#34A853" d="M8.98 17c2.16 0 3.97-.72 5.3-1.94l-2.6-2a4.8 4.8 0 0 1-7.18-2.54H1.83v2.07A8 8 0 0 0 8.98 17Z"/><path fill="#FBBC05" d="M4.5 10.52a4.8 4.8 0 0 1 0-3.04V5.41H1.83a8 8 0 0 0 0 7.18l2.67-2.07Z"/><path fill="#EA4335" d="M8.98 4.18c1.17 0 2.23.4 3.06 1.2l2.3-2.3A8 8 0 0 0 1.83 5.4L4.5 7.49a4.77 4.77 0 0 1 4.48-3.3Z"/></svg> Sign up using Google
</div>
<div class="flex--item s-btn s-btn__muted s-btn__icon facebook-login" data-ga="[&quot;sign up&quot;,&quot;Sign Up Started - Facebook&quot;,&quot;New Post&quot;,null,null]">
<svg aria-hidden="true" class="svg-icon iconFacebook" width="18" height="18" viewBox="0 0 18 18"><path fill="#4167B2" d="M3 1a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H3Zm6.55 16v-6.2H7.46V8.4h2.09V6.61c0-2.07 1.26-3.2 3.1-3.2.88 0 1.64.07 1.87.1v2.16h-1.29c-1 0-1.19.48-1.19 1.18V8.4h2.39l-.31 2.42h-2.08V17h-2.5Z"/></svg> Sign up using Facebook
</div>
<div class="flex--item s-btn s-btn__muted s-btn__outlined s-btn__icon stackexchange-login" data-ga="[&quot;sign up&quot;,&quot;Sign Up Navigation&quot;,&quot;New Post&quot;,null,null]">
<svg aria-hidden="true" class="native svg-icon iconLogoGlyphXSm" width="18" height="18" viewBox="0 0 18 18"><path d="M14 16v-5h2v7H2v-7h2v5h10Z" fill="#BCBBBB"/><path d="m12.09.72-1.21.9 4.5 6.07 1.22-.9L12.09.71ZM5 15h8v-2H5v2Zm9.15-5.87L8.35 4.3l.96-1.16 5.8 4.83-.96 1.16Zm-7.7-1.47 6.85 3.19.63-1.37-6.85-3.2-.63 1.38Zm6.53 5L5.4 11.39l.38-1.67 7.42 1.48-.22 1.46Z" fill="#F48024"/></svg> Sign up using Email and Password
</div>
</div>
<input type="hidden" name="use-facebook" class="use-facebook" value="false" />
<input type="hidden" name="use-google" class="use-google" value="false" />
<button type="button" class="d-none js-submit-openid">Submit</button>
<div class="d-flex gsy gs8 fd-column w50 md:w-auto new-login-right form-item p0">
<h3 class="flex--item fs-title">Post as a guest</h3>
<div class="flex--item">
<div class="d-flex gs4 gsy fd-column">
<label class="s-label" for="display-name">Name</label>
<div class="d-flex ps-relative">
<input class="s-input" id="display-name" name="display-name" maxlength="30" type="text" value="" tabindex="105" placeholder="" />
</div>
</div>
</div>
<div class="flex--item">
<div class="d-flex gs4 gsy fd-column">
<div class="flex--item">
<div class="d-flex gs2 gsy fd-column">
<label class="flex--item s-label" for="m-address">Email</label>
<p class="flex--item s-description">Required, but never shown</p>
</div>
</div>
<div class="d-flex ps-relative">
<input class="s-input js-post-email-field" id="m-address" name="m-address" type="text" value="" size="40" tabindex="106" placeholder="" />
</div>
</div>
</div>
</div>
</div>
</div>
<script>
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f439871%2fusing-sed-awk-to-bulk-generate-static-html-pages-off-of-a-template%23new-answer', 'question_page');
}
);
</script>
<noscript>
<h3 class="flex--item fs-title">Post as a guest</h3>
<div class="flex--item">
<div class="d-flex gs4 gsy fd-column">
<label class="s-label" for="display-name">Name</label>
<div class="d-flex ps-relative">
<input class="s-input" id="display-name" name="display-name" maxlength="30" type="text" value="" tabindex="105" placeholder="" />
</div>
</div>
</div>
<div class="flex--item">
<div class="d-flex gs4 gsy fd-column">
<div class="flex--item">
<div class="d-flex gs2 gsy fd-column">
<label class="flex--item s-label" for="m-address">Email</label>
<p class="flex--item s-description">Required, but never shown</p>
</div>
</div>
<div class="d-flex ps-relative">
<input class="s-input js-post-email-field" id="m-address" name="m-address" type="text" value="" size="40" tabindex="106" placeholder="" />
</div>
</div>
</div>
</noscript>
</div>
<div class="form-submit clear-both d-flex gsx gs4">
<button id="submit-button" class="flex--item s-btn s-btn__filled s-btn__icon" type="submit" tabindex="120" autocomplete="off">
Post Your Answer
</button>
<button class="flex--item s-btn s-btn__danger discard-answer dno">
Discard
</button>
<p class="privacy-policy-agreement">
By clicking “Post Your Answer”, you agree to our <a href='https://stackoverflow.com/legal/terms-of-service/public' name='tos' target='_blank' class='-link'>terms of service</a> and acknowledge you have read our <a href='https://stackoverflow.com/legal/privacy-policy' name='privacy' target='_blank' class='-link'>privacy policy</a>.<input type="hidden" name="legalLinksShown" value="1" />
</p>
</div>
<div class="js-general-error general-error clear-both d-none" aria-live="polite"></div>
</form>
<h2 class="bottom-notice" data-loc="1">
<div>
Not the answer you&#x27;re looking for? Browse other questions tagged <ul class='ml0 list-ls-none js-post-tag-list-wrapper d-inline'><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/html" class="post-tag" title="show questions tagged &#39;html&#39;" aria-label="show questions tagged &#39;html&#39;" rel="tag" aria-labelledby="tag-html-tooltip-container">html</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/front-end" class="post-tag" title="show questions tagged &#39;front-end&#39;" aria-label="show questions tagged &#39;front-end&#39;" rel="tag" aria-labelledby="tag-front-end-tooltip-container">front-end</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/scripting" class="post-tag" title="show questions tagged &#39;scripting&#39;" aria-label="show questions tagged &#39;scripting&#39;" rel="tag" aria-labelledby="tag-scripting-tooltip-container">scripting</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/code-generation" class="post-tag" title="show questions tagged &#39;code-generation&#39;" aria-label="show questions tagged &#39;code-generation&#39;" rel="tag" aria-labelledby="tag-code-generation-tooltip-container">code-generation</a></li><li class='d-inline mr4 js-post-tag-list-item'><a href="/questions/tagged/unix" class="post-tag" title="show questions tagged &#39;unix&#39;" aria-label="show questions tagged &#39;unix&#39;" rel="tag" aria-labelledby="tag-unix-tooltip-container">unix</a></li></ul> or <a href="/questions/ask">ask your own question</a>. </div>
</h2>
</div>
</div>
<div id="sidebar" class="show-votes" role="complementary" aria-label="sidebar">
<div class="s-sidebarwidget s-sidebarwidget__yellow s-anchors s-anchors__grayscale mb16" data-tracker="cb=1">
<ul class="d-block p0 m0">
<li class="s-sidebarwidget--header s-sidebarwidget__small-bold-text d-flex fc-black-500 d:fc-black-600 bb bbw1">
The Overflow Blog
</li>
<li class="s-sidebarwidget--item d-flex px16">
<div class="flex--item1 fl-shrink0">
<svg aria-hidden="true" class="va-text-top svg-icon iconPencilSm" width="14" height="14" viewBox="0 0 14 14"><path fill="#F1B600" d="m2 10.12 6.37-6.43 1.88 1.88L3.88 12H2v-1.88Z"/><path fill="#E87C87" d="m11.1 1.71 1.13 1.12c.2.2.2.51 0 .71L11.1 4.7 9.21 2.86l1.17-1.15c.2-.2.51-.2.71 0Z"/></svg> </div>
<div class="flex--item wmn0 ow-break-word">
<a href="https://stackoverflow.blog/2024/03/05/chunking-express-an-expert-breaks-down-how-to-build-your-rag-system/" class="js-gps-track" data-ga="[&quot;community bulletin board&quot;,&quot;The Overflow Blog&quot;,&quot;https://stackoverflow.blog/2024/03/05/chunking-express-an-expert-breaks-down-how-to-build-your-rag-system/&quot;,null,null]" data-gps-track="communitybulletin.click({ priority: 1, position: 0 })">Chunking express: An expert breaks down how to build your RAG system</a>
</div>
</li>
<li class="s-sidebarwidget--item d-flex px16">
<div class="flex--item1 fl-shrink0">
<svg aria-hidden="true" class="va-text-top svg-icon iconPencilSm" width="14" height="14" viewBox="0 0 14 14"><path fill="#F1B600" d="m2 10.12 6.37-6.43 1.88 1.88L3.88 12H2v-1.88Z"/><path fill="#E87C87" d="m11.1 1.71 1.13 1.12c.2.2.2.51 0 .71L11.1 4.7 9.21 2.86l1.17-1.15c.2-.2.51-.2.71 0Z"/></svg> </div>
<div class="flex--item wmn0 ow-break-word">
<a href="https://stackoverflow.blog/2024/03/06/building-genai-features-in-practice-with-intuit-mailchimp/" class="js-gps-track" data-ga="[&quot;community bulletin board&quot;,&quot;The Overflow Blog&quot;,&quot;https://stackoverflow.blog/2024/03/06/building-genai-features-in-practice-with-intuit-mailchimp/&quot;,null,null]" data-gps-track="communitybulletin.click({ priority: 1, position: 1 })">Building GenAI features in practice with Intuit Mailchimp</a>
</div>
</li>
<li class="s-sidebarwidget--header s-sidebarwidget__small-bold-text d-flex fc-black-500 d:fc-black-600 bb bbw1">
Featured on Meta
</li>
<li class="s-sidebarwidget--item d-flex px16">
<div class="flex--item1 fl-shrink0">
<div class="favicon favicon-stackexchangemeta" title="Meta Stack Exchange"></div> </div>
<div class="flex--item wmn0 ow-break-word">
<a href="https://meta.stackexchange.com/questions/398127/our-partnership-with-google-and-commitment-to-socially-responsible-ai" class="js-gps-track" data-ga="[&quot;community bulletin board&quot;,&quot;Featured on Meta&quot;,&quot;https://meta.stackexchange.com/questions/398127/our-partnership-with-google-and-commitment-to-socially-responsible-ai&quot;,null,null]" data-gps-track="communitybulletin.click({ priority: 3, position: 2 })">Our partnership with Google and commitment to socially responsible AI</a>
</div>
</li>
<li class="s-sidebarwidget--item d-flex px16">
<div class="flex--item1 fl-shrink0">
<div class="favicon favicon-stackexchangemeta" title="Meta Stack Exchange"></div> </div>
<div class="flex--item wmn0 ow-break-word">
<a href="https://meta.stackexchange.com/questions/398279/shifting-the-data-dump-schedule-a-proposal" class="js-gps-track" data-ga="[&quot;community bulletin board&quot;,&quot;Featured on Meta&quot;,&quot;https://meta.stackexchange.com/questions/398279/shifting-the-data-dump-schedule-a-proposal&quot;,null,null]" data-gps-track="communitybulletin.click({ priority: 3, position: 3 })">Shifting the data dump schedule: A proposal</a>
</div>
</li>
</ul>
</div>
<div class="js-zone-container zone-container-sidebar">
<div id="dfp-tsb" class="everyonelovesstackoverflow everyoneloves__top-sidebar"></div>
<div class="js-report-ad-button-container " style="width: 300px"></div>
</div>
<div class="js-zone-container zone-container-sidebar">
<div id="dfp-msb" class="everyonelovesstackoverflow everyoneloves__mid-sidebar"></div>
<div class="js-report-ad-button-container " style="width: 300px"></div>
</div>
<div id="hireme"></div>
<div class="module sidebar-related">
<h4 id="h-related">Related</h4>
<div class="related js-gps-related-questions" data-tracker="rq=1">
<div class="spacer" data-question-id="158685">
<a href="/q/158685" title="Question score (upvotes - downvotes)" >
<div class="answer-votes default">3</div>
</a>
<a href="/questions/158685/is-it-possible-to-use-rubygnome2s-qtrubys-html-renderers-to-make-ui-for-a-ruby" class="question-hyperlink">Is it possible to use RubyGnome2&#39;s/QtRuby&#39;s HTML renderers to make UI for a Ruby script?</a>
</div>
<div class="spacer" data-question-id="167304">
<a href="/q/167304" title="Question score (upvotes - downvotes)" >
<div class="answer-votes answered-accepted default">17</div>
</a>
<a href="/questions/167304/asp-net-webforms-developers-and-web-designers-how-to-interact" class="question-hyperlink">ASP.NET Webforms developers and web designers: how to interact?</a>
</div>
<div class="spacer" data-question-id="250432">
<a href="/q/250432" title="Question score (upvotes - downvotes)" >
<div class="answer-votes answered-accepted default">0</div>
</a>
<a href="/questions/250432/javascript-function-should-call-python-logic-in-django-web-development-without-a" class="question-hyperlink">Javascript function should call python logic in django web development without additional triiger</a>
</div>
<div class="spacer" data-question-id="277807">
<a href="/q/277807" title="Question score (upvotes - downvotes)" >
<div class="answer-votes answered-accepted default">2</div>
</a>
<a href="/questions/277807/best-use-of-the-react-frontend-framework" class="question-hyperlink">Best use of the React frontend framework</a>
</div>
<div class="spacer" data-question-id="350335">
<a href="/q/350335" title="Question score (upvotes - downvotes)" >
<div class="answer-votes default">4</div>
</a>
<a href="/questions/350335/how-would-you-optimize-the-rendering-of-10-000-elements-on-a-webpage" class="question-hyperlink">How would you optimize the rendering of 10,000 elements on a webpage?</a>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$(".js-gps-related-questions .spacer").click(function () {
fireRelatedEvent($(this).index() + 1, $(this).data('question-id'));
});
function fireRelatedEvent(position, questionId) {
StackExchange.using("gps", function() {
StackExchange.gps.track('related_questions.click',
{
position: position,
originQuestionId: 439871,
relatedQuestionId: +questionId,
location: 'sidebar',
source: 'Baseline'
});
});
}
});
</script>
<div id="hot-network-questions" class="module tex2jax_ignore">
<h4>
<a href="https://stackexchange.com/questions?tab=hot"
class="js-gps-track s-link s-link__inherit"
data-gps-track="posts_hot_network.click({ item_type:1, location:11 })">
Hot Network Questions
</a>
</h4>
<ul>
<li >
<div class="favicon favicon-physics" title="Physics Stack Exchange"></div><a href="https://physics.stackexchange.com/questions/805391/a-ball-was-thrown-horizontally-but-it-has-zero-horizontal-initial-velocity" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:151 }); posts_hot_network.click({ item_type:2, location:11 })">
A ball was thrown horizontally but it has zero horizontal initial velocity?
</a>
</li>
<li >
<div class="favicon favicon-softwarerecs" title="Software Recommendations Stack Exchange"></div><a href="https://softwarerecs.stackexchange.com/questions/90020/is-there-a-language-to-write-programmes-by-pictures" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:536 }); posts_hot_network.click({ item_type:2, location:11 })">
Is there a language to write programmes by pictures?
</a>
</li>
<li >
<div class="favicon favicon-superuser" title="Super User"></div><a href="https://superuser.com/questions/1834118/how-does-hot-cloning-a-running-windows-drive-actually-work" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:3 }); posts_hot_network.click({ item_type:2, location:11 })">
How does hot cloning a running Windows drive actually work?
</a>
</li>
<li >
<div class="favicon favicon-worldbuilding" title="Worldbuilding Stack Exchange"></div><a href="https://worldbuilding.stackexchange.com/questions/255899/how-would-a-sentient-species-without-technology-derive-general-relativity" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:579 }); posts_hot_network.click({ item_type:2, location:11 })">
How would a sentient species without technology derive General Relativity?
</a>
</li>
<li >
<div class="favicon favicon-tex" title="TeX - LaTeX Stack Exchange"></div><a href="https://tex.stackexchange.com/questions/712438/adjust-the-vertical-distance-between-sectionrule-package-sectsty-and-the-foll" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:85 }); posts_hot_network.click({ item_type:2, location:11 })">
Adjust the vertical distance between \sectionrule (package sectsty) and the following text
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-politics" title="Politics Stack Exchange"></div><a href="https://politics.stackexchange.com/questions/86173/what-makes-the-golan-heights-a-geopolitical-region-and-strategically-important-f" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:475 }); posts_hot_network.click({ item_type:2, location:11 })">
What makes the Golan Heights a geopolitical region and strategically important for Israel?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-scifi" title="Science Fiction &amp; Fantasy Stack Exchange"></div><a href="https://scifi.stackexchange.com/questions/285985/short-story-in-which-a-spacecraft-is-destroyed-when-all-its-internal-friction-is" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:186 }); posts_hot_network.click({ item_type:2, location:11 })">
Short story in which a spacecraft is destroyed when all its internal friction is removed, so that it falls apart
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-math" title="Mathematics Stack Exchange"></div><a href="https://math.stackexchange.com/questions/4876605/finding-the-power-for-which-an-expression-is-a-factor-of-a-function" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:69 }); posts_hot_network.click({ item_type:2, location:11 })">
Finding the power for which an expression is a factor of a function,
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-electronics" title="Electrical Engineering Stack Exchange"></div><a href="https://electronics.stackexchange.com/questions/705224/can-air-itself-be-theoretically-considered-as-a-very-poor-wireless-esd-groundi" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:135 }); posts_hot_network.click({ item_type:2, location:11 })">
Can air itself be theoretically considered as a (very poor) wireless ESD grounding strap?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-gamedev" title="Game Development Stack Exchange"></div><a href="https://gamedev.stackexchange.com/questions/210230/how-hard-to-brake-to-perfectly-smoothly-reach-the-destination" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:53 }); posts_hot_network.click({ item_type:2, location:11 })">
How hard to brake to perfectly smoothly reach the destination?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-travel" title="Travel Stack Exchange"></div><a href="https://travel.stackexchange.com/questions/187759/travelling-europe-with-uk-partner-as-dutch-citizen" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:273 }); posts_hot_network.click({ item_type:2, location:11 })">
Travelling Europe with UK partner as Dutch citizen
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-travel" title="Travel Stack Exchange"></div><a href="https://travel.stackexchange.com/questions/187710/travel-ban-in-the-united-kingdom-for-criminal-history" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:273 }); posts_hot_network.click({ item_type:2, location:11 })">
Travel Ban in the United Kingdom for Criminal History
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-blender" title="Blender Stack Exchange"></div><a href="https://blender.stackexchange.com/questions/314278/how-can-i-make-this-grunge-texture" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:502 }); posts_hot_network.click({ item_type:2, location:11 })">
How can I make this grunge texture
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-codegolf" title="Code Golf Stack Exchange"></div><a href="https://codegolf.stackexchange.com/questions/271522/can-i-follow-this-recipe" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:200 }); posts_hot_network.click({ item_type:2, location:11 })">
Can I follow this recipe?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-philosophy" title="Philosophy Stack Exchange"></div><a href="https://philosophy.stackexchange.com/questions/110258/example-of-not-falsifiable" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:265 }); posts_hot_network.click({ item_type:2, location:11 })">
Example of NOT-falsifiable
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-diy" title="Home Improvement Stack Exchange"></div><a href="https://diy.stackexchange.com/questions/295745/why-is-my-clear-wood-finish-drying-orange" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:73 }); posts_hot_network.click({ item_type:2, location:11 })">
Why is my clear wood finish drying orange?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-gis" title="Geographic Information Systems Stack Exchange"></div><a href="https://gis.stackexchange.com/questions/478187/making-trivial-geojson-file-with-feature-collection-of-points" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:79 }); posts_hot_network.click({ item_type:2, location:11 })">
Making trivial GeoJSON file with Feature collection of points
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-tex" title="TeX - LaTeX Stack Exchange"></div><a href="https://tex.stackexchange.com/questions/712406/how-can-i-write-a-complex-exponential-in-latex-so-that-it-looks-presentable" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:85 }); posts_hot_network.click({ item_type:2, location:11 })">
How can I write a complex exponential in LaTeX so that it looks presentable?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-unix" title="Unix &amp; Linux Stack Exchange"></div><a href="https://unix.stackexchange.com/questions/771785/how-do-executables-use-posix-to-keep-compatibility-between-different-unix-system" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:106 }); posts_hot_network.click({ item_type:2, location:11 })">
How do executables use POSIX to keep compatibility between different UNIX systems?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-worldbuilding" title="Worldbuilding Stack Exchange"></div><a href="https://worldbuilding.stackexchange.com/questions/255922/how-can-i-penalize-using-accelerated-time-in-full-dive-virtual-reality" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:579 }); posts_hot_network.click({ item_type:2, location:11 })">
How can I penalize using accelerated time in Full Dive Virtual Reality?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-diy" title="Home Improvement Stack Exchange"></div><a href="https://diy.stackexchange.com/questions/295804/how-can-i-seal-improperly-installed-vinyl-tile-joints" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:73 }); posts_hot_network.click({ item_type:2, location:11 })">
How can I seal improperly installed vinyl tile joints?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-philosophy" title="Philosophy Stack Exchange"></div><a href="https://philosophy.stackexchange.com/questions/110276/is-non-physicalism-reasonable" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:265 }); posts_hot_network.click({ item_type:2, location:11 })">
Is non-physicalism reasonable?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-rpg" title="Role-playing Games Stack Exchange"></div><a href="https://rpg.stackexchange.com/questions/210738/is-the-spellcaster-aware-if-their-clone-is-destroyed" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:122 }); posts_hot_network.click({ item_type:2, location:11 })">
Is the spellcaster aware if their clone is destroyed?
</a>
</li>
<li class="dno js-hidden">
<div class="favicon favicon-hsm" title="History of Science and Mathematics Stack Exchange"></div><a href="https://hsm.stackexchange.com/questions/17319/emmy-noethers-announcement-in-1932-icm" class="js-gps-track question-hyperlink mb0" data-gps-track="site.switch({ item_type:11, target_site:587 }); posts_hot_network.click({ item_type:2, location:11 })">
Emmy Noether&#x27;s announcement in 1932 ICM
</a>
</li>
</ul>
<a href="#"
class="show-more js-show-more js-gps-track"
data-gps-track="posts_hot_network.click({ item_type:3, location:11 })">
more hot questions
</a>
</div>
<div id="feed-link" class="js-feed-link">
<a href="/feeds/question/439871" title="Feed of this question and its answers">
<svg aria-hidden="true" class="fc-orange-400 svg-icon iconRss" width="18" height="18" viewBox="0 0 18 18"><path d="M3 1a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H3Zm0 1.5c6.9 0 12.5 5.6 12.5 12.5H13C13 9.55 8.45 5 3 5V2.5Zm0 5c4.08 0 7.5 3.41 7.5 7.5H8c0-2.72-2.28-5-5-5V7.5Zm0 5c1.36 0 2.5 1.14 2.5 2.5H3v-2.5Z"/></svg>
Question feed
</a>
</div>
<aside class="s-modal js-feed-link-modal" tabindex="-1" role="dialog" aria-labelledby="feed-modal-title" aria-describedby="feed-modal-description" aria-hidden="true">
<div class="s-modal--dialog js-modal-dialog wmx4" role="document" data-controller="se-draggable">
<h1 class="s-modal--header fw-bold js-first-tabbable" id="feed-modal-title" data-se-draggable-target="handle" tabindex="0">
Subscribe to RSS
</h1>
<div class="d-flex gs4 gsy fd-column">
<div class="flex--item">
<label class="d-block s-label c-default" for="feed-url">
Question feed
<p class="s-description mt2" id="feed-modal-description">To subscribe to this RSS feed, copy and paste this URL into your RSS reader.</p>
</label>
</div>
<div class="d-flex ps-relative">
<input class="s-input" type="text" name="feed-url" id="feed-url" readonly="readonly" value="https://softwareengineering.stackexchange.com/feeds/question/439871" />
<svg aria-hidden="true" class="s-input-icon fc-orange-400 svg-icon iconRss" width="18" height="18" viewBox="0 0 18 18"><path d="M3 1a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H3Zm0 1.5c6.9 0 12.5 5.6 12.5 12.5H13C13 9.55 8.45 5 3 5V2.5Zm0 5c4.08 0 7.5 3.41 7.5 7.5H8c0-2.72-2.28-5-5-5V7.5Zm0 5c1.36 0 2.5 1.14 2.5 2.5H3v-2.5Z"/></svg>
</div>
</div>
<a class="s-modal--close s-btn s-btn__muted js-modal-close js-last-tabbable" href="#" aria-label="Close">
<svg aria-hidden="true" class="svg-icon iconClearSm" width="14" height="14" viewBox="0 0 14 14"><path d="M12 3.41 10.59 2 7 5.59 3.41 2 2 3.41 5.59 7 2 10.59 3.41 12 7 8.41 10.59 12 12 10.59 8.41 7 12 3.41Z"/></svg>
</a>
</div>
</aside>
</div>
</div>
<script>StackExchange.ready(function(){$.get('/posts/439871/ivc/9f64?prg=1783d7fd-f958-437c-abf8-0cb5d6cb1439');});</script>
<noscript><div><img src="/posts/439871/ivc/9f64?prg=1783d7fd-f958-437c-abf8-0cb5d6cb1439" class="dno" alt="" width="0" height="0"></div></noscript><div style="display:none" id="js-codeblock-lang">lang-html</div></div>
</div>
</div>
<script type="text/javascript">
var cam = cam || { opt: {} };
var clcGamLoaderOptions = cam || { opt: {} };
var opt = clcGamLoaderOptions.opt;
opt.omni = 'BwoLCOilkpzivd88EAUYv-waIBIoAjovfGh0bWx8ZnJvbnQtZW5kfHNjcmlwdGluZ3xjb2RlLWdlbmVyYXRpb258dW5peHxIABENxVUItjynEJI';
opt.refresh = !1;
opt.refreshInterval = 0;
opt.sf = !1;
opt.hb = !1;
opt.ll = !0;
opt.tlb_position = 0;
opt.personalization_consent = !1;
opt.targeting_consent = !1;
opt.performance_consent = !1;
opt.targeting = {Registered:['false'],'ron-tag':['html','front-end','scripting','code-generation','unix'],NumberOfAnswers:['1']};
opt.adReportEnabled = !1;
opt.adReportUrl = '/ads/report-ad';
opt.adReportText = 'Report this ad';
opt.adReportFileTypeErrorMessage = 'Please select a PNG or JPG file.';
opt.adReportFileSizeErrorMessage = 'The file must be under 2 MiB.';
opt.adReportErrorText = 'Error uploading ad report.';
opt.adReportThanksText = 'Thanks for your feedback. We’ll review this against our code of conduct and take action if necessary.';
opt.adReportLoginExpiredMessage = 'Your login session has expired, please login and try again.';
opt.adReportLoginErrorMessage = 'An error occurred when loading the report form - please try again';
opt.adReportModalClass = 'js-ad-report';
opt.perRequestGuid = '1783d7fd-f958-437c-abf8-0cb5d6cb1439';
opt.responseHash = '90txI1WRXk7LOBt&#x2B;JkXhxWYGCCB0N5ty3PiJuKDmE1Q=';
opt.targeting.TargetingConsent = ['False_Passive'];
opt.allowAccountTargetingForThisRequest = !1;
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('dfptestads')) {
const dfptestads = urlParams.get('dfptestads');
opt.targeting.DfpTestAds = dfptestads;
}
</script>
<script>;(()=>{"use strict";var __webpack_modules__={23:(e,t,s)=>{s.d(t,{Z7:()=>l,eq:()=>d,kG:()=>i});const n=(r=location.pathname,/^\/tags\//.test(r)||/^\/questions\/tagged\//.test(r)?"tag-pages":/^\/discussions\//.test(r)||/^\/beta\/discussions/.test(r)?"discussions":/^\/$/.test(r)||/^\/home/.test(r)?"home-page":"question-pages");var r;let a=location.hostname;const o={slots:{lb:[[728,90]],mlb:[[728,90]],smlb:[[728,90]],bmlb:[[728,90]],sb:e=>"dfp-tsb"===e?[[300,250],[300,600]]:[[300,250]],"tag-sponsorship":[[730,135]],"mobile-below-question":[[320,50],[300,250]],msb:[[300,250],[300,600]],"talent-conversion-tracking":[[1,1]],"site-sponsorship":[[230,60]]},ids:{"dfp-tlb":"lb","dfp-mlb":"mlb","dfp-smlb":"smlb","dfp-bmlb":"bmlb","dfp-tsb":"sb","dfp-isb":"sb","dfp-tag":"tag-sponsorship","dfp-msb":"msb","dfp-sspon":"site-sponsorship","dfp-m-aq":"mobile-below-question"},idsToExcludeFromAdReports:["dfp-sspon"]};function i(){return Object.keys(o.ids)}function d(e){return o.idsToExcludeFromAdReports.indexOf(e)<0}function l(e){var t=e.split("_")[0];const s=o.ids[t];let r=o.slots[s];return"function"==typeof r&&(r=r(t)),{path:`/248424177/${a}/${s}/${n}`,sizes:r,zone:s}}},865:(e,t,s)=>{function n(e){return"string"==typeof e?document.getElementById(e):e}function r(e){return!!(e=n(e))&&"none"===getComputedStyle(e).display}function a(e){return!r(e)}function o(e){return!!e}function i(e){return/^\s*$/.test(n(e).innerHTML)}function d(e){const{style:t}=e;t.height=t.maxHeight=t.minHeight="auto",t.display="none"}function l(e){const{style:t}=e;t.height=t.maxHeight=t.minHeight="auto",t.display="none",[].forEach.call(e.children,l)}function c(e){const{style:t}=e;t.height=t.maxHeight=t.minHeight="auto",t.removeProperty("display")}function g(e){const t=document.createElement("script");t.src=e,document.body.appendChild(t)}function p(e){return s=e,(t=[]).push=function(e){return s(),delete this.push,this.push(e)},t;var t,s}function h(e){let t="function"==typeof HTMLTemplateElement;var s=document.createElement(t?"template":"div");return e=e.trim(),s.innerHTML=e,t?s.content.firstChild:s.firstChild}s.d(t,{$Z:()=>c,Bv:()=>h,Gx:()=>g,Nj:()=>n,QZ:()=>p,cf:()=>d,pn:()=>a,wo:()=>l,xb:()=>i,xj:()=>r,yb:()=>o})},763:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.d(__webpack_exports__,{t:()=>AdReports});var _common_helper__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(865),_console__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(276),_ad_units__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(23);class AdReports{constructor(e,t){if(this.googletag=e,this.cam=t,this.allowedFileTypes=["image/png","image/jpg","image/jpeg"],this.ignoreValidation=!1,_console__WEBPACK_IMPORTED_MODULE_1__.cM("Ad reporting init"),this.cam=t,this.callOnButtonClick=e=>this.onButtonClick(e),this.googletag.pubads().addEventListener("slotRenderEnded",e=>this.handleSlotRendered(e)),Array.isArray(t.slotsRenderedEvents)){_console__WEBPACK_IMPORTED_MODULE_1__.cM("Adding report button to "+t.slotsRenderedEvents.length+" events that have transpired");for(var s=0;s<t.slotsRenderedEvents.length;s++)this.handleSlotRendered(t.slotsRenderedEvents[s])}}handleSlotRendered(e){if(e&&e.slot&&!e.isEmpty&&(e.creativeId||e.lineItemId||!e.isEmpty)){var t=e.slot.getSlotElementId();if(t){var s=document.getElementById(t);if(s)if((0,_ad_units__WEBPACK_IMPORTED_MODULE_0__.eq)(t)){var n=s?.closest(".js-zone-container")?.querySelector(".js-report-ad-button-container");n.innerHTML="",n.append(this.createButton(e)),n.style.height="24px",_console__WEBPACK_IMPORTED_MODULE_1__.cM("Added report button to the bottom of "+t)}else _console__WEBPACK_IMPORTED_MODULE_1__.cM("Not adding report button to the bottom of "+t+": shouldHaveReportButton = false");else _console__WEBPACK_IMPORTED_MODULE_1__.cM("Not adding report button to the bottom of "+t+": resolved invalid adUnit element")}else _console__WEBPACK_IMPORTED_MODULE_1__.cM("Not adding report button to the bottom of element: invalid adUnitElementId")}else _console__WEBPACK_IMPORTED_MODULE_1__.cM("Not adding report button to the bottom of element: invalid SlotRenderEndedEvent")}async onButtonClick(e){e.preventDefault();let t=e.target;const s=t.dataset.modalUrl,n=t.dataset.googleEventData;return await this.loadModal(s,t,n),!1}createButton(e){let t=document.createElement("button");var s=JSON.stringify(e);return t.dataset.googleEventData=s,t.dataset.modalUrl=this.cam.opt.adReportUrl,t.dataset.adUnit=e.slot.getSlotElementId(),t.classList.add("js-report-ad","s-btn","s-btn__link","fs-fine","mt2","float-right"),t.append(document.createTextNode(this.cam.opt.adReportText)),t.removeEventListener("click",this.callOnButtonClick),t.addEventListener("click",this.callOnButtonClick),t}async loadModal(url,$link,googleEventData){try{await window.StackExchange.helpers.loadModal(url,{returnElements:window.$($link)}),this.initForm(googleEventData)}catch(e){var message="",response=e.responseText?eval(`(${e.responseText})`):null;message=response&&response.isLoggedOut?this.cam.opt.adReportLoginExpiredMessage:this.cam.opt.adReportLoginErrorMessage,window.StackExchange.helpers.showToast(message,{type:"danger"})}}removeModal(){window.StackExchange.helpers.closePopups(document.querySelectorAll("."+this.cam.opt.adReportModalClass),"dismiss")}initForm(e,t=!1){this.ignoreValidation=t,this.$form=document.querySelector(".js-ad-report-form"),this.$googleEventData=this.$form.querySelector(".js-json-data"),this.$adReportReasons=this.$form.querySelectorAll(".js-ad-report-reason"),this.$adReportReasonOther=this.$form.querySelector(".js-ad-report-reason-other"),this.$fileUploaderInput=this.$form.querySelector(".js-file-uploader-input"),this.$imageUploader=this.$form.querySelector(".js-image-uploader"),this.$clearImageUpload=this.$form.querySelector(".js-clear-image-upload"),this.$imageUploaderText=this.$form.querySelector(".js-image-uploader-text"),this.$imageUploaderPreview=this.$form.querySelector(".js-image-uploader-preview"),this.$fileErrorMessage=this.$form.querySelector(".js-file-error");const s=this.$form.querySelector(".js-drag-drop-enabled"),n=this.$form.querySelector(".js-drag-drop-disabled");this.$googleEventData.value=e,this.$adReportReasons.forEach((e,t)=>e.addEventListener("change",e=>{this.$adReportReasonOther.classList.toggle("d-none","3"!==e.target.value)})),this.$fileUploaderInput.addEventListener("change",()=>{this.validateFileInput()&&this.updateImagePreview(this.$fileUploaderInput.files)}),this.$clearImageUpload.addEventListener("click",e=>{e.preventDefault(),this.clearImageUpload()});try{this.$fileUploaderInput[0].value="",this.$imageUploader.addEventListener("dragenter dragover dragleave drop",this.preventDefaults),this.$imageUploader.addEventListener("dragenter dragover",this.handleDragStart),this.$imageUploader.addEventListener("dragleave drop",this.handleDragEnd),this.$imageUploader.addEventListener("drop",this.handleDrop)}catch(e){s.classList.add("d-none"),n.classList.remove("d-none")}this.$form.removeEventListener("",this.handleDragEnd),this.$form.addEventListener("submit",async e=>(e.preventDefault(),this.submitForm(),!1))}clearImageUpload(){this.$fileUploaderInput.value="",this.$imageUploaderPreview.setAttribute("src",""),this.$imageUploaderPreview.classList.add("d-none"),this.$clearImageUpload.classList.add("d-none"),this.$imageUploaderText.classList.remove("d-none"),this.$imageUploader.classList.add("p16","ba","bas-dashed","bc-black-100")}preventDefaults(e){e.preventDefault(),e.stopPropagation()}handleDragStart(e){this.$imageUploader.classList.remove("bas-dashed"),this.$imageUploader.classList.add("bas-solid","bc-black-100")}handleDragEnd(e){this.$imageUploader.classList.remove("bas-solid","bc-black-100"),this.$imageUploader.classList.add("bas-dashed")}handleDrop(e){var t=e.originalEvent.dataTransfer.files;FileReader&&t&&1===t.length&&(this.$fileUploaderInput.files=t,this.validateFileInput()&&this.updateImagePreview(t))}setError(e){this.$fileErrorMessage.parentElement.classList.toggle("has-error",e)}updateImagePreview(e){this.$imageUploader.classList.remove("p16","ba","bas-dashed","bc-black-100"),this.$clearImageUpload.classList.remove("d-none"),this.$imageUploaderText.classList.add("d-none");var t=new FileReader;t.onload=e=>{null!=e.target&&(this.$imageUploaderPreview.setAttribute("src",e.target.result),this.$imageUploaderPreview.classList.remove("d-none"))},t.readAsDataURL(e[0])}validateFileInput(){if(this.ignoreValidation)return!0;const e=this.cam.opt.adReportFileTypeErrorMessage,t=this.cam.opt.adReportFileSizeErrorMessage;if(null==this.$fileUploaderInput.files)return!1;var s=this.$fileUploaderInput.files[0];return null==s?(this.setError(!0),!1):this.allowedFileTypes.indexOf(s.type)<0?(this.$fileErrorMessage.textContent=e,this.$fileErrorMessage.classList.remove("d-none"),this.setError(!0),!1):s.size>2097152?(this.$fileErrorMessage.textContent=t,this.$fileErrorMessage.classList.remove("d-none"),this.setError(!0),!1):(this.$fileErrorMessage.classList.add("d-none"),this.setError(!1),!0)}async gatherDiagnosticInfo(){return{BrowserVersion:await this.getBrowserVersion()}}getElementSource(e){return e.outerHTML}getNestedIFrameElement(e){var t=e.querySelector("iframe");return t.contentDocument?t.contentDocument.documentElement:t.contentWindow.document.documentElement}async getBrowserVersion(){return await navigator.userAgentData.getHighEntropyValues(["fullVersionList"]).then(e=>JSON.stringify(e.fullVersionList))}async submitForm(){if(!this.validateFileInput())return!1;this.$form.querySelector("[type=submit]").setAttribute("disabled","true");var e=JSON.parse(this.$googleEventData.value||"{}");e.Reason=parseInt(this.$form.querySelector(".js-ad-report-reason:checked").value,10),e.Description=this.$adReportReasonOther.value,this.$googleEventData.value=JSON.stringify(e);var t=new FormData(this.$form);if("1"===t.get("shareDiagnosticInfo")){var s=await this.gatherDiagnosticInfo();Object.keys(s).forEach(e=>t.append(e,s[e]))}try{const e=await window.fetch(this.$form.getAttribute("action"),{method:this.$form.getAttribute("method"),body:t,cache:"no-cache"}),s=e.headers.get("content-type")||"",r=await e.text();if(!e.ok)throw new Error("response not valid");if(0===s.indexOf("text/html")){var n=(0,_common_helper__WEBPACK_IMPORTED_MODULE_2__.Bv)(r);const e=n?n.querySelector(".js-modal-content"):null;if(_console__WEBPACK_IMPORTED_MODULE_1__.cM("$popupContent"),_console__WEBPACK_IMPORTED_MODULE_1__.cM(e),!e)throw new Error(`Could not find .js-modal-content in response from ${this.$form.getAttribute("action")}`);document.querySelector(".js-modal-content").replaceWith(e)}else window.StackExchange.helpers.showToast(this.cam.opt.adReportThanksText,{type:"success"}),this.removeModal()}catch(e){window.StackExchange.helpers.showToast(this.cam.opt.adReportErrorText,{type:"danger"})}finally{let e=this.$form.querySelector("[type=submit]");e&&e.removeAttribute("disabled")}}}},276:(e,t,s)=>{function n(...e){}function r(...e){}s.d(t,{cM:()=>n,vU:()=>r})}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var s=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](s,s.exports,__webpack_require__),s.exports}__webpack_require__.d=(e,t)=>{for(var s in t)__webpack_require__.o(t,s)&&!__webpack_require__.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var __webpack_exports__={};(()=>{var e=__webpack_require__(276),t=(e=>(e[e.Above=0]="Above",e[e.Below=1]="Below",e))(t||{});const s=Object.assign({},{"lib":"https://cdn.sstatic.net/clc/js/bundles/gam_loader_script/gam_loader_script.bundle.741.e6ce4ee02b887d174e72.min.js","style":null,"u":null,"wa":true,"kt":2000,"tto":true,"h":"clc.stackoverflow.com","allowed":"^(((talent\\.)?stackoverflow)|(blog\\.codinghorror)|(.*\\.googlesyndication)|(serverfault|askubuntu|superuser)|([^\\.]+\\.stackexchange))\\.com$","wv":true,"al":false,"abd":true,"cpa_liid":[5882654614],"cpa_cid":[138377597667],"dp":false,"tgt_to":1000,"tgt_u":"https://clc.stackoverflow.com/get-user-acct-tgt","tgt_e":true,"tgt_p":100});var n=__webpack_require__(23),r=__webpack_require__(865),a=__webpack_require__(763);class o{constructor(t,s){this.googletag=t,this.interval=s,e.cM("Ad refresh init. interval: "+s),this.googletag.pubads().addEventListener("impressionViewable",e=>this.onImpressionViewable(e)),e.cM("done enabling ad refresh")}onImpressionViewable(t){var s=t.slot;e.cM("ad refresh - slot "+s.getSlotElementId()+" is viewable, initializing refresh"),this.scheduleRefresh(s)}scheduleRefresh(e){setTimeout(()=>this.refreshAdSlot(e),1e3*this.interval)}static refreshMyAd(t,s){let n=t.pubads().getSlots().find(e=>e.getSlotElementId()===s);n&&(e.cM("refreshMyAd - refreshing ad slot "+s),t.pubads().refresh([n]))}refreshAdSlot(t){var s=t.getSlotElementId();this.isElementVisibleInBrowser(s)?(e.cM("refreshing ad slot "+s),googletag.pubads().refresh([t])):(e.cM("refresh skipped this time; ad slot not viewable:"+s),this.scheduleRefresh(t))}isElementVisibleInBrowser(e){var t=document.getElementById(e);if(null!==t){var s=t.getBoundingClientRect();if(s.top>=0&&s.left>=0&&s.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&s.right<=(window.innerWidth||document.documentElement.clientWidth))return!0}return!1}}var i=(e=>(e.Off="Off",e.PreSurvey="PreSurvey",e.Collect="Collect",e.PostSurvey="PostSurvey",e))(i||{});class d{constructor(e,t){this.lineItemImpressions=[],this.surveysIdsCompleted=[],this.lineItemImpressions=e,this.surveysIdsCompleted=t}addImpression(e,t){let s={brandId:e,lineItemId:t,timestamp:new Date};this.lineItemImpressions.push(s)}addBrandSurveyCompleted(e){-1===this.surveysIdsCompleted.indexOf(e)&&this.surveysIdsCompleted.push(e)}getTotalBrandImpressions(){let e=new Map;for(let t of this.lineItemImpressions)if(e.has(t.brandId)){let s=e.get(t.brandId);e.set(t.brandId,s+1)}else e.set(t.brandId,1);return e}getBrandLineItemImpressions(e){let t={};for(let s of this.lineItemImpressions)if(s.brandId==e)if(void 0!==t[s.lineItemId]){let e=t[s.lineItemId];t[s.lineItemId]=e+1}else t[s.lineItemId]=1;return t}}class l{constructor(){this.surveyEngagementLocalStorageKey="clc-survey-engagement"}getBrandSurveyEngagement(){let e=localStorage.getItem(this.surveyEngagementLocalStorageKey);if(null===e)return new d([],[]);let t=JSON.parse(e);return new d(t.lineItemImpressions,t.surveysIdsCompleted)}saveBrandSurveyEngagement(e){let t=JSON.stringify(e);localStorage.setItem(this.surveyEngagementLocalStorageKey,t)}}class c{constructor(){this.surveyRepository=new l}getBrandSurveyEngagement(){return this.surveyRepository.getBrandSurveyEngagement()}recordImpression(e,t){let s=this.getBrandSurveyEngagement();s.addImpression(e,t),this.surveyRepository.saveBrandSurveyEngagement(s)}recordBrandSurveyCompleted(e){let t=this.getBrandSurveyEngagement();t.addBrandSurveyCompleted(e),this.surveyRepository.saveBrandSurveyEngagement(t)}}class g{constructor(t,s){this.googletag=t,this.brandSettings=s,this.brandSlotMap=new Map,this.brandSurveyEngagementService=new c,e.cM("Brand Survey init: "+JSON.stringify(s)),void 0!==s?(this.googletag.pubads().addEventListener("slotRenderEnded",e=>this.handleSlotRendered(e)),this.googletag.pubads().addEventListener("impressionViewable",e=>this.onImpressionViewable(e)),e.cM("done enabling Brand Survey")):e.cM("Brand Survey init: brandSettings is undefined, not initializing")}handleSlotRendered(t){e.cM("Brand Survey - slot rendered - slot:"+JSON.stringify(t.slot.getSlotElementId())+" lineItem: "+t.lineItemId);let s=this.findItemWithId(t.lineItemId);if(null===s||s.mode!==i.Collect)this.brandSlotMap.delete(t.slot.getSlotElementId());else{let e={brandId:s.brandId,lineItemId:t.lineItemId};this.brandSlotMap.set(t.slot.getSlotElementId(),e)}}onImpressionViewable(t){let s=t.slot;if(e.cM("ad - Brand Survey - impression viewable. Details: "+JSON.stringify(s.getSlotElementId())),e.cM("ad - Brand Survey - slot "+s.getSlotElementId()+" is viewable"),this.brandSlotMap.has(s.getSlotElementId())){let t=this.brandSlotMap.get(s.getSlotElementId());e.cM("Brand Survey - brand "+t.brandId+" is viewable"),this.recordImpression(this.brandSlotMap.get(s.getSlotElementId()))}}recordImpression(t){e.cM("ad - Brand Survey - recording impression for brand "+t.brandId),this.brandSurveyEngagementService.recordImpression(t.brandId,t.lineItemId)}findItemWithId(t){return e.cM("brand settings: "+JSON.stringify(this.brandSettings)),this.brandSettings.find(e=>e.lineItemIds.includes(t))||null}}const p="response-brand-survey-submit|",h="request-brand-survey-metadata|",m="record-metric-on-server|",u="request-dsp-tags",f="response-dsp-tags|";class _{static refreshAdIfBrandSurveyIsDuplicated(e,t,s){this.alreadyCompletedThisBrandSurvey(t)&&o.refreshMyAd(e,s)}static alreadyCompletedThisBrandSurvey(e){return(new c).getBrandSurveyEngagement().surveysIdsCompleted.includes(e)}}window.cam=new class{constructor(t=null){if(this.gptImported=!1,this.slotsRenderedEvents=[],this.collapsed={},e.cM("constructor"),this.clc_options=s,window.clcGamLoaderOptions)Object.assign(this,window.clcGamLoaderOptions);else if(void 0===this.opt){let e=window.opt;e&&(this.opt=e)}}init(){if(e.cM("init"),void 0===this.opt)throw new Error("opt not set, required by GAM Loader");e.cM("init brand survey service"),this.getUserMetaPromise=this.getUserMeta(),e.cM("setup message handler"),window.addEventListener("message",e=>{this.onmessage(e)})}handleSlotRenderedNoAdReport(){if(googletag.pubads().addEventListener("slotRenderEnded",e=>this.applyExtraMarginBottom(e)),Array.isArray(this.slotsRenderedEvents))for(var e=0;e<this.slotsRenderedEvents.length;e++)this.applyExtraMarginBottom(this.slotsRenderedEvents[e])}onmessage(t){let s="omni";if(t.data&&("string"==typeof t.data||t.data instanceof String))if(0===t.data.indexOf("get-omni-")){e.cM("Recevied get-omni message, sending back omni");var n=t.source,a=this.opt.omni,o="string"==typeof a?a:"";n.postMessage([s,o,this.opt.perRequestGuid].join("|"),"*")}else if(0===t.data.indexOf("collapse-")){e.cM("Recevied collapse message, collapse ad iframe"),e.cM(t);for(var i=t.source.window,d=document.getElementsByTagName("IFRAME"),l=0;l<d.length;l++){var g=d[l];if(g.contentWindow==i)return void(0,r.wo)(g.parentElement.parentElement.parentElement)}}else if(0===t.data.indexOf("resize|")){e.cM("Recevied resize message, resize ad iframe"),e.cM(t);let s=this._getFrameByEvent(t),n=t.data.indexOf("|")+1,r=t.data.slice(n),a=parseFloat(r)+.5;e.cM("New iframe height "+a),s.height=a.toString(),s.parentElement.style.height=a.toString()+"px"}else if(0===t.data.indexOf("getmarkup|")){let s=t.data.indexOf("|")+1,n=t.data.slice(s);e.cM("Recevied get markup message: "+n);let r=this._getFrameByEvent(t).closest(".everyonelovesstackoverflow");const a=document.createElement("script");a.dataset.adZoneId=r.id,a.src=n,document.body.appendChild(a)}else if(0===t.data.indexOf("window-location|")){let s=t.data.indexOf("|")+1,n=t.data.slice(s);e.cM("Recevied window location message: "+n),n.startsWith("/")||(n="/"+n),window.open(window.location.protocol+"//"+window.location.host+n,"_blank")}else if(0===t.data.indexOf("request-brand-survey-submit|")){let s=t.data.split("|"),n=s[1],r=s[2],a=s[3],o=JSON.parse(a);e.cM(n),e.cM(r),e.cM(a),e.cM("Received brand survey "+n+" response message: "+r);var v=new FormData;for(var b in o)v.append(b,o[b]);let i=this._getFrameByEvent(t);if(_.alreadyCompletedThisBrandSurvey(+n))return e.cM("Already completed this brand survey. Not submitting duplicate to server."),void i.contentWindow.postMessage("response-brand-survey-submit-duplicate|","*");e.cM("Send the brand survey to the server"),fetch(r,{method:"POST",body:v}).then(e=>e.json()).then(e=>i.contentWindow.postMessage(p,"*")).catch(e=>i.contentWindow.postMessage(p,"*"))}else if(0===t.data.indexOf("brand-survey-completed-store|")){let s=t.data.split("|"),n=(s[1],s[2]);if(e.cM("Received brand survey completed store message for survey ID "+n),_.alreadyCompletedThisBrandSurvey(+n))return void e.cM("Already completed this brand survey. Not recording duplicate locally.");e.cM("Record brand survey completion locally"),(new c).recordBrandSurveyCompleted(+n)}else if(0===t.data.indexOf(h)){let s=t.data.split("|"),n=s[1],r=s[2];e.cM("Received message: request-brand-survey-metadata| with Brand Survey ID "+r);let a=(new c).getBrandSurveyEngagement().getBrandLineItemImpressions(+n),o=JSON.stringify(a),i=this._getFrameByEvent(t);e.cM("sending impression data: "+o),i.contentWindow.postMessage("response-brand-survey-metadata|"+this.opt.responseHash+"|"+this.opt.perRequestGuid+"|"+o,"*")}else if(0===t.data.indexOf("refresh-if-duplicate-brand-survey|")){let e=t.data.split("|")[1],s=this.getSlotElementIdByEvent(t);_.refreshAdIfBrandSurveyIsDuplicated(googletag,+e,s)}else if(0===t.data.indexOf(m)){e.cM("Received message: record-metric-on-server| with args: "+t.data);let s=t.data.split("|"),n=s[1],r=s[2],a=s[3],o=s[4],i=new FormData;i.append("brandSurveyId",a.toString()),i.append("responseHash",this.opt.responseHash),i.append("perRequestGuid",this.opt.perRequestGuid),i.append("questionNumber",n.toString()),i.append("metricType",o.toString()),fetch(r,{method:"POST",body:i}).then(e=>e.ok).catch(t=>{e.cM("SendMetricToServer: Error sending metric to server: "+t)})}else if(0===t.data.indexOf(u)){e.cM("Received message: request-dsp-tags with args: "+t.data);let s=this._getFrameByEvent(t);if(!this.opt.targeting["so-tag"])return void s.contentWindow.postMessage(f,"*");const n=this.opt.targeting["so-tag"].join(",");e.cM("sending targeting tags: "+n),s.contentWindow.postMessage(f+n,"*")}else e.cM("Received unhandled message")}getSlotElementIdByEvent(e){let t=this._getFrameByEvent(e).parentElement?.parentElement?.id;return t||""}_getFrameByEvent(e){return Array.from(document.getElementsByTagName("iframe")).filter(t=>t.contentWindow===e.source)[0]}classifyZoneIds(e){const t=e.map(r.Nj).filter(r.yb);return{eligible:t.filter(r.xb).filter(r.pn),ineligible:t.filter(r.xj)}}applyExtraMarginBottom(t){if(t&&t.slot&&!t.isEmpty&&(t.creativeId||t.lineItemId||!t.isEmpty)){var s=t.slot.getSlotElementId();if(s){var r=document.getElementById(s);if(r)if((0,n.eq)(s)){var a=r?.closest(".js-zone-container");a.style.marginBottom="24px",e.cM("Applied extra margin to the bottom of "+s)}else e.cM("Not applying extra margin to the bottom of "+s+": shouldHaveReportButton = false");else e.cM("Not applying extra margin to the bottom of "+s+": resolved invalid adUnit element")}else e.cM("Not applying extra margin to the bottom of element: invalid adUnitElementId")}else e.cM("Not applying extra margin to the bottom of element: invalid SlotRenderEndedEvent")}async load(s=(0,n.kG)()){const i=this.opt.tlb_position===t.Above?["dfp-mlb","dfp-smlb"]:["dfp-mlb","dfp-smlb","dfp-tlb"];if(!this.isGptReady())return e.cM("Initializing..."),this.initGpt(),void googletag.cmd.push(()=>this.load(s));this.opt.adReportEnabled?(e.cM("Ad reporting enabled"),this.adReports=new a.t(googletag,this)):(e.cM("Ad reporting not enabled"),this.handleSlotRenderedNoAdReport()),this.opt.refresh?(e.cM("Ad refresh enabled"),this.adRefresh=new o(googletag,this.opt.refreshInterval)):e.cM("Ad refresh not enabled"),this.opt.brandSurveyEnabled&&(e.cM("Brand Survey enabled"),this.brandSurvey=new g(googletag,this.opt.brandSurveySettings)),e.cM("Attempting to load ads into ids: ",s);const{eligible:d,ineligible:l}=this.classifyZoneIds(s);if(this.initDebugPanel(googletag,d.concat(l)),d.forEach(e=>(0,r.cf)(e)),l.forEach(r.wo),0===d.length)return void e.cM("Found no ad ids on page");e.cM("Eligible ids:",d),this.opt.abd&&this.appendAdblockDetector();var c=googletag.pubads().getSlots();if(c){var p=c.filter(e=>s.indexOf(e.getSlotElementId())>=0);googletag.destroySlots(p)}this.opt.sf&&(googletag.pubads().setForceSafeFrame(!0),googletag.pubads().setSafeFrameConfig({allowOverlayExpansion:!0,allowPushExpansion:!0,sandbox:!0})),e.cM("Targeting consent: Checking...");let h=!1,m=!1;void 0!==this.opt.targeting_consent&&(m=!0,e.cM("Targeting consent: Parameter set"),e.cM("Targeting consent: Consent given? ",this.opt.targeting_consent),h=this.opt.targeting_consent),void 0!==this.opt.personalization_consent&&(e.cM("Personalization consent: Parameter set"),e.cM("Personalization consent: Consent given? ",this.opt.personalization_consent),h=h&&this.opt.personalization_consent),h=h&&m,this.setPrivacySettings(h),this.opt.ll||googletag.pubads().enableSingleRequest(),cam.sreEvent||(googletag.pubads().addEventListener("slotRenderEnded",e=>this.onSlotRendered(e)),cam.sreEvent=!0),await this.setTargeting();var u=d.filter(e=>!this.opt.ll||i.indexOf(e.id)<0),f=d.filter(e=>!!this.opt.ll&&i.indexOf(e.id)>=0);e.cM("Up front ids:",u),e.cM("Lazy loaded ids:",f),u.forEach(t=>{e.cM(`Defining ad for element ${t.id}`),this.defineSlot(t.id,googletag),t.setAttribute("data-dfp-zone","true")}),googletag.enableServices(),u.forEach(t=>{e.cM(`Displaying ad for element ${t.id}`),googletag.cmd.push(()=>googletag.display(t.id))}),this.opt.ll&&(e.cM("Enabling lazy loading for GAM"),googletag.pubads().enableLazyLoad({fetchMarginPercent:0,renderMarginPercent:0}),e.cM("Setting up lazy loaded ad units"),f.forEach(t=>{e.cM(`Lazy loading - Defining Slot ${t.id}`),this.defineSlot(t.id,googletag)}),f.forEach(t=>{e.cM(`Lazy loading - Displaying ad for element ${t.id}`),googletag.cmd.push(()=>googletag.display(t.id))}))}setPrivacySettings(e){e||googletag.pubads().setPrivacySettings({nonPersonalizedAds:!0})}async setTargeting(){if(!googletag)throw new Error("googletag not defined");let t=this.opt.targeting;if(!t)throw new Error("Targeting not defined (is "+typeof t+")");Object.keys(t).forEach(s=>{e.cM(`-> targeting - ${s}: ${t[s]}`),googletag.pubads().setTargeting(s,t[s])});let s=!1;if(void 0!==this.opt.targeting_consent&&(s=this.opt.targeting_consent),s){let t=(new c).getBrandSurveyEngagement();if(t.getTotalBrandImpressions().forEach((t,s)=>{e.cM(`-> targeting - BrandImpressions: ${s}: ${t}`),googletag.pubads().setTargeting("brand_"+s.toString()+"_impressions",t.toString())}),t.surveysIdsCompleted.forEach(t=>{e.cM(`-> targeting - SurveysTaken: ${t}`),googletag.pubads().setTargeting("survey_"+t+"_taken","true")}),this.clc_options.tgt_e&&this.getUserMetaPromise){let t=await this.getUserMetaPromise;t&&t.tgt_acct?(e.cM("-> targeting - User Account: "+t.tgt_acct),googletag.pubads().setTargeting("user-acct",t.tgt_acct.company_name),googletag.pubads().setTargeting("user_acct_top",t.tgt_acct.company_name),googletag.pubads().setTargeting("user_industry",t.tgt_acct.industry),googletag.pubads().setTargeting("user_employee_count",t.tgt_acct.employee_range)):e.cM("-> targeting - User Account: Not Found"),t&&Object.prototype.hasOwnProperty.call(t,"is_high_rep_earner")?(e.cM("-> targeting - High Rep Earner: "+t.is_high_rep_earner),googletag.pubads().setTargeting("IsHighRepEarner",t.is_high_rep_earner?"true":"false")):e.cM("-> targeting - High Rep Earner: not found")}}}appendAdblockDetector(){const e=document.createElement("div");e.className="adsbox",e.id="clc-abd",e.style.position="absolute",e.style.pointerEvents="none",e.innerHTML="&nbsp;",document.body.appendChild(e)}onSlotRendered(s){try{const o=s.slot.getSlotElementId();let i=[];o||i.push("id=0");const d=document.getElementById(o);if(o&&!d&&i.push("el=0"),0!==i.length)return void this.stalled(i.join("&"));const{path:l,sizes:c,zone:g}=(0,n.Z7)(o);if(this.collapsed[g]&&s.isEmpty)return e.cM(`No line item for the element #${d.id}... collapsing.`),void(0,r.wo)(d);if(this.slotsRenderedEvents.push(s),s.lineItemId||s.creativeId||!s.isEmpty){e.cM(`Rendered ad for element #${d.id} [line item #${s.lineItemId}]`),e.cM(s);var a=d.parentElement;if(a.classList.contains("js-zone-container")){switch((0,r.cf)(a),o){case"dfp-tlb":this.opt.tlb_position===t.Above?a.classList.add("mb8"):a.classList.add("mt16");break;case"dfp-tag":a.classList.add("mb8");break;case"dfp-msb":a.classList.add("mt16");break;case"dfp-mlb":case"dfp-smlb":case"dfp-bmlb":a.classList.add("my8");break;case"dfp-isb":a.classList.add("mt24");break;case"dfp-m-aq":a.classList.add("my12"),a.classList.add("mx-auto")}(0,r.$Z)(a),(0,r.$Z)(d)}else e.cM(`No ad for element #${d.id}, collapsing`),e.cM(s),(0,r.wo)(d)}}catch(t){e.cM("Exception thrown onSlotRendered"),e.cM(t),this.stalled("e=1")}}stalled(e){(new Image).src=`https://${this.clc_options.h}/stalled.gif?${e}`}defineSlot(t,s){"dfp-isb"===t&&(e.cM("-> targeting - Sidebar: Inline"),s.pubads().setTargeting("Sidebar",["Inline"])),"dfp-tsb"===t&&(e.cM("-> targeting - Sidebar: Right"),s.pubads().setTargeting("Sidebar",["Right"]));const{path:r,sizes:a,zone:o}=(0,n.Z7)(t);e.cM(`Defining slot for ${t}: ${r}, sizes: ${JSON.stringify(a)}`),s.defineSlot(r,a,t).addService(s.pubads())}importGptLibrary(){this.gptImported||(this.gptImported=!0,void 0===this.opt.targeting_consent||this.opt.targeting_consent?(0,r.Gx)("https://securepubads.g.doubleclick.net/tag/js/gpt.js"):(0,r.Gx)("https://pagead2.googlesyndication.com/tag/js/gpt.js"))}isGptReady(){return"undefined"!=typeof googletag&&!!googletag.apiReady}initGpt(){"undefined"==typeof googletag&&(window.googletag={cmd:(0,r.QZ)(()=>this.importGptLibrary())})}getUserMeta(){if(this.opt.allowAccountTargetingForThisRequest&&this.clc_options.tgt_e&&this.clc_options.tgt_p>0){if(e.cM("Targeting enabled."),this.clc_options.tgt_p<100){e.cM("Targeting rate limit enabled. Rolling the dice...");const t=Math.floor(100*Math.random())+1;if(e.cM("Rolled "+t+" and the max is "+this.clc_options.tgt_p),t>this.clc_options.tgt_p)return void e.cM("Will not request targeting.")}return e.cM("Will request targeting."),function(e,t,s,n){if(t){const t=new Headers;return t.append("Accept","application/json"),async function(e,t={},s=5e3){if("number"!=typeof s&&null!=s&&!1!==s){if("string"!=typeof s)throw new Error("fetchWithTimeout: timeout must be a number");if(s=parseInt(s),isNaN(s))throw new Error("fetchWithTimeout: timeout must be a number (or string that can be parsed to a number)")}const n=new AbortController,{signal:r}=n,a=fetch(e,{...t,signal:r}),o=setTimeout(()=>n.abort(),s);try{const e=await a;return clearTimeout(o),e}catch(e){throw clearTimeout(o),e}}(s+"?"+new URLSearchParams({omni:e}),{method:"GET",mode:"cors",headers:t},n).then(e=>e.json())}return Promise.reject("No consent")}(this.opt.omni,this.opt.targeting_consent,this.clc_options.tgt_u,this.clc_options.tgt_to).catch(t=>{e.vU("Error fetching user account targeting"),e.vU(t)})}e.cM("Targeting disabled. Will not request account targeting data.")}initDebugPanel(t,s){e.cM("initDebugPanel"),e.cM("Not showing debug panel.")}},window.clcGamLoaderOptions&&(cam.init(),cam.load())})()})();</script>
<footer id="footer" class="site-footer js-footer" role="contentinfo">
<div class="site-footer--container">
<nav class="site-footer--nav">
<div class="site-footer--col">
<h5 class="-title"><a href="/">Software Engineering</a></h5>
<ul class="-list js-primary-footer-links">
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 2 })" href="/tour">Tour</a></li>
<li><a href="/help" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 3 })">Help</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 5 })" href="https://chat.stackexchange.com?tab=site&host=softwareengineering.stackexchange.com">Chat</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 13 })" href="/contact">Contact</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 14 })" href="https://softwareengineering.meta.stackexchange.com">Feedback</a></li>
</ul>
</div>
<div class="site-footer--col">
<h5 class="-title"><a class="js-gps-track" data-gps-track="footer.click({ location: 2, link: 1 })" href="https://stackoverflow.co/">Company</a></h5>
<ul class="-list">
<li><a href="https://stackoverflow.com" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 15})">Stack Overflow</a></li>
<li><a href="https://stackoverflow.co/teams/" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 29 })">Teams</a></li>
<li><a href="https://stackoverflow.co/advertising/" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 21 })">Advertising</a></li>
<li><a href="https://stackoverflow.co/collectives/" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 40 })">Collectives</a></li>
<li><a href="https://stackoverflow.co/talent/" class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 20 })">Talent</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 1 })" href="https://stackoverflow.co/">About</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 27 })" href="https://stackoverflow.co/company/press/">Press</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 7 })" href="https://stackoverflow.com/legal">Legal</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 8 })" href="https://stackoverflow.com/legal/privacy-policy">Privacy Policy</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 37 })" href="https://stackoverflow.com/legal/terms-of-service/public">Terms of Service</a></li>
<li class="" id="consent-footer-link"><a class="js-gps-track -link js-cookie-settings" data-gps-track="footer.click({ location: 2, link: 38 })" href="#" data-consent-popup-loader="footer">Cookie Settings</a></li>
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link: 39 })" href="https://stackoverflow.com/legal/cookie-policy">Cookie Policy</a></li>
</ul>
</div>
<div class="site-footer--col site-footer--categories-nav">
<div>
<h5 class="-title"><a href="https://stackexchange.com" data-gps-track="footer.click({ location: 2, link: 30 })">Stack Exchange Network</a></h5>
<ul class="-list">
<li>
<a href="https://stackexchange.com/sites#technology" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Technology
</a>
</li>
<li>
<a href="https://stackexchange.com/sites#culturerecreation" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Culture &amp; recreation
</a>
</li>
<li>
<a href="https://stackexchange.com/sites#lifearts" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Life &amp; arts
</a>
</li>
<li>
<a href="https://stackexchange.com/sites#science" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Science
</a>
</li>
<li>
<a href="https://stackexchange.com/sites#professional" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Professional
</a>
</li>
<li>
<a href="https://stackexchange.com/sites#business" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Business
</a>
</li>
<li class="mt16 md:mt0">
<a href="https://api.stackexchange.com/" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
API
</a>
</li>
<li>
<a href="https://data.stackexchange.com/" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 24 })">
Data
</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="site-footer--copyright fs-fine md:mt24">
<ul class="-list -social md:mb8">
<li><a class="js-gps-track -link" data-gps-track="footer.click({ location: 2, link:4 })" href="https://stackoverflow.blog?blb=1">Blog</a></li>
<li><a href="https://www.facebook.com/officialstackoverflow/" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 31 })">Facebook</a></li>
<li><a href="https://twitter.com/stackoverflow" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 32 })">Twitter</a></li>
<li><a href="https://linkedin.com/company/stack-overflow" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 33 })">LinkedIn</a></li>
<li><a href="https://www.instagram.com/thestackoverflow" class="-link js-gps-track" data-gps-track="footer.click({ location: 2, link: 36 })">Instagram</a></li>
</ul>
<p class="md:mb0">
Site design / logo &#169; 2024 Stack Exchange Inc; user contributions licensed under <span class='td-underline'><a href="https://stackoverflow.com/help/licensing">CC BY-SA</a></span>. <span id="svnrev">rev&nbsp;2024.3.7.5898</span>
</p>
</div>
</div>
</footer>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-S812YQPLT2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
</script>
<script>
StackExchange.ready(function() {
var ga3Settings = {
autoLink: ["stackoverflow.blog","info.stackoverflowsolutions.com","stackoverflowsolutions.com"],
sendTitles: true,
tracker: window.ga,
trackingCodes: [
'UA-108242619-5'
],
checkDimension: 'dimension42'
};
var customGA4Dimensions = {};
customGA4Dimensions["routename"] = "Questions/Show";
customGA4Dimensions["post_id"] = "439871";
customGA4Dimensions["tags"] = "|html|front-end|scripting|code-generation|unix|";
var ga4Settings = {
tracker: gtag,
trackingCodes: [
'G-S812YQPLT2'
],
consentsToPerformanceCookies: "denied",
consentsToTargetingCookies: "denied",
eventParameters: customGA4Dimensions,
checkForAdBlock: true,
sendTitles: true,
trackClicks: false,
};
StackExchange.ga.init({ GA3: ga3Settings, GA4: ga4Settings });
StackExchange.ga.setDimension('dimension2', '|html|front-end|scripting|code-generation|unix|');
StackExchange.ga.setDimension('dimension3', 'Questions/Show');
StackExchange.ga.setDimension('dimension7', "1709846696.838722319");
StackExchange.ga.trackPageView();
});
</script>
<script src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" charset="UTF-8" data-document-language="false" data-domain-script="cb0f3c87-b769-4e66-bbaa-377f9194216d"></script>
</body>
</html>