Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=en>
  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,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Github and money — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <!-- Canonical URL for SEO purposes -->
  28. <link rel="canonical" href="https://larlet.fr/david/stream/2018/02/25/">
  29. <style>
  30. /* http://meyerweb.com/eric/tools/css/reset/ */
  31. html, body, div, span,
  32. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  33. a, abbr, address, big, cite, code,
  34. del, dfn, em, img, ins,
  35. small, strike, strong, tt, var,
  36. dl, dt, dd, ol, ul, li,
  37. fieldset, form, label, legend,
  38. table, caption, tbody, tfoot, thead, tr, th, td,
  39. article, aside, canvas, details, embed,
  40. figure, figcaption, footer, header, hgroup,
  41. menu, nav, output, ruby, section, summary,
  42. time, mark, audio, video {
  43. margin: 0;
  44. padding: 0;
  45. border: 0;
  46. font-size: 100%;
  47. font: inherit;
  48. vertical-align: baseline;
  49. }
  50. /* HTML5 display-role reset for older browsers */
  51. article, aside, details, figcaption, figure,
  52. footer, header, hgroup, menu, nav, section { display: block; }
  53. body { line-height: 1; }
  54. blockquote, q { quotes: none; }
  55. blockquote:before, blockquote:after,
  56. q:before, q:after {
  57. content: '';
  58. content: none;
  59. }
  60. table {
  61. border-collapse: collapse;
  62. border-spacing: 0;
  63. }
  64. /* http://practicaltypography.com/equity.html */
  65. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  66. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  67. @font-face {
  68. font-family: 'EquityTextB';
  69. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  70. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  71. font-weight: 300;
  72. font-style: normal;
  73. font-display: swap;
  74. }
  75. @font-face {
  76. font-family: 'EquityTextB';
  77. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  78. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  79. font-weight: 300;
  80. font-style: italic;
  81. font-display: swap;
  82. }
  83. @font-face {
  84. font-family: 'EquityTextB';
  85. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  86. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  87. font-weight: 700;
  88. font-style: normal;
  89. font-display: swap;
  90. }
  91. @font-face {
  92. font-family: 'TriplicateT4c';
  93. src: url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff2') format('woff2'),
  94. url('/static/david/css/fonts/Triplicate-T4-Code-Regular-webfont.woff') format('woff');
  95. font-weight: 300;
  96. font-style: normal;
  97. font-display: swap;
  98. }
  99. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  100. body {
  101. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  102. font-family: "EquityTextB", Palatino, serif;
  103. background-color: #f0f0ea;
  104. color: #07486c;
  105. font-kerning: normal;
  106. -moz-osx-font-smoothing: grayscale;
  107. -webkit-font-smoothing: subpixel-antialiased;
  108. text-rendering: optimizeLegibility;
  109. font-variant-ligatures: common-ligatures contextual;
  110. font-feature-settings: "kern", "liga", "clig", "calt";
  111. }
  112. pre, code, kbd, samp, var, tt {
  113. font-family: 'TriplicateT4c', monospace;
  114. }
  115. em {
  116. font-style: italic;
  117. color: #323a45;
  118. }
  119. strong {
  120. font-weight: bold;
  121. color: black;
  122. }
  123. nav {
  124. background-color: #323a45;
  125. color: #f0f0ea;
  126. display: flex;
  127. justify-content: space-around;
  128. padding: 1rem .5rem;
  129. }
  130. nav:first-child {
  131. border-top: 1vh solid #2d7474;
  132. }
  133. nav:last-child {
  134. border-bottom: 1vh solid #2d7474;
  135. }
  136. nav a {
  137. color: #f0f0ea;
  138. }
  139. nav abbr {
  140. border-bottom: 1px dotted white;
  141. }
  142. h1 {
  143. border-bottom: .2vh solid #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 2rem 0 1rem;
  148. width: 100%;
  149. }
  150. h2 {
  151. margin: 4rem 0 1rem;
  152. border-top: .2vh solid #2d7474;
  153. }
  154. h3 {
  155. text-align: center;
  156. margin: 3rem 0 .75em;
  157. }
  158. hr {
  159. height: .4rem;
  160. width: .4rem;
  161. border-radius: .4rem;
  162. background: #07486c;
  163. margin: 2.5rem auto;
  164. }
  165. time {
  166. display: bloc;
  167. background-color: #2d7474;
  168. color: #e3e1e1;
  169. padding: .29rem 1rem;
  170. float: right;
  171. }
  172. ul, ol {
  173. margin: 2rem;
  174. }
  175. ul {
  176. list-style-type: square;
  177. }
  178. a {
  179. text-decoration-skip-ink: auto;
  180. }
  181. article {
  182. max-width: 50rem;
  183. display: flex;
  184. flex-direction: column;
  185. margin: 3rem auto 1rem auto;
  186. }
  187. article p:last-child {
  188. margin-bottom: 1rem;
  189. }
  190. p {
  191. padding: 0 .5rem;
  192. }
  193. p + p {
  194. margin-top: 2rem;
  195. }
  196. blockquote {
  197. background-color: #e3e1e1;
  198. border-left: .5vw solid #2d7474;
  199. display: flex;
  200. flex-direction: column;
  201. align-items: center;
  202. padding: 1rem;
  203. margin: 1.5rem;
  204. }
  205. blockquote cite {
  206. font-style: italic;
  207. }
  208. figure {
  209. border-top: .2vh solid #2d7474;
  210. background-color: #e3e1e1;
  211. text-align: center;
  212. padding: 1.5rem 0;
  213. margin: 1rem 0 0;
  214. font-size: 1.5rem;
  215. width: 100%;
  216. }
  217. figure img {
  218. width: 250px;
  219. height: 250px;
  220. border: .5vw solid #323a45;
  221. padding: 1px;
  222. }
  223. figcaption {
  224. padding: 1rem;
  225. line-height: 1.4;
  226. }
  227. aside {
  228. display: flex;
  229. flex-direction: column;
  230. background-color: #e3e1e1;
  231. padding: 1rem 0;
  232. border-bottom: .2vh solid #07486c;
  233. }
  234. aside p {
  235. max-width: 50rem;
  236. margin: 0 auto;
  237. }
  238. /* https://fvsch.com/code/css-locks/ */
  239. p, li, pre, code, kbd, samp, var, tt, time {
  240. font-size: .95rem;
  241. line-height: calc( 1.5em + 0.2 * 1rem );
  242. }
  243. h1 {
  244. font-size: 1.7rem;
  245. line-height: calc( 1.2em + 0.2 * 1rem );
  246. }
  247. h2 {
  248. font-size: 1.6rem;
  249. line-height: calc( 1.3em + 0.2 * 1rem );
  250. }
  251. h3 {
  252. font-size: 1.35rem;
  253. line-height: calc( 1.4em + 0.2 * 1rem );
  254. }
  255. @media (min-width: 20em) {
  256. /* The (100vw - 20rem) / (50 - 20) part
  257. resolves to 0-1rem, depending on the
  258. viewport width (between 20em and 50em). */
  259. p, li, pre, code, kbd, samp, var, tt, time {
  260. font-size: calc( .95rem + .6 * (100vw - 20rem) / (50 - 20) );
  261. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  262. }
  263. h1 {
  264. font-size: calc( 1.7rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  265. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  266. }
  267. h2 {
  268. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  269. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  270. }
  271. h3 {
  272. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  273. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  274. }
  275. }
  276. @media (min-width: 50em) {
  277. /* The right part of the addition *must* be a
  278. rem value. In this example we *could* change
  279. the whole declaration to font-size:2.5rem,
  280. but if our baseline value was not expressed
  281. in rem we would have to use calc. */
  282. p, li, pre, code, kbd, samp, var, tt, time {
  283. font-size: calc( .95rem + .6 * 1rem );
  284. line-height: 1.5em;
  285. }
  286. h1 {
  287. font-size: calc( 1.7rem + 1.5 * 1rem );
  288. line-height: 1.2em;
  289. }
  290. h2 {
  291. font-size: calc( 1.5rem + 1.5 * 1rem );
  292. line-height: 1.3em;
  293. }
  294. h3 {
  295. font-size: calc( 1.35rem + 1.5 * 1rem );
  296. line-height: 1.4em;
  297. }
  298. figure img {
  299. width: 500px;
  300. height: 500px;
  301. }
  302. blockquote {
  303. margin-left: -1.5rem;
  304. }
  305. }
  306. figure.unsquared {
  307. margin-bottom: 1.5rem;
  308. }
  309. figure.unsquared img {
  310. height: inherit;
  311. }
  312. /* https://github.com/richleland/pygments-css */
  313. .codehilite{
  314. background-color: #fdf6e3;
  315. margin: 1rem auto;
  316. padding: 1rem;
  317. overflow-x:auto;
  318. box-shadow:inset 0 0 2px rgba(0,0,0,0.2)
  319. }
  320. .codehilite .t{color:#586e75}
  321. .codehilite .w{color:#073642}
  322. .codehilite .err{color:#cb4b16}
  323. .codehilite .k{color:#859900}
  324. .codehilite .kc{color:#2aa198}
  325. .codehilite .kd{color:#268bd2}
  326. .codehilite .kn{color:#b58900}
  327. .codehilite .kp{color:#859900}
  328. .codehilite .kr{color:#073642}
  329. .codehilite .kt{color:#b58900}
  330. .codehilite .n{color:#586e75}
  331. .codehilite .na{color:#2aa198}
  332. .codehilite .nb{color:#268bd2}
  333. .codehilite .nc{color:#268bd2}
  334. .codehilite .ne{color:#cb4b16}
  335. .codehilite .no{color:#2aa198}
  336. .codehilite .nd{color:#2aa198}
  337. .codehilite .ni{color:#2aa198;font-weight:bold}
  338. .codehilite .nf{color:#268bd2}
  339. .codehilite .nn{color:#586e75}
  340. .codehilite .nt{color:#2aa198;font-weight:bold}
  341. .codehilite .nv{color:#cb4b16}
  342. .codehilite .b{color:#859900}
  343. .codehilite .bp{color:#586e75}
  344. .codehilite .v{color:#586e75}
  345. .codehilite .vc{color:#586e75}
  346. .codehilite .vg{color:#268bd2}
  347. .codehilite .vi{color:#268bd2}
  348. .codehilite .m{color:#268bd2}
  349. .codehilite .mf{color:#268bd2}
  350. .codehilite .mh{color:#268bd2}
  351. .codehilite .mi{color:#268bd2}
  352. .codehilite .mo{color:#268bd2}
  353. .codehilite .s{color:#2aa198}
  354. .codehilite .sb{color:#2aa198}
  355. .codehilite .sc{color:#2aa198}
  356. .codehilite .sd{color:#2aa198}
  357. .codehilite .s2{color:#2aa198}
  358. .codehilite .se{color:#cb4b16}
  359. .codehilite .sh{color:#2aa198}
  360. .codehilite .si{color:#cb4b16}
  361. .codehilite .sx{color:#2aa198}
  362. .codehilite .sr{color:#cb4b16}
  363. .codehilite .s1{color:#2aa198}
  364. .codehilite .ss{color:#cb4b16}
  365. .codehilite .il{color:#268bd2}
  366. .codehilite .o{color:#586e75}
  367. .codehilite .ow{color:#859900}
  368. .codehilite .p{color:#586e75}
  369. .codehilite .c{color:#93a1a1;font-style:italic}
  370. .codehilite .cm{color:#93a1a1}
  371. .codehilite .cp{color:#93a1a1}
  372. .codehilite .c1{color:#93a1a1}
  373. .codehilite .cs{color:#93a1a1}
  374. .codehilite .hll{background-color:#dc322f}
  375. .codehilite .g{color:#586e75}
  376. .codehilite .gd{color:#586e75}
  377. .codehilite .ge{font-style:italic}
  378. .codehilite .gr{color:#586e75}
  379. .codehilite .gh{color:#586e75;font-weight:bold}
  380. .codehilite .gi{color:#586e75}
  381. .codehilite .go{color:#586e75}
  382. .codehilite .gp{color:#586e75}
  383. .codehilite .gs{font-weight:bold}
  384. .codehilite .gu{color:#586e75;font-weight:bold}
  385. .codehilite .gt{color:#586e75}
  386. @media print {
  387. body { font-size: 100%; }
  388. a:after { content: " (" attr(href) ")"; }
  389. a, a:link, a:visited, a:after {
  390. text-decoration: underline;
  391. text-shadow: none !important;
  392. background-image: none !important;
  393. background: white;
  394. color: black;
  395. }
  396. abbr[title] { border-bottom: 0; }
  397. abbr[title]:after { content: " (" attr(title) ")"; }
  398. img { page-break-inside: avoid; }
  399. @page { margin: 2cm .5cm; }
  400. h1, h2, h3 { page-break-after: avoid; }
  401. p3 { orphans: 3; widows: 3; }
  402. img {
  403. max-width: 250px !important;
  404. max-height: 250px !important;
  405. }
  406. nav, aside { display: none; }
  407. }
  408. /* Dark theme */
  409. [lang=en] body {
  410. background: #323a45;
  411. }
  412. [lang=en] article,
  413. [lang=en] article em,
  414. [lang=en] article strong {
  415. color: #f0f0ea;
  416. }
  417. [lang=en] article a {
  418. color: #ffbd2b;
  419. }
  420. [lang=en] article a:visited {
  421. color: #ff6b03;
  422. }
  423. [lang=en] blockquote,
  424. [lang=en] figure {
  425. background: #111930;
  426. color: #ccc;
  427. }
  428. </style>
  429. <nav>
  430. <p>
  431. <a href="/david/" title="Profil public">David&nbsp;Larlet</a> partage ses <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et sa <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a>.
  432. </p>
  433. </nav>
  434. <h1>Github and money</h1>
  435. <time>2018-02-25</time>
  436. <article>
  437. <blockquote>
  438. <p>I’m going to make a bold statement:</p>
  439. <p>Github having a [Buy A License] button would be the equivalent business move that Adwords was for Google. It’d turn the company from barely making it to a giant in the software world.</p>
  440. <p>The reason is the same as with Adwords:</p>
  441. <p>The real money is in helping other people make money and skimming off the top.</p>
  442. <p>Facilitating developers making a living off their projects would turn FLOSS into a viable career option rather than a stressful non-hobby begging for survival</p>
  443. <p>The simple buttons break down to:</p>
  444. <ul>
  445. <li>
  446. <p>Buy A License: Purchase a commercial license and long term support. This is MRR for the project.</p>
  447. </li>
  448. <li>
  449. <p>Buy Support: Get help on a single problem or bug you need solved now. This is a one time payment.</p>
  450. </li>
  451. </ul>
  452. <p>And if you’re worry about money killing the soul of open source remember this:</p>
  453. <p>You’re expected to act professionally just like a business, but for free. If people want you to act like a business and not an art project, then you should be paid like one.</p>
  454. <p>That means the contact changed. It used to be you make something you feel like making and maybe people help but you have creative freedom.</p>
  455. <p>Now you’re expected to be professional, but still paid like you’re doing a hobby. That’s wrong.</p>
  456. <p>You want professionalism? You need to pay.</p>
  457. <p>However, I believe that the <em>reason</em> github doesn’t enable this and even works against FLOSS devs getting paid is because their investors realize that’d raise the cost of their nearly free startup ventures. The stupidity of this is staggering given the insane money possible.</p>
  458. <p>It also comes down a perception of self-worth. Currently, and this is a weird California values thing, but developers are cultured to feel their value is only in giving things away for free and making money is "dirty".</p>
  459. <p>But, corporations are totally allowed to make money.</p>
  460. <p>Not only are corporations allowed to make money, but they’re allowed to outright steal resources from lone developers and then abuse the developers for not treating the corporation "professionally". Devs put up with this because they feel their aren’t worthy of their value.</p>
  461. <p>I believe that now programmers are sick of having to beg for scraps while corporations make TRILLIONS of dollars on their work. They can’t even get a job after 40 let alone a piece of the Google/Amazon/Apple pie.</p>
  462. <p>In fact, the rallying cry can simply be: "Pro Fees for Pro Support".</p>
  463. <p>You want me to deal with your bugs professionally like I’m a business? Well, professionals get paid for their work so time to pay up.</p>
  464. <p><cite><em><a href="https://twitter.com/zedshaw/status/966125251624079360">Zed Shaw on Twitter</a></em> (<a href="/david/cache/bd9042301f25ad74d5ac5d301368b534/">cache</a>)</cite></p>
  465. </blockquote>
  466. <p>I wonder what would be the consequence of adding prices to bugs. Even in an informative way. Or maybe the retroactive way with pull-requests. Imagine you would be able — when you merge one — to give the time/cost associated to such a development, reviews included. Mixed with other metrics, that would be a fascinating tool to measure the return over investment of each iteration.</p>
  467. </article>
  468. <nav>
  469. <p>
  470. <a rel=prev href="/david/stream/2018/02/24/">← Coquilles vides</a> | <a href="/david/stream/2018/" title="Retour à la liste complète">↑</a> | <a rel=next href="/david/stream/2018/02/26/">Mailbox is your copy →</a>
  471. </p>
  472. </nav>
  473. <aside>
  474. <p>
  475. Other articles in English:
  476. <a href="/david/blog/2018/caching-links/">On caching links</a>,
  477. <a href="/david/blog/2018/bushcraft-retrospective/">Bushcraft retrospective</a>,
  478. <a href="/david/blog/2018/into-the-raft/">Into the Raft</a>,
  479. <a href="/david/blog/2018/into-the-bugs/">Into the Bugs</a>,
  480. <a href="/david/blog/2018/meritocracy-crisis/">Meritocracy crisis</a>,
  481. <a href="/david/blog/2018/seller-teacher-wise/">The Seller, the Teacher and the Wise</a>,
  482. <a href="/david/blog/2018/into-the-good/">Into the Good</a>,
  483. <a href="/david/blog/2018/into-the-mice/">Into the Mice</a>,
  484. <a href="/david/blog/2018/into-the-camp/">Into the Camp</a>,
  485. <a href="/david/blog/2018/into-the-wind/">Into the Wind</a>,
  486. <a href="/david/blog/2018/into-the-snow/">Into the Snow</a>,
  487. <a href="/david/blog/2018/into-the-cold/">Into the Cold</a>,
  488. <a href="/david/blog/2017/async-python-frameworks/">Async Python Frameworks</a>,
  489. <a href="/david/blog/2017/distributed-teams/">Distributed teams</a>,
  490. <a href="/david/blog/2017/into-the-wild/">Into the Wild</a>,
  491. <a href="/david/blog/2017/without-javascript/">Without JavaScript</a>,
  492. <a href="/david/blog/2017/inclusive-python/">Inclusive Python</a>,
  493. <a href="/david/blog/2017/micro-cultures-governance/">Micro-cultures and governance</a>,
  494. <a href="/david/blog/2017/resilient-web-tools/">Resilient Web and Tools</a>,
  495. <a href="/david/blog/2017/bitcoin-energy/">Bitcoin and energy</a>,
  496. <a href="/david/blog/2016/team-building/">Team building</a>,
  497. <a href="/david/blog/2016/inclusive-developer/">Inclusive developer</a>,
  498. <a href="/david/blog/2016/cultural-intimacy/">Cultural Intimacy</a>,
  499. <a href="/david/blog/2016/tools-teams/">Tools and teams</a>,
  500. <a href="/david/blog/2016/senior-developer/">Senior developer</a>,
  501. <a href="/david/blog/2016/slow-data/">Slow Data</a>,
  502. <a href="/david/blog/2016/inclusive-communities/">Inclusive communities</a>,
  503. <a href="/david/blog/2016/delivery-values/">Delivery and value(s)</a>,
  504. <a href="/david/blog/2016/collaboration-debt/">Collaboration debt</a>,
  505. <a href="/david/blog/2016/communities-leadership/">Communities and leadership</a>,
  506. <a href="/david/blog/2016/specifications-apis/">Specifications and APIs</a>.
  507. Oh, and most of <a href="/david/stream/2018/">the 2018 thoughts</a>.
  508. </p>
  509. </aside>
  510. <nav>
  511. <p>
  512. <abbr title="Lieu de vie et de potentielles rencontres actuel">Montréal</abbr> ·
  513. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">Contact</a> ·
  514. <a href="http://larlet.com" title="Identité professionnelle">[Travailler ensemble ?]</a> ·
  515. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">Hébergeur</abbr> ·
  516. <a href="/david/log/" title="S’abonner aux publications via RSS">Flux</a>
  517. </p>
  518. </nav>
  519. <script>
  520. /* Service workers */
  521. if (navigator.serviceWorker) {
  522. window.addEventListener('load', function () {
  523. var selector = 'a[href^="/david/cache/"], a[rel=prev], a[rel=next]'
  524. function sendLinks (selector) {
  525. var links = [].slice.call(document.querySelectorAll(selector)).map(function (link) {
  526. return link.getAttribute('href')
  527. })
  528. links.push(location.pathname) // Put the current page in cache too.
  529. navigator.serviceWorker.controller.postMessage({ links: links })
  530. }
  531. navigator.serviceWorker.getRegistration()
  532. .then(function (registration) {
  533. if (!registration || !navigator.serviceWorker.controller) {
  534. return navigator.serviceWorker.register('/serviceworker.js')
  535. .then(navigator.serviceWorker.ready)
  536. .then(function () {
  537. console.log('[ServiceWorker] Ready to go!')
  538. })
  539. .catch(console.error.bind(console))
  540. } else {
  541. console.log('[ServiceWorker] Send links via registration')
  542. sendLinks(selector)
  543. }
  544. })
  545. navigator.serviceWorker.addEventListener('controllerchange', function () {
  546. console.log('[ServiceWorker] Send links via controller change')
  547. sendLinks(selector)
  548. })
  549. navigator.serviceWorker.addEventListener('message', function (event) {
  550. var link = document.querySelector('a[href="' + event.data.link + '"]')
  551. if (event.data.status && link) {
  552. link.style.backgroundColor = '#2d7474'
  553. link.style.color = '#f0f0ea'
  554. link.setAttribute('title', 'Put in cache for offline use')
  555. }
  556. })
  557. })
  558. } else {
  559. console.warn('[ServiceWorker] No cache for old browsers.')
  560. }
  561. </script>