Skip to content

Commit 81e3c8c

Browse files
committed
- to_ip_port now supports real ips
- updating server.md - updating man pages
1 parent 6d1ac55 commit 81e3c8c

File tree

9 files changed

+263
-191
lines changed

9 files changed

+263
-191
lines changed

docs/headless.html

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ <h2 id="table-of-contents">Table of Contents <span style="padding-left: 10px;"><
5050
</ul></li>
5151
<li><a href="#installation">Installation</a>
5252
<ul>
53+
<li><a href="#notice">Notice</a></li>
5354
<li><a href="#using-tmux">Using tmux</a>
5455
<ul>
5556
<li><a href="#systemd">systemd</a></li>
@@ -58,7 +59,8 @@ <h2 id="table-of-contents">Table of Contents <span style="padding-left: 10px;"><
5859
<ul>
5960
<li><a href="#systemd">systemd</a></li>
6061
</ul></li>
61-
<li><a href="#things-to-consider-for-systemd">Things to consider for systemd</a></li>
62+
<li><a href="#systemd-service-file">systemd service file</a></li>
63+
<li><a href="#notice-for-systemd-installation">Notice for systemd installation</a></li>
6264
</ul></li>
6365
</ul>
6466
<!-- vim-markdown-toc -->
@@ -118,6 +120,14 @@ <h3 id="how-it-works">How it works</h3>
118120
<h2 id="installation">Installation <span style="padding-left: 10px;"><sup style="font-size: 50%"><a href="#" title="Go to top of the page">Top</a></sup></span></h2>
119121
<p>By the term “installation”, we mean that we set up things in such a way, that after we log into the system, we find <strong>PyRadio</strong> ready to accept connections.</p>
120122
<p>So, the installation can be as easy as adding a line in a configuration file (or the startup section of the <em>desktop environment</em>) or as hard as adding a system service.</p>
123+
<h3 id="notice">Notice</h3>
124+
<p>The commands that follow use the following conventions:</p>
125+
<ol type="1">
126+
<li><p>The username is <strong>spiros</strong>.<br />
127+
Please replace it with your username.</p></li>
128+
<li><p><strong>PyRadio</strong> is installed from source; this means that its executable is <strong>~/.local/bin/pyradio</strong>. If this is not the case (using a distribution package, for example), please replace it with the correct one.</p></li>
129+
<li><p>Both <strong>tmux</strong> and <strong>screen</strong> are executed using their <em>absolute path</em> (<strong>/usr/bin/tmux</strong> and <strong>/usr/bin/screen</strong> respectively). If they are installed at a different location, please use the correct one instead.</p></li>
130+
</ol>
121131
<h3 id="using-tmux">Using tmux</h3>
122132
<p>If <strong>bash</strong> is the default shell, this would do the trick:</p>
123133
<pre>echo &quot;/usr/bin/tmux new-session \
@@ -129,65 +139,46 @@ <h3 id="using-tmux">Using tmux</h3>
129139
<h4 id="systemd">systemd</h4>
130140
<p>The first thing you do is create the log file:</p>
131141
<pre>touch ~/pyradio.log</pre>
132-
<p>Then create the start file:</p>
133-
<pre>mkdir ~/.local/bin
134-
echo &quot;#!/bin/bash&quot; &gt; ~/.local/bin/start-headless-pyradio.sh
135-
echo &quot;/usr/bin/tmux new-session -dA -s pyradio-session /home/spiros/.local/bin/pyradio --headless auto&quot; &gt;&gt; ~/.local/bin/start-headless-pyradio.sh
136-
chmod +x ~/.local/bin/start-headless-pyradio.sh</pre>
137-
<p style="margin: 1.5em 4em 0 4em; text-indent: -2.5em;"><strong>Note:</strong> You will want to replace the word “<em>spiros</em>” with your <strong>username</strong> in this file.</p>
138-
<p>Then create the stop file:</p>
139-
<pre>echo &quot;#!/bin/bash&quot; &gt; ~/.local/bin/stop-headless-pyradio.sh
140-
echo &quot;/usr/bin/tmux send-keys -t pyradio-session q&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
141-
echo &quot;sleep 1&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
142-
echo &quot;/usr/bin/tmux send-keys -t pyradio-session q&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
142+
<p>Then create the start file. Write this to <strong>~/.local/bin/start-headless-pyradio.sh</strong></p>
143+
<pre>#!/bin/bash
144+
/usr/bin/tmux new-session -dA -s pyradio-session /home/spiros/.local/bin/pyradio --headless auto</pre>
145+
<p>Then create the stop file. Writhe this to <strong>~/.local/bin/stop-headless-pyradio.sh</strong></p>
146+
<pre>#!/bin/bash
147+
[ -z &quot;$(/usr/bin/tmux ls | grep pyradio-session)&quot; ] || /usr/bin/tmux send-keys -t pyradio-session q
148+
sleep 2
149+
[ -z &quot;$(/usr/bin/tmux ls | grep pyradio-session)&quot; ] || /usr/bin/tmux send-keys -t pyradio-session q
150+
[ -e /home/spiros/.config/pyradio/data/server-headless.txt ] &amp;&amp; rm /home/spiros/.config/pyradio/data/server-headless.txt</pre>
151+
<p>Make both files executable:</p>
152+
<pre>chmod +x ~/.local/bin/start-headless-pyradio.sh
143153
chmod +x ~/.local/bin/stop-headless-pyradio.sh</pre>
144-
<p>Finally create the service:</p>
145-
<p>File <em>/lib/systemd/system/pyradio.service</em></p>
146-
<pre>[Unit]
147-
Description=PyRadio Service
148-
After=multi-user.target
149-
150-
[Service]
151-
Type=forking
152-
User=spiros
153-
Environment=&quot;XDG_RUNTIME_DIR=/run/user/1000&quot;
154-
Environment=&quot;PULSE_RUNTIME_PATH=/run/user/1000/pulse/&quot;
155-
StandardOutput=append:/home/spiros/pyradio.log
156-
StandardError=append:/home/spiros/pyradio.log
157-
ExecStart=/home/spiros/.local/bin/start-headless-pyradio.sh
158-
ExecStop=/home/spiros/.local/bin/stop-headless-pyradio.sh
159-
160-
[Install]
161-
WantedBy=multi-user.target</pre>
162-
<p>Then execute:</p>
163-
<pre>$ sudo chmod 644 /lib/systemd/system/pyradio.service
164-
$ sudo systemctl daemon-reload
165-
$ sudo systemctl enable pyradio # enabling the autostart on every boot</pre>
154+
<p>Now you are ready to create the <a href="#systemd-service-file">service file</a>.</p>
166155
<h3 id="using-screen">Using screen</h3>
167156
<p>If <strong>bash</strong> is the default shell, this would do the trick:</p>
168157
<pre>echo &quot;/usr/bin/screen -U -S pyradio-session -d -m \
169-
pyradio-session /home/spiros/.local/bin/pyradio \
158+
/home/spiros/.local/bin/pyradio \
170159
--headless auto&quot; &gt;&gt; ~/.profile</pre>
171160
<p>In case a <em>Window manager</em> is used, adding a line in its <strong>autostart</strong> file would be enough. For example, this would work for <strong>openbox</strong>:</p>
172-
<pre>echo &quot;(sleep 10; /usr/bin/screen -U -S pyradio-session -d -m pyradio-session /home/spiros/.local/bin/pyradio --headless auto)&quot; &gt;&gt; ~/.config/openbox/autostart</pre>
161+
<pre>echo &quot;(sleep 10; /usr/bin/screen -U -S pyradio-session -d -m /home/spiros/.local/bin/pyradio --headless auto)&quot; &gt;&gt; ~/.config/openbox/autostart</pre>
173162
<p>And so on, and so forth…</p>
174163
<h4 id="systemd-1">systemd</h4>
175164
<p>The first thing you do is create the log file:</p>
176165
<pre>touch ~/pyradio.log</pre>
177-
<p>Then create the start file:</p>
178-
<pre>mkdir ~/.local/bin
179-
echo &quot;#!/bin/bash&quot; &gt; ~/.local/bin/start-headless-pyradio.sh
180-
echo &quot;/usr/bin/screen -U -S pyradio-session -d -m pyradio-session /home/spiros/.local/bin/pyradio --headless auto&quot; &gt;&gt; ~/.local/bin/start-headless-pyradio.sh
181-
chmod +x ~/.local/bin/start-headless-pyradio.sh</pre>
182-
<p style="margin: 1.5em 4em 0 4em; text-indent: -2.5em;"><strong>Note:</strong> You will want to replace the word “<em>spiros</em>” with your <strong>username</strong> in this file.</p>
183-
<p>Then create the stop file:</p>
184-
<pre>echo &quot;#!/bin/bash&quot; &gt; ~/.local/bin/stop-headless-pyradio.sh
185-
echo &quot;/usr/bin/screen -S pyradio-session -p 0 -X stuff q&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
186-
echo &quot;sleep 1&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
187-
echo &quot;/usr/bin/screen -S pyradio-session -p 0 -X stuff q&quot; &gt;&gt; ~/.local/bin/stop-headless-pyradio.sh
166+
<p>Then create the start file. Write this to <strong>~/.local/bin/start-headless-pyradio.sh</strong></p>
167+
<pre>#!/bin/bash
168+
/usr/bin/screen -U -S pyradio-session -d -m /home/spiros/.local/bin/pyradio --headless auto</pre>
169+
<p>Then create the stop file. Writhe this to <strong>~/.local/bin/stop-headless-pyradio.sh</strong></p>
170+
<pre>#!/bin/bash
171+
[ -z &quot;$(/usr/bin/screen -ls | grep pyradio-session)&quot; ] || /usr/bin/screen -S pyradio-session -p 0 -X stuff q
172+
sleep 2
173+
[ -z &quot;$(/usr/bin/screen -ls | grep pyradio-session)&quot; ] || /usr/bin/screen -S pyradio-session -p 0 -X stuff q
174+
[ -e /home/spiros/.config/pyradio/data/server-headless.txt ] &amp;&amp; rm /home/spiros/.config/pyradio/data/server-headless.txt
175+
</pre>
176+
<p>Make both files executable:</p>
177+
<pre>chmod +x ~/.local/bin/start-headless-pyradio.sh
188178
chmod +x ~/.local/bin/stop-headless-pyradio.sh</pre>
189-
<p>Finally create the service:</p>
190-
<p>File <em>/lib/systemd/system/pyradio.service</em></p>
179+
<p>Now you are ready to create the service file</p>
180+
<h3 id="systemd-service-file">systemd service file</h3>
181+
<p>Create the file <strong>/lib/systemd/system/pyradio.service</strong></p>
191182
<pre>[Unit]
192183
Description=PyRadio Service
193184
After=multi-user.target
@@ -205,17 +196,12 @@ <h4 id="systemd-1">systemd</h4>
205196
[Install]
206197
WantedBy=multi-user.target</pre>
207198
<p>Then execute:</p>
208-
<pre>$ sudo chmod 644 /lib/systemd/system/pyradio.service
209-
$ sudo systemctl daemon-reload
210-
$ sudo systemctl enable pyradio # enabling the autostart on every boot</pre>
211-
<h3 id="things-to-consider-for-systemd">Things to consider for systemd</h3>
212-
<ol type="1">
213-
<li><p>You will want to replace the word “<em>spiros</em>” with your <strong>username</strong> in the <em>/lib/systemd/system/pyradio.service</em> file.</p></li>
214-
<li><p>The service file has two lines starting with “<em>Environment=</em><br />
215-
<br />
216-
These two lines provide an environment for <em>systemd</em>; I’ve found out that on Arch Linux, for example, <strong>PyRadio</strong> would produce no sound at all without them (actually not connection to the sound server).<br />
217-
<br />
218-
On other systems, on Raspberry Pi for example, they can be omitted altogether.</p></li>
219-
</ol>
199+
<pre>sudo chmod 644 /lib/systemd/system/pyradio.service
200+
sudo systemctl daemon-reload
201+
sudo systemctl enable pyradio # enabling the autostart on every boot</pre>
202+
<h3 id="notice-for-systemd-installation">Notice for systemd installation</h3>
203+
<p>The service file has two lines starting with “<em>Environment=</em></p>
204+
<p>These two lines provide an environment for <em>systemd</em>; I’ve found out that on Arch Linux, for example, <strong>PyRadio</strong> would produce no sound at all without them (it would not be able to connect to the sound server).</p>
205+
<p>On other systems, on Raspberry Pi for example, they can be omitted altogether.</p>
220206
</body>
221207
</html>

docs/headless.md

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
* [Usage](#usage)
88
* [How it works](#how-it-works)
99
* [Installation](#installation)
10+
* [Notice](#notice)
1011
* [Using tmux](#using-tmux)
1112
* [systemd](#systemd)
1213
* [Using screen](#using-screen)
1314
* [systemd](#systemd)
14-
* [Things to consider for systemd](#things-to-consider-for-systemd)
15+
* [systemd service file](#systemd-service-file)
16+
* [Notice for systemd installation](#notice-for-systemd-installation)
1517

1618
<!-- vim-markdown-toc -->
1719

@@ -108,6 +110,17 @@ By the term "installation", we mean that we set up things in such a way, that af
108110

109111
So, the installation can be as easy as adding a line in a configuration file (or the startup section of the *desktop environment*) or as hard as adding a system service.
110112

113+
### Notice
114+
115+
The commands that follow use the following conventions:
116+
117+
1. The username is **spiros**. \
118+
Please replace it with your username.
119+
120+
2. **PyRadio** is installed from source; this means that its executable is **~/.local/bin/pyradio**. If this is not the case (using a distribution package, for example), please replace it with the correct one.
121+
122+
3. Both **tmux** and **screen** are executed using their *absolute path* (**/usr/bin/tmux** and **/usr/bin/screen** respectively). If they are installed at a different location, please use the correct one instead.
123+
111124
### Using tmux
112125

113126
If **bash** is the default shell, this would do the trick:
@@ -131,66 +144,43 @@ The first thing you do is create the log file:
131144

132145
touch ~/pyradio.log
133146

134-
Then create the start file:
135-
136-
mkdir ~/.local/bin
137-
echo "#!/bin/bash" > ~/.local/bin/start-headless-pyradio.sh
138-
echo "/usr/bin/tmux new-session -dA -s pyradio-session /home/spiros/.local/bin/pyradio --headless auto" >> ~/.local/bin/start-headless-pyradio.sh
139-
chmod +x ~/.local/bin/start-headless-pyradio.sh
140-
141-
**Note:** You will want to replace the word "*spiros*" with your **username** in this file.
142-
143-
Then create the stop file:
144-
145-
echo "#!/bin/bash" > ~/.local/bin/stop-headless-pyradio.sh
146-
echo "/usr/bin/tmux send-keys -t pyradio-session q" >> ~/.local/bin/stop-headless-pyradio.sh
147-
echo "sleep 1" >> ~/.local/bin/stop-headless-pyradio.sh
148-
echo "/usr/bin/tmux send-keys -t pyradio-session q" >> ~/.local/bin/stop-headless-pyradio.sh
149-
chmod +x ~/.local/bin/stop-headless-pyradio.sh
147+
Then create the start file. Write this to **~/.local/bin/start-headless-pyradio.sh**
150148

151-
Finally create the service:
149+
```
150+
#!/bin/bash
151+
/usr/bin/tmux new-session -dA -s pyradio-session /home/spiros/.local/bin/pyradio --headless auto
152+
```
152153

153-
File */lib/systemd/system/pyradio.service*
154+
Then create the stop file. Writhe this to **~/.local/bin/stop-headless-pyradio.sh**
154155

155156
```
156-
[Unit]
157-
Description=PyRadio Service
158-
After=multi-user.target
157+
#!/bin/bash
158+
[ -z "$(/usr/bin/tmux ls | grep pyradio-session)" ] || /usr/bin/tmux send-keys -t pyradio-session q
159+
sleep 2
160+
[ -z "$(/usr/bin/tmux ls | grep pyradio-session)" ] || /usr/bin/tmux send-keys -t pyradio-session q
161+
[ -e /home/spiros/.config/pyradio/data/server-headless.txt ] && rm /home/spiros/.config/pyradio/data/server-headless.txt
162+
```
159163

160-
[Service]
161-
Type=forking
162-
User=spiros
163-
Environment="XDG_RUNTIME_DIR=/run/user/1000"
164-
Environment="PULSE_RUNTIME_PATH=/run/user/1000/pulse/"
165-
StandardOutput=append:/home/spiros/pyradio.log
166-
StandardError=append:/home/spiros/pyradio.log
167-
ExecStart=/home/spiros/.local/bin/start-headless-pyradio.sh
168-
ExecStop=/home/spiros/.local/bin/stop-headless-pyradio.sh
164+
Make both files executable:
169165

170-
[Install]
171-
WantedBy=multi-user.target
172-
```
166+
chmod +x ~/.local/bin/start-headless-pyradio.sh
167+
chmod +x ~/.local/bin/stop-headless-pyradio.sh
173168

174-
Then execute:
175-
```
176-
$ sudo chmod 644 /lib/systemd/system/pyradio.service
177-
$ sudo systemctl daemon-reload
178-
$ sudo systemctl enable pyradio # enabling the autostart on every boot
179-
```
169+
Now you are ready to create the [service file](#systemd-service-file).
180170

181171
### Using screen
182172

183173
If **bash** is the default shell, this would do the trick:
184174
```
185175
echo "/usr/bin/screen -U -S pyradio-session -d -m \
186-
pyradio-session /home/spiros/.local/bin/pyradio \
176+
/home/spiros/.local/bin/pyradio \
187177
--headless auto" >> ~/.profile
188178
```
189179

190180
In case a *Window manager* is used, adding a line in its **autostart** file would be enough. For example, this would work for **openbox**:
191181

192182
```
193-
echo "(sleep 10; /usr/bin/screen -U -S pyradio-session -d -m pyradio-session /home/spiros/.local/bin/pyradio --headless auto)" >> ~/.config/openbox/autostart
183+
echo "(sleep 10; /usr/bin/screen -U -S pyradio-session -d -m /home/spiros/.local/bin/pyradio --headless auto)" >> ~/.config/openbox/autostart
194184
```
195185

196186
And so on, and so forth...
@@ -201,26 +191,34 @@ The first thing you do is create the log file:
201191

202192
touch ~/pyradio.log
203193

204-
Then create the start file:
194+
Then create the start file. Write this to **~/.local/bin/start-headless-pyradio.sh**
205195

206-
mkdir ~/.local/bin
207-
echo "#!/bin/bash" > ~/.local/bin/start-headless-pyradio.sh
208-
echo "/usr/bin/screen -U -S pyradio-session -d -m pyradio-session /home/spiros/.local/bin/pyradio --headless auto" >> ~/.local/bin/start-headless-pyradio.sh
209-
chmod +x ~/.local/bin/start-headless-pyradio.sh
196+
```
197+
#!/bin/bash
198+
/usr/bin/screen -U -S pyradio-session -d -m /home/spiros/.local/bin/pyradio --headless auto
199+
```
210200

211-
**Note:** You will want to replace the word "*spiros*" with your **username** in this file.
201+
Then create the stop file. Writhe this to **~/.local/bin/stop-headless-pyradio.sh**
212202

213-
Then create the stop file:
203+
```
204+
#!/bin/bash
205+
[ -z "$(/usr/bin/screen -ls | grep pyradio-session)" ] || /usr/bin/screen -S pyradio-session -p 0 -X stuff q
206+
sleep 2
207+
[ -z "$(/usr/bin/screen -ls | grep pyradio-session)" ] || /usr/bin/screen -S pyradio-session -p 0 -X stuff q
208+
[ -e /home/spiros/.config/pyradio/data/server-headless.txt ] && rm /home/spiros/.config/pyradio/data/server-headless.txt
214209
215-
echo "#!/bin/bash" > ~/.local/bin/stop-headless-pyradio.sh
216-
echo "/usr/bin/screen -S pyradio-session -p 0 -X stuff q" >> ~/.local/bin/stop-headless-pyradio.sh
217-
echo "sleep 1" >> ~/.local/bin/stop-headless-pyradio.sh
218-
echo "/usr/bin/screen -S pyradio-session -p 0 -X stuff q" >> ~/.local/bin/stop-headless-pyradio.sh
210+
```
211+
212+
Make both files executable:
213+
214+
chmod +x ~/.local/bin/start-headless-pyradio.sh
219215
chmod +x ~/.local/bin/stop-headless-pyradio.sh
220216

221-
Finally create the service:
217+
Now you are ready to create the service file
222218

223-
File */lib/systemd/system/pyradio.service*
219+
### systemd service file
220+
221+
Create the file **/lib/systemd/system/pyradio.service**
224222

225223
```
226224
[Unit]
@@ -243,18 +241,16 @@ WantedBy=multi-user.target
243241

244242
Then execute:
245243
```
246-
$ sudo chmod 644 /lib/systemd/system/pyradio.service
247-
$ sudo systemctl daemon-reload
248-
$ sudo systemctl enable pyradio # enabling the autostart on every boot
244+
sudo chmod 644 /lib/systemd/system/pyradio.service
245+
sudo systemctl daemon-reload
246+
sudo systemctl enable pyradio # enabling the autostart on every boot
249247
```
250248

251-
### Things to consider for systemd
249+
### Notice for systemd installation
250+
251+
The service file has two lines starting with "*Environment=*"
252252

253-
1. You will want to replace the word "*spiros*" with your **username** in the */lib/systemd/system/pyradio.service* file.
253+
These two lines provide an environment for *systemd*; I've found out that on Arch Linux, for example, **PyRadio** would produce no sound at all without them (it would not be able to connect to the sound server).
254254

255-
2. The service file has two lines starting with "*Environment=*" \
256-
\
257-
These two lines provide an environment for *systemd*; I've found out that on Arch Linux, for example, **PyRadio** would produce no sound at all without them (actually not connection to the sound server). \
258-
\
259255
On other systems, on Raspberry Pi for example, they can be omitted altogether.
260256

docs/pyradio.1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.\" Copyright (C) 2011 Ben Dowling <http://www.coderholic.com/pyradio>
2-
.\" Copyright (C) 2018-2023 Spiros Georgaras <[email protected]>
2+
.\" Copyright (C) 2018-2024 Spiros Georgaras <[email protected]>
33
.\" This manual is freely distributable under the terms of the GPL.
44
.\"
5-
.TH pyradio 1 "November 2023" pyradio
5+
.TH pyradio 1 "January 2024" pyradio
66

77
.SH Name
88
.PP

docs/pyradio_rb.1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
.\" Copyright (C) 2018-2023 Spiros Georgaras <[email protected]>
1+
.\" Copyright (C) 2018-2024 Spiros Georgaras <[email protected]>
22
.\" This manual is freely distributable under the terms of the GPL.
33
.\"
4-
.TH pyradio_rb 1 "November 2023" pyradio
4+
.TH pyradio_rb 1 "January 2024" pyradio
55

66
.SH Name
77
.PP

docs/pyradio_rec.1

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH pyradio_rec 1 "November 2023" pyradio
1+
.TH pyradio_rec 1 "January 2024" pyradio
22

33
.SH Name
44
.PP
@@ -384,10 +384,9 @@ directory\fR.
384384
If \fBMKVToolNix\fR is not installed, the file will be downloaded in
385385
this directory and will not be altered by \fBpyradio\fR.
386386
.PP
387-
If \fBMKVToolNix\fR is installed, the file will initially be
388-
downloaded in the \[lq]\fIdata\fR\[rq] directory; the final file,
389-
after chapters addition, will be placed in the \fBrecordings\fR
390-
directory and the downloaded file will be deleted.
387+
If \fBMKVToolNix\fR is installed, a “\fItmp_\fR” prefix will be added
388+
to the recorded filename, which will be removed after chapters addition.
389+
391390
.SS Pausing playback
392391
.PP
393392
After you have started recording a station, \fBpyradio\fR will

0 commit comments

Comments
 (0)