Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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` element
  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>
  13. uMap&nbsp;2
  14. — David Larlet</title>
  15. <script>
  16. function toggleTheme(themeName) {
  17. document.documentElement.classList.toggle(
  18. 'forced-dark',
  19. themeName === 'dark'
  20. )
  21. document.documentElement.classList.toggle(
  22. 'forced-light',
  23. themeName === 'light'
  24. )
  25. }
  26. const selectedTheme = localStorage.getItem('theme')
  27. if (selectedTheme !== 'undefined') {
  28. toggleTheme(selectedTheme)
  29. }
  30. </script>
  31. <!-- Documented, feel free to shoot an email. -->
  32. <link rel="stylesheet" href="/static/david/css/style_2024-03-09.css">
  33. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  34. <link rel="preload"
  35. href="/static/david/css/fonts/century_supra_ot_a_regular.woff2"
  36. as="font"
  37. type="font/woff2"
  38. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  39. crossorigin>
  40. <link rel="preload"
  41. href="/static/david/css/fonts/century_supra_ot_a_bold.woff2"
  42. as="font"
  43. type="font/woff2"
  44. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  45. crossorigin>
  46. <link rel="preload"
  47. href="/static/david/css/fonts/century_supra_ot_a_italic.woff2"
  48. as="font"
  49. type="font/woff2"
  50. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  51. crossorigin>
  52. <link rel="preload"
  53. href="/static/david/css/fonts/century_supra_ot_b_regular.woff2"
  54. as="font"
  55. type="font/woff2"
  56. media="(prefers-color-scheme: dark)"
  57. crossorigin>
  58. <link rel="preload"
  59. href="/static/david/css/fonts/century_supra_ot_b_bold.woff2"
  60. as="font"
  61. type="font/woff2"
  62. media="(prefers-color-scheme: dark)"
  63. crossorigin>
  64. <link rel="preload"
  65. href="/static/david/css/fonts/century_supra_ot_b_italic.woff2"
  66. as="font"
  67. type="font/woff2"
  68. media="(prefers-color-scheme: dark)"
  69. crossorigin>
  70. <meta name="description" content="But it’s deeper that that. Open source is good for humanity. It’s only slightly hyperbolic to say that open source is one of the most notable collective successes of humankind as a species! It’s one of the few places where essentially all of humanity works together on something that benefits everyone. A world without open source would be substantially worse than the world we live in.">
  71. <!-- That good ol' feed, subscribe :). -->
  72. <link rel="alternate"
  73. type="application/atom+xml"
  74. title="Feed"
  75. href="/david/log/">
  76. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  77. <link rel="apple-touch-icon"
  78. sizes="180x180"
  79. href="/static/david/icons2/apple-touch-icon.png">
  80. <link rel="icon"
  81. type="image/png"
  82. sizes="32x32"
  83. href="/static/david/icons2/favicon-32x32.png">
  84. <link rel="icon"
  85. type="image/png"
  86. sizes="16x16"
  87. href="/static/david/icons2/favicon-16x16.png">
  88. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  89. <link rel="mask-icon"
  90. href="/static/david/icons2/safari-pinned-tab.svg"
  91. color="#07486c">
  92. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  93. <meta name="msapplication-TileColor" content="#f7f7f7">
  94. <meta name="msapplication-config"
  95. content="/static/david/icons2/browserconfig.xml">
  96. <meta name="theme-color"
  97. content="#f7f7f7"
  98. media="(prefers-color-scheme: light)">
  99. <meta name="theme-color"
  100. content="#272727"
  101. media="(prefers-color-scheme: dark)">
  102. <!-- Is that even respected? Retrospectively? What a shAItshow…
  103. https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ -->
  104. <meta name="robots" content="noai, noimageai">
  105. <style type="text/css">
  106. .tippy-content {
  107. min-width: 280px;
  108. padding: .5rem;
  109. font-size: calc(var(--fluid-0) * 0.8);
  110. font-family: var(--labor-font);
  111. letter-spacing: initial;
  112. text-align: left;
  113. }
  114. .tippy-content h3 {
  115. margin-top: 0;
  116. }
  117. .tippy-content h3 img {
  118. max-width: 2rem;
  119. max-height: 2rem;
  120. display: inline-block;
  121. }
  122. .tippy-content .tippy-links {
  123. display: flex;
  124. justify-content: space-around;
  125. }
  126. .tippy-content a {
  127. padding: .4rem;
  128. color: #F06048;
  129. }
  130. </style>
  131. <body data-instant-intensity="viewport-all">
  132. <article>
  133. <header>
  134. <hgroup>
  135. <h1>uMap&nbsp;2</h1>
  136. <p>Le <time datetime="2024-02-16">16 février 2024</time></p>
  137. </hgroup>
  138. </header>
  139. <nav>
  140. <p>
  141. <a rel="prev"
  142. href="/david/2024/02/15/"
  143. title="Publication précédente : Licence">← Précédent</a> •
  144. <a href="/david/" title="Aller à l’accueil" rel="up">Accueil</a>
  145. <a href="/david/recherche/"
  146. title="Aller à la page de recherche"
  147. rel="search" data-no-instant>Recherche</a>
  148. • <a rel="next"
  149. href="/david/2024/02/17/"
  150. title="Publication suivante : Quotidien">Suivant →</a>
  151. </p>
  152. </nav>
  153. <blockquote lang="en">
  154. <p>But it’s deeper that that. Open source is <em>good for humanity</em>. It’s only slightly hyperbolic to say that <mark>open source is one of the most notable collective successes</mark> of humankind as a species! It’s one of the few places where essentially all of humanity works together on something that benefits everyone. A world without open source would be substantially worse than the world we live&nbsp;in.</p>
  155. <p><cite><em><a data-link-domain="jacobian.org" href="https://jacobian.org/2024/feb/16/paying-maintainers-is-good/" hreflang="en"
  156. title="Consultation de l’article (anglais)">Paying people to work on open source is good actually</a>
  157. <a href="/david/cache/2024/ad0648259b032d4d0e5a9e6220c3c71e/" hreflang="en"
  158. data-tippy data-description="If you have a problem with maintainers getting paid then you have a problem with me and I suggest you let that one marinate."
  159. data-source="https://jacobian.org/2024/feb/16/paying-maintainers-is-good/"
  160. data-date="2024-02-17"
  161. data-favicon="https://jacobian.org/favicon.ico"
  162. data-domain="jacobian.org"
  163. ><svg xmlns="http://www.w3.org/2000/svg"
  164. width="24" height="24" viewBox="0 0 24 24" fill="none"
  165. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  166. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  167. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  168. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  169. </svg>
  170. <span class="sr-only">[archive]</span></a></em></cite></p>
  171. </blockquote>
  172. <p>J’ai déjà parlé <a href="/david/2024/01/18/" title="Open-source">d’open-source</a>, de <a href="/david/2024/01/31/" title="Mécénat">mécénat</a>, de <a href="/david/2024/02/09/" title="Version">versions</a>, de <a href="/david/2024/02/15/" title="Licence">licences</a>, mais comment se passe une <em>release</em> de produit&nbsp;open-source&#8239;?</p>
  173. <p>On commence à avoir affiné et <a data-link-domain="docs.umap-project.org" href="https://docs.umap-project.org/en/master/release/">documenté le processus</a>, on a <a data-link-domain="github.com" href="https://github.com/umap-project/umap-deploy-osmfr">des scripts dédiés</a> pour arriver à cela lorsque le moment est venu et nous sommes pour l’instant 2&nbsp;à pouvoir faire cela de bout en bout avec <a data-link-domain="yohanboniface.me" href="https://yohanboniface.me/">Yohan</a>. C’est peu mais c’est aussi +100% par rapport à l’année&nbsp;dernière…</p>
  174. <p>Nous n’étions pas très loin de repousser encore une fois la version&nbsp;2&nbsp;car il y avait un dernier changement majeur à faire passer. Tiraillés, nous avons repoussé cela à une version&nbsp;3&nbsp;quitte à ce qu’elle arrive prochainement. Franchir cette barrière psychologique était important pour la suite. Le faire en visio de bout en bout (comme une bonne partie de nos interactions sur le produit) était enthousiasmant. En bonus, c’était un vendredi&nbsp;après-midi.</p>
  175. <p>Voilà donc <a data-link-domain="docs.umap-project.org" href="https://docs.umap-project.org/en/master/changelog/#200-2024-02-16">un <em>changelog</em></a> déjà bien chargé. Nous nous sommes rendu compte au cours du processus que le versionnement était davantage pertinent pour les mainteneur·euses que pour les utilisateur·ices. Les fonctionnalités sont ajoutées au compte-goutte mais il faut prévenir les personnes qui vont mettre à jour l’outil de ce qui pourrait coincer lors du déploiement. Certains changements ont été volontaires (modules ESM =&gt; support navigateurs), d’autres contraints (fin du support de l’authification OpenStreetMap OAuth1), d’autres subis (Django&nbsp;5 =&gt; Python 3.10). Un beau&nbsp;mélange.</p>
  176. <p>Je ne vais rien annoncer pour une version&nbsp;3&nbsp;car ce serait ajouter une pression inutile et même si on a des intuitions tout est loin d’être priorisé. Dans mes motivations <em>personnelles</em>&nbsp;:</p>
  177. <ul>
  178. <li>aller vers une amélioration de&nbsp;l’accessibilité&#8239;;</li>
  179. <li>voir les <a data-link-domain="blog.notmyidea.org" href="https://blog.notmyidea.org/tag/umap.html">explorations d’Alexis</a> prendre&nbsp;forme&#8239;;</li>
  180. <li>clarifier les lieux de support / documentation en participant&nbsp;davantage.</li>
  181. </ul>
  182. <blockquote lang="en">
  183. <p>We have to accept the world as it is – even if it’s not the world we want. This means we have to be okay with the idea that maintainers need to be paid. Far too often I see arguments like: “<mark>maintainers shouldn’t be paid by private companies because the government should be supporting them.</mark>” Sure, this sounds great – but <em>governments aren’t doing this!</em> So this argument reduces to “open source maintainers shouldn’t be paid”. I can’t get on board with&nbsp;that.</p>
  184. <p><cite><em>Ibid.</em></cite></p>
  185. </blockquote>
  186. <p>Étant actuellement payé par l’Agence nationale de la cohésion des territoires pour participer à de l’<em>open-source</em>, je ne peux qu’approuver cette partie de la citation et être heureux de me trouver là où je suis. Les exceptions existent grâce à une conjonction de volontés, de privilèges et de coups de&nbsp;bol.</p>
  187. <a href="#hr-73" title="Lien vers cette section de la page"><hr id="hr-73" /></a>
  188. <blockquote lang="en">
  189. <p><a data-link-domain="github.com" href="https://github.com/astral-sh/uv">uv</a> represents a milestone in our pursuit of a “<a data-link-domain="blog.rust-lang.org" href="https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo">Cargo for Python</a>”: a comprehensive Python project and package manager that’s fast, reliable, and easy to&nbsp;use.</p>
  190. <p><cite><em><a data-link-domain="astral.sh" href="https://astral.sh/blog/uv" hreflang="en"
  191. title="Consultation de l’article (anglais)">uv: Python packaging in Rust</a>
  192. <a href="/david/cache/2024/359df603dbf60e8476027b2eb26cb7ce/" hreflang="en"
  193. data-tippy data-description="uv is an extremely fast Python package installer and resolver, designed as a drop-in alternative to pip and pip-tools."
  194. data-source="https://astral.sh/blog/uv"
  195. data-date="2024-02-17"
  196. data-favicon="https://astral.sh/static/favicon-32x32.png"
  197. data-domain="astral.sh"
  198. ><svg xmlns="http://www.w3.org/2000/svg"
  199. width="24" height="24" viewBox="0 0 24 24" fill="none"
  200. stroke="currentColor" stroke-width="2" stroke-linecap="square"
  201. stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle>
  202. <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
  203. <line x1="12" y1="17" x2="12.01" y2="17"></line>
  204. </svg>
  205. <span class="sr-only">[archive]</span></a></em></cite></p>
  206. </blockquote>
  207. <p>Un futur de Python se dessine et j’en apprécie les&nbsp;esquisses.</p>
  208. <nav>
  209. <p>
  210. <a href="/david/2024/commun/"
  211. title="Liste de tous les articles 2024 associés à cette étiquette"
  212. rel="tag">#commun</a>
  213. <a href="/david/2024/decision/"
  214. title="Liste de tous les articles 2024 associés à cette étiquette"
  215. rel="tag">#décision</a>
  216. <a href="/david/2024/opensource/"
  217. title="Liste de tous les articles 2024 associés à cette étiquette"
  218. rel="tag">#opensource</a>
  219. <a href="/david/2024/#tags" title="Liste de toutes les étiquettes 2024">tous ?</a>
  220. </p>
  221. </nav>
  222. <nav>
  223. <p>
  224. <a rel="prev"
  225. href="/david/2024/02/15/"
  226. title="Publication précédente : Licence">← Précédent</a> •
  227. <a href="/david/2024/" title="Liste des publications récentes">↑ En 2024</a>
  228. • <a rel="next"
  229. href="/david/2024/02/17/"
  230. title="Publication suivante : Quotidien">Suivant →</a>
  231. </p>
  232. </nav>
  233. <form action="/david/recherche/" method="get">
  234. <fieldset>
  235. <legend>Recherche</legend>
  236. <label for="input-search">Termes de votre recherche :</label>
  237. <input id="input-search" type="search" name="s" aria-describedby="indexation-infos" required>
  238. <input type="submit" value="Chercher">
  239. <p id="indexation-infos">
  240. <small>
  241. Seuls les contenus de ces 8 dernières années sont indexés.
  242. </small>
  243. </p>
  244. </fieldset>
  245. </form>
  246. <aside>
  247. <theme-toggle></theme-toggle>
  248. </aside>
  249. </article>
  250. <hr>
  251. <footer>
  252. <p>
  253. <a href="/david/" title="Aller à l’accueil">Accueil</a>
  254. <a href="/david/log/" title="Accès au flux RSS">Suivre</a>
  255. <a href="http://larlet.com"
  256. title="Go to my English profile"
  257. data-instant>Pro</a>
  258. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Email</a>
  259. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">Légal</abbr>
  260. </p>
  261. <template id="theme-selector">
  262. <form>
  263. <style type="text/css">
  264. fieldset div {
  265. text-align: center;
  266. }
  267. </style>
  268. <fieldset>
  269. <legend>Thème</legend>
  270. <div>
  271. <label>
  272. <input type="radio" value="auto" name="chosen-color-scheme" checked>
  273. Auto
  274. </label>
  275. <label>
  276. <input type="radio" value="dark" name="chosen-color-scheme">
  277. Foncé
  278. </label>
  279. <label>
  280. <input type="radio" value="light" name="chosen-color-scheme">
  281. Clair
  282. </label>
  283. </div>
  284. </fieldset>
  285. </form>
  286. </template>
  287. </footer>
  288. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  289. <script>
  290. class ThemeToggle extends HTMLElement {
  291. constructor() {
  292. super()
  293. const themeSelectorTemplate = document.querySelector('#theme-selector')
  294. const form = themeSelectorTemplate.content.firstElementChild
  295. this.attachShadow({ mode: 'open' })
  296. this.shadowRoot.appendChild(form.cloneNode(true))
  297. }
  298. connectedCallback() {
  299. const form = this.shadowRoot.querySelector('form')
  300. form.addEventListener('change', (e) => {
  301. const chosenColorScheme = e.target.value
  302. localStorage.setItem('theme', chosenColorScheme)
  303. toggleTheme(chosenColorScheme)
  304. })
  305. const selectedTheme = localStorage.getItem('theme')
  306. if (selectedTheme && selectedTheme !== 'undefined') {
  307. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  308. }
  309. }
  310. }
  311. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  312. window.addEventListener('load', () => {
  313. let colorsLayer = undefined
  314. let hasDarkRules = false
  315. for (const styleSheet of Array.from(document.styleSheets)) {
  316. let mediaRules = []
  317. for (const layerRule of styleSheet.cssRules) {
  318. if (!(layerRule instanceof CSSLayerBlockRule)) {
  319. continue
  320. }
  321. if (layerRule.name === 'colors') {
  322. colorsLayer = layerRule
  323. }
  324. for (const cssRule of layerRule.cssRules) {
  325. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  326. continue
  327. }
  328. // WARNING: Safari does not have/supports `conditionText`.
  329. if (cssRule.conditionText) {
  330. if (cssRule.conditionText !== prefersColorSchemeDark) {
  331. continue
  332. }
  333. } else {
  334. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  335. continue
  336. }
  337. }
  338. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  339. }
  340. }
  341. // WARNING: do not try to insert a Rule to a styleSheet you are
  342. // currently iterating on, otherwise the browser will be stuck
  343. // in a infinite loop…
  344. for (const mediaRule of mediaRules) {
  345. // Safari requires the `0` second parameter (even if default).
  346. colorsLayer.insertRule(mediaRule.cssText, 0)
  347. hasDarkRules = true
  348. }
  349. }
  350. if (hasDarkRules) {
  351. if ('customElements' in window && !customElements.get('theme-toggle')) {
  352. customElements.define('theme-toggle', ThemeToggle)
  353. }
  354. }
  355. })
  356. </script>
  357. <script src="/static/david/js/popper-2.11.8.min.js"></script>
  358. <script src="/static/david/js/tippy-bundle-6.3.7.umd.min.js"></script>
  359. <script>
  360. tippy('[data-tippy]', {
  361. content(reference) {
  362. reference.addEventListener('click', (e) => e.preventDefault())
  363. return `
  364. <h3 lang="fr">
  365. <img src="${reference.dataset.favicon}" loading="lazy">
  366. <a href="${reference.dataset.source}"
  367. >Article sur ${reference.dataset.domain}</a></h3>
  368. <p lang="${reference.hreflang}"><em>${reference.dataset.description}</em></p>
  369. <div class="tippy-links" lang="fr">
  370. <a href="${reference.href}">Archive au ${reference.dataset.date}</a>
  371. </div>
  372. `
  373. },
  374. allowHTML: true,
  375. interactive: true,
  376. delay: [150, 700],
  377. hideOnClick: false
  378. })
  379. </script>
  380. <script type="module">
  381. import { annotate } from '/static/david/js/rough-notation-0.5.1.esm.min.js'
  382. const markObserver = new IntersectionObserver((entries, observer) => {
  383. const computedStyle = getComputedStyle(document.documentElement)
  384. const markBackground = computedStyle.getPropertyValue('--mark-background')
  385. for (const entry of entries) {
  386. if (entry.intersectionRatio === 0) continue
  387. const markElement = entry.target
  388. const annotation = annotate(
  389. markElement, {
  390. type: 'highlight',
  391. multiline: true,
  392. color: markBackground,
  393. animate: !window.matchMedia('(prefers-reduced-motion: reduce)').matches
  394. }
  395. )
  396. annotation.show()
  397. observer.unobserve(markElement)
  398. }
  399. }, {threshold: 1.0})
  400. for (const markElement of document.querySelectorAll('mark')) {
  401. markElement.style.backgroundColor = 'inherit'
  402. markObserver.observe(markElement)
  403. }
  404. </script>
  405. </body>
  406. </html>