1 ; Lyx for Windows, NSIS v2 series installer script
3 ; File lyx_installer.nsi
4 ; This file is part of LyX, the document processor.
6 ; Licence details can be found in the file COPYING or copy at
7 ; http://www.lyx.org/about/license.php3
11 ; Full author contact details are available in file CREDITS or copy at
12 ; http://www.lyx.org/about/credits.php
14 ; This script requires NSIS 2.06 and above
15 ; http://nsis.sourceforge.net/
16 ;--------------------------------
18 ; Do a Cyclic Redundancy Check to make sure the installer
19 ; was not corrupted by the download.
22 ; Make the installer as small as possible.
25 ;--------------------------------
26 ; You should need to change only these macros...
28 !define PRODUCT_NAME "LyX"
29 !define PRODUCT_VERSION "1.4.0"
30 !define PRODUCT_LICENSE_FILE "..\..\..\..\COPYING"
31 !define PRODUCT_SOURCEDIR "..\..\..\..\build\installprefix"
32 !define PRODUCT_EXE "$INSTDIR\bin\lyx.exe"
33 !define PRODUCT_BAT "$INSTDIR\bin\lyx.bat"
34 !define PRODUCT_EXT ".lyx"
35 !define PRODUCT_MIME_TYPE "application/lyx"
36 !define PRODUCT_UNINSTALL_EXE "$INSTDIR\uninstall.exe"
38 !define INSTALLER_EXE "lyx_setup_140.exe"
39 !define INSTALLER_ICON "..\icons\lyx_32x32.ico"
41 ; Replaced by HKLM or HKCU depending on SetShellVarContext.
42 !define PRODUCT_ROOT_KEY "SHCTX"
44 !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\lyx.exe"
45 !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
47 ;--------------------------------
48 ; Make some of the information above available to NSIS.
50 Name "${PRODUCT_NAME}"
51 OutFile "${INSTALLER_EXE}"
52 InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
54 ;--------------------------------
56 !include "LogicLib.nsh"
57 !include "StrFunc.nsh"
58 !include "strtrim.nsh"
59 !include "download.nsh"
60 !include "lyx_utils.nsh"
63 ; http://nsis.sourceforge.net/archive/viewpage.php?pageid=275
64 !include "is_user_admin.nsh"
67 ; http://abiword.pchasm.org/source/cvs/abiword-cvs/abi/src/pkg/win/setup/NSISv2/abi_util_fileassoc.nsh
68 ; Use the Abiword macros to help set up associations with the file extension.
70 !include "abi_util_fileassoc.nsh"
72 ;--------------------------------
73 ; Declare used functions
85 ${EnableBrowseControls}
90 ;--------------------------------
99 Var DoNotRequireMiKTeX
103 Var DoNotRequireGhostscript
105 Var DownloadGhostscript
107 Var DoNotRequireImageMagick
109 Var DownloadImageMagick
119 Var CreateFileAssociations
120 Var CreateDesktopIcon
127 ;--------------------------------
129 ; Remember the installer language
130 !define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
131 !define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
132 !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
134 !define MUI_ABORTWARNING
135 !define MUI_ICON "${INSTALLER_ICON}"
136 !define MUI_UNICON "${INSTALLER_ICON}"
139 !insertmacro MUI_PAGE_WELCOME
141 Page custom DownloadMinSYS DownloadMinSYS_LeaveFunction
142 Page custom DownloadPython DownloadPython_LeaveFunction
143 Page custom DownloadMiKTeX DownloadMiKTeX_LeaveFunction
144 Page custom DownloadGhostscript DownloadGhostscript_LeaveFunction
145 Page custom DownloadImageMagick DownloadImageMagick_LeaveFunction
146 Page custom SummariseDownloads SummariseDownloads_LeaveFunction
149 !insertmacro MUI_PAGE_LICENSE "${PRODUCT_LICENSE_FILE}"
151 ; Specify the installation directory.
152 !insertmacro MUI_PAGE_DIRECTORY
154 ; Specify LyX's menu language.
155 Page custom SelectMenuLanguage SelectMenuLanguage_LeaveFunction
157 ; Define which components to install.
158 !insertmacro MUI_PAGE_COMPONENTS
160 ; Specify where to install program shortcuts.
161 !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_ROOT_KEY}"
162 !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
163 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
164 !insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} $StartmenuFolder
166 ; Watch the components being installed.
167 !insertmacro MUI_PAGE_INSTFILES
169 !define MUI_FINISHPAGE_RUN
170 !define MUI_FINISHPAGE_TEXT_LARGE
171 !define MUI_FINISHPAGE_TEXT "$(FinishPageMessage)"
172 !define MUI_FINISHPAGE_RUN_TEXT "$(FinishPageRun)"
173 !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchProduct"
174 !insertmacro MUI_PAGE_FINISH
177 !insertmacro MUI_UNPAGE_INSTFILES
179 ;--------------------------------
182 !insertmacro MUI_LANGUAGE "English" # first language is the default language
183 !insertmacro MUI_LANGUAGE "Danish"
184 !insertmacro MUI_LANGUAGE "German"
185 !insertmacro MUI_LANGUAGE "Spanish"
186 !insertmacro MUI_LANGUAGE "French"
187 !insertmacro MUI_LANGUAGE "Italian"
188 !insertmacro MUI_LANGUAGE "Dutch"
189 !insertmacro MUI_LANGUAGE "Polish"
190 !insertmacro MUI_LANGUAGE "Swedish"
192 !include "lyx_languages\english.nsh"
193 !include "lyx_languages\danish.nsh"
194 !include "lyx_languages\dutch.nsh"
195 !include "lyx_languages\french.nsh"
196 !include "lyx_languages\german.nsh"
197 !include "lyx_languages\italian.nsh"
198 !include "lyx_languages\polish.nsh"
199 !include "lyx_languages\spanish.nsh"
200 !include "lyx_languages\swedish.nsh"
202 LicenseData "$(LyXLicenseData)"
204 ;--------------------------------
207 ; These files should be inserted before other files in the data block
208 ; Keep these lines before any File command
209 ; Only for solid compression (by default, solid compression
210 ; is enabled for BZIP2 and LZMA)
211 ReserveFile "io_download.ini"
212 ReserveFile "io_summary.ini"
213 !insertmacro MUI_RESERVEFILE_LANGDLL
214 ReserveFile "io_ui_language.ini"
215 !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
217 ;--------------------------------
219 Section "!${PRODUCT_NAME}" SecCore
223 Section /o "$(SecAllUsersTitle)" SecAllUsers
224 SetShellVarContext all
225 StrCpy $ProductRootKey "HKLM"
228 Section "$(SecFileAssocTitle)" SecFileAssoc
229 StrCpy $CreateFileAssociations "true"
232 Section "$(SecDesktopTitle)" SecDesktop
233 StrCpy $CreateDesktopIcon "true"
236 ; The '-' makes the section invisible.
237 ; Sections are entered in order, so the settings above are all
238 ; available to SecInstallation
239 Section "-Installation actions" SecInstallation
241 SetOutPath "$INSTDIR"
242 File /r "${PRODUCT_SOURCEDIR}\Resources"
243 File /r "${PRODUCT_SOURCEDIR}\bin"
245 ${if} "$PathPrefix" != ""
246 lyx_configure::set_path_prefix "$INSTDIR\Resources\configure" "$PathPrefix"
249 MessageBox MB_OK "$(ModifyingConfigureFailed)"
253 lyx_configure::create_lyx_bat "$INSTDIR\bin" "$LangCode"
256 MessageBox MB_OK "$(CreateCmdFilesFailed)"
259 lyx_configure::run_configure "$INSTDIR\Resources\configure" "$PathPrefix"
262 MessageBox MB_OK "$(RunConfigureFailed)"
265 WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "${PRODUCT_EXE}"
266 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "RootKey" "$ProductRootKey"
267 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
268 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "${PRODUCT_UNINSTALL_EXE}"
269 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "${PRODUCT_EXE}"
270 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
271 WriteRegStr ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "StartMenu" "$SMPROGRAMS\$StartmenuFolder"
273 CreateDirectory "$SMPROGRAMS\$StartmenuFolder"
274 CreateShortCut "$SMPROGRAMS\$StartmenuFolder\${PRODUCT_NAME}.lnk" "${PRODUCT_BAT}" "" "${PRODUCT_EXE}"
275 CreateShortCut "$SMPROGRAMS\$StartmenuFolder\Uninstall.lnk" "${PRODUCT_UNINSTALL_EXE}"
277 ${if} $CreateDesktopIcon == "true"
278 CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "${PRODUCT_BAT}" "" "${PRODUCT_EXE}"
281 ${if} $CreateFileAssociations == "true"
282 ${CreateApplicationAssociation} \
285 "${PRODUCT_NAME} Document" \
289 ${CreateFileAssociation} "${PRODUCT_EXT}" "${PRODUCT_NAME}" "${PRODUCT_MIME_TYPE}"
292 WriteUninstaller "${PRODUCT_UNINSTALL_EXE}"
295 ; Section descriptions
296 !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
297 !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "$(SecCoreDescription)"
298 !insertmacro MUI_DESCRIPTION_TEXT ${SecAllUsers} "$(SecAllUsersDescription)"
299 !insertmacro MUI_DESCRIPTION_TEXT ${SecFileAssoc} "$(SecFileAssocDescription)"
300 !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} "$(SecDesktopDescription)"
301 !insertmacro MUI_FUNCTION_DESCRIPTION_END
303 ;--------------------------------
305 !define MUI_LANGDLL_ALWAYSSHOW
307 ; This hook function is called internally by NSIS on installer startup
309 !insertmacro MUI_LANGDLL_DISPLAY
311 !insertmacro MUI_INSTALLOPTIONS_EXTRACT "io_download.ini"
312 !insertmacro MUI_INSTALLOPTIONS_EXTRACT "io_summary.ini"
313 !insertmacro MUI_INSTALLOPTIONS_EXTRACT "io_ui_language.ini"
316 ; These can be reset to "all" in section SecAllUsers.
317 SetShellVarContext current
318 StrCpy $ProductRootKey "HKCU"
320 ; This can be reset to "true" in section SecDesktop.
321 StrCpy $CreateDesktopIcon "false"
322 StrCpy $CreateFileAssociations "false"
324 ; If the user does *not* have administrator privileges,
325 ; then make section SecAllUsers readonly.
329 !define ENABLE 0x00000001
330 SectionGetFlags ${SecAllUsers} $0
331 IntOp $0 $0 | ${ENABLE}
332 SectionSetFlags ${SecAllUsers} $0
335 !define READ_ONLY 0x00000010
336 SectionGetFlags ${SecAllUsers} $0
337 IntOp $0 $0 | ${READ_ONLY}
338 SectionSetFlags ${SecAllUsers} $0
345 Call SearchGhostscript
346 Call SearchImageMagick
353 ;--------------------------------
355 Function LaunchProduct
356 lyx_configure::set_env LANG $LangCode
360 ;--------------------------------
362 ; Sets the value of the global $MinSYSPath variable.
363 Function SearchMinSYS
364 ; This function manipulates the registers $0-$3,
365 ; so push their current content onto the stack.
371 ; Search the registry for the MinSYS uninstaller.
372 ; If successful, put its location in $2.
373 StrCpy $3 "Software\Microsoft\Windows\CurrentVersion\Uninstall"
377 EnumRegKey $1 HKLM "$3" $0
382 ${StrLoc} $2 "$1" "MSYS-1.0" "<"
396 "Inno Setup: App Path" \
400 ; Return the $0, $1, $2 and $2 registers to their original state
407 Function DownloadMinSYS
408 StrCpy $DownloadMinSYS "0"
413 "$(MinSYSDownloadLabel)" \
414 "$(MinSYSFolderLabel)" \
416 "$(MinSYSDescription)"
419 Function DownloadMinSYS_LeaveFunction
420 ; This function manipulates the $0 register
421 ; so push its current content onto the stack.
428 "http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=82721&release_id=158803" \
429 "$(EnterMinSYSFolder)" \
431 "$(InvalidMinSYSFolder)"
433 ; Return the $0 register to its original state
437 ;--------------------------------
439 ; Sets the value of the global $PythonPath variable.
440 Function SearchPython
443 "Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe" \
449 Function DownloadPython
450 StrCpy $DownloadPython "0"
455 "$(PythonDownloadLabel)" \
456 "$(PythonFolderLabel)" \
458 "$(PythonDescription)"
461 Function DownloadPython_LeaveFunction
462 ; This function manipulates the $0 register
463 ; so push its current content onto the stack.
470 "http://www.python.org/download/" \
471 "$(EnterPythonFolder)" \
473 "$(InvalidPythonFolder)"
475 ; Return the $0 register to its original state
479 ;--------------------------------
481 ; Sets the value of the global $MiKTeXPath variable.
482 Function SearchMiKTeX
485 "Software\MiK\MiKTeX\CurrentVersion\MiKTeX" \
491 Function DownloadMiKTeX
492 StrCpy $DoNotRequireMiKTeX "1"
493 StrCpy $DownloadMiKTeX "0"
498 "$(MiKTeXDownloadLabel)" \
499 "$(MiKTeXFolderLabel)" \
501 "$(MiKTeXDescription)"
504 Function DownloadMiKTeX_LeaveFunction
506 $DoNotRequireMiKTeX \
509 "http://www.miktex.org/setup.html" \
510 "$(EnterMiKTeXFolder)" \
512 "$(InvalidMiKTeXFolder)"
515 ;--------------------------------
517 ; Sets the value of the global $GhostscriptPath variable.
518 Function SearchGhostscript
519 ; This function manipulates the $0 and $1 registers,
520 ; so push their current content onto the stack.
524 ; Find which version of ghostscript, if any, is installed.
525 ; Store this value in $0.
527 EnumRegKey $1 HKLM "Software\AFPL Ghostscript" 0
529 StrCpy $0 "Software\AFPL Ghostscript\$1"
531 EnumRegKey $1 HKLM "Software\GPL Ghostscript" 0
533 StrCpy $0 "Software\GPL Ghostscript\$1"
544 ; Return the $0 and $1 registers to their original states
549 Function DownloadGhostscript
550 StrCpy $DoNotRequireGhostscript "1"
551 StrCpy $DownloadGhostscript "0"
553 ; Find which version of ghostscript, if any, is installed.
554 EnumRegKey $1 HKLM "Software\AFPL Ghostscript" 0
556 EnumRegKey $1 HKLM "Software\GPL Ghostscript" 0
561 StrCpy $0 "Software\GPL Ghostscript\$1"
563 StrCpy $0 "Software\AFPL Ghostscript\$1"
572 "$(GhostscriptDownloadLabel)" \
573 "$(GhostscriptFolderLabel)" \
574 "$(GhostscriptHeader)" \
575 "$(GhostscriptDescription)"
578 Function DownloadGhostscript_LeaveFunction
580 $DoNotRequireGhostscript \
581 $DownloadGhostscript \
583 "http://www.cs.wisc.edu/~ghost/doc/AFPL/index.htm" \
584 "$(EnterGhostscriptFolder)" \
586 "$(InvalidGhostscriptFolder)"
589 ;--------------------------------
591 ; Sets the value of the global $ImageMagickPath variable.
592 Function SearchImageMagick
595 "Software\ImageMagick\Current" \
601 Function DownloadImageMagick
602 StrCpy $DoNotRequireImageMagick "1"
603 StrCpy $DownloadImageMagick "0"
608 "$(ImageMagickDownloadLabel)" \
609 "$(ImageMagickFolderLabel)" \
610 "$(ImageMagickHeader)" \
611 "$(ImageMagickDescription)"
614 Function DownloadImageMagick_LeaveFunction
616 $DoNotRequireImageMagick \
617 $DownloadImageMagick \
619 "http://www.imagemagick.org/script/binary-releases.php" \
620 "$(EnterImageMagickFolder)" \
622 "$(InvalidImageMagickFolder)"
625 ;--------------------------------
627 ; Sets the value of the global $PDFViewerPath variable.
628 Function SearchPDFViewer
629 ; test if a pdf-viewer is installed, only test for Acrobat, Adobe Reader (AroRD32), and GSview32
630 StrCpy $PDFViewerPath ""
631 ReadRegStr $PDFViewerPath HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe" "Path"
632 ${if} $PDFViewerPath == ""
633 ReadRegStr $PDFViewerPath HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe" "Path"
635 ${if} $PDFViewerPath == ""
636 ReadRegStr $PDFViewerPath HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\gsview32.exe" "Path"
638 StrCpy $0 $PDFViewerPath "" -1 ;remove the "\" at the end
640 StrCpy $PDFViewerPath $PDFViewerPath -1
644 ;--------------------------------
646 Function SearchPSViewer
647 ; This function manipulates the $0 register,
648 ; so push its current content onto the stack.
651 ; test if a ps-viewer is installed, only check for GSview32
652 StrCpy $PSViewerPath ""
653 ReadRegStr $PSViewerPath HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\gsview32.exe" "Path"
655 ; Failed to find anything that way. Try another.
656 ${if} $PSViewerPath == ""
657 ReadRegStr $PSViewerProg HKCR "psfile\shell\open\command" ""
658 ; Extract the first quoted word.
659 ${StrTok} $0 "$PSViewerProg" '"' '1' '0'
661 StrCpy $PSViewerProg $0
664 ${StrTrim} $PSViewerProg "$PSViewerProg"
665 ; Split into <path,exe> pair
666 ${StrStrAdv} $PSViewerPath $PSViewerProg "\" "<" "<" "0" "0" "0"
667 ${StrStrAdv} $PSViewerProg $PSViewerProg "\" "<" ">" "0" "0" "0"
670 ; Return the $0 register to its original states
674 ;--------------------------------
676 Function SummariseDownloads
678 StrCpy $PathPrefix ""
679 ${if} $MinSYSPath != ""
680 StrCpy $PathPrefix "$PathPrefix;$MinSYSPath"
682 ${if} $PythonPath != ""
683 StrCpy $PathPrefix "$PathPrefix;$PythonPath"
685 ${if} $MiKTeXPath != ""
686 StrCpy $PathPrefix "$PathPrefix;$MiKTeXPath"
688 ${if} $GhostscriptPath != ""
689 StrCpy $PathPrefix "$PathPrefix;$GhostscriptPath"
691 ${if} $ImageMagickPath != ""
692 StrCpy $PathPrefix "$PathPrefix;$ImageMagickPath"
694 ; Remove the leading ';'
695 StrCpy $PathPrefix "$PathPrefix" "" 1
697 IntOp $DoNotInstallLyX $DownloadMinSYS + $DownloadPython
698 IntOp $DoNotInstallLyX $DoNotInstallLyX + $DownloadMiKTeX
699 IntOp $DoNotInstallLyX $DoNotInstallLyX + $DownloadGhostscript
700 IntOp $DoNotInstallLyX $DoNotInstallLyX + $DownloadImageMagick
702 ${if} "$DoNotInstallLyX" == 1
703 !insertmacro MUI_INSTALLOPTIONS_WRITE "io_summary.ini" "Field 1" "Text" "$(SummaryPleaseInstall)"
705 ${StrNSISToIO} $0 '$PathPrefix'
706 ${StrRep} $0 "$0" ";" "\r\n"
707 StrCpy $0 "$(SummaryPathPrefix)\r\n\r\n$0"
708 !insertmacro MUI_INSTALLOPTIONS_WRITE "io_summary.ini" "Field 1" "Text" "$0"
711 !insertmacro MUI_HEADER_TEXT "$(SummaryTitle)" ""
712 !insertmacro MUI_INSTALLOPTIONS_DISPLAY "io_summary.ini"
715 Function SummariseDownloads_LeaveFunction
716 ${if} "$DoNotInstallLyX" == 1
721 ;--------------------------------
723 Function SelectMenuLanguage
726 ;tranlate NSIS's language code to the language name; macro from lyx_utils.nsh
727 !insertmacro TranslateLangCode $LangName $Language
729 !insertmacro MUI_INSTALLOPTIONS_WRITE "io_ui_language.ini" "Field 1" "State" "$(UILanguageAvailableLanguages)"
730 !insertmacro MUI_INSTALLOPTIONS_WRITE "io_ui_language.ini" "Field 2" "State" "$LangName"
732 !insertmacro MUI_HEADER_TEXT "$(UILangageTitle)" "$(UILangageDescription)"
733 !insertmacro MUI_INSTALLOPTIONS_DISPLAY "io_ui_language.ini"
736 ;--------------------------------
738 Function SelectMenuLanguage_LeaveFunction
739 !insertmacro MUI_INSTALLOPTIONS_READ $LangName "io_ui_language.ini" "Field 2" "State"
741 ;Get the language code; macro from lyx_utils.nsh
743 !insertmacro GetLangCode $LangCode $LangName
746 ;--------------------------------
751 !insertmacro MUI_UNGETLANGUAGE
753 ; Ascertain whether the user has sufficient privileges to uninstall.
754 SetShellVarContext current
756 ReadRegStr $0 HKCU "${PRODUCT_UNINST_KEY}" "RootKey"
758 ReadRegStr $0 HKLM "${PRODUCT_UNINST_KEY}" "RootKey"
760 MessageBox MB_OK "$(UnNotInRegistryLabel)"
768 SetShellVarContext all
770 MessageBox MB_OK "$(UnNotAdminLabel)"
775 MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(UnReallyRemoveLabel)" IDYES +2
780 Function un.onUninstSuccess
782 MessageBox MB_ICONINFORMATION|MB_OK "$(UnRemoveSuccessLabel)"
789 ReadRegStr $0 ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "StartMenu"
792 Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
794 DeleteRegKey "HKCU" "${PRODUCT_UNINST_KEY}"
795 DeleteRegKey ${PRODUCT_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
796 DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
797 DeleteRegKey HKCR "Applications\lyx.exe"
798 DeleteRegKey HKCR "Applications\lyx.bat"
800 ; remove extension .lyx
801 ${RemoveFileAssociation} "${PRODUCT_EXT}" "${PRODUCT_NAME}"
802 DeleteRegKey HKCR "${PRODUCT_NAME}"