Skip to content

Commit fe6e3c5

Browse files
committed
Build scripts improved, QtCreator build fixed.
qmake and travis builds use -j4 for make.
1 parent 0854dba commit fe6e3c5

7 files changed

Lines changed: 234 additions & 98 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/Telegram/Target
1+
/Telegram/build/target
22
/Telegram/GeneratedFiles/
33
/Telegram/SourceFiles/art/grid.png
44
/Telegram/SourceFiles/art/grid_125x.png

.travis/build.sh

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,37 +102,37 @@ build() {
102102
./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \
103103
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
104104
-qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests
105-
make --silent -j
106-
make --silent -j install
105+
make --silent -j4
106+
make --silent -j4 install
107107

108108
export PATH="$srcdir/qt/bin:$PATH"
109109

110110
info_msg "Build breakpad"
111111
# Build breakpad
112112
cd "$srcdir/Libraries/breakpad"
113113
./configure
114-
make --silent -j
115-
116-
info_msg "Build codegen_style"
117-
# Build codegen_style
118-
mkdir -p "$srcdir/tdesktop/Linux/obj/codegen_style/Debug"
119-
cd "$srcdir/tdesktop/Linux/obj/codegen_style/Debug"
120-
qmake CONFIG+=debug "../../../../Telegram/build/qmake/codegen_style/codegen_style.pro"
121-
make --silent -j
122-
123-
info_msg "Build codegen_numbers"
124-
# Build codegen_numbers
125-
mkdir -p "$srcdir/tdesktop/Linux/obj/codegen_numbers/Debug"
126-
cd "$srcdir/tdesktop/Linux/obj/codegen_numbers/Debug"
127-
qmake CONFIG+=debug "../../../../Telegram/build/qmake/codegen_numbers/codegen_numbers.pro"
128-
make --silent -j
114+
make --silent -j4
115+
116+
info_msg "Build codegen_style"
117+
# Build codegen_style
118+
mkdir -p "$srcdir/tdesktop/Linux/obj/codegen_style/Debug"
119+
cd "$srcdir/tdesktop/Linux/obj/codegen_style/Debug"
120+
qmake CONFIG+=debug "../../../../Telegram/build/qmake/codegen_style/codegen_style.pro"
121+
make --silent -j4
122+
123+
info_msg "Build codegen_numbers"
124+
# Build codegen_numbers
125+
mkdir -p "$srcdir/tdesktop/Linux/obj/codegen_numbers/Debug"
126+
cd "$srcdir/tdesktop/Linux/obj/codegen_numbers/Debug"
127+
qmake CONFIG+=debug "../../../../Telegram/build/qmake/codegen_numbers/codegen_numbers.pro"
128+
make --silent -j4
129129

130130
info_msg "Build MetaLang"
131131
# Build MetaLang
132132
mkdir -p "$srcdir/tdesktop/Linux/DebugIntermediateLang"
133133
cd "$srcdir/tdesktop/Linux/DebugIntermediateLang"
134134
qmake CONFIG+=debug "../../Telegram/MetaLang.pro"
135-
make --silent -j
135+
make --silent -j4
136136

137137
info_msg "Build Telegram Desktop"
138138
# Build Telegram Desktop
@@ -141,9 +141,9 @@ build() {
141141

142142
./../codegen/Debug/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild
143143
./../codegen/Debug/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt"
144-
./../DebugLang/MetaLang -lang_in ./../../Telegram/Resources/lang.strings -lang_out ./GeneratedFiles/lang_auto
144+
./../DebugLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto
145145
qmake CONFIG+=debug "../../Telegram/Telegram.pro"
146-
make -j
146+
make -j4
147147
}
148148

149149
check() {

Telegram/build/build.sh

100644100755
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,12 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
134134
mkdir -p "$WorkPath/ReleaseIntermediate"
135135
cd "$WorkPath/ReleaseIntermediate"
136136
"$QMakePath" "$HomePath/Telegram.pro" -r -spec linux-g++
137+
137138
eval "$HomePath/build/makefile_static.sh"
138-
make
139+
./../codegen/Debug/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild
140+
./../codegen/Debug/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt"
141+
./../DebugLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto
142+
make -j4
139143
echo "$BinaryName build complete!"
140144

141145
if [ ! -f "$ReleasePath/$BinaryName" ]; then

Telegram/build/deploy.sh

100644100755
Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,59 @@ pushd `dirname $0` > /dev/null
44
FullScriptPath=`pwd`
55
popd > /dev/null
66

7+
if [ ! -d "$FullScriptPath/../../../TelegramPrivate" ]; then
8+
echo ""
9+
echo "This script is for building the production version of Telegram Desktop."
10+
echo ""
11+
echo "For building custom versions please visit the build instructions page at:"
12+
echo "https://github.com/telegramdesktop/tdesktop/#build-instructions"
13+
exit
14+
fi
15+
16+
Error () {
17+
cd $FullExecPath
18+
echo "$1"
19+
exit 1
20+
}
21+
722
DeployTarget="$1"
823

24+
if [ ! -f "$FullScriptPath/target" ]; then
25+
Error "Build target not found!"
26+
fi
27+
28+
while IFS='' read -r line || [[ -n "$line" ]]; do
29+
BuildTarget="$line"
30+
done < "$FullScriptPath/target"
31+
932
while IFS='' read -r line || [[ -n "$line" ]]; do
1033
set $line
1134
eval $1="$2"
12-
done < Version
35+
done < "$FullScriptPath/version"
1336

1437
if [ "$BetaVersion" != "0" ]; then
1538
AppVersion="$BetaVersion"
1639
AppVersionStrFull="${AppVersionStr}_${BetaVersion}"
17-
DevParam="-beta $BetaVersion"
1840
BetaKeyFile="tbeta_${AppVersion}_key"
19-
elif [ "$DevChannel" == "0" ]; then
41+
elif [ "$AlphaChannel" == "0" ]; then
2042
AppVersionStrFull="$AppVersionStr"
21-
DevParam=''
2243
else
23-
AppVersionStrFull="$AppVersionStr.dev"
24-
DevParam='-dev'
44+
AppVersionStrFull="$AppVersionStr.alpha"
2545
fi
2646

27-
if [ ! -f "Target" ]; then
28-
echo "Deploy target not found!"
29-
exit 1
30-
fi
31-
32-
while IFS='' read -r line || [[ -n "$line" ]]; do
33-
BuildTarget="$line"
34-
done < Target
35-
3647
echo ""
48+
HomePath="$FullScriptPath/.."
3749
if [ "$BuildTarget" == "linux" ]; then
3850
echo "Deploying version $AppVersionStrFull for Linux 64bit.."
3951
UpdateFile="tlinuxupd$AppVersion"
4052
SetupFile="tsetup.$AppVersionStrFull.tar.xz"
41-
ReleasePath="./../Linux/Release"
53+
ReleasePath="$HomePath/../Linux/Release"
4254
RemoteFolder="tlinux"
4355
elif [ "$BuildTarget" == "linux32" ]; then
4456
echo "Deploying version $AppVersionStrFull for Linux 32bit.."
4557
UpdateFile="tlinux32upd$AppVersion"
4658
SetupFile="tsetup32.$AppVersionStrFull.tar.xz"
47-
ReleasePath="./../Linux/Release"
59+
ReleasePath="$HomePath/../Linux/Release"
4860
RemoteFolder="tlinux32"
4961
elif [ "$BuildTarget" == "mac" ]; then
5062
DeployMac="0"
@@ -71,27 +83,25 @@ elif [ "$BuildTarget" == "mac" ]; then
7183
fi
7284
UpdateFile="tmacupd$AppVersion"
7385
SetupFile="tsetup.$AppVersionStrFull.dmg"
74-
ReleasePath="./../Mac/Release"
86+
ReleasePath="$HomePath/../Mac/Release"
7587
RemoteFolder="tmac"
76-
Mac32DeployPath="./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStrFull"
88+
Mac32DeployPath="$HomePath/../../tother/tmac32/$AppVersionStrMajor/$AppVersionStrFull"
7789
Mac32UpdateFile="tmac32upd$AppVersion"
7890
Mac32SetupFile="tsetup32.$AppVersionStrFull.dmg"
7991
Mac32RemoteFolder="tmac32"
80-
WinDeployPath="./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStrFull"
92+
WinDeployPath="$HomePath/../../tother/tsetup/$AppVersionStrMajor/$AppVersionStrFull"
8193
WinUpdateFile="tupdate$AppVersion"
8294
WinSetupFile="tsetup.$AppVersionStrFull.exe"
8395
WinPortableFile="tportable.$AppVersionStrFull.zip"
8496
WinRemoteFolder="tsetup"
85-
DropboxPath="./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor"
97+
DropboxPath="/Volumes/Storage/Dropbox/Telegram/deploy/$AppVersionStrMajor"
8698
DropboxDeployPath="$DropboxPath/$AppVersionStrFull"
8799
DropboxSetupFile="$SetupFile"
88100
DropboxMac32SetupFile="$Mac32SetupFile"
89101
elif [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" = "macstore" ]; then
90-
echo "No need to deploy this target."
91-
exit
102+
Error "No need to deploy this target."
92103
else
93-
echo "Invalid target!"
94-
exit 1
104+
Error "Invalid target!"
95105
fi
96106

97107
DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
@@ -105,8 +115,7 @@ if [ "$BetaVersion" != "0" ]; then
105115
BetaFilePath="$DeployPath/$BetaKeyFile"
106116
fi
107117
if [ ! -f "$BetaFilePath" ]; then
108-
echo "Beta key file for $AppVersionStrFull not found :("
109-
exit 1
118+
Error "Beta key file for $AppVersionStrFull not found :("
110119
fi
111120

112121
while IFS='' read -r line || [[ -n "$line" ]]; do
@@ -131,45 +140,38 @@ fi
131140

132141
if [ "$BuildTarget" != "mac" ] || [ "$DeployMac" == "1" ]; then
133142
if [ ! -f "$DeployPath/$UpdateFile" ]; then
134-
echo "$UpdateFile not found!";
135-
exit 1
143+
Error "$UpdateFile not found!";
136144
fi
137145

138146
if [ ! -f "$DeployPath/$SetupFile" ]; then
139-
echo "$SetupFile not found!"
140-
exit 1
147+
Error "$SetupFile not found!"
141148
fi
142149
fi
143150

144151
if [ "$BuildTarget" == "mac" ]; then
145152
if [ "$DeployMac32" == "1" ]; then
146153
if [ ! -f "$Mac32DeployPath/$Mac32UpdateFile" ]; then
147-
echo "$Mac32UpdateFile not found!"
148-
exit 1
154+
Error "$Mac32UpdateFile not found!"
149155
fi
150156

151157
if [ ! -f "$Mac32DeployPath/$Mac32SetupFile" ]; then
152-
echo "$Mac32SetupFile not found!"
153-
exit 1
158+
Error "$Mac32SetupFile not found!"
154159
fi
155160
fi
156161

157162
if [ "$DeployWin" == "1" ]; then
158163
if [ ! -f "$WinDeployPath/$WinUpdateFile" ]; then
159-
echo "$WinUpdateFile not found!"
160-
exit 1
164+
Error "$WinUpdateFile not found!"
161165
fi
162166

163167
if [ "$BetaVersion" == "0" ]; then
164168
if [ ! -f "$WinDeployPath/$WinSetupFile" ]; then
165-
echo "$WinSetupFile not found!"
166-
exit 1
169+
Error "$WinSetupFile not found!"
167170
fi
168171
fi
169172

170173
if [ ! -f "$WinDeployPath/$WinPortableFile" ]; then
171-
echo "$WinPortableFile not found!"
172-
exit 1
174+
Error "$WinPortableFile not found!"
173175
fi
174176
fi
175177

@@ -221,4 +223,6 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$Build
221223
fi
222224
fi
223225

224-
echo "Version $AppVersionStrFull was deployed!";
226+
echo "Version $AppVersionStrFull was deployed!"
227+
cd $FullExecPath
228+

Telegram/build/makefile_static.sh

100644100755
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ Replace () {
4949
}
5050

5151
Replace '\-llzma' "$ArchDirPath\/liblzma\.a"
52-
Replace '\-lXi' '$ArchDirPath\/libXi\.a $ArchDirPath\/libXext\.a'
53-
Replace '\-lSM' '$ArchDirPath\/libSM\.a'
54-
Replace '\-lICE' '$ArchDirPath\/libICE\.a'
55-
Replace '\-lfontconfig' '$ArchDirPath\/libfontconfig\.a $ArchDirPath\/libexpat\.a'
56-
Replace '\-lfreetype' '$ArchDirPath\/libfreetype\.a'
57-
Replace '\-lXext' '$ArchDirPath\/libXext\.a'
58-
Replace '\-lopus' '$LocalDirPath\/libopus\.a'
59-
Replace '\-lopenal' '$LocalDirPath\/libopenal\.a'
60-
Replace '\-lavformat' '$LocalDirPath\/libavformat\.a'
61-
Replace '\-lavcodec' '$LocalDirPath\/libavcodec\.a'
62-
Replace '\-lswresample' '$LocalDirPath\/libswresample\.a'
63-
Replace '\-lswscale' '$LocalDirPath\/libswscale\.a'
64-
Replace '\-lavutil' '$LocalDirPath\/libavutil\.a'
65-
Replace '\-lva' '$LocalDirPath\/libva\.a'
52+
Replace '\-lXi' "$ArchDirPath\/libXi\.a $ArchDirPath\/libXext\.a"
53+
Replace '\-lSM' "$ArchDirPath\/libSM\.a"
54+
Replace '\-lICE' "$ArchDirPath\/libICE\.a"
55+
Replace '\-lfontconfig' "$ArchDirPath\/libfontconfig\.a $ArchDirPath\/libexpat\.a"
56+
Replace '\-lfreetype' "$ArchDirPath\/libfreetype\.a"
57+
Replace '\-lXext' "$ArchDirPath\/libXext\.a"
58+
Replace '\-lopus' "$LocalDirPath\/libopus\.a"
59+
Replace '\-lopenal' "$LocalDirPath\/libopenal\.a"
60+
Replace '\-lavformat' "$LocalDirPath\/libavformat\.a"
61+
Replace '\-lavcodec' "$LocalDirPath\/libavcodec\.a"
62+
Replace '\-lswresample' "$LocalDirPath\/libswresample\.a"
63+
Replace '\-lswscale' "$LocalDirPath\/libswscale\.a"
64+
Replace '\-lavutil' "$LocalDirPath\/libavutil\.a"
65+
Replace '\-lva' "$LocalDirPath\/libva\.a"

Telegram/build/set_version.bat

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ set "InputVersion=%1"
77
for /F "tokens=1,2,3,4 delims=. " %%a in ("%InputVersion%") do (
88
set "VersionMajor=%%a"
99
set "VersionMinor=%%b"
10-
set "VersionMicro=%%c"
10+
set "VersionPatch=%%c"
1111
if "%%d" == "" (
1212
set "VersionBeta=0"
1313
set "VersionAlpha=0"
@@ -30,9 +30,9 @@ if "%VersionMinorCleared%" neq "%VersionMinor%" (
3030
echo Bad minor version!
3131
exit /b 1
3232
)
33-
set /a "VersionMicroCleared=%VersionMicro% %% 1000"
34-
if "%VersionMicroCleared%" neq "%VersionMicro%" (
35-
echo Bad micro version!
33+
set /a "VersionPatchCleared=%VersionPatch% %% 1000"
34+
if "%VersionPatchCleared%" neq "%VersionPatch%" (
35+
echo Bad patch version!
3636
exit /b 1
3737
)
3838
if "%VersionAlpha%" neq "0" (
@@ -45,7 +45,7 @@ if "%VersionAlpha%" neq "0" (
4545
set "VersionAlphaBool=false"
4646
)
4747

48-
set /a "VersionFull=%VersionMajor% * 1000000 + %VersionMinor% * 1000 + %VersionMicro%"
48+
set /a "VersionFull=%VersionMajor% * 1000000 + %VersionMinor% * 1000 + %VersionPatch%"
4949
if "%VersionBeta%" neq "0" (
5050
set /a "VersionBetaCleared=%VersionBeta% %% 1000"
5151
if "!VersionBetaCleared!" neq "%VersionBeta%" (
@@ -58,18 +58,19 @@ if "%VersionBeta%" neq "0" (
5858
set "VersionFullBeta=0"
5959
)
6060

61-
set "VersionStr=%VersionMajor%.%VersionMinor%.%VersionMicro%"
62-
set "VersionStrSmall=%VersionMajor%.%VersionMinor%"
63-
if "%VersionMicro%" neq "0" (
64-
set "VersionStrSmall=%VersionStrSmall%.%VersionMicro%"
61+
set "VersionStr=%VersionMajor%.%VersionMinor%.%VersionPatch%"
62+
if "%VersionPatch%" neq "0" (
63+
set "VersionStrSmall=%VersionStr%"
64+
) else (
65+
set "VersionStrSmall=%VersionMajor%.%VersionMinor%"
6566
)
6667

6768
if "%VersionAlpha%" neq "0" (
68-
echo Setting version: %VersionMajor%.%VersionMinor%.%VersionMicro% alpha
69+
echo Setting version: %VersionStr% alpha
6970
) else if "%VersionBeta%" neq "0" (
70-
echo Setting version: %VersionMajor%.%VersionMinor%.%VersionMicro%.%VersionBeta% closed beta
71+
echo Setting version: %VersionStr%.%VersionBeta% closed beta
7172
) else (
72-
echo Setting version: %VersionMajor%.%VersionMinor%.%VersionMicro% stable
73+
echo Setting version: %VersionStr% stable
7374
)
7475

7576
echo Patching build/version...
@@ -95,17 +96,17 @@ call :repl "Replace=(TDESKTOP_VERSION\s+=) (\s*)[&hat;;]+/$1$2 %VersionStrSmall%
9596

9697
echo Patching Telegram.rc...
9798
set "ResourcePath=%FullScriptPath%..\Resources\winrc\Telegram.rc"
98-
call :repl "Replace=(FILEVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionMicro%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
99-
call :repl "Replace=(PRODUCTVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionMicro%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
100-
call :repl "Replace=(&quot;FileVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionMicro%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
101-
call :repl "Replace=(&quot;ProductVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionMicro%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
99+
call :repl "Replace=(FILEVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionPatch%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
100+
call :repl "Replace=(PRODUCTVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionPatch%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
101+
call :repl "Replace=(&quot;FileVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionPatch%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
102+
call :repl "Replace=(&quot;ProductVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionPatch%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
102103

103104
echo Patching Updater.rc...
104105
set "ResourcePath=%FullScriptPath%..\Resources\winrc\Updater.rc"
105-
call :repl "Replace=(FILEVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionMicro%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
106-
call :repl "Replace=(PRODUCTVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionMicro%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
107-
call :repl "Replace=(&quot;FileVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionMicro%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
108-
call :repl "Replace=(&quot;ProductVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionMicro%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
106+
call :repl "Replace=(FILEVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionPatch%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
107+
call :repl "Replace=(PRODUCTVERSION) (\s*)\d+,\d+,\d+,\d+/$1$2 %VersionMajor%,%VersionMinor%,%VersionPatch%,%VersionBeta%" "Filename=%ResourcePath%" || goto :error
108+
call :repl "Replace=(&quot;FileVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionPatch%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
109+
call :repl "Replace=(&quot;ProductVersion&quot;,) (\s*)&quot;\d+.\d+.\d+.\d+&quot;/$1$2 &quot;%VersionMajor%.%VersionMinor%.%VersionPatch%.%VersionBeta%&quot;" "Filename=%ResourcePath%" || goto :error
109110

110111
exit /b
111112

0 commit comments

Comments
 (0)