Merge remote-tracking branch 'upstream/develop' into no-frontend-worker

This commit is contained in:
Michael 2021-01-07 10:44:12 +00:00
commit df135c31fe
62 changed files with 306 additions and 14176 deletions

106
CHANGELOG
View file

@ -1,3 +1,109 @@
Version 2021.03 (unreleased)
Version 2021.01 (2021-01-04)
Friendica Core
Added HU translation
Updates to the translations: DE, IT, RU [translation teams]
Updates to the themes (duepuntozero, frio, vier) [annando, MrPetovan, tobiasd, vinzv]
General Code cleanup [annando, MrPetovan, nupplaphil]
Enhanced the handling of permission sets [annando]
Enhanced the usage of system resources when displaying photos and updating contacts [annando]
Enhanced the database structure [annando, Quix0r]
Enhanced the detection of PeerTube servers [annando]
Enhanced the photo cache [annando]
Enhanced the import of old postings which would otherwise not be imported due their age [annando]
Enhanced the delivery process of ActivityPub content [annando]
Enhanced the performance profiler [annando]
Enhanced the background worker [annando]
Enhanced the handling of blocked authors [MrPetovan]
Enhanced the user management in the admin panel [MrPetovan]
Enhanced the process of expiring postings [annando]
Enhanced the un/follow process of contacts [annando]
Enhanced the handling of HTTP requests [nupplaphil]
Enhanced filter possibilities of contacts [annando]
Enhanced language detection of postings [annando]
Enhanced the admin panel [MrPetovan, tobiasd]
Enhanced the contact suggestions [annando]
Enhanced the community page (filter, tags) [annando]
Enhanced the display of the reason why a posting is displayed in a stream [annando]
Enhanced the forum delivery of postings [redmatrix]
Enhanced PHP8 compatibility [annando]
Enhanced the worker_cooldown mechanism [annando]
Added new options to the remote_self feature [annando]
Added API endpoints for accounts and trends [annando]
Added API endpoints for re-sharing of postings [annando]
Added provider fields to the API [annando]
Added the possibility to map $_SERVER variables during installation [nupplaphil]
Added the possibility to filter account types on the network page [annando]
Added missing Mastodon API endpoints as "unsupported" [annando]
Added a watchdog mode to check if the daemon is running [annando]
Added number of group members to the contact widget [annando]
Added endless scrolling in several places [annando]
Added an option to stay local when clicking on a contact profile [annando]
Added support of ActivityPub relays [annando]
Model\User::getAuthenticationInfo is now available for addons [MrPetovan]
Contact details can only edited for mail and feed contacts [annando]
Fixed some problems during the export of user data [annando]
Fixed various problems with the notification system [MrPetovan]
Fixed a problem with emoticon alt-text interpretation [MrPetovan]
Fixed a problem that caused comments on Tweets being distributed via ActivityPub [annando]
Fixed a problem with the auto-completion when composing comments [MrPetovan]
Fixed an ACL problem while poking contacts [MrPetovan]
Fixed a problem with Mastodon emoticons [MrPetovan]
Fixed a parser problem that caused additional <br> tags [annando]
Fixed escaping of several HTML snippets [MrPetovan]
Fixed a problem with fetching objects by URL [annando]
Friendica Addons
Updated to the translations IT, HU [translation teams]
advancedcontentfilter:
Added examples [hoergen]
blackout:
Improved the wording in the admin interface [urbalazs]
catavatar:
Improved the generation of avatars [annando]
ifttt:
Added support for delayed postings [annando]
mailstream:
Improved code structure [nupplaphil]
Fix case-sensitive check by [nupplaphil]
markdown:
Improved parsing [MrPetovan]
newmemberwidget:
Improved addon description [SpencerDub]
langfilter:
Changed the input to use a slider [MrPetovan]
ldapauth:
Reworked the authentication code [MrPetovan]
libravatar:
Fixed a problem with DNS requests [annando]
Improved the list of available avatars [annando]
phpmailer:
Fixed UTF8 encoding problems [MrPetovan]
rendertime:
Added more information about the "other" things that cost time [annando]
showmore:
Improved handling of the HTML structure of postings [MrPetovan]
showmore_dyn:
Improved user settings, language [MrPetovan]
twitter:
Improved logging [annando]
Improved the twitter_post_hook [MrPetovan]
Improved the posts send to twitter [annando]
Improved the remote_self functionality [annando]
Added support for delayed postings [annando]
Fixed a bug with direct re-shares [MrPetovan]
Closed Issues
2803, 4230, 4486, 4494, 5616, 7393, 7697, 8485, 8533, 8605, 8689,
8796, 8896, 8943, 8950, 9042, 9089, 9127, 9142, 9165, 9235, 9236,
9238, 9249, 9264, 9268, 9276, 9281, 9291, 9296, 9305, 9306, 9315,
9326, 9328, 9329, 9337, 9344, 9348, 9363, 9383, 9385, 9407, 9427,
9430, 9432, 9457, 9461, 9464, 9465, 9480, 9486, 9496, 9508, 9518,
9525, 9538, 9549, 9564, 9568, 9573, 9598, 9611, 9622, 9629, 9630,
9633, 9636, 9639, 9641, 9642, 9662, 9672, 9673, 9678, 9682, 9692,
9712
Version 2020.09-1 (2020-09-24)
Friendica Core:
Updates to the translations: RU [translation teams]

View file

@ -35,6 +35,7 @@ Athalbert
aweiher
axelt
balderino
Balázs Úr
Beanow
beardyunixer
Beatriz Vital
@ -133,6 +134,7 @@ julia.domagalska
Julio Cova
Karel
Karolina
Kastal András
Keenan Pepper
Keith Fernie
Klaus Weidenbach
@ -144,11 +146,11 @@ Leberwurscht
Leonard Lausen
Lionel Triay
loma-one
loma1
Lorem Ipsum
Ludovic Grossard
Lynn Stephenson
maase2
Magdalena Gazda
Mai Anh Nguyen
Manuel Pérez Monís
Marcin Klessa
@ -157,7 +159,6 @@ Marcus Müller
Marie Olive
Mariusz Pisz
marmor
Marquis_de_Carabas
Martin Schmitt
Mateusz Mikos
Mats Sjöberg
@ -177,6 +178,7 @@ mpanhans
mytbk
nathilia-peirce
Nicola Spanti
nobody
Olaf Conradi
Oliver
Olivier
@ -225,7 +227,6 @@ Samuli Valavuo
Sandro Santilli
Sebastian Egbers
sella
Sennewood
Seth
Silke Meyer
Simon L'nu
@ -242,7 +243,6 @@ Sveinn í Felli
Sven Anders
Sylke Vicious
Sylvain Lagacé
szymon.filip
Sérgio Lima
Taekus
Tazman DeVille

View file

@ -1 +1 @@
2020.12-rc
2021.03-dev

View file

@ -223,6 +223,11 @@ while (true) {
$sleep = min(1000000, round(log10($arg) * 1000000, 0));
usleep($sleep);
$pid = pcntl_waitpid(-1, $status, WNOHANG);
if ($pid > 0) {
Logger::info('Children quit via pcntl_waitpid', ['pid' => $pid, 'status' => $status]);
}
$timeout = ($seconds >= $wait_interval);
} while (!$timeout && !Worker::IPCJobsExists());

View file

@ -38,7 +38,7 @@ use Friendica\Util\DateTimeFormat;
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Red Hot Poker');
define('FRIENDICA_VERSION', '2020.12-rc');
define('FRIENDICA_VERSION', '2021.03-dev');
define('DFRN_PROTOCOL_VERSION', '2.23');
define('NEW_UPDATE_ROUTINE_VERSION', 1170);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,021 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,015 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -1,240 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="96"
height="96"
id="svg2"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="friendica.svg"
inkscape:export-filename="/home/meta/Documents/My random images/friendica.png"
inkscape:export-xdpi="80.552788"
inkscape:export-ydpi="80.552788">
<defs
id="defs4">
<linearGradient
id="highlightgradient">
<stop
id="stop3833"
offset="0"
style="stop-color:#ffffff;stop-opacity:0.74374998;" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3829" />
</linearGradient>
<linearGradient
id="shadowgradient">
<stop
id="stop3833-5"
offset="0"
style="stop-color:#000000;stop-opacity:0.5;" />
<stop
style="stop-color:#818080;stop-opacity:0;"
offset="1"
id="stop3829-9" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#highlightgradient"
id="linearGradient4011"
x1="44.948269"
y1="0"
x2="54.103466"
y2="46.797421"
gradientUnits="userSpaceOnUse"
gradientTransform="scale(1,0.54545455)" />
<linearGradient
inkscape:collect="always"
xlink:href="#shadowgradient"
id="linearGradient4021"
x1="52.016712"
y1="96"
x2="42.867535"
y2="41.837971"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.5,0,48)" />
<filter
inkscape:collect="always"
id="filter4055"
x="-0.03"
width="1.06"
y="-0.12"
height="1.24">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="1.2"
id="feGaussianBlur4057" />
</filter>
<filter
inkscape:collect="always"
id="filter4059"
x="-0.029877551"
width="1.0597551"
y="-0.122"
height="1.244">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="1.22"
id="feGaussianBlur4061" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.9132799"
inkscape:cx="53.033009"
inkscape:cy="2.8284271"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
width="256px"
inkscape:snap-global="true"
inkscape:window-width="1680"
inkscape:window-height="1010"
inkscape:window-x="194"
inkscape:window-y="0"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="3"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="2px"
spacingy="2px" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Colors"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-956.3622)"
style="display:inline">
<path
style="fill:#ffc019;fill-opacity:1;stroke:none"
d="M 16,0 C 7.0091019,0.04308252 0,7.0521845 0,16 0,16 0,57.499123 0,80 0,89.120146 7.0091019,96 16,96 L 32,96 32,70 64,70 63.916016,46.068359 32,46.236328 32,26 64,26 64,0 C 64,0 24,0 16,0 z"
transform="translate(0,956.3622)"
id="rect2993"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccsccccccccc" />
<path
style="fill:#1872a2;fill-opacity:1;stroke:none"
d="m 80,1052.3622 c 8.990898,0 16.086165,-6.966 16,-16 0,0 0,-41.4991 0,-64 0.07767,-9.01639 -7.067354,-16 -16,-16 l -16,0 0,26 -32,0 0,22 32,0 0,22 -32,0 0,26 c 0,0 32,0 48,0 z"
id="rect2993-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccsccccccccc" />
</g>
<g
style="display:inline"
inkscape:label="Lines as original logo"
id="g3997"
inkscape:groupmode="layer">
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path3999"
d="m 64,0 0,26 -32,0 0,22 m 32,0 0,22 -32,0 0,26"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
ry="16"
rx="16"
y="0"
x="0"
height="96"
width="96"
id="rect4001"
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Lines with center break"
style="display:none">
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 64,0 0,26 -32,0 0,22 32,0 0,22 -32,0 0,26"
id="path3926"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<rect
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3928"
width="96"
height="96"
x="0"
y="0"
rx="16"
ry="16" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Effects"
style="display:inline">
<rect
style="fill:url(#linearGradient3930);fill-opacity:1;stroke:none"
id="rect3823"
width="96"
height="48.04369"
x="-3.1086245e-15"
y="1.8024861e-14"
ry="15.215644"
rx="15.214664" />
<rect
style="fill:url(#linearGradient3904);fill-opacity:1;stroke:none"
id="rect3823-8"
width="96"
height="47.86721"
x="1.5376101e-14"
y="-96"
ry="15.159752"
rx="15.214664"
transform="scale(1,-1)" />
<rect
style="fill:url(#linearGradient4011);fill-opacity:1;stroke:none;filter:url(#filter4059)"
id="rect4003"
width="98"
height="24"
x="0"
y="0"
rx="15.214664"
ry="8.2994423"
transform="matrix(1.0296115,0,0,1.1963836,-2.901924,-4.7132067)" />
<rect
style="opacity:0.56746030000000003;fill:url(#linearGradient4021);fill-opacity:1;stroke:none;filter:url(#filter4055)"
id="rect4013"
width="96"
height="24"
x="0"
y="72"
rx="14.008356"
ry="12"
transform="matrix(0.9768331,0,0,0.91974646,1.1649641,8.098115)" />
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg2" width="96" height="96" version="1.1"><defs id="defs4"><linearGradient id="highlightgradient"><stop id="stop3833" offset="0" style="stop-color:#fff;stop-opacity:.74374998"/><stop style="stop-color:#fff;stop-opacity:0" id="stop3829" offset="1"/></linearGradient><linearGradient id="shadowgradient"><stop id="stop3833-5" offset="0" style="stop-color:#000;stop-opacity:.5"/><stop style="stop-color:#818080;stop-opacity:0" id="stop3829-9" offset="1"/></linearGradient><linearGradient id="linearGradient4011" x1="44.948" x2="54.103" y1="0" y2="46.797" gradientTransform="scale(1,0.54545455)" gradientUnits="userSpaceOnUse" xlink:href="#highlightgradient"/><linearGradient id="linearGradient4021" x1="52.017" x2="42.868" y1="96" y2="41.838" gradientTransform="matrix(1,0,0,0.5,0,48)" gradientUnits="userSpaceOnUse" xlink:href="#shadowgradient"/><filter id="filter4055" width="1.06" height="1.24" x="-.03" y="-.12"><feGaussianBlur id="feGaussianBlur4057" stdDeviation="1.2"/></filter><filter id="filter4059" width="1.06" height="1.244" x="-.03" y="-.122"><feGaussianBlur id="feGaussianBlur4061" stdDeviation="1.22"/></filter></defs><metadata id="metadata7"/><g id="layer1" transform="translate(0,-956.3622)" style="display:inline"><path style="fill:#ffc019;fill-opacity:1;stroke:none" id="rect2993" d="M 16,0 C 7.0091019,0.04308252 0,7.0521845 0,16 0,16 0,57.499123 0,80 0,89.120146 7.0091019,96 16,96 L 32,96 32,70 64,70 63.916016,46.068359 32,46.236328 32,26 64,26 64,0 C 64,0 24,0 16,0 z" transform="translate(0,956.3622)"/><path style="fill:#1872a2;fill-opacity:1;stroke:none" id="rect2993-6" d="m 80,1052.3622 c 8.990898,0 16.086165,-6.966 16,-16 0,0 0,-41.4991 0,-64 0.07767,-9.01639 -7.067354,-16 -16,-16 l -16,0 0,26 -32,0 0,22 32,0 0,22 -32,0 0,26 c 0,0 32,0 48,0 z"/></g><g style="display:inline" id="g3997"><path id="path3999" d="m 64,0 0,26 -32,0 0,22 m 32,0 0,22 -32,0 0,26" style="fill:none;stroke:#000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/><rect id="rect4001" width="96" height="96" x="0" y="0" rx="16" ry="16" style="fill:none;stroke:#000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/></g><g id="layer3" style="display:none"><path style="fill:none;stroke:#000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="path3926" d="m 64,0 0,26 -32,0 0,22 32,0 0,22 -32,0 0,26"/><rect style="fill:none;stroke:#000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="rect3928" width="96" height="96" x="0" y="0" rx="16" ry="16"/></g><g id="layer2" style="display:inline"><rect style="fill:url(#linearGradient3930);fill-opacity:1;stroke:none" id="rect3823" width="96" height="48.044" x="0" y="0" rx="15.215" ry="15.216"/><rect style="fill:url(#linearGradient3904);fill-opacity:1;stroke:none" id="rect3823-8" width="96" height="47.867" x="0" y="-96" rx="15.215" ry="15.16" transform="scale(1,-1)"/><rect style="fill:url(#linearGradient4011);fill-opacity:1;stroke:none;filter:url(#filter4059)" id="rect4003" width="98" height="24" x="0" y="0" rx="15.215" ry="8.299" transform="matrix(1.0296115,0,0,1.1963836,-2.901924,-4.7132067)"/><rect style="opacity:.56746030000000003;fill:url(#linearGradient4021);fill-opacity:1;stroke:none;filter:url(#filter4055)" id="rect4013" width="96" height="24" x="0" y="72" rx="14.008" ry="12" transform="matrix(0.9768331,0,0,0.91974646,1.1649641,8.098115)"/></g></svg>

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 625 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,004 B

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 932 B

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 866 B

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 B

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,003 B

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 885 B

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 938 B

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

After

Width:  |  Height:  |  Size: 221 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -77,6 +77,17 @@ class Process
$this->pid = $pid;
}
/**
* Set the process id
*
* @param integer $pid
* @return void
*/
public function setPid(int $pid)
{
$this->pid = $pid;
}
/**
* Log active processes into the "process" table
*/

View file

@ -50,6 +50,7 @@ class Worker
private static $lock_duration = 0;
private static $last_update;
private static $state;
private static $daemon_mode = null;
/**
* Processes the tasks that are in the workerqueue table
@ -96,6 +97,10 @@ class Worker
// We fetch the next queue entry that is about to be executed
while ($r = self::workerProcess()) {
if (self::IPCJobsExists(getmypid())) {
self::IPCDeleteJobState(getmypid());
}
// Don't refetch when a worker fetches tasks for multiple workers
$refetched = DI::config()->get('system', 'worker_multiple_fetch');
foreach ($r as $entry) {
@ -146,13 +151,17 @@ class Worker
if (time() > ($starttime + (DI::config()->get('system', 'cron_interval') * 60))) {
Logger::info('Process lifetime reached, respawning.');
self::unclaimProcess();
self::spawnWorker();
if (self::isDaemonMode()) {
self::IPCSetJobState(true);
} else {
self::spawnWorker();
}
return;
}
}
// Cleaning up. Possibly not needed, but it doesn't harm anything.
if (DI::config()->get('system', 'worker_daemon_mode', false)) {
if (self::isDaemonMode()) {
self::IPCSetJobState(false);
}
Logger::info("Couldn't select a workerqueue entry, quitting process", ['pid' => getmypid()]);
@ -190,7 +199,7 @@ class Worker
Logger::warning('Maximum processes reached, quitting.');
return false;
}
return true;
}
@ -412,6 +421,12 @@ class Worker
{
$a = DI::app();
$cooldown = DI::config()->get("system", "worker_cooldown", 0);
if ($cooldown > 0) {
Logger::info('Pre execution cooldown.', ['priority' => $queue["priority"], 'id' => $queue["id"], 'cooldown' => $cooldown]);
sleep($cooldown);
}
Logger::enableWorker($funcname);
Logger::info("Process start.", ['priority' => $queue["priority"], 'id' => $queue["id"]]);
@ -484,10 +499,8 @@ class Worker
DI::profiler()->saveLog(DI::logger(), "ID " . $queue["id"] . ": " . $funcname);
$cooldown = DI::config()->get("system", "worker_cooldown", 0);
if ($cooldown > 0) {
Logger::info('Cooldown.', ['priority' => $queue["priority"], 'id' => $queue["id"], 'cooldown' => $cooldown]);
Logger::info('Post execution cooldown.', ['priority' => $queue["priority"], 'id' => $queue["id"], 'cooldown' => $cooldown]);
sleep($cooldown);
}
}
@ -771,7 +784,7 @@ class Worker
// Are there fewer workers running as possible? Then fork a new one.
if (!DI::config()->get("system", "worker_dont_fork", false) && ($queues > ($active + 1)) && self::entriesExists()) {
Logger::info("There are fewer workers as possible, fork a new worker.", ['active' => $active, 'queues' => $queues]);
if (DI::config()->get('system', 'worker_daemon_mode', false)) {
if (self::isDaemonMode()) {
self::IPCSetJobState(true);
} else {
self::spawnWorker();
@ -780,7 +793,7 @@ class Worker
}
// if there are too much worker, we don't spawn a new one.
if (DI::config()->get('system', 'worker_daemon_mode', false) && ($active > $queues)) {
if (self::isDaemonMode() && ($active > $queues)) {
self::IPCSetJobState(false);
}
@ -1100,6 +1113,11 @@ class Worker
*/
private static function forkProcess(bool $do_cron)
{
if (DI::process()->isMinMemoryReached()) {
Logger::warning('Memory limit reached - quitting');
return;
}
// Children inherit their parent's database connection.
// To avoid problems we disconnect and connect both parent and child
DBA::disconnect();
@ -1111,22 +1129,40 @@ class Worker
} elseif ($pid) {
// The parent process continues here
DBA::connect();
Logger::info('Spawned new worker', ['cron' => $do_cron, 'pid' => $pid]);
self::IPCSetJobState(true, $pid);
Logger::info('Spawned new worker', ['pid' => $pid]);
$cycles = 0;
while (self::IPCJobsExists($pid) && (++$cycles < 100)) {
usleep(10000);
}
Logger::info('Spawned worker is ready', ['pid' => $pid, 'wait_cycles' => $cycles]);
return;
}
// We now are in the new worker
DBA::connect();
Logger::info('Worker spawned', ['cron' => $do_cron, 'pid' => getmypid()]);
DI::process()->start();
// We now are in the new worker
$pid = getmypid();
DBA::connect();
/// @todo Reinitialize the logger to set a new process_id and uid
DI::process()->setPid($pid);
$cycles = 0;
while (!self::IPCJobsExists($pid) && (++$cycles < 100)) {
usleep(10000);
}
Logger::info('Worker spawned', ['pid' => $pid, 'wait_cycles' => $cycles]);
self::processQueue($do_cron);
self::unclaimProcess();
self::IPCSetJobState(false, $pid);
DI::process()->end();
Logger::info('Worker ended', ['cron' => $do_cron, 'pid' => getmypid()]);
Logger::info('Worker ended', ['pid' => $pid]);
exit();
}
@ -1139,18 +1175,14 @@ class Worker
*/
public static function spawnWorker($do_cron = false)
{
// Worker and daemon are started from the command line.
// This means that this is executed by a PHP interpreter without runtime limitations
if (function_exists('pcntl_fork') && in_array(DI::mode()->getExecutor(), [Mode::DAEMON, Mode::WORKER])) {
if (self::isDaemonMode() && DI::config()->get('system', 'worker_fork')) {
self::forkProcess($do_cron);
} else {
$process = new Core\Process(DI::logger(), DI::mode(), DI::config(),
DI::modelProcess(), DI::app()->getBasePath(), getmypid());
$process->run('bin/worker.php', ['no_cron' => !$do_cron]);
}
// after spawning we have to remove the flag.
if (DI::config()->get('system', 'worker_daemon_mode', false)) {
if (self::isDaemonMode()) {
self::IPCSetJobState(false);
}
}
@ -1242,7 +1274,7 @@ class Worker
}
// Set the IPC flag to ensure an immediate process execution via daemon
if (DI::config()->get('system', 'worker_daemon_mode', false)) {
if (self::isDaemonMode()) {
self::IPCSetJobState(true);
}
@ -1267,7 +1299,7 @@ class Worker
}
// Quit on daemon mode
if (DI::config()->get('system', 'worker_daemon_mode', false)) {
if (self::isDaemonMode()) {
return $added;
}
@ -1361,12 +1393,27 @@ class Worker
* Set the flag if some job is waiting
*
* @param boolean $jobs Is there a waiting job?
* @param int $key Key number
* @throws \Exception
*/
public static function IPCSetJobState($jobs)
public static function IPCSetJobState(bool $jobs, int $key = 0)
{
$stamp = (float)microtime(true);
DBA::update('worker-ipc', ['jobs' => $jobs], ['key' => 1], true);
DBA::replace('worker-ipc', ['jobs' => $jobs, 'key' => $key]);
self::$db_duration += (microtime(true) - $stamp);
self::$db_duration_write += (microtime(true) - $stamp);
}
/**
* Delete a key entry
*
* @param int $key Key number
* @throws \Exception
*/
public static function IPCDeleteJobState(int $key)
{
$stamp = (float)microtime(true);
DBA::delete('worker-ipc', ['key' => $key]);
self::$db_duration += (microtime(true) - $stamp);
self::$db_duration_write += (microtime(true) - $stamp);
}
@ -1374,13 +1421,14 @@ class Worker
/**
* Checks if some worker job waits to be executed
*
* @param int $key Key number
* @return bool
* @throws \Exception
*/
public static function IPCJobsExists()
public static function IPCJobsExists(int $key = 0)
{
$stamp = (float)microtime(true);
$row = DBA::selectFirst('worker-ipc', ['jobs'], ['key' => 1]);
$row = DBA::selectFirst('worker-ipc', ['jobs'], ['key' => $key]);
self::$db_duration += (microtime(true) - $stamp);
// When we don't have a row, no job is running
@ -1391,6 +1439,51 @@ class Worker
return (bool)$row['jobs'];
}
/**
* Checks if the worker is running in the daemon mode.
*
* @return boolean
*/
public static function isDaemonMode()
{
if (!is_null(self::$daemon_mode)) {
return self::$daemon_mode;
}
if (DI::mode()->getExecutor() == Mode::DAEMON) {
return true;
}
$daemon_mode = DI::config()->get('system', 'worker_daemon_mode', false, true);
if ($daemon_mode) {
return $daemon_mode;
}
if (!function_exists('pcntl_fork')) {
self::$daemon_mode = false;
return false;
}
$pidfile = DI::config()->get('system', 'pidfile');
if (empty($pidfile)) {
// No pid file, no daemon
self::$daemon_mode = false;
return false;
}
if (!is_readable($pidfile)) {
// No pid file. We assume that the daemon had been intentionally stopped.
self::$daemon_mode = false;
return false;
}
$pid = intval(file_get_contents($pidfile));
$running = posix_kill($pid, 0);
self::$daemon_mode = $running;
return $running;
}
/**
* Test if the daemon is running. If not, it will be started
*

View file

@ -1159,6 +1159,9 @@ class User
return false;
}
// Delete the avatar
Photo::delete(['uid' => $register['uid']]);
return DBA::delete('user', ['uid' => $register['uid']]) &&
Register::deleteByHash($register['hash']);
}

View file

@ -24,6 +24,7 @@ namespace Friendica\Worker;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Tag;
@ -54,6 +55,10 @@ class Cron
copy($basepath . '/.htaccess-dist', $basepath . '/.htaccess');
}
if (DI::config()->get('system', 'delete_sleeping_processes')) {
self::deleteSleepingProcesses();
}
// Fork the cron jobs in separate parts to avoid problems when one of them is crashing
Hook::fork(PRIORITY_MEDIUM, 'cron');
@ -137,4 +142,25 @@ class Cron
DI::config()->set('system', 'last_cron', time());
}
/**
* Kill sleeping database processes
*
* @return void
*/
private static function deleteSleepingProcesses()
{
Logger::info('Looking for sleeping processes');
$processes = DBA::p("SHOW FULL PROCESSLIST");
while ($process = DBA::fetch($processes)) {
if (($process['Command'] != 'Sleep') || ($process['Time'] < 300) || ($process['db'] != DBA::databaseName())) {
continue;
}
DBA::e("KILL ?", $process['Id']);
Logger::notice('Killed sleeping process', ['id' => $process['Id']]);
}
DBA::close($processes);
}
}

View file

@ -194,6 +194,10 @@ return [
// If it is not running and hadn't been terminated normally, it will be started automatically.
'daemon_watchdog' => false,
// delete_sleeping_processes (Boolean)
// Periodically delete waiting database processes.
'delete_sleeping_processes' => false,
// diaspora_test (Boolean)
// For development only. Disables the message transfer.
'diaspora_test' => false,
@ -534,6 +538,11 @@ return [
// Number of worker tasks that are fetched in a single query.
'worker_fetch_limit' => 1,
// worker_fork (Boolean)
// Experimental setting. Use pcntl_fork to spawn a new worker process.
// Does not work when "worker_multiple_fetch" is enabled (Needs more testing)
'worker_fork' => false,
// worker_jpm (Boolean)
// If enabled, it prints out the jobs per minute.
'worker_jpm' => false,
@ -551,6 +560,7 @@ return [
// worker_multiple_fetch (Boolean)
// When activated, the worker fetches jobs for multiple workers (not only for itself).
// This is an experimental setting without knowing the performance impact.
// Does not work when "worker_fork" is enabled (Needs more testing)
'worker_multiple_fetch' => false,
// worker_defer_limit (Integer)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 229 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 264 KiB

After

Width:  |  Height:  |  Size: 258 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 284 KiB

After

Width:  |  Height:  |  Size: 278 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 259 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 277 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 285 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 252 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 285 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 266 KiB

After

Width:  |  Height:  |  Size: 260 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 264 KiB

After

Width:  |  Height:  |  Size: 258 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 290 KiB

After

Width:  |  Height:  |  Size: 283 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View file

@ -1,17 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="logo_mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"> >
<path
d="M 3.373397,24.925245 3.1938175,24.864033 C 2.9783852,24.790602 2.7764427,24.711452 2.576333,24.622018 2.1356898,24.425082 1.5892046,24.079338 1.3712245,23.859582 c -0.2590846,-0.261194 -1.09281192,-1.09343 -1.38119999,-1.57298 0,0 0.04301756,-13.080693 0.03682785,-18.90953 C 0.18855639,2.6656386 0.64742664,2.0535848 0.99775771,1.5652652 1.6072296,0.97025411 2.5701313,0.19769558 2.9678895,0.09950949 c 0,0 12.9137435,-0.01484001 18.7039335,-0.05867517 0.847454,0.33698487 1.568727,0.88542472 2.11547,1.39213058 0.494844,0.4061206 0.731319,1.0034068 0.991156,1.5173636 0.08059,6.4402732 0.282614,12.9244675 0.19849,18.0961945 -0.343259,1.893337 -1.391611,3.042648 -2.974927,3.719347 -0.09256,0.02206 -0.277975,0.06698 -0.412038,0.09983 -6.265977,0.251978 -12.772934,0.154464 -18.216577,0.05954 z m 17.765379,-1.071592 c 0.761914,-0.07648 1.302942,-0.483573 1.80374,-0.883622 0.367357,-0.361514 0.877684,-0.872658 0.975573,-1.28968 0.28152,-6.286673 -0.0046,-12.5361934 -0.03236,-18.283829 C 23.789738,3.1265829 23.574866,2.7623056 23.332691,2.459023 22.762957,1.7080191 21.824771,1.336704 21.096224,1.0480279 19.421104,0.93184658 18.373471,0.94587766 16.992164,0.9257547 c -6.01e-4,2.2079105 0.0093,4.417548 -0.0085,6.6245631 -2.573444,0.038646 -5.159205,0.044099 -7.9906245,0.076741 -0.00473,1.7025313 -0.00312,3.0000532 -0.00312,4.8341202 2.6428485,0.01943 5.2871665,0.04325 7.9284675,0.10321 0.08164,1.990898 0.123956,3.951248 0.02955,5.922013 -2.797791,0.05135 -4.983297,0.0798 -7.9548925,0.12738 -0.00163,1.883617 -0.014112,3.365037 0.012505,5.357484 4.2382165,-0.0779 8.4402525,0.04732 12.1332265,-0.117613 z"
style="fill-rule:evenodd;clip-rule:evenodd;fill:#ffffff;" />
</mask>
</defs>
<g id="layer1">
<path
d="M 3.373397,24.925245 3.1938175,24.864033 C 2.9783852,24.790602 2.7764427,24.711452 2.576333,24.622018 2.1356898,24.425082 1.5892046,24.079338 1.3712245,23.859582 c -0.2590846,-0.261194 -1.09281192,-1.09343 -1.38119999,-1.57298 0,0 0.04301756,-13.080693 0.03682785,-18.90953 C 0.18855639,2.6656386 0.64742664,2.0535848 0.99775771,1.5652652 1.6072296,0.97025411 2.5701313,0.19769558 2.9678895,0.09950949 c 0,0 12.9137435,-0.01484001 18.7039335,-0.05867517 0.847454,0.33698487 1.568727,0.88542472 2.11547,1.39213058 0.494844,0.4061206 0.731319,1.0034068 0.991156,1.5173636 0.08059,6.4402732 0.282614,12.9244675 0.19849,18.0961945 -0.343259,1.893337 -1.391611,3.042648 -2.974927,3.719347 -0.09256,0.02206 -0.277975,0.06698 -0.412038,0.09983 -6.265977,0.251978 -12.772934,0.154464 -18.216577,0.05954 z m 17.765379,-1.071592 c 0.761914,-0.07648 1.302942,-0.483573 1.80374,-0.883622 0.367357,-0.361514 0.877684,-0.872658 0.975573,-1.28968 0.28152,-6.286673 -0.0046,-12.5361934 -0.03236,-18.283829 C 23.789738,3.1265829 23.574866,2.7623056 23.332691,2.459023 22.762957,1.7080191 21.824771,1.336704 21.096224,1.0480279 19.421104,0.93184658 18.373471,0.94587766 16.992164,0.9257547 c -6.01e-4,2.2079105 0.0093,4.417548 -0.0085,6.6245631 -2.573444,0.038646 -5.159205,0.044099 -7.9906245,0.076741 -0.00473,1.7025313 -0.00312,3.0000532 -0.00312,4.8341202 2.6428485,0.01943 5.2871665,0.04325 7.9284675,0.10321 0.08164,1.990898 0.123956,3.951248 0.02955,5.922013 -2.797791,0.05135 -4.983297,0.0798 -7.9548925,0.12738 -0.00163,1.883617 -0.014112,3.365037 0.012505,5.357484 4.2382165,-0.0779 8.4402525,0.04732 12.1332265,-0.117613 z"
id="path3425"
style="fill:#000000" />
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"><defs><mask id="logo_mask" maskContentUnits="objectBoundingBox" maskUnits="objectBoundingBox">&gt;<path d="M 3.373397,24.925245 3.1938175,24.864033 C 2.9783852,24.790602 2.7764427,24.711452 2.576333,24.622018 2.1356898,24.425082 1.5892046,24.079338 1.3712245,23.859582 c -0.2590846,-0.261194 -1.09281192,-1.09343 -1.38119999,-1.57298 0,0 0.04301756,-13.080693 0.03682785,-18.90953 C 0.18855639,2.6656386 0.64742664,2.0535848 0.99775771,1.5652652 1.6072296,0.97025411 2.5701313,0.19769558 2.9678895,0.09950949 c 0,0 12.9137435,-0.01484001 18.7039335,-0.05867517 0.847454,0.33698487 1.568727,0.88542472 2.11547,1.39213058 0.494844,0.4061206 0.731319,1.0034068 0.991156,1.5173636 0.08059,6.4402732 0.282614,12.9244675 0.19849,18.0961945 -0.343259,1.893337 -1.391611,3.042648 -2.974927,3.719347 -0.09256,0.02206 -0.277975,0.06698 -0.412038,0.09983 -6.265977,0.251978 -12.772934,0.154464 -18.216577,0.05954 z m 17.765379,-1.071592 c 0.761914,-0.07648 1.302942,-0.483573 1.80374,-0.883622 0.367357,-0.361514 0.877684,-0.872658 0.975573,-1.28968 0.28152,-6.286673 -0.0046,-12.5361934 -0.03236,-18.283829 C 23.789738,3.1265829 23.574866,2.7623056 23.332691,2.459023 22.762957,1.7080191 21.824771,1.336704 21.096224,1.0480279 19.421104,0.93184658 18.373471,0.94587766 16.992164,0.9257547 c -6.01e-4,2.2079105 0.0093,4.417548 -0.0085,6.6245631 -2.573444,0.038646 -5.159205,0.044099 -7.9906245,0.076741 -0.00473,1.7025313 -0.00312,3.0000532 -0.00312,4.8341202 2.6428485,0.01943 5.2871665,0.04325 7.9284675,0.10321 0.08164,1.990898 0.123956,3.951248 0.02955,5.922013 -2.797791,0.05135 -4.983297,0.0798 -7.9548925,0.12738 -0.00163,1.883617 -0.014112,3.365037 0.012505,5.357484 4.2382165,-0.0779 8.4402525,0.04732 12.1332265,-0.117613 z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"/></mask></defs><g id="layer1"><path id="path3425" d="M 3.373397,24.925245 3.1938175,24.864033 C 2.9783852,24.790602 2.7764427,24.711452 2.576333,24.622018 2.1356898,24.425082 1.5892046,24.079338 1.3712245,23.859582 c -0.2590846,-0.261194 -1.09281192,-1.09343 -1.38119999,-1.57298 0,0 0.04301756,-13.080693 0.03682785,-18.90953 C 0.18855639,2.6656386 0.64742664,2.0535848 0.99775771,1.5652652 1.6072296,0.97025411 2.5701313,0.19769558 2.9678895,0.09950949 c 0,0 12.9137435,-0.01484001 18.7039335,-0.05867517 0.847454,0.33698487 1.568727,0.88542472 2.11547,1.39213058 0.494844,0.4061206 0.731319,1.0034068 0.991156,1.5173636 0.08059,6.4402732 0.282614,12.9244675 0.19849,18.0961945 -0.343259,1.893337 -1.391611,3.042648 -2.974927,3.719347 -0.09256,0.02206 -0.277975,0.06698 -0.412038,0.09983 -6.265977,0.251978 -12.772934,0.154464 -18.216577,0.05954 z m 17.765379,-1.071592 c 0.761914,-0.07648 1.302942,-0.483573 1.80374,-0.883622 0.367357,-0.361514 0.877684,-0.872658 0.975573,-1.28968 0.28152,-6.286673 -0.0046,-12.5361934 -0.03236,-18.283829 C 23.789738,3.1265829 23.574866,2.7623056 23.332691,2.459023 22.762957,1.7080191 21.824771,1.336704 21.096224,1.0480279 19.421104,0.93184658 18.373471,0.94587766 16.992164,0.9257547 c -6.01e-4,2.2079105 0.0093,4.417548 -0.0085,6.6245631 -2.573444,0.038646 -5.159205,0.044099 -7.9906245,0.076741 -0.00473,1.7025313 -0.00312,3.0000532 -0.00312,4.8341202 2.6428485,0.01943 5.2871665,0.04325 7.9284675,0.10321 0.08164,1.990898 0.123956,3.951248 0.02955,5.922013 -2.797791,0.05135 -4.983297,0.0798 -7.9548925,0.12738 -0.00163,1.883617 -0.014112,3.365037 0.012505,5.357484 4.2382165,-0.0779 8.4402525,0.04732 12.1332265,-0.117613 z" style="fill:#000"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 389 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 357 KiB

After

Width:  |  Height:  |  Size: 352 KiB