PyConFr 2023 proofreading.

This commit is contained in:
Julien Palard 2023-02-14 23:53:23 +01:00
parent efd5a81806
commit 7815e682f8
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
5 changed files with 295 additions and 36 deletions

View File

@ -1,22 +1,33 @@
# sphinx-lint
<!-- .slide: data-background="static/background.jpg" -->
<!-- .slide: data-background="static/2023-snakes.svg" -->
Un linter pour ta doc.
<br/>
<b>Julien Palard</b>
Julien Palard
CPython core dev<br/>
Sysadmin de lAFPy<br/>
hackinscience.org<br/>
<br/>
## Julien Palard
<!-- .slide: data-background="static/background.jpg" -->
- CPython core dev
- Sysadmin à lAFPy
- hackinscience.org
Notes:
- Je moccupe surtout de docs.python.org
- Formateur, indépendant, faites passer le mot :)
# Pourquoi ?
Notes:
Trouver des fautes de frappe dans du rst, ni plus, ni moins.
## Depuis quand ?
@ -28,38 +39,46 @@ Date: Sat Jan 3 20:30:15 2009 +0000
Dans `cpython` dans `Doc/tools/rstlint.py` !
::: notes
Notes:
Oui oui, Georg, l'auteur de Sphinx-doc.
## Depuis quand, quoi ?
# La motivation
Et dans `cpython` on en avait un autre, `make suspicious`.
`make suspicious`
Bien connu pour ses faux positifs.
Bien connu pour ses faux positifs, n'est-ce pas ?
::: notes
Notes:
Lui il date du portage de la doc de LaTeX à Sphinx, 2009 aussi.
Lui il date du portage de la doc de LaTeX à Sphinx, il était là pour
repérer les erreurs de portage. Il date donc de 2009 aussi.
## La motivation
Remplacer `make suspicious` par un outil qui naurait **aucun** faux positif.
::: notes
Notes:
Et qui serait rapide !
Parler de la lenteur de `make suspicious`.
- Aucun faux positif == cool pour les contributeurs !
- Et qui serait rapide !
- Parler de la lenteur de `make suspicious`.
## La motivation
Sortir loutil de `cpython/Doc/tools` pour que tout le monde puisse l'utiliser.
Sortir `rstlint.py` de `cpython/Doc/tools` pour que tout le monde puisse l'utiliser.
Notes: Et pour faciliter la contribution.
## La motivation
![](static/2023-pyconfr-issue-open.png)
# Parsons du rst !
## Le reStructuredText
@ -77,6 +96,7 @@ Lien_
`Un lien anonyme <https://...>`__
```
Notes: Comme en Markdown, comme en Org.
## Le reStructuredText
@ -99,7 +119,7 @@ Donc oui le balisage et le texte interprété peuvent jouer le même rôle :
``ça`` c'est pareil que :literal:`ça`.
```
::: notes
Notes:
Mais comme en Python on a plus de méthodes que d'opérateurs…
@ -114,33 +134,37 @@ Les directives :
.. image:: Lenna.jpg
.. important::
Elle sappelle Lena Sjööblom.
Elle sappelle *Lena Sjööblom*.
```
::: notes
Notes:
Je prends un gros raccourci : les directives ne sont qu'un bout de
tout le balisage "explicite" comme les commentaires, les notes de bas
de page, ...
Retenez-bien que le corps d'une directive peut contenir du reStructuredText !
## Parsons du rst !
C'est facile ! Ou pas…
Jusque-là, cest facile !
Exemple, comment on interprète :
## Parsons du rst !
Maintenant, parsez ça, avec vos yeux :
```text
*2 * x *a **b *.txt*
```
::: notes
Notes:
C'est tout en italique !
## Parsons du rst !
Vous voyez des balises, vous ?
Vous voyez du balisage, vous, ici ?
```text
2 * x ** 2 + 3 * x ** 3
@ -152,7 +176,7 @@ a || b
2*x a**b O(N**2) e**(x*y)
```
::: notes
Notes:
Pas le parseur. Mais bon les règles sont bien documentées ♥
@ -166,14 +190,14 @@ Regardons du côté des directives :
```text
.. code-block:: python
def fib(x):
def fib(n):
if n in (0, 1):
return 1
x = n // 2
return fib(x - 1) * fib(n - x - 1) + fib(x) * fib(n - x)
return fib(x-1) * fib(n-x-1) + fib(x) * fib(n-x)
```
::: notes
Notes:
Une directive peut avoir un corps, ici du code.
@ -190,7 +214,7 @@ Regardons du côté des directives :
:alt: Lenna Sjööblom
```
::: notes
Notes:
Une directive peut avoir des options mais **pas de corps**.
@ -210,7 +234,7 @@ Regardons du côté des directives :
aze.fr, 200, 200
```
::: notes
Notes:
Une directive peut avoir des options **et** un corps.
@ -249,7 +273,7 @@ Une directive peut avoir des options **et** un corps.
aze.fr
```
::: notes
Notes:
Les valeurs manquantes sont moins graves que les valeurs surnuméraires.
@ -259,9 +283,85 @@ Les valeurs manquantes sont moins graves que les valeurs surnuméraires.
De toutes façons `sphinx-lint` ne cherche pas du rst valide, il cherche du rst invalide !
## Mes amies les regex
```python
SIMPLENAME = r"(?:(?!_)\w)+(?:[-._+:](?:(?!_)\w)+)*"
ROLE_GLUED_WITH_WORD_RE = re.compile(
fr"(^|\s)(?<!:){SIMPLENAME}:`(?!`)")
ROLE_WITH_NO_BACKTICKS_RE = re.compile(
fr"(^|\s):{SIMPLENAME}:(?![`:])[^\s`]+(\s|$)")
ROLE_MISSING_RIGHT_COLON_RE = re.compile(
fr"(^|\s):{SIMPLENAME}`(?!`)")
ROLE_MISSING_CLOSING_BACKTICK_RE = re.compile(
fr"({ROLE_HEAD}`[^`]+?)[^`]*$")
```
Notes: Parfois lisibles.
## Mes amies les regex
```python
ASCII_BEFORE = r"""[-:/'"<(\[{]"""
UNICODE_BEFORE = r"[\p{Ps}\p{Pi}\p{Pf}\p{Pd}\p{Po}]"
ASCII_AFTER = r"""[-.,:;!?/'")\]}>]"""
UNICODE_AFTER = r"[\p{Pe}\p{Pi}\p{Pf}\p{Pd}\p{Po}]"
re.compile(
fr"(?<!\x00)(?<=^|\s|{ASCII_BEFORE}|{UNICODE_BEFORE})"
fr"(?P<inline_markup>{start_string}\S{QUOTE_PAIRS_NLB}"
fr".*?(?<=\S){end_string})"
fr"(?=$|\s|\x00|{ASCII_AFTER}|{UNICODE_AFTER})"
)
```
Notes: Parfois pas. Mais vous connaissez `re.VERBOSE` ?
## Mes amies les regex
```python
re.compile(
fr"""
(?<!\x00) # Both inline markup start-string and end-string
# must not be preceded by an unescaped backslash
(?<= # Inline markup start-strings must:
^| # start a text block
\s| # or be immediately preceded by whitespace,
{ASCII_BEFORE}| # one of the ASCII characters or a
{UNICODE_BEFORE} # similar non-ASCII punctuation char.
)
(?P<inline_markup>
{start_string} # Inline markup start
\S # Inline markup start-strings must be
# immediately followed by non-whitespace.
# The inline markup end-string must be
# separated by at least one character
# from the start-string.
{QUOTE_PAIRS_NEGATIVE_LOOKBEHIND}
.*?
(?<=\S) # Inline markup end-strings must be
# immediately preceded by non-whitespace.
{end_string} # Inline markup end
)
(?= # Inline markup end-strings must
$| # end a text block or
\s| # be immediately followed by whitespace,
\x00|
{ASCII_AFTER}| # one of the ASCII characters or a
{UNICODE_AFTER} # similar non-ASCII punctuation char.
)
""",
flags=re.VERBOSE | re.DOTALL,
)
```
Notes: Les commentaires sont un copié-collé de la spec !
# Cest utilisé ?
- CPython (depuis longtemps), devguide, peps, traductions, ...
- CPython (forcément…), devguide, peps, traductions, ...
- neo4j-python-driver
- pandas
- Spyder IDE
@ -311,19 +411,46 @@ De toutes façons `sphinx-lint` ne cherche pas du rst valide, il cherche du rst
+"datetime`. :const:`MINYEAR` es ``1``."
```
... notes
Notes:
Ils ont réparé plus de 300 erreurs !
# Et les perfs ?
```text
$ time make suspicious
real 1m10.416s
user 3m28.918s
sys 0m3.127s
```
```text
$ time make check # (c'est sphinx-lint derrière)
real 0m6.351s
user 0m43.478s
sys 0m0.227s
```
# Et les faux positifs ?
- `make suspicious` → 400
- `make checks` → 0
## Et les faux positifs ?
Ils se cachent bien :
- Aucun dans la doc de Sphinx, cest un bon test (beaucoup de rst dans du rst).
- Aucun dans la doc de Python, cest un bon test (286k lignes de rst).
## Et `make suspicious` ?
![](static/2023-pyconfr-issue-open.png)
![](static/2023-pyconfr-issue-close.png)
# OK, vendu !
Mais comment ça sutilise ?
@ -337,14 +464,17 @@ $ sphinx-lint
Bah, fais-le.
Notes: Pour Debian je veux bien le faire ;)
# Questions ?
- <s>Twitter : [@sizeof](https://twitter.com/sizeof)</s>
- Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk)
- XMPP : mdk@chapril.org
- HTTP : https://mdk.fr
- HTTP : https://mdk.fr (et https://discuss.afpy.org)
- SMTP : julien@python.org
- Whatsapp : HAHAHA jamais.
- IRC : mdk sur irc.libera.chat (#python-fr, #afpy)
- Whatsapp : HaHa. Jamais.
- Instagram : Et puis quoi encore ?
- TikTok : Euh, stop maintenant ?
- TikTok : Euh, bon, stop maintenant !?

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

129
static/2023-snakes.svg Normal file
View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:serif="http://www.serif.com/" width="100%" height="100%" viewBox="0 0 1200 675" version="1.1" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
<g transform="matrix(1.74419,0,0,2.0329,-1.29928e-13,2.84217e-14)">
<rect x="0" y="0" width="688" height="332.037" style="fill:none;"/>
<clipPath id="_clip1">
<rect x="0" y="0" width="688" height="332.037"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1393.14,343.574C1378.85,338.005 1365.47,330.733 1353.2,322.133C1366.26,313.788 1377.62,305.122 1387.48,296.3C1400.28,303.589 1414.34,309.101 1429.33,312.289C1419.03,322.939 1407.05,333.428 1393.14,343.572C1442.44,362.793 1502.5,361.744 1564.3,324.815C1627.16,287.254 1668.6,219.797 1676.67,142.73C1662.75,150.452 1648.25,157.627 1633.19,164.126C1621.53,217.375 1590,262.864 1543.79,290.478C1503.39,314.615 1463.89,319.639 1429.33,312.285C1466.17,274.204 1481.55,234.068 1486.63,200.501C1473.19,201.52 1459.43,201.991 1445.37,201.843C1439.17,230.58 1423.01,264.499 1387.48,296.288C1369.09,285.823 1353.3,271.687 1341.08,255.512C1324.64,233.749 1314.46,208.29 1313.81,183.452C1299.08,178.771 1286.03,173.324 1274.5,167.256C1271.92,192.661 1276.81,219.039 1287.91,243.833C1301.42,273.981 1324.15,301.766 1353.21,322.125C1337.34,332.268 1318.97,341.936 1297.72,350.849C1216.25,385.029 1169.11,429.862 1144.91,475.622C1162.09,473.467 1179.04,472.05 1195.61,471.367C1218.98,440.568 1256.69,411.442 1313.2,387.735C1345.13,374.335 1371.48,359.375 1393.14,343.574Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1285.12,127.736C1295.43,134.042 1307.49,139.604 1321.49,144.314L1322.19,142.778C1334.59,117.105 1352.61,105.762 1371.35,102.657C1412.86,95.779 1441.57,123.255 1446.68,149.361C1447.4,153.056 1447.99,157.255 1448.34,161.877C1461.97,161.991 1475.29,161.414 1488.29,160.225C1487.85,153.233 1486.97,146.998 1485.93,141.683C1477.62,99.171 1432.41,51.995 1364.82,63.195C1335.21,68.1 1305.77,84.818 1286.17,125.378L1285.12,127.736Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1638.22,118.253C1651.87,111.625 1664.96,104.373 1677.52,96.66C1669.74,-19.67 1586.65,-147.934 1391.72,-225.907C1381.47,-230.007 1369.82,-225.014 1365.72,-214.765C1361.62,-204.516 1366.61,-192.867 1376.86,-188.768C1563.3,-114.194 1638.79,10.908 1638.22,118.253Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1393.14,343.574L1393.14,343.572C1407.05,333.428 1419.03,322.939 1429.33,312.289C1414.34,309.101 1400.28,303.589 1387.48,296.3C1377.62,305.122 1366.26,313.788 1353.2,322.133C1365.47,330.733 1378.85,338.005 1393.14,343.574Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1321.49,144.314C1315.78,156.714 1313.38,169.99 1313.81,183.452C1346.23,193.771 1386.76,200.381 1437.15,201.754L1445.37,201.843C1448.66,186.734 1449.18,173.057 1448.34,161.877L1438.24,161.769C1389.37,160.437 1351.09,154.278 1321.49,144.314Z" style="fill:rgb(139,189,200);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1638.22,118.253C1593.94,139.906 1544,155.343 1488.29,160.225C1489.16,171.827 1488.93,185.509 1486.63,200.501C1540.36,196.371 1589.19,183.144 1633.19,164.126C1636.44,149.365 1638.15,134 1638.22,118.253Z" style="fill:rgb(139,189,200);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1274.5,167.256C1275.84,153.67 1279.33,140.369 1285.12,127.736C1270.56,118.827 1259.49,108.437 1251.35,96.876C1228.3,64.147 1230.47,23.392 1240,-13.585C1255.55,-73.87 1291.9,-125.212 1291.9,-125.212C1298.27,-134.222 1296.13,-146.714 1287.12,-153.091C1278.12,-159.467 1265.62,-157.33 1259.25,-148.32L1201.27,-23.574C1188.86,24.553 1188.65,77.306 1218.64,119.904C1231.14,137.659 1249.19,153.948 1274.5,167.256Z" style="fill:rgb(139,189,200);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1488.29,160.225C1475.29,161.375 1461.97,161.941 1448.34,161.877C1449.18,173.057 1448.65,186.733 1445.37,201.843C1459.43,202.052 1473.19,201.572 1486.63,200.501C1488.91,185.512 1489.13,171.831 1488.29,160.225Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1285.12,127.736C1279.29,140.356 1275.82,153.665 1274.5,167.256C1286.04,173.323 1299.09,178.769 1313.81,183.452C1313.39,170 1315.79,156.723 1321.49,144.314C1307.48,139.603 1295.43,134.04 1285.12,127.736Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M911.351,559.971C787.62,647.696 701.565,787.398 701.565,787.398C695.804,796.814 698.772,809.135 708.188,814.896C717.604,820.656 729.925,817.688 735.686,808.272C735.686,808.272 818.9,671.24 938.288,589.366C934.257,584.681 930.121,580.01 925.898,575.369C921.177,570.179 916.338,565.025 911.351,559.971Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-374.331,-29.4403)">
<path d="M1186.23,480.742C1175.85,494.341 1168.3,508.284 1163.16,522.221C1206.56,518.393 1247.87,519.782 1283.78,526.486C1289.56,527.566 1295.2,528.776 1300.67,530.121C1288.63,562.486 1285.37,593.88 1291.47,618.461C1302.02,660.955 1353.84,685.901 1392.06,665.131C1434.29,642.177 1444.37,595.332 1417.38,555.933C1403.69,535.949 1382.74,519.6 1356.26,507.309C1390.78,451.425 1454.65,400.827 1536.79,401.87C1564.93,402.227 1590.62,407.112 1614.09,415.692C1623.15,404.821 1632.78,394.225 1642.9,384.05C1611.45,370.315 1576.37,362.369 1537.29,361.873C1439.24,360.628 1362.57,420.409 1321.68,487.168C1320.42,489.231 1319.19,491.301 1318.01,493.38C1309.4,490.976 1300.42,488.903 1291.12,487.166C1259.42,481.248 1223.8,479.093 1186.23,480.742ZM1338.41,542.817C1329,567.01 1325.69,590.301 1330.29,608.822C1334.82,627.074 1356.54,638.907 1372.96,629.987C1392.81,619.195 1397.07,597.062 1384.38,578.539C1374.09,563.515 1358.24,551.753 1338.41,542.817Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-374.331,-29.4403)">
<path d="M1317.91,493.602C1311.01,505.62 1305.26,517.802 1300.72,529.828C1314.48,533.159 1327.19,537.388 1338.57,542.576C1343.05,530.917 1348.94,519.085 1356.1,507.487C1344.39,502.077 1331.61,497.439 1317.91,493.602Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1327.29,484.227C1320.39,496.245 1314.64,508.427 1310.1,520.453C1323.86,523.784 1336.56,528.013 1347.94,533.201C1352.42,521.542 1358.31,509.71 1365.48,498.112C1353.77,492.702 1340.98,488.064 1327.29,484.227Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1144.91,475.622C1102.6,480.908 1059.01,490.638 1016.64,504.759C992.091,512.943 968.299,524.276 945.511,537.752C948.893,541.285 952.216,544.856 955.486,548.451C961.376,554.925 967.077,561.472 972.603,568.014C990.86,557.829 1009.81,549.2 1029.29,542.707C1062.07,531.782 1095.63,523.618 1128.63,518.322C1131.23,507.444 1134.98,496.527 1139.94,485.655C1141.47,482.306 1143.12,478.958 1144.91,475.622Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1195.61,471.367C1179.03,472.021 1162.08,473.457 1144.91,475.622C1143.12,478.958 1141.47,482.306 1139.94,485.655C1134.98,496.527 1131.23,507.444 1128.63,518.322C1143.42,515.904 1158.09,514.087 1172.54,512.846C1177.66,498.914 1185.23,484.979 1195.61,471.367Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M633.569,459.443C608.408,471.786 585.359,488.279 562.509,507.275C511.943,549.312 462.359,604.326 388.601,649.888C343.489,677.753 288.176,695.273 233.907,699.489L234.868,705.25C236.603,716.924 237.711,728.212 238.179,739.129C298.403,734.212 359.611,714.81 409.622,683.919C485.215,637.225 536.256,581.116 588.08,538.034C609.558,520.179 631.16,504.687 655.145,493.662L651.693,487.365C645.801,477.111 639.762,467.827 633.569,459.443Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M972.603,568.014C960.869,574.536 949.42,581.708 938.288,589.366C980.768,638.315 1014.36,687.862 1044.69,709.27C1053.71,715.636 1066.2,713.483 1072.57,704.465C1078.93,695.447 1076.78,682.957 1067.76,676.592C1040.18,657.122 1010.36,612.67 972.603,568.014Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M911.351,559.971C922.448,552.09 933.846,544.642 945.511,537.752C896.677,486.591 836.32,442.346 758.272,436.476C725.92,434.043 697.687,437.153 672.061,444.523C676.924,451.644 681.69,459.282 686.375,467.436C688.883,471.8 691.262,476.15 693.501,480.485C712.172,476.251 732.512,474.652 755.272,476.363C820.063,481.236 870.105,517.79 911.351,559.971Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M945.511,537.752C933.841,544.643 922.442,552.098 911.351,559.971C916.338,565.025 921.177,570.179 925.898,575.369C930.121,580.01 934.257,584.681 938.288,589.366C949.403,581.712 960.864,574.545 972.603,568.014C967.077,561.472 961.376,554.925 955.486,548.451C952.216,544.856 948.893,541.285 945.511,537.752Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M693.501,480.485C679.921,483.57 667.23,488.049 655.145,493.662C717.095,607.394 678.929,710.317 625.409,785.281C569.215,863.991 495.846,912.781 495.846,912.781C486.651,918.887 484.142,931.31 490.248,940.505C496.354,949.701 508.777,952.21 517.973,946.104L657.964,808.523C718.29,724.025 760.01,608.353 693.501,480.485Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M633.586,459.435C645.844,453.408 658.603,448.375 672.082,444.517C653.584,417.12 634.025,396.843 613.89,381.923C606.36,392.58 597.669,402.997 587.691,413.156C603.479,424.346 618.889,439.37 633.586,459.435Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M306.058,302.916C300.321,304.702 294.627,306.337 289.012,307.868C282.126,309.746 274.353,311.681 265.895,313.767C285.152,348.713 316.891,374.937 354.128,382.554C387.775,389.436 430.015,382.352 474.992,381.992C499.64,381.794 525.197,384.09 550.423,393.451C561.583,383.054 571.047,372.3 579.05,361.243C544.29,345.288 508.716,341.72 474.671,341.993C432.794,342.328 393.472,349.773 362.144,343.365C339.146,338.661 319.597,323.302 306.058,302.916Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M484.772,90.843C484.099,105.149 482.451,118.485 479.988,130.929C517.963,140.861 561.646,152.945 617.245,155.925L615.841,139.451C615.305,133.631 614.768,127.81 614.232,121.99L613.64,115.548C561.362,112.12 520.445,100.095 484.772,90.843Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M672.082,444.517C658.6,448.369 645.843,453.41 633.586,459.435C639.76,467.823 645.8,477.109 651.693,487.365L655.145,493.662C667.221,488.02 679.917,483.556 693.501,480.485C691.262,476.15 688.883,471.8 686.375,467.436C681.693,459.288 676.931,451.654 672.082,444.517Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.354,-24.2732)">
<path d="M130.479,359.364C125.332,361.917 120.273,364.651 115.292,367.533C108.14,371.671 101.155,376.131 94.425,380.951C131.72,410.217 167.117,443.791 197.752,459.386C301.524,512.211 445.69,519.548 543.677,450.344C560.428,438.513 574.888,426.228 587.316,413.531C575.077,404.845 562.602,398.464 550.048,393.826C541.309,402.004 531.528,409.954 520.601,417.671C434.304,478.619 307.291,470.262 215.898,423.739C190.209,410.661 161.204,384.601 130.479,359.364Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.354,-24.2732)">
<path d="M616.87,156.3C617.833,168.19 618.639,180.041 619.156,191.816C621.796,251.939 616.103,310.041 578.675,361.618C590.412,366.98 602.055,373.77 613.515,382.298C655.05,323.759 662.109,258.208 659.118,190.061C658.633,179.029 657.858,167.927 656.919,156.773C642.899,157.195 629.573,156.985 616.87,156.3Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.354,-24.2732)">
<path d="M613.265,115.923C625.859,116.8 639.119,117.139 653.125,116.823C646.611,52.455 639.935,-12.5 657.719,-73.58C685.255,-168.155 794.192,-238.482 890.009,-201.669C900.313,-197.71 911.892,-202.862 915.851,-213.166C919.81,-223.47 914.658,-235.049 904.354,-239.008C787.286,-283.986 652.957,-200.313 619.314,-84.762C600.57,-20.385 606.869,48.098 613.265,115.923Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.354,-24.2732)">
<path d="M578.675,361.618C570.672,372.673 561.202,383.422 550.048,393.826C562.601,398.453 575.073,404.841 587.316,413.531C597.302,403.38 605.982,392.956 613.515,382.298C602.064,373.758 590.416,366.983 578.675,361.618Z" style="fill:rgb(139,189,200);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.354,-24.2732)">
<path d="M613.265,115.923L613.857,122.365C614.393,128.185 614.93,134.006 615.466,139.826L616.87,156.3C629.572,156.975 642.897,157.179 656.919,156.773L655.458,140.503C654.913,134.955 654.369,129.407 653.824,123.858L653.125,116.823C639.124,117.132 625.865,116.779 613.265,115.923Z" style="fill:rgb(254,111,97);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M653.5,116.448L654.199,123.483C654.744,129.032 655.288,134.58 655.833,140.128L657.294,156.398C681.732,155.72 708.288,153.168 737.351,148.053C769.551,142.386 800.295,134.888 829.585,125.932C840.141,122.705 846.09,111.514 842.863,100.959C839.635,90.403 828.445,84.453 817.889,87.68C790.111,96.174 760.955,103.284 730.417,108.659C702.429,113.585 676.926,115.939 653.5,116.448Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M1623.46,406.317C1587.08,449.735 1559.44,497.369 1544.79,539.04C1510.37,636.918 1444.53,680.367 1399.98,692.28C1280.56,724.208 1202.04,682.354 1174.74,616.492C1162.07,585.953 1158.97,549.412 1172.54,512.846C1158.09,514.079 1143.42,515.916 1128.63,518.322C1118.68,558.739 1123.92,598.37 1137.78,631.811C1171.1,712.178 1264.59,769.882 1410.31,730.922C1462.74,716.904 1542.02,667.492 1582.52,552.31C1596.71,511.951 1624.28,465.261 1660.59,423.746C1648.88,416.91 1636.51,411.049 1623.46,406.317Z" style="fill:rgb(246,179,106);"/>
</g>
<g transform="matrix(0.669155,0,0,0.57412,-380.605,-24.0579)">
<path d="M633.569,459.443C608.408,471.786 585.359,488.279 562.509,507.275C511.943,549.312 462.359,604.326 388.601,649.888C319.948,692.295 227.668,710.74 151.393,694.812C79.18,679.733 21.878,632.528 17.625,543.206C17.316,536.726 17.264,530.439 17.482,524.344C4.36,522.466 -9.013,521.456 -22.461,521.151C-22.773,528.877 -22.723,536.863 -22.33,545.109C-17.046,656.06 53.517,715.237 143.217,733.968C228.857,751.851 332.54,731.532 409.622,683.919C485.215,637.225 536.256,581.116 588.08,538.034C609.558,520.179 631.16,504.687 655.141,493.664L651.693,487.365C645.801,477.111 639.762,467.827 633.569,459.443Z" style="fill:rgb(254,111,97);"/>
</g>
<g id="tete-serpent" serif:id="tete serpent" transform="matrix(0.441701,0,0,0.37897,-197.299,-5.57697)">
<g transform="matrix(0.789258,0,0,0.789258,197.22,21.2506)">
<g transform="matrix(0.999997,7.51095e-07,7.51095e-07,1,0.00242926,-0.000661111)">
<path d="M903.768,86.612L990.168,63.099" style="fill:none;stroke:rgb(254,111,97);stroke-width:19.9px;"/>
</g>
<g transform="matrix(0.105379,0.394071,-0.314646,0.0841396,930.243,-364.309)">
<path d="M1015.58,74.856L1050.06,161.228L1084.54,74.856" style="fill:none;stroke:rgb(254,111,97);stroke-width:53.93px;"/>
</g>
</g>
<g transform="matrix(0.297375,0.954761,-0.954761,0.297375,647.942,-993.704)">
<g transform="matrix(0.938152,0,0,0.938152,99.9695,-700.69)">
<path d="M1057.73,784.291C1062.71,780.607 1068.84,778.479 1075.36,778.479C1075.36,778.479 1075.36,778.479 1075.36,778.479C1081.88,778.479 1088.01,780.607 1092.99,784.291C1105.3,791.622 1119.48,816.918 1127.98,848.839C1135.86,878.413 1136.69,905.513 1131.19,919.309C1128.61,927.85 1123.74,935.71 1116.86,941.933C1114.26,944.281 1111.58,946.705 1108.89,949.137C1089.85,966.346 1060.87,966.346 1041.83,949.137C1039.14,946.705 1036.46,944.281 1033.86,941.933C1026.98,935.71 1022.11,927.85 1019.53,919.309C1014.03,905.513 1014.86,878.413 1022.74,848.839C1031.24,816.918 1045.42,791.622 1057.73,784.291Z" style="fill:rgb(55,136,153);"/>
</g>
<g transform="matrix(0.0619749,-0.0217318,0.0384816,0.109742,1069.77,106.189)">
<circle cx="1051.36" cy="219.607" r="91.359"/>
</g>
<g transform="matrix(-0.0619749,-0.0217318,-0.0384816,0.109742,1148.13,106.281)">
<circle cx="1051.36" cy="219.607" r="91.359"/>
</g>
</g>
</g>
</g>
</g>
<script xmlns=""/></svg>

After

Width:  |  Height:  |  Size: 19 KiB