A place to cache linked articles (think custom and personal wayback machine)
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

pirms 3 gadiem
pirms 3 gadiem
pirms 3 gadiem
pirms 3 gadiem
pirms 3 gadiem
pirms 3 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Built to Last (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f0f0ea">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f0f0ea">
  26. <!-- Documented, feel free to shoot an email. -->
  27. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  28. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <script>
  36. function toggleTheme(themeName) {
  37. document.documentElement.classList.toggle(
  38. 'forced-dark',
  39. themeName === 'dark'
  40. )
  41. document.documentElement.classList.toggle(
  42. 'forced-light',
  43. themeName === 'light'
  44. )
  45. }
  46. const selectedTheme = localStorage.getItem('theme')
  47. if (selectedTheme !== 'undefined') {
  48. toggleTheme(selectedTheme)
  49. }
  50. </script>
  51. <meta name="robots" content="noindex, nofollow">
  52. <meta content="origin-when-cross-origin" name="referrer">
  53. <!-- Canonical URL for SEO purposes -->
  54. <link rel="canonical" href="https://logicmag.io/care/built-to-last/">
  55. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick">
  56. <article>
  57. <header>
  58. <h1>Built to Last</h1>
  59. </header>
  60. <nav>
  61. <p class="center">
  62. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  63. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  64. </svg> Accueil</a> •
  65. <a href="https://logicmag.io/care/built-to-last/" title="Lien vers le contenu original">Source originale</a>
  66. </p>
  67. </nav>
  68. <hr>
  69. <p>At the time of this writing, in July 2020, the COVID-19 pandemic has killed over 133,000 people in the United States. The dead are disproportionately Black and Latinx people and those who were unable, or not allowed by their employers, to work remotely. During the pandemic, we’ve seen our technological infrastructures assume ever more importance—from the communications technology that allows people with the means and privilege to telecommute, to the platforms that amplify public health information or deadly, politicized misinformation. We’ve also seen some of the infrastructure that runs the social safety net break down under an increasing load. This includes state unemployment systems that pay workers the benefits they’ve contributed to for decades through taxes. In a global pandemic, being able to work from home, to quit and live on savings, or to be laid off and draw unemployment benefits has literally become a matter of life and death. </p>
  70. <p>The cracks in our technological infrastructure became painfully evident in the spring, as US corporations responded to the pandemic by laying off more and more workers. So many people had to file for unemployment at once that computerized unemployment claim systems started to malfunction. Around the country, phone lines jammed, websites crashed, and millions of people faced the possibility of not being able to pay for rent, medicine, or food. </p>
  71. <p>As the catastrophe unfolded, several state governments blamed it on aged, supposedly obsolete computer systems written in COBOL, a programming language that originated in the late 1950s. <a href="https://www.theverge.com/2020/4/14/21219561/coronavirus-pandemic-unemployment-systems-cobol-legacy-software-infrastructure"><u>At least a dozen</u></a> state unemployment systems still run on this sixty-one-year-old language, including ones that help administer funds of a billion dollars or more in California, Colorado, and New Jersey. When the deluge of unemployment claims hit, the havoc it seemed to wreak on COBOL systems was so widespread that many states apparently didn’t have enough programmers to repair the damage; the governor of New Jersey even publicly pleaded for the help of volunteers who knew the language.</p>
  72. <p>But then something strange happened. When scores of COBOL programmers rushed to offer their services, the state governments blaming COBOL didn’t accept the help. In fact, it turned out the states didn’t really need it to begin with. For many reasons, COBOL was an easy scapegoat in this crisis—but in reality what failed wasn’t the technology at all.</p>
  73. <p>
  74. </p>
  75. <h2>A “Dead” Language is Born</h2>
  76. <p>One of the most remarkable things about the unemployment claims malfunction wasn’t that things might suddenly go terribly wrong with COBOL systems, but that they never had before. Many computerized government and business processes around the world still run on and are actively written in COBOL—from the programs that reconcile almost every credit card transaction around the globe to the ones that administer a disability benefits system serving roughly ten million US veterans. The language remains so important that IBM’s latest, fastest “Z” series of mainframes have COBOL support as a key feature. </p>
  77. <p>For six decades, systems written in COBOL have proven highly robust—which is exactly what they were designed to be. COBOL was conceived in 1959, when a computer scientist named Mary Hawes, who worked in the electronics division of the business equipment manufacturer Burroughs, called for a meeting of computer professionals at the University of Pennsylvania. Hawes wanted to bring industry, government, and academic experts together to design a programming language for basic business functions, especially finance and accounting, that was easily adaptable to the needs of different organizations and portable between mainframes manufactured by different computer companies. </p>
  78. <p>The group that Hawes convened evolved into a body called CODASYL, the Conference on Data Systems Languages, which included computer scientists from the major computing hardware manufacturers of the time, as well as the government and the military. CODASYL set out to design a programming language that would be easier to use, easier to read, and easier to maintain than any other programming language then in existence. </p>
  79. <p>The committee’s central insight was to design the language using terms from plain English, in a way that was more self-explanatory than other languages. With COBOL, which stands for “Common Business-Oriented Language,” the goal was to make the code so readable that the program itself would document how it worked, allowing programmers to understand and maintain the code more easily.</p>
  80. <p>COBOL is a “problem-oriented” language, whose structure was designed around the goals of business and administrative users, instead of being maximally flexible for the kind of complex mathematical problems that scientific users would need to solve. The main architect of COBOL, Jean Sammet, then a researcher at Sylvania Electric and later a manager at IBM, wrote, “It was certainly intended (and expected) that the language could be used by novice programmers and read by management.” (Although the pioneering computer scientist Grace Hopper has often been referred to as the “mother of COBOL,” her involvement in developing the specification for the language was minimal; Sammet is the one who really deserves the title.)</p>
  81. <p>Other early high-level programming languages, such as FORTRAN, a language for performing complex mathematical functions, used idiosyncratic abbreviations and mathematical symbols that could be difficult to understand if you weren’t a seasoned user of the language. For example, while a FORTRAN program would require programmers to know mathematical formula notation, and write commands like:</p>
  82. <p><code>TOTAL = REAL(NINT(EARN * TAX * 100.0))/100.0</code></p>
  83. <p>users of COBOL could write the same command as: </p>
  84. <p><code>MULTIPLY EARNINGS BY TAXRATE GIVING SOCIAL-SECUR ROUNDED.</code></p>
  85. <p>As you can tell from the COBOL version, but probably not from the FORTRAN version, this line of code is a (simplified) example of how both languages could compute a social security payment and round the total to the penny. Because it was designed not just to be written but also to be read, COBOL would make computerized business processes more legible, both for the original programmers and managers and for those who maintained these systems long afterwards. </p>
  86. <figure>
  87. <img src="//images.ctfassets.net/e529ilab8frl/3cfhPIvZUdyHOCtsysKTJg/59b22629034cc6714266a25accbfa295/X572_85_COBOL_tombstone_0002.jpg" alt="A granite tombstone with a sheep on top, that reads COBOL.">
  88. <figcaption>Image of COBOL tombstone, copyright Mark Richards. Courtesy of the Computer History Museum in Mountain View, CA.</figcaption>
  89. </figure>
  90. <p></p>
  91. <p>A portable, easier-to-use programming language was a revolutionary idea for its time, and prefigured many of the programming languages that came after. Yet COBOL was almost pronounced dead even before it was born. In 1960, the year that the language’s specification was published, a member of the CODASYL committee named Howard Bromberg commissioned a little “<a href="https://www.computerhistory.org/revolution/early-computer-companies/5/117/2401"><u>COBOL tombstone</u></a>” as a practical joke. Bromberg, a manager at the electronics company RCA who had earlier worked with Grace Hopper on her FLOW-MATIC language, was concerned that by the time everybody finally got done designing COBOL, competitors working on proprietary languages would have swept the market, locking users into programming languages that might only run well on one manufacturer’s line of machines.</p>
  92. <p>But when COBOL came out in 1960, less than a year after Mary Hawes’s initial call to action, it was by no means dead on arrival. The earliest demonstrations of COBOL showed the language could be universal across hardware. “The significance of this,” Sammet wrote, with characteristic understatement, was that it meant “compatibility could really be achieved.” Suddenly, computer users had a full-featured cross-platform programming language of far greater power than anything that came before. COBOL was a runaway success. By 1970, it was the most widely used programming language in the world.</p>
  93. <p> </p>
  94. <h2>Scapegoats and Gatekeepers</h2>
  95. <p>Over the subsequent decades, billions and billions of lines of COBOL code were written, many of which are still running within financial institutions and government agencies today. The language has been continually improved and given new features. And yet, COBOL has been derided by many within the computer science field as a weak or simplistic language. Though couched in technical terms, these criticisms have drawn on a deeper source: the culture and gender dynamics of early computer programming.</p>
  96. <p>During the 1960s, as computer programming increasingly came to be regarded as a science, more and more men flooded into what had previously been a field dominated by women. Many of these men fancied themselves to be a cut above the programmers who came before, and they often perceived COBOL as inferior and unattractive, in part because it did not require abstruse knowledge of underlying computer hardware or a computer science qualification. Arguments about which languages and programming techniques were “best” were part of the field’s growing pains as new practitioners tried to prove their worth and professionalize what had been seen until the 1960s as rote, unintellectual, feminized work. Consciously or not, the last thing many male computer scientists entering the field wanted was to make the field easier to enter or code easier to read, which might undermine their claims to professional and “scientific” expertise. </p>
  97. <p>At first, however, the men needed help. Looking back, we see many examples of women teaching men how to program, before women gradually receded from positions of prominence in the field. Juliet Muro Oeffinger, one of about a dozen programmers I interviewed for this piece, began programming in assembly language in 1964 after graduating college with a BA in math. “When COBOL became the next hot thing,” she said, “I learned COBOL and taught it for Honeywell Computer Systems as a Customer Education Rep.” In the images below, Oeffinger teaches a room full of men at the Southern Indiana Gas and Electric Company how to program in the language. Within a short time, these trainees—who had no prior experience with computer work of any kind—would have been programming in COBOL.</p>
  98. <figure>
  99. <img src="//images.ctfassets.net/e529ilab8frl/2f3euaWiSR6eVdM9gNacdl/8f70b3bdbd1ed3d787e49de3e6bd6ba1/JulietOeffingerCOBOL2v2.jpg" alt="A black and white photo of four men in suits and a woman in a dress. The woman is drawing diagrams on the blackboard, while the men watch from a table filled with papers.">
  100. <figcaption></figcaption>
  101. </figure>
  102. <figure>
  103. <img src="//images.ctfassets.net/e529ilab8frl/58dqQzZleHZDc4PonQCCm4/cfd48181974bfa09059dd54726873dbb/JulietOeffingerCOBOL1v2.jpg" alt="A black and white photo of four men and one woman at a paper-filled desk with a chalkboard with diagrams in the background. The men wear suits and the woman is wearing a white shirt with a vest, possibly a dress.">
  104. <figcaption>Programmer Juliet Muro Oeffinger teaching students Gerald Griepenstroh, Ron Holander, Von Hale, and Ed Tombaugh how to program in COBOL c. 1967. Photos from the personal collection of Juliet Muro Oeffinger.</figcaption>
  105. </figure>
  106. <p></p>
  107. <p></p>
  108. <p>Another retired programmer I spoke to named Pam Foltz noted that good COBOL was great long-term infrastructure, because it was so transparent. Almost anyone with a decent grasp of programming could come into a COBOL system built by someone else decades earlier and understand how the code worked. Foltz had a long career as a programmer for financial institutions, retraining in COBOL soon after getting her BA in American studies from the University of North Carolina at Chapel Hill in the 1960s. Perhaps this dual background is one reason why her code was so readable; as one of her supervisors admiringly told her, “You write COBOL like a novel! Anyone could follow your code.” </p>
  109. <p>Ironically, this accessibility is one of the reasons that COBOL was denigrated. It is not simply that the language is old; so are many infrastructural programming languages. Take the C programming language: it was created in 1972, but as one of the current COBOL programmers I interviewed pointed out, nobody makes fun of it or calls it an “old dead language” the way people do with COBOL. Many interviewees noted that knowing COBOL is in fact a useful present-day skill that’s still taught in many community college computer science courses in the US, and many colleges around the world. </p>
  110. <p>But despite this, there’s a cottage industry devoted to making fun of COBOL precisely for its strengths. COBOL’s qualities of being relatively self-documenting, having a short onboarding period (though a long path to becoming an expert), and having been originally designed by committee for big, unglamorous, infrastructural business systems all count against it. So does the fact that it did not come out of a research-oriented context, like languages such as C, ALGOL, or FORTRAN.</p>
  111. <p>In a broader sense, hating COBOL was—and is—part of a struggle between consolidating and protecting computer programmers’ professional prestige on the one hand, and making programming less opaque and more accessible on the other. There’s an old joke among programmers: “If it was hard to write, it should be hard to read.” In other words, if your code is easy to understand, maybe you and your skills aren’t all that unique or valuable. If management thinks the tools you use and the code you write could be easily learned by anyone, you are eminently replaceable. </p>
  112. <p>The fear of this existential threat to computing expertise has become so ingrained in the field that many people don’t even see the preference for complex languages for what it is: an attempt to protect one’s status by favoring tools that gate-keep rather than those that assist newcomers. As one contemporary programmer, who works mainly in C++ and Java at IBM, told me, “Every new programming language that comes out that makes things simpler in some way is usually made fun of by some contingent of existing programmers as making programming too easy—or they say it’s not a ‘real language.’” Because Java, for example, included automatic memory management, it was seen as a less robust language, and the people who programmed in it were sometimes considered inferior programmers. “It's been going on forever,” said this programmer, who has been working in the field for close to thirty years. “It's about gatekeeping, and keeping one’s prestige and importance in the face of technological advancements that make it easier to be replaced by new people with easier to use tools.” Gatekeeping is not only done by people and institutions; it’s written into programming languages themselves.</p>
  113. <p>In a field that has elevated boy geniuses and rockstar coders, obscure hacks and complex black-boxed algorithms, it’s perhaps no wonder that a committee-designed language meant to be easier to learn and use—and which was created by a team that included multiple women in positions of authority—would be held in low esteem. But modern computing has started to become undone, and to undo other parts of our societies, through the field’s high opinion of itself, and through the way that it concentrates power into the hands of programmers who mistake social, political, and economic problems for technical ones, often with disastrous results.</p>
  114. <p>
  115. </p>
  116. <h2>The Labor of Care</h2>
  117. <p>A global pandemic in which more people than ever before are applying for unemployment is a situation that COBOL systems were never designed to handle, because a global catastrophe on this scale was never supposed to happen. And yet, even in the midst of this crisis, COBOL systems didn’t actually break down. Although New Jersey’s governor issued his desperate plea for COBOL programmers, <a href="https://www.wired.com/story/cant-file-unemployment-dont-blame-cobol/"><u>later investigations</u></a> revealed that it was the website through which people filed claims, written in the comparatively much newer programming language Java, that was responsible for the errors, breakdowns, and slowdowns. The backend system that processed those claims—the one written in COBOL—hadn’t been to blame at all.</p>
  118. <p>So why was COBOL framed as the culprit? It’s a common fiction that computing technologies tend to become obsolete in a matter of years or even months, because this sells more units of consumer electronics. But this has never been true when it comes to large-scale computing infrastructure. This misapprehension, and the language’s history of being disdained by an increasingly toxic programming culture, made COBOL an easy scapegoat. But the narrative that COBOL was to blame for recent failures undoes itself: scapegoating COBOL can’t get far when the code is in fact meant to be easy to read and maintain. </p>
  119. <p>That said, even the most robust systems need proper maintenance in order to fix bugs, add features, and interface with new computing technologies. Despite the essential functions they perform, many COBOL systems have not been well cared for. If they had come close to faltering in the current crisis, it wouldn’t have been because of the technology itself. Instead, it would have been due to the austerity logic to which so many state and local governments have succumbed.</p>
  120. <p>In order to care for technological infrastructure, we need maintenance engineers, not just systems designers—and that means paying for people, not just for products. COBOL was never meant to cut programmers out of the equation. But as state governments have moved to slash their budgets, they’ve been less and less inclined to pay for the labor needed to maintain critical systems. Many of the people who should have been on payroll to maintain and update the COBOL unemployment systems in states such as New Jersey have instead been laid off due to state budget cuts. As a result, those systems can become fragile, and in a crisis, they’re liable to collapse due to lack of maintenance. </p>
  121. <p>It was this austerity-driven lack of investment in people—rather than the handy fiction, peddled by state governments, that programmers with obsolete skills retired—that removed COBOL programmers years before this recent crisis. The reality is that there are plenty of new COBOL programmers out there who could do the job. In fact, the majority of people in the COBOL programmers’ Facebook group are twenty-five to thirty-five-years-old, and the number of people being trained to program and maintain COBOL systems globally is only growing. Many people who work with COBOL graduated in the 1990s or 2000s and have spent most of their twenty-first century careers maintaining and programming COBOL systems.  </p>
  122. <p>If the government programmers who were supposed to be around were still on payroll to maintain unemployment systems, there’s a very good chance that the failure of unemployment insurance systems to meet the life-or-death needs of people across the country wouldn't have happened. It’s likely those programmers would have needed to break out their Java skills to fix the issue, though. Because, despite the age of COBOL systems, when the crisis hit, COBOL trundled along, remarkably stable.</p>
  123. <p>Indeed, present-day tech could use more of the sort of resilience and accessibility that COBOL brought to computing—especially for systems that have broad impacts, will be widely used, and will be long-term infrastructure that needs to be maintained by many hands in the future. In this sense, COBOL and its scapegoating show us an important aspect of high tech that few in Silicon Valley, or in government, seem to understand. Older systems have value, and constantly building new technological systems for short-term profit at the expense of existing infrastructure is not progress. In fact, it is among the most regressive paths a society can take.</p>
  124. <p>As we stand in the middle of this pandemic, it is time for us to collectively rethink and recalculate the value that many so-called tech innovations, and innovators, bring to democracy. When these contributions are designed around monetizing flaws or gaps in existing economic, social, or political systems, rather than doing the mundane, plodding work of caring for and fixing the systems we all rely on, we end up with more problems than solutions, more scapegoats instead of insights into where we truly went wrong.</p>
  125. <p>There are analogies between the failure of state unemployment systems  and the failure of all sorts of public infrastructure: Hurricane Sandy hit the New York City subway system so hard because it, too, had been weakened by decades of disinvestment. Hurricane Katrina destroyed Black lives and neighborhoods in New Orleans because the levee maintenance work that was the responsibility of the federal government was far past due, a result of racist resource allocation. COVID-19 continues to ravage the United States more than any other nation because the federal infrastructure needed to confront public health crises has been hollowed for decades, and held in particular contempt by an Administration that puts profits over people, and cares little, if at all, about the predominantly Black and Latinx people in the US who are disproportionately dying. </p>
  126. <p>If we want to care for people in a pandemic, we also have to be willing to pay for the labor of care. This means the nurses and doctors who treat COVID patients; the students and teachers who require smaller, online classes to return to school; and the grocery workers who risk their lives every day. It also means making long-term investments in the engineers who care for the digital infrastructures that care for us in a crisis.</p>
  127. <p>When systems are built to last for decades, we often don’t see the disaster unfolding until the people who cared for those systems have been gone for quite some time. The blessing and the curse of good infrastructure is that when it works, it is invisible: which means that too often, we don’t devote much care to it until it collapses.</p>
  128. </article>
  129. <hr>
  130. <footer>
  131. <p>
  132. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  133. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-home"></use>
  134. </svg> Accueil</a> •
  135. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  136. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-rss2"></use>
  137. </svg> RSS</a> •
  138. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  139. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-user-tie"></use>
  140. </svg> Pro</a> •
  141. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  142. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-mail"></use>
  143. </svg> Email</a> •
  144. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  145. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-hammer2"></use>
  146. </svg> Légal</abbr>
  147. </p>
  148. <template id="theme-selector">
  149. <form>
  150. <fieldset>
  151. <legend><svg class="icon icon-brightness-contrast">
  152. <use xlink:href="/static/david/icons2/symbol-defs.svg#icon-brightness-contrast"></use>
  153. </svg> Thème</legend>
  154. <label>
  155. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  156. </label>
  157. <label>
  158. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  159. </label>
  160. <label>
  161. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  162. </label>
  163. </fieldset>
  164. </form>
  165. </template>
  166. </footer>
  167. <script>
  168. function loadThemeForm(templateName) {
  169. const themeSelectorTemplate = document.querySelector(templateName)
  170. const form = themeSelectorTemplate.content.firstElementChild
  171. themeSelectorTemplate.replaceWith(form)
  172. form.addEventListener('change', (e) => {
  173. const chosenColorScheme = e.target.value
  174. localStorage.setItem('theme', chosenColorScheme)
  175. toggleTheme(chosenColorScheme)
  176. })
  177. const selectedTheme = localStorage.getItem('theme')
  178. if (selectedTheme && selectedTheme !== 'undefined') {
  179. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  180. }
  181. }
  182. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  183. window.addEventListener('load', () => {
  184. let hasDarkRules = false
  185. for (const styleSheet of Array.from(document.styleSheets)) {
  186. let mediaRules = []
  187. for (const cssRule of styleSheet.cssRules) {
  188. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  189. continue
  190. }
  191. // WARNING: Safari does not have/supports `conditionText`.
  192. if (cssRule.conditionText) {
  193. if (cssRule.conditionText !== prefersColorSchemeDark) {
  194. continue
  195. }
  196. } else {
  197. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  198. continue
  199. }
  200. }
  201. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  202. }
  203. // WARNING: do not try to insert a Rule to a styleSheet you are
  204. // currently iterating on, otherwise the browser will be stuck
  205. // in a infinite loop…
  206. for (const mediaRule of mediaRules) {
  207. styleSheet.insertRule(mediaRule.cssText)
  208. hasDarkRules = true
  209. }
  210. }
  211. if (hasDarkRules) {
  212. loadThemeForm('#theme-selector')
  213. }
  214. })
  215. </script>
  216. </body>
  217. </html>