pax_global_header00006660000000000000000000000064143126630350014515gustar00rootroot0000000000000052 comment=b93d71271bd42e0c4421b2edd1ccc855e3c45a8d gtkhash-1.5/000077500000000000000000000000001431266303500130135ustar00rootroot00000000000000gtkhash-1.5/.appveyor.yml000066400000000000000000000015061431266303500154630ustar00rootroot00000000000000version: git-{branch}.{build} image: Visual Studio 2019 platform: x64 environment: MSYSTEM: MINGW64 init: - cmd: PATH C:\msys64\mingw64\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH% install: - cmd: bash -l -c "exec pacman -Syy --noconfirm" - cmd: bash -l -c "exec pacman -Suu --noconfirm" - cmd: bash -l -c "exec pacman -Syy --noconfirm" - cmd: bash -l -c "exec pacman -Suu --noconfirm" - cmd: bash -l %APPVEYOR_BUILD_FOLDER%\msys2\installdeps.sh build_script: - cmd: bash -l %APPVEYOR_BUILD_FOLDER%\msys2\makepkg.sh after_build: - cmd: bash -l %APPVEYOR_BUILD_FOLDER%\msys2\styrene.sh artifacts: - path: 'msys2\styrene\gtkhash-w64-*-installer.exe' - path: 'msys2\styrene\gtkhash-w32-*-installer.exe' - path: 'msys2\styrene\gtkhash-w64-*-standalone.zip' - path: 'msys2\styrene\gtkhash-w32-*-standalone.zip' gtkhash-1.5/.codecov.yml000066400000000000000000000002441431266303500152360ustar00rootroot00000000000000coverage: status: project: default: informational: true patch: default: informational: true comment: require_changes: true gtkhash-1.5/.gitignore000066400000000000000000000013571431266303500150110ustar00rootroot00000000000000src/gtkhash src/gtkhash-test src/resources.c src/resources.h src/nautilus/properties-resources.c src/nautilus/properties-resources.h data/appdata/*.xml data/appdata/*.xml.in data/caja/libgtkhash-properties-caja.caja-extension data/caja/libgtkhash-properties-caja.caja-extension.in data/icons/32/ data/icons/48/ data/icons/64/ data/icons/128/ data/icons/256/ po/*.header po/*.sed po/*.sin po/*.template po/POTFILES po/Rules-quot po/stamp-po .deps/ .libs/ autom4te.cache/ build-aux/ intl/ m4/ .dirstamp ABOUT-NLS INSTALL Makefile Makefile.in Makefile.in.in aclocal.m4 config.h config.h.in config.log config.status configure libtool stamp-h1 stamp-it test.md5sum *~ *.bytes *.desktop *.gcda *.gcno *.gmo *.gz *.la *.lo *.log *.o *.trs *.valid *.xz gtkhash-1.5/.gitlab-ci.yml000066400000000000000000000035571431266303500154610ustar00rootroot00000000000000.build_gtkhash: &build_gtkhash - ./autogen.sh - export DISTCHECK_CONFIGURE_FLAGS=$(echo --enable-debug --enable-blake2 --enable-gcrypt --enable-glib-checksums --enable-mbedtls --enable-nettle --enable-libcrypto --enable-linux-crypto --enable-nautilus --enable-nemo --enable-caja --enable-thunar --disable-dependency-tracking ) - ./configure ${DISTCHECK_CONFIGURE_FLAGS} - make -j$(nproc) VERBOSE=1 DESTDIR=$(mktemp -d) distcheck fedora: image: fedora before_script: - dnf -y install make libtool gettext gettext-devel appstream glib-devel gtk3-devel libgcrypt-devel nettle-devel libb2-devel mbedtls-devel openssl-devel kernel-headers librsvg2-tools libxml2 at-spi2-core xorg-x11-server-Xvfb gnome-icon-theme nautilus-devel nemo-devel caja-devel Thunar-devel script: - export NO_AT_BRIDGE=1 - *build_gtkhash - sha256sum *.tar.gz > "$(echo *.tar.gz)".sha256 - sha256sum *.tar.xz > "$(echo *.tar.xz)".sha256 artifacts: paths: - gtkhash-*.tar.* ubuntu: image: ubuntu:rolling before_script: - export DEBIAN_FRONTEND=noninteractive - apt-get -y update - apt-get -y install build-essential libtool gettext autopoint appstream libglib2.0-dev libgtk-3-dev libgcrypt20-dev nettle-dev libb2-dev libmbedtls-dev libssl-dev linux-libc-dev librsvg2-bin libxml2-utils at-spi2-core xvfb gnome-icon-theme libnautilus-extension-dev libnemo-extension-dev libcaja-extension-dev libthunarx-3-dev script: - *build_gtkhash gtkhash-1.5/.travis.yml000066400000000000000000000020201431266303500151160ustar00rootroot00000000000000dist: focal language: c compiler: - gcc - clang addons: apt: packages: - meson - gcovr - gettext - appstream - libglib2.0-dev - libgtk-3-dev - libgcrypt20-dev - nettle-dev - libb2-dev - libmbedtls-dev - linux-libc-dev - librsvg2-bin - libxml2-utils - at-spi2-core - xvfb - gnome-icon-theme - libcaja-extension-dev - libnautilus-extension-dev - libnemo-extension-dev - libthunarx-3-dev script: - meson _build --buildtype=debug -Db_coverage=true -Dglib-checksums=true -Dlibcrypto=true -Dlinux-crypto=true -Dmbedtls=true -Dnettle=true -Dbuild-caja=true -Dbuild-nautilus=true -Dbuild-nemo=true -Dbuild-thunar=true - cd _build - xvfb-run -s "-screen 0 800x600x24" meson test -v - test "${TRAVIS_COMPILER}" = "clang" || { ninja coverage && curl -Os https://uploader.codecov.io/latest/linux/codecov && chmod +x codecov && ./codecov -Z ; } gtkhash-1.5/AUTHORS000066400000000000000000000000531431266303500140610ustar00rootroot00000000000000Tristan Heaven gtkhash-1.5/COPYING000066400000000000000000000431031431266303500140470ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. gtkhash-1.5/ChangeLog000066400000000000000000000001711431266303500145640ustar00rootroot00000000000000Most noticable changes are listed in the NEWS file. For a full commit log, see https://github.com/tristanheaven/gtkhash gtkhash-1.5/Makefile.am000066400000000000000000000002701431266303500150460ustar00rootroot00000000000000SUBDIRS = data src if ENABLE_NLS SUBDIRS += po endif ACLOCAL_AMFLAGS = -I m4 --install EXTRA_DIST = \ autogen.sh \ README.md \ meson_options.txt \ meson.build \ po/meson.build gtkhash-1.5/NEWS000066400000000000000000000053431431266303500135170ustar00rootroot00000000000000Summary of changes for each GtkHash release: 1.5 (2022-09-21) * Added xxHash XXH64 * Added HMAC-BLAKE2s and HMAC-BLAKE2b (#86) * Made hashing start automatically in file manager extensions (#103) * Added Meson build system (#116, #140) * Removed dependency on intltool * Removed Peony extension as Peony 2+ is incompatible 1.4 (2020-07-11) * Added CRC32C * Replaced the word "Digest" with "Checksum" in some places (#40) * Added a separate hash button for each function (#50) * Added preference to show/hide HMAC feature * Fixed translations not showing on Windows and Snap package * Reduced Windows install size 1.3 (2020-05-25) * Fixed crash when program is closed (#47) * Added vertical scrolling to File/Text view (#35) * Added clipboard paste button to Check input * Added Windows compatibility * Removed support for GTK 2 1.2 (2018-11-27) * Added compatibility for Thunar 1.7 * Added optional Peony (UKUI file manager) extension 1.1.1 (2017-11-01) * Fixed bug in loading user preferences 1.1 (2017-03-12) * Removed internal BLAKE2 code and added option to use libb2 instead * Added OpenSSL-1.1 as a BLAKE2b/BLAKE2s provider * Removed PolarSSL support (replaced by mbed TLS) 1.0.1 (2017-03-02) * Fixed crash when certain Linux kernel crypto modules aren't loaded * Fixed plugin crash when viewing file properties in Thunar * Other bug fixes 1.0 (2016-11-16) * Added feature for checking digests from files (md5sum, sfv, etc.) * Added commandline option for enabling hash functions by name * Added Caja (MATE file manager) extension * Added BLAKE2 hash functions * Added support for mbed TLS * Switched to use GTK 3 by default * Added desktop menu entry and icon 0.7.0 (2013-10-30) * Added optional Nemo (Cinnamon file manager) extension * Added more commandline options * Added support for PolarSSL * Added support for Nettle * UI bug fixes 0.6.0 (2011-12-14) * Added "Check" feature for comparing digests * Added HMAC support * Added MD6 hash function * Switched from GConf to GSettings 0.5.0 (2011-10-31) * Improved hashing speed on SMP systems * Added support for libcrypto 0.4.0 (2011-10-26) * Added support for hashing non-local files using GIO * Made mhash an optional dependency * Added optional support for other hash libraries/interfaces * Added Digest Format option * Added optional Thunar (Xfce file manager) plugin * Added support for GTK 3 * General usability improvements 0.3.0 (2009-11-22) * Added optional Nautilus (GNOME file manager) extension 0.2.1 (2008-12-31) * Fixed progress bar display for large files * Removed dependency on libglade 0.2.0 (2007-08-14) * Added file list mode for hashing multiple files 0.1.1 (2007-07-21) * Added gettext support 0.1.0 (2007-06-29) * Initial release gtkhash-1.5/README.md000066400000000000000000000046311431266303500142760ustar00rootroot00000000000000[![Build Status](https://api.travis-ci.com/tristanheaven/gtkhash.svg?branch=master)](https://app.travis-ci.com/github/tristanheaven/gtkhash) [![Pipeline Status](https://gitlab.com/tristanheaven/gtkhash/badges/master/pipeline.svg)](https://gitlab.com/tristanheaven/gtkhash/commits/master) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/1hm3cs5f0islas0w/branch/master?svg=true)](https://ci.appveyor.com/project/tristanheaven/gtkhash/branch/master) [![Test Coverage](https://codecov.io/gh/tristanheaven/gtkhash/branch/master/graph/badge.svg)](https://codecov.io/gh/tristanheaven/gtkhash) [![Translations](https://hosted.weblate.org/widgets/gtkhash/-/svg-badge.svg)](https://hosted.weblate.org/engage/gtkhash/) [![Snap Status](https://snapcraft.io/gtkhash/badge.svg)](https://snapcraft.io/gtkhash/builds) GtkHash ======= ![Screenshot](screenshots/readme.png) GtkHash is a desktop utility for computing message digests or checksums. Most well-known hash functions are supported, including MD5, SHA1, SHA2 (SHA256/SHA512), SHA3 and BLAKE2. It's designed to be an easy to use, graphical alternative to command-line tools such as md5sum. Features: * Support for verifying checksum files from sfv, sha256sum, etc. * Keyed hashing (HMAC) * Parallel/multi-threaded hash calculation * Remote file access using GIO/GVfs * File manager integration * Small and fast GtkHash is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. Required Dependencies ------------- * GTK 3.18 * GLib 2.48 Optional Dependencies --------------------- * Libgcrypt (default) * libb2 (default) * Nettle * OpenSSL * mbed TLS * Linux kernel AF_ALG See `./configure --help` for the full list of build options. File Manager Extension ----------------------- ![Screenshot](screenshots/gtkhash-nemo-properties.png) Adds a Hash feature to File Properties in: * Caja (MATE) * Nautilus (GNOME) * Nemo (Cinnamon) * Thunar (Xfce) Translations ------------ ![Translation Details](https://hosted.weblate.org/widgets/gtkhash/-/multi-auto.svg) If you would like to contribute a translation, the easiest way is by using Weblate: https://hosted.weblate.org/engage/gtkhash/ Alternatively, updated .po files can be submitted as a Pull Request or Issue on GitHub: https://github.com/tristanheaven/gtkhash gtkhash-1.5/autogen.sh000077500000000000000000000000661431266303500150160ustar00rootroot00000000000000#!/bin/sh exec autoreconf -v -Wall --force --install gtkhash-1.5/configure.ac000066400000000000000000000406311431266303500153050ustar00rootroot00000000000000AC_PREREQ([2.61]) AC_INIT([GtkHash], [1.5]) AC_SUBST([RELEASE_DATE], [2022-09-21]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 check-news dist-xz foreign subdir-objects -Wall]) AM_SILENT_RULES([yes]) AC_PROG_CC_C99 AM_PROG_CC_C_O AM_PROG_AR LT_INIT GETTEXT_PACKAGE="${PACKAGE}" AC_SUBST([GETTEXT_PACKAGE]) AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["${GETTEXT_PACKAGE}"], [Define the gettext package]) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.19.7]) AM_CONDITIONAL([ENABLE_NLS], [test "${enable_nls}" != "no"]) GTKHASH_CFLAGS="" for opt in \ -Werror=unknown-warning-option \ -Werror=implicit-function-declaration \ -fno-common \ -fvisibility=hidden \ -pedantic \ -Wall \ -Wextra \ -Waggregate-return \ -Wbad-function-cast \ -Wcast-align \ -Winit-self \ -Wfloat-equal \ -Wformat \ -Wformat-nonliteral \ -Wformat-overflow \ -Wformat-security \ -Wformat-signedness \ -Wformat-truncation \ -Wlogical-op \ -Wmissing-declarations \ -Wmissing-noreturn \ -Wredundant-decls \ -Wshadow \ -Wswitch-default \ -Wundef \ -Wwrite-strings \ -Wno-parentheses-equality do AC_MSG_CHECKING([whether ${CC} accepts option ${opt}]) ac_save_CFLAGS="${CFLAGS}" CFLAGS="${GTKHASH_CFLAGS} ${opt} ${CFLAGS}" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [])], [AC_MSG_RESULT([yes]) ; GTKHASH_CFLAGS="${GTKHASH_CFLAGS} ${opt}"], [AC_MSG_RESULT([no])]) CFLAGS="${ac_save_CFLAGS}" done AC_SUBST([GTKHASH_CFLAGS]) # check for pkg-config PKG_PROG_PKG_CONFIG # check for glib/gio {{{ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.48]) AC_SUBST([GLIB_CFLAGS]) AC_SUBST([GLIB_LIBS]) PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.48]) AC_SUBST([GIO_CFLAGS]) AC_SUBST([GIO_LIBS]) m4_ifdef([PKG_CHECK_VAR], [PKG_CHECK_VAR([GLIB_COMPILE_RESOURCES], [gio-2.0], [glib_compile_resources])], [AC_CHECK_PROGS([GLIB_COMPILE_RESOURCES], [glib-compile-resources])]) AC_SUBST([GLIB_COMPILE_RESOURCES]) GLIB_GSETTINGS # }}} # check for gtk {{{ AC_MSG_CHECKING([which GTK version to use]) AC_ARG_WITH([gtk], [AS_HELP_STRING([--with-gtk=3.0], [GTK version to use [default=3.0]])], [with_gtk="${withval}"], [with_gtk="3.0"]) AC_MSG_RESULT([${with_gtk}]) PKG_CHECK_MODULES([GTK], ["gtk+-${with_gtk}" >= 3.18]) AC_SUBST([GTK_CFLAGS]) AC_SUBST([GTK_LIBS]) # }}} # native file chooser option {{{ AC_MSG_CHECKING([whether to enable native file chooser dialogs]) AC_ARG_ENABLE([native-file-chooser], [AS_HELP_STRING([--disable-native-file-chooser], [disable native file chooser dialogs])], [enable_native_file_chooser="${enableval}"], [enable_native_file_chooser="yes"]) AC_MSG_RESULT([${enable_native_file_chooser}]) if test "${enable_native_file_chooser}" = "yes" ; then AC_DEFINE([ENABLE_NATIVE_FILE_CHOOSER], [1], [Native file chooser]) else AC_DEFINE([ENABLE_NATIVE_FILE_CHOOSER], [0], [Native file chooser]) fi # }}} # debug option {{{ AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [enable debugging])], [enable_debug="${enableval}"], [enable_debug="no"]) AC_MSG_RESULT([${enable_debug}]) if test "${enable_debug}" = "yes" ; then AC_DEFINE([G_DISABLE_DEPRECATED], [1], [disable glib deprecated]) AC_DEFINE([GDK_DISABLE_DEPRECATED], [1], [disable gdk deprecated]) AC_DEFINE([GTK_DISABLE_DEPRECATED], [1], [disable gtk deprecated]) else AC_DEFINE([G_DISABLE_ASSERT], [1], [disable glib assert]) AC_DEFINE([G_DISABLE_CAST_CHECKS], [1], [disable glib cast checks]) fi # }}} # blake2 option {{{ AC_MSG_CHECKING([whether to use libb2]) AC_ARG_ENABLE([blake2], [AS_HELP_STRING([--disable-blake2], [do not use libb2])], [enable_blake2="${enableval}"], [enable_blake2="yes"]) AC_MSG_RESULT([${enable_blake2}]) AM_CONDITIONAL([ENABLE_BLAKE2], [test "${enable_blake2}" = "yes"]) if test "${enable_blake2}" = "yes" ; then AC_CHECK_HEADER([blake2.h], [:], [AC_MSG_ERROR([blake2 header not found])]) AC_CHECK_LIB([b2], [blake2sp_init], [:], [AC_MSG_ERROR([blake2 library not found])]) BLAKE2_LIBS="-lb2" AC_SUBST([BLAKE2_LIBS]) AC_DEFINE([ENABLE_BLAKE2], [1], [libb2]) else AC_DEFINE([ENABLE_BLAKE2], [0], [libb2]) fi # }}} # gcrypt option {{{ AC_MSG_CHECKING([whether to use Libgcrypt]) AC_ARG_ENABLE([gcrypt], [AS_HELP_STRING([--disable-gcrypt], [do not use Libgcrypt])], [enable_gcrypt="${enableval}"], [enable_gcrypt="yes"]) AC_MSG_RESULT([${enable_gcrypt}]) AM_CONDITIONAL([ENABLE_GCRYPT], [test "${enable_gcrypt}" = "yes"]) gcrypt_funcs= HASH_LIB_GCRYPT_MIN_VER="1.6.0" AC_DEFINE_UNQUOTED([HASH_LIB_GCRYPT_MIN_VER], ["${HASH_LIB_GCRYPT_MIN_VER}"], [required gcrypt version]) if test "${enable_gcrypt}" = "yes" ; then AM_PATH_LIBGCRYPT(["${HASH_LIB_GCRYPT_MIN_VER}"], [:], [AC_MSG_ERROR([Libgcrypt not found])]) AC_DEFINE([ENABLE_GCRYPT], [1], [Libgcrypt]) ac_save_CPPFLAGS="${CPPFLAGS}" ac_save_LIBS="${LIBS}" CPPFLAGS="${CPPFLAGS} ${LIBGCRYPT_CFLAGS}" LIBS="${LIBS} ${LIBGCRYPT_LIBS}" AC_CHECK_DECL([GCRY_MD_BLAKE2B_512], [gcrypt_funcs="${gcrypt_funcs} BLAKE2b BLAKE2s"], [:], [#include ]) AC_CHECK_DECL([GCRY_MD_SHA3_512], [gcrypt_funcs="${gcrypt_funcs} SHA3-224 SHA3-256 SHA3-384 SHA3-512"], [:], [#include ]) AC_CHECK_DECL([GCRY_MD_SM3], [gcrypt_funcs="${gcrypt_funcs} SM3"], [:], [#include ]) CPPFLAGS="${ac_save_CPPFLAGS}" LIBS="${ac_save_LIBS}" else AC_DEFINE([ENABLE_GCRYPT], [0], [Libgcrypt]) fi # }}} # glib checksums option {{{ AC_MSG_CHECKING([whether to use the Glib Data Checksums API]) AC_ARG_ENABLE([glib-checksums], [AS_HELP_STRING([--enable-glib-checksums], [use the Glib Data Checksums API])], [enable_glib_checksums="${enableval}"], [enable_glib_checksums="no"]) AC_MSG_RESULT([${enable_glib_checksums}]) AM_CONDITIONAL([ENABLE_GLIB_CHECKSUMS], [test "${enable_glib_checksums}" = "yes"]) if test "${enable_glib_checksums}" = "yes" ; then AC_DEFINE([ENABLE_GLIB_CHECKSUMS], [1], [Glib Checksums]) else AC_DEFINE([ENABLE_GLIB_CHECKSUMS], [0], [Glib Checksums]) fi # }}} # internal md6 option {{{ AC_MSG_CHECKING([whether to use the internal MD6 library]) AC_ARG_ENABLE([internal-md6], [AS_HELP_STRING([--disable-internal-md6], [do not use the internal MD6 library])], [enable_internal_md6="${enableval}"], [enable_internal_md6="yes"]) AC_MSG_RESULT([${enable_internal_md6}]) AM_CONDITIONAL([ENABLE_INTERNAL_MD6], [test "${enable_internal_md6}" = "yes"]) if test "${enable_internal_md6}" = "yes" ; then AC_DEFINE([ENABLE_INTERNAL_MD6], [1], [MD6]) else AC_DEFINE([ENABLE_INTERNAL_MD6], [0], [MD6]) fi # }}} # libcrypto (openssl) option {{{ AC_MSG_CHECKING([whether to use OpenSSL libcrypto]) AC_ARG_ENABLE([libcrypto], [AS_HELP_STRING([--enable-libcrypto], [use libcrypto])], [enable_libcrypto="${enableval}"], [enable_libcrypto="no"]) AC_MSG_RESULT([${enable_libcrypto}]) AM_CONDITIONAL([ENABLE_LIBCRYPTO], [test "${enable_libcrypto}" = "yes"]) if test "${enable_libcrypto}" = "yes" ; then PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto >= 1.1]) AC_SUBST([LIBCRYPTO_CFLAGS]) AC_SUBST([LIBCRYPTO_LIBS]) AC_DEFINE([ENABLE_LIBCRYPTO], [1], [libcrypto]) else AC_DEFINE([ENABLE_LIBCRYPTO], [0], [libcrypto]) fi # }}} # linux crypto option {{{ AC_MSG_CHECKING([whether to use Linux kernel AF_ALG]) AC_ARG_ENABLE([linux-crypto], [AS_HELP_STRING([--enable-linux-crypto], [use Linux kernel AF_ALG])], [enable_linux_crypto="${enableval}"], [enable_linux_crypto="no"]) AC_MSG_RESULT([${enable_linux_crypto}]) AM_CONDITIONAL([ENABLE_LINUX_CRYPTO], [test "${enable_linux_crypto}" = "yes"]) if test "${enable_linux_crypto}" = "yes" ; then AC_CHECK_HEADER([linux/if_alg.h], [:], [AC_MSG_ERROR([linux/if_alg.h not found])]) AC_DEFINE([ENABLE_LINUX_CRYPTO], [1], [Linux kernel AF_ALG]) else AC_DEFINE([ENABLE_LINUX_CRYPTO], [0], [Linux kernel AF_ALG]) fi # }}} # mbedtls option {{{ AC_MSG_CHECKING([whether to use Mbed TLS]) AC_ARG_ENABLE([mbedtls], [AS_HELP_STRING([--enable-mbedtls], [use Mbed TLS])], [enable_mbedtls="${enableval}"], [enable_mbedtls="no"]) AC_MSG_RESULT([${enable_mbedtls}]) AM_CONDITIONAL([ENABLE_MBEDTLS], [test "${enable_mbedtls}" = "yes"]) if test "${enable_mbedtls}" = "yes" ; then AC_CHECK_HEADER([mbedtls/md.h], [:], [AC_MSG_ERROR([mbedtls headers not found])]) AC_CHECK_LIB([mbedcrypto], [mbedtls_md_update], [:], [AC_MSG_ERROR([mbedtls library not found])]) MBEDTLS_LIBS="-lmbedcrypto" AC_SUBST([MBEDTLS_LIBS]) AC_DEFINE([ENABLE_MBEDTLS], [1], [Mbed TLS]) else AC_DEFINE([ENABLE_MBEDTLS], [0], [Mbed TLS]) fi # }}} # nettle option {{{ AC_MSG_CHECKING([whether to use Nettle]) AC_ARG_ENABLE([nettle], [AS_HELP_STRING([--enable-nettle], [use Nettle])], [enable_nettle="${enableval}"], [enable_nettle="no"]) AC_MSG_RESULT([${enable_nettle}]) AM_CONDITIONAL([ENABLE_NETTLE], [test "${enable_nettle}" = "yes"]) if test "${enable_nettle}" = "yes" ; then PKG_CHECK_MODULES([NETTLE], [nettle]) AC_SUBST([NETTLE_CFLAGS]) AC_SUBST([NETTLE_LIBS]) AC_DEFINE([ENABLE_NETTLE], [1], [Nettle]) else AC_DEFINE([ENABLE_NETTLE], [0], [Nettle]) fi # }}} # zlib option {{{ AC_MSG_CHECKING([whether to use zlib]) AC_ARG_ENABLE([zlib], [AS_HELP_STRING([--disable-zlib], [do not use zlib])], [enable_zlib="${enableval}"], [enable_zlib="yes"]) AC_MSG_RESULT([${enable_zlib}]) AM_CONDITIONAL([ENABLE_ZLIB], [test "${enable_zlib}" = "yes"]) if test "${enable_zlib}" = "yes" ; then PKG_CHECK_MODULES([ZLIB], [zlib]) AC_SUBST([ZLIB_CFLAGS]) AC_SUBST([ZLIB_LIBS]) AC_DEFINE([ENABLE_ZLIB], [1], [zlib]) else AC_DEFINE([ENABLE_ZLIB], [0], [zlib]) fi # }}} AC_MSG_CHECKING([whether to build gtkhash binary]) AC_ARG_ENABLE([gtkhash], [AS_HELP_STRING([--disable-gtkhash], [do not build gtkhash binary])], [enable_gtkhash="${enableval}"], [enable_gtkhash="yes"]) AC_MSG_RESULT([${enable_gtkhash}]) AM_CONDITIONAL([ENABLE_GTKHASH], [test "${enable_gtkhash}" = "yes"]) # appstream option {{{ AC_MSG_CHECKING([whether to install AppStream metadata files]) AC_ARG_ENABLE([appstream], [AS_HELP_STRING([--disable-appstream], [do not install AppStream metadata files])], [enable_appstream="${enableval}"], [enable_appstream="yes"]) AC_MSG_RESULT([${enable_appstream}]) AM_CONDITIONAL([ENABLE_APPSTREAM], [test "${enable_appstream}" = "yes"]) # }}} # caja option {{{ AC_MSG_CHECKING([whether to build the Caja extension]) AC_ARG_ENABLE([caja], [AS_HELP_STRING([--enable-caja], [build the Caja extension])], [enable_caja="${enableval}"], [enable_caja="no"]) AC_MSG_RESULT([${enable_caja}]) AM_CONDITIONAL([ENABLE_CAJA], [test "${enable_caja}" = "yes"]) if test "${enable_caja}" = "yes" ; then # Check for caja PKG_CHECK_MODULES([CAJA], [libcaja-extension]) AC_SUBST([CAJA_CFLAGS]) AC_SUBST([CAJA_LIBS]) CAJA_EXTENSION_DIR=`${PKG_CONFIG} --variable=extensiondir libcaja-extension` AC_SUBST([CAJA_EXTENSION_DIR]) fi # }}} # nautilus option {{{ AC_MSG_CHECKING([whether to build the Nautilus extension]) AC_ARG_ENABLE([nautilus], [AS_HELP_STRING([--enable-nautilus], [build the Nautilus extension])], [enable_nautilus="${enableval}"], [enable_nautilus="no"]) AC_MSG_RESULT([${enable_nautilus}]) AM_CONDITIONAL([ENABLE_NAUTILUS], [test "${enable_nautilus}" = "yes"]) if test "${enable_nautilus}" = "yes" ; then # Check for nautilus PKG_CHECK_MODULES([NAUTILUS], [libnautilus-extension]) AC_SUBST([NAUTILUS_CFLAGS]) AC_SUBST([NAUTILUS_LIBS]) NAUTILUS_EXTENSION_DIR=`${PKG_CONFIG} --variable=extensiondir libnautilus-extension` AC_SUBST([NAUTILUS_EXTENSION_DIR]) # nautilus-3.29.90+ moved to a different header file ac_save_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} ${NAUTILUS_CFLAGS}" AC_CHECK_HEADERS([nautilus-extension.h]) CPPFLAGS="${ac_save_CPPFLAGS}" fi # }}} # nemo option {{{ AC_MSG_CHECKING([whether to build the Nemo extension]) AC_ARG_ENABLE([nemo], [AS_HELP_STRING([--enable-nemo], [build the Nemo extension])], [enable_nemo="${enableval}"], [enable_nemo="no"]) AC_MSG_RESULT([${enable_nemo}]) AM_CONDITIONAL([ENABLE_NEMO], [test "${enable_nemo}" = "yes"]) if test "${enable_nemo}" = "yes" ; then # Check for nemo PKG_CHECK_MODULES([NEMO], [libnemo-extension]) AC_SUBST([NEMO_CFLAGS]) AC_SUBST([NEMO_LIBS]) NEMO_EXTENSION_DIR=`${PKG_CONFIG} --variable=extensiondir libnemo-extension` AC_SUBST([NEMO_EXTENSION_DIR]) fi # }}} # thunar option {{{ AC_MSG_CHECKING([whether to build the Thunar extension]) AC_ARG_ENABLE([thunar], [AS_HELP_STRING([--enable-thunar], [build the Thunar extension])], [enable_thunar="${enableval}"], [enable_thunar="no"]) AC_MSG_RESULT([${enable_thunar}]) AM_CONDITIONAL([ENABLE_THUNAR], [test "${enable_thunar}" = "yes"]) AC_MSG_CHECKING([which Thunarx version to use]) AC_ARG_WITH([thunarx], [AS_HELP_STRING([--with-thunarx=3], [Thunarx version to use [default=3]])], [with_thunar="${withval}"], [with_thunarx="3"]) AC_MSG_RESULT([${with_thunarx}]) if test "${enable_thunar}" = "yes" ; then # Check for thunar PKG_CHECK_MODULES([THUNAR], ["thunarx-${with_thunarx}" >= 1.7.0]) AC_SUBST([THUNAR_CFLAGS]) AC_SUBST([THUNAR_LIBS]) THUNAR_EXTENSION_DIR=`${PKG_CONFIG} --variable=extensionsdir "thunarx-${with_thunarx}"` AC_SUBST([THUNAR_EXTENSION_DIR]) fi # }}} AM_CONDITIONAL([ENABLE_NAUTILUS_DATA], [ test "${enable_caja}" = "yes" || test "${enable_nautilus}" = "yes" || test "${enable_nemo}" = "yes" || test "${enable_thunar}" = "yes"]) # Matches preferred order from src/hash/hash-lib.c HASH_LIBS="blake2 gcrypt libcrypto mbedtls nettle linux_crypto zlib glib_checksums internal_md6" AC_SUBST([HASH_LIBS]) AC_DEFINE_UNQUOTED([G_LOG_DOMAIN], ["${PACKAGE_NAME}"], [Define the Glib log domain]) AC_DEFINE([HASH_FILE_BUFFER_SIZE], [131072], [Define file read buffer size (bytes)]) AC_DEFINE([HASH_FILE_REPORT_INTERVAL], [166], [Define progress report interval (milliseconds)]) AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([data/Makefile]) AC_CONFIG_FILES([data/appdata/Makefile]) AC_CONFIG_FILES([data/appdata/org.gtkhash.gtkhash.appdata.xml.in]) AC_CONFIG_FILES([data/appdata/org.gtkhash.caja.metainfo.xml.in]) AC_CONFIG_FILES([data/appdata/org.gtkhash.nautilus.metainfo.xml.in]) AC_CONFIG_FILES([data/appdata/org.gtkhash.nemo.metainfo.xml.in]) AC_CONFIG_FILES([data/appdata/org.gtkhash.thunar.metainfo.xml.in]) AC_CONFIG_FILES([data/caja/Makefile]) AC_CONFIG_FILES([data/caja/libgtkhash-properties-caja.caja-extension.in]) AC_CONFIG_FILES([data/icons/Makefile]) AC_CONFIG_FILES([data/nautilus/Makefile]) AC_CONFIG_FILES([po/Makefile.in]) AC_CONFIG_FILES([src/Makefile]) AC_CONFIG_FILES([src/hash/Makefile]) AC_CONFIG_FILES([src/test.md5sum]) AC_CONFIG_FILES([src/nautilus/Makefile]) AC_CONFIG_FILES([src/util/Makefile]) AC_OUTPUT echo echo "Interfaces:" echo " gtkhash: ${enable_gtkhash} (gtk+-${with_gtk})" echo " gtkhash-caja: ${enable_caja}" echo " gtkhash-nautilus: ${enable_nautilus}" echo " gtkhash-nemo: ${enable_nemo}" echo " gtkhash-thunar: ${enable_thunar} (thunarx-${with_thunarx})" blake2_funcs=" BLAKE2b BLAKE2s BLAKE2bp BLAKE2sp" gcrypt_funcs="${gcrypt_funcs} CRC32 GOST MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512 TIGER192 WHIRLPOOL" glib_checksums_funcs=" MD5 SHA1 SHA256 SHA384 SHA512" internal_md6_funcs=" MD6-224 MD6-256 MD6-384 MD6-512" libcrypto_funcs=" BLAKE2b BLAKE2s MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512 SHA3-224 SHA3-256 SHA3-384 SHA3-512 SM3 WHIRLPOOL" linux_crypto_funcs=" BLAKE2b BLAKE2s CRC32C MD4 MD5 RIPEMD128 RIPEMD160 RIPEMD256 RIPEMD320 SHA1 SHA224 SHA256 SHA384 SHA512 SHA3-224 SHA3-256 SHA3-384 SHA3-512 TIGER192 WHIRLPOOL XXH64" mbedtls_funcs=" MD2 MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512" nettle_funcs=" GOST MD2 MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512 SHA3-224 SHA3-256 SHA3-384 SHA3-512" zlib_funcs=" ADLER32 CRC32" echo printf "%-20s%s\n" "Hash Function" "Preferred Implementation" have_libs="" for func in \ ADLER32 \ BLAKE2b BLAKE2s BLAKE2bp BLAKE2sp \ CRC32 CRC32C \ GOST \ MD2 \ MD4 \ MD5 \ MD6-224 MD6-256 MD6-384 MD6-512 \ MDC2 \ RIPEMD128 RIPEMD160 RIPEMD256 RIPEMD320 \ SHA1 \ SHA224 SHA256 SHA384 SHA512 \ SHA3-224 SHA3-256 SHA3-384 SHA3-512 \ SM3 \ TIGER192 \ WHIRLPOOL \ XXH64 do printf " %-20s" "${func}" enabled="" for lib in ${HASH_LIBS} ; do eval test \${enable_${lib}} = "yes" || continue if eval echo \${${lib}_funcs} | tr ' ' '\n' \ | grep -q "^${func}$" then test -n "${enabled}" && printf "," printf "${lib}" enabled="yes" have_libs="yes" test "${lib}" = "linux_crypto" && printf "*" fi done test -n "${enabled}" && echo || echo "_" done if test "${enable_linux_crypto}" = "yes" ; then echo echo "* linux_crypto support depends on kernel module availability - check /proc/crypto" fi echo test -z "${have_libs}" && AC_MSG_ERROR([No hash libraries enabled]) # Exit status true gtkhash-1.5/data/000077500000000000000000000000001431266303500137245ustar00rootroot00000000000000gtkhash-1.5/data/Makefile.am000066400000000000000000000011211431266303500157530ustar00rootroot00000000000000SUBDIRS = icons if ENABLE_APPSTREAM SUBDIRS += appdata endif if ENABLE_CAJA SUBDIRS += caja endif if ENABLE_NAUTILUS_DATA SUBDIRS += nautilus endif if ENABLE_GTKHASH applicationsdir = $(datadir)/applications applications_DATA = org.gtkhash.gtkhash.desktop gsettings_SCHEMAS = org.gtkhash.gschema.xml EXTRA_DIST = \ $(applications_DATA).in \ $(gsettings_SCHEMAS) \ gtkhash-gtk3.ui \ gtkhash-gtk3.gresource.xml \ meson.build CLEANFILES = $(applications_DATA) endif %.desktop: %.desktop.in $(AM_V_GEN)$(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@ @GSETTINGS_RULES@ gtkhash-1.5/data/appdata/000077500000000000000000000000001431266303500153365ustar00rootroot00000000000000gtkhash-1.5/data/appdata/Makefile.am000066400000000000000000000013411431266303500173710ustar00rootroot00000000000000appdatadir = $(datadir)/metainfo appdata_DATA = if ENABLE_GTKHASH appdata_DATA += org.gtkhash.gtkhash.appdata.xml endif if ENABLE_CAJA appdata_DATA += org.gtkhash.caja.metainfo.xml endif if ENABLE_NAUTILUS appdata_DATA += org.gtkhash.nautilus.metainfo.xml endif if ENABLE_NEMO appdata_DATA += org.gtkhash.nemo.metainfo.xml endif if ENABLE_THUNAR appdata_DATA += org.gtkhash.thunar.metainfo.xml endif CLEANFILES = $(appdata_DATA) EXTRA_DIST = \ org.gtkhash.gtkhash.appdata.xml.in \ org.gtkhash.caja.metainfo.xml.in \ org.gtkhash.nautilus.metainfo.xml.in \ org.gtkhash.nemo.metainfo.xml.in \ org.gtkhash.thunar.metainfo.xml.in \ meson.build %.xml: %.xml.in $(AM_V_GEN)$(MSGFMT) --xml --template $< -d $(top_srcdir)/po -o $@ gtkhash-1.5/data/appdata/meson.build000066400000000000000000000014121431266303500174760ustar00rootroot00000000000000metainfos = [] if build_gtkhash metainfos += 'org.gtkhash.gtkhash.appdata.xml' endif if build_caja metainfos += 'org.gtkhash.caja.metainfo.xml' endif if build_nautilus metainfos += 'org.gtkhash.nautilus.metainfo.xml' endif if build_nemo metainfos += 'org.gtkhash.nemo.metainfo.xml' endif if build_thunar metainfos += 'org.gtkhash.thunar.metainfo.xml' endif foreach metainfo : metainfos metainfo_in = configure_file( input: metainfo + '.in.in', output: metainfo + '.in', configuration: data_config, ) i18n.merge_file( input: metainfo_in, output: metainfo, install: true, install_dir: get_option('datadir') / 'metainfo', po_dir: po_dir, type: 'xml', ) endforeach gtkhash-1.5/data/appdata/org.gtkhash.caja.metainfo.xml.in.in000066400000000000000000000014201431266303500240040ustar00rootroot00000000000000 org.gtkhash.caja caja.desktop CC0-1.0 GPL-2.0+ Checksums Adds message digests or checksums to file properties https://github.com/tristanheaven/gtkhash https://github.com/tristanheaven/gtkhash/issues https://hosted.weblate.org/engage/gtkhash/ Tristan Heaven tristan@tristanheaven.net gtkhash-1.5/data/appdata/org.gtkhash.gtkhash.appdata.xml.in.in000066400000000000000000000031731431266303500243560ustar00rootroot00000000000000 org.gtkhash.gtkhash org.gtkhash.gtkhash.desktop CC0-1.0 GPL-2.0+ GtkHash Calculate message digests or checksums

GtkHash is an application for computing file checksums, or message digests. It's designed to be an easy to use, graphical alternative to command-line programs such as md5sum.

Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32.

https://raw.githubusercontent.com/tristanheaven/gtkhash/master/screenshots/gtkhash-screenshot-light.png gtkhash https://github.com/tristanheaven/gtkhash https://github.com/tristanheaven/gtkhash/issues https://hosted.weblate.org/engage/gtkhash/ Tristan Heaven tristan@tristanheaven.net gtkhash
gtkhash-1.5/data/appdata/org.gtkhash.nautilus.metainfo.xml.in.in000066400000000000000000000014421431266303500247560ustar00rootroot00000000000000 org.gtkhash.nautilus org.gnome.Nautilus.desktop CC0-1.0 GPL-2.0+ Checksums Adds message digests or checksums to file properties https://github.com/tristanheaven/gtkhash https://github.com/tristanheaven/gtkhash/issues https://hosted.weblate.org/engage/gtkhash/ Tristan Heaven tristan@tristanheaven.net gtkhash-1.5/data/appdata/org.gtkhash.nemo.metainfo.xml.in.in000066400000000000000000000014661431266303500240560ustar00rootroot00000000000000 org.gtkhash.nemo nemo.desktop org.Nemo.desktop CC0-1.0 GPL-2.0+ Checksums Adds message digests or checksums to file properties https://github.com/tristanheaven/gtkhash https://github.com/tristanheaven/gtkhash/issues https://hosted.weblate.org/engage/gtkhash/ Tristan Heaven tristan@tristanheaven.net gtkhash-1.5/data/appdata/org.gtkhash.thunar.metainfo.xml.in.in000066400000000000000000000014241431266303500244130ustar00rootroot00000000000000 org.gtkhash.thunar Thunar.desktop CC0-1.0 GPL-2.0+ Checksums Adds message digests or checksums to file properties https://github.com/tristanheaven/gtkhash https://github.com/tristanheaven/gtkhash/issues https://hosted.weblate.org/engage/gtkhash/ Tristan Heaven tristan@tristanheaven.net gtkhash-1.5/data/caja/000077500000000000000000000000001431266303500146225ustar00rootroot00000000000000gtkhash-1.5/data/caja/Makefile.am000066400000000000000000000005421431266303500166570ustar00rootroot00000000000000cajaextensionsdir = $(datadir)/caja/extensions cajaextensions_DATA = libgtkhash-properties-caja.caja-extension EXTRA_DIST = \ $(cajaextensions_DATA).in \ meson.build CLEANFILES = $(cajaextensions_DATA) %.caja-extension: %.caja-extension.in $(AM_V_GEN)$(MSGFMT) --desktop --keyword Name --keyword Description --template $< -d $(top_srcdir)/po -o $@ gtkhash-1.5/data/caja/libgtkhash-properties-caja.caja-extension.in.in000066400000000000000000000003541431266303500256760ustar00rootroot00000000000000[Caja Extension] Icon=org.gtkhash.gtkhash Name=Checksums Description=Calculate message digests or checksums Author=Tristan Heaven Copyright= Version=@VERSION@ Website=https://github.com/tristanheaven/gtkhash gtkhash-1.5/data/caja/meson.build000066400000000000000000000007511431266303500167670ustar00rootroot00000000000000 cajaextension = 'libgtkhash-properties-caja.caja-extension' cajaextension_in = configure_file( input: cajaextension + '.in.in', output: cajaextension + '.in', configuration: data_config, ) i18n.merge_file( input: cajaextension_in, output: cajaextension, install: true, install_dir: get_option('datadir') / 'caja' / 'extensions', po_dir: po_dir, type: 'desktop', args: [ '--keyword', 'Name', '--keyword', 'Description', ] ) gtkhash-1.5/data/gtkhash-gtk3.gresource.xml000066400000000000000000000003011431266303500207340ustar00rootroot00000000000000 gtkhash-gtk3.ui gtkhash-1.5/data/gtkhash-gtk3.ui000066400000000000000000001573731431266303500166020ustar00rootroot00000000000000 Lowercase Hexadecimal Uppercase Hexadecimal Base64 True False edit-copy 1 True False gtk-add True False True True True gtk-remove True False False True True True gtk-clear True False False True True True True False Copy _Digest True False False True image_copy False True True False True False True False Show _Toolbar True True False system-run True False document-open 1 True False document-save-as 1 False GtkHash 500 340 org.gtkhash.gtkhash True False vertical True False True False _File True True False _Open Digest File… True False True image_open False True _Save Digest File… True False False True image_save_as False True True False gtk-quit True False True True True True False _Edit True True False gtk-cut True False True True True gtk-copy True False True True True gtk-paste True False True True True gtk-delete True False True True True True False gtk-select-all True False True True True True False gtk-preferences True False True True True True False _View True True False True False _File True True True True False _Text True True radiomenuitem_file True False File _List True True radiomenuitem_file True False _Help True True False gtk-about True False True True True False True 0 False both-horiz 2 True False True gtk-add False True True False False True gtk-remove False True True False False True gtk-clear False True False True 1 True False 6 vertical True False vertical True False 6 True False vertical 3 True True False start File: True True 0 True False start Text: True True 1 True False start Check: True True 2 False True 0 True False vertical 3 True True False False False True False 0 True True True True 1 True False 2 True True True gtk-paste False Paste digest from clipboard True True 0 True True True gtk-paste False Paste digest from clipboard True True 1 HMAC Key: True True False False False True 2 True True False False True True 3 HMAC Key: True True False False False True 4 True True False False True True 5 True True 2 True True 1 False True 0 True False False True 6 1 True True never False True False start natural natural none True False 6 True False vertical 3 True False True 0 True False vertical 3 True True True 1 True False vertical 3 True True True 2 True True 2 True True 0 True False vertical True False 6 True True 450 150 False True True True 2 False True 3 multiple False True True 1 1 False 1 True 100 File True True 2 2 False 3 False 4 True True 0 True True 1 True False vertical True False False True 6 0 True False 6 True False 0.5 False True middle True True 0 True False 6 end Ha_sh True False True True True image_execute True True False False 0 gtk-stop True True True True True False False 1 False True 1 False True 1 False True end 2 True True 2 False 6 GtkHash Preferences True dialog window True False vertical 6 True False end gtk-close True True True True True True False False 0 True True end 0 True False 0 True False True True True False Hash Functions False True 0 True False 0 HMAC True True False True True False MAC Functions False True 1 True False 6 True False Digest Format: False True 0 True False dialog_liststore 0 0 True True 1 False True 2 dialog_button_close gtkhash-1.5/data/icons/000077500000000000000000000000001431266303500150375ustar00rootroot00000000000000gtkhash-1.5/data/icons/Makefile.am000066400000000000000000000015521431266303500170760ustar00rootroot00000000000000icondir = $(datadir)/icons/hicolor/scalable/apps icon_DATA = scalable/org.gtkhash.gtkhash.svg icon32dir = $(datadir)/icons/hicolor/32x32/apps icon32_DATA = 32/org.gtkhash.gtkhash.png icon48dir = $(datadir)/icons/hicolor/48x48/apps icon48_DATA = 48/org.gtkhash.gtkhash.png icon64dir = $(datadir)/icons/hicolor/64x64/apps icon64_DATA = 64/org.gtkhash.gtkhash.png icon128dir = $(datadir)/icons/hicolor/128x128/apps icon128_DATA = 128/org.gtkhash.gtkhash.png icon256dir = $(datadir)/icons/hicolor/256x256/apps icon256_DATA = 256/org.gtkhash.gtkhash.png genicons = \ $(icon32_DATA) \ $(icon48_DATA) \ $(icon64_DATA) \ $(icon128_DATA) \ $(icon256_DATA) EXTRA_DIST = \ $(icon_DATA) \ $(genicons) \ meson.build \ rename_icons.sh MAINTAINERCLEANFILES = $(genicons) %.png: $(icon_DATA) $(AM_V_GEN) $(MKDIR_P) -- $(@D) && \ rsvg-convert -w $(@D) -h $(@D) $< -o $@ gtkhash-1.5/data/icons/meson.build000066400000000000000000000021431431266303500172010ustar00rootroot00000000000000icons_install_dir = get_option('datadir')/'icons'/'hicolor' generated_sizes = [ 32, 48, 64, 128, 256, ] icon_basename = 'org.gtkhash.gtkhash' svg_file = files('scalable/@0@.svg'.format(icon_basename)) install_data(svg_file, install_dir: icons_install_dir / 'scalable' / 'apps') foreach size : generated_sizes sizestr = '@0@'.format(size) sizedir = '@0@x@0@'.format(size) local_icon_name = '@0@.@1@.png'.format(icon_basename, sizedir) icon = custom_target(local_icon_name, input: svg_file, output: local_icon_name, command: [ 'rsvg-convert', '-w', sizestr, '-h', sizestr, '@INPUT@', '-o', '@OUTPUT@' ], install: true, install_dir: icons_install_dir / sizedir / 'apps', # install_rename: '@0@.png'.format(icon_basename), ) # That's required because Meson does not yet allow custom_target to be # renamed on install step. meson.add_install_script('rename_icons.sh', icons_install_dir/sizedir/'apps', local_icon_name, '@0@.png'.format(icon_basename), ) endforeach gtkhash-1.5/data/icons/rename_icons.sh000066400000000000000000000002461431266303500200370ustar00rootroot00000000000000#!/bin/sh mv_dir="$1" file_in="$2" file_out="$3" exec mv -- "$MESON_INSTALL_DESTDIR_PREFIX/$mv_dir/$file_in" \ "$MESON_INSTALL_DESTDIR_PREFIX/$mv_dir/$file_out" gtkhash-1.5/data/icons/scalable/000077500000000000000000000000001431266303500166055ustar00rootroot00000000000000gtkhash-1.5/data/icons/scalable/org.gtkhash.gtkhash.svg000066400000000000000000000103231431266303500231740ustar00rootroot00000000000000 image/svg+xml gtkhash-1.5/data/meson.build000066400000000000000000000011701431266303500160650ustar00rootroot00000000000000subdir('icons') if enable_appstream subdir('appdata') endif if build_caja subdir('caja') endif if enable_nautilus_data subdir('nautilus') endif if build_gtkhash i18n.merge_file( input: 'org.gtkhash.gtkhash.desktop.in', output: 'org.gtkhash.gtkhash.desktop', install: true, install_dir: get_option('datadir') / 'applications', po_dir: po_dir, type: 'desktop', ) install_data( 'org.gtkhash.gschema.xml', install_dir: get_option('datadir') / 'glib-2.0' / 'schemas', ) endif gtkhash_gtk3_gresource = files('gtkhash-gtk3.gresource.xml') gtkhash-1.5/data/nautilus/000077500000000000000000000000001431266303500155705ustar00rootroot00000000000000gtkhash-1.5/data/nautilus/Makefile.am000066400000000000000000000002701431266303500176230ustar00rootroot00000000000000gsettings_SCHEMAS = org.gtkhash.plugin.gschema.xml EXTRA_DIST = \ $(gsettings_SCHEMAS) \ gtkhash-properties.ui \ gtkhash-properties.gresource.xml \ meson.build @GSETTINGS_RULES@ gtkhash-1.5/data/nautilus/gtkhash-properties.gresource.xml000066400000000000000000000003161431266303500241320ustar00rootroot00000000000000 gtkhash-properties.ui gtkhash-1.5/data/nautilus/gtkhash-properties.ui000066400000000000000000000312111431266303500217500ustar00rootroot00000000000000 True False edit-copy 1 True False _Copy Digest True False True image_copy False True True False True False Show _Disabled Hash Functions True True True False system-run liststore True False vertical True True 8 in True True treemodelfilter False False 0 False 1 Hash Function 2 Digest 3 True True 0 True False 4 8 8 True False True False 6 True False Check: False True 0 True True True gtk-paste False Paste digest from clipboard True True 1 True True 0 True False HMAC Key: True True False False False True 0 True True False False True True 1 True True 2 False True 2 True False True False 0.5 8 2 False True middle True True 0 True False 8 8 end gtk-stop True False True True True True False False 0 H_ash True True True image_execute True True False False 1 False True 1 False True 6 3 gtkhash-1.5/data/nautilus/meson.build000066400000000000000000000003011431266303500177240ustar00rootroot00000000000000install_data( 'org.gtkhash.plugin.gschema.xml', install_dir: get_option('datadir') / 'glib-2.0' / 'schemas', ) gtkhash_properties_gresource = files('gtkhash-properties.gresource.xml') gtkhash-1.5/data/nautilus/org.gtkhash.plugin.gschema.xml000066400000000000000000000005401431266303500234330ustar00rootroot00000000000000 [ 'MD5', 'SHA1', 'SHA256', 'CRC32' ] true gtkhash-1.5/data/org.gtkhash.gschema.xml000066400000000000000000000020611431266303500202720ustar00rootroot00000000000000 'hex-lower' [ 'MD5', 'SHA1', 'SHA256', 'CRC32' ] false true 'file' 0 false 0 gtkhash-1.5/data/org.gtkhash.gtkhash.desktop.in000066400000000000000000000004561431266303500216000ustar00rootroot00000000000000[Desktop Entry] Name=GtkHash GenericName=Checksum Calculator Comment=Calculate message digests or checksums Keywords=hash;checksum;digest;md5;sha1;sha256;crc32; TryExec=gtkhash Exec=gtkhash %U Icon=org.gtkhash.gtkhash Terminal=false Type=Application StartupNotify=true Categories=Utility;Security;GTK; gtkhash-1.5/meson.build000066400000000000000000000215731431266303500151650ustar00rootroot00000000000000project('gtkhash', 'c', version: '1.5', meson_version: '>=0.53.0', default_options: [ 'warning_level=2', ], ) gnome = import('gnome') pkgconfig = import('pkgconfig') i18n = import('i18n') ################################################################################ # Project configuration config = configuration_data() data_config = configuration_data() gettext_package = meson.project_name() config.set_quoted('GETTEXT_PACKAGE', gettext_package) config.set10('ENABLE_NLS', true) build_gtkhash = get_option('build-gtkhash') enable_appstream = get_option('appstream') config.set10('ENABLE_NATIVE_FILE_CHOOSER', get_option('native-file-chooser')) config.set('HASH_FILE_BUFFER_SIZE', 131072, description: 'File read buffer size (bytes)') config.set('HASH_FILE_REPORT_INTERVAL', 166, description: 'Progress report interval (milliseconds)') package_name = 'GtkHash' config.set_quoted('VERSION', meson.project_version()) config.set_quoted('PACKAGE', meson.project_name()) config.set_quoted('PACKAGE_NAME', package_name) config.set_quoted('PACKAGE_STRING', package_name + ' ' + meson.project_version()) config.set_quoted('G_LOG_DOMAIN', package_name) config.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir')) data_config.set('VERSION', meson.project_version()) data_config.set('RELEASE_DATE', '2020-07-11') ################################################################################ # Compiler options cc = meson.get_compiler('c') assert(get_option('warning_level').to_int() >= 2) # Todo check which options are used by Meson compiler_options = [ '-fno-common', '-fvisibility=hidden', '-pedantic', '-Waggregate-return', '-Wbad-function-cast', '-Wcast-align', '-Werror=implicit-function-declaration', '-Wfloat-equal', '-Wformat-nonliteral', '-Wformat-security', '-Wformat-signedness', '-Wformat', '-Wlogical-op', '-Wmissing-declarations', '-Wmissing-noreturn', '-Wno-parentheses-equality', '-Wredundant-decls', '-Wshadow', '-Wswitch-default', '-Wundef', '-Wwrite-strings', ] add_project_arguments(cc.get_supported_arguments(compiler_options), language: 'c') ################################################################################ # Dependencies no_dep = dependency('', required: false) glib = dependency('glib-2.0', version: '>=2.48.0') gio = dependency('gio-2.0', version: '>=2.48.0') gtk = dependency('gtk+-3.0', version: '>=3.18') ####################################### # Hash libraries ##### Blake2 blake2 = get_option('blake2') ? dependency('libb2') : no_dep config.set10('ENABLE_BLAKE2', get_option('blake2')) ##### GCrypt libgcrypt = get_option('gcrypt') ? dependency('libgcrypt', version: '>=1.6.0') : no_dep config.set10('ENABLE_GCRYPT', get_option('gcrypt')) config.set_quoted('HASH_LIB_GCRYPT_MIN_VER', '1.6.0') detected_gcrypt_functions = [] if cc.has_header_symbol('gcrypt.h', 'GCRY_MD_BLAKE2B_512') detected_gcrypt_functions += [ 'BLAKE2b', 'BLAKE2s' ] endif if cc.has_header_symbol('gcrypt.h', 'GCRY_MD_SHA3_512') detected_gcrypt_functions += [ 'SHA3-224', 'SHA3-256', 'SHA3-384', 'SHA3-512' ] endif if cc.has_header_symbol('gcrypt.h', 'GCRY_MD_SM3') detected_gcrypt_functions += [ 'SM3' ] endif ##### Glib checksums config.set10('ENABLE_GLIB_CHECKSUMS', get_option('glib-checksums')) ##### Internal MD6 config.set10('ENABLE_INTERNAL_MD6', get_option('internal-md6')) ##### Libcrypto (openssl) libcrypto = get_option('libcrypto') ? dependency('libcrypto', version: '>=1.1') : no_dep config.set10('ENABLE_LIBCRYPTO', get_option('libcrypto')) ##### Linux crypto if get_option('linux-crypto') cc.has_header('linux/if_alg.h') or error('Header if_alg.h not found !') endif config.set10('ENABLE_LINUX_CRYPTO', get_option('linux-crypto')) ##### MbedTLS mbedtls = get_option('mbedtls') ? \ cc.find_library('mbedcrypto', has_headers: 'mbedtls/md.h') : no_dep config.set10('ENABLE_MBEDTLS', get_option('mbedtls')) ##### Nettle nettle = get_option('nettle') ? dependency('nettle') : no_dep config.set10('ENABLE_NETTLE', nettle.found()) ##### Zlib zlib = get_option('zlib') ? dependency('zlib') : no_dep config.set10('ENABLE_ZLIB', zlib.found()) ####################################### # File manager extensions build_caja = get_option('build-caja') if build_caja caja = dependency('libcaja-extension') caja_extension_dir = caja.get_pkgconfig_variable('extensiondir') endif build_nautilus = get_option('build-nautilus') if build_nautilus nautilus = dependency('libnautilus-extension') nautilus_extension_dir = nautilus.get_pkgconfig_variable('extensiondir') have_nautilus_header = cc.has_header('nautilus/nautilus-extension.h') endif config.set10('HAVE_NAUTILUS_EXTENSION_H', build_nautilus and have_nautilus_header) build_nemo = get_option('build-nemo') if build_nemo nemo = dependency('libnemo-extension') nemo_extension_dir = nemo.get_pkgconfig_variable('extensiondir') endif build_thunar = get_option('build-thunar') thunarx = get_option('thunarx') if build_thunar thunar = dependency('thunarx-' + thunarx, version: '>=1.7.0') thunar_extension_dir = thunar.get_pkgconfig_variable('extensionsdir') endif enable_nautilus_data = build_caja or build_nautilus or build_nemo or build_thunar if [ 'debug', 'debugoptimized' ].contains(get_option('buildtype')) config.set10('G_DISABLE_DEPRECATED', true) config.set10('GDK_DISABLE_DEPRECATED', true) config.set10('GTK_DISABLE_DEPRECATED', true) else config.set10('G_DISABLE_ASSERT', true) config.set10('G_DISABLE_CAST_CHECKS', true) endif add_project_arguments('-DHAVE_CONFIG_H', language: 'c') root_include = include_directories('.') configure_file( output: 'config.h', configuration: config, ) summary({ 'gtkhash' : '@0@ (@1@)'.format(build_gtkhash, gtk.name()), 'gtkhash-caja' : '@0@'.format(build_caja), 'gtkhash-nautilus' : '@0@'.format(build_nautilus), 'gtkhash-nemo' : '@0@'.format(build_nemo), 'gtkhash-thunar' : '@0@ (thunarx-@1@)'.format(build_thunar, thunarx), }, section: 'Interfaces', ) ################################################################################ # List available hash functions hash_functions = [ 'ADLER32', 'BLAKE2b', 'BLAKE2s', 'BLAKE2bp', 'BLAKE2sp', 'CRC32', 'CRC32C', 'GOST', 'MD2', 'MD4', 'MD5', 'MD6-224', 'MD6-256', 'MD6-384', 'MD6-512', 'MDC2', 'RIPEMD128', 'RIPEMD160', 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'SHA3-224', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'SM3', 'TIGER192', 'WHIRLPOOL', 'XXH64', ] gcrypt_funcs = detected_gcrypt_functions + [ 'CRC32', 'GOST', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'TIGER192', 'WHIRLPOOL', ] libcrypto_funcs = [ 'BLAKE2b', 'BLAKE2s', 'MD2', 'MD4', 'MD5', 'MDC2', 'RIPEMD160', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'SHA3-224', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'SM3', 'WHIRLPOOL', ] linux_crypto_funcs = [ 'BLAKE2b', 'BLAKE2s', 'CRC32C', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'SHA3-224', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'TIGER192', 'WHIRLPOOL', 'XXH64', ] mbedtls_funcs = [ 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', ] nettle_funcs = [ 'GOST', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'SHA3-224', 'SHA3-256', 'SHA3-384', 'SHA3-512', ] # Matches preferred order from src/hash/hash-lib.c hash_libs = { 'blake2': [ 'BLAKE2b', 'BLAKE2s', 'BLAKE2bp', 'BLAKE2sp', ], 'gcrypt': gcrypt_funcs, 'glib_checksums': [ 'MD5', 'SHA1', 'SHA256', 'SHA384', 'SHA512', ], 'internal_md6': [ 'MD6-224', 'MD6-256', 'MD6-384', 'MD6-512', ], 'libcrypto': libcrypto_funcs, 'linux_crypto': linux_crypto_funcs, 'mbedtls': mbedtls_funcs, 'nettle': nettle_funcs, 'zlib': [ 'ADLER32', 'CRC32', ], } functions_provided = { 'Hash Function': 'Preferred Implementation' } foreach function : hash_functions provide = [] foreach lib, functions : hash_libs lib_enabled = config.get('ENABLE_' + lib.to_upper()) == 1 if lib_enabled and functions.contains(function) provide += lib endif endforeach functions_provided += { function: ', '.join(provide) } endforeach summary(functions_provided, section: 'Libraries') if get_option('linux-crypto') summary({ 'linux-crypto': 'support depends on kernel module availability - check /proc/crypto'}) endif ############################################################################### subdir('po') subdir('data') subdir('src') gtkhash-1.5/meson_options.txt000066400000000000000000000031571431266303500164560ustar00rootroot00000000000000option('blake2', type: 'boolean', value: 'true', description: 'Use libb2') option('gcrypt', type: 'boolean', value: 'true', description: 'Use Libgcrypt') option('glib-checksums', type: 'boolean', value: 'false', description: 'Use the Glib Data Checksums API') option('internal-md6', type: 'boolean', value: 'true', description: 'Use the internal MD6 library') option('libcrypto', type: 'boolean', value: 'false', description: 'Use OpenSSL libcrypto') option('linux-crypto', type: 'boolean', value: 'false', description: 'Use Linux kernel AF_ALG') option('mbedtls', type: 'boolean', value: 'false', description: 'Use Mbed TLS') option('nettle', type: 'boolean', value: 'false', description: 'Use Nettle') option('zlib', type: 'boolean', value: 'true', description: 'Use zlib') option('native-file-chooser', type: 'boolean', value: 'true', description: 'Use native file chooser dialogs') option('appstream', type: 'boolean', value: 'true', description: 'Install AppStream metadata files') option('build-gtkhash', type: 'boolean', value: 'true', description: 'Build gtkhash binary') option('build-caja', type: 'boolean', value: 'false', description: 'Build the Caja extension') option('build-nautilus', type: 'boolean', value: 'false', description: 'Build the Nautilus extension') option('build-nemo', type: 'boolean', value: 'false', description: 'Build the Nemo extension') option('build-thunar', type: 'boolean', value: 'false', description: 'Build the Thunar extension') option('thunarx', type: 'string', value: '3', description: 'Thunarx version to use') gtkhash-1.5/msys2/000077500000000000000000000000001431266303500140705ustar00rootroot00000000000000gtkhash-1.5/msys2/installdeps.sh000077500000000000000000000007121431266303500167510ustar00rootroot00000000000000#!/usr/bin/env bash # All rights waived: https://creativecommons.org/publicdomain/zero/1.0/ set -e pacman -S --noconfirm --needed --noprogressbar \ mingw-w64-{x86_64,i686}-toolchain \ mingw-w64-{x86_64,i686}-pkg-config \ mingw-w64-{x86_64,i686}-glib2 \ mingw-w64-{x86_64,i686}-gtk3 \ mingw-w64-{x86_64,i686}-librsvg \ mingw-w64-{x86_64,i686}-gsettings-desktop-schemas \ mingw-w64-{x86_64,i686}-styrene \ mingw-w64-{x86_64,i686}-meson \ base-devel gtkhash-1.5/msys2/makepkg.sh000077500000000000000000000006011431266303500160430ustar00rootroot00000000000000#!/usr/bin/env bash # All rights waived: https://creativecommons.org/publicdomain/zero/1.0/ set -e cd "$(dirname "$0")"/.. git archive --prefix gtkhash/ -o msys2/mingw-w64-gtkhash/gtkhash.tar.gz HEAD cd msys2/mingw-w64-gtkhash MINGW_ARCH="mingw64 mingw32" PKGEXT='.pkg.tar.xz' exec makepkg-mingw \ --noconfirm \ --noprogressbar \ --syncdeps \ --clean \ --cleanbuild \ --force gtkhash-1.5/msys2/mingw-w64-gtkhash/000077500000000000000000000000001431266303500172565ustar00rootroot00000000000000gtkhash-1.5/msys2/mingw-w64-gtkhash/PKGBUILD000066400000000000000000000020021431266303500203740ustar00rootroot00000000000000_realname=gtkhash pkgbase=mingw-w64-${_realname} pkgname=${MINGW_PACKAGE_PREFIX}-${_realname} pkgver=git pkgrel=1 arch=( any ) pkgdesc="Desktop utility for computing message digests or checksums (mingw-w64)" depends=( ${MINGW_PACKAGE_PREFIX}-gtk3 ${MINGW_PACKAGE_PREFIX}-adwaita-icon-theme ${MINGW_PACKAGE_PREFIX}-libgcrypt ) makedepends=( ${MINGW_PACKAGE_PREFIX}-pkg-config ${MINGW_PACKAGE_PREFIX}-meson git ) options=( strip ) license=( GPL ) url="https://github.com/tristanheaven/gtkhash" install=${_realname}-${CARCH}.install source=( ${_realname}.tar.gz ) sha256sums=( SKIP ) pkgver() { git describe --always | sed -e 's/v//' -e 's/-/+/g' } _getdir() { echo "${srcdir}/${_realname}" } build() { cd "$(_getdir)" meson setup \ --prefix="/${MINGW_PREFIX}" \ --buildtype=minsize \ -Db_lto=true \ -Dappstream=false \ -Dblake2=false \ _build meson compile -C _build } check() { cd "$(_getdir)/_build" meson test -v -t 2 } package() { cd "$(_getdir)/_build" meson install --destdir "${pkgdir}" } gtkhash-1.5/msys2/mingw-w64-gtkhash/gtkhash-i686.install000066400000000000000000000003361431266303500227730ustar00rootroot00000000000000post_install() { mingw32/bin/glib-compile-schemas mingw32/share/glib-2.0/schemas mingw32/bin/gtk-update-icon-cache-3.0 -qf mingw32/share/icons/hicolor } post_upgrade() { post_install } post_remove() { post_install } gtkhash-1.5/msys2/mingw-w64-gtkhash/gtkhash-x86_64.install000066400000000000000000000003361431266303500232350ustar00rootroot00000000000000post_install() { mingw64/bin/glib-compile-schemas mingw64/share/glib-2.0/schemas mingw64/bin/gtk-update-icon-cache-3.0 -qf mingw64/share/icons/hicolor } post_upgrade() { post_install } post_remove() { post_install } gtkhash-1.5/msys2/styrene.sh000077500000000000000000000004651431266303500161250ustar00rootroot00000000000000#!/usr/bin/env bash # All rights waived: https://creativecommons.org/publicdomain/zero/1.0/ set -e cd "$(dirname "$0")"/styrene do_styrene() { local pkgdir=$(readlink -f ../mingw-w64-gtkhash) MSYSTEM=MINGW${1} bash -l -c "exec styrene --pkg-dir \"${pkgdir}\" styrene.cfg" } do_styrene 64 do_styrene 32 gtkhash-1.5/msys2/styrene/000077500000000000000000000000001431266303500155615ustar00rootroot00000000000000gtkhash-1.5/msys2/styrene/styrene.cfg000066400000000000000000000046421431266303500177410ustar00rootroot00000000000000[bundle] packages = {pkg_prefix}gtkhash msys2-runtime filename_stub = gtkhash display_name = GtkHash launchers = org.gtkhash.gtkhash.desktop assume_installed = {pkg_prefix}adobe-source-code-pro-fonts {pkg_prefix}ca-certificates {pkg_prefix}cantarell-fonts {pkg_prefix}freeglut {pkg_prefix}jasper {pkg_prefix}libjpeg-turbo {pkg_prefix}librsvg {pkg_prefix}libtiff {pkg_prefix}lzo2 {pkg_prefix}python {pkg_prefix}python3 {pkg_prefix}shared-mime-info {pkg_prefix}tcl {pkg_prefix}tk {pkg_prefix}xz {pkg_prefix}zstd delete = etc mingw*/bin mingw*/include mingw*/lib mingw*/libexec mingw*/share/aclocal mingw*/share/applications/gtk3-* mingw*/share/bash-completion mingw*/share/common-lisp mingw*/share/doc mingw*/share/gettext* mingw*/share/gir-* mingw*/share/glib-2.0 mingw*/share/graphite2 mingw*/share/gtk-doc mingw*/share/icons/**/*.svg mingw*/share/icons/Adwaita/256x256 mingw*/share/icons/Adwaita/512x512 mingw*/share/icons/Adwaita/cursors mingw*/share/icons/Adwaita/*/actions mingw*/share/icons/Adwaita/*/apps mingw*/share/icons/Adwaita/*/categories mingw*/share/icons/Adwaita/*/devices mingw*/share/icons/Adwaita/*/emblems mingw*/share/icons/Adwaita/*/emotes mingw*/share/icons/Adwaita/*/mimetypes mingw*/share/icons/Adwaita/*/status mingw*/share/icons/Adwaita/*/ui mingw*/share/icons/hicolor/*/apps/gtk3-* mingw*/share/info mingw*/share/installed-tests mingw*/share/libgpg-error mingw*/share/licenses mingw*/share/locale mingw*/share/man mingw*/share/pkgconfig mingw*/share/themes mingw*/share/thumbnailers mingw*/share/vala usr/bin usr/libexec usr/share var/lib/pacman var/log nodelete = mingw*/bin/gtkhash* mingw*/bin/*.dll mingw*/bin/fc-cache* mingw*/bin/gdk-pixbuf-query-loaders* mingw*/bin/glib-compile-schemas* mingw*/bin/gspawn* mingw*/bin/gtk-launch* mingw*/bin/gtk-update-icon-cache* mingw*/lib/gdk-pixbuf-*/*/loaders.cache mingw*/lib/gdk-pixbuf-*/*/loaders/*-png.dll mingw*/share/glib-2.0/schemas mingw*/share/locale/*/*/glib20.mo mingw*/share/locale/*/*/gtk30.mo mingw*/share/locale/*/*/gtkhash.mo usr/bin/bash.exe usr/bin/cat.exe usr/bin/msys-2.0.dll var/lib/pacman/local/*-fontconfig-*/install var/lib/pacman/local/*-gtkhash-*/install var/lib/pacman/local/*-gsettings-*/install var/lib/pacman/local/*-icon-theme-*/install [org.gtkhash.gtkhash.desktop] StyreneLaunchUsingShell = true gtkhash-1.5/po/000077500000000000000000000000001431266303500134315ustar00rootroot00000000000000gtkhash-1.5/po/ChangeLog000066400000000000000000000000001431266303500151710ustar00rootroot00000000000000gtkhash-1.5/po/LINGUAS000066400000000000000000000002071431266303500144550ustar00rootroot00000000000000ar bn bn_BD ca cs da de el en_GB en_US eo es fa fi fr gl he hr hu id ie it ja lt nb_NO nl nl_BE pl pt pt_BR ru sr sv tr vi zh_CN zh_TW gtkhash-1.5/po/Makevars000066400000000000000000000066631431266303500151400ustar00rootroot00000000000000# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = GtkHash authors # This tells whether or not to prepend "GNU " prefix to the package # name that gets inserted into the header of the $(DOMAIN).pot file. # Possible values are "yes", "no", or empty. If it is empty, try to # detect it automatically by scanning the files in $(top_srcdir) for # "GNU packagename" string. PACKAGE_GNU = no # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = https://github.com/tristanheaven/gtkhash/issues # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = # This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' # context. Possible values are "yes" and "no". Set this to yes if the # package uses functions taking also a message context, like pgettext(), or # if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. USE_MSGCTXT = yes # These options get passed to msgmerge. # Useful options are in particular: # --previous to keep previous msgids of translated messages, # --quiet to reduce the verbosity. MSGMERGE_OPTIONS = # These options get passed to msginit. # If you want to disable line wrapping when writing PO files, add # --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and # MSGINIT_OPTIONS. MSGINIT_OPTIONS = # This tells whether or not to regenerate a PO file when $(DOMAIN).pot # has changed. Possible values are "yes" and "no". Set this to no if # the POT file is checked in the repository and the version control # program ignores timestamps. PO_DEPENDS_ON_POT = no # This tells whether or not to forcibly update $(DOMAIN).pot and # regenerate PO files on "make dist". Possible values are "yes" and # "no". Set this to no if the POT file and PO files are maintained # externally. DIST_DEPENDS_ON_UPDATE_PO = no gtkhash-1.5/po/POTFILES.in000066400000000000000000000011341431266303500152050ustar00rootroot00000000000000# gtkhash data/gtkhash-gtk3.ui data/org.gtkhash.gtkhash.desktop.in src/callbacks.c src/check.c src/gui.c src/hash.c src/list.c src/main.c src/opts.c src/prefs.c src/util/util.c # gtkhash-properties data/nautilus/gtkhash-properties.ui src/nautilus/properties.c src/nautilus/properties-hash.c src/nautilus/properties-list.c src/nautilus/properties-prefs.c # appdata data/appdata/org.gtkhash.gtkhash.appdata.xml.in data/appdata/org.gtkhash.caja.metainfo.xml.in data/appdata/org.gtkhash.nautilus.metainfo.xml.in data/appdata/org.gtkhash.nemo.metainfo.xml.in data/appdata/org.gtkhash.thunar.metainfo.xml.in gtkhash-1.5/po/ar.po000066400000000000000000000246301431266303500144000ustar00rootroot00000000000000# Arabic translation for gtkhash # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2012. # mohammadA , 2018. # Ahmed Eldemery , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-04-05 17:26+0000\n" "Last-Translator: Ahmed Eldemery \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "X-Generator: Weblate 4.6-dev\n" "X-Launchpad-Export-Date: 2015-08-04 05:18+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "عرض بأحرف صغيرة للنظام السداسي العشري" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "عرض أحرف كبيرة للنظام السداسي العشري" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "انسخ ال_خلاصة" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "أظهر _شريط الأدوات" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_ملف" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "ا_فتح ملف حساب الخوارزمية…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "اح_فظ ملف حساب الخوارزمية…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_حرّر" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_اعرض" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_نص" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_قائمة الملف" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_مساعدة" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "الملف:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "النص:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "فحص:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "انسخ الخوارزمية المحسوبة من الحافظة" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "مفتاح HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "ملفّ" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "ها_ش" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "تفضيلات GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "دوال حساب الخوارزميات" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "الدوال بنظام MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "صيغة الخلاصة:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "حاسبة التَثَبتُ من رقم التحقق" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "احسب جُملة ورقم التحقق" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "افتح ملف التحقق" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_افتح" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_ألغ" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "ملفات التحقق بنُظم تَثَبُتٍ مختلفةٍ" #: src/callbacks.c:78 msgid "All Files" msgstr "كل الملفات" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "احفظ ملف التحقُق" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_احفظ" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "برنامج لحساب أرقام التَثَبُتُ والتحقق من موثوقية الملفات" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Ahmed Eldemery, aeldemery.de at gmail" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "اختر الملفات" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "أ_ظهر مفتاح HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "فشل في قراءة ملف التحقق: \"%s\" : %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "ليس ملفا عاديا" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "فشل في إضافة ملف: \"%s\":%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "دالة تحقق غير معروفةِ الإسم \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "تثبت من الموثوقية عن طريق المقارنة برقم تحقق" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "رقم التحقق" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "تحقق من الموثوقية عن طريق مقارنة أرقام التحقق الموجودة في الملف المُعيّن" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ملف|عنوان الملف" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "تنشيط دالة حساب التحقق المعيّنة (مثلاً بنظام MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "الدوال والخوارزميات" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "احسب رقم التحقق للنص المحدد" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "النصّ" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "أظهر معلومات الإصدار" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ملف|عنوان…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "فشل تمكين أي من وظائف التحقق." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "تبقى دقيقة %u" msgstr[1] "تبقى دقيقة %u" msgstr[2] "تبقى دقيقتان %u" msgstr[3] "تبقت %u دقائق" msgstr[4] "تبقت %u دقائق" msgstr[5] "تبقت %u دقيقة" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "تبقت ثانية %u" msgstr[1] "تبقت ثانية %u" msgstr[2] "تبقت ثانيتان %u" msgstr[3] "تبقت %u ثوان" msgstr[4] "تبقت %u ثانية" msgstr[5] "تبقت %u ثانية" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "تبقى %s من %s - %s (%s/الثوان)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "ا_نسخ رقم التحقق" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "أظهر دوال التجزئة الم_عطلة" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "دالة الهاش" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "ملخص" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_هاش" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "أرقام التحقق" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "برنامج GtkHash يتيح حساب أرقام التحقق من الموثوقية. يسمح للمستخدم بأسلوب سهل " "وواجهة استخدام بديلة عن استخدام سطر الأوامر." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "الخوارزميات وطرق الحساب المعتمدة في البرنامج تشمل الآتي MD5، SHA1، SHA256، " "SHA512، CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "أضِفْ رقم التحقق من الموثوقية إلى خصائص الملفّ" #~ msgid "Digests" #~ msgstr "ملخصات" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "احفظ الخلاصة" #, fuzzy #~ msgid "Check Digests" #~ msgstr "احفظ الخلاصة" #~ msgid "Unknown error" #~ msgstr "خطأ مجهول" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s من %s - تبقى دقيقة واحدة (%s/ثانية)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s من %s - تبقى ثانية واحدة (%s/ثانية)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s من %s - %u دقيقة متبقية (%s/ثانية)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "فشل في إضافة \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "فشل في قراءة \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "اقرأ بيانات البرنامج من الدليل المحدد" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "دليل" gtkhash-1.5/po/bn.po000066400000000000000000000237701431266303500144010ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR GtkHash authors # This file is distributed under the same license as the gtkhash package. # Oymate , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash 1.4\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-31 09:41+0000\n" "Last-Translator: Oymate \n" "Language-Team: Bengali \n" "Language: bn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "ছোট হাতের, হেক্সাডেসিমেল" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "বড়হাতের হেক্সাডেসিমেল" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "কপি _ডাইজেস্ট" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "টুলবার _দেখান" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_ফাইল" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_ডাইজেস্ট ফাইল খুলুন…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_ডাইজেস্ট ফাইল সংরক্ষণ করো…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_সম্পাদনা" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_দেখুন" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_লেখা" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "ফাইল_তালিকা" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_সহায়তা" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "ফাইল:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "লেখা:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "পরীক্ষা করুন:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "ক্লিপবোর্ড থেকে ডাইজেস্ট পেস্ট করুন" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "এইচএমএসি কী:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "ফাইল" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "হ্যা_শ" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "জিটিকেহ্যাশ পছন্দসমূহ" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "হ্যাশ ক্রিয়া" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "ম্যাক ক্রিয়া" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "ডাইজেস্ট সজ্জা:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "চেকসাম ক্যালকুলেটর" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "ডাইজেস্ট বা চেকসাম বার্তা গণনা করুন" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "ডাইজেস্ট ফাইল খুলুন" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_খুলুন" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_বাতিল" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "ডাইজেস্ট /চেকসাম ফাইলগুলি (*.sha1, *.md5, *.sfv, …)”" #: src/callbacks.c:78 msgid "All Files" msgstr "সব ফাইল" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "ডাইজেস্ট ফাইল সংরক্ষণ করুন" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_সংরক্ষণ" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "ডাইজেস্ট বা চেকসামের গণনা বার্তার জন্য একটি ডেস্কটপ যন্ত্র" #: src/callbacks.c:279 msgid "translator-credits" msgstr "অনুবাদকারি-কৃতিত্ব" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "ফাইল নির্বাচন করুন" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_এইচএমএসি(HMAC) কী দেখান" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "\"%s\" ফাইলটি পরীক্ষা করতে ব্যর্থ : %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "একটি সাধারণ ফাইল না" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "\"%s\" ফাইলটি যুক্ত করতে ব্যর্থ : %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "অজানা হ্যাশ ফাংশনের নাম \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "নির্দিষ্ট হজম বা চেকসামের সাথে পরীক্ষা করুন" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ডাইজেস্ট" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "নির্দিষ্ট ফাইল থেকে ডাইজেস্ট বা চেকসাম পরীক্ষা করুন" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ফাইল|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "নির্দিষ্ট হ্যাশ ফাংশন সক্ষম করুন (উদাঃ এমডি৫)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "ফাংশন" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "নির্দিষ্ট লেখা হ্যাশ করুন" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "টেক্সট" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "সংস্করণ তথ্য প্রদর্শন করুন" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ফাইল|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "কোনও সমর্থিত হ্যাশ ফাংশন সক্ষম করতে ব্যর্থ।" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u মিনিট বাকি" msgstr[1] "%u মিনিট বাকি" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u মিনিট বাকি" msgstr[1] "%u মিনিট বাকি" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s of %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_কপি ডাইজেস্ট" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "দেখান _অক্ষমকৃত হ্যাশ ফাংশনগুলি" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "হ্যাশ ফাংশন" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "ডাইজেস্ট" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "পরীক্ষার ফল" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "ফাইল বা বার্তা ডাইজেস্টের জন্য জিটিকেহ্যাশ একটি অ্যাপ্লিকেশন। এটি এমডি৫সামের মতো " "কমান্ড-লাইন প্রোগ্রামগুলির গ্রাফিকাল বিকল্প, যা সহজে ব্যবহারযোগ্য।" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "সমর্থিত হ্যাশ ফাংশন অন্তর্ভুক্ত এমডি৫, শা১, শা২৫৬, শা৫১২ এবং সিআরসি৩২।" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "ফাইলের বৈশিষ্ট্যে বার্তা ডাইজেস্ট বা চেকসাম যুক্ত করে" gtkhash-1.5/po/bn_BD.po000066400000000000000000000245761431266303500147530ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Oymate , 2020. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-31 08:27+0000\n" "Last-Translator: Oymate \n" "Language-Team: Bengali (Bangladesh) \n" "Language: bn_BD\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "ছোট হাতের, হেক্সাডেসিমেল" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "বড়হাতের হেক্সাডেসিমেল" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "কপি _ডাইজেস্ট" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "টুলবার _দেখান" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_ফাইল" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_ডাইজেস্ট ফাইল খুলুন…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_ডাইজেস্ট ফাইল সংরক্ষণ করো…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_সম্পাদনা" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_দেখুন" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_লেখা" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "ফাইল_তালিকা" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_সহায়তা" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "ফাইল:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "লেখা:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "পরীক্ষা করুন:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "ক্লিপবোর্ড থেকে ডাইজেস্ট পেস্ট করুন" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "এইচএমএসি কী:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "ফাইল" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "হ্যা_শ" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "জিটিকেহ্যাশ পছন্দসমূহ" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "হ্যাশ ক্রিয়া" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "ম্যাক ক্রিয়া" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "ডাইজেস্ট সজ্জা:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "চেকসাম ক্যালকুলেটর" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "ডাইজেস্ট বা চেকসাম বার্তা গণনা করুন" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "ডাইজেস্ট ফাইল খুলুন" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_খুলুন" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_বাতিল" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "ডাইজেস্ট /চেকসাম ফাইলগুলি (*.sha1, *.md5, *.sfv, …)”" #: src/callbacks.c:78 msgid "All Files" msgstr "সব ফাইল" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "ডাইজেস্ট ফাইল সংরক্ষণ করুন" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_সংরক্ষণ" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "ডাইজেস্ট বা চেকসামের গণনা বার্তার জন্য একটি ডেস্কটপ যন্ত্র" #: src/callbacks.c:279 msgid "translator-credits" msgstr "অনুবাদকারি-কৃতিত্ব" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "ফাইল নির্বাচন করুন" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_এইচএমএসি(HMAC) কী দেখান" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "\"%s\" ফাইলটি পরীক্ষা করতে ব্যর্থ : %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "একটি সাধারণ ফাইল না" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "\"%s\" ফাইলটি যুক্ত করতে ব্যর্থ : %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "অজানা হ্যাশ ফাংশনের নাম \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "নির্দিষ্ট হজম বা চেকসামের সাথে পরীক্ষা করুন" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ডাইজেস্ট" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "নির্দিষ্ট ফাইল থেকে ডাইজেস্ট বা চেকসাম পরীক্ষা করুন" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ফাইল|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "নির্দিষ্ট হ্যাশ ফাংশন সক্ষম করুন (উদাঃ এমডি৫)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "ফাংশন" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "নির্দিষ্ট লেখা হ্যাশ করুন" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "টেক্সট" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "সংস্করণ তথ্য প্রদর্শন করুন" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ফাইল|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "কোনও সমর্থিত হ্যাশ ফাংশন সক্ষম করতে ব্যর্থ।" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u মিনিট বাকি" msgstr[1] "%u মিনিট বাকি" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u সেকেন্ড বাকি" msgstr[1] "%u সেকেন্ড বাকি" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s এর %s - %s(%s/সেকেন্ড)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_কপি ডাইজেস্ট" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "দেখান _অক্ষমকৃত হ্যাশ ফাংশনগুলি" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "হ্যাশ ফাংশন" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "ডাইজেস্ট" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "পরীক্ষার ফল" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "ফাইল বা বার্তা ডাইজেস্টের জন্য জিটিকেহ্যাশ একটি অ্যাপ্লিকেশন। এটি এমডি৫সামের মতো " "কমান্ড-লাইন প্রোগ্রামগুলির গ্রাফিকাল বিকল্প, যা সহজে ব্যবহারযোগ্য।" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "সমর্থিত হ্যাশ ফাংশন অন্তর্ভুক্ত এমডি৫, শা১, শা২৫৬, শা৫১২ এবং সিআরসি৩২।" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "ফাইলের বৈশিষ্ট্যে বার্তা ডাইজেস্ট বা চেকসাম যুক্ত করে" #~ msgid "Digests" #~ msgstr "ডাইজেস্ট" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_ডাইজেস্ট ফাইল খুলুন..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_ডাইজেস্ট ফাইল সংরক্ষণ করুন..." gtkhash-1.5/po/ca.po000066400000000000000000000212471431266303500143620ustar00rootroot00000000000000# Catalan translation for gtkhash # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2016. # Toni Estévez , 2019, 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-04 23:41+0000\n" "Last-Translator: Toni Estévez \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2016-01-29 05:16+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimal en minúscules" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimal en majúscules" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copia el _resum" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "_Mostra la barra d'eines" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Fitxer" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Obre un fitxer de resums…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Desa els resums en un fitxer…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Edita" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vista" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Llista de fitxers" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Ajuda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fitxer:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Verifica:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Enganxa el resum del porta-retalls" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Clau HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fitxer" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "_Calcula" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferències del GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funcions resum" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funcions MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format del resum:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculadora de la suma de verificació" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcula resums de missatges o sumes de verificació" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Obre un fitxer de resums" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Obre" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancel·la" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Fitxers de resum/verificació (*.sha1, *.md5, *.sfv...)" #: src/callbacks.c:78 msgid "All Files" msgstr "Tots els fitxers" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Desa els resums en un fitxer" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Desa" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Una eina d'escriptori per calcular resums de missatges o sumes de verificació" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Toni Estevez " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Selecciona fitxers" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Mostra la clau HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "S'ha produït un error en llegir el fitxer de verificació «%s»: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "No és un fitxer vàlid" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "S'ha produït un error en afegir el fitxer «%s»: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "El nom de la funció resum «%s» és desconegut" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Compara amb el resum o la suma de verificació especificats" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "RESUM" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Comprova els resums o les sumes de verificació del fitxer especificat" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FITXER|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Activa la funció resum especificada (p. ex. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCIÓ" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Calcula el resum del text especificat" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Mostra informació de la versió" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FITXER|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "S'ha produït un error en activar les funcions resum compatibles." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "falta %u minut" msgstr[1] "falten %u minuts" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "falta %u segon" msgstr[1] "falten %u segons" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s - %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copia el resum" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Mostra les funcions resum _desactivades" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Funció resum" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Resum" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_Calcula" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Sumes de verificació" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash és una aplicació per calcular sumes de verificació de fitxers o " "resums de missatges. S'ha dissenyat per ser una alternativa gràfica fàcil " "d'utilitzar per a programes de línia d'ordres com md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Les funcions resum compatibles inclouen MD5, SHA1, SHA256, SHA512 i CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Afegeix resums de missatges o sumes de verificació a les propietats d'un " "fitxer." #~ msgid "Digests" #~ msgstr "Resums" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Obre un fitxer de resums..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Desa els resums en un fitxer..." #, fuzzy #~ msgid "Check Digests" #~ msgstr "Desa els resums" #~ msgid "Unknown error" #~ msgstr "S'ha produït un error desconegut." gtkhash-1.5/po/cs.po000066400000000000000000000231331431266303500144000ustar00rootroot00000000000000# Czech translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # Pavel Borecki , 2022. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2022-03-05 20:57+0000\n" "Last-Translator: Pavel Borecki \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 4.12-dev\n" "X-Launchpad-Export-Date: 2012-07-14 06:30+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Šestnáctkové (hexadecimální) malými písmeny" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Šestnáctkové (hexadecimální) velkými písmeny" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Zkopírovat _digest" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Zobrazi_t lištu nástrojů" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Soubor" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Otevřít soubor s digestem…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Uložit soubor s digestem…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "Ú_pravy" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Zobrazit" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Sezna_m souborů" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Nápověda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Soubor:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kontrola:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Vložit digest ze schránky" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC klíč:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Soubor" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Předvolby pro GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funkce pro vytváření otisku" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC funkce" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formát digestu:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kalkulátor kontrolního součtu" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Vypočítává digest zpráv nebo kontrolní součty" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Otevřít soubor s digestem" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Otevřít" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Storno" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Soubory s digestem / kontrolním součtem (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Všechny soubory" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Uložit soubor s digestem" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Uložit" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Nástroj pro výpočet digestu zpráv nebo kontrolních součtů" #: src/callbacks.c:279 #, fuzzy msgid "translator-credits" msgstr "" "Jakub Žáček https://launchpad.net/~dawon\n" "Mank https://launchpad.net/~freedcpp\n" "Martin \"sachy\" Šácha https://launchpad.net/~sachy\n" "Zbyněk Schwarz https://launchpad.net/~tsbook\n" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Vyberte soubory" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Zobrazit HMAC klíč" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Nepodařilo se číst soubor s kontrolou „%s“: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Není běžný soubor" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Nepodařilo se přidat soubor „%s“:%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Neznámá funkce pro vytváření otisku „%s“" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Zkontrolovat vůči zadanému digestu či kontrolnímu součtu" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Zkontrolovat digesty nebo kontrolní součty ze zadaného souboru" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Zapnout danou funkci pro vytváření otisku (např. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKCE" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Vytvořit otisk pro zadaný text" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Zobrazit informace o verzi" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "" "Nepodařilo se zapnout žádnou z podporovaných funkcí pro vytváření otisku." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "zbývá %u minuta" msgstr[1] "zbývají %u minuty" msgstr[2] "zbývá %u minut" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "zbývá %u sekunda" msgstr[1] "zbývají %u sekundy" msgstr[2] "zbývá %u sekund" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s z %s – %s (%s/sek)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Zkopírovat digest" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Zobrazit vypnuté funkce pro vytváření otisku" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Funkce pro vytváření otisku" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Otisk (ha_sh)" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kontrolní součty" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash je aplikace pro vypočítávání kontrolních součtů pro soubory, nebo " "digesty zpráv. Je navržena jako snadno použitelná, grafická alternativa k " "programům pro příkazový řádek, jako například md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Mezi podporované funkce pro vytváření otisků patří MD5, SHA1, SHA256, SHA512 " "a CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Přidá digest zprávy nebo kontrolní součty k vlastnostem souboru" #~ msgid "Digests" #~ msgstr "Digesty" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Uložit Digest" #, fuzzy #~ msgid "Check Digests" #~ msgstr "Uložit Digest" #~ msgid "Unknown error" #~ msgstr "Neznámá chyba" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s of %s - zbývá 1 minuta (%s/sec)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s of zbývá %s - 1 minut (%s/sec)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s of %s - zbývá %u sekund (%s/sec)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Nelze přidat \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Nelze přečíst \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Přečist data programu ze zadaného adresáře" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "ADRESÁŘ" gtkhash-1.5/po/da.po000066400000000000000000000204341431266303500143600ustar00rootroot00000000000000# Danish translation for GtkHash. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # scootergrisen, 2017. # scootergrisen , 2018, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-03 21:08+0000\n" "Last-Translator: scootergrisen \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Heksadecimal med små bogstaver" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Heksadecimal med store bogstaver" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopiér _fingeraftryk" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Vis _værktøjslinje" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Fil" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Åbn fingeraftryksfil …" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Gem fingeraftryksfil …" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Rediger" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vis" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Tekst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Fil_liste" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hjælp" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fil:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Tjek:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Indsæt fingeraftryk fra udklipsholder" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-nøgle:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fil" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-præferencer" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash-funktioner" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC-funktioner" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format for fingeraftryk:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Tjeksum-udregner" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Udregn fingeraftryk eller tjeksumme" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Åbn fingeraftryksfil" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Åbn" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Annuller" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Fingeraftryk-/tjeksum-filer (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alle filer" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Gem fingeraftryksfil" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Gem" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Et skrivebordsværktøj til at udregne fingeraftryk eller tjeksumme" #: src/callbacks.c:279 msgid "translator-credits" msgstr "scootergrisen" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Vælg filer" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Vis HMAC-nøgle" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Kunne ikke tjekke filen \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ikke en almindelig fil" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Kunne ikke tilføje filen \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Ukendt hash-funktionsnavn \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Tjek mod det angivne fingeraftryk eller tjeksum" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "FINGERAFTRYK" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Tjek fingeraftryk eller tjeksumme fra den angivne fil" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FIL|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Aktivér den angivne hash-funktion (f.eks. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash den angivne tekst" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Vis versionsinformation" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FIL|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Kunne ikke aktivere nogen understøttede hash-funktioner." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minut tilbage" msgstr[1] "%u minutter tilbage" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u sekund tilbage" msgstr[1] "%u sekunder tilbage" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s af %s - %s (%s/sek.)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopiér fingeraftryk" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Vis _deaktiverede hash-funktioner" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash-funktion" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Fingeraftryk" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Tjeksumme" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash er et program til at udregne tjeksumme på filer eller fingeraftryk. " "Det er designet til at være let at bruge og er et grafisk alternativ til " "kommandolinjeprogrammer såsom md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Understøtter hash-funktioner omfatter MD5, SHA1, SHA256, SHA512 og CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Tilføjer fingeraftryk eller tjeksumme til filegenskaber" #~ msgid "Digests" #~ msgstr "Fingeraftryk" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Åbn fingeraftryksfil..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Gem fingeraftryksfil..." #~ msgid "Check Digests" #~ msgstr "Tjek fingeraftryk" #~ msgid "Unknown error" #~ msgstr "Ukendt fejl" gtkhash-1.5/po/de.po000066400000000000000000000232201431266303500143600ustar00rootroot00000000000000# German translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # ssantos , 2018. # Ettore Atalan , 2018. # nautilusx , 2019, 2020. # Milo Ivir , 2020. # Paul , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-12-07 18:29+0000\n" "Last-Translator: Paul \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4-dev\n" "X-Launchpad-Export-Date: 2012-12-04 05:56+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadezimal in Kleinschreibung" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadezimal in Großschreibung" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Digest kopieren" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "_Werkzeugleiste anzeigen" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Datei" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Digest-Datei öffnen…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Digest-Datei speichern…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Bearbeiten" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Ansicht" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Dateiliste" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hilfe" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Datei:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Prüfung:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Digest aus der Zwischenablage einfügen" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC Schlüssel:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Datei" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-Einstellungen" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash-Funktionen" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC-Funktionen" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Digest-Format:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Prüfsummenrechner" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Berechnet Message Digest oder Prüfsummen" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Digest-Datei öffnen" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Öffnen" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Abbrechen" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Digest/Prüfsummen-Dateien (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alle Dateien" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Digest-Datei speichern" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Speichern" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Ein Desktopprogramm zur Berechnung von Digests (Prüfsummen)" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Daniel Winzen https://launchpad.net/~q-d\n" "Dennis Baudys https://launchpad.net/~thecondordb\n" "Julian Beckmann https://launchpad.net/~julian-beckmann\n" "Patrick Kolesa https://launchpad.net/~pkol\n" "Trip McKay https://launchpad.net/~trip-mckay\n" "u2ix https://launchpad.net/~u2ix" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Dateien auswählen" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Zeige HMAC Schlüssel" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Die Prüfdatei \"%s\" konnte nicht gelesen werden: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Keine gültige Datei" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Die Datei \"%s\" konnte nicht hinzugefügt werden: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Unbekannter Name der Hash-Funktion \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Prüfe gegen die bestimmte Digests oder Prüfsumme" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Digests oder Prüfsummen aus der angegebenen Datei überprüfen" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "DATEI|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Aktivieren der angegebenen Hash-Funktion (z.B. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKTIONEN" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hashe den angegebenen Text" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Versionsinformationen anzeigen" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[DATEI|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Es konnte keine der unterstützten Hash-Funktionen aktiviert werden." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u Minute verbleibend" msgstr[1] "%u Minuten verbleibend" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u Sekunde verbleibend" msgstr[1] "%u Sekunden verbleibend" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s von %s - %s (%s/sek.)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Digest kopieren" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "_Deaktivierte Hash-Funktionen anzeigen" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash Funktion" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Prüfsummen" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash ist eine Anwendung zur Berechnung von Dateiprüfsummen oder Digests. " "Es ist eine einfach zu bedienende, grafische Alternative zu " "Befehlszeilenprogrammen wie md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Unterstützte Hash-Funktionen umfassen MD5, SHA1, SHA256, SHA512 und CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Hinzufügen von Nachrichten-Digests oder Prüfsummen zu Dateieigenschaften" #~ msgid "Digests" #~ msgstr "Digests" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Digest-Datei öffnen..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Digests-Datei speichern..." #~ msgid "Check Digests" #~ msgstr "Digests prüfen" #~ msgid "Unknown error" #~ msgstr "Unbekannter Fehler" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s von %s – 1 Minute verbleibend (%s/Sek)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s von %s – 1 Sekunde verbleibend (%s/Sek)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s von %s – %u Sekunden verbleibend (%s/Sek)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Hinzufügen von »%s« gescheitert:\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Lesen von »%s« gescheitert" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Programmdaten aus dem angegebenen Ordner lesen" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "ORDNER" gtkhash-1.5/po/el.po000066400000000000000000000242341431266303500143760ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Giorgos Kostopoulos , 2019, 2020. # george k , 2020. # Michalis , 2021. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-02-08 17:50+0000\n" "Last-Translator: Michalis \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.5-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Πεζά Δεκαεξαδικά" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Κεφαλαία δεκαεξαδικά" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Αντιγραφή _Σύνοψης" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Προβολή _Εργαλειοθήκης" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Αρχείο" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "Άνοιγμα Αρχείου Σύνοψης…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Αποθήκευση Αρχείου Σύνοψης…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Επεξεργασία" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Εμφάνιση" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Κείμενο" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Αρχείων _Κατάλογος" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Βοήθεια" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Αρχείο:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Κείμενο:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Έλεγχος:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Επικόλληση από πρόχειρο" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Κλειδί HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Αρχείο" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Κα_τατεμαχισμός" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Προτιμήσεις GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Λειτουργίες Κατατεμαχισμού" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Λειτουργίες MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Σχήμα Σύνοψης:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Υπολογιστής αθροίσματος ελέγχου" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Υπολογίστε συνόψεις μηνυμάτων ή αθροίσματα ελέγχου" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Άνοιγμα Αρχείου Σύνοψης" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Άνοιγμα" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Άκυρο" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Αρχεία Συνόψεων/Αθροισμάτων (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Όλα τ' Αρχεία" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Αποθήκευση Αρχείου Σύνοψης" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Αποθήκευση" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Ένα εργαλείο για υπολογισμό συνόψεων μηνυμάτων ή αθροισμάτων ελέγχου" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Μεταφραστής - μνεία\n" "Γιώργος Κωστόπουλος giorgosk67@gmail.com" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Επιλογή Αρχείων" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "Προσθήκη checkbutton" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Αποτυχία ανάγνωσης αρχείου ελέγχου \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Μη κανονικό αρχείο" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Αποτυχία προσθήκης αρχείου \"%s\":%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "'Άγνωστο όνομα Λειτουργίας Ελέγχου \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Σύγκριση με συγκεκριμένη σύνοψη ή άθροισμα ελέγχου" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ΣΥΝΟΨΗ" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Έλεγχος συνόψεων ή αθροισμάτων ελέγχου απ' το συγκεκριμένο αρχείο" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "[ΑΡΧΕΙΟ|URI...]" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Ενεργοποίηση συγκεκριμένης Λειτουργίας Αθροίσματος (e.g. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "ΛΕΙΤΟΥΡΓΙΑ" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "'Ελεγχος του συγκεκριμένου κειμένου" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "ΚΕΙΜΕΝΟ" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Προβολή πληροφοριών έκδοσης" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ΑΡΧΕΙΟ|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "" "Αποτυχία ενεργοποίησης οποιασδήποτε υποστηριζόμενης λειτουργίας " "κατατεμαχισμού." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u 1 λεπτό έμεινε" msgstr[1] "%u 2 λεπτά έμειναν" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u 1 δευτερόλεπτο έμεινε" msgstr[1] "%u 2 δευτερόλεπτα έμειναν" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s 1 of %s 2 - %s 3 (%s 4/dδευτ.)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Αντιγραφή Σύνοψης" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Προβολή _Απενεργοποιημένων Λειτουργιών Κατατεμαχισμού" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Λειτουργία Κατατεμαχισμού" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Σύνοψη" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Σ_ύνοψη" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Αθροίσματα" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "Το GtkHash είναι μια εφαρμογή υπολογισμού αρχείων αθροισμάτων ή συνόψεων " "μηνυμάτων. Είναι σχεδιασμένο για ευκολία χρήσης, γραφική εναλλακτική λύση " "προγραμμάτων γραμμής εντολών, όπως το md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Υποστηρίζονται οι λειτουργίες κατατεμαχισμού, συμπεριλαμβανομένων των MD5, " "SHA1, SHA256, SHA512 και CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Πρόσθεση συνόψεων μηνυμάτων ή αθροισμάτων ελέγχου στις ιδιότητες αρχείου" #~ msgid "Digests" #~ msgstr "Συνόψεις" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Άνοιγμα Αρχείου Σύνοψης..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Αποθήκευση Αρχείου Σύνοψης..." #~ msgid "Check Digests" #~ msgstr "Αποθήκευση Συνόψεων" #~ msgid "Unknown error" #~ msgstr "Άγνωστο λάθος" gtkhash-1.5/po/en_GB.po000066400000000000000000000221511431266303500147440ustar00rootroot00000000000000# English (United Kingdom) translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # Tristan Heaven , 2018, 2019, 2020. # Oymate , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-02 20:41+0000\n" "Last-Translator: Tristan Heaven \n" "Language-Team: English (United Kingdom) \n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2012-12-11 04:50+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Lowercase Hexadecimal" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Uppercase Hexadecimal" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copy _Digest" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Show _Toolbar" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_File" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Open Digest File…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Save Digest File…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Edit" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_View" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "File _List" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Help" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "File:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Check:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Paste digest from clipboard" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC Key:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "File" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash Preferences" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash Functions" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC Functions" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Digest Format:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Checksum Calculator" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calculate message digests or checksums" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Open Digest File" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Open" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancel" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "All Files" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Save Digest File" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Save" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "A desktop utility for computing message digests or checksums" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Abhishek https://launchpad.net/~ar.abhishek\n" "Julian Beckmann https://launchpad.net/~julian-beckmann\n" "Stefan Pynappels https://launchpad.net/~stefan-pynappels\n" "Tristan Heaven" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Select Files" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Show HMAC Key" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Failed to read check file \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Not a regular file" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Failed to add file \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Unknown Hash Function name \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Check against the specified digest or checksum" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Check digests or checksums from the specified file" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Enable the specified Hash Function (e.g. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash the specified text" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Show version information" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Failed to enable any supported hash functions." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minute left" msgstr[1] "%u minutes left" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u second left" msgstr[1] "%u seconds left" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s of %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copy Digest" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Show _Disabled Hash Functions" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash Function" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Checksums" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Adds message digests or checksums to file properties" #~ msgid "Digests" #~ msgstr "Digests" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Open Digest File..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Save Digest File..." #~ msgid "Check Digests" #~ msgstr "Check Digests" #~ msgid "Unknown error" #~ msgstr "Unknown error" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s of %s - 1 minute left (%s/sec)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s of %s - 1 second left (%s/sec)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s of %s - %u seconds left (%s/sec)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Failed to add \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Failed to read \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Read program data from the specified directory" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "DIRECTORY" gtkhash-1.5/po/en_US.po000066400000000000000000000175001431266303500150050ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Tristan Heaven , 2020. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-02 20:41+0000\n" "Last-Translator: Tristan Heaven \n" "Language-Team: English (United States) \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Lowercase Hexadecimal" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Uppercase Hexadecimal" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copy _Digest" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Show _Toolbar" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_File" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Open Digest File…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Save Digest File…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Edit" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_View" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "File _List" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Help" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "File:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Check:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Paste digest from clipboard" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC Key:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "File" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash Preferences" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash Functions" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC Functions" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Digest Format:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Checksum Calculator" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calculate message digests or checksums" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Open Digest File" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Open" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancel" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "All Files" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Save Digest File" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Save" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "A desktop utility for computing message digests or checksums" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Tristan Heaven" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Select Files" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Show HMAC Key" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Failed to read check file \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Not a regular file" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Failed to add file \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Unknown Hash Function name \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Check against the specified digest or checksum" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Check digests or checksums from the specified file" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Enable the specified Hash Function (e.g. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash the specified text" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Show version information" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Failed to enable any supported hash functions." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minute left" msgstr[1] "%u minutes left" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u second left" msgstr[1] "%u seconds left" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s of %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copy Digest" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Show _Disabled Hash Functions" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash Function" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Checksums" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Adds message digests or checksums to file properties" #~ msgid "Digests" #~ msgstr "Digests" gtkhash-1.5/po/eo.po000066400000000000000000000203371431266303500144010ustar00rootroot00000000000000# Esperanto translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # phlostically , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-03-20 03:18+0000\n" "Last-Translator: phlostically \n" "Language-Team: Esperanto \n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.5.2-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Minuskla Heksesumaĵo" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Majuskla Deksesumaĵo" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopii _Haketaĵon" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Montri _Ilobreton" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Dosiero" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Malfermi Dosieron de Haketaĵo…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Konservi Dosieron de Haketaĵo…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Redakti" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vidi" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Teksto" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Listo de Dosieroj" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Helpo" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Dosiero:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Teksto:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kontrolo:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Alglui haketaĵon el tondujo" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAK-Ŝlosilo:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Dosiero" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_ketaĵo" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferoj pri GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Haketaj Funkcioj" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAK-Funkcioj" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formo de Haketaĵo:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kontrolsumo-Kalkulilo" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Kalkuli haketaĵojn aŭ kontrolsumojn" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Malfermi Dosieron de Haketaĵoj" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Malfermi" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Nuligi" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Dosieroj de Haketaĵoj/Kontrolsumoj (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Ĉiuj Dosieroj" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Konservi Dosieron de Haketaĵo" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Konservi" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Komputila utilaĵo por komputi haketaĵojn aŭ kontrolsumojn" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Kristjan SCHMIDT https://launchpad.net/~kristjan-eo\n" "Lucas Larson https://launchpad.net/~lucaslarson" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Elekti Dosierojn" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Montri HMAK-Ŝlosilon" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Malsukcesis legi kontrolsuman dosieron \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ne estas regula dosiero" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Malsukcesis aldoni dosieron \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nekonata haketa funkcio \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Kompari kun specifita haketaĵo aŭ kontrosumo" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "HAKETAĴO" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Kontroli haketaĵojn aŭ kontrolsumojn el specifita dosiero" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "DOSIERO|RETADRESO" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Ŝalti la specifitan haketan dosieron (ekz. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKCIO" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Haketi la specifitan tekston" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKSTO" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Montri versiajn informojn" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[DOSIERO|RETADRESO...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Malsukcesis ŝalti iujn ajn subtenatajn haketajn funkciojn." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuto restas" msgstr[1] "%u minutoj restas" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u sekundo restas" msgstr[1] "%u sekundoj restas" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s el %s - %s (%s/sekundo)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopii Haketaĵon" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Montri Malŝaltitajn Haketajn _Funkciojn" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Haketa Funkcio" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Haketaĵo" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Ha_ketaĵo" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kontrolsumoj" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash estas programo por komputi dosierajn kontrolsumojn aŭ haketaĵojn. Ĝi " "estas dezajnita kiel uzebla grafika alternativo de komandliniaj programoj " "kiel md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Jen kelkaj subtenataj haketaj funkcioj: MD5, SHA1, SHA256, SHA512, CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Aldonas haketaĵojn aŭ kontrolsumojn al dosieraj atributoj" gtkhash-1.5/po/es.po000066400000000000000000000230131431266303500143770ustar00rootroot00000000000000# Spanish translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # emma peel , 2018. # Toni Estévez , 2019, 2020. # Sebastian Duque , 2019. # El Pirujo , 2022. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2022-06-15 09:20+0000\n" "Last-Translator: El Pirujo \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.13-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimal en minúsculas" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimal en mayúsculas" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copiar el _resumen" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Mostrar la barra de _herramientas" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Archivo" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Abrir un archivo de resúmenes…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Guardar los resúmenes en un archivo…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Editar" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Ver" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Texto" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista de archivos" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Ay_uda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Archivo:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Texto:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Comprobar:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Pegar el resumen del portapapeles" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Clave HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Archivo" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "_Calcular" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferencias de GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funciones resumen" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funciones MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formato del resumen:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculadora de la suma de comprobación" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcular resúmenes de mensajes o sumas de comprobación" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Abrir un archivo de resúmenes" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Abrir" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancelar" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Archivos de resumen/comprobación (*.sha1, *.md5, *.sfv...)" #: src/callbacks.c:78 msgid "All Files" msgstr "Todos los archivos" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Guardar los resúmenes en un archivo" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Guardar" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Una herramienta de escritorio para calcular resúmenes de mensajes o sumas de " "comprobación" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Toni Estevez " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Seleccionar archivos" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Mostrar la clave HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Se ha producido un error al leer el archivo de comprobación «%s»: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "No es un archivo válido" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "No se ha podido añadir el archivo «%s»: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "El nombre de la función resumen «%s» es desconocido" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Comparar con el resumen o la suma de comprobación especificados" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "RESUMEN" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "" "Comprobar los resúmenes o las sumas de comprobación del archivo especificado" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ARCHIVO|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Activar la función resumen especificada (p. ej. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCIÓN" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Calcular el resumen del texto especificado" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXTO" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Mostrar información de la versión" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ARCHIVO|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Se ha producido un error al activar las funciones resumen compatibles." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "falta %u minuto" msgstr[1] "faltan %u minutos" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "falta %u segundo" msgstr[1] "faltan %u segundos" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s - %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copiar el resumen" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Mostrar las funciones resumen _desactivadas" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Función resumen" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Resumen" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_Calcular" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Sumas de verificación" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash es una aplicación para calcular sumas de comprobación de archivos o " "resúmenes de mensajes. Se ha diseñado para ser una alternativa gráfica fácil " "de usar para programas de línea de órdenes como md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Las funciones resumen compatibles incluyen MD5, SHA1, SHA256, SHA512 y CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Añade resúmenes de mensajes o sumas de comprobación a las propiedades de un " "archivo" #~ msgid "Digests" #~ msgstr "Resúmenes" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Abrir un archivo de resúmenes..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Guardar los resúmenes en un archivo..." #, fuzzy #~ msgid "Check Digests" #~ msgstr "Revisar resúmenes" #~ msgid "Unknown error" #~ msgstr "Se ha producido un error desconocido" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s de %s - queda 1 minuto (%s/seg)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s de %s - queda 1 segundo (%s/seg)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s de %s - quedan %u segundos (%s/seg)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Error al añadir \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Error en la lectura \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "DIRECTORIO" gtkhash-1.5/po/fa.po000066400000000000000000000157701431266303500143710ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR GtkHash authors # This file is distributed under the same license as the gtkhash package. # Ali , 2021. # Tristan Heaven , 2021. # Alireza Ivaz , 2022. msgid "" msgstr "" "Project-Id-Version: gtkhash 1.4\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2022-01-28 13:53+0000\n" "Last-Translator: Alireza Ivaz \n" "Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.11-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "هگزادسیمال کوچک" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "هگزادسیمال بزرگ" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "نمایش نوار ابزار" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "پرونده" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "ویرایش" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "دیدن" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "متن" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "لیست فایل" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "کمک" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "پرونده" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "متن" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "بررسی" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "پرونده" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "توابع درهم‌سازی" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "توابع کد اصالت سنجی پیام" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "محاسبه گر جمع کنترلی" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "بازکردن خلاصه پرونده" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "باز کردن" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "لغو کردن" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "" #: src/callbacks.c:78 msgid "All Files" msgstr "همه پوشه‌ها" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "ذخیره کردن" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" #: src/callbacks.c:279 msgid "translator-credits" msgstr "اعتبار مترجم" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "انتخاب پرونده‌ها" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "نمایش کد اصالت‌سنجی پیام برپایه درهم‌سازی" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "" #: src/gui.c:308 msgid "Not a regular file" msgstr "" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" gtkhash-1.5/po/fi.po000066400000000000000000000201271431266303500143710ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR GtkHash authors # This file is distributed under the same license as the gtkhash package. # Ricky Tigg , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash 1.4\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-09-11 12:36+0000\n" "Last-Translator: Ricky Tigg \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Heksadesimaali pieninä kirjaimina" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Heksadesimaali isoina kirjaimina" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopioi _hajautus" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Näytä _työkalupalkki" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Tiedosto" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Avaa hajautustiedosto…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Tallenna hajautustiedosto…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Muokkaa" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Näytä" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Teksti" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Tiedosto_luettelo" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Apu" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Tiedosto:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Teksti:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Tarkista:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Liitä hajautus leikepöydältä" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-avain:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Tiedosto" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_jautus" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHashin asetukset" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hajautusfunktiot" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC-funktiot" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Hajautuksen muoto:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Tarkistussummalaskin" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Laske viestien hajautukset tai tarkistussummat" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Avaa hajautustiedosto" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Avaa" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "__Peruuta" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Hajautus-/tarkistussummatiedostot ( *.sha1, *.md5, *.sfv,…)" #: src/callbacks.c:78 msgid "All Files" msgstr "Kaikki tiedostot" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Tallenna hajautustiedosto" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Tallenna" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Työpöytäapuohjelma viestien hajautusten tai tarkistussummien laskemiseen" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Vincent Toivanen" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Valitse tiedostot" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Näytä HMAC-avain" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Tarkistustiedoston \"%s\" lukeminen epäonnistui: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ei tavallinen tiedosto" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Tiedoston \"%s\" lisääminen epäonnistui: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Tuntematon hajautusfunktion nimi \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Tarkista määritettyä hajautusta tai tarkistussummaa vastaan" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "HAJAUTUS" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Tarkista hajautukset tai tarkistussummat määritetystä tiedostosta" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "TIEDOSTO|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Ota käyttöön määritetty hajautusfunktio (esim. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKTIO" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hajauta määritetty teksti" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKSTI" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Näytä versiotiedot" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[TIEDOSTO|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Tuettujen hajautusfunktioiden käyttöönotto epäonnistui." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuutti jäljellä" msgstr[1] "%u minuuttia jäljellä" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u sekunti jäljellä" msgstr[1] "%u sekuntia jäljellä" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s %s:sta - %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopioi hajautus" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Näytä käytöstä _poistetut hajautusfunktiot" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hajautusfunktio" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Hajautus" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Ha_jautus" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Tarkistussummat" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash on sovellus tiedostojen tarkistussummien tai viestien hajautusten " "laskemiseen. Se on suunniteltu helppokäyttöiseksi graafiseksi vaihtoehdoksi " "komentoriviohjelmille, kuten md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Tuetut hajautukset ovat CRC32, MD5, SHA1, SHA256 ja SHA512." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Lisää viestin hajautukset tai tarkistussummat tiedoston ominaisuuksiin" gtkhash-1.5/po/fr.po000066400000000000000000000234461431266303500144110ustar00rootroot00000000000000# French translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # xin , 2019. # Éfrit , 2019. # Éfrit , 2020. # aezjrareareare , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-12-02 01:50+0000\n" "Last-Translator: aezjrareareare \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.10-dev\n" "X-Launchpad-Export-Date: 2012-09-16 04:40+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadécimal en minuscule" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadécimal en majuscule" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copier le con_densat" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Afficher la barre d’ou_tils" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Fichier" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Ouvrir un fichier de condensat" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Enregistrer le condensat" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "Édition" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vue" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Texte" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Liste de fichiers" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Aide" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fichier :" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Texte :" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Vérifier :" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Coller le condensat depuis le presse-papier" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Clé HMAC :" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fichier" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Hacher" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Préférences GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Fonctions de hachage" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Fonctions de code d’authentification de message" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format du condensat :" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculateur de sommes de contrôle" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcule des condensats ou des sommes de contrôle" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Ouvrir un fichier de condensat" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Ouvrir" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "Annuler" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Fichiers de condensats ou de sommes de contrôle" #: src/callbacks.c:78 msgid "All Files" msgstr "Tous les fichiers" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Enregistrer le condensat" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "Enregi_strer" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Un utilitaire GTK+ pour calculer des condensats ou des sommes de contrôle" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "ERE https://launchpad.net/~karfter\n" "LEROY Jean-Christophe https://launchpad.net/~celtic2-deactivatedaccount\n" "Thibault Févry https://launchpad.net/~thibaultfevry\n" "jc1 https://launchpad.net/~jc1-quebecos" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Sélectionner les fichiers" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "Afficher la clé HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Échec de la lecture du fichier de vérification « %s » : %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ce n’est pas un fichier ordinaire" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Échec de l’ajout du fichier « %s » : %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Fonction de hachage « %s » inconnue" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Compare au condensat ou à la somme de contrôle spécifiée" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "CONDENSAT" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Compare aux condensats ou aux sommes de contrôle du fichier spécifié" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FICHIER|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Active la fonction de hachage spécifiée (p. ex. SHA-256)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FONCTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hache le texte spécifié" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXTE" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Affiche les informations de version" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FICHIER|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Échec de l’activation des fonctions de hachage prises en charge." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minute restante" msgstr[1] "%u minutes restantes" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u seconde restante" msgstr[1] "%u secondes restantes" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s – %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copier le condensat" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Afficher les fonctions de hachage _désactivées" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Fonction de hachage" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Condensat" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_achage" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Sommes de contrôle" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash est une application permettant de calculer les sommes de contrôle ou " "les condensats de fichier. Elle est conçue pour être une alternative " "graphique aux programmes en ligne de commande comme md5sum, et facile à " "utiliser." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Les fonctions de hachage prises en charge sont MD5, SHA-1, SHA-256, SHA-512 " "et le code cyclique CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Ajoute les condensats ou les sommes de contrôle aux propriétés du fichier" #~ msgid "Digests" #~ msgstr "Condensats" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Ouvrir un condensat" #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Enregi_strer le condensat" #~ msgid "Check Digests" #~ msgstr "Vérifier empreintes" #~ msgid "Unknown error" #~ msgstr "Erreur inconnue" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s de %s - 1 minute restant (%s/s)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s de %s - 1 seconde restant (%s/s)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s de %s - %u secondes restant (%s/s)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Impossible d'ajouter « %s »\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Échec de lecture « %s »" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Lire les données du programme à partir du répertoire spécifié" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "RÉPERTOIRE" gtkhash-1.5/po/gl.po000066400000000000000000000167471431266303500144120ustar00rootroot00000000000000# Galician translation for gtkhash # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2011-04-25 21:04+0000\n" "Last-Translator: Miguel Anxo Bouzada \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" "X-Generator: Launchpad (build 15520)\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Ficheiro" #: data/gtkhash-gtk3.ui:149 #, fuzzy msgctxt "menu" msgid "_Open Digest File…" msgstr "Gardar o valor hash" #: data/gtkhash-gtk3.ui:160 #, fuzzy msgctxt "menu" msgid "_Save Digest File…" msgstr "Gardar o valor hash" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Editar" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Ver" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Texto" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista de ficheiros" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Axuda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Ficheiro:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Texto:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Function" msgid "Hash Functions" msgstr "Función de hash" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Function" msgid "MAC Functions" msgstr "Función de hash" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "" #: src/callbacks.c:78 #, fuzzy msgid "All Files" msgstr "Seleccionar os ficheiros" #: src/callbacks.c:120 src/callbacks.c:124 #, fuzzy msgid "Save Digest File" msgstr "Gardar o valor hash" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" #: src/callbacks.c:279 #, fuzzy msgid "translator-credits" msgstr "" "Marcos Lans https://launchpad.net/~markooss\n" "Miguel Anxo Bouzada https://launchpad.net/~mbouzada\n" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Seleccionar os ficheiros" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "" #: src/gui.c:308 msgid "Not a regular file" msgstr "" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "" #: src/opts.c:104 #, fuzzy msgctxt " --help" msgid "FILE|URI" msgstr "[FICHEIRO|URI...]" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 #, fuzzy msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FICHEIRO|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Produciuse un fallo ao activar todas as funcións hash admitidas." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:58 #, fuzzy, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s - restan %u minutos (%s/seg)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copiar o valor hash" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Mostrar as funcións de hash _desactivadas" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Función de hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Valor hash" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy msgid "Checksums" msgstr "Gardar o valor hash" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" #~ msgid "Digests" #~ msgstr "Valores hash" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Gardar o valor hash" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s de %s - resta 1 minuto (%s/seg)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s de %s - resta 1 segundo (%s/seg)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s de %s - restan %u segundos (%s/seg)" gtkhash-1.5/po/gtkhash.pot000066400000000000000000000144571431266303500156210ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR GtkHash authors # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: gtkhash 1.4\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "" #: src/callbacks.c:78 msgid "All Files" msgstr "" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "" #: src/gui.c:308 msgid "Not a regular file" msgstr "" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" gtkhash-1.5/po/he.po000066400000000000000000000226171431266303500143750ustar00rootroot00000000000000# Hebrew translation for gtkhash # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2016. # Roi Klevansky , 2020. # Yaron Shahrabani , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-21 11:41+0000\n" "Last-Translator: Yaron Shahrabani \n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2016-01-29 05:16+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "הקסדצימלי באותיות קטנות" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "הקסדצימלי באותיות גדולות" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "העתקת קוד _גיבוב" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "הצגת _סרגל כלים" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_קובץ" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_פתיחת קובץ קוד גיבוב…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_שמירת קוד גיבוב לקובץ…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_עריכה" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_תצוגה" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_טקסט" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "רשימת_קבצים" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "ע_זרה" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "קובץ:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "טקסט:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "בדיקה מול:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "הדבקת קוד גיבוב מלוח ההעתקה" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "מפתח HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "קובץ" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "חי_שוב" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "העדפות GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "פונקציות גיבוב" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "פונקציות MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "תסדיר קוד גיבוב:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "מחשבון סיכום ביקורת" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "חישוב קוד גיבוב או סיכום ביקורת" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "פתיחת קובץ קוד גיבוב" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_פתיחה" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_ביטול" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "קובצי קוד גיבוב/סיכום ביקורת (‎*.sha1,‏ ‎*.md5,‏ ‎*.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "כל הקבצים" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "שמירת קוד גיבוב לקובץ" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_שמירה" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "כלי לשולחן עבודה לחישוב קוד גיבוב או סיכום ביקורת" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "ttv20 https://launchpad.net/~ttv200\n" "Roi Klevansky https://gitlab.com/RoiKlevansky\n" "Yaron Shahrabani https://github.com/yarons" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "בחירת קבצים" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "ה_צגת מפתח HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "קריאת קובץ הבדיקה „%s” נכשלה: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "לא קובץ רגיל" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "הוספת הקובץ „%s” נכשלה: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "לא נמצאה פונקציית גיבוב בשם „%s”" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "בדיקה מול קוד הגיבוב או סיכום הביקורת שצוין" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "קוד גיבוב" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "בדיקת קודי גיבוב או סיכומי ביקורת מהקובץ שצוין" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "הפעלת פונקציית הגיבוב שצוינה (לדוגמה: MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "חישוב הטקסט שצוין" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "הצגת מידע על הגרסה" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "הפעלת פונקציות הגיבוב הנתמכות נכשלה." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "נשארה דקה אחת" msgstr[1] "נשארו שתי דקות" msgstr[2] "נשארו %u דקות" msgstr[3] "נשארו %u דקות" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "נשארה שנייה אחת" msgstr[1] "נשארו שתי שניות" msgstr[2] "נשארו %u שניות" msgstr[3] "נשארו %u שניות" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s מתוך %s‏ - %s (%s לשנייה)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "ה_עתקת קוד גיבוב" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "הצגת פונקציות גיבוב מו_שבתות" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "פונקציית גיבוב" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "קוד גיבוב" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_חישוב" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "סיכומי ביקורות" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash הוא כלי לשולחן עבודה לחישוב קוד גיבוב או סיכום ביקורת. הכלי נועד " "לספק חלופה גרפית קלה לשימוש, לתכניות שורת פקודה כמו md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "פונקציות הגיבוב הנתמכות כוללות את MD5,‏ SHA1,‏ SHA256,‏ SHA512 ו־CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "הוספת הודעה עם קודי גבוב או סיכומי ביקורות למאפייני קובץ" #~ msgid "Digests" #~ msgstr "קודי גבוב" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_פתח קובץ קוד גיבוב..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_שמור לקובץ קוד גיבוב..." gtkhash-1.5/po/hr.po000066400000000000000000000226421431266303500144100ustar00rootroot00000000000000# Croatian translation for gtkhash # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2014. # Milo Ivir , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-04 11:41+0000\n" "Last-Translator: Milo Ivir \n" "Language-Team: Croatian \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2014-04-23 05:49+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Mala slova, heksadecimalno" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Velika slova, heksadecimalno" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopiraj _sažetak" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Prikaži _alatnu traku" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Datoteka" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Otvori datoteku sažetka …" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Spremi datoteku sažetka …" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Uredi" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Prikaz" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Tekst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Popis _datoteka" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Po_moć" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Datoteka:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Provjera:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Umetni sažetak iz međuspremnika" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC ključ:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Datoteka" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash osobitosti" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash funkcije" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC funkcije" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format sažetka:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kalkulator kontrolne sume" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Izračunaj sažetke poruka ili kontrolne sume" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Otvori datoteku sažetka" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Otvori" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "O_dustani" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Datoteke sažetka/kontrolnog zbroja (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Sve datoteke" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Spremi datoteku sažetka" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Spremi" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Uslužni program za izračunavanje sažetaka poruka ili kontrolnih zbrojeva" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "gogo https://launchpad.net/~trebelnik-stefina\n" "Milo Ivir , 2020." #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Odaberi datoteke" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Prikaži HMAC ključ" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Neuspjelo čitanje datoteke za provjeru „%s”: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Nije regularna datoteka" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Neuspjelo dodavanje datoteke „%s”: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nepoznato ime hash funkcije „%s”" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Provjeri određeni sažetak ili kontrolni zbroj" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "SAŽETAK" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Provjeri sažetke ili kontrolne zbrojeve navedene datoteke" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "DATOTEKA|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Aktiviraj određenu hash funkciju (npr. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKCIJA" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Izračunaj kontrolni zbroj određenog teksta" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Prikaži podatke verzije" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[DATOTEKA|URI …]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Neuspjelo aktiviranje bilo koje podržane hash funkcije." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "preostala %u minuta" msgstr[1] "preostale %u minute" msgstr[2] "preostalo %u minuta" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "preostala %u sekunda" msgstr[1] "preostale %u sekunde" msgstr[2] "preostalo %u sekundi" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s od %s – %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopiraj sažetak" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Prikaži _deaktivirane hash funkcije" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash funkcije" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Sažetak" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kontrolni zbrojevi" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash je program za računanje kontrolnih zbrojeva datoteka ili sažetaka " "poruka. Zamišljen je da bude jednostavan u upotrebi i kao grafička " "alternativa programima naredbenog retka poput md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Podržane hash funkcije uključuju MD5, SHA1, SHA256, SHA512 i CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Dodaje sažetke poruka ili kontrolne zbrojeve svojstvima datoteke" #~ msgid "Digests" #~ msgstr "Sažeci" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Otvori datoteku sažetka …" #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Spremi datoteku sažetka …" #, fuzzy #~ msgid "Check Digests" #~ msgstr "Spremi zbirove" #~ msgid "Unknown error" #~ msgstr "Nepoznata greška" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s od %s - 1 minuta preostala (%s/sec)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s od %s - 1 sekunda preostala (%s/sec)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s od %s - %u sekunda preostalo (%s/sec)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Neuspjelo dodavanje \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Neuspjelo čitanje \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Čitaj podatke programa iz određeneog direktorija" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "DIREKTORIJ" gtkhash-1.5/po/hu.po000066400000000000000000000165531431266303500144170ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # notramo , 2018. # notramo , 2019, 2020. # Noway Imtellingyouidiot , 2021. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-05-12 17:33+0000\n" "Last-Translator: Noway Imtellingyouidiot \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.7-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "kisbetűs hexadecimális" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "nagybetűs hexadecimális" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Ellenőrző összeg másolása" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "E_szköztár mutatása" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Fájl" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Kivonat fájl megnyitása…" #: data/gtkhash-gtk3.ui:160 #, fuzzy #| msgctxt "menu" #| msgid "_Save Digest File..." msgctxt "menu" msgid "_Save Digest File…" msgstr "Digest fájl _mentése..." #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Szerkesztés" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Nézet" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "Sz_öveg" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "F_ájl lista" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "S_úgó" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fájl:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Szöveg:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Ellenőrzés:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Hash beillesztése a vágólapról" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC kulcs:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fájl" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "H_ash" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash Beállítások" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "Hash funkciók:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "Hash funkciók:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Ellenőrző összeg formátuma:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Ellenőrzőösszeg számoló" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Kivonat fájl megnyitása" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Megnyitás" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "M_egszakítás" #: src/callbacks.c:73 #, fuzzy #| msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, ...)" msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Kivonat/Ellenőrzőösszeg fájlok (*.sha1, *.md5, *.sfv, ...)" #: src/callbacks.c:78 msgid "All Files" msgstr "" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "" #: src/gui.c:308 msgid "Not a regular file" msgstr "" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "Ellenőrzés:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Digest fájl megnyitása..." gtkhash-1.5/po/id.po000066400000000000000000000176011431266303500143720ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Ferdinand Tampubolon , 2021. # Neko Nekowazarashi , 2021. # I. Musthafa , 2021. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-11-09 16:49+0000\n" "Last-Translator: I. Musthafa \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.9-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Heksadesimal Huruf Kecil" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Heksadesimal Huruf Kapital" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Salin_Intisari" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Tampilkan_Bilah Alat" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Berkas" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Buka Berkas Inti…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Simpan Berkas Inti…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "__Ubah" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Lihat" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Teks" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Daftar_Berkas" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Bantuan" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Berkas:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Teks:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Cek:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Tempel inti dari papan klip" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Kunci HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Berkas" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Pengaturan GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Fungsi Hash" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Fungsi MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format Inti:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kalkulator Ceksum" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Menghitung pesan inti atau ceksum" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Buka Berkas Inti" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Buka" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Batal" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Berkas Inti/Ceksum (*.sha1, *.md5, *.sfv, ...)" #: src/callbacks.c:78 msgid "All Files" msgstr "Semua Berkas" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Simpan Berkas Inti" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Simpan" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Suatu aplikasi desktop untuk menghitung inti atau ceksum pesan" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Ferdinand Tampubolon \n" "I. Musthafa" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Pilih Berkas" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Lihat Kunci HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Gagal untuk membaca ceksum berkas \"%s\":%s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Bukan berkas biasa" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Gagal untuk menambahkan berkas \"%s\":%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nama Fungsi Hash tidak diketahui \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Cek terhadap inti atau ceksum yang diberikan" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "INTI" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Cek inti atau ceksum dari berkas yang dipilih" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "BERKAS|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Aktifkan Fungsi Hash yang diberikan (cth. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNGSI" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash teks yang diberikan" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKS" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Lihat info versi" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[BERKAS|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Gagal untuk mengaktifkan fungsi hash yang didukung mana pun." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u menit tersisa" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u detik tersisa" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s dari %s - %s (%s/dtk)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Salin Inti" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Lihat _Fungsi Hash Yang Dinonaktifkan" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Fungsi Hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Inti" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Ceksum" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash adalah sebuah aplikasi untuk mengecek ceksum berkas atau inti pesan. " "Di rancang untuk mudah digunakan dan alternatif grafik untuk program baris " "perintah seperti md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Fungsi Hash yang didukung: MD5,SHA1, SHA256, SHA512, dan CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Tambahkan inti pesan atau ceksum ke properti berkas" gtkhash-1.5/po/ie.po000066400000000000000000000206561431266303500143770ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # OIS , 2019. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2019-06-18 19:03+0000\n" "Last-Translator: OIS \n" "Language-Team: Occidental \n" "Language: ie\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimal minuscules" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimal majuscules" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copiar _digeste" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Monstrar _instrumentarium" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_File" #: data/gtkhash-gtk3.ui:149 #, fuzzy #| msgid "Open Digest File" msgctxt "menu" msgid "_Open Digest File…" msgstr "Aperter un file de digeste" #: data/gtkhash-gtk3.ui:160 #, fuzzy #| msgid "Save Digest File" msgctxt "menu" msgid "_Save Digest File…" msgstr "Gardar li digeste" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Redacter" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vise" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Textu" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Liste de files" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Au_xilie" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "File:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Textu:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Controlar:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Collar un digeste ex li Paperiere" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Clave HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "File" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferenties de GtkHash" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "Hash-fuctiones:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "Hash-fuctiones:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formate de digeste:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculator de summa de control" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcular digestes o summas de control de missages" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Aperter un file de digeste" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Aperter" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Anullar" #: src/callbacks.c:73 #, fuzzy #| msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, ...)" msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Files de digestes e summas (*.sha1, *.md5, *.sfv, ...)" #: src/callbacks.c:78 msgid "All Files" msgstr "Omni files" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Gardar li digeste" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Gardar" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Un utensile por calcular digestes o summas de control de missages" #: src/callbacks.c:279 msgid "translator-credits" msgstr "OIS , 2018" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Selecter files" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Monstrar clave HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Ne successat leer un file de control «%s»: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ne es un file regulari" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Ne successat adjunter un file «%s»: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Ínconosset nómine de function hash «%s»" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Controlar per un digeste o summa de control" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGESTE" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Controlar digestes o summas de control de un file" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Activar li providet function hash (p.ex. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hashar li providet textu" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXTU" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Monstrar li information pri li version" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Ne successat activar alquel supportat function hash." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minute resta" msgstr[1] "%u minutes resta" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u seconde resta" msgstr[1] "%u secondes resta" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s ex %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copiar li digeste" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Monstrar _deactivat functiones hash" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Function hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digeste" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ashar" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "Controlar:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash es un application por computar summas de control de files, o " "digestes de missages. It esset dessinat quam un facil grafic alternative por " "comandes de terminal tal quam md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Supportat hash-functiones include MD5, SHA1, SHA256, SHA512 e CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Adjunter digestes o summas de control al proprietás de un file" #~ msgid "Digests" #~ msgstr "Digestes" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Aperter un file de digeste..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Gardar li digeste..." gtkhash-1.5/po/it.po000066400000000000000000000217501431266303500144120ustar00rootroot00000000000000# Italian translation for gtkhash # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2010. # Matteo Fumagalli , 2018. # Fabio Fantoni , 2021. # BMN , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-04-30 09:32+0000\n" "Last-Translator: BMN \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.7-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Esadecimale minuscolo" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Esadecimale maiuscolo" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copia _Digest" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Mostra _Barra degli strumenti" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_File" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "Salva file impr_onta (Digest)…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Salva file impronta (Digest)…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Modifica" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vista" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Testo" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista file" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Aiuto (_H)" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "File:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Testo:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Verifica:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Incolla digest dagli appunti" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Chiave HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "File" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferenze GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funzioni Hash" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funzioni MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formato Digest:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calcolatore Checksum" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "" "Un'utility GTK+ per calcolare i digest (impronte) di messaggi o checksum" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Apri file Digest" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Apri" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Annulla" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "File Digest/Checksum (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Tutti i File" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Salva File Digest" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Salva" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Un'utility desktop per calcolare digest o checksum di file" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Crediti Traduzione" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Seleziona i file" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Mostra chiave HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Impossibile leggere il file di controllo \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Non è un file regolare" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Impossibile aggiungere il file \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nome della funzione di Hash \"%s\" sconosciuto" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Controlla con uno specifico file digest o checksum" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Verifica digest o checksum del file specificato" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Abilita la funzione di Hash specificata (es. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNZIONE" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Genera Hash del testo specificato" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TESTO" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Mostra informazioni sulla versione" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Errore nell'abilitare le funzioni di hash." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuto rimasto" msgstr[1] "%u minuti rimasti" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u secondo rimasto" msgstr[1] "%u secondi rimasti" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s di %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copia Digest" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Visualizza _Funzioni Hash Disabilitate" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Funzione di Hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Checksum" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash è una applicazione per calcolare checksum di file o digest. Creata " "per essere un'alternativa intuitiva ai programmi in riga di comando come " "md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Le funzioni hash supportate includono MD5, SHA1, SHA256, SHA512 e CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Aggiungi digest o checksum alle proprietà del file" #~ msgid "Digests" #~ msgstr "Impronte (Digest)" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Salva impronta (Digest)" #~ msgid "Check Digests" #~ msgstr "Salva impronta (Digest)" #~ msgid "Unknown error" #~ msgstr "Errore sconosciuto" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s di %s - minuto (%s/sec)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s di %s - secondo (%s/sec)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s di %s - %u secondi (%s/sec)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Errore aggiungendo \"%s\":\n" #~ "%s" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Leggi i dati del programma dalla dirctory specificata" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "DIRECTORY" gtkhash-1.5/po/ja.po000066400000000000000000000224441431266303500143710ustar00rootroot00000000000000# Japanese translation for gtkhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2011. # Kyotaro Iijima , 2018, 2019. # YAMADA Shinichirou , 2018, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-03 21:08+0000\n" "Last-Translator: YAMADA Shinichirou \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "16 進数小文字" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "16 進数大文字" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "ダイジェスト値のコピー(_D)" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "ツールバーの表示(_T)" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "ファイル(_F)" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "ダイジェストファイルを開く(_O)…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "ダイジェスト値の保存(_S)…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "編集(_E)" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "表示(_V)" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "テキスト(_T)" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "ファイルリスト(_L)" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "ヘルプ(_H)" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "ファイル:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "テキスト:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "チェック:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "クリップボードからダイジェスト値を貼り付け" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC キー:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "ファイル" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "ハッシュ(_S)" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash の設定" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "ハッシュ関数" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC 関数" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "ダイジェスト形式:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "チェックサム計算機" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "メッセージダイジェストやチェックサムの計算" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "ダイジェストファイルを開く" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "開く(_O)" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "キャンセル(_C)" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "ダイジェスト/チェックサムファイル (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "すべてのファイル" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "ダイジェスト値の保存" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "保存(_S)" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "メッセージダイジェストやチェックサムの計算を行うためのデスクトップユーティリ" "ティです" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "bigriver9 https://launchpad.net/~bigriver9615\n" "belphegor@belbel.or.jp\n" "Shinichirou Yamada" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "ファイルの選択" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "HMAC キーの表示(_S)" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "チェックファイル \"%s\" の読み込みに失敗しました: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "通常のファイルではありません" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "ファイル \"%s\" の追加に失敗しました: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "不明なハッシュ関数名 \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "指定したダイジェスト値やチェックサムを確認" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ダイジェスト" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "指定したファイルのダイジェスト値またはチェックサムの確認" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FILE|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "指定したハッシュ関数を有効にする (例: MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "関数" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "指定したテキストのハッシュ値を求める" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "テキスト" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "バージョン情報の表示" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FILE|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "全ての対応するハッシュ関数の有効化に失敗しました。" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "残り %u 分" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "残り %u 秒" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s / %s - %s (毎秒 %s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "ダイジェスト値のコピー(_C)" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "無効化されたハッシュ関数の表示(_D)" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "ハッシュ関数" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "ダイジェスト" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "ハッシュ(_A)" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "チェックサム" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash はファイルのチェックサムやメッセージのダイジェスト値を計算するための" "アプリケーションです。 md5sum のようなコマンドラインプログラムと比べて、使い" "やすくグラフィカルな表示を特長としています。" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "対応するハッシュ関数は、MD5、SHA1、SHA256、SHA512、CRC32。" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "ファイルのプロパティに対するメッセージダイジェストやチェックサムの追加" #~ msgid "Digests" #~ msgstr "ダイジェスト" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "ダイジェスト ファイルを開く(_O)..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "ダイジェスト値の保存(_S)..." #~ msgid "Check Digests" #~ msgstr "ダイジェスト値の確認" #~ msgid "Unknown error" #~ msgstr "不明なエラー" gtkhash-1.5/po/lt.po000066400000000000000000000214241431266303500144130ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Moo , 2018, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-03 16:41+0000\n" "Last-Translator: Moo \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" "%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Mažosios šešioliktainės" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Didžiosios šešioliktainės" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopijuoti _maišos reikšmę" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Rodyti į_rankių juostą" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Failas" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Atverti maišos reikšmių failą…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Į_rašyti maišos reikšmių failą…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Taisa" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "R_odinys" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Tekstas" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Failų _sąrašas" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Ž_inynas" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Failas:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekstas:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Patikrinti:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Įdėti maišos reikšmę iš iškarpinės" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC raktas:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Failas" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ma_iša" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash nuostatos" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Maišos funkcijos" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC funkcijos" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Maišos reikšmės formatas:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kontrolinės sumos skaičiuotuvas" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Apskaičiuoti žinučių maišos reikšmes ar kontrolines sumas" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Atverti maišos reikšmių failą" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "A_tverti" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Atsisakyti" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Maišos reikšmės/Kontrolinės sumos failai (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Visi failai" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Įrašyti maišos reikšmių failą" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "Į_rašyti" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Darbalaukio paslaugų programa, skirta maišos reikšmių ar kontrolinės sumos " "žinučių apskaičiavimui" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Išvertė: Moo" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Pasirinkite failus" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Rodyti HMAC raktą" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Nepavyko perskaityti tikrinimo failo \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Nėra normalus failas" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Nepavyko pridėti failo \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nežinomas maišos funkcijos pavadinimas \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Tikrinti su nurodyta maišos reikšme ar kontroline suma" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "MAIŠOS_REIKŠMĖ" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Tikrinti maišos reikšmes ar kontrolines sumas iš nurodyto failo" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FAILAS|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Įjungti nurodytą maišos funkciją (pvz., MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKCIJA" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Apskaičiuoti nurodyto teksto maišą" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKSTAS" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Rodyti versijos informaciją" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FAILAS|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Nepavyko įjungti jokių palaikomų maišos funkcijų." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "liko %u minutė" msgstr[1] "liko %u minutės" msgstr[2] "liko %u minučių" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "liko %u sekundė" msgstr[1] "liko %u sekundės" msgstr[2] "liko %u sekundžių" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s iš %s - %s (%s/sek.)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopijuoti maišos reikšmę" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Rodyti iš_jungtas maišos funkcijas" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Maišos funkcija" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Maišos reikšmė" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "M_aiša" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kontrolinės sumos" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash yra programa, skirta apskaičiuoti failų kontrolines sumas ar žinučių " "maišos reikšmes. Ji yra sukurta, kad būtų lengva naudoti ir kaip grafinė " "alternatyva tokioms komandų eilutės programoms kaip md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Palaikomos maišos funkcijos, įskaitant MD5, SHA1, SHA256, SHA512 ir CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Prideda žinutės maišos reikšmes ar kontrolines sumas į failo savybes" #~ msgid "Digests" #~ msgstr "Maišos reikšmės" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Atverti maišos reikšmių failą..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Į_rašyti maišos reikšmių failą..." #~ msgid "Check Digests" #~ msgstr "Tikrinti maišos reikšmes" #~ msgid "Unknown error" #~ msgstr "Nežinoma klaida" gtkhash-1.5/po/meson.build000066400000000000000000000001221431266303500155660ustar00rootroot00000000000000po_dir = meson.current_source_dir() i18n.gettext(gettext_package, preset: 'glib') gtkhash-1.5/po/nb_NO.po000066400000000000000000000213241431266303500147660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Allan Nordhøy , 2018, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-05-11 14:41+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.1-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Heksadesimal med små bokstaver" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Heksadesimal med store bokstaver" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopier _føljetong" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Vis _verktøyslinje" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Fil" #: data/gtkhash-gtk3.ui:149 #, fuzzy #| msgid "Open Digest File" msgctxt "menu" msgid "_Open Digest File…" msgstr "Åpne føljetongsfil" #: data/gtkhash-gtk3.ui:160 #, fuzzy #| msgid "Save Digest File" msgctxt "menu" msgid "_Save Digest File…" msgstr "Lagre føljetongsfil" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Rediger" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Vis" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Tekst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Fil_liste" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hjelp" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fil:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kontroll:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Lim inn føljetong fra utklippstavle" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-nøkkel:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fil" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "_Sjekksummer" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-innstillinger" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "Sjekksummeringsfunksjoner:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "Sjekksummeringsfunksjoner:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Føljetongsformat:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Sjekksum-kalkulator" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Kalkuler meldingsføljetonger eller sjekksummer" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Åpne føljetongsfil" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Åpne" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Avbryt" #: src/callbacks.c:73 #, fuzzy #| msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, ...)" msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Føljetong-/sjekksum-filer (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alle filer" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Lagre føljetongsfil" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Lagre" #: src/callbacks.c:274 #, fuzzy msgid "A desktop utility for computing message digests or checksums" msgstr "Et GTK+verktøy for utregning av meldingsføljetonger eller sjekksummer." #: src/callbacks.c:279 msgid "translator-credits" msgstr "Allan Nordhøy " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Velg filer" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Vis HMAC-nøkkel" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Klarte ikke å lese sjekkfil \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Ikke ei vanlig fil" #: src/gui.c:331 #, fuzzy, c-format msgid "Failed to add file \"%s\": %s" msgstr "" "Klarte ikke å legge til \"%s\":\n" "%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Ukjent sjekksummeringsfunksjonsnavn \"%s\"" #: src/opts.c:97 #, fuzzy msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Sjekk mot angitt føljetong eller sjekksum" #: src/opts.c:98 #, fuzzy msgctxt " --help" msgid "DIGEST" msgstr "FØLJETONG" #: src/opts.c:103 #, fuzzy msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Legger til føljetonger eller sjekksummer til filegenskaper" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FIL|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Skru på angitt sjekksummeringsfunksjon (f.eks. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKSJON" #: src/opts.c:114 #, fuzzy msgctxt " --help" msgid "Hash the specified text" msgstr "Sjekksummer valgt tekst" #: src/opts.c:115 #, fuzzy msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 #, fuzzy msgctxt " --help" msgid "Show version information" msgstr "Vis versjonsinformasjon" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 #, fuzzy msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FIL|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Klarte ikke å skru på noen støttede sjekksummeringsfunksjoner." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minutt igjen" msgstr[1] "%u minutter igjen" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u sekund igjen" msgstr[1] "%u sekunder igjen" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s av %s - %s (%s(sek)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopier føljetong" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Vis _avskrudde sjekksummeringsfunksjoner" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Sjekksummeringsfunksjon" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Føljetong" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_Sjekksummer" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "Kontroll:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash er et program for beregning av sjekksummer, eller " "meldingsføljetonger. Det er designet for å være et enkelt å bruke, grafisk " "alternativ til kommandolinjeprogrammer som md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Støttede sjekksummeringsfunksjoner innebefatter MD5, SHA1, SHA256, SHA512 og " "CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Legger til føljetonger eller sjekksummer til filegenskaper" #~ msgid "Digests" #~ msgstr "Føljetonger" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Åpne føljetongsfil…" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Lagre føljetonger" #, fuzzy #~ msgid "Check Digests" #~ msgstr "Lagre føljetonger" #~ msgid "Unknown error" #~ msgstr "Ukjent feil" gtkhash-1.5/po/nl.po000066400000000000000000000213201431266303500144000ustar00rootroot00000000000000# Dutch translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # Nathan Follens , 2018, 2019. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2019-06-18 19:03+0000\n" "Last-Translator: Nathan Follens \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimaal kleine letters" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimaal hoofdletters" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Digest kopiëren" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Werkbalk _tonen" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Bestand" #: data/gtkhash-gtk3.ui:149 #, fuzzy #| msgid "Open Digest File" msgctxt "menu" msgid "_Open Digest File…" msgstr "Digest-bestand openen" #: data/gtkhash-gtk3.ui:160 #, fuzzy #| msgid "Save Digest File" msgctxt "menu" msgid "_Save Digest File…" msgstr "Digest-bestand opslaan" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "B_ewerken" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Beeld" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "Te_kst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Bestands_lijst" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hulp" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Bestand:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Controle:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Digest kopiëren van klembord" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-sleutel:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Bestand" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-voorkeuren" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "Hashfuncties:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "Hashfuncties:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Digestformaat:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Controlesomberekening" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Berichtdigests of controlesommen berekenen" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Digest-bestand openen" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Openen" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Annuleren" #: src/callbacks.c:73 #, fuzzy #| msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, ...)" msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Digest-/controlesombestanden (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alle bestanden" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Digest-bestand opslaan" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "Op_slaan" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Een bureaubladhulpmiddel voor het berekenen van berichtdigests of " "controlesommen" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "cumulus007 https://launchpad.net/~cumulus-007\n" "Nathan Follens " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Bestanden selecteren" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "HMAC-_sleutel tonen" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Lezen van controlebestand ‘%s’ mislukt: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Geen gewoon bestand" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Toevoegen van bestand ‘%s’ mislukt: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Onbekende hashfunctienaam ‘%s’" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Controleer aan de hand van de opgegeven digest of controlesom" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Controleer digests of controlesommen van het opgegeven bestand" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "BESTAND|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Schakel de aangegeven hashfunctie in (bv. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTIE" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash de opgegeven tekst" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Versieinformatie tonen" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[BESTAND|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Inschakelen van ondersteunde hashfuncties mislukt." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuut resterend" msgstr[1] "%u minuten resterend" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u seconde resterend" msgstr[1] "%u seconden resterend" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s van %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "Digest _kopiëren" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Uitgeschakel_de hashfuncties tonen" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hashfunctie" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "Controle:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash is een toepassing voor het berekenen van bestandscontrolesommen en " "berichtdigests. Het is ontworpen als eenvoudig te gebruiken grafisch " "alternatief voor opdrachtregelprogramma’s als md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Ondersteunde hashfuncties zijn MD5, SHA1, SHA256, SHA512 en CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Voegt berichtdigests of controlesommen toe aan bestandseigenschappen" #~ msgid "Digests" #~ msgstr "Digests" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "Digest-bestand _openen…" #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Digest-bestand op_slaan…" #~ msgid "Check Digests" #~ msgstr "Digests controleren" #~ msgid "Unknown error" #~ msgstr "Onbekende fout" gtkhash-1.5/po/nl_BE.po000066400000000000000000000210771431266303500147570ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Nathan Follens , 2019. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2019-06-18 19:03+0000\n" "Last-Translator: Nathan Follens \n" "Language-Team: Flemish \n" "Language: nl_BE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.7\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimaal kleine letters" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimaal hoofdletters" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Digest kopiëren" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Werkbalk _tonen" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Bestand" #: data/gtkhash-gtk3.ui:149 #, fuzzy #| msgid "Open Digest File" msgctxt "menu" msgid "_Open Digest File…" msgstr "Digest-bestand openen" #: data/gtkhash-gtk3.ui:160 #, fuzzy #| msgid "Save Digest File" msgctxt "menu" msgid "_Save Digest File…" msgstr "Digest-bestand opslaan" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "B_ewerken" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Beeld" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "Te_kst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Bestands_lijst" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hulp" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Bestand:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Controle:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Digest kopiëren van klembord" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-sleutel:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Bestand" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-voorkeuren" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "Hashfuncties:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "Hashfuncties:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Digestformaat:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Controlesomberekening" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Berichtdigests of controlesommen berekenen" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Digest-bestand openen" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Openen" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Annuleren" #: src/callbacks.c:73 #, fuzzy #| msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, ...)" msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Digest-/controlesombestanden (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alle bestanden" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Digest-bestand opslaan" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "Op_slaan" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Een bureaubladhulpmiddel voor het berekenen van berichtdigests of " "controlesommen" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "cumulus007 https://launchpad.net/~cumulus-007\n" "Nathan Follens " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Bestanden selecteren" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "HMAC-_sleutel tonen" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Lezen van controlebestand ‘%s’ mislukt: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Geen gewoon bestand" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Toevoegen van bestand ‘%s’ mislukt: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Onbekenden hashfunctienaam ‘%s’" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Controleert aan de hand van den opgegeven digest of controlesom" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "DIGEST" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Controleert digests of controlesommen van het opgegeven bestand" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "BESTAND|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Schakelt de aangegeven hashfunctie in (bv. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNCTIE" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hasht den opgegeven tekst" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Versieinformatie tonen" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[BESTAND|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Inschakelen van ondersteunde hashfuncties mislukt." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuut resterend" msgstr[1] "%u minuten resterend" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u seconde resterend" msgstr[1] "%u seconden resterend" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s van %s - %s (%s/sec)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "Digest _kopiëren" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Uitgeschakel_de hashfuncties tonen" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hashfunctie" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Digest" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "Controle:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash is een toepassing voor het berekenen van bestandscontrolesommen en " "berichtdigests. Ze is ontworpen als eenvoudig te gebruiken grafisch " "alternatief voor opdrachtregelprogramma’s als md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Ondersteunde hashfuncties zijn MD5, SHA1, SHA256, SHA512 en CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Voegt berichtdigests of controlesommen toe aan bestandseigenschappen" #~ msgid "Digests" #~ msgstr "Digests" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "Digest-bestand _openen…" #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Digest-bestand op_slaan…" #~ msgid "Check Digests" #~ msgstr "Digests controleren" gtkhash-1.5/po/pl.po000066400000000000000000000212731431266303500144110ustar00rootroot00000000000000# Polish translation for gtkhash. # Copyright © 2011, 2017 the gtkhash authors. # This file is distributed under the same license as the gtkhash package. # Łukasz Szeremeta , 2011. # Piotr Drąg , 2017, 2018, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-02 18:57+0000\n" "Last-Translator: Piotr Drąg \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Szesnastkowy małymi znakami" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Szesnastkowy wielkimi znakami" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Skopiuj skrót" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Pasek _narzędziowy" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Plik" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Otwórz plik skrótu…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Zapi_sz plik skrótu…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Edycja" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Widok" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Tekst" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista plików" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Pomo_c" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Plik:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Tekst:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Sprawdzanie:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Wkleja skrót ze schowka" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Klucz HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Plik" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "_Oblicz" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferencje GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funkcje sum kontrolnych" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funkcje MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Format skrótu:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kalkulator sum kontrolnych" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Obliczanie skrótów wiadomości i sum kontrolnych" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Otwarcie pliku skrótu" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Otwórz" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Anuluj" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Pliki skrótów/sum kontrolnych (*.sha1, *.md5, *.sfv…)" #: src/callbacks.c:78 msgid "All Files" msgstr "Wszystkie pliki" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Zapis pliku skrótu" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Zapisz" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Narzędzie do obliczania skrótów wiadomości i sum kontrolnych" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Łukasz Szeremeta , 2011\n" "Piotr Drąg , 2017-2019" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Wybór plików" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Klucz HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Odczytanie pliku sprawdzenia „%s” się nie powiodło: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Nie jest zwykłym plikiem" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Dodanie pliku „%s” się nie powiodło: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nieznana nazwa funkcji sum kontrolnych „%s”" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Sprawdza z podanym skrótem lub sumą kontrolną" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "SKRÓT" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Sprawdza skróty lub sumy kontrolne z podanego pliku" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "PLIK|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Włącza podaną funkcję sum kontrolnych (np. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKCJA" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Oblicza sumę kontrolną podanego tekstu" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEKST" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Wyświetla informacje o wersji" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[PLIK|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Włączenie obsługiwanej funkcji sum kontrolnych się nie powiodło." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "Pozostała %u minuta" msgstr[1] "Pozostały %u minuty" msgstr[2] "Pozostało %u minut" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "Pozostała %u sekunda" msgstr[1] "Pozostały %u sekundy" msgstr[2] "Pozostało %u sekund" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s z %s — %s (%s/s)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "S_kopiuj skrót" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "_Wyłączone funkcje sum kontrolnych" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Funkcja sum kontrolnych" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Skrót" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "_Oblicz" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Sumy kontrolne" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash to program do obliczania sum kontrolnych plików i skrótów " "wiadomości. Jest zaprojektowany tak, aby był łatwą w użyciu, graficzną " "alternatywą dla programów wiersza poleceń, takich jak md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Obsługiwane funkcje sum kontrolnych: MD5, SHA1, SHA256, SHA512 i CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Dodaje skróty wiadomości i sumy kontrolne do właściwości plików" #~ msgid "Digests" #~ msgstr "Skróty" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Otwórz plik skrótu…" #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Zapisz plik skrótu…" #~ msgid "Check Digests" #~ msgstr "Sprawdzenie skrótów" #~ msgid "Unknown error" #~ msgstr "Nieznany błąd" gtkhash-1.5/po/pt.po000066400000000000000000000213261431266303500144200ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Rui Mendes , 2019. # ssantos , 2020. # Hugo Carvalho , 2021. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-03-17 13:18+0000\n" "Last-Translator: Hugo Carvalho \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.5.2-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimal em minúsculas" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimal em maiúsculas" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Copiar _resumo" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Mostrar barra de ferramen_tas" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Ficheiro" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "Abrir ficheir_o de resumo…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Gravar ficheiro de re_sumo…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Editar" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Visualização" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Texto" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista de ficheiros" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Ajuda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Ficheiro:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Texto:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Verificar:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Colar resumo da área de transferência" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Chave HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Ficheiro" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferências do GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funções de hash" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funções de MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formato do resumo:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculadora de soma de verificação" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcula resumos de mensagens e somas de verificação (checksums)" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Abrir ficheiro de resumo" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Abrir" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancelar" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Ficheiros de resumo / somas de verificação (*.sha1, *md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Todos os ficheiros" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Guardar ficheiro de resumo" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Guardar" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Um utilitário para calcular resumos de mensagens (message digest) e somas de " "verificação (checksums)" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "tonela https://hosted.weblate.org/user/tonela/\n" "Hugo Carvalho " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Selecionar ficheiros" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Mostrar chave HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Ocorreu uma falha ao ler o ficheiro de verificação \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Não é um ficheiro normal" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Ocorreu uma falha ao adicionar o ficheiro \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nome de função hash desconhecida \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" "Comparar com o resumo especificado ou com a soma de verificação (checksum)" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "RESUMO" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Verificar resumos ou somas de verificação do ficheiro especificado" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FICHEIRO|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Ativa a função hash especificada (por ex. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNÇÃO" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash do texto especificado" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXTO" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Mostrar informações da versão" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FICHEIRO|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Ocorreu uma falha ao ativar as funções de hash suportadas." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuto restante" msgstr[1] "%u minutos restantes" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u segundo restante" msgstr[1] "%u segundos restantes" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s - %s (%s/seg)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copiar resumo" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Mostrar funções hash _desativadas" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Função hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Resumo" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Somas de verificação" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash é uma aplicação para calcular somas de verificação (checksums) e " "resumos de mensagens (message digest) de ficheiros. Foi projetado para ser " "fácil de usar e para ser uma alternativa gráfica aos programas de linha de " "comandos como o md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "As funções de hash suportadas incluem MD5, SHA1, SHA256, SHA512 e CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Adicionar resumos de mensagens ou somas de verificação às propriedades do " "ficheiro" #~ msgid "Digests" #~ msgstr "Resumos" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Abrir ficheiro de resumo..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Guardar ficheiro de resumo..." gtkhash-1.5/po/pt_BR.po000066400000000000000000000235501431266303500150040ustar00rootroot00000000000000# Brazilian Portuguese translation for gtkhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2011. # Rui Mendes , 2019. # Samuel Carvalho de Araújo , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-07-13 15:41+0000\n" "Last-Translator: Samuel Carvalho de Araújo \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2012-08-14 04:46+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimal em minúscula" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimal em maiúscula" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Copiar resumo" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Mostrar barra de ferramen_tas" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Arquivo" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Abrir arquivo de resumo…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Salvar arquivo de resumo…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Editar" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Visualizar" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Texto" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Lista de arquivos" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "Aj_uda" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Arquivo:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Texto:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Verificar:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Colar resumo da área de transferência" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Chave HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Arquivo" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Preferências do GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Funções hash" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Funções MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Formato do resumo:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Calculadora Checksum" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Calcular resumos de mensagens ou somas de verificação (checksums)" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Abrir arquivo de resumo" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Abrir" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Cancelar" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Arquivos de resumo/somas de verificação (*.sha1, *md5, *.sfv…)" #: src/callbacks.c:78 msgid "All Files" msgstr "Todos os arquivos" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Salvar arquivo de resumo" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Salvar" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "" "Um utilitário para computar resumos de mensagens e somas de verificação " "(checksums)" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "André Gondim https://launchpad.net/~andregondim\n" "Cristiano Nunes https://launchpad.net/~cfgnunes\n" "João Marcus P. Gomes https://launchpad.net/~joaompg\n" "Lucas Silveira Melo https://launchpad.net/~lucas-silveiramelo\n" "Marco https://launchpad.net/~marcodefreitas\n" "Rafael Neri https://launchpad.net/~rafepel\n" "Rafael Capaci https://github.com/capaci\n" "Cezar Campos https://github.com/cizordj" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Selecionar arquivos" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Exibir chave HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Falha ao ler arquivo de verificação \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Não é um arquivo comum" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Falha ao adicionar o arquivo \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Nome de função hash desconhecida \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "" "Compare com o resumo especificado ou com a soma de verificação (checksum)" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "RESUMO" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Verificar resumos ou somas de verificação do arquivo especificado" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ARQUIVO|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Habilita a função hash especificada (por ex. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNÇÃO" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hash do texto especificado" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXTO" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Exibir informações da versão" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ARQUIVO|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Falha ao habilitar funções de hash suportadas." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minuto restante" msgstr[1] "%u minutos restantes" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u segundo restante" msgstr[1] "%u segundos restantes" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s de %s - %s minutos restantes (%s/seg)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Copiar resumo" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Mostrar funções hash _desabilitadas" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Função hash" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Resumo" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Verificar" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash é um aplicativo para computar somas de verificação (checksums) e " "resumos de mensagens (message digest) de arquivos. Foi projetado para ser " "fácil de usar e para ser uma alternativa gráfica aos programas de linha de " "comando como o md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "As funções de hash suportadas incluem MD5, SHA1, SHA256, SHA512 e CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Adicionar resumos de mensagens ou somas de verificação às propriedades do " "arquivo" #~ msgid "Digests" #~ msgstr "Resumos" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Abrir arquivo de resumo..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Salvar arquivo de resumo..." #, fuzzy #~ msgid "Check Digests" #~ msgstr "Salvar cômputos" #~ msgid "Unknown error" #~ msgstr "Erro desconhecido" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s de %s - 1 minuto restante (%s/s)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s de %s - 1 segundo restante (%s/s)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s de %s - %u segundos restantes (%s/s)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Falha ao adicionar \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Falha ao ler \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Ler dados do programa do diretório especificado" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "DIRETÓRIO" gtkhash-1.5/po/ru.po000066400000000000000000000257621431266303500144330ustar00rootroot00000000000000# Russian translation for gtkhash # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2010. # Igor , 2018, 2019. # Alexey Napalkov , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-08-10 10:32+0000\n" "Last-Translator: Alexey Napalkov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.2-dev\n" "X-Launchpad-Export-Date: 2016-03-16 05:31+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Шестнадцатеричный (нижний регистр)" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Шестнадцатеричный (верхний регистр)" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Копировать _дайджест" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "П_оказать панель инструментов" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Файл" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "Открыть файл дайджеста…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Сохранить файл дайджеста…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Правка" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Вид" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Текст" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Список ф_айлов" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Справка" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Файл:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Текст:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Сравнить:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Вставить дайджест из буфера обмена" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Ключ HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Файл" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "_Хэш" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Настройки GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Хеш-функции" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC-функции" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Формат дайджеста:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Калькулятор контрольных сумм" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Вычисление дайджестов или контрольных сумм" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Открыть файл дайджеста" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Открыть" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Отмена" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Файлы дайджестов/контрольных сумм (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Все файлы" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Сохранить файл дайджеста" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Сохранить" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Десктопное приложение для вычисления дайджестов или контрольных сумм" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Alexey Shentyakov https://launchpad.net/~alexey-shentyakov\n" "Grigorii Chirkov https://launchpad.net/~ridgentsailor\n" "WhiteRabbit https://launchpad.net/~whiterabbit" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Выбрать файлы" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Показать ключ HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Не удалось прочитать проверочный файл \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Не является обычным файлом" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Не удалось добавить файл \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Неизвестное имя хеш функции \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Сравнить с заданным дайджестом или контрольной суммой" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ДАЙДЖЕСТ" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Проверить дайджесты или контрольные суммы из указанного файла" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ФАЙЛ|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Включить указанную хеш функцию (например, MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "ФУНКЦИЯ" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Подсчитать контрольную сумму указанного текста" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "ТЕКСТ" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Показать информацию о версии" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ФАЙЛ|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Не удалось активировать поддерживаемые хеш-функции." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u минута осталась" msgstr[1] "%u минуты осталось" msgstr[2] "%u минут осталось" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u секунда осталась" msgstr[1] "%u секунды осталось" msgstr[2] "%u секунд осталось" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s из %s - %s (%s/с)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Копировать дайджест" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "П_оказать отключённые хеш-функции" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Хеш-функция" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Дайджест" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Х_еш" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Контрольные суммы" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash — это программа для вычисления контрольной суммы файлов или " "дайджестов. Программа проста в использовании и является более удобной " "альтернативой утилитам командной строки, таким как md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Поддерживаются хеш-функции MD5, SHA1, SHA256, SHA512 и CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Добавляет дайджесты или контрольные суммы в свойства файлов" #~ msgid "Digests" #~ msgstr "Дайджесты" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "_Открыть файл дайджеста..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "_Сохранить файл дайджеста..." #~ msgid "Check Digests" #~ msgstr "Проверить дайджесты" #~ msgid "Unknown error" #~ msgstr "Неизвестная ошибка" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s из %s - осталась 1 минута (%s/сек)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s из %s - осталась 1 секунда (%s/сек)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s из %s - осталось %u секунд (%s/сек)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Не удалось добавить \"%s\":\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Не удалось прочитать \"%s\"" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Прочитать данные программы из определенного каталога" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "КАТАЛОГ" gtkhash-1.5/po/sr.po000066400000000000000000000253401431266303500144210ustar00rootroot00000000000000# Serbian translation for gtkhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the gtkhash package. # # Мирослав Николић , 2016, 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-01-08 22:32+0000\n" "Last-Translator: Мирослав Николић \n" "Language-Team: Serbian \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.4.1-dev\n" "X-Launchpad-Export-Date: 2016-01-24 05:11+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Хексадецимална мала слова" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Хексадецимална велика слова" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Умножи _сажетак" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Прикажи траку _алата" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Датотека" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Отвори датотеку сажетка…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Сачувај датотеку сажетка…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Уређивање" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Преглед" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Текст" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Списак _датотека" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "По_моћ" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Датотека:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Текст:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Провери:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Убаците сажетак из оставе" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC кључ:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Датотека" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Х_еш" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Поставке Гтк Хеша" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Функције хеша" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC функције" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Формат сажетка:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Израчунавач суме провере" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Израчунајте сажетке порука или суме провере" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Отворите датотеку сажетка" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "От_вори" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "От_кажи" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Датотеке сажетка/суме провере (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Све датотеке" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Сачувајте датотеку сажетка" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Сачувај" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Помагало радне површи за израчунавање сажетака порука или сума провере" #: src/callbacks.c:279 msgid "translator-credits" msgstr "Мирослав Николић " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Изаберите датотеке" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Прикажи „HMAC“ кључ" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Нисам успео да прочитам датотеку провере „%s“: %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Није обична датотека" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Нисам успео да додам датотеку „%s“: %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Непознат назив хеш функције „%s“" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Проверава наведени сажетак или суму провере" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "САЖЕТАК" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Проверава сажетке или суме провера из наведене датотеке" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "ДАТОТЕКА|ПУТАЊА" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Укључује наведену хеш функцију (нпр. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "ФУНКЦИЈА" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Хешира наведени текст" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "ТЕКСТ" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Приказује податке о издању" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[ДАТОТЕКА|ПУТАЊА...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Нисам успео да укључим ниједну од подржаних хеш функција." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u минут је преостао" msgstr[1] "%u минута су преостала" msgstr[2] "%u минута је преостало" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u секунда је преостала" msgstr[1] "%u секунде су преостале" msgstr[2] "%u секунди је преостало" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s од %s – %s (%s/сек)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Умножи сажетак" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Прикажи _искључене функције хеша" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Функција хеша" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Сажетак" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "Х_еш" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Суме провере" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "Гтк Хеш је програм за израчунавање суме провере датотеке или сажетке поруке. " "Осмишљен је да буде лак за коришћење, графичка замена за програме линије " "наредби као што је „md5sum“." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "У подржане хеш функције спадају MD5, SHA1, SHA256, SHA512 и CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Додаје сажетке порука или суме провера у својства датотеке" #~ msgid "Digests" #~ msgstr "Сажетак" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Сачувај сажетке" #, fuzzy #~ msgid "Check Digests" #~ msgstr "Сачувај сажетке" #~ msgid "Unknown error" #~ msgstr "Непозната грешка" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "%s од %s — 1 минут преостаје (%s/сек)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "%s од %s — 1 секунда преостаје (%s/сек)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "%s од %s — %u секунде преостају (%s/сек)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "Нисам успео да додам „%s“:\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "Нисам успео да прочитам „%s“" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "Чита податке програма из наведеног директоријума" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "ДИРЕКТОРИЈУМ" gtkhash-1.5/po/sv.po000066400000000000000000000206141431266303500144240ustar00rootroot00000000000000# Swedish translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # Mattias Münster , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-09-27 08:40+0000\n" "Last-Translator: Mattias Münster \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Hexadecimala gemener" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Hexadecimala versaler" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Kopiera _sammandrag" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Visa _verktygsfält" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Arkiv" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Öppna sammandrag…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Spara sammandrag…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Redigera" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Visa" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Text" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Fil_lista" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hjälp" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Fil:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Text:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kontroll:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Klistra in sammandrag från urklipp" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC-nyckel:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Fil" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash-inställningar" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hashfunktioner" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC-funktioner" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Sammandragsformat:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Kontrollsummeberäknare" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Beräkna meddelandesammandrag eller kontrollsummor" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Öppna sammandrag" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "Ö_ppna" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "A_vbryt" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Sammandrag/Checksum filer (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Alla filer" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Spara sammandrag" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Spara" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Ett GTK+-verktyg för att beräkna sammandrag eller kontrollsummor" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Mattias Ohlsson https://launchpad.net/~mattias-oh\n" "Anders Jonsson " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Välj filer" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Visa HMAC-nyckel" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Det gick inte att läsa kontrollfilen \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Inte en vanlig fil" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Det gick inte att lägga till filen \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Okänt Hash-funktionsnamn \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Kontrollera mot angivet sammandrag eller kontrollsumma" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "SAMMANDRAG" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Kontrollera sammandrag eller kontrollsummor från den angivna filen" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "FIL|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Aktivera den angivna Hash-funktionen (t.ex. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "FUNKTION" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Hasha den angivna texten" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "TEXT" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Visa versionsinformation" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[FIL|URI…]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Lyckades inte aktivera någon hashfunktion som stöds." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u minut kvar" msgstr[1] "%u minuter kvar" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u sekund kvar" msgstr[1] "%u sekunder kvar" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s av %s - %s (%s/sek)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Kopiera sammandrag" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Visa _inaktiverade hashfunktioner" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hashfunktion" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Sammandrag" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kontrollsummor" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash är ett program för att beräkna kontrollsummor för filer eller " "meddelandesammandrag. Det är designat för att vara ett lättanvänt grafiskt " "alternativ till kommandoradsprogram så som md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" "Hashfunktioner som stöds inkluderar MD5, SHA1, SHA256, SHA512 och CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "" "Lägger till meddelandesammandrag eller kontrollsummor till filegenskaper" #~ msgid "Digests" #~ msgstr "Sammandrag" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Spara sammandrag" #, fuzzy #~ msgid "Check Digests" #~ msgstr "Spara sammandrag" #~ msgid "Unknown error" #~ msgstr "Okänt fel" gtkhash-1.5/po/tr.po000066400000000000000000000213051431266303500144170ustar00rootroot00000000000000# Turkish translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # Muha Aliss , 2019. # Kemal Oktay Aktoğan , 2019. # Serdar Sağlam , 2019. # Oğuz Ersen , 2020. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2020-09-19 00:36+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.3-dev\n" "X-Launchpad-Export-Date: 2012-06-30 05:10+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Küçük Harf Onaltılık" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Büyük Harf Onaltılık" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "_Özeti Kopyala" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "_Araç Çubuğunu Göster" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Dosya" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "Özet Dosyasını _Aç…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "Özet Dosyasını _Kaydet…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Düzenle" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Görünüm" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Metin" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "Dosya _Listesi" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Yardım" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Dosya:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Metin:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kontrol:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Panodaki özeti yapıştır" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC Anahtarı:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Dosya" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash Tercihleri" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Hash İşlevleri" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "MAC İşlevleri" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Özet Biçimi:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Sağlama Hesaplayıcı" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Mesaj özetlerini veya sağlama toplamlarını hesapla" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Özet Dosyasını Aç" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Aç" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_İptal" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Özet/Sağlama Dosyaları (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Tüm Dosyalar" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Özet Dosyasını Kaydet" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Kaydet" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "İleti özeti ya da sağlama hesaplamak için yardımcı araç" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Muha Aliss \n" "Kemal Oktay Aktoğan \n" "Serdar Sağlam \n" "Oğuz Ersen " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Dosyaları Seç" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "HMAC Anahtarını _Göster" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Kontrol dosyasını okumadı \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Normal bir dosya değil" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Dosya eklenemedi \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Bilinmeyen Hash İşlevi adı \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Belirtilen özete veya sağlama toplamına karşı kontrol edin" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "ÖZET" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Belirtilen dosyadan özetleri veya sağlama toplamlarını kontrol et" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "DOSYA|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Belirtilen Hash İşlevini etkinleştirin (örneğin, MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "İŞLEV" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Belirtilen metni hash'la" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "METİN" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Sürüm bilgisini göster" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[DOSYA|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Desteklenen hiçbir bir hash işlevi etkinleştirilemedi." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "%u dakika kaldı" msgstr[1] "%u dakika daha kaldı" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "%u saniye kaldı" msgstr[1] "%u saniye daha kaldı" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s için %s - %s (%s/san)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "Özeti _Kopyala" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "_Devre Dışı Bırakılmış Hash İşlevini Göster" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hash İşlevi" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Özet" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "H_ash" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Sağlamalar" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash dosya sağlama toplamı veya ileti özetlerini hesaplamak için " "kullanılan bir uygulamadır. md5sum gibi komut satırı programlarına kullanımı " "kolay, grafiksel bir alternatif olacak şekilde tasarlanmıştır." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Desteklenen hash işlevleri MD5, SHA1, SHA256, SHA512 ve CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Dosya özelliklerine ileti özetleri veya sağlama toplamları ekler" #~ msgid "Digests" #~ msgstr "Özet" #~ msgctxt "menu" #~ msgid "_Open Digest File..." #~ msgstr "Özet Dosyasını _Aç..." #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "Özet Dosyasını _Kaydet..." #~ msgid "Check Digests" #~ msgstr "Özetleri Kontrol Et" gtkhash-1.5/po/vi.po000066400000000000000000000204741431266303500144160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR GtkHash authors # This file is distributed under the same license as the gtkhash package. # Cao Nguyen , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash 1.4\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-01-22 00:39+0000\n" "Last-Translator: Cao Nguyen \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.5-dev\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "Chữ số hệ 16 in thường" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "Chữ số hệ 16 in hoa" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "Sao chép _Chữ số" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "Hiện _Thanh công cụ" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "_Tập tin" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "_Open Tập tin …" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "_Lưu ra tập tin …" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "_Biên tập" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "_Hiển thị" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "_Văn bản" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "_Danh sách Tập tin" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "_Hỗ trợ" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "Tập tin:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "Văn bản:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "Kiểm tra:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "Dán các chữ số từ vùng nhớ đệm" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "Khóa HMAC:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "Tập tin" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "Ha_sh" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "Tùy chỉnh GtkHash" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "Các hàm băm" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "Các hàm MAC" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "Định dạng các chữ số:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "Công cụ Kiểm tra tổng" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "Tính toán thông báo các chữ số hoặc kiểm tra tổng" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "Mở tập tin chứa các chữ số" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "_Mở" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "_Hủy" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "Các tập tin chứa các Chữ số/Kiểm tra tổng (*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "Tất cả các tập tin" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "Lưu các Chữ số ra tập tin" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "_Lưu" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "Một phần mềm tính toán thông báo các chữ số hoặc kiểm tra tổng" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Nguyen Cao \n" "Nguyen Cao " #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "Chọn tập tin" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "_Hiện Khóa HMAC" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "Không thể đọc tập tin kiểm tra \"%s\": %s" #: src/gui.c:308 msgid "Not a regular file" msgstr "Không phải một tập tin thông thường" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "Không thể thêm tập tin \"%s\": %s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "Tên hàm Băm không xác định \"%s\"" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "Kiểm tra với các kí tự và chữ số đặc biệt" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "CHỮ SỐ" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "Kiểm tra các chữ số hoặc kiểm tra tổng từ một tập tin nào đó" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "TẬP TIN|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "Sử dụng một hàm băm đặc biệt (ví dụ như MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "HÀM BĂM" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "Băm một đoạn văn bản nào đó" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "VĂN BẢN" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "Hiện thông tin phiên bản" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[TẬP TIN|URI ...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "Không thể kích hoạt bất kì hàm băm nào." #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "còn %u phút nữa" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "còn %u giây nữa" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s của %s - %s (%s/giây)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "_Sao chép Chữ số" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "Hiện các hàm băm bị _Ẩn" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "Hàm băm" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "Chữ số" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "B_ăm" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "Kiểm tra tổng" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash là một ứng dụng dùng để tính toán kiểm tra tổng của tập tin hoặc của " "các kí tự trong văn bản. Nó được thiết kế để dễ sử dụng, giúp dử dụng giao " "diện đồ họa cho các chương trình dòng lệnh như md5sum." #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "Hỗ trợ các hàm băm như MD5, SHA1, SHA256, SHA512 và CRC32." #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "Thêm các kết quả băm và kiểm tra tổng vào thuộc tính của tập tin" gtkhash-1.5/po/zh_CN.po000066400000000000000000000215651431266303500150030ustar00rootroot00000000000000# Chinese (Simplified) translation for gtkhash # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2009. # pessoa , 2020. # Liu Tao , 2021. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2021-09-24 10:38+0000\n" "Last-Translator: Liu Tao \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.9-dev\n" "X-Launchpad-Export-Date: 2012-07-10 05:35+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "小写十六进制" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "大写十六进制" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "复制摘要(_D)" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "显示工具栏(_T)" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "文件(_F)" #: data/gtkhash-gtk3.ui:149 msgctxt "menu" msgid "_Open Digest File…" msgstr "打开摘要文件(_O)…" #: data/gtkhash-gtk3.ui:160 msgctxt "menu" msgid "_Save Digest File…" msgstr "保存摘要文件(_S)…" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "编辑(_E)" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "视图(_V)" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "文本(_T)" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "文件列表(_L)" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "帮助(_H)" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "文件:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "文本:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "检测:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "从剪贴板粘贴摘要" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 msgid "HMAC Key:" msgstr "HMAC 键:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "文件" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "哈希(_S)" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash 首选项" #: data/gtkhash-gtk3.ui:1039 msgid "Hash Functions" msgstr "哈希函数" #: data/gtkhash-gtk3.ui:1070 msgid "MAC Functions" msgstr "消息认证码函数" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "摘要格式:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "校验和计算器" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "计算信息摘要或校验和" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "打开摘要文件" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "打开(_O)" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "取消(_C)" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "摘要/校验文件(*.sha1, *.md5, *.sfv, …)" #: src/callbacks.c:78 msgid "All Files" msgstr "所有文件" #: src/callbacks.c:120 src/callbacks.c:124 msgid "Save Digest File" msgstr "保存摘要文件" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "保存(_S)" #: src/callbacks.c:274 msgid "A desktop utility for computing message digests or checksums" msgstr "用来计算信息摘要或校验的桌面工具" #: src/callbacks.c:279 msgid "translator-credits" msgstr "" "Careone https://launchpad.net/~zzbusagain\n" "Wang Dianjin https://launchpad.net/~tuhaihe\n" "giwhub https://github.com/giwhub" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "选择文件" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "显示 HMAC 键(_S)" #: src/check.c:202 #, c-format msgid "Failed to read check file \"%s\": %s" msgstr "无法读取 “%s”:%s" #: src/gui.c:308 msgid "Not a regular file" msgstr "非常规文件" #: src/gui.c:331 #, c-format msgid "Failed to add file \"%s\": %s" msgstr "无法添加 “%s”:%s" #: src/hash.c:188 src/prefs.c:113 #, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "未知哈希函数 “%s”" #: src/opts.c:97 msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "根据指定的摘要或校验和进行检查" #: src/opts.c:98 msgctxt " --help" msgid "DIGEST" msgstr "摘要" #: src/opts.c:103 msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "检查指定文件的摘要或校验和" #: src/opts.c:104 msgctxt " --help" msgid "FILE|URI" msgstr "文件|URI" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "启用指定的哈希函数 (e.g. MD5)" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "函数" #: src/opts.c:114 msgctxt " --help" msgid "Hash the specified text" msgstr "散列计算指定的文本" #: src/opts.c:115 msgctxt " --help" msgid "TEXT" msgstr "文本" #: src/opts.c:119 msgctxt " --help" msgid "Show version information" msgstr "显示版本信息" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 msgctxt " --help" msgid "[FILE|URI...]" msgstr "[文件|URI...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "无法启用任何支持的哈希函数。" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "剩余%u分钟" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "剩余%u秒" #: src/util/util.c:58 #, c-format msgid "%s of %s - %s (%s/sec)" msgstr "%s / %s - %s (%s/秒)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "复制摘要(_C)" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "显示已禁用的哈希函数(_D)" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "哈希函数" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "摘要" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "哈希(_A)" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 msgid "Checksums" msgstr "校验" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" "GtkHash是一个用于计算文件校验和或消息摘要的应用程序。 它旨在成为一个易于使用" "的图形替代命令行程序,如md5sum。" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "支持的哈希函数包含MD5、SHA1、SHA256、SHA512和CRC32。" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 msgid "Adds message digests or checksums to file properties" msgstr "将消息摘要或校验和添加到文件属性" #~ msgid "Digests" #~ msgstr "摘要" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "保存摘要" #, fuzzy #~ msgid "Check Digests" #~ msgstr "保存摘要" #~ msgid "Unknown error" #~ msgstr "未知错误" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "进度 %s/ %s - 还剩 1 分钟(%s/秒)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "进度 %s/%s - 还剩 1 秒钟(%s/秒)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "进度 %s/%s - 还剩 %u 秒(%s/秒)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "无法添加 “%s”:\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "无法读取 “%s”" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "从指定目录读取程序数据" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "目录" gtkhash-1.5/po/zh_TW.po000066400000000000000000000217671431266303500150410ustar00rootroot00000000000000# Chinese (Traditional) translation for gtkhash # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the gtkhash package. # FIRST AUTHOR , 2013. # 王家泽 , 2022. msgid "" msgstr "" "Project-Id-Version: gtkhash\n" "Report-Msgid-Bugs-To: https://github.com/tristanheaven/gtkhash/issues\n" "POT-Creation-Date: 2021-06-26 20:39+0100\n" "PO-Revision-Date: 2022-01-20 14:52+0000\n" "Last-Translator: 王家泽 \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.11-dev\n" "X-Launchpad-Export-Date: 2013-04-26 05:41+0000\n" #: data/gtkhash-gtk3.ui:12 msgid "Lowercase Hexadecimal" msgstr "十六進位小寫" #: data/gtkhash-gtk3.ui:15 msgid "Uppercase Hexadecimal" msgstr "十六進位大寫" #: data/gtkhash-gtk3.ui:71 msgid "Copy _Digest" msgstr "複製訊息摘要(_D)" #: data/gtkhash-gtk3.ui:97 msgid "Show _Toolbar" msgstr "顯示工具列(_T)" #: data/gtkhash-gtk3.ui:141 data/gtkhash-gtk3.ui:290 msgid "_File" msgstr "檔案(_F)" #: data/gtkhash-gtk3.ui:149 #, fuzzy msgctxt "menu" msgid "_Open Digest File…" msgstr "保存訊息摘要" #: data/gtkhash-gtk3.ui:160 #, fuzzy msgctxt "menu" msgid "_Save Digest File…" msgstr "保存訊息摘要" #: data/gtkhash-gtk3.ui:194 msgid "_Edit" msgstr "編輯(_E)" #: data/gtkhash-gtk3.ui:280 msgid "_View" msgstr "檢視(_V)" #: data/gtkhash-gtk3.ui:300 msgid "_Text" msgstr "純文字(_T)" #: data/gtkhash-gtk3.ui:310 msgid "File _List" msgstr "檔案清單" #: data/gtkhash-gtk3.ui:324 msgid "_Help" msgstr "尋求幫助(_H)" #: data/gtkhash-gtk3.ui:429 msgid "File:" msgstr "檔案:" #: data/gtkhash-gtk3.ui:442 msgid "Text:" msgstr "純文字:" #: data/gtkhash-gtk3.ui:455 data/nautilus/gtkhash-properties.ui:144 msgid "Check:" msgstr "比對:" #: data/gtkhash-gtk3.ui:513 data/gtkhash-gtk3.ui:531 #: data/nautilus/gtkhash-properties.ui:159 msgid "Paste digest from clipboard" msgstr "從剪貼板粘貼摘要" #: data/gtkhash-gtk3.ui:544 data/gtkhash-gtk3.ui:571 #: data/nautilus/gtkhash-properties.ui:180 #, fuzzy msgid "HMAC Key:" msgstr "HMAC 鍵:" #: data/gtkhash-gtk3.ui:783 msgid "File" msgstr "檔案" #: data/gtkhash-gtk3.ui:887 msgid "Ha_sh" msgstr "開始計算(_S)" #: data/gtkhash-gtk3.ui:953 msgid "GtkHash Preferences" msgstr "GtkHash 偏好設定" #: data/gtkhash-gtk3.ui:1039 #, fuzzy #| msgid "Hash Functions:" msgid "Hash Functions" msgstr "雜湊函式:" #: data/gtkhash-gtk3.ui:1070 #, fuzzy #| msgid "Hash Functions:" msgid "MAC Functions" msgstr "雜湊函式:" #: data/gtkhash-gtk3.ui:1092 msgid "Digest Format:" msgstr "訊息摘要(message digest)格式:" #: data/org.gtkhash.gtkhash.desktop.in:4 msgid "Checksum Calculator" msgstr "資料校驗值計算器" #: data/org.gtkhash.gtkhash.desktop.in:5 src/nautilus/properties.c:595 #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:8 msgid "Calculate message digests or checksums" msgstr "計算訊息摘要或資料校驗值" #: src/callbacks.c:51 src/callbacks.c:55 msgid "Open Digest File" msgstr "打开文摘文件" #: src/callbacks.c:52 src/callbacks.c:58 src/callbacks.c:308 #: src/callbacks.c:314 msgid "_Open" msgstr "開啟(_O)" #: src/callbacks.c:52 src/callbacks.c:57 src/callbacks.c:121 #: src/callbacks.c:126 src/callbacks.c:308 src/callbacks.c:313 msgid "_Cancel" msgstr "取消(_C)" #: src/callbacks.c:73 msgid "Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)" msgstr "" #: src/callbacks.c:78 #, fuzzy msgid "All Files" msgstr "選擇檔案" #: src/callbacks.c:120 src/callbacks.c:124 #, fuzzy msgid "Save Digest File" msgstr "保存訊息摘要" #: src/callbacks.c:121 src/callbacks.c:127 msgid "_Save" msgstr "保存(_S)" #: src/callbacks.c:274 #, fuzzy msgid "A desktop utility for computing message digests or checksums" msgstr "一個基於 GTK+ 用於計算訊息摘要與校驗值的工具" #: src/callbacks.c:279 msgid "translator-credits" msgstr "V字龍(Vdragon) https://launchpad.net/~vdragon" #: src/callbacks.c:307 src/callbacks.c:311 msgid "Select Files" msgstr "選擇檔案" #: src/callbacks.c:529 src/nautilus/properties.c:253 msgid "_Show HMAC Key" msgstr "顯示 HMAC 鍵(_S)" #: src/check.c:202 #, fuzzy, c-format msgid "Failed to read check file \"%s\": %s" msgstr "" "無法讀取「%s」:\n" "%s" #: src/gui.c:308 msgid "Not a regular file" msgstr "不是一般檔案(regular file)" #: src/gui.c:331 #, fuzzy, c-format msgid "Failed to add file \"%s\": %s" msgstr "" "無法加入「%s」:\n" "%s" #: src/hash.c:188 src/prefs.c:113 #, fuzzy, c-format msgid "Unknown Hash Function name \"%s\"" msgstr "雜湊函式:" #: src/opts.c:97 #, fuzzy msgctxt " --help" msgid "Check against the specified digest or checksum" msgstr "檢查指定的訊息摘要或校驗碼" #: src/opts.c:98 #, fuzzy msgctxt " --help" msgid "DIGEST" msgstr "訊息摘要" #: src/opts.c:103 #, fuzzy msgctxt " --help" msgid "Check digests or checksums from the specified file" msgstr "一個基於 GTK+ 用於計算訊息摘要與校驗值的工具" #: src/opts.c:104 #, fuzzy msgctxt " --help" msgid "FILE|URI" msgstr "[檔案|網址...]" #: src/opts.c:109 msgctxt " --help" msgid "Enable the specified Hash Function (e.g. MD5)" msgstr "" #: src/opts.c:110 msgctxt " --help" msgid "FUNCTION" msgstr "" #: src/opts.c:114 #, fuzzy msgctxt " --help" msgid "Hash the specified text" msgstr "算出指定的文字的雜湊值" #: src/opts.c:115 #, fuzzy msgctxt " --help" msgid "TEXT" msgstr "文字" #: src/opts.c:119 #, fuzzy msgctxt " --help" msgid "Show version information" msgstr "顯示版本資訊" #. Translators: Unicode ellipsis(…) can be used here #: src/opts.c:124 #, fuzzy msgctxt " --help" msgid "[FILE|URI...]" msgstr "[檔案|網址...]" #: src/prefs.c:82 msgid "Failed to enable any supported hash functions." msgstr "無法啟用任何支援的雜湊函式" #: src/util/util.c:35 #, c-format msgid "%u minute left" msgid_plural "%u minutes left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:39 #, c-format msgid "%u second left" msgid_plural "%u seconds left" msgstr[0] "" msgstr[1] "" #: src/util/util.c:58 #, fuzzy, c-format msgid "%s of %s - %s (%s/sec)" msgstr "已處理 %s (總共:%s) - 剩下約 %u 分鐘(%s 每秒)" #: data/nautilus/gtkhash-properties.ui:16 msgid "_Copy Digest" msgstr "複製訊息摘要(_C)" #: data/nautilus/gtkhash-properties.ui:35 msgid "Show _Disabled Hash Functions" msgstr "顯示已停用的雜湊函式" #: data/nautilus/gtkhash-properties.ui:95 msgid "Hash Function" msgstr "雜湊函式" #: data/nautilus/gtkhash-properties.ui:106 msgid "Digest" msgstr "訊息摘要" #: data/nautilus/gtkhash-properties.ui:271 msgid "H_ash" msgstr "" #: src/nautilus/properties.c:473 src/nautilus/properties.c:476 #: src/nautilus/properties.c:479 src/nautilus/properties.c:481 #: data/appdata/org.gtkhash.caja.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:7 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:8 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:7 #, fuzzy #| msgid "Check:" msgid "Checksums" msgstr "比對:" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:10 msgid "" "GtkHash is an application for computing file checksums, or message digests. " "It's designed to be an easy to use, graphical alternative to command-line " "programs such as md5sum." msgstr "" #: data/appdata/org.gtkhash.gtkhash.appdata.xml.in:15 msgid "Supported hash functions include MD5, SHA1, SHA256, SHA512 and CRC32." msgstr "" #: data/appdata/org.gtkhash.caja.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nautilus.metainfo.xml.in:8 #: data/appdata/org.gtkhash.nemo.metainfo.xml.in:9 #: data/appdata/org.gtkhash.thunar.metainfo.xml.in:8 #, fuzzy msgid "Adds message digests or checksums to file properties" msgstr "一個基於 GTK+ 用於計算訊息摘要與校驗值的工具" #~ msgid "Digests" #~ msgstr "訊息摘要" #, fuzzy #~ msgctxt "menu" #~ msgid "_Save Digest File..." #~ msgstr "保存訊息摘要" #, fuzzy #~ msgid "Check Digests" #~ msgstr "保存訊息摘要" #~ msgid "Unknown error" #~ msgstr "發生未知的錯誤" #~ msgid "%s of %s - 1 minute left (%s/sec)" #~ msgstr "已處理 %s (總共:%s) - 剩下約 1 分鐘(%s 每秒)" #~ msgid "%s of %s - 1 second left (%s/sec)" #~ msgstr "已處理 %s (總共:%s) - 剩下約 1 秒鐘(%s 每秒)" #~ msgid "%s of %s - %u seconds left (%s/sec)" #~ msgstr "已處理 %s (總共:%s) - 剩下約 %u 秒(%s 每秒)" #, fuzzy #~ msgid "" #~ "Failed to load \"%s\":\n" #~ "\n" #~ "%s" #~ msgstr "" #~ "無法加入「%s」:\n" #~ "%s" #~ msgid "Failed to read \"%s\"" #~ msgstr "無法讀取「%s」" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "Read program data from the specified directory" #~ msgstr "從一個指定的目錄中讀取程式資料" #, fuzzy #~ msgctxt "gtkhash --help" #~ msgid "DIRECTORY" #~ msgstr "目錄" gtkhash-1.5/screenshots/000077500000000000000000000000001431266303500153535ustar00rootroot00000000000000gtkhash-1.5/screenshots/README.md000066400000000000000000000005451431266303500166360ustar00rootroot00000000000000## GtkHash Screenshots ### Main window and preferences: ![Main window](readme.png) ### Using drag-and-drop to select files: ![Drag and drop files](drag-and-drop-files.png) ![File list](file-list.png) --- Screenshots by [Stéphane Gourichon](https://github.com/fidergo-stephane-gourichon), issue [#38](https://github.com/tristanheaven/gtkhash/issues/38). gtkhash-1.5/screenshots/drag-and-drop-files.png000066400000000000000000001633501431266303500216100ustar00rootroot00000000000000PNG  IHDRQ" IDATxw|TṲNBD{ײZPٟm+(˪ ^B!O2Hz/[=yr̲)8""""eRjYѝ^'mѢHM4g^mH|ۦHeݜt{P.!&Će=3?%UDDjB "91Gw>y-̇-G9f8TEDD^.^mpO\J""RMHLawdŶ+Hڃ;?2~ur J-"""Rߔ=WvYϐq#HSBZDӬ9󊿙p9KPNnty!e(8}Ew,z_l?<;+W$9%%_L0/1M/O@@^7mfǎoߎ92v;+V"99Mس'.ik]=O"u݃4 l=d¢*g]4>e_3[QDDj""M<",.,),3+Yng< Ѷ>^<4iRI"-5Ӊ/anӎFbwK, #=~^Bl\cf~5? V}B U۶0G(_N/m3z|;7,/WX|}r6}lI鹌<$RgU|9WiD6nC]j욮WV\wo&ٺ /z[8[slCl~xNJ R?; G3a[ֲ`9f-=p[4KO۹s' HMذ'HX^ b1yBOz%ߗl;;{8r$*+-ӹe4NGM5&,տҲ}77@p>dr`2ӓ1nhٮ+!QLӤu$;@AȘƴZmvnZIVF*Nga]C#hݡek30M6zqnm6z^8 GA~GNV: בoćs 9G^o`=X6.z&|;S%Z#Ș&E*=GR comLx|<^ G?}@} TɽWNϱli&]u}:Nj{O27Phv9I<^¢y|CpZtԖ֤fdeN:.eW@Lzs35q_saӇwM<[xq~^>k3p8)w+:Wp-#i2ZufVkxڮlۈ`rlٗ_Ưqv]P^IEe_xW`0S󑓙oNPZŅ|REn8Yf¦eHt,屛/屛/-ZȇgоgK3߹ w'*,%iч˭ˌרK>XCDxҙ3p$nF"_H ㅿW焀jzNH\(p_~ g꽅8x"_wLnop.gHFH(!-"a.͇ý2n4=VnxYvG"]Pd3l~~nޅ 6Nj3iNG\dAv(p(ZŅq81ٿmb"ؽi_?u-bØz/yLڍ~G~{LHEB`htd5"()-i% XtXn^WO+ؗ7tnf4Z Ҕ@?u77 ND??m8ȱ,,({W,& $26?yض7U{ҎwcUƞM&9ױ1{ 6"Wy}p,xwUa]ؽS!"ğ-{OerNSRnK٘E8*Qq#D2oirpۯ|2TpMb>A㨐rc plrXVn>G!4%Δ|d=q8NE vٞۿz)EۿmApsyQEC;}.讧):3יcEDDj""f,0?&.09 ,v*!- Ol~9iIKD?Xy\Х)yS2[/GsG`>f>F&% ;F٧bu(ֶg?\0ap2c ЯS 8ݥeorW~HQyL=o-d9L{(Yy8?UT'2̢KnSѺ6 +8mb`߲! %ED0YztI,t;1Mg/ej44fp`/LMð٪7'8M#Xf/jO iEב (iTM#ׁk˗Ԭ4Dc`sW&0_kzwy붰h~nŴ{p,9;_V|kPtK|KqTCEžc"M8X,v~޸ݮJq]$[0'<ğſ/8~k)pwޓF5#-^nLJi?G>x! Bb&]y_ ~,53L_ @h_Q7ήn{9z)m~>h]ULLۓ 19Qt?yけYq&tӐR7DvM% ,Z~UݲOet[߫pߊ6N ݦ6\\Iyᑴiciy(4I#ԹP}tn rPBZDÌFHW3!ab+?"I7i(~??ѯk3߆{K6JBXs/Nd*.u2.'|a̤up߉i4y򿿒Xr5q|b(vYEO~;1_;vnޣDjWR/t?gdiQ8=Cz/9tmßDf;‰[$Gh&%9#a}r|tgD'N)ixY-E| R32;8UU|xŰjҳ4 ,;[k8ecc`XY3>$U;+cYHKXy>G?37e*TVu[%++'ҫ]ԹEZh*U*[cDD0w;bLng0 hA8qK}Rnڞq~Yt!Ԙ[Gbl?,B@~Źx܄wxr6ixtSoWO ӊ<>LKp@#߈,ڳ/O{ѽM#zu#9=Ek=<O`ptq%&- Չ7BtnM1uN䎩sB_zwhLflJ8߬!H+FM]X{_&Պoq>ssyKr^k>{wqcZe@.1>Yiʊw\ Xfl$#-.i0J>/'0+8!zTi6L~{宯hߊʮ/l_֬0Mُ5ASMpssz^K=wӲe=CjxE!̛ڝ/6 q29Gĵ..I oAPӞU49GV"~-'4܄7T%_%iy>\yیۑw`/o ҏيϪ̬+qf'ؤ~-q妒W~w^i:VVDzϪ4%Tve8sR˧\eNq|܁PNj- @48ccEld)!-"""[%ٲzy\ iYCD&JosŖ-gy pFY%QAze@DDjDDDDDDDDDDDj""""""""""R+Z %EDVޓ9~ℂ!""""""0x¿h(!-"ROe%3+.8̳ߣ?tV|e:ݺtp',u=UwQcx`'3t8~&?$W:sZ_ٞڶ>*""""""=x3)z?r=%8(ʴZkO:u^n=۵%,4tna~ŖwthߞzfbaYX,6nBh?.;&u4!-"RG>%/Y% Y /M/fɘT\Ɋyfz:"""""" ""b?e,=צMyfEw7ן~kYn} {+Ǐc:xO=BWyOx-N<$'\?0fpVZ]jɓ 2"7_̯(vLc 2_/MC~&f|13>חϿʐ9|?Λ_޻>O8jFuL`_i-y},a]t჏?)?/ܙ2v3Jߓ1)ϹUgE}ӱihyIF]v%.'~غ;wpWKM.ZWCXh(={rȑt1z.7v5 [nF6 .?{&Zl6FjႾ}i߮mݽ'ɸ1Z-t؁K/ŧF\̈́b1Q,_A. fb.liN}9 b)ktELEj=+꣞HC/5}xݺv$@zz1Qۍ ]l}jj*i錺ʢe~dgg io:=-KKO':*WERJ Q"==19[?_ >2sr_>dp9s:㻙,ZInn!qZ.*翶cr.dUYQt,EDDDDD%EDꨐbS:)44rTEla4O?>2jJxXiŖeff]'Ku ')9زZ6oguvl6+Vy󫝐>s늕|9}5"#"Xr>+"K5;;翶cR}:z2"""""" vY?rHNI!3+wrYnN)<6pݸn c8,^i߸ܺwR_HعSGnݻu  [K.XbfСl߱ ba,^SѺ:t:Yx [mg?gթgE}\]K""""""""7/A#pVm6/OK~!1披<^{ErѠ 9{ >3f3~̨2y7{v{L< -b蘱<)<iҸG Z|4/\t!s/9=~6&'Sϊ蹺D IDATDDDDD+B "91G>5)r \CDDD*5yA_>9-?*w ""5F#EDD5֓Wː6k:vh9/5i~Z O>(p_)""""""Ri~>~>BDDDDDD M!""""""""""B iJHH""Db """"uR\l ""EDDDDDDDjZ"""RoyΎmXyb]t$""R%EDD1M' GҠ>Umץb._D$""R%EDDegeD~^nQ!2 $ S]Fst2j̆p'Պ@ Q1*""R딐r5mNpp(V#ٺa \rNۺvO_pIH^է넴a8 Ed߷iMNvǎo#Q-""J i19YdҮcWl^̰=7^OuU98=@}]5}MYm6B &a64RZDDj"""RcRSkڼVzW4/3֧6[J, "uzqM|R iU<Ԙ\VDD^ Ş@Hi1a`jfh֣q`̧q$RUV p+""RzTl]FQ_i4e KSv4ܺ$""" )!-" -#5-Z`.=3K/fx<>pp_hJO?>Jel6n~"rsա>'DԗDDDD%ED͢~ȑ#̝7F\g뜝yɳ!ctәؓXm<4 > V]a_2T2bxnF刈Ϣ鯿4oLA?4%EDŢ?qرeyv;{wu{g>r ,exySs$8=OWRg\2_(SRgǯ#v8xwqseq8|O-%+3]dfUeYr7.У3d\gx1?NHp0Szzu[NN7mѣCZ4o4.KFҥS:].;Vc,\U'Td4@¾}s$dK&o=|e:缞6l232 mDGEӽ[7ƌ#w /yymymDFDCXh(YYTbQ[-~jOo<QIF0xÏq\hղ%07O#8,/}ү4s݆۰>񽪵Y,Yٴu+׬&n'&:Ҿ];}|}˷NzfiP|]:fc~7\b"aL sge6m*o*w7zxڸe =O:O izt`N5bxEK%O&1B9cn^>0;w.w{xʴցW./:lצ9dY|zF:a8 [ @DX8i`&.LJ;agV[ͪS {?h'}>1l(^}WrҹS}ث'MmL}W{Un}.^g_}M~~ y IȠI8#4kv?x^hټ=M4H(EK/11r8nJ۲w~: מw9g.cFٌaBrrػ 7}# WA>r!ߟsQ=p>CG5޽j/%y[r:kJJH}H=p8pIɥedfW__\l#Fq={<OVy'`!#n3icJݺ};?LJ@^di֖ߕ,Bٹ{A 0X~=wbйSGzvvCLHYm6l6+W̝?,V {/Jf᧟MXh(OEسwf|MM8w<ڴ_Q^ }=P0.&?OO3/gȿ_{VoIKO玻Jmw~rrx'ky7HSz d239vIFCZDZ2ѕ9Qd'$񓒓YsR|lܼlٺG}sR&O/xZ=k"mV'3#7k0 c ߟmM^~>adddVZ~UPzqjifM9t /žKfM1 t a!,[VT뮙Nj8z8&&:#$8ۇĤr۱}.\n#&/7cFsn223kvU82f(Z]a[ ALtVy)={Z 2{^.}{ѹcS=t\v'$r3r8<ڴjɀK/eT؇N-vn8={b С}J^ucY]>>k/(๗^vsMaZӫ!!  ۶f2z`na"m _!/~} z?SaL{RhcGs~:ǃ餴L#ED)4ZȣabڵiC¾}EV+ڶaek7l|i/L6m ChrEM˖swyp] .(ڵyƘxTY}BC,͆f|?3NtuYbu:UεօHSRiݢ9۴.w_8(&|?oS<-=Vsٴ`9֍3Lz~Qjg(!-"RO )?.XHjjj)޵)&:####sRߒuоLˮ(ZfXx}KbIǏz}{t놿?bٷ@mӺO$ң[ZkSdxrWzF:iߦ 'N$2g{vq\]:w }ǎgmкUK;i (ZZzѲ믲qCsUbjf|7,e9yhGxx8Mݗ_yyQkmMKK#<,T"#+lKXX())xpRJܯˍKdD8'ߏiѼy}:7됙Ya?TBB0k7n^=6<496Ix`Đ\toR䏫dCߋ>:1""Rg)!-"RO2fp.XX*i¨#= *2Ç{揞>HL]۶6EKm̛/O+]mԈ?Wգ;8͚2b͗qQwZ{I>ҜIxX(f`K8|$lrl6/VkHը({$.IXhUtu?VELt4nO|/<Ȗm>tNۛH5Y WIO$V>2hK`9_ԱܯK8.> ƍa;pJOt߽ddf1wHNM)-;vt0slFNzF&>ބJ~3yLO\|zbҟ+uo;wls,"77<А7 V^KXh>>9v1Çj_?4ڛ&'? GMdJHcތ6s"1hyFV?ΝWg%nC>gu^f\6n,!!((W_f3rPI+J(`ZFXXXw%+#[Hn]iڴ ͛4bv1 oo/Lp9t0[mKNdddzf`CoK&1l(t:\Y|:ߓ#gSd\wm1~X=v%{mڋŗx%Jbճ'Wp3pWpy}jSyw  !$0!m&~<|﷙3<)L zN>}׹D\^yq Ͼ0w/11>ra.͚[k}IxL{/(|L %EDDJ(""}ySyaXGpXhQ/  e3g7(aэcc:x^1G4?WO<}=E+uye.Ϊsv\3Hl06LN2ƞSal\.'/\v;u$ߟM[sڷkwVqUtn iT,';()]S3TDDSN_Dfؐ,ZLߟvmzkۖ] 3d@*lp޽Y|Yݷw|C4N}\e*yEQ#,$V]/>rw*((PpDDD*w"" X23:x0!!u!!1Πbtm6}{ftMܥ*\{jZM=UW\&#sca8 q9՗Z-_kkAݮTB if1tzUP&\qEk_uhN蚘/>ճ;+ZRo0n-W&jnlr2jRBZDDD>Rrvf:ԧxȹc`6HCdUDDDDDDDDDD6hՊvc/ הj/WۍjS DDV)!-"""5? ,Bk鈚Um%O? @Z);DDDDDŐxnKnǎ`HRBZDDDjLPH(!$Ffzۭ!ň4AhxA *M!"""5*Q~&g6//_uNΖZ-uԧW@`0\90 _DٺaM_OV 5nJPp-""N iqA!xf鄑a4k|iX,#Y6_͆j-[ՅHCDDDʣԻ7ߜ[,%DuyڬϿEt=x"""Rި|DU}Hԧ piדHyz&\^<#(S]}]"IDD2JH2@ V|pVnZ)\zyHTTN9a/X|YTSxADD<^Z! ?0+Z{Yu|SN%))6m駟Ҿ}{uƔ)S5jׯg̘1=z?}N/:u*yyy\s5[?`/DA:Ǟ튏5V ir4L4j5~̺K.,\Tdz> ĉ1cFv3f`„ lr9m$$${nϟ… uDDDDDDDʡM g5 -C߾}iڴ)#F\{̚5 7|u]W>ŀسgΝH94eQϮve'x +YYYDFFкukڷo… iԨirWiqqqE.JjHiJHHtƔj+sٳyW_e֬YE'N7|Cll,'N>V>l$""""""RUJHHe ]FY_jD-v_[50m4/TuHdv2FH_}l6:t:thkJΝH]p8/e8̙;"Wvv6> /u*y]̙|Wڽ?CxziL-)88 [v-{xjrw)w~ mӆ!-iެÆ VO,Ef>}V+Go(h(Jgdfr!zcUua&Sо!!YdL(""RS:' ];םQ .{GnDG/ɹ׺U+"#IIK#11&MFDDx^^1?"ooo:v@nn.𑣌1fMVٻoNH[,:u*.˫W^[2 z)JHHg$AΉ(SRXz5ƌ.sԴ4O IDATXIrJ >>>tڅݻSpG'>I[nc1h@얪ޭ+[m#11mҡ}{6m®]! ݻӥsجiSFQ$%'|JR o޴nժζ}wߑƍM$00'N9mӆK.>ݻ#Ghà =[>>>\N$&2٬Xk~yV؉i4cܘUXj5=zU:fyTXv-'OtڕА~]/C$%'b媢cuܙÆ+9r^$%'s"AA bbbtCAsH!,,vmr :\jdy$%'ӡ];Yz v.f݆ ج6bcIJNfq\4kڔtVY@KpDGsAZ,|9.`yddsQ~hRl;JL8x m׶M6ljy|n6 r-GEOTZѯZi[m֣EڪxQ"( A53?6$dsqx#s|f33iѼ22 ?4˧8IHfaXŠtֵuSRR§}vm۲o3^7k׶Mj`CiN3uz:G޲4ukrXjۙ5n BCB!$ 鍦ilش 4+}Xݻ1hƔކ{1 C7}o׶-#G~[ѡ/-]]lՊŢѹS'ZjU8~`0Hn]4pOcu\fMڶT["::N;֤I}ޭ+dOV9$&&#bؐ!ĺ\Cӥ=zЯojՓ={S!D!]v!BT`.]:}Ƿ|{V~Y. h,K%"@\lUVEQp9gT8caifš=^8kݔ]b-&nLY5mS;[^]Ǖ3**˼{܁#h! $B!"y޳G5]QQJA_b0%~϶;hۦ z^~`oNֵ m۔wy(m=Puhߎ-[h_P4MlV4Mo]Ԥ$B4TB! f%ƍƷh#;qX۵J畮ï 8㏧]V͉ٿ4Fnn=wkuвE 9~NJ Y )}۶?cq1TUe@CkGt4EEE| hztVii;3O\6Wtl6+;Ϗ'::XW{nȥ=zC-%->B!ѵK-eV+cF"99qY~thN*LWڶyfx _nHO5f1ILLd7-cZU]i)5mJ XF-7~[`0]ߓCVkhִiwϞĺ\ۿ:Mtt4Æ֥+:\6՗nÉg= )1uZ}8zI^BpBqvm%Q~h#F*F`u(QK4bz,'8}tgݿ&'1!oͣE9RbCzoԽ<=cO\M֎e;BqHB!B#ݿ͚ѕROB! $B4X۶VW}a|{Get %h2`hղC !B IH !h6}ð"N_싈bR={{sR9B\^֟;U=wOJB!h$!-Ar=qzշ޸iiC||#B!B4 B0eeÇNkQI62^/8TB!B4 B E[u.ZvwB!BH#2Ɠ^70`D,7ޠSN$%%ѷo_ СCY`>KOOg׮]zG?~STU~)ĦԏB!ODB!&#Fв7zȑ<@<e˘:u*O>$^k2lذr+Wd֬Y|DGGqbTB+B{B@zo)=DNH_SXXHRRg|rMYn]38N9DB!B!D=}B! ]vk0[H/Y^z qFfΜE߾}?>QQQjՊ+V~J e˖ѱcGf̘!H!B!'IH !hp^ C hժiii~aaÆ1k,ƌXl%%%o><_ZZse^ZB!BQB0&"8q"ѡC+M6l;w '۶mK0dСUJIIaΜ9yKB!B!D]IB!$4QvT=bʕM<9zРAUۿ`yƍcܸqrB!BzBHbOsd@Q'QyFUU4jjbXجXV, ECUU%tci t`?X71 ouRB!BQ$B4H<" 9]7T jAIiMi*`n4-P.)41-iDh/B!!-BF+ 0MQ0P1C0U ,X,( X-(+z*+Z5{{R\ӹǚP=*X|q~81 $BqB!hASUQ **(h|誉( A3zoύ}b}U+k ЍJ*U0KZؘ_Fvu5 LYHtLѼ`ײʘL}7:Rel( ϛxoJj{ua*y &E[gX7ȅM!D$ ! &#LT @ŏJPPJL%Ta0"gNཻSfE+⸬6]+ߑӛ}iM&wZ$મ=ҸktMa*|2zb >Ct\N6ޝʊyDxFuuH@x=o>%iٻu2l=0aBz"ޡ6<ùAz(a*x́oDidcxdp꺁s| uoSs}='ҹqư_V=, LK;ShY!^kW&^/mS,Fh($(WT"#~f괾k4&&KwxM\_em8ӎSմ?d;[z5@BJv^ZNO.'Jd)+eWY?i\Vc}C݀/a>R5mGv)1LXKxi&񒄴B!i&C e|}T&%QJP\4K[JHVp@N'X+> WpXTnHb%\q{/' DmqsY?^P~Or˙F6c{8^>MG ׾ɝod1܄DXvO8-j}Fc 'I -N2of6veDNz&ƨ9_WGlEZQCxvY>DuUFtf>i{LJ&VOrq\fr1E+^Wpo?{elN6͎md!-Nx\[&Z8So6HZմou jg&ӈk(,uVMKgɴǔhJ`B;5yLOME쒤fQg 6G,(٩1yEM!D%? ! `&nbAG `Y8Jh?W躎:A@ Y:qե}g~ϼRܵEv-ӵY5B#Of6Nf{PDNnUt_`__7 & tl0^XYppa3JznqM9iFvΌxҝmޙIP/橔h=)9>CBFNN[dJ w]z9FYgȺQ]v9ߎD}>ކ W:AQU]~0=<:~s_'w&wi>nsTJ0,6fnՖoNN&V*9ŕ+Xx&ˊ|> 6)9ťMI<,ٽS4|_~|^D~hfI;ɖC>6z;{[2~IAQ=XJzCZVWSI杜2*k[׳nD:%&[&(o<8Jזu4^18W '%sY5UҖA~^ȭic8]-b5>2 tڦZv_>1#A%MKbxT& 0!B4&B!D ꨪNP bQ44%f*h%hZ,(i F %:F ^Һ:mS(-|LuEU$;6?sd6BfV5Yr4,MabZj·i,s$TޯX"xV,aΒp|;&\ ߜkk m?W X YgvtH|VGl9cp[/Iх'k>dbKS [uI jg禾Nb!LUޙy} jgg^/i\ꤺz$7HyBK =8:&Z:bWݥ/fܥ1tHV{ UQPU( =ݥlg~Ga(|{F7ǒq87(0!!-ھ;|Eov`J"qLCLЍP7?)pxq=={=><%><^o/-FN. nLXۣR, 7q6"?[*' tN \Yg@w:U]:7LxB~7&+;Et\ )17yӎSմc:]H O4+.-P]5Чu6MnUXb J nBU`hh\vYJׯΓJ?v ,Ӿ6)VT>N&' tx !hBi۶o/`oذ>"XzJS@ 534 L U/B4 U %"ʦ f0=׬O[9),/5x~yJ~dڂ\c8r=?IAs>*.#%a>^d?EQ`Kq3ULY]nP,*(E[]~; .B띾(F3}T<[Gthb%׭p?#FӾ1*>e7l/~1x‰'HNN>+hX!>>W_M7ĤI.ٺaJ3-8߸W''|ܳX4T jEZQZ,iVީivۡc;@#uQ:z;ި 5SPbTz]ٓygCq(ΎVxM"7luPk`a=xDz!~\qN{X`WcB5BZ!;Ҋnb:R"4 4!mfJHJ4QP@V IDATM5*@ZatJ5~E1?IϖQtJO6lw7}>4*)dB!B;+44l`ATE J(G f23ԭaAC ӦI{xFt됧!?]͢]I47ACYB!8Bq,Zzynfn*cJuǧ^g\ 0 {g}4:u*x7LVVmڴwޡ}l߾{w[ŋ֭[ry~G.\֭[2e  6x̤IhҤ .dҤIу>ݻwsm6yg?~<Ÿ\.K_M7ĕW^ɔ)SHLL+O>$L89s( _}sdԨQ{,]O裏P:N,<+̱j|8_*Nwg{%ID !B BqΌ?ڤtuh@IֻmN۾};$++!CгgOFM.]Xj͛7駟f޼yƎ˴iO8z(-[T+O1 SOqmb ƌO֭#55`05\o[>lȑ#ܹ3-Zq? Yf {~j* „ xgXr%G榛nbҥ۷Ç( vjh!B!$BS%kJF`xb3bVl<6͛swxbFM߾}9g}7Ю]J\Yf_͆ Po=\Vg4 VZi&~?SLO>\{,\iӦպ<vСCٷoNwކK/6mڰg/^̸q޽B!BFD !8ƏNBрOoNlSRR¯8q/2_~L6 Eͫ-oƌĉ4mڴ~8iii,Y^z qFfΜ'99j[l;vdƌe*EF&M8zhGE~u]U&%%69s8vXnZZse^޽{?>_~%_}Uӷo_l6s0 6oG}Ą 4k֌uw_Zuzc&k֬a8pcBܹ3|> N!B!$B4Lc>TBUV 4֭[ӫW/ƌĉ4:0tP^&**>2`*SRR3gwy'>gyDpWT%K{ɓy뭷hӦ gW^322:t(׏'|J!B!B!Ĺ"5B Y4+{H~prbʕM<9wlڴJy`0zܸq7cǎaÆPe2;vdڵyر;6S˚3gNAo#.o> 0!B!? IH !h)ٽ崖$۾j*?g˖-KB!BFOB!^l?&MҴiSx 䠞cv{^qv!B!h@$!-Be*Tyֲy _y\R1B!BрHBZ!ڃBK!B!D" i!B\TUsǎtQ*C!B!w7!B!B!烴BJ,sřuˤs}%B!H i!B4ZJqPˆ`A0X" V?m?DߟF\|\?f$B!.\BZ!7*0R!JSM^Nj2-<.le۞İx_MS(==F /*kH4T^XYb*~*/%ɩY|w_eم4a| -%1LïeW4EӄB>_U@V^~4+/096dW )@7Bӎy_wG8l Lgȟ/1yMm, G󂼻;k)oeUbf9l9#!Fexo?ȭӾ4n:3%pɂƐv>/=O5%2wm!-ϧg&ł_s>ޡ<}p@cydD<DUym]!v0eG1cQ'w2Hp<=.G툏*%ԴRuP8'yĭYMTƤNf9(Qg]ϡnULz=\ΔLoɑBFIB!.xD()FYXKjjTPLL% P%)_U]1&h5Ets\NϖQLW3itLrm &ﮎe'<8#U[Y5#6 1?/8Qtnj[ p+'X@:3˟M`_fi Nf|8OI煕;,UQXօ4mOu7NI*T'X6O/a|L[h&4Q5v<2Gws93o_Ê%}fXQBq_UZ'Y-8n[1f*s|'bKT,k鼲)]4/72ȅݪbE(fppe.*G<5L]ϫ2 |K۔Ui#p )](Wwx#z\|.cf ~s}LR38^s9xS>{bWFCzg.d#;*dzuh* !F%H)CU`Bo'SheWTO.ێϚΡS˨n;tX_^˘',ђB Z+sV{q-O-#4m/`c{E At,}mP6Qt,{ӔPTLRWbDsk'/abng(Y"§ߗ;Uxoc1S!56t뻪_oHXÍ}z3ʺ"QcLLL.Jb|3ݜ-h)]j^v[6-l\r&NDnOukyR:3q޸3G&$2B;/ޘĶFˉ1*w EfQgkS{oHdf7w tjחPy|L<.g_fsUFtf>i_LJ&VI4+ߑ]5&qNIevE:^Y:A.\Rm缪XmR\)Rqӏ>]j9>u*BZƒgGnl'=~S/8^P}orM,aP;;#]|gC1?h吟ܾбXmh_F˿ ɫ 9P5~oN#9QA_e=<"(EyfݒaWr + N{nv4LvfC -nɑ Gr4.ٙQ_c@j]]tiZ `dF(^oTJ0k c~*S 2W `KBmO,U0Y'(*1j0y'&1av&u$ɩqQw6 zb{%bWk}tf2"ih_)l8eA!D% i!Ζ\~{?gG @,m)mZ^&A:'C.GU^WdFS㼁Э7urgi67?8ɯr屼rjn)ߞbvM5n@uT+8xEh>uM}bi䖪).nL'ٛ`BfOJ׳t;0"KtG3MI)ےZ`$]~uäĨ,zpegV-Բlb8;9:FY"ϣ `.(1pEJ(ֹ,:՝IMI<,?cRaNQ @WcA"gOĪnn tm)(1]GMt WkTMJ[ y!sY/[#o>#@m%b7)곮Pm 6k/;S0;3BјHBZ!-a0઻Okԣ| 8;>[sC5 鶩V]ŖC>&pK(c4ϭG|@ t{ҖQxc׾|#Z6٩oMO8Y׸=5.e״]ynko?MC&p20]4Ҭ<_"Q, _@ϖ6ve]n]C4+;VM 吏m<6&R5dbKSD^UuP;;7urN iogeZc8>.fLwhW~!87ڽ^ 3UӸGC7'BW8GrJ*)j[Wbg +vS7!mTIVmHרRU@f$ƨzi^ej;7ǒ7B!U@!ąOz @դU]ww*5ĸkNL6v2vMB~1)ޗFTkwt19OEu -hjr?|)1i!,纞1\b2c~l\3҈V0W  S-⺚[Hqp?Ml+MR-,mָ=խfQZ$Xj,&``DPmtknkq<}Q.7C][踥UM5, u6:^Ӭ|.N0GhYn$mDl$:TN,~ei|39J7`|"r`gnLWvbՔ?>eWuK2 7Yϋæ) :Fws`~7K/FD &~Qqqէu6MnUXGl^ J nBU`hC5gMPkY$XibEUBIDB7`!441rY| 8: L^eWBgC"[_]S﯎痧Ā_7 #6<\ORPb&kzyjIU~?6gopo/qLWV2wj_quS6~Ehj.cL_c>*|Qq)-AbA/4u-x?Y}ogg1?l(fΤd, %O,ΫOjV}<^1 .C:`˳KiB`67^j5ft:W㨟 Rp\"X.T=b TR*,KJקgJ !B!ĩ! _ߞx\vZ*'0Awzɗ_~ e]F6m8t5ԲYUAQPQQ zJ3i41L01i``if u='llrVEQ 1z&"!t*wt'V IDATv1(¾, mnL<--.+ׯSyaeKvx6v<$FfΟW1ӄr0w ])ӄL x~UY:O${3} nOvʚt#ʿnL9#6&tѵ Eh^w74±9-I]eW摑)u X˦}bq49%y#QXm{^#m屷_V׫ bwYs׹>b*6i;j;BF=L@!DCmչ䊻Okmkߩv(?߿k&~ԨQrCAQT0 aUTJhwa& aPBNP0 ?'Қ'XX _?;}~zH,($.8:V<׳uLQT>jW SxxD3V*dV vfOogx]]wݥ:H:t+VT+Pa2OאgoQiUlMѲ)ڨW6E(aZe[dY$!kWYoM.7V8=yy<8^gԝ[KNjncitͽ-UR쒤vmEjW6S˦51gh;dͽ-U#{DkMŸ4vm3jZڅSyi(3ZH'w3庤9)/izddS34A$ S~-ޯxS*OTLhm^S-ޯ3G*6GݣU6~Onx|܊OnEBMMO_-)$:Re$ܕb4T}1.MKNѼ+n@\X8< Ĕyruhfx+]k.i_w!:z"mW͇>FOkus3?#mܸQ۷oWNN&N("ϧ#FoVaaFks>:s5ydmڴ)hB8y1dz$#+^CʠݴȡWiQU{*|^CV婨&T=>D.?5F}RkV&^SsdtE\Om3+!=yES^v볟ʼn5k"t[Iݒm3u!ۭ? Gâ-l=ctIZ.k+ѐɻRX'?VvhԦ_6U+-*IjcѵE52_SW4Հ"ЈD=徠mHhҕI8HEZt~(}^}cs.~&Gw,Vk_Ә~qjg 9CúW5q uIs.QZl$R5M-Z|XsJ\i1 {_WjZP\ )fh֍4=dIթ_ehέ~]NoQ?U]5$9x<ΗѬ%5_ND$ 86X2ww!á 3F|$wȐ$ 2DYYYkd233%I˖-رc%I7t-[vX' Ugv0//۔m{Lc╬>CvQ50mZ0+~C6߯h3Px"w9"Q/,_-ׯ$ܢb5Jڱ+Tt#zS]5bW6d$4w~Y|lNiPfv٭~;VVykR92E%ghn*f͚a?55UV$=zwvo>%%%I2335{l?~&OÇkQjjjhjʔ)z%I/`2 ,lvCCYİ*bSͦHEvU$>__^J *L!Oy%/ߔ"J>\;F}YbU5jk'w{*tcumՠTa[TܮѲ[+V=-LQ6tRsb-/ڗRՎ^ |bFkצsTj.:P.Q/~YUL]*w٩1zd]r\z|oh~ؙ4}Rꅫ5\q:!߬2?}~V `8<7x g_q_qQY^O_U4GϫMGiweP!"HG6*Zr:}y`*-e58 .{ԡ +W{ _>JZ֊F^Үb:شz;<بc5i[B@pl:(eGXC>8{nj޼y2e-ZT͝;WO*ڧwֱNԨޱaz J|:c:#ck zZU%>:Jڗ&Jݦf.+ѭ4QZU;z:h8xu&F:(uJʡu2N]rJ:kLAЫ\:C[Pkg(-Y5ϷNa 5CPFCmjIZ\~Tuh}^ZO7Hj>ӟOe+N^{Kf>"\=*\Ð"y*iEAaܾW}Ea3Y] c@N躼|zɓrӧkU֭*ϧYfoٲEْ]***J.K}ԩSzrj|Ha]3X;px|>n _Fedtd}'ϔWTտ_EM9|>(w.ҾJnyʼA*߇%#tikfVlVid,Yen,.;5FVV f__R26hOO%>Y ܮQ5xZy8ah=cpC~*_YgfC3L:ܮ XS<\^SCGa54_rޫ+^+^6녅IO*f(ȧ[8Ҥ"`9ծ`w(O}Vvl#*6CWBƕ %<5z_ÖQjQ ߔ~OsDX/?$N}\CCC!C8*rD?tq^]rQ߹t 6&BHi5;ܵX?ئ_,4S"-ڔ^j<mc g_~ ciJ>Oū.+[nM62MSr k̙ԩRRRtu_$ڵK^{|P钤[n/XjSقRdKL_/˧Rl.EڭrX-Y-TS˫2*q{d ӔdJfA}bǕB>}E *>Sf!w^uu|0A/ ׼s2O[_9/^Ώe=t^hwssujFR"i+Ra֜[Kf-/ѷ+VWM j[˷ hJ&?vΙrWቺǣ$;$kܯ_oIl\Z\2ּeS-Ԕ+Y۵ӌJB>x19;j6Qd^S˲\{T)i{{ቺvjr{+Қ^ַ}DldSᅤuz? DJ9<=z袢c0|=z+ qnodD-8*M ZŐjb/yMSajff1d4My}>~~SL2_Ҧ`n|]J֛KKjx4iv=tqS]B ;u6ͺ)EOڣyq-+ݟEk)w|b i1_~^Qc@%SFR<8 Fׁ㛪7W+W+ |!)5*iV AB}FlJݦzP4G ,n[<|8pmJhFci 2+i֯_Oy$+U0O_EoFln`(sDS9lJ|燅*(!4{Q/㓼~,l(PO~\G?.#A?IQu8C !X@c h4Q4 Facd}-jjpVQE5V{1H-_%Tq_-җ_-q_B|rJ&14tO^*--qWGlUlڳg\tE5j*pDj:԰Jp! 8&E}9zzApXɯ*PWyvIΘ1CJKKӄ ۧM.]())I{ֆ $In[_ҔaÆﯨT>}~iƍAϛ^{MJMMC=Ts>p@͚5Kr߁󤥥iݺuZdzx5h4$4e=2}u|=2M3hk֬QVV/_iӦi ݺuq`G}7jĉeX4b|*,,ԨQt5=oII/^,}wzW4H|$髯R6m'H6n(߯.ӸqTXXc#4d+=u|y+ ;PFFƌ>@ԻwoeddH ,IR~z}2 Ce˖vkرnI˖-S~~~syr8jݺƎy80?nV\RZp +Wfi̘1X,2dN9Q޺|I͚5 |={H}YyӧƍHˑٳgkԩԩS`UݻTUVVaa0 _~9piiiɩ׹m۷6mڤb}6l飯Z| \hѢʘ1Makҿrjj͛)ShѢEJMMܹsO߿,X jذaRJJڶmW;DŽ ݻռysIҶm}{3g*""B[\O?T/ֽޫ@W7@`4?./Gj8yd\.eggk>|rssպuk (I[lQvv$k׮R߾}x4uTy^\.X"d&MreggW^ш#u`%iРAzg4l0I)@ϟ2uQzo4M}嗵B@pl2M+ ֭[kjӦN=T3FÆ _.ժN:i:ڵKTJJ|Pl?{=%&&E:uj.[ڵ駟o]^xalT駟:jH͚5K</g9<=z~i`[Tt o߽GZcy]>fSNN dodDU^}dk^,Z3Hk;4 XN/?d8NW ie'<j7 % 5!4FA@(Hi@1c5?}11}z/ VHI˖Raa P,՗_-k@fϙ?<o`[A窨r{+Fx߾җYc-N\_SyT}zRiii>{}Llo>5t}GJ}Ժuk0y+/)gK~C/Mߡm۷/fϙ&Sv Vl@X,[wd˟n}N䔧׹C룏?q4 u便1Zzu}k\.W17hsrjs=1*+/͡-]LWz 1Rct~\N4MS7[F XOR%-ӹCkʕG^ g ~?oD@={$i̘1PKί׹ [ z}:S,ժɓ'+11*w)11A_yQM^cOMOj)p /2M ΁gyHH2ZWW׆<$5OIq~{;g^y}&=&mX IDATZr^|iEEEUg'?^={HyVjL}e]ye<矞Ν:Ͽ?yTޜv?ߚ9KVLzRScߚ9K~7o~Tpʞ?9cV^^={ +.A(O=P^f}ap!5m4%''KFɠ$99Ic}5j,yV=ڱcڴn[-32TF׫OֵW_(t51WUϟoI/O{]ee''>f}A` ryKٿ/YVx2e}vn]v?5{\3JNN*&5>=Y^5[mq=䤰ﻋy H);jahJ7U^]?h3fPzz4a„iӦK.JJJR޽aI_4%%%iذaoe˖JJJ-k֬Qm~$/:sԴiSu1M?ӕɓ'륗^ _WlBB^{5+55U=PէO%&&_~ڸq$o5x`iF>JꫯUVjڴnFy\[g݈߯G衇s9өM7iά5^kjo3V=+_wߚwߚ+WjيԴz[K[;wj3u˟n̓KX!z{zժejX|||=֧CO|JY۶{}s8:gO%&$VҕW/@;%ioa^{M;=~}Ni:}tt{paaƍWwuNо9D-qF}kI۵ULLtm/I]z۽iѷKMQ5|@gN;G%CuzU߯8B٪ߜ~޿ihK$E\sj٢/%IZ;zt頷^7GHn~nWo33OyEO>Pc|à}[Kmo _G kҍ^ؾfՎsfwc[4UzWPPzɁ`uDD_%Nrx[V7վ֓tß&WoڷӣzH/:ME[5ai>)YrGn~%'U֬Y ߇{MB11 %11!p?]G͘h/%I qi2M4QYYYJKKQc7^wOn͕SWϞ*++ӬSoRtRb js}v]wWON|X'us;i/(""~:NmVw$^(-5U6oQ=wv]v]Ng)ip\! PGѺz{jy`dbbR<&a #y8#HUgv?YN~J߯YqќYo+IZ4D */ v*)1QyUM=ؾ+**Jϙ 7%N}oܤq-qkBY۶/++Sn^^h^={jz䉧 ި(]KK/+/@ 7jg#B{ 4x>>9Z xx<& /ÆMyV~y<^9UZj*NU^O̕W/r9z4Ӧ[dwV^emZ+""BJ`e'w"ǣ~(׫@y]:f7Z[3z_Pm gnڙ]m얯\%ǣr{E~5iW_g՟xtݵ!]wr}۶ǟ}.ǣz[=3{(...d۴ek}Irn[~_ V ж;k}-Ӻ'"}F^~ZfڷS|x1c~S_}HCa_Ps*9Z}}v5MLTtt4o i8~~evdgA"##*#C;up7y4k;jnW)gZ5z|=uf~Wr9z^5Z}NyN;^OJNDGk(k,s}zчĤ)sjI=&MݷWochO^Pj^+ϧeWw#.Zԋ-YYr8:W/HPp(6&F11*..zeZ|]-Z?'>Ǟ;Qz/֩6M;tSnڴyJKK+j_]4zV||=p=҉azlCƛjzN+kSPCݪkujej9<=z~i`/7^/ڰi:ءv|BAO1kW.U^L ~YA=2Qo>ҩzi\2uM7SysgњE]; ;w0 'uaCm?S |%RvA#G\|̴%=-M: xF.tc+(jђA@N  i8:w(;y!V-3ԹcGC@"Ţ;k 8(H);uD_!x<:%G+4a  HGtq1 ~48!#+%s((w|W\jT`fe 4~[kHMrۍ}>$F q4MyD6 k0kUPPs/W\j>ny:"`G6I5%$q㕛k$Eҡpìf[uGuhBRe!sQ:?(ۢ}:;1ΡS'|`Yn8rds9]7fLuQS&lp{ZIΐhD~0gyVӆ qp{ZfN$)-- BmU?DުyjޤIp\ذi2MSJm\.K;p82E1CogTVn֮]HvZeffϑms|NNNVvv8Hڵk,u*&&FӚj'Ӭ|8}[vmje=˥¢"I۳UQq$iI~N٣J}e*޷Og飞ng_,О+PJJxIҲ+~pib|>_N`Z7C7Y{knnIR3j>9""Լys:u쨵?2iZqqqj֬Yσ.K_|S޽#{W? =3laQZjڽ[۶oWD]41Q]vQyywQAEKUZj߯7*==]:ą8#ZNV"(]O֩gϞH;mVPZڲe$m6#Sv> CZӠe^?;~$IE11)-;I nZңlݪ2u@>~駫gffϊӾ}j-w\RW.]5TPWro_] Mغ[ gڷ7맟V~A:eYmjD]vՒ%9333n:٬Y3bi)Գn)UɘaF!7DsHWk_>WNf"4%**S_G.:Z,-զ͛kd[qq"ԡ=Y[9>Pm_~-;mڲEU-+/Sˌjۦmg H4!jQRSIȅ-IϬNjZ'*R;v#>6BD~VRSSrm6r̭֮m׫})+niZCi>֥ahw43նuk7irP@psE=Ia&]2"EFDݎMuAg%ݮ>_q.Ӕbނ~m۱C7n駞|<D˅Ԝ3<̖Wǫk*`SΊ#D綅;)yʕ"2?wv;C_~P6oV]jjecccUW+{.uY O;Mij͚ɧxk7*ֱx=eemޱsZS+p"?@ٴi#Pqmh7yu.b5tffw]N)--=եY!pDǧN'X^V9yړhkF;ȿ|J*,,R^~r*#J@ڐ4謳T,UjCkmeյKgl6ycbbdX~Fy<EEF]խK. ~ ^Yg8"m=R6kL,A9:+coD]:wV6m3uZ^:kEo3K.8_ G|{x[}{+WɔԥS'ك FziSΝt~o|>}WޭձCعZPtT^pF] FKR|&lIBj2qIKMӞI=9=}$l`t]QNnF]~F  7je$ /,V$)=-U:ry}ءK-WyARdHG|:=-MC/8_N^Ѣe`۵m-YYjղdmSˌmaKZj,[&IڱsvUWiONR_G",^]eX:t;+ }f~j"IU*--UYYzgց۬r. =lU'I劎-**Q]۶ikVwVqIi}vkgvw몝;{O(=5zu۶V6EF{H:̀tDDDX(6j"##UVVVe媹Ѱ王U|&ڼu ԲeFǥYrl͒Z8#vVNnzff6X[׮,PWI~(9S5׺_7_Р0MS~4MIRrR|>6o*Iڽg k<> ڦvmkԪel5 m\R?UFE0;E ؙ-נlkO,-պU+2st,Cw/Y+Wbu:+cͦWj9j%ZdZedIk`03ta#B$A\MJT5f}<|ǯy4h)"o ij!ij=82\M7a]jweHP 4HP 4HP 4HP 4HP 4HP 4h_)ӝi,eUfgV Ҧ;208v;'ͅsYvTaMOO0:I:uԅ9y<7fphU%a4?-*䥣)"EQs>x ti7';?OUU*kw^ ޛoΡ_̉'qÆmNC{8S/f-Ҷ:Mo_Ә7ÿn=Z$I{n.Ov;۸%=IL=Fקhd왔UkFvXd=3Ndnn6f33j$G_>28*I27;Ɏݷ\uwﲐs\={,Irwf֭׾v8}"7f5ʹVWԅs97q6n'==ݶ= c-]|3ztoeK5:eU-,e?H[DK/3E -n7M{vثdϮ]WVKË5,V|UGre8|SY~!H>+Yn}G:q,[/ԤvӞ]7=7W_y)C#ٶts^6f3'^}%k֮Ϧ;27{)ǏIoo_V ԅ@zⅬZ5K?T۷oMݛ{nϥdhxRz{iZ=9{D&'Ng|?e7gOgiZ~Yt<1\MLHQ4BD?oSVUn+Gal,}}}ٽsg~vj6s4"7ߴ'Iu˖_.In3"#2U Xǎ,= 3j$RUUG$IFVS'v^7z4EQ F3#צ(7vb8?\U#sȋY_U)"S2iU{\V=Xʲ$X-}#n7fwը`i߁U97q沿kFק7egg.;ieF ۪}ʲL,S7Hp`^=~"$In/gݙe ,vWVNt//V5u7nٞ;Һnn=h, gE. bvݴZVnzzzӛK3i.?So{:\?EqC݅{lZ υs8uaO׭o;uHUbm[ tf3*Pk4u)raթ:ץٜtx: 'wHF*ReIט:t8;oUKnڽ;3=3֥g?q"g.1Ҷ905mwyZ/ 7'fu*M.h^ j(\8?k37{)3SټnK.-̀޺uk{lݺuYv˙SǓ$CI| ~u;ݴzzfOO] e ȿvٺZf5j4?7|=7jem9xP|Swy8=poݚ7߲p[nGor+Y6lϙS'2qdp6\`m9}x&NLՓ[ӳ0Cj7n7}Kcˡ'S_[_~k_l{lY$Yv4Eә?q,EQd`hU6,[hhx$畗lexL?9o_ͥe?ǿtg!lɋO'MN˷7ʹZ| _P4x C!ʲ@s}_vگ5}+{Gyї.[ah3A  /* @A @-B @-B @-B @-B @-B @-B @-B @-B @-Ԣu-;{D{n=<+~ U٫ ij!ij!333kU`ju,Gٵsg~3I?#~(mOԲ_?Hf?]w}-ؾ=ys9OcG0;wg?<}4۷mP_Me ~ݺ$gjjjXCCC[}-GÏ?Ws>sO^||*~mI/_v>}۶g?{CZk~;9yT:N֭[~ٴqָ,<#y̵͗4z<䓙p~Te$i6YjUnۿ?wW7>6}9}Lzd$_M{}m{Ҳa|''j44;:I֍f޽$jcްmtt4ccyȑ_e.]mlgx޽}vo_ezf&lۺ5_|1eY^ǎeڵ9sl֟񱏽a7ͼ|H\ֲLLNʩӧ3483n ]irWsԩ]m;oG'?G/4;v֭=ϝ?Ëǻپ333̧>9zXޝ$K3+_yO^p~7~ciK33yg255f5vyrӞ=O:n7===7t?~E/~]6eYfvn.S.$I6oޜ{>>ٰa[K/ K-vٸauHzzzSO%UޚիW_+v}٬$yх۹3#?q.^N5>.2OHFX.djj*7)27tS~ӟN&''3>67  ,B|z\ik^G?}ٽ]Xٖeǥ<3Kld-{-tWt>pٷo_>~IԮҦsĉ+[ $֭}oޥ =kחsY~}{ix9sl~y=v,ov͚7m;k#D>񱏥j]Ư`7{v /^׽/-~W /plrUvlߞ[n9eǟx"nm5)˯}Kr$~8{?=Kylݲ%v^lZkϾurdz{׮뺆|ϙgs橧m27_cǎeff&ϟҺY54uz(Oя={y$Ioߞߟ۶9}uM+¦MӓIg1Tq~|K/-[74 ӓ.e9u>|xz+ٱ}[bouֽaۍ4pvv63/K\n]$sWwܹ\m3ޏ~4Bީk|'w?A>y}GS _tOk3KSe/ܼiS~3ɚիOݾ⸟ oVwҷ~TU$x18ڹ3Iv͚}/dzqÆlݲ%yjl3ٸaCֿIxʵyȑ={6G^y%}妛rY~}v:lΞ =s$WZ닽{fxʲÏ<ǎe-?svʲd}822 K}?p-kۛ[#G#ɓIm۶]ss?_d9{lf7;ߟ'z*뮷ח|07nLOOO:F͋aW/`e{陙|~>sL}}]v)~ɓy3x޷>{<?xʪڵ뭞2ŋٱ}{ t:e>/-݅H Ug=gqsU,IH-UUes1NRUm; t-JU-̼^-VF3EIY% [jtS3*ݲLQ$NJW݅)/R$ES}+H EŀLQ)3F2,S4)E6ZhQ t;NWU8- V#)i(uHP 4HP /5XAzxט! @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-B @-Z:K?j\k gT %٫޷N^Oij!ij!ijR`8&37{)UU)U*"}Yv4Cy@XQM۸)Chh$qʲŜ9u"٬]M13}1Sel65P~!}4SZ''2a05͌mؔ4N s2jX!^4bTUg2i4(uHP,3=[IDATEg{.Ir}*}}}+.ie4;;(lܸ1I*7ٓ[-;YQOQ} 3>EӧNSi43>[<̓v;QUU)"f3eY&IfHUUo:楃23}uOؑj#XFۿ?ǏOvڕ;w/Ǐ_ѵRCevg۶mIÇ/͖^Mft;emKUU9uX/^HUU̖M?SeGd|Ӗw.ieߟ}{h>nܒ'N楗^޽\ {uzzrī8}*l i[$^ʮ,9L_Ъw6i477(s%Inݷoarիk׮>}:۶oDgfjh :~uAuUV\'ęSIsU##kG{Z28*94ϒ7q6SΥe7Bߟ[w9}x7lҸVu1pQJK SQOQ}…lٲ%===i9yd&''jk׮LLXf3Vkii4NO]lں#wݔ.;08;vgm9~H.S/4uxg36S9uTFvsԩ4LNLo|F_ӹ:Nzzzg;Wpni|Ng>BhdʹUU-fn,Ecܹ3f3k֮O<ޞ(KٱcUkxdMΟKjeќ?7$tsWRv4ߐV=Y34uxyr7g]I59r$ccyW3>>gi6i9|pz{z/;Λ#fd$I/߾faPvݴM_M[՚ S?m۶%I>,m۶Z<388ǏgZH\ۻ7F#?~$#eY?I280d9p@200 zH\$=wI+M6z5|d@Z@Z(eˠ,k? f/cќ9u"e7vs䉬^;zM18*Gry;QYvsqBx(FVgph5o)!]޾LN͉R Zh?cF'i`Zu]*7Fj!ij!ij!ijH)ZJ_ fzz:_ד$]W[CUx<epguIENDB`gtkhash-1.5/screenshots/file-list.png000066400000000000000000001054011431266303500177520ustar00rootroot00000000000000PNG  IHDR%y IDATxw|Te6kf2I%TZj(JW( uu]uʊ>賫]_WUQB &2ɜs&3PJN3?Nhp^L.J Oc%XK ënIQ;pz;V;$0n!ƨɦY܂r#g'SŜ_Fç'OǁKdwG DDDDDDDDD:2)[j?ۅ?<2^/+~&a6JzsǥMDDDDDDDDD\G:vk ~  YuG1{*jmxx?~5#$c[c?_,3oAAA<Q2u` hkErPU l:޴Aq[> UFVU^^EEyV+ #Хkw6_Jy K {=VI22!09 0L24I)Eؾ- zgU]Ln#Ô}-JmJXc0Ogd<~h)?0_2G\Z]mMo H["N۬зk,9M3% +8eV#"""+G(*1{B 5!' _o:BGç'wj'<>#)6UZV~7+ޜ`:8%C(,c┙Vy """CX+eK޼p/PjChtg|[lz7>H|0Wg̹et\]A$Dž.msei@ot"mɱF$\qYZfzDDDDte)>smx푛hPUۈ}?l3Y㨫q:o,Ʒ;liY U@'mQ4[ۆrXf. =Ɗ~ K|+Rz*ڎ?;y6,?ɱaXx>;asڟ{׻śelnb:Nv asp8,DPoDQ%.vJxxh Dcx뿛o4DDDDWKa)>g RS;? Eķ9r&dϗO;"7h 'dž#l%ɮp55B&5@tY.nnt:lv fi,iѕuEH?Ϸ XTB]hea$c4b<Ane xc$dž/mjy(drtc[_#i>0g LA\d~%8g*È >;_cgm ӱH!v=68esGcSEHK?4O qqmN#m]N vp;_)m]H,,6?g:Uxbu{ׁ4'% 8"9'hlvVk*M=lvwd#Q37)MX pNgDf?'E8 "zʷ <+ H ;_mW[s$NY؟cDRLW $;^YF: պ{@ ȳlEjl(:.ފQ8HO6c|L:zDcsn1"DDDDWVf,V;j8[g+x/& ]>vG& [|[B.k ubFp'v6K*M@im g@yMӷ0@^~3ttSC:?Ӷ06ö\'MSaΓJOd[`nuV1NTc?8 }:@Jc 8: MObaxJDDDtht?? `37:W7adWJP[Bt}MvulWi;i7VC?*M1y)x/+Q' ~jU~B-fpf$6Xm Ht:%)-U]9Q}|Lwڄ*( tOՠ]10:<;H 46Zҋi c{}_\GɊ0Z)?#HA(<0=L #ݯiV_"xJDDDthl/(Q=s.]*;W<>}izS@ׯ"u(w>I!6׿+F ?/ ҡi"""""""""xbLv+aWv Vj4_F-it6Qhx$nUҒL3Uw\ȴRcWSڒHymzgQ{~u """"""""""'&""""""""""`@|i"""""""""" '5 -InvTF˪<"V^*rQ.6&""""""""˓~}2njwwThZoGhHO */o]-zcNJϝõ&d$uTw{sڶr """"""""v_ 8hcU^4Z?,¼qvضn&dKVGDDDDDDDDDDWttj{ÉSp0i u6V+^?_kGzf©|twn+1٘z-O9ˆ'_j(I}q.nq|&ZVa[vSzg@RS.k0a|X?uG2 yz-z-xw8(VM 9ci/{ɧ~;?&_VaУ{7T7nL]/ľ[7X,ػgd[^ԛn_mw[!.6&Of@zKǕSoű`@mmm 0h@m-:*';qXðZXamvo8suض#w6vdcϾ g l6oGذi#ֶ -** ?8QFDDDDDDDDD HT=."" qۧGyEӶǺEJGrR"V]yy5"һWOYz=bc1|Pع=wڲC=nrDFDKDDDDDDDDDwH6_/]ՊcvRž=`Xzz!{>=qBv'0 mXͷy>=bPlݾfI/b\Y#=( [0q Ly6vY^㉧Q'aI0e:~9&NK[Ouyw onVLvӄqcQ\RyT/ SN6uv{ͷ =(ny&F QFDDDDDDDDDML+u qof42AXmZ2>|v؁ ~ >{+*?KZnfߡG Ěuѿo_:c嚵G״.8CTPf㫨$]|1sLhM\1c[n;Isqݿƴ)`o 蒚/_t{ ?7>xY.v}e*Vd/NNFuYE1v4FBx lE>a4b¸xl6`00maУ{7Pk 6 U}L,l޽_(I5i))(=wdGnM+=۳wьwϞj !ӡf4h4 K{ttFJrN[.X HhZkŹ2k_PRR}ѢE5k`Xh׫FxXԇᜣZm6e2`xiq$Iw!.63]Rn6"٠$hZh=+#IѫVcמ=uuS8t|tT(JM5tY]&+HOn.棡&S#>򫋝ObP800O`08,IL t^pPLF",̈¢"B|k']ҴYx>tchaۡ-//GEe%tcZa7KvXmV7 ,u'D'""""""""5 - M"j`+G@_$ IR! RUYYO9y[+WJsޕL6-U}dɦmkMYYҥ 7T8C=mM0@.8@tMK7Y\:=%}}a̙X|9WvvNKMEhH6n ƍU<6"" qվ۰x{CTd$6gm[sieDDDDDDDDti-%DmK1f㧟zVVX[mK1" i嚵fH!S'tɓ&++CX,Xn=ؽwr}fXM,ZvvB|N I=IjzJYYy :9ǎAr -55-EgQPpݺ4üy/#,,L,]1>c,]>k۰55#9ۻ7l6;^ vVg+HHu6rf#"""""""R=!hM =lfmVN "w,z?Z>6i[@׌Wݿo7}I>_.i2(֮Cqزm;vV$\=Mi\7qnC kF53h6#ivv{ dz>xGq:f…Xpa\Y@ǟ|W^3z=F _y8N3Z}CfH}YL;k֭ǭwݍ̘6˚r?U>޸?ХtZ IDAT*@_8N0w5OɓxyZOވd<:MowH$IuE7Vڧ˛ڥ ?p;ȵ Hw J]yNbSYtB0LDDDDDDDD:4 ﰆe/0 MDDDDDDDDDD>4DDDDDDDDDD HO0 MDDDDDDDDDD>4DDDDDDDDDD HO0 MDDDDDDDDDD>4DDDDDDDDDD HO0 MDDDDDDDDDD>4DDDDDDDDDD HO0 MDDDDDDDDDD>4_[ fUP㓈GjC_p&""""""""""`@|i"""""""""" '|nh0l։~|u!I?GjJ &_7 w~عhȃER^ai󠌁6d9)I ľPUU ޮ{k?޳;wFRb" . `ؐ|b9 Ư#JԎ -;UUU0 Hc\sҥ0Ç ũ|ZGD>Y[ÈƬ79c?Z$%&bڔɬh"ь 6l6"#1b0ũWH;X,g@9PL7N`U^ $IB]1aXfCee:uvZ-i)\z `4ϻïƍEhQiC؈#9GLΝУ{6uЯ?O^{FD\|\+dCSb+==z ?Z$y`0iS}`"kVcq$( Μq^XT@XVDDJDmG6***pͨSZ;***0zHtIKC8y* EDD>ueٳw>Z?b蜐yIIޭv;<ݮv][St4ni%@ި?߁v`ێ3CDt$ǣs1_m(lbBILN(/,:r T3Ehh0/rlGpp0+.{^fP#4 /TKHo!"<ee娪* k&Ib(Iho& !N}/`Xp*/Թǎ`@jJ ""yزmbcb  ?B劉Nù2"Up24Qp ޵+,DGGbɓ@|\<+bيHMI14'O\JһwGLL $I(,*Dzرs'f3$IBee%6ge!S'LOgQ?aPlٶAAv|W! !{_G.((.-$&vfC~CW`!Nj1p@l>#kVOlj'jZMh41.#nhhM̰6mFdD# ݯO8s׎޽zaڔض}8IDDDwl5"UTVII>t(!^:bpXaD$44]RqQ#FsBΝW h!tϹ?*z9 €4usR}Cuӣ[/|R;ZlܴFP` = 1:z ]Cp*/PBq=w{p!W<8I1׌FxXNVT(t*no\נzp`ߣHDW?SC=;"O""?DDD\ }A󫃰xDDDDDDDDDDtc@|i"""""""""" '&""""""""""`@|i"""""""""" ljg/;"O""?DDD\) #""""""""""_ADDDDDDDDDD>4DDDDDDDDDD HObݺu/b׮]>W^yk9sï#&&ᗼ*/rرc}Z^{ sNS?/q>u^9 ;y[g+y>p~sR~r/\˯̺yu_xtա]UUUG~~O2]R>v;yرUUU̼*.ш<'Oo6lF#z˗nǜ9s3wz/ưaà[333h.P\\I&!00Ν;;>gϞxcȑv<ٌ7BHH~ƠeWڗ !##7ywNku;էZt/̧z߾}N׺gʕ^_4BR+թ\թ'ϥ\էx ތA_\t^ ̡AIy:7yw곭]_x{RwrZt,yzoI>Yҽ>4lzd>WgJ\>+rcBOHތ[O(oƟcziƘR^yLO\ #+ꀀG}I&!%%'|^)ZΝnGZZU+!C|Ty睸QUU~vnCc8q 3f@z(̝;W67d2d2aѢE^CDDΞ=;f͂f|ᇱ}vƌ3 Iy=vZ{uk zZv}fgc=js=[`*$Ixꩧзo_ힶ\}|zگ ฎdBvv6"""0n8RRKrmQk{:k_:dTtZoǠޔ9ԝ14}/vS뻾&W~Iسgؠ Tk QTT| ?x:>|d᪯)Az>,ŦMTҘW? 2Y,"8riٕ߿_9ғ$I;g7xxWB/r)|_{'Ŝ9sjcНKJec^NgԛǓ9͛@>L Μ(k$wZ]ݝCrAμ摶E>ݝӔ#rPjCo!w=vRZCL)/iG>]d*EiR-Em>wwq5>]붬-BOHތ[ F^t}t=vwgmwY]Jk˽]eܶ7Ҽv^[?ōoDL_~:tہK<3B$QSS#~V#DiiBG^O)ͮ]iӦZzj"fB?P=zTv_PQWWcNJ{L466hϔ1aQWW'm&)嫯b߾}fM6'O:w-AQIDϞ=ł b=* |#F>X,oڭw-СC"44TfaE;#fxg'sժU{N̜9U @ Vi)էm{"g=ˀaaa Z5/0bٲe"99Y444}s˖- f57)/܀r-ĉn52>|Xuuu_gϞ~bJc^m>B{W ;T-ѣGEppxWEDD֭[kOʮO?W-{YYիv`jE>R_˧ZJ},"5jcPƒRXWSUSOO4OT32xjkڜݲkvW:O jkr[P16]ՙ7sR$/jM@e9Гr(]Oo+!rYwtWu&w=w4#-y:vOW6{犯ɍkw2MOy>PgJJo??y2eo<r˖-sl?r VU!DIIˀt]8ܱW^{+Wt3"//O>|)/gϞuʋZO!o+222DfffEJnBOoREn )ɋZ@w1k,ѫW/G=*#re:NTVVΝ;-[QF (4!?xW5egg ???:n:a0U+kllqqq&I,X@>H>_5`jE>R_˧ZJ}ԣG6Q1V~WcIrsR+թN=<<S>\yjkd[jZݕS*;kr[P16]ՙ7sR$/j}9͛trӆC hϝuWmNwӟ\lӱ}jՋ|}\?e7yr_i)qj<(ד H{>z;-7[;ƻڽlksgzٛռv'؀tC:;;Oٳ>7@PP4|WҥKfTT& "33HMMEee%Vb^ FϞ=ѳgOl޼nKllKKKURPPT:]j ŋ; ::~~~MhVURzDFF:šح s]d2)/qqqNyQk?|Gw^tnQ>m[_%..2\'ɋ"""DII}W_SSS⥗^lʕ+qѣnm2p7ìYݙ\1cO?Ǒה #G!!!i*yѭ[7?PfCpp0Ə"++K<->%K>@LL vڅ FŲڵ ;w<*j_S%|… qw=>Jwŝ2c^NWN=<<SxFirtRY:*Awƃ'i^4Wӷ_%Jk>wݶrs?lӱ}Jiz(O~j\OWizz}mTvoƭxPjXW;b=vgL{2INso窿x;6=m[W}`ɒ%={6bccQVV???;wڴ,_LL V+***Ab$ԶJ_uuj\}vhNf!'')))KMMNsjVZg=--M^F={두n˖}׮]ؿ-[CaѢEkKiYr}P/)sŊieEEEXv-}R-˯V*+Juڭ[7$Wm){{ijneSKSili]<2&;*Awƃi^sFW)mwtw?)sgm뜮t(>OnΝeO4=]c2 IDATQ̧\Ju4_PrrNd*9#^=9ϓ)rKJJRg/cƌxlzӶy:y>sZK޾@FW;\pM7zK!_Ze˖9^XߊVN _rSJS5",,L ! rykܹsECC0b͚5"77W5SPP/R$%% .ZCZ!{-Ξ=x;#l6x饗\U鰰0QYYڶrumE=gYO>?S !?̓!;kҸVjw@ rl;=ON?SJSRP*}U[NJSm QQ[w\)]Om(Sn7cW)/JTEi>jrZ)Jizs}m6z2nƟ'gy)Jut_<޴>w3=(7g+`w?+P_u@瞓}ݻEzz=zsxa4E~ڵk H+]O)Mw+W^bҤI^IIInϞ=+nVѩS'.&NJLII/LX-/ѣ #FOnBOL>]!ľ}DEXXx嗅`;~;v0o߾b͚5nR]ݻW :Tdff'xB;&A;vmZŐ!C7ޕ'Wo*?;r`%T*ZKxJ՞Tbzc\c(VU+JP A@ ᒐdl[[]>#}g:>}^pZPP}涱o/_\ZXX콯On|4僓S͟?_uСYYYzUW֭[}5SuܸqoS4yk{ѱcjnnmVٳGKJJ4--M{쩿}RtWjZZ~ X[\LL/xƠqm?U޽{O>CxK~rWbտXrk>04_l?kLk^ݔLmXr9!KG\bg^۾*vW=mOdzit5tT)gb^4lǫor4L94^Lcu}t]׼>ijK.c]>~?+ @ktW᫪M6-џ[nj*ׯ_7ww.㒕%'N*yn3լY?<|y饗K.9.4Y2s+s̉\wsw.Z(Nřϳe BY&0cC 8nΕznݺU&L ""^xw;ϳe iBFOY?.[^_Hi@\p q4 .8ys ݫW/yΈt]6lТe~2k֬_RSSe޽ H^^qp&eŊm<n;gyѻ5hc_6wxyEEEд~}Ɣ)St̙zIIIѲVwU`0iii1uփ>wqӽK,.}8qDԩȑ#uڵ]V ڧO---UUD¿_VZֶm9lӦM;-TzRW%f3];qu]ڮ];MOO[o5|gaÆiRRRT9T\:?o0;C5==]/rݼy>[ۧW\qE]֭OU;]'lذA^uliK~}y-ǘR,s+.2MusKֿ}WܢϩiS[*~隸zu:<3qZ[l[?qmnfz4&\Į0 ]ǙLuoz^k|prZ&#ƴ5-g_|pf4o5ڢҿ/uĉqkh4;MɁtlю}iJJi]xH\7ݻwCtڱcG Bk6c BkijjCڭ[7i`'x{ij{ky< _8هHluq^%շcKA4u.%׶[49u?mjcKXϼ^Gg6=x-~|Znʽb9q\Į0 ]瘩K,{~Z+'DzVI.ȶ1AM-g_|p\|  [nfCmTUuΝ/Yssscǎ:{fw޼y:`ԩx,**_ڳgO燯=#ڣG!C[o.׉'jW^/KaaΘ1C򴠠@~iuY`G333uȑkj~~~_6oެ LO~lqj߮]tر з~WٳuĈ(7n e̙byAڥKJ=ZUDYBKߞκDkaahFFF.Ǐsjaa&''oy]v}{:b߿.Y$|?y1h&>OHMXk^A۴i~޴FUOg#-[hZZZ{ѩS)ߙi˓K=]ʴ;׺Z]]fddw뮻mNbm+4W\tь߲2-//}_ӸUWWkrrrkkk5===6i`'Sٴuubz^,n…z}u]ÜZmS=Mcϸj߾[Mǒ.~L:5irl{Cx/6Sz^mc晭 ^stk\lk߽i>4W?@4&k}\1?k`7=O1|Z5lcGa扦nt mګ%S}\yhNs=Æ k,^7|{РGUV5#Gۭ3YTT_ѣohFF֪Et fffcǬu3fyz ݲevA?Sk= uܸqz1}w5---|.?vM7oެ`PW\'7nܨCц۷>ZWWӦMSiv }#GO_viUU[nEUU?Z Bڻwo}ǴVFu x._\{ǎ믿فfYYY3ӵoOW]"Ҷ7hР'wޭSׁƠ`Շ~999*"zM75)?_kkkTu2^'LvCgi/:thL4O[k=]ʴ;׺5==]|A^z>􊵟2J,eOWUTt`}Mcto>8p.Zڇ+~lvۺW1=5̙y%UOX=?}k[Mǒ.).2Mu3A?O [?y'S]bj{zmKkg2Msk5'LŶijk|ru }隟VWLŲ/tc~@~ris34LibGM0~Duζ>*Ӂ2W>sNȑ#u[nn P?DHg͚\k^`ڣG˗*T?ݼyN8Q8<_,X555裏jRRm.]ōfgE;lZhʴ;׺ںu4))ILǎӿ/;vdwM.=tS.]}Mn:MLLJڵYF/2}G}gr m+im{׽yo952iKoMy+؍f6ͽb+4\9= [?E{ m[_LmtyXLe<4\b[[ls޶k|ru }隟VWL cc~%=yc/eeg4ΣH{?y":g[b9Z]RkH{hDw ?qݺug4i{~aIKKaÆI=owzleo>e˖Ɉ#{ҽ{wzc]DDdСҷo_۷oJ_qرc8pZ2޽gL/_. %KVQQ!:t/~e^$$$Xc}INNvڅ֩S'ٿ>99YjjjҩSFu)wqlڴIn6ILLUGxڷKN$H ;wF5LInnnڵ kbgƠ-?#z~W>S5|pkZyeɲ}vk^{_ $O=رCmf)))tRYpɆ dȐ!-^Xnmj-~rvӺRO2mε.󺖖&`PM&RRR"իW[ǶWϴ2Mߚ[o'F5JOOP($w^җ$G k0=G,{ 6eʔ)͞cf844Lx1学lm{-k>IJyA5rLKkbjkLM3׶zf˯i5'LŶim&:tOΎvOl+ӫ}\sϢGc/.ut]MΣH{y"^m tK+~?I-Qܹs宻F_OMM`0(""*G _ܹ,^XDD.]*SLI&I <) ߖaÆTkZ̔m۶yUOit[QQ!cǎ֥@vٖ{G~Ieҥ2i$ر3f%KxuXڵ6l`lmV$/GSi>IJyhlڴx饗:yY2# Ҿ0\a3k&ӵhr=myT}_j]?\Y3xq禽mtYM㬸س,X<0A>2rHdp<b}eGYYfee5zI7 *":l2ܹsotLezbbΝGU/ ,"U/\g̘Z[[oܹZH)++ӂݲeB!]zuwHڡCݷo_=A}"#RZYYi[XB!-..f׿u9s5\g֫:SfM-O׾w]Llsl:jԨ?! ^QRRGwyGt޽6駟6{y^c|py%;w7'hEEN>]۶mk^J322҆ݴifddom,B{9-//r;(>}8ܸq߿_?Qzf_ӔLHuqk|RSꫯֻKw{ ZSSSNo]kjj4 Zcm*kZPHo:OmӸ?|z}G@?=ʎHe\*滦L>.cVOX;Ӗclcɫ.~r*4\9mO^qi}15̴Kkglk2;=ykk>w];]jY:j(3gN Ϙ1C;wYYY:`]b1Ley]/-((hjSl裏TDgmv </6ٳGǎڶm[:th֦k||rUO[LcƖ'ZO2MΥ.={DҴgϞy{ꇢS͟?kSKkMiܛV^^ƍӔ߿'qɴ?0=v L[Meb{Ks=uliK~}^ŔcLcT[{ūL|pYlcG9fb_[?yTbjkLM3^qiǴ{3Sߚ>SS\\Msud5&bWL ]昭Luozm7|vն9ydØm@ڴ̥> H^g"_Umni\]]-ݺuUVI~ZsǏ,9qDWsc K/%\r|ȧ~yz=3 ɽ+k׮Çˈ#ɺDҒYYY{ny'˸e\d\z饒U̽ B2uT)(( =zlٲ崴mzEDVK%##Cn&MΝ;Kzz|K_uzuɥ^*YYYҷo_yV^-C 42d!FѨ7|Ƭ5+mʀdQoƍ(?[}|m^1mڇ˸0ų5'DOHengk4m)Ǹ#>kux?5kߟ u3GUZrtk~uGp167r˞85tej~KӺĒ?Mtz'l9L0 ؎e皳)7ҿo+¸T>;y6}B!ѣ9]%\gˌ3>p/ Irr˲k.kU{ $555_֭\;vL6M֭['+V;wʷwޓ2[k3MetM|E>,sΕnA:$2i$;JM&L P(/b>?cmkZ+oy睒+oQ&N(`׽ rEm{4bZs׵c{qx-xXrizVϖmkSqG.}d׮Nk~k%o ]ǚ}JK.%xϣXĒc\rmnF854&Hu%>5OϫZkaWxGbDlMg1/`0ݺu5kքVTTn۷m۶Ν;_jǎuٍ+,,ySNz7Zg*H_hϞ=577Wϟ#h=433S o߿_'N۷^z/+.:c ӂ}}eڧOԑ#GjYYN2EgΜk׮|]nn޼Y DSRRڷk.;vfggշEEE:{l1b7ƍu9sfDxpvE׮]G|-,,B]~5.}{:뵰Psrr4###Ǐ[˴Kѣ5/r>wqGk]v}{:b߿.Y$|6vO~:鮻jFӜ7w2-//)Wb{tԩZWW^{MED\?Evטb[^mjkk5==]W\+f .O:}}M^6O[L[zڞ5lqaW?CS3ͽ2Hly^zyG̿6ykM5Ĵ=GޫLbhǶwɡ#iNh~_] a؎e`?.廗5hk{96lX-of{A9Vjv3rH=pn߾_|Q۵kUUUoUU433Skkk5 i޽Z{6&|rݻ;vLfeeeҬ,S<]t˃>L|p96էk׮ٽ{fggkyyo~H{y"ڥK 1 IڡC߾}>ګWfokNNtMָjiivM=7=<󌯱}SÇ7I&L]vY3?cto>8p.Zj~*i[;Lsoik]L9t_,k׸0ӫ}CS3ͽ2mcɫ-33Rm9umyk]m"!igy*X55ƚ>3ֽiNrV~摩}.XmWYf5O^uzjѣfddUUĉکS']`裏>III؎>}~RźT?ݼyN8Q^mw~Lm_n&&&jeevU׬Y]v>֘~Gs mkiNm^1mkz)xZ൞>qh1~STm,yճcf~)ֶ:\6"464]爴&ޫLb{|`{kozi?b۫x [v٣7Œ_]?L>}o6+Mcf^4|uuw隟mG\+۵k'n<栉ל뮻NnV8qbHuϓ/^,rKiii eڴi.%%%2x`YzuH^?|mC@#T#Gkx@jkk_ɓ'%%%E.]* .<ٰa 2D|3g~F?[Z߿ 4Hz)ٱcl۶vטhHzzBOҗ$G }6l˔)S_vWML1myZ Lj84XƓWʴ%\13A1o.e)֦14!=5?{ϳWض},9uEbڏ-gQm&gH>}o6Wlsӥoh@5=ߵ%tz'L3[b1~R{X>Gp̝;W.INNnUU=ֹsgYx,]TL"&M@ ;^y^SfSr7o-Æ i>Դ.)۶m,߫"`BƎkKAA޽۳-sG?ҥKeҤIұcG9xAIJJ>,]hھF겾6[zڞ5L]uU16Mվhɩ9fɫ6lLX [2f=z𜃮c>\h|b1m۶`5-oEztϵ]Ƕcɡ#k_=/~ ujK~ydj˾׶O94WLkn4o߆B!csYnjy隟%z1^:%Kxuc ʎH>|xwHgggkeeob 8z_W9gkTUuzWkCCzڷŋuԨQ^U}vm׮]jrҧ~8~^QRRGwyGt޽n) jMMN:Uov kΛ Bz 77ިZSS555Sm~>CZRR,.W_}u]ZWW󎦦;tΝF?ӧk۶m24##Cz)mhhM6iFFFnܸQ߯|xۑgk.늊 }紼\;Ԣ"%f~+or_'O#G#<ZWWUNҦvx SMӖKbY " [<:m94\rLSMlyALs+Ǹ#>2kۘ0lZ#Mki-7=ϔMeK߻m[Ns͡.c>iNO=i_]۸6eOc[#L13MS<4\@5}iLخ?MX+#Wv| =m4wmܸQ飣F9s4z3sΚ +V:6=Tdzf~W^:޷o~[ .@srr+/bz<iVyiqqfddȑ#uϞ=UUoV?~n޼YLSRR};v1chVV^tEo[S7mڤÆ #F~mӦMx+k׮ռpK.Dq_x騋MUUhǎk׮zqk1x2ٚ>Rg}6ӧ\gnW?\N5|OEnd_ S]LSUwO6ɞ={DҴgϞ>cjnnmVxq@IZG$)-}YDDZJ޽p -hǎޓD0a\RB>oc+;%$$!!AƏ/m۶m%11Qȁ4e^qIBB<OHbbȲe/ŵ.#.+Θp -A$%%%ILLL_e͍o 4i$ydԩ2{liӦ<2iҤ"@y}lǁ4`^N8!͓' /  ;W,OyaElt+(zy?ʚwޕ`PP/^ƛĉZrXvsbÁ4>}HBBiF.\(mڴR%%%%r{y\:u_磲e֌d*@ >>پcKFnm]AĆipG;%99IJK_뮻VҫWHvv?UVI߾}e͚5eK5+{d[WW'.( :9b˧{_zK\e٣j)VT;$5m23%;;++---|m;Ȓ_?~!O/ow\Կ,YsHz ps -{Iƍ' OO3ihhhV'*ҹdK]],sE?$n $%5E뚔|fࠡA$%%EBPՒ"%%%*G9sH޽%55U$k3(+oL/.7GqɜC;.iii2% j yɳ_f8`0( kr?YrL:U6meҩS'+W^{d…~~zrr!Q9  ED$))I44$!!Qz $"Q !rH)-$7"&Kf"'Nȼy󤲲R*++e޼yR[[+7p|[ߒ^e˖-?/QYE쓇_(mڴ{LDDn6^DUZ~ai߾ٳGDD㻒uFRq TUzu=HZ3g>whɃ妯8>Pxi@\p q4FBB442 P6@ mؑ#;zDRۦI }i@@sˁ  L T"$B\$!陒^[#[^N8&+ Je';Si) & @@$(Q& ~%&&IzFt).Y9$11!Wvp wi/ٹҠ*J Ł4! 8P:H&H(0|(0Zi)?/At1H8zwG["z Hi@\$%Vq :IDȽk%95ZLWDD$pw~{׾HT&7ߚHIENDB`gtkhash-1.5/screenshots/gtkhash-nemo-properties.png000066400000000000000000002111211431266303500226360ustar00rootroot00000000000000PNG  IHDRnkYesBIT|dtEXtSoftwaregnome-screenshot> IDATxw|̖N 5ޤHP@Tbް{Ջ]{*׆(]AЛ֙Bn6H /|Ӟه93͛v( z!Bj hb۱lXN'NB4K.7t{B!klݺ9DFEpPR\ R*Bq| WޔtR$$4LڄB!ı#"" lV:w,WلB!Q;v$//аnB!#""BtyzT!z ˤB!<+mB!>kC7@OC54ebR}9Zmd> q'n&閲71L̊w1#w,I<6)ߧs8j=U?BF3hZ͚LooxKCX nJ^CrIth$sn^"' Q/SvHLF'Si .7]GaKRE/Yf\RY⥪_4}㛢 m5m%!>7e}1ڜpp/??`~6frӬn}-Q& ]SUG2e*ʮ,q6 U%V5ǣ☺hV;av Dž#/5)͓w5cT+]}Sˮ|jʪ=?"ST W]3OURiPg}70~0,z?p0'0,Ks.ys\i5S,3XN&nTwгߟGwR`oΠ sȖb}>sd'FD\Kz ǥgE%cWJ6-c #:)gv#ztj {Z ;?'~a *10<<bG,ĕNhVn[3x>q1?ͮ{4ޝI>bV&l-x g6j#XS[Y3<\+X{4mN7~K6#υ%)]zsFPUe ?RPފ!.-oEHubN,}iacFMeY3w?]~<6&>u*_T*D *yo·o懙sVķlMbN:{J@lB&a`mN+Ӡh\DsxLi!KjK*;d&{M,,o_PU/),]jg f>+ NMpgaOش:N8N]In`khp}04 Ys<4›ӽ{[Jvlaټؚ})O_ݟ8m*@\XCu7CP]L'xG +ɕt:宫Dy)+xJCʂޘ׽18Zָy>Of֙9NRi1.J.Vei{2q o]:q'9\s',y iӏ-tn;.D ^ub,'bg|f=POHIcRolf+_ko;㠴WuZ F |ѓi`K_#T CC-WcBrשPexqn!,ժ[v*J2vl3 bmӋ?s{1*7V2Dܹxvgi Es9Z,1 <+ԣ.=9<B#W܄8UQ G4BBm]2⑗1<[NxXh"YRxU#cOg\(Azw;;餮x:PUܯL Sq8sT2n\0^8ηC񌊌MQfi{]C$k;^Ep݉[[`i|z;W04|DfMd)%`eۖUWyZ+B7!MlI3Zv;Y'FSvU8 KSyˍaLʯnTz䕗blzI`%{gك 7>چ*%7'L$@s⩻G&1!:P=`~f^RekQ=aY CMb(Ë .nvai?;a/ƂVzDUQ5;q޲<.xcjQP[)Hj&=s^Be[yHeWLW{`kjEeFK1rp,kY@ %M3t]kRךvdd>L4-iinM :Mrqz ټb;hnWS8B, f0gbW}Ji~)ߣTѼY:Yx~- @ueYZh'fxX>j5VW2U+*]͇oG7.̯=ޖh`'kJ9mjjףPʋk$y ozٯ#ϟ}-VzOzdg'6/6G?9/B\|4\(4B3¨ux^3*8Yog}zFaЄ"^zx6~ pϐh ~;PݽY?UV]9a3-&WKo3s,,yQ!=z!$i$gv'{)q䱧c2'QBk=s.|lON"ƓG,v;ph-Uvy*IB# W]}xqȸipbXfcauڞt6gukJ`4f|R(eBtoa"hhXjV,CRMUUVQa>-3V 4?شv_MӭX0 4 5 jAڦ{|mOj֡YX-z=o^/*ŪUYsc|Z\?>{?*7#=WSiEʗq+Y,Re(CwnקT|-+D`&/ 6#a]1qj*D Qګʋ{TהfP_W_sMV@}>լC<5Gϵ)L;`}ٷ301 }azhK}v} 8OW^ FTt^-(1D'tdL9MGB՗*e is~8nǴ%ʲ,[S՗he˛ LS2"}7T*D}Z[8SB!ABqB!}$B!ıNJB!$nB!A7Y*B!87!B !B!DM!"HH&B$ ݀c<ѸhH\3qWc!GPq—ce_8*'Kb)4Mb,KՠB)EqQyq:J+DpX:$4iFdtLC7%['P\O6Ic05ib&on8$Ǐ ,.l/AkL$qA1f{Y=ƥt.vt5 o'3UOߏq ŹgowlGw &Ř&C_ƾab\ow<}<0 |~O<{ BV[4ZMgˉ!`nd5-ҫn_GF Giځ{t,ZXuE]?6ȎQH|Syע2h@C7R!I| sRE{.\ X9o2.ZK{|7ĞLjc3ǹV^YR,x,W5)D4t6G"¡PU~ĸF\^uJ'>)`Z_/7kv㰷`9s5RyWpzW/ Ꮻ^8{({U9v1'zԛ|1c@|8%^w^o ##/駶'[.[CVn!z4:s:4D*]ƻmqp b1{}]4ŋL)}(LJn~!zʹt )+ƻ/м35zӜIjֳyYֱyOn<s%z_Aq?Ym`R1>(Z/@t,KDnޏքcpDϪf14:Vz/@{>Zt9vn:du}sv{P$qkL>V.cd4'?JxH7=5Ő Sdn"CY w+=,O7o?:D=Ѱ :# 941fϲj~?ٻs-_ၡtsKOn͋hY*gg~Ei@]hWk[Ww{Z]Lv/^놶qwoz]ڹ<f2d'q~oa-oIxN׫6v4yvZyhvGfNx^ZЧ~m؏uhz*_ۈǩ"6g~2]˙F.Wm-/t/z"UŒ؋Z|Ǫmy*ۘ8LQ-ng^Yŗb]yd"Sۼ^nwW5ow48miX}6Ǿl$b>ag2q8"nWPZ4NDp qyڝ`ua)pu]|e&gӯXpNOQcMJ[?stca 2ɜ:i::Okc K.;'c_kq@g4p@eg{"9pc[(' @x+`{&w,\8Â@o賆)ባ*ko71 ) !jVߢL"c1)Q 8N:k$RhF=Px ]O${$mFJLR7E+%=ٷtʸra0Ŕ =QS%%ĉޙC#'(iDEBi$iX1qD+4c8˘Ǝ%,(Ť )Y5Mz1it"Vnm`q3s?ņNXvF̾%W| s1y<;.-&cIxQJ,e×o+Q`%yp ,/ioƛw^FہqS}x3?N4Q7Jmpy`d$( IW%:uvRjZ41^T*UZtӴV0 C-VLY{j (Datk$E*C*ک-<^#`F/jQ1D9ꗣMs ѣ^c0 !p/E&yMM}M9.0%gS]I Vc9-&E-bCe$*/؈ bW=ڼuI:&~O}-{#vv~=ΈC%[#<%F~'sb,X<9+s{IЍ-v0tz'N:7%67=hP ^0Cm`:(u5!Xu}m;jQ|'x}l1{6`woT.zkz`sH0vK}i>GX:tmd"zLFY`g+CNtoH#_5tab]`b*xYRpZ/2siyE璹~Y9kkV{V1''12t>LiPsƨ)X|+uͭ?.y1CU IDATf.ICT>s̋Uė*O粮(Ĝ9 >2/ºЧ.b5-z$cGftZļ/V`AGGizd);gL ]ǎԟyy:5>Ҿ| 2)߯wW>a+F 6*,ږKh1a6t]G‰ +a~Gh=c"$پ9a2񲛋[psYč?\OlhbWRYUi:?fhLf\T\xyk{ -ax01 ֐O>v7ן%ߦ;.AUX5|]81d {KWzZ^x1Ο]}\ nmJ~uеWn1y[`.)wUU5W%.KQ,.~)/nG1:~^: v<%x]2ݸJ޳vLw1olj{7`(xa-nz8 6tvq $qAj|j~šĸ *+bDQ8o1D /a| ]&OrFm|(qA=eˍGjX!#  $qBƋ2Bԟ$n>FhHI|3~hI(B$[ c&.9mc"hXFD)t]>Iܪ4аpńGF5tsa%hX0 BxJ%lCL\y1#~D(-ifH-Ӽe"9,IU,V<@TLfջEѺ]KQ7NezIܪit,J$qBcie8HVCʼn@44I$\NP q͇ɛ\mk\*U$ĸM$q @Nĵ !#S!"HH&B$$qB! !B I܄B!$nB!AB7!B QmL]y!B!x ~X#B!|[:RB!DM!"HH&B$$qB! !B I܄B!$nB!AB7!B !B!DM!"HH&B$$qB! !B I܄B!$nB!AB7!B !B!DM!"HH&B$G•8U !B? ~'(-!,u%M+oʞRVFQ:fKf.%f:i_"\lml$/5iXYyV"Z }ZGԻ܁1R,`•tj5VZRמT~3"nӃ,THxӸpH t(ْôռ} 9?ޣ:q, !6hf{w|Uf$$}7kƌ N9'k3uW84g9{(M'c/K,jٖS.֚OGbz~6ܡm[[^w& {lk: ÝM~i:u.ՉKJuǪ, y{:c;K{D&ԣfOlXƾ]1iդN2J5"7+bV.+$NrX.[6ny.l"ixѼ&Bc4qS WX7[9< Hdaw"00n'* )UBh7l"c;kl(%7':.{ i2-.rR {͗k+odK˜3`b:zRorwncw)ZqQxW&1{@[<1oc==-"(y]8vwvJZtwƜ>D?|oRuWF >ϘsJh^G{7!" l]i *݃ V=9!i?ױ`:@ݎǎ[tZ4͛4J1jy.IJYQXfCzΒR @kFS{euW\Z% @%`%66 R<RŅBXhͬV*u`ze{C CK/'3g5_E%X:%![J-M{0c;3ld-{YrvU&{]E+/IRW:vf^vJyp؝;ZځꯇFayvw~MwWu$q0 (4!T_B#$"[er~zM"[PZFHx:-*0|G.58m&zx,?B1nB!DpM*;gPيR6#*TWbG7GBμ}lroҶ+3P*}b8l=䤤tC?3+ĮU6)tLgc:~@YH针]۾^-z(.(ԫC!hiҮUGڇ`Kz~<2Xާ 6M,KٗKsH,#ޚq܄B愈N1,k%haFO-kY<0Z aD#$ބ'uIGޚ RŖ#:\BH݇16X~}\B iIc 9a84?yURXZt> !r M:GZ%ѐ6 =mEL_kٜެ#mc !A@;u>7nL]Ik+qG^j/U†y $qy3JBqL:9еW?۾7/8JEcbOYamBޜٔE M[HIڄB*$q L#"!o'ue 'mOzЏ. !UI&N^8WCC!8 B!#I܄B!$nB!AB7!B '8JBb'B4I܎ć !B4vT*B$$qB! !B I܄B!$n0߳ oC7EFWϖwoK14#>!8>C6^nοWx+4 ]ݜN&]qP>M CӴKU8J>bRV-f- x/\}k򺟩Fsso<mJlLyWVdv8B4~*WE%oqąi4lJX?k:cRI1GpaZEfЭ#U967tHs6Q>]It _.%w2>q9=|ĮfAW9~T;#*DL|Ge,{>༦mplk=KzK=Y(zN}9 ֑75\zc*w|]Xs79xӥ/nie30v q&0VM*3s`4ƼY]ԼFOLf:>OaHٝKN*+`?ٗF@u )< dIo23bTBjOTiIϟgT`(uzP+_jߨ{1*yOuc}ՂVV'媣%}?I/TF=^@H5zm,J>T[TD:梩?D:-cUr}[TQ IjUZ5v>jΥTp]5i:Sns}Yg_lk#T2+1 p\597.;9 uQN?+zTސZ\1O9ITrHIs?Q7vp<+`.ʌ-y"fpQF}4no I}Tng=?.xK'#'_o)ӹg23h{TWճ'']=cB.z^MdSU; G ĶLn ~3TZltqѳSG+]KߴDjWSuJ\8&Fq+H=vZ?΁'wv[;}]|Yh8fvn,9H&G W\ӭw2E7eSO@ !1ay )X_Mz, 4IL|7g<5;ODҹ|!Zl=|13_܃.솥xoDモi~"ݐ/-~ 86+W. S{ZZ^~v\ 1|l)M~bςgxa^fq% \\+.桇Ϡ]ڌCzҤ^[uj\kWG֔aϢob8=2%a=FuW?u]9JQEQyFDd{]\\!DphBI~L_Beu\@L| :!t?:>xT8Xp3#EZWlm'u|ۻ{Yr]T.ާbHBlQMIjJwR>՗ekuWrmKócYxǸe4zX@d׉\xVOVeIDŽ`DP`4a8[LaԸګ8Sg?Ry7~G6d{-^ *&(:ƨ*ӹQgu("T % @QR\D{]\^wBp1z˳]Lro>w|5ÇqMsM KfecBم1ѳq]h]%Hf-Hl5ScaxD)/;ĠJn[yxļy^Lǚ˨un׈w-oymy{ygb7 "Vyw5qhh)9 gն#\Jݷ#y{7ɞ4е<G)`ݣ15s Ļ9| X7=bzW2DKcTq!͍eWUemۍY'7SVZuq.ru՚q?O/3ﳶ2xyY.92O|lʣ`޽gi6`ϙC6&>o~_P+Iv-z9cxbSF6b.ÌG~"T`߆_nY=nt*tl ԯZՍ'ٗ޼i8.Ը֚'u98EKXd2[zQ]ܨ稈Q\tb/_OlLxT8(W$J'uJ]\RYUhtsiu󿨌̼ԽVfT=NU^2*X/Y:$5[S:xXͻjy7G q**4{+7xaMW.㰗)Bqf?ګm͛w . !B$qB! !B I܄B!$nB!AB7!B !B!DM!"HH&B$$qB! qTxXtg YRɳ].ےf}9 U4rcgOq'IL<Bx|k ;'<7fU;tιD?VW=7zJ8.p'mGJ~};v\(I}k'.,N>g+hb'ѣm"CBm;)j%51)͈y\71 M*,Wc;gpBRw??Rc#Yqʧd8zmz*X UT8mq)xH*9\;~Z]}9ū$sUB4fD>%{."gB>wm2 Cs8PFX\HߛɚO@1;.,d+?#1/.`{v'5ydƔtiq >#Fx/YL+hGaH'enc`ړ"ZJSkB v"_GRzw>L#OfL<{J\>!dْ՗ב{^6fuV}@C}ŏ-%ʻKЅecVˆT^ wUT EO$IQ6g͸2י +̶F$ s2 rZt>vNZ'[EF&dEcԕr  |;-[oرHl®Tqv_!2#.]F.c81"?%M'Y:X~p{kc0Pv,N$絹J`yk=.OfZ_[#8,{ ^1R cXȝws=;#vxs> kc 0 s7Otr$Dw 3  [c,KfL<{refaX}W#>ܬr/J4iΡ`2?0SnR܎iut|UzT!'~pZ Sy]ü3ןHCnRxuKD NjMv""*I5)l~ʭؑIQ<<ܕB+v8sAG;ǵ=1I*hIy 2)Qf(/vѪtMTd$0t|]6fsl;uPJmNNK(A_JfkOgn|OVsH9'>H&\HaSvQ^j{-ŕ@ew>}n&ەw6xj1;w] l*G(A̦Hd23Fn[qUkGND'<16z nptd! |}{] A@G.i̛wu?`Acп[{ŲwDŽFݫy3':UgN gnP!⿝]CЪe ZR )Hݍ Ehh(BC;Ky2ɓZ0t^Rl[ B(l߳lf69*H*ԕFX8:NbUr,1>*VƬ>E䃸W*5 cOǐΊ+@YUַ'Oq`p?6NGɡw_}bNźcFO6.W`{IHHۉw` G4)+5 z}c% ecex+<[=/ 9վʯX=g8þ?[w="j qؐpWRu/Ϟlkґ{IaDJZ!ti)r ۼMء Z!.\x`ŕPv_E5fC.Ssׄs=ョ +Xm\,~z-l7_bl䷳J 3$nXl\MCAEw:wCk~&앏v.^ؾ%NMEF@4Rh"-CqGp9-E97qQ ̟ +^+?QHV4 c/"?MsIY(,?}E[ x߮kZ`gk.chܳhgOEg7,Aw.Cͯ‚úhMh4ЕPG`G- FMv_A{n*.BCڵv5:[Icv,K0y ʂ5CfL\d KGe .ci|g k)g|g~xu[Vťb= };=OٗbM8ܘGVڬt#?X|-aۙq%h 3iRDKW&{6cR[ RmBm'M͑)gh |~/QpFY}+;/RQS̢')=YRWJoH^'o9{cPXp J=Hp ϐ^4~e4Wǫ"ҋ]ޭ *7F #W;R(ȧ@UIp7Vlw*Tpr ڞ:?ї6 'gn97k=6CzsM_֒.y/-эܜHM!=^!3O&?2zǍ#:_P_ѹg\ABL5c=)k=C%tlwYf+ilboG-џPtRNf;/Fa&AdrQw% >޻Qg8c @ i@ ys7@ fX @ 4M  n@ p4]xwz L~؂4 [;`d/? ٫Y ~6zPS>$hu~}Q+_@=}(_­y =ů}$S`$/#]>vaK)k qX #_ƻ^jejV`hglk 'T:R/QvϏⶲ*f_dwt@gWZl9ߧU$} rH|rͫ9IHm%ȗ4 ᏹazgzYAs.âJhӿ>3l;?Ф\<PR֩\] {|jU,8'3? rppx>VѡeVxY7N_G */?cKHwS6:.bA5 @mcO6|11o~,J#'ױ#_6h 9ԕHXKNp#l!_.G`(rW{ 0(XcW 2k+jud|ڹ`wd̪'~/&g>J~GFع*V"mf.WjAJ|;&f{&gaG}]^ZX_? ojsV@Y1S)Cf"%5~(:54+֭vX29te.̜ =qbBtw'|:S3:ق#͋X٥G{z#\qC\)%hPd/aAN`ta CrX%9>vg-H`ִ#W6h 9}+&p*VhTzjXw;J F:_n^-2+€`4tzBWe`ӭ ԥN}vZ:Ƞ/ŏMXoO"CvqĬ ^Nk;gb;{g|>kEXO: ܼM-u}/猘a/G!^,CS?!1̴-s@k88W'Jǵ#u@k8}-A:zCn.hv(l1=*\Vu-#yZuT鑭rT]XbˬdJqO _}IF|a +bx#']wU|`d_ja"8vfkY?4\`L\[s#IБgC9i.VL儊++~PWRq &p3iqQ @鑢nWn­qt 8s.B:*լkw"zd(/pP{`nz{3ZaEXy(Ra\P:a`g\*G!{2^^ 8C\2[[ ?R#cB. &'ux-Fݴ#c'{2aeofb9#rV2+l{ qŌy7_@kk=NfWLFHá5d@\a^6NW йVDX^Y~ \v'ϋ;V?1bV-|5w@A0#kGXbp9q:`(+NWu31,]}(KgM50;3ӯ3G&R`㚛lӑVdJZ(CgyX~Њ/m0gX4J5X)QZ䉭s|+.Z xǷlcs)_7@{O6  KrG<|r2 7dlm[HvmOfiq׊ F"ܾXj<%!K8-F=n +qu 眉ת hU ];N!_p{V:ՅuEn%QG>1ߤiA:8zg @)6k1-ZɴHl2vqh 'G_,;Ϲbkw99컮C{# n9! :vEUooWSn>9;f aK.r3lK.Div/[(uœ~E$CV_C1|&JzR gו" t@ _(!K' =bvr8Z!op1~cuGl"m04\l= |QQ^ C/*o.XqӅqk*GoIvdzyT/ֹ;qrK&7BNE mѣ xYR[ ]g[\5S) F䫌U>4q0Q)zټ}o/zPΉ,=3}n7p|. _~t1.2BNN) -EA3#n_+4]n :F>b55 vp`.6>vC1GrUŝK6N$o;gL}^@q'bsŹj'jj1w f_agu'> 4@$$Wfs/RG= x<[XG`˳)GGuLJ2k CvfԂkk<ܸؐ/m0*EF 2x% >޻Q'S_#.E/.jc cݴx4 v6?\Gi$TqC`e\?NqnW:e93FkIX5ʧaH!X3^iXァA:`ٍ'a$ $&"v]1R!?+_/wp{,KWz˥Ezj.ڇNxR`'Oj IDATƘ -_])j!ûC!Evnloyrl/SӸ~"3Rq~$7by{=bQ} G }EBv6酳ӳo<vrK`bwWS\odIǞE))/f$`Vv לsf즍AUPruG'|K vy(“o4WsbT EO$IQ2>&D F)=͔dറ2 ! '{ϖNfӃ<;mjSa:Nj+~[fK槺ki> sC5ǫ- h7 -ډ|]I݉^$2Dyym,ŴsU\_"#Fx/YL+hGa㨢(DsVRJӢtbŮ0R֮רutiwe:uS֞쨤/¨T&Bn.!/ekZJ0uN2.AMb:'wƊ+@<s ;-[oرHl®w-/z gSgKY*ƌSKi /vj 'G ,?-ʎʼn66=Z@>oEUYWCe\U""aQt2Ҍq cO+D~J N2vS.F?5*wE~*t^tDwn^XG׿_ MaǍ/X'[+)\ڙX'ВGd jҖv4gS9&H;C::RՉw'w8}ӯ^ e'ZpRSK +Z3f\IY;n4aOխsIa>W>Grr﷌:w݅:̋R"ҝ:(Pd57mNNK(A_{tOjw1xr]hM\=8ɕYjI2ݟoƛdZh 3)=&]G%c,[Tl݄^ jK-%1g1ZG`tFicªsm )Hݍ Ehh(BC;Kؾ> N>xbmzl"c-DokTlVݘҧ(|JtPFatKڅLߋ mjoCSW=4<,՝[,lɃza<*m 7cf4zYhJdކzYJQw_^-ܴiv {jY`+m:-x:]Hp"iΦKTuiQpueQXE+&>-Xvu~M/H@;wkC}nKծ?h.dOJPC/#{!NHMRU)-G<^|rp~-&PW$/E6K殅1j,8DwP8gH/2+mǮ-׊E"%#Q)])Kx=2b=AHaI̢jz|_#\CO͡cBj~Uj6yx%ޒ\޵%=:(7bRbƦٛڵ} !9W,,՝5;㗇pEF 2w% >޻3m1@ 4cMs揣йɶQQM7@ A]M  n@ p@ h&@ A3A,@  b&@L 7@ fX @ 4M  n0fwG["ShM2vYJ]u7`B?I 4>_kFYuD=aFa.`i%^\TWPvx_wStc "gEVpki42ES_[}.m-hXRCvϯC6IW|[LT6\pjFj@&F9GQe9Ű*E/.jc 9V9QA>pn}RǗ3i)Kџ'?n4u,N\I'w"5/g:anpy@;zph ܮk#9Kz\LK&b=f}uR ~Q?{*BN lYZ _|n_)*#Ȕ4nT1 8дLtҝqu2vvO βoӠVVQrKh3"}$ Z>Dnz},Tl~kh:ú> 8[7S.+tmJm(V2;e7-' OⵥêQ>R2B V俆_HY4 H3Ҽϭ 5WiqNh!,.. HOZPx]F<]^K,qC=ua"2rMG15B wN[t'ВGhئ? 謮D 9^I焐a4=. sC)'}~ya ^K&Н"Lc,KC7Q8I|:4O=PS_݌YۇkkOrvTRhaTjYK)gŻUzXHH-yyg;|Wyį gu1}]3/滬ιO^VmI]$OYs:ܺ,2r5x-+ĖHmާ lcb# R pbAWy{YՏ$h3N!. "::VUCke{T>XHlksѣ z\T5L&6ˇOāq<)qnb'8ʚ /Iĕok=>:1T^8q~Cƈ=rFݝ0bqVKvܺX9b;~Ȉ]1sGH}^nN2`gdrDn 8O;-LS4|fHPDW ,=\Frc;|l˰]|cJڧ7sQ#ye.sgY%G}hbzi.#82a}bԔYrI_ϓ}]3/&[+e0{ř@"/̍+sƧ)V5 ${k%K;WZlQPڒڎl R>GߤtghQGG:Ǝ0SnR܎iut._ h r+w8}ӯ^ e'ZpRS&OQ-i%Nuwbw 9?TZU;XO&viž%{'_#"2RΉhd;$9Rؔ];jIQ[vsO]u~WsL$̤ց(ZSіGRh]`1V ]oGJ)gSPT _e89E,>rlǓk[ꓷ䯁ɺa옕:7{|wEE|HuѓPFC釗PW9%غC1jʎL6ƣyqjpmpt]'o-j.ܖEf^q} x=8y# y0n+&L+W6xj1;w] o fS$P_`GC歸ZB`tFicªsЃp+/QQWz ߽: _W[坭-AnԶ+Ů st Cy}|a4Mzc*D0d#7ut`^X1+L4!o*/*l#@1OQ4 J1dZ/pe&$<*FU1|7!=i# Ehh[y 6"fe"Ϸ5*_&qD@;F @vv Ah"N,JE\x>9*H*ԕX8:Qf l`[ƴϊYs1]#%G:8';>AO̿^/v;\dl]Yr`Pr#Sڀx43I5 O^V uWqMfV[ߞ>^čJ`Pvл?[gDzNdy4D "V ˆf=,B!^{#KYY$$yM977blH?z-?wб̪/HIKKA7ũiܺ{o9gVj TIeNo_f uAcVFJ uT;l$m}pueۇbaG\Ԋ*Iǫlyٵ77En^1}(4GhҍtJ*kTx;V!羡q witJO/?Ҫ28iƵL*(H S/wWMhIVZ!mv0~~Ra][?::;/|Nd6#+OJOѢG<{NLpe %tt]|mA%\Nѧ(|2L|iS#f_ó)k P ٹsng~2K(k\&U14mMړI"PP%0JI.ߦ$7RZCg5liϥv!"""e{Д\>75 .jzλ-͎)`8DZ-/$Y9uR1+anV\y5[n~,Rjfߠ1ZGmҕ<ّ%ܮc#.<|_'/vq綤.2=xT$nhZƳҕl޽ :oM\㤩92lM^oӁ{hÁ  EWFSOJ7V Pk@DƼhajG tHs6]K.)(ŎPݔfHi t"g@zl_yǭ:>uWt o+ilboG-џPtF)jr |M%#Q)])Kx=2 N]S'S1!5,cʥd]#?n;sfojz34lƇz瀲%ɦ 1Z3 :ٓҿ;3lo$؎#Ӷܘ-?n4b?7;-OEOPk7;R{Rhcɪ-CR|Ȫlpr;g ]>wǪ\y;EuSθc&Adr7Jt}wh)@k3E]M퍊j @ "n@ p@ h&@ A3A,@  b&@L 7@ fX @ 4M  n@ po.~pwkg=n^ 5F{I?ØV><8jc^?m\͈#ĸ'5 +pK(JӇ8Wƻ|^ǞS9/:򄓭\[uǘOaֳ~=d2Ya3e<ӥ5\mV>u@78;| p٩iBqnW:e9?,a IDAT{šg{ %9.m-hXrp?Kp]H-qň?$epXsR7jFjLf6sBU6G]{~Iip^U:ջ 4fmQ߂X%!VxU`߼EӤ[VODj^&h&jMz> Bqk\~Q?{*BN lYZHUn'P9LNV`HH@ߌû{ `зiPP(%T'a(:$M:r\`8ܺ{g㧉c (`EknnEpA~.Gz}b;s%Ȋ[}S0k)wxH> &a 15G_o )h\Z¿m0ld][8gǖq4+S}o FyݡTjS nIZ%`wqϷHF7pv|z|ó)%Ӌ+\auh4(vI@&mZs5Rv{(DFU#>56ԝYHNiKNZ TXgնqUHv!+ir2eYaw`<0ą%3CC3ZT:MwG85;wӫ^!α 5==|'EȘE}8$gG%FVڼ4'Z04\HH'm$ja;¡őޝOb(HDQ4;VBӢ|ˑ|t;OExMfrkȥBAN-)00QNvԏ>=_orv!i(l~L i67?I27#ytR[%6za]Q'Ӡ(BIm Lo=:[JP6}&)Nkfyym,ŴsioSn* 6PX& ufc5&z>kjc3.g7Dh~̭"#wPqݢbJl9/`1v,F<>1+_ ~b~ f}a;˜q q)mѱ#4M ɗqUEGѕH3!|Anao h|D &v̒~ϺX9b;~Ȉ]1sGȦ&NCܶߐ1$iF;8 8Pv,N$絹J`yk=.*D@.s}#,/Nd ̈KKx6b^1+duhhc5&'oH'7o46*ff27=W; rPh ;nDD%7o B< [yxT;9<7F"ZёzNqǥ-̤c>w7Gw8}ӯ^ e'ZpRS< ;n% f?OmfA9"hprXB zSh~x;z縖GPd2scI?s~֞Kmߤ}3Idv$I.s)(Ŕd6x_Uɽ2:VBi^w0/J-ݷ6BVxihXW& DIQthpW 5ƌ/5F 7WS/eO*g5 F=Ǔtu@oJ𒽓ȯ|g]/ Mr'?;*ߥW)AAEEbOPS&15hLb9јDI,Q*-DĊ5 E:eݽ!sϑ;3|;whJ/++i5%T jʬN˧ڏKu¶os?bD?n>enb]c_|sv Lۼ~:e!/8fĩ68MT?.AtH!YtA``;\ ݃JZɵ z)čqA0|*71`X˭6~36;M%̩ťUs Pm>h#sB! td;Z~d)H=ݼ/x} QwsSOYũz8 V܁ z6 p6X8?<2[0M"NEc]:;=\o cghj&\RROmlc[zQNbD?Xj3|.Vm p9Zu{} cW0kX=6I}nnJlM9OyQo(/ڃ7bϋC%IBdOCD04A*BO&ď3x8#rg00ߘnz/_qg@{aa>\i&L]i'h'kHcidwtݳD$5ەު[=u(YNk&WyIU/3=q[M,^(b@]0շsm^r@[} ;+J'ǬqגݓҊSM=VQW]ƍ!s/@VvEHIs$-Yp\#NP0%>ӱʊ_k Kgh*B3,tb+mK jr\'Ʌx1?Bc,b>a\xn֌I}CW^^bMCp~KPt|ԥ:h$czc]7acQ!N .1 pr,} о󸟖)s>VŰ]T2IPVV2$$4 Kf``xP!}Tj:Ə`S$EA܏Xn0@E(1sC;k@[Qb}owWD"@Ys٤C= {#* KלBr Rd=cW,/#tUHIf 'lW0aoڌ,1$.h]BuYaY$`c]ͪ/*cB55ք:Z0DpĄ;su k0E8i3b_ŷ͈QjMj7gBqK~x{wQ7N5a/0`h F}V,2.V7zQN? bDc{,OX>jK5Vmɵ>_;n(`š Զ"V>hf}U*Nì킋T 49 : ~ۇ<yR(JWI)NВ7: ZS4/U? еd|Dh#5T.FwM/laJhiӟڵF&9MFNVR -|˛--Ysw=uwŗOu'$݃l,ڑS򣔢#24ǒSV}F,8.Xa&osfphp/V׹IԬf_lky~=}B&p8?MCi_>]|ԖlJ9p8lp8np8Mpp8i"p8N/8p|p8D 7p8&_q84p8n"9mcM˶FO Dy!yOQ[̖FοW&.M%Mv A$A$҃5텺rd1%" }W7}n#s8zł}QPZ45bHE?wSe ?Z&÷#* b@tji cX1_D!C)GcfwXeƟAc=jif-`q(R*/ۂ[fv^<,׾>\P+ؘ {TǮ;MI%m__ҎK;%J\ۏԼLݪ&VOU[l=eNy+p\0z@{s`y\Sq緹s 8z †X+NmQ1\T2h 71vB"$:~6↖Kl}dQDԟ#188 }_uAefTqkTkOG8<9_ޒӸ8؛_[xϾ%GyT~3:Լ%:[sS@'G \SW1aկ`.`}}'F#eY -(ד!˷-AVZi?Wi13(=~[ >;1Fm&# ےо$Gղ}M~agjǂ~1Ss&Pvԡ z>E {yKVf\Аvڶ9"Q{.ȑ6Ö&b!!51!ac]_@Up*).R{\9G6񴲛)P$:XRDr֪d6ϓwP\z>:ǟLoA$7iEW ؕ_8Bn\LCʅzNB5BN [Y&PQd1leշ hGŒh#In_/,XyNy.M${3=2kAm7wщ&;jfnIoԊgi.#>JItt&g+stL﬋LZ#{7[GS*&/˅4*+:HN]5`3u?%AAxopT{M߬v_qV< bSZk')_LANAJZ^yݿy*:cǡiXU\Zv1[װvd\iOŶɝa!b#K^]uWd]ۣ]bt=29J` C-3 Hs<]܉4'QJ?"YN]zaӬY~agh@0/ ̓-1p5$};{ $! g?m>@4HOMaDuڄȈY =bB 6h[d h.T&Wuh(;uԀ#e`Kaܣ Ѕcp),@Vl>܁Z&>#xOmlxIWƳfH*YEQ9+jƮXُ%UN$N:7 wxZ͈,YՀ tD}ƖͩyÁQPOR')j/94H[ɱ)ažߐ+#bYԃFe$ 2)=o _ClGm\R;]1QV[Qdu%KsiΌDzz'2PTrAۋOӬ6є^VFgWk=2zkJ琇LRGKq7^FSWSkwegZWV3¬/+/a_H#hV wݒXZݎ>_L8j!ںWm~Dvc"H8.x=, ym:ͅq ig +u?ǥcmjr:iGi%T'-eEP9C74hq1F =GP~zz!g`p-t+uaH% T0kk/ ..Cu\l 򎏞\u>7ٍA{{B{<[WߩHnmƂcX -b8H2ґB5 29BqQ1`ns@0/P84HP*Zg n:օCӓ=0eg"n 4GKw;;}cxѺ/؊~Oq`|ŗW~agi@0/Xڱ*-31-[s$~N(Dq1 &d)H=ݼ/x} ]<"mNS*lА:CRCةc۬r\Cx\:omsWC.t[\Φ0qy gӓP&P1^ _hV mpPp!Qrtuv+{[z/1,x՘D0u[ fJ ď3x8`Q}|+DJZud:®Q@Hn tO"b܄KѸo(QI$! 2.{:H/u{a١#\Yr\vL F/6)ڿ"@yYQ\%R"Hs/ ,X" SWbĮx4 O>z FYmKN3>߯<"Dh 9-NmުG9/YuVqŠԵmq]ZֱM-rW X9zDҿtӜÓ7F RҲ\}"S]Ю\.)CYYQr 9yz%lMFwiz_ú?❄1HTz_2eA.IDaX7Ã*(g.͈͓Cn6#Fk-71!{aBTdWW5hPEl;,<˱lsCv|E$K T1T2IPVVu%[qH>`Y^F趫ȑl{ :Y]U.lObnZ> s鯦by0,}F_~[OdA@-ǟ+&^*C~Z XuÆw|L}_X1-U%fnha ȑuz+"ʘeRưw0°t)$ +E8v%,=y6[v^2ꟲSǶYca.tVn2F`8ߴ1YbH2]@!N_X79vQ+t}qH߄{?^|jy{pvOì킋TVA9 dGifgkj7)Ե 2챖J6R_CQ͉н5DqE.]#"GIӫ#Zy47#CC3 Q.Dヴ-orfݩݕ_IRo2jU<2mNd} IDATڋ&ﺒrF+F 7 v$>ЊTމyQO瑚/P޲򒙷u+'Uth@;un9MF~Kap93ЅJnӎineB6hlf݄rX5߅/U:wD4|0{ӷ._>_mr84ĚGmٱp8pp8i"p8N/8p|p8D 7p8&_q84p8np8Mpp8i"BO /۔&NL[ >mPcBk$g1Mw,j\~m4 -/ƱpªFDol ~#C 5!̠4 GO{'棇CGLHFՇi.@Ml6zC`C7M-ڿ5lMaf~C@v,k#Zy,}\-ЬEL9EUDN-`al떽0(dTe5ZWoSSzaTw~A^07 lhY_C!;Km*R+w +qo?R2qrv+1|]Ϭ]5ᤶtՑ9@AMN뚏u6\?~LoG6iWGXwmカcmY,<״e8ncʅD"FIu' 'm -o%d! lG*C/ào_3QZZ85*KG?Vwq#[/oiMM|=ib|dŮisnbª_=Y'?pieXzǭGعHH)_#>ӾsX'5` ⳳ/n/nTMrMsHHM@LgX>CCXw؛_Ov= f3C+!Fzj.{wB2~aؖ49%I?H;s: Ҕבּ뚏ԅd<Nm*oҝej  jK ""JbQ}MihGŒô$+XYesw5%+'ʜ,;;)SN]XW9e6l_Ugщ&;jfnIoTd3S+}-ϥdoGv-Ƚ A߱eu)v[;r5ŎBh]tG|`ǝuGGӜ]ÍiY[Pω[(Xfi֥lʯr:0N&a(1c.dܹ+<ֆ>YhWcKC4""©U#/MA]=\='(}N!8o/Cu#Î!u޹g\AlJ+td^uטw56B~^ul b](Ipqlk*︩Y#5{"9E.K ``e6.hc5@b$Ĩ%x핊Gq~.Ri~秱be*&o:s,mS;;\|@07: jly4[9oV΂YK ٢O-@1KyA#[' 4R@(: Y^*P3ZήpD7^|`9UlB`P[+1@VťkhsCX`p[5:׾>XdsӪE00P k \3{VhgjǮ/lA!_ųr<;5,sW~ /WϐurcW_X,$8,E3XLC5 V 3LΰaWz>_&\`*fys(Jwrƿt7p$;A_^cL+pGRgK^YZ ؾS3=f}":6aG?VVÊ0|W|TДc5+k=ޘYrM6}|Ž7_KE:KLo)s,ݵҭ!zMkx #B @Dpמ#(?=fZd B0vuaH% T0kk/ ..Cu~@l?~߿J\]~hmct[4mC(zJ$(NDY_uUf[œQ\bJYdhi'6xO7\xk>s|fc]:;=\o cl'l 7pV<=y e,dٙs"XNزtd;)H=ݼ/x} Ql,] A|lt1\2C}<Ѳ;<7rORo JnmƂcXjCR Xk[#B(7YcOЈnՈ qly / |I 'r(%g>AWg'89(>YbÂwQ `b 77͔Kagp/ѝhBdG&#C.n4nhd]L}񟱝T4X/uj'B{a١#4mlI$! Dg:_H@V^6/~O>zhER> };e!GqvVbYv& :;q*RLkB$b`h)KzkHň]Wi}3=@:XbE TP꾀"H 19BYG!9;14m]| DJZS%i)Ȳu^O(Taƛ_ 9qYq]{%QS98)fCwtkD&k,^ RHRHrq]LuA6fr eeUG9%2czc7ack,u; cTfe(*&I"B' Òط=Tѷ2%cߥ'(he }=A+tmW#$1ض,;tsetT2IPVVo:Ə`S$EA܏Xn0@PP /DzwO;h 'œsœqX? xU<2z9͈Cy_ZvZggk4D$ !rb`}owWD"@YsFU9dȼ{Ǯdt<&aY`_#'%fnha ȑuz+"*ol3C+f𝐝Y:;iy(|+;c1[ ZĄ6EGA랏(G7mFlv1 ] &"teƛ_EpĄ;Ov+p 4b+ߵM66״NԐ " 5@Brr(γ~fEm\ )',gП/~5*K?J3;[SITmatWJ$}B܈oN$_N͛5#+2bJW=9e@AZ Z(*J ][M53/XisPwr0%K^4שZy47#CC3 QTXR~acBv~\'hDD%i4_r2!SV4`N>U6SO{o 6b-Yi[hiA͚S嗢_>Jъ=Ƃ,ɳ;33tgZAENu#*)&9]no҈ٟӤ.n4d6 ku![6_<-y#Z9uJBPY1: KS|g]||R' c1ua2Kv+_U)#tgۦ;6d,<״e|U*Æ]݋q\|p8i5ѡڲcQ)p8G3|p8D 7p8&_q84p8np8Mpp8i"p8N/8p|p8D 7]6ݱe[#A̧^^|FNL[ >~sEo{=v?T? ô^n;q7(k2h 7-nHH7?\-)-12Ps NpDʑqb>z8tĔ$Hk]}B>o L= =DyCip4C}08)oLJ[o`nأj)=Z-{aQȨj,YdvdSEq[0kؚ̮=>ڋڗŸ\ raCD;^K߯5H٭ I+l~uhS`VCMLcWiX{mXWzxEߎś=`mdPXz1}Y[{He;:lU@Z^&Nn?@T_ 'k(1Y]sZ/Ʊp#`W.$1J2>X8i#nhĖ=އK&EHd_dH=2w۟]wTk&JKKG@eȱǪx.}dÓngc>>Ó,KϖTw?[_|qc|qrbY;w>8|r@-"ӟQ֩MO+ד!˷-AVZi?W!Gz [A=Ą|zZ/b­'LъSկ>`jhBxϾ%G}kc# ے$Gi++*sa;\SW1aկӋ {4He;:lum CZJ\ڵ⢎qG֜*M1YsbF""©Hq-7j۔n4"@b`HU[y qDD$˨tz]o_IS[ӼUnbfkS.I˻ѨLgщ&;jfnIoT-&QPWGjfL+hX k/ϥdoGv-ȽTX+V,XHtt&g+stL﬋L9C'f ˈߚ)d뵐Rqw䪏/|.FnwALgf$HCuW 9Rxt%+ lNR4Ǩv$\A Tsw'www7#[7ro:}#a#kg_< +gkj|P$M번pjD;nKS$2CC-*HcGƾ HU!ydͺa:o53 6v2Qb$Ĩ%x-yyWObvjS.oȒ~zWݪc(wirfS$GڝU~\.a2[c07>R?=?+S1y8V2.{er$3ڵQN1 vO +X6obN'yO֘$g8\Dzk;8$#j^ G$+v'̓-1p5$}; k菩%&6Np51's³@B:e@_)+~k8(vA˱УƼ[b\\0%ރ?g`k,Xzi(io~85sV~4[5"C+}k[^K_@IJGəO NN>on--/1,xոnnn+)훊agp/ѝh*DJZud:N>3$=?MBryFeGx>{Uwb܋"4ċ_mS,.H' I՟kԟs)7 A]{%QS98)d]L}񟱝O% IDATT4r=Got׃HV v_zkHň]Wi}3=?-};e!Gk|N2[V1bҊi3\ag}ܿ_y]K %7'GÍǯD04A*VLj"lŠEy}ۣgHV 3a:jlVs^;{G֜/\. s鯦by0,}!N .1 pr,}T/!pztn'gί@#Y^F趫ȑl{ :Y]W0aoڌ,1$.h϶ Qbv0Y"j+[F_~[OdA@-ǟW_(+֊K+V} 5\BwOؕ,tbP1!8F3T2IPVVҋgmeأaA,_Rgvmd#Ua3fYς׬}֜ɘYc>5,12h<_D$7hW(_ZyvOì킋TVA9 ůFeGifgkj7)Ե 2챖J6R_CQ͉_՗DqEUOJCyeԝ-LҵMu*TR~acBv~\N'gh>܌ ӗ7DQz'fLk _R2 ՂLMԺ \GQ2-ˉ6KV&djӊLIUC`O$??kۍ^}M1sō,blrzf iO] F̣EclEݽۿ^/6556`bp80kϣCe"#ףRp8fp854߄/ p8p8N/8p|p8D 7p8&_q84p8np8Mp6ݱe b>+x9jBS <܉]`k'B R4q,dD"D"=[ãDp(BmȟG?3;M^+GƉS" wa Pzg6012P, ſr~;ov\f rq^6oVCM<SK;Xe/" ZaV15Hoe ?Z&÷#*dEX|~ZY>sjnQL0kaUAlյuAP3V1?`6 'm}8f%cWi īmj?}\~%Gj^&Nn%nq}airVc0F\H$bd^}pFr+{L`#>ܸz9 T;N1ݒ\r-)d뵐ץHyv4MRXtt&g+stL﬋L9$v!o6(\_Dl TݼL.ub6ʒ'N!oI_RfH*wՑY; A;($DD4ű5;_em9F-fFXf9mYel]5]7ymf-L7ӟD則iI@Wr kJ(% _hv iB5?b5VOm4a51f>ry.M${3=2kAm7w>__YsCKҰёk14""©U#/MA]ط:vy>AAxopT5M߬v_qV< bSZk'cƼíV2ЯN+'1x5ƭVnGb$Ĩ%x.㔧3h9vzr .-csX V~ǭǒ0z :mՌdĬ` }Yiw"Ɗa\@ߪĎ,.zw:vm{w&PzƮAxy%\a](IxˌSV,a7y%Ŀc~8Z&ϊOBZ4ώ!MZЫGSzY]I蕯)AFDTL1zPרt7M}@]\YL,PDuPQdu%Ks}&E)(t5y)siΌDzz'2P:*g/mL]GXHDDXZݎ>(fN]O ߡ֖i_N`)}}L )t ݚIrVZǽ ֒1F =GP~zzӡ!g`p-t+^0K a^@\\\q>T~l?~߿ʻdV8w:NY9M9&'ٍAn.0tq}nm)ý=!=k]nhi'6?;&-ʐ * " 7nQq჈(@q n RAd=&Gi)&+/K:ܓs9d<=ߴYsݑi߾=I/%$xh;JOoBѫqD$%`wLDWrU+&SHaqٌ‚B%V !Ьy<1~\pT.X~kog6=mƪe/ \=vRUL|=;Yh}&/̧?[6٨%5Ut܁0:pmXP3H|0X Avlә#_>h"| `mm5x]t]5]>{\7O[fdsĜ=nSũI1iii(pu0weYftdrOmWYn8iqKwճlo9izt)<\f]nw }VaIf[|.A<!m̪Ol^?-3~lzN.oW Œ#"|ҧũm̭szRMv΅B3eHoǚ#b0ob_Qh`z۪pQgT޼5G6><87sg&o<Uʽ8٥/wAr+۾<;>nϊ*i;摒uoޗ%ַ)=+믪-V9r[EUsw_>X]4_2^x?>q>xm%>`vyMfӦ ̣L둳R0~cFdZ^4SbXwq{|/Ē255J3dz)2RitC9lz|A5XYV2{iz3-cfWיv;DŌ99/͚"fťCPAJuuʶGA_4`:h̔f?6dufWMߕ;/h[ 6}Y>H ^}p +?rF'+ؕ<. L+}3ͯ3wQo\xi{f{OƄ=,[9.JM'W1#ԣxt:cv̰ʮL7/y,,0]*^]ks|6S`0@}u6-RMXXiк̦ \k4cm2bM\bi}fWmcI&,iwv?#ضcs~2O^piet1>?>&'yۙNN4}~ W4I4aa&c󟷗kN?xMUu| |.ܬ? 0`è,Ozf:K o>{P~b_d?N8˩SH n""""!BcxJ؉] 9MDDD$D(7&""""DDDDBHPp  n""""!b? n,h woMH"ӱ5L~#>beYX'M9z}LlWoy{=x"5 6"f]8Rxvi<:gG5:=x8ӯᛒtpoHLd,i<^o` ْcy It952^IDDdO/5H6ykZ3ׯmƼߑe"8,%l_m{K%Y8\-0/ 0MlOĸg2>9OGJBJ8^Hqq1y>el6wZE +mM;_vzYEl7_]5/m`Ҩqwl//-NjNsg*rp‰mz"Ձ%YuF$'ФekEnm6`%g264NkN+GsI>k%X8"$22Ά[‹N^cTY:d=8TbIxcXM7ns:.O('1-Og j|;6]S 7Ɵu%߶Y?W<Ng!4,+""R_";{;9ѩ4 4O.ǺAbL|,-Tk0kߐǺ͟6ax1O_q/|/g?׽ e|!~2.{/E7~tLW3gڳRqޙkk?d?z1?.rV@bh`_~>-bX&WO䛁gyo3iY߷`yK%I+3sKs٣ ˇū}IRK5Da9-tfW:>`Hb-rB("zoYL|=;Yh}&/̧fr>f?t:no`и_)[6٨%#v/w&\VDD>-ȓ91f?UzIz[\<5eV5\Yc5_~P7/Kh;u\Y|> Ha!߾:vg+[?LiXRЍK=" ;Xk31 6bm O餧7}w 7%_Ep#~ w} ?I?6✵\x$r$~Ǧ]~Kl~kF^f|rc;]ŤpGu%0nn^]Tɟύ7G0d TZݹtHC$s:ǟfLA>Em m_h^>n˫Cº^E pة-66]Bhx{Z p|>ޑ91<вW"""7\n23/s$R7>$aJ*;N/?AVtrG~USdp%krQQQDEs3k?_^FII=@>塓.{V_pa_#1;,Gѣw?)s8DҰQKjhdmJFLHtwDk~l֯‚|e4Æ΢Q$MѾbU$Ҥ!̭4hFmpL$ ? kVQX_ZKz,m}θ!#R-N'hmSRz,biױ-YDl\`JEtDLl+\BLl\Z[7'EK6rѤyKl\ =>Wc|XE&ضe#Cf m"Qflݴ΃nR'$w1DBV\B"yVnj1DP\X@Qaq ]$@QQaoW_j:D_2t:XUe^pLr8JMDԞn"uG.4T*""""&"ufԘ>feѢŻ<ߩz(\{)(Υ(Bw>1qF'wm""5̙ t;_@np8JCm]M°Kfuz.Ȯ|~/?.ؚͦMiВ#ZOO 璊sܼ3(- 8&$+p8lݚϖ-e<'W9S">3cfnj߻M.;1I *IMz=Vק>OɽĴh܅;w!!-ML4O}m5@UzCDBV=b4󻷦al$&|P`l.'gܸqq"={bܸqۚHE%z^ڞEr o=_,}D|j{ԅ|T ]4nw^4iDdx i3d=`mߐXyrx(,*8ӯjW9o}&!{+xH ?ԃ18e-!:eb@|~/x!9#d"(1ŔEDD:HL')#/{٫x3=x?Go_6@zn>4zWlQyΣ.Af.SOנ xԓp;`~y+[v_D!X`z^3a65syf̛YЗBǓ@.HLL ..f/s+]^fQf&^J&zwV5#8KǽΣh{1n- 6dѮ5A / ~{n?.$*sfCΧwZODBW//-NjNsg><؆1%TC/sF''މ`ێ՟rG$1-:VYbș'ˆb}ywiUWҬsvy^J&oчOZFlKn}hCF{5'cgt3d~r3q&{T 8IMr+,.q7r٠IVRF=p-iCtr4^ <%ty5FkOzJ-q+k $"2H""\o7ټ *=CZg²-Ue} m"J;22oczy\=RP31El-^|QϤdRhgR`gď-+1E_9*׻S =qҶo/̌ͪgՇ¬ ڬ{>bnϼi?cV87\Α#dD$|xZnKrU0>6x-'yL >e/Asq;ȱmֿ7Ac'lg.ggI<} ڪ7 Iuܼ 3 JCxo9~֓}.l)}Ã⻎uK[Gڻp0%1+ޘGyz!F3`Wxk?k3_gC=^8l[2DwW!+o#3F3$=bl\Ng!4Q_Dql_5EÐfp_S=˜˜௑4Vp,DJ=+͛ C5ҟXU${cOć~c_1PGul_`m7[!]U)(a]H7>g&"2)2)`;>;uRPSz듣Y/Df_>ʹNn._#|3t<z"ewq>o";ѻk^%g _Eut|D>?L ISeא#LO>f Xg1FЧal_yߜ)"!΃TDѐF{j= /|׉ts2#Dr:cnhf;m&m;qFh GdC~8 >uSߵs_0p<쉧Q 7񲞶?f?9SmV*=;ңq:bi?dK:Bc3y<55 BP׳aX*~JdȑđԕN֔yŋy{X}8zvNٞߘc[m_p}?Q}?s~#= b gդ2ؾjEAʱWmV}?ucG2HW\*|6e3bv<, ˶yq8}m1Wh $3J\b=<ےIIF~كfw&>EGC2< a3HZKfM{Ջ$UXbI VNh zS߲|qttFat1ˑ3%MYĽ]6⚔?P]W`,GeҭǻoPi,_ec s:p.ia ~8, ~j|Þg ; zf?E+XM?I;qR͊1LEQCoԻ`@{+9@u: .q7'H/y x;߀}nڸ)Ht[O͟B>O z 9yp ;dNɟo!iSwrgF7&гRWS׾5.嬇&Azl4h:v|+wL]GNM,;lѮ$Zms~`߿qA/ʢ:[[K[Y:Yڸmi4nl ޼d eꛗЪruTEb |;[L .KwFrU.`һ8dTޯ+#=nJ¢8m\NW7||HOlALd\+G£byى':|`%t_7w].?,a&"ey18b0#'ڜbssፓ)%\w-k ٺl:_ W׋;ƒKv텣ѩԧi9|JO߮*m?~zV̚SA6>,flcfcCgF_' /}U+pB.;uXu?'d^+O=)Ig;q)ߋķbtȾ_ƍ[. ΥCՄ'֙<4;m`sc62;QOud_?{v=sm]cB5?F'p(" np "AxHa\aaaxiF'XsPkC~6𗞀Vi!n~?W:X>8{~wz ?b+ӿȣ<3O6xplᏙ0ҲE{K|;z^KG5-&]Tzr69>A+grSST'Tڞ_rssܶ~}pJ5Zeرypb|=zS־,XhN؈ݸۖJ+DZz:餧 . +"Ԇ ;sӽ )-A}L!= LlTsl0thLJꡜ)Ta*`_A%P Vj|?q2.a@1xb8MoLNN4gio+AXHp *f`r8Mob{yudM6ӱE"vi̚>SΠgb8ёe 88 gbCSmGz9 v.PUl?_>SMuop?rnx *0.:V:F  d/uUA8E|\:.kOGqAwߘ=xټylٺ"?a_ͥf7'( ,<؝D=W>ό vpXrزآg˸z]Dhl93 U/'118Jq{+W41~ =exp֝""6S\G]Hgׯn+?Wa8VU~/^4Y."q)"#q9J{-rMpΛs⎡sgdSʿpx{.j='ivi_N*ݗ YY5&-1mJnn\wõ\lNK_ebN}v%QKn`[:ݓoQPE9x%E`Yuuُ=++d]qO0`ܸ}=Y ϕTqb~5[z\Kh{| 8LjYDT,EϱS߽{? H4V٧i)M|us\ӐDӂҎhڔ6dLiⶇ$ܶ5)"Ppe{O^9{< G&seONJTp8'**F}ٹ+CLd q)4HJ#.6p ٍ"IeV\z:Nۋ+"(] bYᄇ"w~ ~6LD: n"R/4T*"Rs n"RODDjJ'UH+NEDLqÉ'aP)}-8XltWǡ3^? n5G~n6 ("!)?78\a.EDoEDb ?Ĥ.HH%::&L_wka&lXo_ȁٸn iM2HIM';+.mdo$%5ilް_g"5ؼa=i2| n5LRJ*FLZeS#'+?,$A*I)'Ȋekidb"bO 1 Xl Y:"AsI) HHN2h7mNLl[7m`?#$:6-OHQFscؼa }r!m#1˲hܬ1qg׮Rx tK-%ۿLBRr}C$d]JBR fM݌nVʮ, ÁtbYe@튄7SeARm+ՁVtkФ&"ub/PW*ozФ&"b( l V&"NBDzt;&""""DDDDBHPp  n""""!BMDDD$D(7&""""DDDDB~TDD e"me7HYX+ lƘ#)$1cbۖ`.Vp8D01@݇77@Yh۰vyY4jڜ8]bU$Ҥ!@݆7-ΞegѶۦw}/tXq؉,"6.ySp9cضey:0χeY4jҌm[6T=nmж1DP\XmuZq9UԶVp{ߥ~MMDD ޶Q_R7.Cquu5L n"""mϾL7 |ߪIDATP:c oײ~[WKDDD&eWYgٶ΄!xo߾N=PpZ1w)L[F6}-M/>sf{_{g蛬?a9p)%;8<?ܟǸ*aQ\ګR;57wOcsǝ۱w^=bY\q7W9SN=AWy۱ `g2;2x08/ś|;a}|z_5'fs*9_v;pZ΄A`-gQ<8=^Vp= """ڸ{-?6lȻMtλKx/XGy̴·ߘT2,܅ylq w<-\|>3~>3|>i>+Hpx?ásDDDvF͉a5_~_hvg]r\'pHHLnP DDDxedTR0;nfBH!QÁtbYzDDDvU o۶V&"""D^C.U$T&""r:n[}]W n"""!RsHPp  n""""!BMDDD$D(7&""""DDDDBHPp  n""""!BMDDD$D(7&""""DDDDBHPp  n""""!BMDDD$D(W4.!""""A nv\W 4T*""""DDDDBDsce9HewDDD2CU73 necBȔNu3C1\3..¶/pCRTb790)3읚d=u394jڜdj>9Yl\wq  o""r`Qf{5 j˥ 76%%}El\<:v%"6>a$7 } Hhxa >˲hԤ۶l$&.^MDD( aہc]\DtL^2{72CNfpU^`ض]ogYض.+^9""" ʡҊ>jW/'*=Hu(3ԉPWP74T*""""+DB]Ƴ_s,""" ,P aqWg0zz.O>Cd? 8-kDDDVyX7 t9z*]ţ佅Y 9nuSduX(O\"""u>w|׽Z)fb6X=o*\Hn: JQy{mx޷u?Ft9zF]ЉĊ{PH +'Gs9Uf(Ǜo.o1|~6q1觤1^ O?5΅VF?HW'WgpG?eC#}ofo5~fVj3Nf=_IOrA;o=]DDDo";ѻk^0c}%x<]g 뻍oyi߲ F%3^0z p??:.WY=zibK '[Ÿ+t XIxf/E{uΙ ȁ>O<#sA>s ޿f1$<"ZU'{9|7l-ƑԒá0 ·tپ/c+3YOQAb9c]'Ȓ|??y9$AKg}허ȁ>Q#+?\]?fا#v'+r&?+p0\ArF}gp4=0z/B"InځS.c+_l)=m޼bdY4q-_ zC8 q x"Shvhwξ4شσS]ej˅eYXkED$tofp"J*{x+d?Xp##p9,0~|%nJ~3pl %n~CQ7ԩ9n~J vWD¿J|Aeݸ uq{k0v 6 a~R5N4DX =.X !D Il\ۍygᓙȳiB.w{x'0$hV-#n- eݥ->ZgmTi~k$śDwJ@chftw4fh ?DsNim> vfOQ37LGHYh,QKwC3ԫI4Ot=Tae!]_]j4HKڎf_f4393~3LYEL V˱ChzTiܩR&'P?/x z歆/#C3lJ3lj ţB*B̜wrα<ShTh7I;g2nBifv#htͰ*͐:f&?uhziWNXʹ:b \ ) 'B@4Hҧ} QWK=IENDB`gtkhash-1.5/screenshots/gtkhash-screenshot-dark.png000066400000000000000000000655131431266303500226160ustar00rootroot00000000000000PNG  IHDRp_kIDATxtע>{뽷 {NNPlɸcqLB38AH-ɡ C/zB16۲c06X IG+|Z뷐gٳH2_O? ޞ͠rsՠfͧ3|ODDDD£CZGGsj)9FF>q~+oqqDDDDTə_*=ADDDD_Tl,KnP_8JIj?9\􀈈j'.&8"""ZKjv]OD{ࢣVL,ڶGNѶsIg$v퍖kץiuX+*>U68"Ğñd^\ܯ#*!! K@LL m1p>£G0{\eL+;GP|3~:'{|'.f b\8_~2Bم(Ӗ ЏNTXU/^/9YG/?gO[ pDT-.-ӝ(GtH0z^VqyÓoXB;&Ÿ%G{PDTX\Lxt'ѡsgt32;I#3ݦ++au}@3享wvm=m1Q8sRl[5荤]# 'ѼZwĎ+|kiꮊmO$.yUpnJ25g+,~`&3 wCz;lvUdggc:}9\+QBl~j+^exXvE@sؽs~wۋ?<П\˟7|$.})1eZź_jiQt#kOL9ejQVzi'uJom@k#)3T>%%Ws$U' V:a%t6׮-$ Oԗʟ7},=mvCǶk/= IwGĴx=qaMQ*Q paaDDDDT\K~ pDDDDu6Qp""""""""jk!= """Ikݚ8""""8""""b#""""8""""8""""b#"""jpzk{g""Z _R }}ZQ- p򋲩|6-Wvs "4lYˈ8~8G֩e1բW^YWuc[Jge]g-Թ+g pDDDOQdH>^3[#:BB`h,ndjr}h} R'A BLCY&Ҧq-&F}P Ƚz`nMyVK^ M~qūDDDTHe!Ep\9FW[츴.;b_WݐvFϵLym<==;yy)=8qh8ܚ<% ' HDDT߁v_`X|qn9^m߁; O0Z\dYȺx%wyb)]ә>×]6U:c+[ӱ51:6^-ȯF]˓lfHD8ْW!쭅|`mZFŵ#?\n)~a񑬫1enMt(HDDTެ\􍉨1*ɕK}|VAc,c3u*kcqDkHӗ羮1j:0Wjk5{/w-Dm2$mz- Xqi;")>B 14}=aIQU0!Xw% 9VWipUqO eڳ㬟ΘNwjP0~w8v7 4H?SSm߁kz^3a_~$`324*(5qz:~i}B'>z{[QGQD}5+,^Þus_UK#+DDDG pDDD pD pDDD pDDDDGDDDGDDDD9yhADDDDu#T""""b#""""8""""8""""b#"""g8ѰqcޠQ%NoNhߵ+EDDDTkyE-B3$ء"GDDDTky%61Q_'_$<6֓C_MDDDTg0IEDDDTg0I:2R70׫g۴*KDDDb _xn6' @pDUnmNSJؾRvUzHlӦSS99Yۯb^89[5:;7qt(٠F͙8WƎ}uu:/lߜTnŚS8p`pLv[› C_?וc&[L~b}C/piW^~QK .AOo7?=_>hZ_\^}/F>Fֶ9A}WХm4Bʓ>!±~<6 '-hLeݝ嗤6'S5|o=i讯kJѶS_ԝկ-5|7|-WPpJ pu#T2wp#}7|7[g*< 7e{.kSݴ)>ZȾzK?n'KCײzP}Y?gą+]_gl;k\ehѤܽhy@F1|56h6糳5V8dTќx6Όx+&Rڷ41m3a!N_@Ȱ͔5DZ`pz{y48olub;n ר/8D%q>#Kz-ZcOI)[ubnGBᑙ(<4Q(cffیyg#)!:c֎_ kv!=~QFvh6/W~߁wBxD8ZE&oƷG5$!}/~] E2nhN)`v7mgonnm]97R >7|_;ފPA 4[,coW}\U_~H pG@s˯Mm~LX\nA>|[⏂X{{5ƚNblmxD;:bzce|1s\؇QxIx\>!m'"Gy1z;p Xn9^jeq l"ڔg`_K8?6o/Xg2s˗w z }\ yȷÚBF;=m8ϝE- n.qsqτھm:|\ꃽ~ FCUG8qgDPc5-ekzuqڰ(Y.-]3z֮e,[WR7j4/rK]?{+r?tu,_ .l~hN7Q\ba,QkSQ: ۙOBdd8||MWW^o 7 B~J͙O|ܠB>'Lcy9^^1?:v2ۦonwJjoL^z>W0*utD4E/3f$n0ێ { F/1elJ` pBm.okS4&ֶYfX{>{+V8fl\}5r=}"fr7: gDDt(p;X;pΞ;#l\{k!zun!hs0?T߁+9]s\"WwNz,z^3a(ԗ9=-:6^m}WPPC{%$k~z>hkkoĥ, .bâ/hc |/b־ힰ |ը L)ψ`x8iMnkWa?;JrX8SSG94[(r}T]km ~FSUWflW"""Ø7llS=w}_rkBHc֢ź}8YiY Ƨ㷕j0 &ۦ7|(a px IͿ@6OY˹ "(PQ_v%'8"""Js' @s??""":NOi 89 p}|g>5l^^BDDDT۹yz3<ְIS&9"""J+rn3¢ҬdˑDDDDW"g:DĵkGDDDTkyZx{ӂvR;pDu.j5cg9'.y@Ѱ!1kxc'WW]z" t5m澾#ZN>VcZ{f\7$:o ;t@d|<"y|b+QR3&M1+}9ƒLǎ/Du+-i7mJDui &V(RpM"b͚Kc4so'7tsr홆֑5[uԱįDjѣjY_mdQR&Ϲ o̴V#!?/? F+[?`ݸy]Z.gGB*eL11="cʹ#/<PvnD`ci@Ey8m|܌-ꟹ*]V2-TNƾ=[GI\!Eq}|92XnI{f66k\X믒OƆg1/EIE:WqNM&^S=1a}/wL/oaϽ.x}nyYMCHP%eaF2ޑ_p93+^7woSYжM "ѹh,rhRe$Vnۇi)}gM vN \6}J4k_=)Cz">0y+2U[.^>u(0[q}8?k?E;|Zӵex]saO+83aRy)wpN Hm hY[+U9\oOu)< b N]| .>Y&$/YY-/ g6!ZW#͞"{XfVO'@3''Es)S8 '+.7rF7"F쟋H5_ԥݖϓgK{1g<\Rcc98֦.#Zk*b\jW}s%rnށ>r/@p.OxDB{W4<)+qOKviǏBoko"l1` > $ozɛ!yKC X:yE=_Ցگgy%mHy|]0V i[S:W8xCNz DZ, /χoj3h[Q>/tj1:} W{=_T)kNƥK5I*iOtWj;VGW'/*s8:z).7l[=(IG<Rd/ή-PvM7\N>GאOH\w"om\+@vGʡ\\X=ApթxW4ޥἴp'N`OV"aM}赡m$JlG5a&:r][\@p󅒲-Bbp8+u! j gD7q{rX)۠r "~W12XQ#[EvC^qYa_|Ǒ7w5c8<]gBa<\~T7u'ձ'j0|~iÁi=*{{p,;Cj= p=s*6 BCi|Z¿e GW7jn_? \}gxrSv@ }8UQ?/+mᢂOPhTd+ZuSx ½΁hNo&K‚ٸmqz׈k wot . Z+[&wG9A~\k .82Ɯ}$c~#/"W{:r]Q!ķeK%e֖3,6-zŚ]&Rd-?0+(d[qlGP/aшDǿB]k^Z^۠eH.>K{K$owUh'8vgaF8'gg˚ ֣P\Gb`He(. n3zh җ\1{ܾEIa&hԿa_\V!R75FJo8UtwQT_4_2e`)pu{<KP&͹C[0<ѯB_͟vrVaܼMȹuWɝx̷U*gzQb;/a*R2)W_;Q/aȎ7+:r]Q\` )G;pm䝣g\HҮFa;}~:e\Jê/\9+5TNpzm{1Ж޽,$?*FxY|:J6 !>R0!e Yz1 'T./#G3WKz.zp}]!hA 111Ur {q#4{/ՈzN#>I}'yB pD p pDJ\hz돹&΍teJO 11=N":44Nh STҋ-!S:2 pD p pDT;/)GW5lX} ]! O86B_9 p^^hШ?ZF:cV>v CC:unF'~y5m{A #Qo1kx|&\Xt>JvU]ҰIJDrd<>8y$g2b׮rjzbqs Q>>F'~"zZ0111Qp-ZQ 8""""~JDDDD pDDDDGDDDGDDDD pDDDDW)Thظ1^oЀZEf7Ƀ A88 7jEl$'74!"""ra#5nڔF01ܳHGDDDT p͚ uTM=zhZrT}}ӎ ҜRgv% #\M+вBY6^֕.+˹~4U\SiD ˴R9{Pt6㌔EۑWtru{p2htpR_Z-ͱ_s̭Rx{Ŝձȸeq|-жeHqi,>WJo}ٳ}s-;ciM%QEknߴ7[S"RʴL,h|ܠJB+o e:!6{6 j0l.hʹUmG8JD(+83EYOnG;(-Śi(u>R]Tn^ҺK;"e\/8}!Zϕ%([_}e4Vom̝ci\3g9k+*'"z&\0l]buEvk*;y9njK\<{g99 7ǟ)S2 '˳krCQ{97@QvWbsw`”RPp⧥T[؈9j-Kf\D<ˈEߑwx1⃽,9h'}SRG7ox#x,u nAtM:26RJwRm+Koc7'4עhm଍ p8yG8&XZGPt_睫nnj!vOWzP:Ϯ:2IRyQHЖUg-OMR<i}5%korqRa\){G>{Hk\[|3G);giEs':'Y_Q93d]g@&f2[n){\T)wW.W7|P{GxAN1F?yQ􉞇_=u,,<'qSGI&6F+_hr rW[g馴$?uԷ.fx;Wo\<עvlW+py 52 ƴPcP=#8$1bTۜR$7ǫ5%P]*nKqB l16R_~zKWUMM7]D̩)\Z^G&4Q#ߗeliYS9Bd<}iAg[6=Ct&K2yyj p-#:b8u2n@t۾w/SXX`.S OiN pMIoJsV"vV|-жeHq3jd}jKs}9}{E8wp# pFʢ+{Eغ=8)\fVL /qrt}r%t#Zxƾ=[GI\!Eq}| [=K-i{Ɔ9cm [Q㓱iKQj>cXrla#v kp>=Sv]e2urN֗g"IChݢMPsҾyt[jT>OZa?/Ř pJ폱!Xoh}nq;s]-֎ [9Ҿ~ݦZE}LW J^NjyF~"M ;pAGMo"ys#$oi(6_[?:U:r]Qb8|r֭IaffNr#9W&CkGJ ?cwA(->4 BBzbH]_ۥHOgW\x#u[p>E*Zm{qrt}J۷?~rԤ< k ݽh 5;oHo[KDžr(VOD;ܼ1quW<ƻT:K/w4h(y8oCt_ms\w{}Wͱ 3N-Tg;t⿧QS)q^\~c S)gmݢgn]-h?o:Ra?:QtTJ=ڴ~eDst{W޺}k9Kaz\:*u,VM_-^êsO_xZ+y_tp64҅~;a/1h E~O{c= \qRp^ oLmH37S nwn(*D/I zks`jOڇvq6XѺcny(Yhݢ pҾ ia?OH3vAǂmڏ]>GW7jn_? #kgr\:B1O8k='qSGIۓxEPC?6D/aֆzÏ'^~%$"yo$CC {z>B==&7mc2$I0=vzM.qf\9:2_c;֪9'~wqB<|#0kOV?BVpUq3}ynRy@XƵm]AޡEoW`|Q-/Bѵ%fZz׾㋡PU4 5?cluڶ6&'OzH{R94F| >AqQnh}noN) 2; _#7\ܽi'TjsswȭH?Bv#txW Z?ɵ |:>=ۈ/cWN_0N2W0H>"y#p8|m.]FAA.2.ֵߠ{lMnYZ&e1#+mU{svҽ3 @{6o ?W = G4({EqA6nXD2e`)puї;4;{J5X=mR][KAzKһbيa^˸`’p>CePںm;b`89>Q}QD}-J 3v@ ڿ5*W~ñ2ܭGb~ ʤ9wh '|[hU7ornյr2Dy*yF~"n^G{`70K-A΅`)K D\W>'* pDDD,8'E6S_=ØSRhK} ^\{ v _Cr%m3LDDDDu6U5Kˈx>z~EQc U }C_Dch&Im31Qٛ߫P}FCԤtZ U4lM<Ն+q͚M4sk?87ҕ) n p8F0T88"""b{5lX3w """n<РQ;Ucx3El .ʗ0= "g8;C\Lb"ڵ#"""r 8""""ݝ߁#""jZgox U+9X q pV\7$""";pvO o6iBDDDT#?17mJDDDT#pM#""" pfj%tY)£G*eݕў-:"*G>oR-Et1ۗ4h|Y9X4/PvnD`s`(~X>Cۖ!8ٺ%G)%Lj}Z{l;[Ɔ9cmrd_2WDdWͅoJq=RKu͵5]{[)/}Q2-h*k_1oQߪ:9G\~U+鏹:>J pY7bu[\Los{iXҷ+mP8' [dw+3UBL卯ŕkX3c@jn++rd_ͅoc9"e\/8}!Z_D>seeW8Z9GY;כkOڠ䵃NA{ 0CDDDcWc6iV/5j/Z nhpQ, +pui2p`Rt 95sr|3}ܝ0e%"i)"wJw[ WCys+,7d>~b sm 3- Y;;Ԟeߑwx1⃽,9/T)S '++ k~ Rv7'7}ʹ--t-ܫgqpsVʭmK3Az cCET_T.%hV~BdT uQsh_QRnؾ-enWDs!h[+3׷ķo>]ܹJGWѹ޴=J^;b8|r֭I}G-8~$r5^`X<~`H|uGtg.C#+]ĉUS&6H=P+#>|'/OZOb_rIp*8[9,'v$.;˝]mdڡ-.E]:x=»MQ]f]PZ|rAI:←XyRWWʭm)g({Q(o\4}@S4vAycT(W۲ߊ櫲s h[+㘳ԷCE*u IU| Zw گ,Gt7mOή_ ۘzlW^ـwjy sYt`>EE~9T)dv0R* k$e7.4OqAfKaFM Z}d*Ap8w 4[g-OMR,h8Kg~sS kpxճ؅y7ze]~(W۲ߊˑ}E49s}}THQAk&:M s7kmƍŗvks`j>Zk+ p/l]Cx8CEu@WgԶ虨EHTnm[NHs4shx,jLET_T.>PB16շ%췢rd_ͅomc\ߎHmwpeW1h~|Z^~`9JɹޖQ9wfzLzo8&ƢeH("a{p"\͸rte8~>^? 'Wcv AL#6˓ۀOA#$|$~9' 7GnE|9=W!g,Dz/si.g }>_';4;{n]Sm6[^@qVz'Y#[10K_nj̵% җ= G4({EqA6nXDw۩_^[ lY>.6G˭mKq.Z75Fm\4cLY+B\/A4nmD?AѾp}͗#h.D}m#ǜp?QbWbM8{M1LV1hnvtt^~`kDzD`(DDDW01\m p*Q`3#""" p pDDDkظg@DDDT?#"g8yxyAF w$"""&g90(,:joo]/aU9{D" pvDĵkGDDDT-a-1A pDDDD pO;GDDD8&?6$"""VroIDDDT#wl҄Fb35nڔF01ܳHGDDDT p͚U Vku}m"q.~'"USG=c!zjkiN t y2#f,_S.# \OǾk0ax72+2u? n`Ԟf7em m {#;/9et95O X>@ٽ";}ci@Ey8m|MzձȸUay1ž=[GI\ܴ.8#ev=|d_g;G`ɶc%ll3YCkd-QܾhOƆg)EIE so}ڶ֯dۭ͋hm9>9AA~ѹGs!*wt{w͟#c/#RX4VU9u8}}2/H~3ƾ]Ny*Dl ^Nt\=96 j0l.h˯ހ!=g El(\i$Ykׯ|Ԯ ߞ@;q3mb["n1ǧ }qOk|" sDx˻+n_Y=DVL^*x%`3^T־nhonEEso+[OĖٳs>ѹCT/h96m9g3?a}CXKG:o &< e,ȹҴL,ۦR\+mPiS=[\;f*<[\K*/1X-¯2jOwi1EGz\V'}ZzgQ*sҋF \o~v1F0P8R#꿣w>}R_;r(VOD;ܼ1quT~z\+@O?8;g@Ծh:~f,mLZs)vKWܾ`߶T_ -RϞ{n>ѹCT.:=oiE͟h~D=vDccѹ6ֶ*= A|1p7AEE~9\ܠ8O&+Tnnj!vOWzP:.j? ]]QQyH;=㍚Lt^~zHkI>GV=/%Qݾ{G.RbߤSx $HY'IRLҋi͍sP?5I/ڿd*,ͳiԷ7niJW>ͽco˾i=[9r%Ǿܱg=6͟h~D=vDccṴ2ֶ8^j[6㌯Ǎ@".(Rm p]R##4&Mψ( pwlnw,.gT. @)Bz'5shx,_mmdnQp2οBقb̍~r`DCqdپ#;.f*a;u3QKCw8X{S#}'EpwsosϽdۭ_Yʿ`Wvlٿ}}Ӟ{lퟭ>ѹCT.:mEǞ`O4?֎}؉[zt^uѿg{ S_ߑsS@NƯ9?ȃ$d㋡PK_4/'1R;0)f|}{{f!'i+zX\|3}l{eܷ <\T u+amYIHNaP:3?ŹclK4{ARx\Tnh 6VF\+o{Op(-O7Cp7 , vgڶQ+Ҟ/si*sPtm/ڿ,ݎgZa_\V!oj.a}ͶazV&Z &, 7~ l_>T6osnLc<[b~ ʤu;N?2e`)puї\1{ܾEIa&XaR][oQ٥9&؉PZo¸ysnlO\(OWz}QD.ZۢWrl9}EstEQ=rpp)>7X_aϟh~D>vcc}A0VΥ83ΏP8"""ggsS5Q `c#"""88""""T*"""ggSIGDDDTװqc܁FD" p6BFACHDDDTM raQXt4޺+_$"""r3E q1k׎ZZxc#"""*ww~;p.j5M4lHDDDT b-1Y;p |F?1٤ Q`gkܴ)Q`c#"""g#5&05r~'"USGUJ{:MDDDU9%-c#""b{vrueџ1-@/Oc{cdMN '/9سy)zLJ˻ {#_6,A* pM1wkKseZxx'cÁ3([~WE})_5Oyjq(7-BQp8NsٗೱhQH,|(Iؙsig3qh7ewA@Xb'|[+-!/nG@d]!塂wPfo:SiNԟb\NQ3 {f@"""kn 峞V1 pXd+oq[AA~>ԶLE7ѩ٫as`PmuwORhK\!ogEfa u_Ug?8㡶Q] pGs4-UX ?r_K^Vik$$rnށ>r/a#v k ĕ?|bG\8ۮ c{^=gtPG)[p8w ADDDTi6}.86٧~% .)u&T˟+y&~i3Ha}8rOb.VY j*Fmȷ+p#57/yW0whFe_.t>r+Pӑs]}{eܷ <\T u}'o,Dz7 mE:)DDDDM3"ra4j@HDDDTM raQXt4޺+_$"""r3E q1k׎ZZxc#"""(yhADDDD5W*11;6n4 ;V3Q7'WWt{";'GDDDBrԦCD#<.$_lbn<J$,6vŘu1襤mμ}_UK+wJo 1#+\3\^W2,k%&yY8}!Z4i/wo;vy7v _3j'pn6UK 1v{y`f'=oZ_WmʗSj' -#}8-}l >Z!"'f|h 0<Cm3x}8"""gDeB]ѩK_ʏ ^y|9oWAtm{ e/?$#z?to-BbG~l|ZP[CfrP0 wcyܰ ˜ºu?ӗG}k~ڇ 9vwk178"""תѣm{NwǤr@v-߇V[{mAz vfӡ4yըЦ߇9lu+GDDDZԉ߷?RVVCuʏ{$okԖ.HYXaiM.&oN~p _WOGOSP%xƌčVam"Gg#""j p:߷ ?:5S!7j|NW~|׿%/oi=em}WPPC{%$k~z>hu+b8n pDDDT-G aFBɟ t.,"Ԯu&a11 pDDDT-λE h}[邌߁wБ#z\@N߷` *?6Cu ՑuGDDDuo/?R\߁kӮo߁st}AHd>UKk:"BK>\%yJCֽO}Rpz΀dZ1?f#""j pj aЭW/܏ŀC8"""r 7ѽ*PnQ߷n E/Oб7PGؒ'"r pjiPaYR}Q䨋U7=h*wJR:gOGz,=gO[ pDT!%](/YFZai(RhsQ5=o}KW?`yNDѯbߊћNTI_SL|.^}ֽ>w .E\RLV@sN\nMQuN0ϼIoJsGDEmz{.c'cYxMy/#'N.uq5B\Vۛ[Kwes˸tƀQ1lڻXRĞ=NjP9`xm8Gd'r']}7 mɴC.??)uWbZqQ~BM1 YyieZN<-nS@F͒J'&ԅJm@DTj#"""*@rss `#"""ƍDDDDT0UCDDDDUQU pDDDDT0UEDDDDU>QGDDDGDDDD pDDDDGDDD?w\w8Ugb]\et*I^MnsR}YˈUS$]sI*l#8""J* =모ٺSU],-s]w XɊ pXxs,|}}խ?fپrOѡd:vǶDk\6D&i >`R85]EϮ]ַ+FŻDDDtܱ6CX=wzSa6#N@By,b_'C{ୃW =<^Ow[Ơ?*4& HDDt'?g)=Iijhyh}n/v^b pgVϥbZgxE;E8W=0v7 /\tlE8G$""wwT*ӡRˡGK_ GZx|+~>z/M;?~UD}8""*BWFW!bd\ ;%3WX;0O\IpA+K}=W +z|5:=7THeN5uňi ^kTxt!O$""BMUBnhꝧ*3p,9Puao)RDo/L{YNpG[w;_OZBA_} UUm1S-T"" pDq2/Q;pDDDD| pGŦM?UZR^9~8F\"k!pRUTPDDDD^nn.N)8"""@ qR~\AAQRIDDDTe0i ??`@^^PP|4~.N% /|;ysXzm>XltvҢ>w±֍MF2LfFoi YǗ#tnnbfG_?kq;ZyP#msu섌 2ecݺ`OJzonR}A|R7zN=suXj/tK1\NBbE|F{\/=ɸ 1߬ϸ}Y$)Rw,>ysQЙHQuFwEf]3yL@BY ">V WxDǔOјXnEr^?@6&_>9gHwYw&""PJ(yN8-S .ab.x_ >s+ Co=fTvj ?̶c9Cظ|}޿^_yVX<+nMmmxv0?|9iϬ\[7}gϔ㌈V~bS ,l| 5V ꝧDK= ɒxd\ ѡ$}}fRW'J-yqZZ T(sJՙ?= iTUȻiTWk@UX f۱4iA>y9mFy4߶͍hLmwRJ/hDDf{eXBX-<7a閱E?8EBDDD[I;s,:vU>vRRR~z@ݱr6>~ʬ*/DDDTLEFF g@rrc5;哾jtmBʼ(;DN_rң]mKtwD3i ))̨T*oH dGDDDU v 8$$$U|۴ibbbpu"""JڵkrOSNaΝ@||<Q%)HpJaaa$+ݎ$"""")$ݼy,,,,,,,,HyZx݂r:z(?GT>qq;"r.\ҷ9bccwe\Y t۷OohX,i|q2{"''G"ܤsU:g{ ##) $j5 ;7%==NɃ1+c)LǎQվ޳U=!db#b+"ZB%DŽRUIE|5\=#= p$\9*dKBWiwTVBW;=PabtXzNq$L pD pn߱mKPTTTiI/%S<]r8W;=޶?-+_x>ě?ƒ_#,>yykBoW:Jȩw1 9=:m ÿh}E!8v>*V:[&ep V ӺujFmw6 Ȯ?s k5Q4'+,ߨ2Tst{/T݆NǹˋaylU^[aS Yg_97V u]ГLፋx~3ݮ@&~yDz?^LJGaP0>: >ꫛGWZƞ') GI9ub8yb/wť@?|=:lw|!$eASb̠2.S pD p:q#dH9zlˉ`W[ 9P$c, 2sQb8> EjYQX=E [<2#Ħ!/=|C6Fڵ/ p7wx1d"=/cf't8F?¶`§~olwżίz=aY<Ҽ2ҲlI9uS CyyKwz z-DAĂqF['ŘM(Ísڐu#7Of5g 8"8$FE=ݸ} ݇ӆUW\\,eSudE Twv]oHNFܵ0-F:=ԙxoD ԩ=Q w3-٥hٜBY7S%g}n)M/sY#.Nϯʻ{}WOmrnf骢R}ߚt|uL^^^3vw{cvxcW[L7Dvi^iiYQ!$++aDN.HaR2ѶMgcoϓs]w X }}:,h?g6Eڂ.ۆԼB*ext[!ސ {? ƒ^ \"Rs8, p}f|qP$׵ëc+m8Os=#KpJ/K {>G_OyΦ;t}L}q"@vaےOa"ipqO{o)LA-mZ|92.wײZ8 s&vy{< cW!>K{Be1Qz-O_xTgԮ?3+Ǵg<d<4vok<CЖz}ZiQ#az.ozL.33a:Y9O#eT/9p0oQGDҟQ44UapοI^=?Gzmd?QEݼ3"QFɥevok"ea6wW; Gc:07W㷷eeE훆:Jȩ8~g}10OSy?|) h|_Qϖ6G'h3R-JovΑWש:4bu&;Փ]oXnT UR?LߥS2bRӨ>[CCXSo Est{%ῄݙ4>1M.]= ge?QE=Y}mSʫ!{VahHoN&lk`6vS`un'1H}㷴5tV<47JՇ~] 2]s?)GѧsO|n/%!5% ug p#Ⱅ(݁a\R1鏩_Qn+|ڋKszy8~9*o)XV74|-u6=y#Ó[ݮO==:5by(EJ-p{Est{,u®@hu ы(.9}=^~dO{SlOʓDwԆ!h5ng :>FA~k2ld^;.M~L6Lb1;&Fo[FZW_2}4>Xz1<}> tӳw oO&`͞ '-ԞXW\M} l~or\2^BKadp}/#pR+nR$ńbloL7?w-ݡ(ˍݍ!]Z.nx&`ʮ?a)n՝@3> rTF޳hZ4xy247Ś ZǨ[maFro8*hwNjS#MSlx]3-aZmbm+[nb}04}Suou[57qmYkL9O74m`}_!q`VD#q!&_L9?m[FZVԾiIMMu:kH3;OZF,ZA73d pD p;p9JMж ;O} u53/m'9$WWZ֨w03OL=絡}|_vL9?Ī!?+p 8"򅖨|HjT8} C@L<FjZ5 w&THm p db#b+MD@ bR |e1臠O߇ u-{?荕߿'#!!*JVۦ!$%%db#bc#"toFdU:'vx!\ԴTkBI&8"88"#LCHRRGwW8WXXXxKLL$઼M6)RuJ~~5 ! H 4MHTuHQxOSNaޤsV:w CHLL _N׮]3Kw^ _FxYk= ]ФJrU霕]sNDDD >>,G' ?DUxO XXX*U Cc~^YX5 pD_x'1UwE""""xo111GbӦM*=?gox۹s'bcc@DDDT!!ek!) ##BIAN" p6na*J""";B" pv8ZMDDDtG04 GDDD p p%BWiwTVJ r{}YmCTOwʲOe}S"bc3x"py+9^;Ne٧>mm)pwD3(UuJ N*զpBJΉۋnm^&jvGnk\2j>Am4+M^tL3V u]Г]<-F޸G7^Kv~~P36xdZMci}%g=gENXcI_;6dxHy^-J'%Cte~3q-L_$=\o&$@ _G>~hj.$ 'Ƶj#dH܁fO-ǐ[0wh;f h{9 -:mqš- !3iر|0\f/}Ec'j_8GCGD pv+ ~K@U}ܝ yҠ[ezBzթ:2EyT즟 o]Og\y nimzhatVACfXo:D:5G0j.>E[OBjp UEf]ToY*{, fƋhިkՇ/PWrֿka0Z4rE: u{Fc%;Q}'+oXڳUveRS0>=}S4Y.9vf4_@EAxgF$VgeE7 \ y(U`B_߼3CZ ͍kҰjԂm1qPnMXl"x5/J>jlߢ6 @Ȕ|.MFE:=L,diݍֿ!cEZTǂ,,z-=gٸeu ){_Y؅wFTo O:; u "5WEHj]ܽ(@CaGvgƮB\8 ךTyVimFE[[S͎<d<4&7T)V@Zؓ~o˨Yn\ܼeEN4>uמgm|EDDLKUbpg?;-uB"UvKmXZGr <ݯR7o I/!>U2lZZ륻:1 FwWRaGP^^KR]?0 vZ)o-mH)(6Hi4^M7e&7tlp*{,k;U+]jNv+s3jk;gi_h|DomՉWTODTٕYZg}1li!3pZpOi\*:UGX?]Duz7!J~:JܚαB{.Ms8Ud_ε3`-U>wL MbM @ZpmF-c4^7p7O]_XcUn4Cp.G%,oj˂xiC<5o?g~{B [}'n/{Qm ïq9mf@<^cЌnqEVQ 'd4ُ+Zx^%<W1 s/yax" ?ܯz bX:|bXvpׇGl>f,]gO@&~yDz?^LJGaP0>: >ꫛGWZB܊xy78dqїow<сX~ |)i6v~~N 2sQr צ駃=\o&$@ _G>~hj.$ 'Ƶj#dKԶh m'G'Z^T_іeb8> EjYQX=m=>DX|4I i׾'H܁fO-ǐ[0wh;K8֨GL6m޾7VO97?GWZFZW'/D%+cK:z{n"v;IV\\,$]w- FFQx"yr7.HWsѴ^: ՝\ڷ:>:M7ZvsӠ!B Ϲ:U7k*՝ӳ++oYm:ӆ䌓#듳-[ڏ֎"u&uj_`]FL:}:.pv6ڀt6P͍h}n)M/yax4vq<~~Uo>צZD㽾'o9uF~"OVn:>:&|/{oo;ju=1}w;-no["H;4}c[c0&)p_w^== _Z[s!HEnjBɷzha {? ƒ^ oҰjԂm1qP^&tV{4Y(Ȏ×Ӻm;j4<0p60W-K }}ZΈVoO Ze[Զ#/}KqrdJk9=za/ԆT&ٴ~yDst{M%-ڵyax<\ uU~ѱ.<_xWM6 j(k> Qx}M/) c5ݏ`ksf)DzW[Rl8EE|\ :y{ï >3OL15sJKޏ~NM~~TBvv[?8= v+_0h=~y.ؚoExQ=lnA >XG:իAeXB.-jgi]hy[8vs1fVSu[ڴ~Dst{ e\eٵqt^:_z鱫2+i=kE{=]\vqX9UlZZ;p1 FwWBκEm笍-oK':NjްߧР>Td -xԭ)> Mv,X:/lu%LΨQ_9jk#{+o\P>84E>a0ag ]H+rÄ1w؃n+^[E2Ҳψ(ЦSMm/n[Roh7PW]J2}7szs,WNGuz_r٥~Z =MiY:UG`ݙF~Bd3YH37NO-8rs1iOmPdHB)82W>GWKߝIG֎{Y估uɸdܼxoF.WV?SW֭[BEpϢQhѨk#yܴ: KtԨ Y8*]T ?,GX_8O:pqeڟb/1Kk8  \ywj4c- nq۷1w]hyQXwP3\=Q/z|<ۼ7l>ݨ^ B^sUŲ/yax]3-aZm6+[nb}04}SuoxDd865lɧ`6;/?0+8&-#-+jݻ>~扩G=06]}sb =)G<⧞X9D|GDDD@W1k7 ~oc0Rܠe֪Q3% po"""" &W._c~Z}Pgز'1X{8q8RdGDDDDVZlD^ũs@.~l'¥ HMKEA?OSn p pDDDT0XXXXXXXXTaccaaaaaaamڴI.,gSNadaaaaaaa&e)0HT",,L~[DDDDAR!N.,,,,,,,,Ua-1UA pDDDD pwG3pDDDTេ;~8mΝ2""" e)X q pV\JJ 222*wO 7@';Z&"""# pҿ""""NdϛO{Zjehϖ " UcET7+7wqe}Ӟ \QQQ$r銐1ehϖ " UcET7+7wqe}ӞHO}z:I!yZhqysuak AkϔۻSF/oot Kp*>٨=SmĄ´q/^=aः[1{;uCOb#6-/ .qoVQ 'd4 g⌺ 8]`/%]ѷ{a/_)w$WM3pI-ZȔ|.M[F1ۆO<<[L5[aP{ CgG88|9nE7 \ y(U`BֲR_ +DvGI]AEnҰjԂm1qP?Dֶ瑕_}Iź9~h}m-/9ǀVpM'D~aSGh_u;ENJzm/sˑcE/D}mkYsv]x YPf\NJOѠAkܵJGWtѵ޴=r^;d}"`. |g^"sK3h7)Ԕ<燽Ifsf+?+UHFxgT/w^:vb{kAq?jY8UTBcZZ{`GZ~:?m|PX9,7/w}|w-ooxAyhm p[[S_}VXA_0 ڲ۵.nv+R.@CaGq$- FݖEEAt !QWxZ;vYڱˊ'cZZZvAѱ"ޖVX17,9K} t=w.fֲAµ+Kqt{Eǁ]M/g[ \9/}lC  x/,(%G/X{4jOY~ڐyNaJyesyM浜84|-IVPl\h OW, ϰ؆6%I~GݚƒVꣵu[[miHyEJw`Ӣ~h:DֲR_LZfUcTYۢ[FGdGzkۢ8-^} _xUs-E :Dǐ^ {35z}kc1j+rm9nEˑcE/D}mkYsV۩Z,AKҵ+Kqt{Eǁ]M/W˟si%um}1wےb~C{ronY?AD/Oi\_}skOI}U{x^K[Ȯt~ZIa6 AC3i4"KVh8k~ߞ4\]맋ՙTOֲm.KF:ݨm1]>DֶGl ";E 0jLE^Dǀs@1&2]iykǠXSoq+_+}!h[37mۡ9c,+kqt{Eǁ(9z[^D p2\Q3͖EWcl p߀0wbhL~[:u];dr FlT ,y/zMۢe-.%!)-3pe6 Aqp=اФ7?< ==mKe:}`+;aWT6ghEujƁ3q11X=n7lEjJ٬Kseu)ٮH&{ˉP!;%kꆆOeq[:x/Ο9}>Dֶ?uj`P#ZO-E ;O='fCS;>œM=)OcPtȩ7lO4^ȱ"gQD9'[.5aQ"A9hMkJG+Q^q`kDzDg7`1 6}׳?&'m pzq^[<}ؖ/0|p_ŷL]Q)_HB<æ,K nݒoQob}04.kgTmkk2NPrkG0jKE4mNX?7[kGyxx͍ݍ!]ZY =zkJسhZH׀!CsS_zR<5;f5|,n~~hq8e946GmKxy#8iڰIKLwE^Vtl|Hfc}:gڴ+r '/rX QD9'Y0v^^ 'iݾՅ Fo/=cv~S)u2%xy{c`oXSr"[שѦ0?s k5Q4'm>) o\ģ,N*uvEct: Qcxؽj7Ơ_Amg1k_aS Ygq,m2EǗHֽ'1{ֶ]~9nm{[+{ODN~ѵGk!w{w?G=cgؾhyGF5ؼ=ƪ<#:V H$+}[_}HI>[Bcp] !+-{ߢMH)2'W`}AX$d07 ;cm(;G?E%YkG=HQ"+9 ^AG [Å$]V 1`}NDX|4I P-y ZN:$}e͍h>r H sE7mߖ͍hyѾ'bK~ѵGk!wO4\3?a4V/Y Q Щ; '40`rҠT"t*՝,_Bu'Wt ҆\QNtQ{p UuӢ`|_K=Ѿh)47Ӷ*ovS7u%C?q-5#{|Dwx fƋhިkՇ/Pc'\SUyWP\cV{#ѠN Z2E4hHsL׃F-U_'oݶ龷uyӾ]~[ڗ3ˋ-='j_?G_tek1e͎rbmX;Ec'nwܱ26wE[+G:e{4 I ܗ/ĝtwOC֖{?xk j#RpW. -恁˶!5Pزt<0; {? ƒ^ NLBhh=rK1fOd> qrZw}]z5zD<+jj_@}N5-˛hE뷥}ѱmnyѾܲgD=l=>ѵCT/:Eǯܳemrc%ZsG46*uX9/-ש2p⃹2t_Ax}g8bsk>!:%U77:zS?}kW9w鍟W}6PA_0[vI}Mק[g|t~mO+NCGCc-_ԨҮ|ƥ_ZիAe(TVEž|߬.fֲU YJ(ɘZf~*@CaGIBm< o_t|w|mhej-3+Ǵg-M[ZǶ{Yjߖٳk'vEҹ'w-m'?}؉[=wDcc}immNy3ݑ6߁;`ـ‚O?gbHzMYBZ7ҽUEШuyU ?>UC +Rj OW, 0߰MߧРVlL6xԭ)> M1z^SOk btQݾNJr7_ {35z8NaOҾH8_?0 vZ)pEN Ju±xDK܁h#]Q9fX [M@"ypL} f#,*B_<9:Cxb648S<ۓnX+0 E_xrO==K8=M7;EWvh8sʹ3z6 Aqp=اФ7hyQD.ZۢE^ι!꟣>ѵCT/:EǯhE5c%ZsG46*hݗLܙ7`1 6}׳?&'m pzQf ]umE[|{k,}7i[nɒC37<0{bs7,EMP3h^g\J_/H{B 6;}75ex<մ!j8Մg+|[5![rѶPl>i4vT ?,GX__;A_E{J7[ԾY'{ybahz] {KIom_N֎m}/rdD=9z];Ds_kܓ}m4Yc%ZsG06*<c辴6ֶg| Un#"""*k p pDDDwo`c#"""88""""JXXXXXXXXTaccaaaaaaamڴ G K|]aѩS~Tdx2ElT*K-L""" e)HY'/2*R 8""""ѣG8"""?~sN"!!BHC B """ %98; """;V8;88"""bc++I+;UV&w}<艈WTTTx"pL'72 pq#dv=l<>rB_ߺ}Gv~]1pL/{S{~kC{aĴ3:I_w~ ^R}oXSw̟6(n.X5<i0ި gҕie.8nwgxUϷH{b_q%6Q-ҳ`Zϟ q[.Z~[+qU$+v?,A[:uaID!"\aӷ<3t˛ Cj*\.@Au|2)4?uj`P#Z pMzCdʌH&ݟ_AF+*'QUp}xkhWVS]Yս/'-~ƮdE[n ްO7A hq8e94FwL M1!pSuoGog7Sug4l>ݨ EТQ=/CM1'YU,kKGDDD u32tJI,;;[zKB\AA:LUHt"\OEr.yGDDDtZnn.&O} ٙtyKue޾~?f#"" pR?qRuyyu?Zʲ=qc#"" pҟoqY.-mV~sg9p~)\YjZ-ʪBg0$ׯ)IoJwf9źҴTo8,eeN )=K_zqޜ2=d%ude=Өm[UHd=06tx yX?CҴTo؆,oX7_vyPk.H6ȺeANwuX[HtL1UH+ymWr }muM)Mر.2jK RcX'}?"I+gɛ\E"珬CCzEkn<\jjΡGmaB4M?"y.I?CT*ڒ vG={̨9m Lk178"""cnw_Q[g,ǰ.=;*.,*2̾q^UYVam"QQ pDDDTNP\?$~ΞuV&w?f#"" p))):? *M~ umS'u? :+qc#"" p:v? Ww.[&,;pҴӮFD3Q$+W|[?f#"" p8@fqc#"" p:҇񣣣$&}CR2GDDDt"]å˗ev><>_ ^xQ? pDDDT6mڄ\~tMd#""ru)ر';I'4 pDDDTes$GOGi< pDDDD pDDDDGDDDD pDDDD pDDDDTɆCVNIENDB`gtkhash-1.5/screenshots/readme.png000066400000000000000000001576341431266303500173360ustar00rootroot00000000000000PNG  IHDR82e IDATxypUWw! 0Xmc@f̚:&珞?:2#.ۙ8b6#v۝?$zh@O{Ͻ;wϢ0ހB1ɄtN~|\%"#L||BYQEQ%mJ%iOJ8%))Io_$B@{ݿD @(JhnB5tI{C`hݿtww+$G!FधvT6g߆Bp(tB16'V߾ӧw; W?ިD-♎p.i3w^j(cNWw7!kAjz_^q\ވg?oP:K˲!N;CBb:.5ߏNRR"vGBLL& Y̌ t8=v;%;+ku>t륗(,Y^WsFi別a}~*R^Ϝ=3;x{>mmmQ} @jjGfB\8>cܖEVrԬORdEM,|Ï(h$%9ö6z=3".:N"܅8EOuuuAjJKKuXϧI[O;!!6.g8qX,&O_Cb`08i/Ne)b=EQe׋;юvz 'N` -/Hr384DŦM4]]= z=IIIlټh._Fnz=q1ٵ NUU8].rrxqvjXfϞ7q\m7oRVV:e`ǎn?sSi)-]͛8N]J`1)-]Nz%?57%b[HQY@R'W';:|l،F C@rr2 PTXH۸nrl$&&FY˷7ntMW]֝O~bAKk+Cε7d%v|~?1ι 24{;=W.m^OYY)oܠ JӼgB8ӎ~V'С<]vV-@Kܼu+ khljv1u䷧dӆ CCC M*y?bCz{z#Qiu:ba˦amܹ{{o/E8bMcJEII #cpJKKANKlTc]| DPT#L~;T!fLY@V!d Xl&q&B#fRRq\74L9d xŝ'hi7߆_BT^D}c#'2H'7'N> f}x \JR"02J,gUOAQ^V6n#j(c}1I^</գct!xi@0?GL0nGnbᥦT^K;MtTԘg2:vl1g+ _W_}o`u74rh^ڹNg_9V.|~?}}ܸycúuc~NHe }]TT*UĵhO>eudfd9.>_8zTyb3))m 76 B!#ؿw))ȶEy#]t^UضuN#f2GB!BH3JZM9zȸ@3384DLt4;o#:*jDù ;dfOxW_nSjsL \>KBjH/fV\9.&˗/ /꒑4><1CLL̼W7pu`eQ/ɧL!B,d@QN}+_\~<{n Xj_PXPmKf{(lV+p:9|IMI .cEYf6e~[~]ȧL!B,GK;vL_N(e+x<9'NKMe={{QT( #=ؼ̤̌tt:%5%˗x!%\" Ejjʜ]r|&%&<k5x}sވd2-P>' ̚Uf/I xƚU%eB!p Ìфj F#n;bۤ36( 33c@cS3jtMyi]韺\nw8-ù`B!?9DB5j).,DQB0wE!RFbȤ A˥{}F@_?1svMy9ܨIVf pM/i)ܹ{(#=O t,[wjؾKm];oOB<>L]7H12r $&tN~|\`ZbW8_y+׮VkdG9;ljGmh4^~E_\e%Y(R.^K9t2OpU6oTʵUl @T %o)]RBgV,&3=]>}B{?&~ƶ )(Jzf;1Xoo/IIIR=|@_pR{Oݟ`_b!=r0|;z/YYO48(Jh3KݳZ[[ua B,=_6gyL[%<N;}8B!5^O0G8}jzJ;֦fP(]F%2m!Y3M{{^G̭_K&!22nB<>8];jIKoeǥ,7AQ/Z,r: yr409| !!1Nc'))V;{#!bN"q?*:?;aVgSSvQM:|L&Yj#3qzvKvVy3G8NvRxfz=_m0]#&$6oHllOU7iko'5%ܑEarB|~*RӦ})߱}Sikk4|>:I!BM3A:+9/mPd E~}=#`4IIN ^OfF 颋[gTB|a6}~%??3p88N2ӉENy9n޺MA~jG`0g'b``h Wߏ6|PMSrX̸#Aywjj(//괧z3sr ͡t\nB!X~աPsj,f (Py7o ^7ڲ2pݬ,*z<g4lڰq>44ФyozVۇ%4t:ba˦amܹ{{o/Eww;=-蘈tVTPR\ $.6[088H446f*[Zp8ϧpcwcݹcVnݾ~200dgoB-So2gQk5Z())rd Nii)555h5ک{Mٚj d|~= Qyx< &3#ܜ[Z8u467JTN)IX"ԿŏX, (*\HAeLГ{1 @_?qy08犋̣><<~}sӥ_X?|_gUOAQ^Vƴ4i$T0M>ȸ!GnnC:S-B!M(|8fq;?@jj*zO˼c;DGE pFv&_Tu|׼ _G}C#kj楝;t|剑s) jǍ7iyں:6[7&PT^tp5Fj 6&wۚ1O{ y{l &XBiӟi/~rjS6?02[ˉld92@YYp&?8B!@ |tZ"L#غߒYzN۱}ۼ\gbb"02] ">:zv9>,B cTݺxhJhlPf K-I{{No#'8.0x=Y/B,lFh":6콁'g׬v fVt+"b6쳚r ɘ|\!K](rӅ&6>O&iABผE=f!bRX6L&3[0MKIN{{b}>%B: -'))I Kzܘ)a!$ق둌B pF( a !Z IF!8B!B pB!B!B!X#*+/fiZ-%ӄB!gi}_I !˯+b[jJ2dB<(ӟ9 ~=rdD(p OYm|B n{wMx?B? hݣl޸^f(ɾ qfqqlRALt}^\ c;y~mOLt?!X& n ~B,`=$Rl~3" ~ )`48FW|E^{u?By9y9\y.ǥyF;m6p~B!B<JBVEl{UgΟgphhvnFtT^?)/IJrҢg2g=Eq\IIN ??=7n(ʢ"^(/2=LyY74ۯT*VPf t܅JzvNd=u99ܻǁ7^l6O!xZ?hCm_ 9z0&iAVTz^988H˃^ Z!.&([T !JwߣhHKM;&ܯn' RXP`.Huz=17l\'_|AKk+֖c`܎BdLҠR|i?NGъp3ܻGCcS8j4K)پu II_!&rp=|x'jKnLǣeF]Ԧn7'~2#6 E~ Gz WůOm]}%@~|C7 k~b1NbK IDATskk8 B!Zp80L^" /^`0HlL ۶T`Z}sxގjeۖ-$%&Lx}xc2JN_{4nrzttvbXؾuk<=v;/_ۋ^V{(o~)~qtyXVti;Yh4$Ņ+XvT,!t Ì#&lV+X1W Fnw6s8r kY7#N\ΰAtѶN艺=U_?IKIqA2F!| ?0z0$1!EEܻIMMn~]$%&сb 4ro|e%|cίڍ*2ǝ7(\Qb`2A6mX?a ?קSXP@wO^`0;:dmln0_N'>'NH3 BܫE ?@BB/)/-%*8 B!ͥ ܺS-x^jع}۔CR(ܭEcX"166VC}C99ܼuԔd 7ֱm'&z$ͳ/q:2˧MlLL~B!OW{ז=xGQB\rt:Cì((`UȀ}g+Rf`pps8p$ؿooƞa{;^5lxᅈc]ʢk~ڲ2֭-?M_Wp&;db0_FB9VػW^ʵ2ّPHE8,MzE]BERRRHKM 8?je1SRy2PWvhx*/R.^KYY\^ ?^̹<8nB,gf':f9N2>Ȧ 0L ;PdbͪșP31LܺsKwO&,_RiT.!r 0  ;V~8sv3;m]BgيWo+g~?N !]f2[xA>Gz^Bgۣ{<%B!>^C!B!B!BH#B!̎Jv3!b BdF!$!xf]N dBH3":6~{PPJY!3% g&:6N2C!$aXl`=](!XTj5d nB-VB!bYB! dB!(" F5*T*d+by8n><BVc4dL1@?^EQ$T* 0YU@Xzj4wzIAYs$`꠿N\BTeBꊐg^HJMbB- E02+=X ɘRO.'=]x=nb# brVO]NN^1q {u Ϊ jyMrl4Z+bop9آb"CVc!;၁h]NCddbڤs9X63st<_8 W&?ŭV[9 < VY5X][gMIH]<=OpHJMGH)%AѐNoO`ɨ.\R!>1pW>S~!"19I.7\)Oz=*>i){wxߡ!z=II[[N|U.S6o@aAԕqu_-7IaH3<7[XR,6mo7&sd3-tu<_ݘ3m1bI1[mtu-W^ĝf`a[YmMMDCjJ z+^߷o\sB%Y*ԕIЁ=e^PB!f"N!4f EQ.J9#&rK8׫nrw=!b O4X׬Z5e:9976Floh$7'gc k(*,ڍ'm@Ӓ/Rʤu`6[PU*M!B,g-\i,ޯ܅JBg/TR3Zz562 :rzhuQ}-6̊RW&+'N}"upB23)Zں:jdhh8U%l\nڴt:ii4PXP@}Cy(LL&|>Rp֖c4LYW~qP(DUu5ߜCH-y#BERؾu EEmcElްa0t:1T*ț+hDVjYv-aC l1~zQFK!l[fF4XoU:霽pfV &ol"-5{ᱏ|ޯ=^߷Nz \i4ZWWTO$L|8tSG撟;3RhRW&eg4ihj|E*6m$3=`0H \f{<׽ ./nxZ裏0 ;R{3g6uj76 p>AUu5F3wub "uE]sUlHh9byHArsغyOdgΟgphhvnFtȊ}}}x {o/fݻ^&.66"KW2pmK3^޹䤟 )[3=ಿ4!LzѢf=})Z&:HIN}Ix<{w9=Ͽ`mY)YYq)~vm|*6>^;-hFE (uEꊘg``MޘvrA~%mrX[VJaAwdzxB!N5JطwN{f{HMId+(AnvqY=H:/ȃVl_ų++3O"5A[ZYv-*p3Xn/mKqqq#=E pL^N:n>BťRKH$.!Q2CH]x^|OeMI FCjJ CCt:B ,*+x /Q_XE`( Y;75  +^`k T|G?_fY냇$'&b0A͌cU^L0 zF8kjnf֭h59 !Bz=PHA| Ә9ꑀrv{h>/{yǯ\F>B ?bgI.?ù{1_wq:o[r$K[HNzmWOͽWO]C=B~^ތc_H~-F(hjn!>>P0EN!bNؘz=ͭ-Sb|h4aZ9tn7.{~׮s56oŵ@  @my_ϵ#&O^v<&k'SvEhPEjXr &cz[;oZ5AC77XQQ6RSRh}.嗧'({ ;J !bFԳYRilnzO{lRb"P{B `Ą wkk B8].^oXĶ-445A0̹ GQCTXҸ|jb4$&i`!q^> BgC?fQ lhh$;+Պbb1SGݎIM~] inyrg_!ϧYZ]Fxjt^~q4*{wʋ\vZCvV&;hػk/^+F~%b-ȶx D٢([z^caՒbɩ{{F»G%7m>{>Pwu7eFeDꊘGBrZK KF[b Nk~ I5!  %3x9g` )8%H]rπۏp x6bccf̴H#/q:lR1q jm9V7nJB prǎĉScfv!OI&!f?Ç#||c}e0Xň]sxeΫ( p]>/ lߺ:kc9].ɧl޸!>X^u_޿-7Bq9" B<# oklj"6~b{餮/ 7\oߦC݃bahx}{`Z|.g׮)_܅J,2+^?tmlEΏ0sd B!9976Floh$wu k(*,ڍ*`jyy=7&d2b3QQ#Sgg3088kNKB\2+0lAVVB!9קt 39YY:}}zj؈``uN{ =$&$5͍[U.^"늢(q TlHLtO:r$OpBt<)Ca<& χ(nauG|>ߔi s._xaF]xuk1Rx˼T*~qGy_ |3D=9$yΨjBXRB``FJ%tQ!JA<tB\A^> ]˛qN^'P0zlZj*6~^o~{ޯ r8ͷlR1n^kjn o.QbyшZFղnZN'ǔ=]ԌFN)ed8=6M]N,Vdr -5̸:X \NGB\fF:g/Ղ*6m\ue,EQPV792 pcwv`ؤŒ l'!1%tc2Q.P(Hsd`/R Nⓒ%3Z&'+s*^yň.^"99Y8^up0p(\q$F3\A`^[؋Eu`24o1ROsS1DE7rK~a47d|7v.ez@O{k Yyr!uE^]oT~Kb-~!Z݌NlQђRWI:8B!Xp iom! F5*@+RW8B!X:T*q %$Jf+bN(Z!B!8B!B!B!B̓YB!PjJdBW#7Y!BEQ144뙱bPTRW!B̅^;>wV 8]eF-+RWĤd B!chYNjIHN14((uEꊐG!KG0UqU7nJBԕI !zèՏ||c}$'%nm9qqiޮ{p{/ lߺ*)B!gFmmdef565ew=p:狯} ۷i}}{`XPesF|k?WIϞiPb| Ё٢;­wolj;fhx}{`Z|.g.)H pv9qB!B!Jh4l y 9976F4Zɡ31Veex}>ݨbϮQjyc>fhCtٸf3kgefP@h= @RB"'M74iI| lVjګ{ IDAT9&dgs9)D p6IXQ+B p:EL4xg++3O3i5hCSsF ׯ#-5u4\n7U`0XYTȩӧ))^IUu5֭{uQ}7W( @?}r@ HB|<63ڻ{ILHByr3<0@NA1 nB,ΗZ-*Bp)HKKy:R2& χ(nauG|>߄ އѱ *) VX.\Z"}LK[[h[uERÇ8;HL@i]s/ (HJMGHf!Xtt$3BA^> 4467N'JE("6&cRSYs ~ޣ~QQ/_g_|Ig̣E(@fPQĐY8x㻱{ݽ^jgugEInv߶׽178hmԨ81$ (2)3E *L4Fo-֢.8;öZijj={x,u,#ض E[{jVihl655ͮ݌L& ( KԀf An`4rDq ?y <]ۼ_Xd_Vd򢹥KbA0d@ mnnn$cǩohۗHOιsTWWKuM h?%?*}ڗl6ܴn.W[ؾkG'26U wjƾA]DFt: V dRt%- 1 ~rx_od,!>1IAA=IT\= L>_鎼1%ED8CFyI1ђ ~A|Epk e]  w/o*.b6hZUq (P|E|Ep,QA?*Kܐ/o|%   w* @E"Ka6nĉ7ngΜq#FpeQOɴi# p86m֬VbǮ]]Xz ;쥺eMM|jߕ:w>M?999 :+Wگ-^4Fų>ٳgԱZ;1{%11w7pIzJܹy1l0~.mL&/_=z4oٳ̛71c0{lGם333;w.#Gdܹ7t}+ZL2ѣG/ϵZDߐYww`0{n^z%k{>ZV+aaa7 zJ0|sS{_8{,_ zB_ &rJ222xWضm>>>~d2xb~0e֭[ǿۿyftSZ,Z-|駼Klٲ9J;;#hd_Ei&4SY~  \㖖EEF_XZ~A!Qx |a؉%~d⋵Tqw,RTvc=72{lƌó>k_USSŋyǘ5k}]زe > {R'99P z~3`26mMKZ\駟f̘1ѰzJ$''3j(e6?kF||< ؞fQQQرcQդV)++sUV1}tƌ_cǎlt]RRBcc#ӧOGSOqU>tH繹/O?4.]it~cĉL:۷;{kk+`޼yFΝիW9uKJAA\fp"cg6mmmQW_O[[|}T={ퟛ9q4S'QuFChHz]6vog>{=bbb8y$fsI*QQQl۶{9OHHbWzj>c7?}Q__ĉ+V̜9-[To,_^xzjW_e̚5d29LGaؿ?oMZZ*z={Mzz:8էh?$<<}K/}vzF.\I޽)..V]wA-l6Օ4d^2+""aa/6bcasZWc2lT*ef2j5ƎyW*mx{{wkW_1g샼2N<ᅬ;$''Ό3փ%\s`0t+… կ~Ŏ;wIyѧO, +Wd…^*++={6s;w-KoOeilld2Q^^֭[9{, , 11pFŒ%KOwA9;v,˖-XE9uDD72e֯_didqf[:>^|E2W_ߓO>^'11Dәj(K,a̘1qU|}}^.KG {*gy^ϐ!Cׯ`.\HZZYYY|GtRH}}}YS]]}F̑tβexȑ#W_Ñ,ض_~SMg8_YjkkZt:mfn{z*!}ޢjkZJ/]& ZWJ@p%+NxAΟˀӵ fR]S_75R]]ðGJUVVr-Zzpp07'k׮vQl:tھ}(((୷rJbpyNg4 j͆? 44tR^wnUYBCCoz3RlԩSQT<ۗǏP555XELIIIZLM4~)VIg3,Zxϟߣϥ~j)**">>Lyy9}uJAX=;~ϐ:,wY?-Bѣ9xOIi)G؄' xc9M1l(_X=֥6ŠozFiYO1 Lb8s6ٴZ d^^eiljb- }9Y.@lL4DF8~k7;t0md|;6t.j4pwwLYy9 ほ+r -.] ҥKyx'0$$$g9͍{b L&QQQ,_'o@,|g曨jyqss˹tR># `Tϙ,ׯO]-[h"fΜ{?0n8y8zw??xw׿5 Rg>}3g< $$$;ʕ+ikkcذa7͠u+tGUU:rI}7~) m:QqwwW_%((i_y,Y„ ӧo o >}nz~0gs׳}LJ`@ z,*Z-78Ϝ%/) w/WZZZ'm^^3!5U3w{OΰϗinjoPC|bx pW{&N{˙|v1Ey9]v<$33) du n||nK|o?OEs |{QPTĐA "yz= JJ;8Ns{j;+Tqd7/+/(4j !2-AAI).)xf{s8j埇һ7%&ȐnGVq(79p"&/KyTddiϓ;+\y@ln,>%%9{lhE  DGn^yy\D]} !h4'Xa#q11 JzK@{﷨;N 6H >,)@p` :H?bA۩p ~s&+n2GS pAARڗ:71G5G>tOu/ X,*/rQR_@\_~Td ޜˡV(EAX-P\9K N̄T{1v':wԙ3^ m l68OٌOLE̓L`ikkc1%q/,d?0{.m8 nYجVY& ]՚*̓ܳ<%8tCpt[BCqs{[qW+'>.O'**z=Ç ǻ}nd߾\z^҂ZZi6\ƍȩ^?%W<==IzAcZt:7%&ȐnGVq(&-aX8_\BtT$18reAlfMZ;wكV/^I_ijn&)bt$c=^G(77siRe KAAI'>.ܼ<rXqz= !h4'Xa#q11 Jzwww=~~[BP`sItDGFr  s&+Ҁ9OFj%)v3hnnL|_b/}r. wp{|j]J[[}zbرk222;4^v(0&!GA+*SP~#NB9®2S .*.9 Xz оYh=MMM|k7#Sw Hj5,Z%P^^,ݾ3O mmmۘ=s---|gϏ\OLH18  ~ص Zp32eX1d@nNC?]cBJfMZվ ֖Š$q|͆fMˋ斖.ENnK]r 777 74PUUM`?k$'9ɥϿ\{=h*-aɏ$A?; 6|}QT˳"]]feb91jl߹N[[pVCCC a еt<}).-d27 w+---Uj|}}/V+hll`𤪺Ʀ&|?vLEe&88~1b4 p>MoMBBBn?b7n$ӔƍN[[I8G'zy?HfdvıVS+3hG̸ѣ\~湂t=@q55L`z)iixz$ IDAT j\Aǎed:ћԱcd'vJ`@Gt"ߟS[Pl۱łNch4^;۴'j2/ 'AZi3uuuI9Ku7sN rss6m-dYx1466Nj/i͛ǯkϟjwӿ^~egΜ~ڬfɒ%dff믿΀ gϞe?@^xFr1uWzV F}zJEZmh47 ӧ9|oMlLOLޘ#QI˼LI{\~|EWfMs <‹1FTBYkEEx7;iBCBhhl$/?۷3%-(%ƺaٳ'ew`0{n^z%k|ճZDwZCjXj{駟K/eT*68p|^xRkkkZYpY׿@Iɏ$w%%%Gə;`4پ};ׯgѢElڴ F믿΄ Xr%+l۶ ΂ J)A3jAyCUECj\VU\# __~'*2.N~A!QTVUv~Vc'2:3&6oaф}g>bRVSS^`̘1}`yHKKsZÛoIYYO?tPSSC}}=>>>(زe >`A/O?ի& @Ӫ;v_[j6lʕ+`{ .`2R>G&66h?JTڧ"Vjڗح^JbbbXl>>>8p?ܹsO8uIIITTT0vXj5)))jq*gws?sTtXl6+ș, ;b,7$:tF_Q[zއrڀndD=۫Rb,FChHzW_}^zm6y.]ʥKOf,[e˖9-ZL:]vԄdTIMMeL88QWzjKrrr įRCGm^;v0e5ȇ~޽{?>/X+WΖ-[زeK:RVVfc2k,oTJ,_ܾ,̥6'|ҥKٻw/?(SQO|P?* @"cODt,~.WW$q777B) Wz=& fOY3k^= Q#XVVɓ'ypww'66dc\zоthΜ9 }>_TQؿ?] >}:}EV3vX+(Kcc#&rnŋy뭷(--uO%Y͛|'T* .b8m󫯾bΜ9šV8p aaa477V1lݺ2 MMM5;w2|px ^}Ut:S9ϙO(Q>8d#W}PAA[>E-6:lRPXĤ'gfhllDn%|NEG_wl?e5553ߴh4b4yg4iqqq.]+Wŋ_~STNy+&Oܥw}g}Fuu=`1]zN, < z!CЯ_?233 Sԧ,7/Y1cPTTիW۬soZtl۶ pB_䣏>"22ҡJʔTOF N}PA8}zC)://OOiۙΉ~NڵkN^^;l#rwT*, ϟ'""©,ջx"yyy z=}(((୷l6h"unZSYYɑ#G:WSSo+'ob9t$KhhMAJf)'h4j6EyyMmj)**">>޾lo߾ԩSQT<ۗǏPl{ƍJVї҉QN@dڸZWGѣ?ϠIS~"̑c쉱, Qjd2aXX,L&V+{&&&ﴶƑ#GpႽuhnn̙39s~"8x _ .n:.^Hmm-+V8EY͜9#GFo[z-V+K,ˋd_f5nJRR!!!kMIӢؽ{7.,zd֬Yl2p@E}*R[[ݻ>"##2e _|XVN}aΜ9<3@ppS(ɒ{?0n8y8ϑ>dX,|g曨jyu 0~x\¢E"&&K+d&L@>}xjhZy?w}~_3h [ҙOJ6fQ[]IC]]O WW~rHsS}A3Dwz_H;TUbjm! 8f< O_\BBA;MC X='Y@p uWE++C$Ac{4`>pusy "r p/PRZJѣ466IB|?ȿnfF Jho /,ߴ(%=W_oe24o'uz$j8s6ٴZ dU: dxf&E11"e}zgUiljb- }Ɗq%A^cTillv.WVj/,)iiiaI;]?},xݐz&Nő~0n'';b63㉩=<8yL~|Mm(sP:DMA=Mxxx___{< 8<7%0oniӀZBVu9'v9M#6o}r }ӓSGRާKhffus*OKK wbPR}#_qss#q;N}CC dȠ.\kj˵Rk8ˏK4tABrCD.R[{S^T*r낂BFwy{͑Ԅb l6ߟ8ApP:v[M&ŀ=/VrHpJKK j__l6ٹtž309,?v VΡ/6F ,N;zOooшZ- pgZ,46Sy/rZ9AC}=j`ƍrs$uN~AQ|Wh uBkj8 )iiA_  ȑT3q|j/ѕeh4t'gˍ475hnjjm -]bAAjtzO|{w={˙|v1%ED8CFyI1ђ~A|EBA)zO(BAn3^>TU\$ 8 X X*.aGA;N/j(/)b1TG탯__$A.BR_@(C_$]\ۃҌM wz Vǧ,AqWOQj jPG奋xy{_" Ninj"KA'CVc`|^: o[A@ڛ5 A"38@KK3(BAk0\*+gg٨'c@R'j=7 ]ZNVWajmQGLUEjD?E  iڣZꮊWW pAA{X=^LI__?%j  q(MxzzߏXi3# %4$~~A!@0˕UhZ Zf3zf<13Or0=ɏOI8G?FLHMϞ1cG:s Mfþto[[)iO~a!y3gtit O1l'd  ?{ ,477-7v|{r~ӓSGRއn 6}r --xzPU*)_6\ƍ `({^ |ÒܴIR` p~1˝lMFvvv w~?/A>Qd=JtKmX,IlL4yșNR+/`bf37ob5l߹TNVN._毶R~>t$c=^G(77siRe8%ݸW_nȩ3ge6mK7Dصvo̓>ϾXMY^x1iii5g}gvɼy6loҦ+0tPV\if2X|9ǏgѼjyF9sʺzqĹsxGoIOOwZ733s2rHΝezY͛ǘ1c={6wLI"o=V,J>qd[)֕PҧJ$CĤ4L6nHƑn-s8 DIIi)f^~O?/\bUW_ϙl yr659A`?Xk\ׇ_b̞{Q[{C*zef$<<<Ĩ7ڸ'75Ϝ%>5{71}t~a0ؽ{7/_5jϟϞ={~6aZyr/ gϞ+\O;`4پ};ׯgѢElڴ Fs[∸88p=^`p7/7 SLaݺuۿ7oFV3aV\IFF ۶mGLI.)))o:Kw}wVOI%U_Rѭ~ǜVJt&#_ᇣ5(Uj3''7|2~ٲe >`lMlI2[[[9p1Fs'p)}X`}jٰli0zyҥbG+&01sdR]S_`R]]ðG{X?FChHzO; ?T,Xĉc%F#~!{eK477+iZyW:u*vիWYz5򬲲2l6'55Yf}v1DDD:zMqqӧټy3˖-cٲe\P̑^'|ҥKٻw/?OOOyt:2G7o}brJ.\իQSzߪΔP[O%_rJκCIgJU*s$g||>U_9VgP_Z!$8qG\\ACt{hD_P@`@Gtp"ߟSR]S gدOIKSOP{ Z.r;yFoRǎ:7(0`ێX,t:cFvύFMVJݎhh42i$;;>3F6kjjb7=3<^gȐ!׏LZt:mfzz^?;?.9KEEaaaN'OV껻;˖-3#G$>>@cc# ,`…ŋ/G}D``òf\cɒ%3"{(pNeo;pK:SB'o?zC_R/p3R,/ ½Flyz :!b4fϘ~ӵؘhbc3m1#G5mK2ߟ;,b$eF=.rJXh$$@Bv?YQTΟW pjjjx7Xb:NHMM8|fzCk xnLT*l6aaahZl6S^^N߾}^^w2G}ܡ~*++9r-2tw$VZSL4~QZZJss3SNERӷo_?΀[oDV;=QIkܒΔ uꟃ rKzR#_rEgp3ڽ;9ٳخ ܫxyPUqZ7U0zWWh^ba$p֭ŋֲb ZZZKbV+& łbd2aZijjB~ݻwfDD~~~}\NcĈZ&V^hn:9s gΜ̙^L_|A~~>V'Ovnݺ$BBBהpE.]JBB۱l;wB"##˔Y[[ݻ>ۑݕ[ՙ,J>qKȗQtd[2%9$3_^<(/)(/ǥbuWWhvY|@FVe$w\Qnnnݻ+V`2bt$Z~=ӟoٲE1sL̙3# ko-~?qkf_:+d&L@>}xL&&&2}gΣ**'= ,%!aSY {stkێg68 * M0 !,}Oe#PH*>srN}<Ͻ}4 O>g*_Ӛ)Si&V*~v ='F{W"44~_zi@T~;k@m'Zg_LL4>Rgv.Yo, qQ(DDE-!$VĵWbdʨB!n,gOp>+mULvɹFtX(oB!B4$B!BH#B!7 !BL6Mg{+ NcLeT MGFP(%V$V$8B!1ta$>9u/pt857&#jIHB!&]ظq>((X3n@! B!nNc\'WN\c$$VnX:(0*RB|O!črqxǎ׏` ;s3ssx}6'l_YUMeuwXᵜ7n#=-ٳde`<|8`Yӥg(-+c6HtT4. $8X{}6, h4ẔΝh/bdrgUpEEl۾a Xzx$8ׇNB)L*C! N/1F===h?+/#:*^lvFPPU^'N=ס8QrCYsתQcZ K&hQCѪs:r˖I_W$lfjѣ:rKp\SX:ȳNs+&2Nȥ! 4vYj4J,/RB slTɩSLIOu9n۶p8p\Ow1mOKk QQҸיfyI X|\ 1;::_c`] )1QO#jutT_JB1J%Z3:$7:QXc'>7"cgB3,ٻC*jLڋuFGjIOMp8]*mv♞3( z~ .S>1gXH: N8¹s #tz.cnqq^rL>='Rh`)\( $8c7RB!W^ϒ ΙáGٳCgd/\@lLj/^|7o0%=PG6~ي پg%')95mhdN@y9yy|^z1=8={YP4V lnwp;wq(x #yytZB솻]5w9pv[^]P!B*t:-y[^kZ+7hW X4r߆Q*QX_ǹ*WZMnNǎ< |nvRv={ȟ=[O:l8A@#&Sqf3OXtnOxűIB!W^gg--l;,* UUդ$'hh405=ֶ6i蠳 ۍ墴 F3pOO C9?NlL :6 l|9YY$'%a;nitRZV^rt:=?bjŹJdܮciϜtOEU)IIp~qݝX!LT .4hT0Ʋ%c.y'IAA$'%QYUEtT4rHV-_J5rP"7"H">>nLRU]M{GŇS|EEcc( "#"X|hw;soS <YBikn8;mMB%Xn!+bAL\¨BɦRKEg{ 581KP"0! XCLRB!nƐkoS(DDE--$V5%}%҄BX*yBH#B!G!B!$B!B 2 BIvlobXQ^/d++B!B|:۰ F:dD-tQ Yh---7[ZKr䶌wMYY5m۱,Fa;ؗKݿ>|u-Cظq>((X3n@[E;F__?iXT883eU5Uܵbrغ4g|v9]zҲ2mDGExBx4ło}~|4e=l6yvލngʒ%K&F+D9Ѻ~]DOt:uzU=nJBbEbEzzz~V._FtT4}}q *ՊU+ 9t+-L \z).NbEVl4vyemذh4w^~{p8x'ڵkyOʶmWJ}Q̙$((DGGG/j&-O~ߑ>ꉄi\. ??(jkk.>2-=!!!ܹ7x[R|-ޝt=_]j[kZ}ԶmDnB&ҊJ232:f̱z^뒚+'.V+DvSV~u0\j'K6on{ߎ96 UּyWf:::页>6l׿u^xʘ>}:Sn׮]Xݏcϴ7yfۉ_׳q[oyfZ[[2e >,eo3cƌQ:l6w}7/w/ SN 2222kkk}V%==??K/q)|S~~{14 ?P_mG[ٶg;233W//2o&]]]$%%cy~_駟b2xG;P(~2};Rɂ P*wKK~4_u=X@&RYYY>h4<.M> /$Yj%qf3V+Б#,_z/^SX:ȳNsk˷UccX,|gɡbᰓWX~F_;Z_ꨫ'9)]BB|no_l߹EE$ӥTVWl4(B惏>"lR9q$eٝwm;N(J;Ơ6:N.Ԓ)TTV9شi ۶-|]24 go446R3uפe˖cj*Ws>vvڵkGh"""p\<䓬[={ߏmXKlڴ}8/-l޼yD@^x^|E4 o6o6v9p˖-cΝcZXaiArr2X,$$$PSSX?g۶m<<455}̱lm}Tn9^BBBxٷoя~O>$ر{M62B_:|vƔ)Sndƒ㒿 zo}bi"uo"@)͗C15=KOϸ.GYN+ rmCM&J%))şʫ-uy"S(H;(  #%9.YZj*^UVUs=F#yf9m?+}5wBVzK/=COo/.0^ZF|\!ttvz]+!!!|իWA\\>,o//^Lffw}5k֌X ?Yn.ݺ ,,|Hdd Mss>0os"RVVƙ3gx'F,4t:NGy^OAAӦM^cݿrjٱcX7]dd$_m-3_;L>uwLvޗ࣏>;zA7M Fnc=~8s ?_JjjeNv,;.3Dc)>>D_ZDcg{P(8Nf XꋯO|$R:rӉQ~ǮݞXjm׭nl :xd"åᾤX|GmwǮ(Jdfd0R@V|M ӦNSq^fv&/ȝ΃_F>h?w/ӕҳM AIpF?yRkoVE_x]hni wT /qʓXVvC$%vqݨԄ3p|gs=\>x^p8fϞ/ իW3m4=zk9LZ^uDXFݶlKYY6bΜ9>=3>徳 IDAT(..n?yB1t+yhFOPPϟ'33ACC)~fc'^|D2mi=::o9|KGG /nٲenbcc1 k>ek/200uP(̚5N8dɎ@%_o;%W_D.+ߴ3eL:knW_j4Яj۽/ JU2KL]4`ٰ=WAUgSUUMJr!FSimkA!'+$vvMOO 8NG'6&NKDD:Bm-6pN'c|_N^xV ryy9466i&INN߾};g<rO??c

2q-$%& 6y~/􇆘FyiD[ΠmӃRۗ*xo@PIITVUViar2_TEJE||׺y')9u SewށJnwP@vV&j /f#--_D]O{q^|Ev;#No>k[[{ ݽͿodggi&6m_Wrrr*[|9]]]<㴵1e6m4m^~oo,]H~󟏩 }'?駟fʕ$&&_rLW0/77 6hx'emkcMpFk[o}HzGyXtӦMe8֌>T*}h=կ . K~K߾ƒ+7~7ck_IiYzrv";+8}#NF w\E%2)n\ ].ERa4 C &10(=SƬ.?Z{MP*IMN'?on nzz{(;{.~~fn.5/z.T*TA**HKMgE;ʳ<7qo1wr2sg_B%edOo0k['Ikqp|L6oFOOgTȈvYP(g^Aw|AB5cƈഴ{^6[ˮ={G}ʙr>9|d64lvj53O''+S~cex6{ܖp''+g; ]{Q:Q߃j7ϛ5@eᄋٳbb@q1BL,,OL@ "#}}LH#BIOpj+ONӧJ"$VxE!.J[s#}\'mMB%V$VOARB!lQtP[S*`S(aQR++B!B8 QDDEKeqMI5!B!$8B!B! B!BHs(J\.TBDB1^2b BqCAߴvlobXQ#/XX\A[S#c*J*D!ėt@T6lzᠭ6Q""K}3SąrzpR)B!&EMYBLa v_{-DƍAAADŚtKB$VxK#jutT_+!tJ@TpS W) Ipnyz(!B|lyMz{{G|?ct"9|n.jSիVb5{5ܚVab)/#7'ORY]MjXt)=ƁOX|VKOEVOsV.[&{ř465{t:< NSs3qqcK2N_ßx}'hdzv6Kp a``'>c{XB1yn B! J奓8r賯OamdFCdD,BAhh(ɉt[,Ys*+ MDEEgEP0`Xz'dBTBW;yE$%&h ۗź1s+;8 ف:[B1'J%:2}uuwǴS-jjkϛ @Zj.֪Rh4imim!:*J:jׇ^ewΙ21d8N:;8Y3g݅a')1k>RIBBMΓ( -wl&yBIrHDXxTu`Z1mBM&֯YwǮݞXjxm]oLt49JgW&g˱ZGsXzz8}uRIlL MMMz"#"P$SWWOdDz@{}rثDN'1xS*`ԩ465F08h 8ϭDtu%Bx0CPQV;9ׁVepІFPwzZ8v׼kZ좕+3yg{cZoHH ハr:FѠ<{^/(85 Cw=ox>Eo|7V'^aVZ湥AL\$7B!n*;;2PAAC<tZ݄Wћ6K|Z^,ܳٳIJL̴LbB'[ZFI2zϏF.10j5uѸ\.74$8ucI*B! -֭d( l\.Gvq~n8L!&Jϔ\et[,|AfϚ ErRvs⋉XBa4hhljcKFƇtz~k̙rGwsRq1,==h4RSYpKXȺ16>p_}[6W;[څBPΞ.!-#+|zW^:)/Օ' ӧJ"$VX]>m !BL`S(m͍8q57b XX>I5!BL(:htJD)Hy?ĊĊG!7BADT4QRBbE\SEM!B! ,Z!BqKPڋ)99T*Xz4 oFww7K-2R,_pv9]zҲ2mDGExIoII o!%%'|lΝ;?=vOSRRBRRO=999 !Bq%8US|0撔餥 ]ܵ sl,Ly99~g::'JNR|0kZjCѪs:r˖MZEl6x vZ^u~ӟm62228xgJ}Q̙JKKHTTmذh4w^~{|gs=GHH;w7g֭T*ӄB!>eL2]8b>BAhh(ɉt[, fϜ>9)ʪ*z= {px(1xs,"Zذa_y(++c^ ޮ]Xb;_^zWdd|7oglBCC)//lxc$?wӟl444p8HNN3< s$8B!&Sg{qpHg{%""McD"=\.,\@ZJ Mv[,l{w;vĄxlgXz(ARs^QFz-֮]ofjzwL&ahhh`픖cKRRr?صkߏJW^```R`,\HiB!dtAAADŚiVrP[иFQh4XV\.VWPG6~G6~Ąپ={Yph4v~ ٙӘ˖7{ٌәw[T c.=p[uT`IpF9Λ5CHCLtԈ0(=SƬ~˶wtT(  gh4 l|9YY$'%a;.]Qr(>t3gb2\*//'&&A?Mrrgۙ={6f^g޼ylٲqYg^F+WWWǡCXh:-[`Z ""Yp!VeѢEg?7$$$3fsBUw}0'/h4ttvV_99]zS,^PHLL ?;úE\hz9|y5wV].7<{zh5} &j5t:/] W((tR}j\'JNriSxOɑ#mT`%'8ٙd_zj߳slL Cqw̜,r|nC?)qF!o}ll,ӟU.66?>L6^z?(?Z4!⫪޾>]z%tawIJL^T@cssP(>vY/|5J  S|gϝ737s8_1n΍8*!Bj`{{moC_AZnu:T_]ıڛo1e gyu]_$2328[Qي Xzz{ׯg ^zWVappkVZPY% p=0`g߇R7B hxr9mo2nQ%B! EDm]Dh4^yxxXjz.z i)ϣY*pWs9Y0`#EA~KJp8*{yTz.w# , B!WB ?p͆k39x v->9u/t857&#j !|AB1z-Dƍ9 "*L[*P! B!nNc\͕$G=.mB[tQB!M卭HOK#,_ߺ F!6&9ygQ|e%ZA|^ Tp9QRB 8"#"XPn7KPZVƠmh/\@Hp4!B iim#(( U+3룢;w+ec8Xs*{IDAṮX,>3eg::'JNR|0kZjCѪs:r˖I# I5!B4**7s`YȜ6㟕i rgQ $'&m`0=sBArR"z'dBTBW<[$$8B!8N.Ԓ)TTV,7nZ⼾)Z(iD!&BB:bjrg8NT*ez=6 :;vU+=wŒ HKI$<ݎn'1!99#k2֭.FB!B!U446-l6jjjL__ZfL/]sת\Vrqf3xPG6~ي پrM?eB`@IpB! X4r߆Q*uTVѝ(c{9Rp zz{ 5ZܳٳIJLFgpBWUUMJr!FSimkk^Mc8ytz~.sݸ\C?n{툏bLtvv]*碴 FCȠErRvsB;8B!;WUż b֌}Z-f3w]CXhWhy^e//{pVj>4rHV-_JlE:LÞk0H ! B!JT AA;q8T#ܻ~ݨ߱xpWi11|يJz{{1%;+KKGlBvMִ ]a:::t'-%vEzj*N7o ?ܜl^y5֬Z X ŋ5 ݭ{e˫,><1\^ϊeK\E%NfjKj2r(>tں:\.1Ѭ\BAggueUUWslXRg'OƊeK}n3@Kk+?9DOo/I cZ~鴼)g%'=CA >;yInN6yfFIpB!KDx8 Rс13gzcβ,B9-/s3eJ}m[jv_d^WMWw7%Ŕ)\`\ށϛK ~ŋ23α{>6al_sI]n۶⫝,xiUD|Yr!<ŪVN0 aD/wGj[fRS gP2cgϟwIg˲5/WVR:k&W^*)IVixd^~f{zӿ;3KJp&#O.+NLJqi95P6۝ 3w+׮1::E Yx1}}}H.oz!*+Q:k&APgZ ƾy_t斗OدA} @~^nXkWb,^%+blSi 8i޻cf|bddnrQz ߟlַc6?`OQ=XM2BLVLSs3S 8pm̛3c'N`Y;:2ή.lbviiP0nD"E \yƝI&rTiikcƴidln;wa-"/PZtkjhimeD}4 Jg-+,LKV_8r̴jNXN~^^Zڒ[y).,5LR9=7뜪Ts-0mD}!YynZZ vg`Y.7puDy\8!"< <3;b*-L^sp7+WpQ.^D2:nH~t:ٰC9~l\zƋp9̝SN鬱*+QW.Q|a~<ȅF^/Jgsq͚IKk -tvvQp!{O.ҝN'[UY;8t(~U$)S8z+- 33m'1MukPwG`O+mpnj?tͺk(1KMmxX4w]Inb۞Ʉ-ء᥹sY+<%esT^z/y!PkN⛋;ޞԯSDDDDDx קB<H$tb& VIR DDDDDDGDDDDDDGDDDDDxyp]K/i444Ѐ`޼y|ٶgڗC)"" 8"""ǶmLtbYmt:q8V۶sq]twPAE3 c'y(Ȥ8v@*|M2339r￿I!O@,r|n2 ""J"`xx/_@mm-$79u4x̌ VLlۦ@=ضM^(D>.siFG-f`ҥI"2N MO <^/PAm[t '#""YYY8>Ϳ0::[o4{ q8"b}u5>q)Vv̀A_o p&FFFß̕W):U;JD>?C-Mx}R=|E#t+4|7YYYXEqqk֬3XF˻g[;wa|,"/={qQQ!'O5A6fLFv08n pp8RP@_GD r{qyhir ?0( +|7YYYQ^>,2ڹ ɦMk+Giji-s܄eٌrY*?#GYL+.NzMSļ>C˷sc""BJ5+WxWzD"N<ɥKp:^{rx<g3gϲz*ꝷyyɒqa]5\={}khͽ#"#""ŋ Fww7}~C"rssrh@Gei4DMDD^HwwcFsr1sf Oxx^vbVɌ\jjmq3 4Sө{ǰ4Qy_> 6PUUf޽s!,X@y _~%>oܶ>x~鬙Κ @zz:׎[><>tug3˖}oi }IGDD^XYl)?;Kkk+;vV /?_|jjjظq=aRDyD"(ȋn~O,,rsؾ};KT}vy4y:~{CD^'yao9WM>\X{!GD䅣"""""#"""""#"""""#"""""#""ψaضB<mcQFT' rUy^lz:mKlۢ`!"#""ϋǗA{K W{`cJk3^_EyDSDD`NCΎk$ra\nrB 7"" 8"":@BCDDDDDDGDDDDDDGDDDDDDGDDDDDDGDDDDDpDDDDDDpDDDDDD_P%DDD&)}ܖPSSƍ|$DQ!DDn2O>|OĶ~PDD,`YHIENDB`gtkhash-1.5/snap/000077500000000000000000000000001431266303500137545ustar00rootroot00000000000000gtkhash-1.5/snap/snapcraft.yaml000066400000000000000000000026111431266303500166210ustar00rootroot00000000000000name: gtkhash adopt-info: gtkhash version: git license: GPL-2.0+ grade: stable base: core20 confinement: strict compression: lzo apps: gtkhash: command: usr/bin/gtkhash desktop: usr/share/applications/org.gtkhash.gtkhash.desktop common-id: org.gtkhash.gtkhash extensions: [ gnome-3-38 ] plugs: [ home ] parts: gtkhash: source: https://github.com/tristanheaven/gtkhash.git plugin: autotools build-packages: - pkg-config - libtool - gettext - autopoint - appstream - libglib2.0-dev - libgtk-3-dev - libgcrypt20-dev - libb2-dev - librsvg2-bin - libxml2-utils - at-spi2-core - xvfb - gnome-icon-theme stage-packages: - libgtk-3-0 - libgcrypt20 - libb2-1 build-environment: - CFLAGS: "${CFLAGS} -O2 -s" autotools-configure-parameters: - --prefix=/usr # For snap's bindtextdomain() hack - --enable-linux-crypto - --disable-silent-rules override-build: | sed -i '/^Icon=/s:=.*:=${SNAP}/meta/gui/gtkhash.svg:' data/org.gtkhash.gtkhash.desktop.in snapcraftctl build make VERBOSE=1 check || : mkdir -vp -- "${SNAPCRAFT_PART_INSTALL}"/meta/gui cp -vf -- data/icons/scalable/org.gtkhash.gtkhash.svg "${SNAPCRAFT_PART_INSTALL}"/meta/gui/gtkhash.svg parse-info: [ usr/share/metainfo/org.gtkhash.gtkhash.appdata.xml ] gtkhash-1.5/src/000077500000000000000000000000001431266303500136025ustar00rootroot00000000000000gtkhash-1.5/src/Makefile.am000066400000000000000000000026431431266303500156430ustar00rootroot00000000000000SUBDIRS = hash util if ENABLE_NAUTILUS_DATA SUBDIRS += nautilus endif if ENABLE_GTKHASH bin_PROGRAMS = gtkhash BUILT_SOURCES = resources.c resources.h nodist_gtkhash_SOURCES = $(BUILT_SOURCES) gtkhash_SOURCES = \ main.c main.h \ callbacks.c callbacks.h \ check.c check.h \ gui.c gui.h \ hash.c hash.h \ list.c list.h \ prefs.c prefs.h \ opts.c opts.h \ uri-digest.c uri-digest.h check_PROGRAMS = gtkhash-test check_DATA = 0.bytes 1.bytes 10M.bytes 5G.bytes nodist_gtkhash_test_SOURCES = $(BUILT_SOURCES) gtkhash_test_SOURCES = \ test.c \ callbacks.c \ check.c \ gui.c \ hash.c \ list.c \ opts.c \ uri-digest.c AM_CPPFLAGS = \ -DLOCALEDIR="\"$(localedir)\"" \ $(GTK_CFLAGS) AM_CFLAGS = $(GTKHASH_CFLAGS) LDADD = \ hash/hash.la \ util/util.la \ $(GTK_LIBS) TESTS = $(check_PROGRAMS) AM_TESTS_ENVIRONMENT = HASH_LIBS="$(HASH_LIBS)"; export HASH_LIBS; LOG_COMPILER = xvfb-run --auto-servernum -s "-screen 0 800x600x24" $(srcdir)/gtkhash-test.sh CLEANFILES = \ $(BUILT_SOURCES) \ $(check_DATA) \ *.gcda *.gcno EXTRA_DIST = \ gtkhash-test.sh \ test.md5sum.in \ meson.build resources.c resources.h: \ ../data/gtkhash-gtk3.gresource.xml \ ../data/gtkhash-gtk3.ui $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) \ --c-name resources \ --internal \ --manual-register \ --generate \ --sourcedir="$(srcdir)"/../data/ \ --target=$@ \ $< %.bytes: $(AM_V_GEN) truncate -s $* $@ endif # ENABLE_GTKHASH gtkhash-1.5/src/callbacks.c000066400000000000000000000466211431266303500156760ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "callbacks.h" #include "main.h" #include "gui.h" #include "hash.h" #include "prefs.h" #include "list.h" #include "check.h" #include "uri-digest.h" #include "hash/hash-string.h" static bool on_window_delete_event(void) { gtk_widget_hide(GTK_WIDGET(gui.window)); gtk_main_quit(); return true; } static void on_menuitem_open_activate(void) { #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) GtkFileChooser *chooser = GTK_FILE_CHOOSER(gtk_file_chooser_native_new( _("Open Digest File"), gui.window, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Open"), _("_Cancel"))); #else GtkFileChooser *chooser = GTK_FILE_CHOOSER( gtk_file_chooser_dialog_new(_("Open Digest File"), gui.window, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, NULL)); #endif gtk_file_chooser_set_select_multiple(chooser, true); gtk_file_chooser_set_local_only(chooser, false); #ifndef G_OS_WIN32 /* Note: Adding filters causes GTK to fallback to GtkFileChooserDialog. On Windows, having a native file chooser is definitely preferable. */ GtkFileFilter *filter = NULL; filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Digest/Checksum Files (*.sha1, *.md5, *.sfv, …)")); check_file_add_filters(filter); gtk_file_chooser_add_filter(chooser, filter); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All Files")); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(chooser, filter); #endif #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) if (gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #else if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #endif GSList *files = gtk_file_chooser_get_files(chooser); GSList *ud_list = NULL; for (GSList *p = files; p; p = p->next) if (p->data) ud_list = check_file_load(ud_list, p->data); if (ud_list) { if (gui.view == GUI_VIEW_FILE_LIST) gui_add_ud_list(ud_list, GUI_VIEW_FILE_LIST); else gui_add_ud_list(ud_list, GUI_VIEW_INVALID); gui_update(); uri_digest_list_free_full(ud_list); } g_slist_free_full(files, g_object_unref); } #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) g_object_unref(chooser); #else gtk_widget_destroy(GTK_WIDGET(chooser)); #endif } static void on_menuitem_save_as_activate(void) { #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) GtkFileChooser *chooser = GTK_FILE_CHOOSER(gtk_file_chooser_native_new( _("Save Digest File"), gui.window, GTK_FILE_CHOOSER_ACTION_SAVE, _("_Save"), _("_Cancel"))); #else GtkFileChooser *chooser = GTK_FILE_CHOOSER( gtk_file_chooser_dialog_new(_("Save Digest File"), gui.window, GTK_FILE_CHOOSER_ACTION_SAVE, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Save"), GTK_RESPONSE_ACCEPT, NULL)); #endif gtk_file_chooser_set_select_multiple(chooser, false); gtk_file_chooser_set_local_only(chooser, true); // TODO gtk_file_chooser_set_do_overwrite_confirmation(chooser, true); #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) if (gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #else if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #endif char *filename = gtk_file_chooser_get_filename(chooser); check_file_save(filename); g_free(filename); } #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) g_object_unref(chooser); #else gtk_widget_destroy(GTK_WIDGET(chooser)); #endif } static void on_menuitem_quit_activate(void) { gtk_widget_hide(GTK_WIDGET(gui.window)); gtk_main_quit(); } static void on_menuitem_edit_activate(void) { GtkWidget *widget = gtk_window_get_focus(gui.window); bool selectable = false; bool editable = false; bool selection_ready = false; bool clipboard_ready = false; if (GTK_IS_ENTRY(widget)) { selectable = gtk_entry_get_text_length(GTK_ENTRY(widget)); editable = gtk_editable_get_editable(GTK_EDITABLE(widget)); selection_ready = gtk_editable_get_selection_bounds( GTK_EDITABLE(widget), NULL, NULL); clipboard_ready = gtk_clipboard_wait_is_text_available( gtk_clipboard_get(GDK_NONE)); } gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_cut), selection_ready && editable); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_copy), selection_ready); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_paste), editable && clipboard_ready); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_delete), selection_ready && editable); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_select_all), selectable); } static void on_menuitem_cut_activate(void) { GtkEditable *widget = GTK_EDITABLE(gtk_window_get_focus(gui.window)); gtk_editable_cut_clipboard(widget); } static void on_menuitem_copy_activate(void) { GtkEditable *widget = GTK_EDITABLE(gtk_window_get_focus(gui.window)); gtk_editable_copy_clipboard(widget); } static void on_menuitem_paste_activate(void) { GtkEditable *widget = GTK_EDITABLE(gtk_window_get_focus(gui.window)); gtk_editable_paste_clipboard(widget); } static void on_menuitem_delete_activate(void) { GtkEditable *widget = GTK_EDITABLE(gtk_window_get_focus(gui.window)); gtk_editable_delete_selection(widget); } static void on_menuitem_select_all_activate(void) { GtkEditable *widget = GTK_EDITABLE(gtk_window_get_focus(gui.window)); gtk_editable_set_position(widget, -1); gtk_editable_select_region(widget, 0, -1); } static void on_menuitem_prefs_activate(void) { gtk_widget_show(GTK_WIDGET(gui.dialog)); } static void on_radiomenuitem_toggled(void) { enum gui_view_e view = GUI_VIEW_INVALID; if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_file))) { view = GUI_VIEW_FILE; } else if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_text))) { view = GUI_VIEW_TEXT; } else if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_file_list))) { view = GUI_VIEW_FILE_LIST; } gui_set_view(view); gui_update(); } static void on_menuitem_about_activate(void) { static const char * const artists[] = { "Icon derived from GTK Logo " "https://wiki.gnome.org/Projects/GTK/Logo", NULL }; static const char * const authors[] = { "Tristan Heaven ", NULL }; const char *snap_version = NULL; if (g_strcmp0(g_getenv("SNAP_NAME"), PACKAGE) == 0) snap_version = g_getenv("SNAP_VERSION"); char *version = g_markup_printf_escaped("%s", snap_version ? snap_version : VERSION); gtk_show_about_dialog( gui.window, "artists", artists, "authors", authors, "comments", _("A desktop utility for computing message digests or checksums"), "license-type", GTK_LICENSE_GPL_2_0, "logo-icon-name", "org.gtkhash.gtkhash", "program-name", PACKAGE_NAME, #if ENABLE_NLS "translator-credits", _("translator-credits"), #endif "version", version, "website", "https://github.com/tristanheaven/gtkhash", NULL); g_free(version); } static void on_filechooserbutton_selection_changed(void) { bool enabled = hash_funcs_count_enabled(); char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER( gui.filechooserbutton)); if (enabled && uri) { g_free(uri); gtk_widget_set_sensitive(GTK_WIDGET(gui.button_hash), true); } else gtk_widget_set_sensitive(GTK_WIDGET(gui.button_hash), false); gui_clear_digests(); } static void on_toolbutton_add_clicked(void) { #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) GtkFileChooser *chooser = GTK_FILE_CHOOSER(gtk_file_chooser_native_new( _("Select Files"), gui.window, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Open"), _("_Cancel"))); #else GtkFileChooser *chooser = GTK_FILE_CHOOSER( gtk_file_chooser_dialog_new(_("Select Files"), gui.window, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, NULL)); #endif gtk_file_chooser_set_select_multiple(chooser, true); gtk_file_chooser_set_local_only(chooser, false); #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) if (gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #else if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { #endif GSList *uris = gtk_file_chooser_get_uris(chooser); GSList *ud_list = uri_digest_list_from_uri_list(uris); gui_add_ud_list(ud_list, GUI_VIEW_FILE_LIST); uri_digest_list_free_full(ud_list); g_slist_free(uris); } #if (GTK_CHECK_VERSION(3,20,0) && ENABLE_NATIVE_FILE_CHOOSER) g_object_unref(chooser); #else gtk_widget_destroy(GTK_WIDGET(chooser)); #endif } static void on_treeselection_changed(void) { const int rows = gtk_tree_selection_count_selected_rows(gui.treeselection); gtk_widget_set_sensitive(GTK_WIDGET(gui.toolbutton_remove), (rows > 0)); } static void show_menu_treeview(GdkEventButton *event) { const int rows = gtk_tree_selection_count_selected_rows(gui.treeselection); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_treeview_remove), (rows > 0)); bool can_copy = false; if (rows == 1) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].enabled) continue; char *digest = list_get_selected_digest(i); if (digest && *digest) { can_copy = true; gtk_widget_set_sensitive(GTK_WIDGET( gui.hash_widgets[i].menuitem_treeview_copy), true); } else { gtk_widget_set_sensitive(GTK_WIDGET( gui.hash_widgets[i].menuitem_treeview_copy), false); } g_free(digest); } } gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_treeview_copy), can_copy); #if GTK_CHECK_VERSION(3,22,0) gtk_menu_popup_at_pointer(gui.menu_treeview, (GdkEvent *)event); #else if (event) { gtk_menu_popup(gui.menu_treeview, NULL, NULL, NULL, NULL, event->button, event->time); } else { gtk_menu_popup(gui.menu_treeview, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); } #endif } static void on_treeview_popup_menu(void) { /* Note: Shift+F10 can trigger this, so it's possible for the pointer to be outside the window */ show_menu_treeview(NULL); } static bool on_treeview_button_press_event(G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event) { if (gdk_event_triggers_context_menu((GdkEvent *)event)) { show_menu_treeview(event); // Stop processing the event now so the selection won't be changed return true; } return false; } static void on_treeview_drag_data_received(G_GNUC_UNUSED GtkWidget *widget, GdkDragContext *context, G_GNUC_UNUSED gint x, G_GNUC_UNUSED gint y, GtkSelectionData *selection, G_GNUC_UNUSED guint info, guint t, G_GNUC_UNUSED gpointer data) { char **uris = gtk_selection_data_get_uris(selection); if (!uris) { gtk_drag_finish(context, false, true, t); return; } GSList *ud_list = uri_digest_list_from_uri_strv(uris); gui_add_ud_list(ud_list, GUI_VIEW_FILE_LIST); uri_digest_list_free(ud_list); g_strfreev(uris); gtk_drag_finish(context, true, true, t); } static void on_menuitem_treeview_copy_activate(G_GNUC_UNUSED GtkMenuItem *menuitem, struct hash_func_s *func) { char *digest = list_get_selected_digest(func->id); g_assert(digest); gtk_clipboard_set_text(gtk_clipboard_get(GDK_NONE), digest, -1); g_free(digest); } static void on_menuitem_treeview_show_toolbar_toggled(void) { const bool show_toolbar = gtk_check_menu_item_get_active( GTK_CHECK_MENU_ITEM(gui.menuitem_treeview_show_toolbar)); gtk_widget_set_visible(GTK_WIDGET(gui.toolbar), show_toolbar); } static void on_button_hash_clicked(G_GNUC_UNUSED GtkButton *button, struct hash_func_s *func) { if (gui.view == GUI_VIEW_FILE) { // Workaround for when user clicks Cancel in FileChooserDialog and // uri is changed without emitting the "selection-changed" signal on_filechooserbutton_selection_changed(); if (!gtk_widget_get_sensitive(GTK_WIDGET(gui.button_hash))) return; // Single-function hash if (func) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported || i == func->id) continue; hash.funcs[i].enabled = false; } } } gui_start_hash(); } static void on_entry_check_icon_press(GtkEntry *entry, GtkEntryIconPosition pos, GdkEventButton *event) { if (pos != GTK_ENTRY_ICON_PRIMARY) return; if (event->type != GDK_BUTTON_PRESS) return; if (event->button != 1) return; gtk_entry_set_text(entry, ""); gtk_editable_paste_clipboard(GTK_EDITABLE(entry)); } static void on_togglebutton_hmac_file_toggled(void) { g_assert(gui.view == GUI_VIEW_FILE); bool active = gtk_toggle_button_get_active(gui.togglebutton_hmac_file); gtk_widget_set_sensitive(GTK_WIDGET(gui.entry_hmac_file), active); gui_clear_digests(); gui_update_hash_func_labels(active); } static void on_togglebutton_hmac_text_toggled(void) { g_assert(gui.view == GUI_VIEW_TEXT); bool active = gtk_toggle_button_get_active(gui.togglebutton_hmac_text); gtk_widget_set_sensitive(GTK_WIDGET(gui.entry_hmac_text), active); hash_string(); gui_update_hash_func_labels(active); } static void on_menuitem_show_hmac_key_toggled(GtkCheckMenuItem *item, GtkEntry *entry) { const bool active = gtk_check_menu_item_get_active(item); gtk_entry_set_visibility(entry, active); } static void on_entry_hmac_populate_popup(GtkEntry *entry, GtkMenu *menu) { GtkWidget *item; // Add separator item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); item = gtk_check_menu_item_new_with_mnemonic(_("_Show HMAC Key")); // Add checkbutton gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), gtk_entry_get_visibility(entry)); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(item, "toggled", G_CALLBACK(on_menuitem_show_hmac_key_toggled), entry); } static bool on_dialog_delete_event(void) { gtk_widget_hide(GTK_WIDGET(gui.dialog)); return true; } static void on_dialog_combobox_changed(void) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; gtk_entry_set_text(gui.hash_widgets[i].entry_file, ""); gtk_entry_set_text(gui.hash_widgets[i].entry_text, ""); } list_clear_digests(); if (gui.view == GUI_VIEW_TEXT) hash_string(); else gui_check_digests(); } void callbacks_init(void) { #define CON(OBJ, SIG, CB) \ g_signal_connect(G_OBJECT(OBJ), SIG, G_CALLBACK(CB), NULL) CON(gui.window, "delete-event", on_window_delete_event); CON(gui.menuitem_open, "activate", on_menuitem_open_activate); CON(gui.menuitem_save_as, "activate", on_menuitem_save_as_activate); CON(gui.menuitem_quit, "activate", on_menuitem_quit_activate); CON(gui.menuitem_edit, "activate", on_menuitem_edit_activate); CON(gui.menuitem_cut, "activate", on_menuitem_cut_activate); CON(gui.menuitem_copy, "activate", on_menuitem_copy_activate); CON(gui.menuitem_paste, "activate", on_menuitem_paste_activate); CON(gui.menuitem_delete, "activate", on_menuitem_delete_activate); CON(gui.menuitem_select_all, "activate", on_menuitem_select_all_activate); CON(gui.menuitem_prefs, "activate", on_menuitem_prefs_activate); CON(gui.radiomenuitem_file, "toggled", on_radiomenuitem_toggled); CON(gui.radiomenuitem_text, "toggled", on_radiomenuitem_toggled); CON(gui.radiomenuitem_file_list, "toggled", on_radiomenuitem_toggled); CON(gui.menuitem_about, "activate", on_menuitem_about_activate); // file-set isn't emitted when file is deleted // CON(gui.filechooserbutton, "file-set", on_filechooserbutton_file_set); CON(gui.filechooserbutton, "selection-changed", on_filechooserbutton_selection_changed); CON(gui.entry_text, "changed", hash_string); CON(gui.togglebutton_hmac_file, "toggled", on_togglebutton_hmac_file_toggled); CON(gui.togglebutton_hmac_text, "toggled", on_togglebutton_hmac_text_toggled); CON(gui.entry_hmac_file, "populate-popup", on_entry_hmac_populate_popup); CON(gui.entry_hmac_text, "populate-popup", on_entry_hmac_populate_popup); CON(gui.entry_hmac_file, "changed", gui_clear_digests); CON(gui.entry_hmac_text, "changed", hash_string); CON(gui.entry_check_file, "changed", gui_check_digests); CON(gui.entry_check_file, "icon-press", on_entry_check_icon_press); CON(gui.entry_check_text, "changed", gui_check_digests); CON(gui.entry_check_text, "icon-press", on_entry_check_icon_press); CON(gui.toolbutton_add, "clicked", on_toolbutton_add_clicked); CON(gui.toolbutton_remove, "clicked", list_remove_selection); CON(gui.toolbutton_clear, "clicked", list_clear); CON(gui.treeselection, "changed", on_treeselection_changed); CON(gui.treeview, "popup-menu", on_treeview_popup_menu); CON(gui.treeview, "button-press-event", on_treeview_button_press_event); CON(gui.treeview, "drag-data-received", on_treeview_drag_data_received); CON(gui.menuitem_treeview_add, "activate", on_toolbutton_add_clicked); CON(gui.menuitem_treeview_remove, "activate", list_remove_selection); CON(gui.menuitem_treeview_clear, "activate", list_clear); CON(gui.menuitem_treeview_show_toolbar, "toggled", on_menuitem_treeview_show_toolbar_toggled); CON(gui.button_hash, "clicked", on_button_hash_clicked); CON(gui.button_stop, "clicked", gui_stop_hash); CON(gui.dialog, "delete-event", G_CALLBACK(on_dialog_delete_event)); CON(gui.dialog_button_close, "clicked", G_CALLBACK(on_dialog_delete_event)); CON(gui.dialog_togglebutton_show_hmac, "toggled", gui_update); CON(gui.dialog_combobox, "changed", on_dialog_combobox_changed); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; CON(gui.hash_widgets[i].button, "toggled", gui_update); g_signal_connect(gui.hash_widgets[i].label_file, "clicked", G_CALLBACK(on_button_hash_clicked), &hash.funcs[i]); g_signal_connect(gui.hash_widgets[i].menuitem_treeview_copy, "activate", G_CALLBACK(on_menuitem_treeview_copy_activate), &hash.funcs[i]); } #undef CON } gtkhash-1.5/src/callbacks.h000066400000000000000000000015461431266303500157000ustar00rootroot00000000000000/* * Copyright (C) 2007-2013 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_CALLBACKS_H #define GTKHASH_CALLBACKS_H void callbacks_init(void); #endif gtkhash-1.5/src/check.c000066400000000000000000000230131431266303500150220ustar00rootroot00000000000000/* * Copyright (C) 2007-2018 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "check.h" #include "main.h" #include "hash.h" #include "gui.h" #include "list.h" #include "uri-digest.h" #include "hash/hash-func.h" #define CHECK_FORMAT_N 3 enum check_format_e { CHECK_FORMAT_UNKNOWN = -1, CHECK_FORMAT_BSD, CHECK_FORMAT_GNU, CHECK_FORMAT_SFV, }; struct { GRegex *regex[CHECK_FORMAT_N]; const char * const pattern[CHECK_FORMAT_N]; } check_priv = { .regex = { NULL, NULL, NULL }, .pattern = { [CHECK_FORMAT_BSD] = "^" "(?[[:upper:][:digit:]-]{3,16})" // capture FUNCTION " \\(" "(?.+)" // capture FILENAME "\\) = " "(?[[:xdigit:]]{8,})" // capture DIGEST "$", [CHECK_FORMAT_GNU] = "^" "(?[[:xdigit:]]{8,})" // capture DIGEST (8+ hex chars) " [* ]" // * indicates binary mode "(?.+)" // capture FILENAE "$", [CHECK_FORMAT_SFV] = "^" "(?[^;].*?[^ ]*)" // capture FILENAME "[ ]+" "(?[[:xdigit:]]{8})" // capture DIGEST (8 hex chars) "$", }, }; static enum check_format_e check_regex_match(const char * const line, GMatchInfo **info) { if (!line || !*line) return CHECK_FORMAT_UNKNOWN; for (enum check_format_e i = 0; i < CHECK_FORMAT_N; i++) { if (!check_priv.regex[i]) continue; if (g_regex_match(check_priv.regex[i], line, 0, info)) return i; } return CHECK_FORMAT_UNKNOWN; } static bool check_file_parse_line(const char * const line, enum hash_func_e *id, char **filename, char **digest) { GMatchInfo *info = NULL; if (check_regex_match(line, &info) != CHECK_FORMAT_UNKNOWN) { char *function = g_match_info_fetch_named(info, "FUNCTION"); if (function) { *id = gtkhash_hash_func_get_id_from_name(function); g_free(function); } *filename = g_match_info_fetch_named(info, "FILENAME"); *digest = g_match_info_fetch_named(info, "DIGEST"); g_match_info_free(info); return true; } else { g_match_info_free(info); return false; } } static void check_file_enable_hinted_hash_func(GFile *file) { char *basename = g_file_get_basename(file); if (!basename) return; size_t len = strlen(basename); #define MATCH(STR, LEN, FUNC) \ g_assert(strlen(STR) == LEN); \ if (g_ascii_strcasecmp(basename + len - LEN, STR) == 0) { \ gui_enable_hash_func(G_PASTE(HASH_FUNC_, FUNC)); \ break; \ } do { if (len > 4) { MATCH(".md5", 4, MD5); MATCH(".sfv", 4, CRC32); } else break; if (len > 5) { MATCH(".sha1", 5, SHA1); } else break; if (len > 7) { MATCH(".md5sum", 7, MD5); MATCH(".sha224", 7, SHA224); MATCH(".sha256", 7, SHA256); MATCH(".sha384", 7, SHA384); MATCH(".sha512", 7, SHA512); } else break; if (len > 8) { MATCH(".sha1sum", 8, SHA1); } else break; if (len > 10) { MATCH(".sha224sum", 10, SHA224); MATCH(".sha256sum", 10, SHA256); MATCH(".sha384sum", 10, SHA384); MATCH(".sha512sum", 10, SHA512); } else break; } while (false); #undef MATCH g_free(basename); } static GSList *check_file_add_uri(GSList *ud_list, GFile *file, char *filename, char *digest) { g_assert(file); g_assert(filename && *filename); g_assert(digest && *digest); char *target_uri = NULL; if (g_path_is_absolute(filename)) { GFile *target = g_file_new_for_path(filename); target_uri = g_file_get_uri(target); g_object_unref(target); } else { // Assume path is relative to the check file GFile *dir = g_file_get_parent(file); char *dir_uri = g_file_get_uri(dir); target_uri = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dir_uri, filename); g_free(dir_uri); g_object_unref(dir); } g_free(filename); return g_slist_prepend(ud_list, uri_digest_new(target_uri, digest)); } static void check_file_error(GFile *file, GError *error) { g_assert(error); char *uri = g_file_get_uri(file); g_message(_("Failed to read check file \"%s\": %s"), uri, error->message); g_free(uri); } GSList *check_file_load(GSList *ud_list, GFile *file) { g_assert(file); char *data = NULL; GError *error = NULL; GFileInputStream *fis = g_file_read(file, NULL, &error); if (!fis) { check_file_error(file, error); g_error_free(error); return NULL; } GDataInputStream *dis = g_data_input_stream_new((GInputStream *)fis); char *line = NULL; gsize len = 0; error = NULL; while ((line = g_data_input_stream_read_line_utf8(dis, &len, NULL, &error))) { enum hash_func_e id = HASH_FUNC_INVALID; char *filename = NULL; char *digest = NULL; if ((len >= 8) && check_file_parse_line(line, &id, &filename, &digest)) { if (HASH_FUNC_IS_VALID(id)) gui_enable_hash_func(id); ud_list = check_file_add_uri(ud_list, file, filename, digest); } g_free(line); } if (error) { check_file_error(file, error); g_error_free(error); } else check_file_enable_hinted_hash_func(file); g_object_unref(dis); g_object_unref(fis); g_free(data); return ud_list; } void check_file_save(const char * const filename) { g_assert(filename); GString *string = g_string_sized_new(1024); for (enum hash_func_e i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].enabled) continue; switch (gui.view) { case GUI_VIEW_FILE: { const char *digest = gtk_entry_get_text( gui.hash_widgets[i].entry_file); if (!(digest && *digest)) continue; const bool hmac_active = gtk_toggle_button_get_active( gui.togglebutton_hmac_file); g_string_append_printf(string, (hmac_active && hash.funcs[i].hmac_supported) ? "# HMAC-%s\n" : "# %s\n", hash.funcs[i].name); GFile *file = gtk_file_chooser_get_file( GTK_FILE_CHOOSER(gui.filechooserbutton)); char *basename = g_file_get_basename(file); g_string_append_printf(string, "%s %s\n", gtk_entry_get_text(gui.hash_widgets[i].entry_file), basename); g_free(basename); g_object_unref(file); break; } case GUI_VIEW_TEXT: { const bool hmac_active = gtk_toggle_button_get_active( gui.togglebutton_hmac_text); g_string_append_printf(string, (hmac_active && hash.funcs[i].hmac_supported) ? "# HMAC-%s\n" : "# %s\n", hash.funcs[i].name); g_string_append_printf(string, "%s \"%s\"\n", gtk_entry_get_text(gui.hash_widgets[i].entry_text), gtk_entry_get_text(gui.entry_text)); break; } case GUI_VIEW_FILE_LIST: { enum hash_func_e prev = HASH_FUNC_INVALID; for (unsigned int row = 0; row < list.rows; row++) { char *digest = list_get_digest(row, i); if (digest && *digest) { if (i != prev) { g_string_append_printf(string, "# %s\n", hash.funcs[i].name); } char *basename = list_get_basename(row); g_string_append_printf(string, "%s %s\n", digest, basename); g_free(basename); } g_free(digest); prev = i; } break; } default: g_assert_not_reached(); } } char *data = g_string_free(string, false); g_file_set_contents(filename, data, -1, NULL); g_free(data); } void check_file_add_filters(GtkFileFilter *filter) { gtk_file_filter_add_mime_type(filter, "application/x-md5"); gtk_file_filter_add_mime_type(filter, "application/x-sha1"); gtk_file_filter_add_mime_type(filter, "text/x-sfv"); gtk_file_filter_add_pattern(filter, "*.md5"); gtk_file_filter_add_pattern(filter, "*.sfv"); gtk_file_filter_add_pattern(filter, "*.sha1"); gtk_file_filter_add_pattern(filter, "*.sha224"); gtk_file_filter_add_pattern(filter, "*.sha256"); gtk_file_filter_add_pattern(filter, "*.sha384"); gtk_file_filter_add_pattern(filter, "*.sha512"); gtk_file_filter_add_pattern(filter, "*md5sum*"); gtk_file_filter_add_pattern(filter, "*sha1sum*"); gtk_file_filter_add_pattern(filter, "*sha224sum*"); gtk_file_filter_add_pattern(filter, "*sha256sum*"); gtk_file_filter_add_pattern(filter, "*sha384sum*"); gtk_file_filter_add_pattern(filter, "*sha512sum*"); gtk_file_filter_add_pattern(filter, "*MD5SUM*"); gtk_file_filter_add_pattern(filter, "*SHA1SUM*"); gtk_file_filter_add_pattern(filter, "*SHA224SUM*"); gtk_file_filter_add_pattern(filter, "*SHA256SUM*"); gtk_file_filter_add_pattern(filter, "*SHA384SUM*"); gtk_file_filter_add_pattern(filter, "*SHA512SUM*"); gtk_file_filter_add_pattern(filter, "*CHECKSUM*"); gtk_file_filter_add_pattern(filter, "*DIGEST*"); } void check_init(void) { for (enum check_format_e i = 0; i < CHECK_FORMAT_N; i++) { GError *error = NULL; check_priv.regex[i] = g_regex_new(check_priv.pattern[i], 0, 0, &error); if (error) { g_warning("g_regex_new(): %s", error->message); g_error_free(error); error = NULL; } } } void check_deinit(void) { for (enum check_format_e i = 0; i < CHECK_FORMAT_N; i++) { if (check_priv.regex[i]) { g_regex_unref(check_priv.regex[i]); check_priv.regex[i] = NULL; } } } gtkhash-1.5/src/check.h000066400000000000000000000020121431266303500150230ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_CHECK_H #define GTKHASH_CHECK_H GSList *check_file_load(GSList *ud_list, GFile *file); void check_file_save(const char *filename); void check_file_add_filters(GtkFileFilter *filter); void check_init(void); void check_deinit(void); #endif gtkhash-1.5/src/gtkhash-test.sh000077500000000000000000000002711431266303500165470ustar00rootroot00000000000000#!/bin/sh set -e set -x # Test with all libs enabled unset GTKHASH_TEST_LIB "$@" for lib in ${HASH_LIBS} ; do # Test with one lib enabled export GTKHASH_TEST_LIB=${lib} "$@" done gtkhash-1.5/src/gui.c000066400000000000000000000607311431266303500145410ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "gui.h" #include "main.h" #include "callbacks.h" #include "hash.h" #include "list.h" #include "prefs.h" #include "resources.h" #include "uri-digest.h" #include "hash/digest-format.h" #include "hash/hash-func.h" #define GUI_XML_RESOURCE "/org/gtkhash/gtkhash-gtk3.ui" struct gui_s gui = { .view = GUI_VIEW_INVALID, }; static struct { enum gui_state_e state; } gui_priv = { .state = GUI_STATE_INVALID, }; static GObject *gui_get_object(GtkBuilder *builder, const char *name) { g_assert(name); GObject *obj = gtk_builder_get_object(builder, name); if (!obj) g_error("unknown object: \"%s\"", name); return obj; } static void gui_init_objects(GtkBuilder *builder) { // Window gui.window = GTK_WINDOW(gui_get_object(builder, "window")); // Menus gui.menuitem_open = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_open")); gui.menuitem_save_as = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_save_as")); gui.menuitem_quit = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_quit")); gui.menuitem_edit = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_edit")); gui.menuitem_cut = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_cut")); gui.menuitem_copy = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_copy")); gui.menuitem_paste = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_paste")); gui.menuitem_delete = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_delete")); gui.menuitem_select_all = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_select_all")); gui.menuitem_prefs = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_prefs")); gui.menuitem_about = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_about")); gui.radiomenuitem_file = GTK_RADIO_MENU_ITEM(gui_get_object(builder, "radiomenuitem_file")); gui.radiomenuitem_text = GTK_RADIO_MENU_ITEM(gui_get_object(builder, "radiomenuitem_text")); gui.radiomenuitem_file_list = GTK_RADIO_MENU_ITEM(gui_get_object(builder, "radiomenuitem_file_list")); // Toolbar gui.toolbar = GTK_TOOLBAR(gui_get_object(builder, "toolbar")); gui.toolbutton_add = GTK_TOOL_BUTTON(gui_get_object(builder, "toolbutton_add")); gui.toolbutton_remove = GTK_TOOL_BUTTON(gui_get_object(builder, "toolbutton_remove")); gui.toolbutton_clear = GTK_TOOL_BUTTON(gui_get_object(builder, "toolbutton_clear")); // Containers gui.vbox_single = GTK_BOX(gui_get_object(builder, "vbox_single")); gui.vbox_list = GTK_BOX(gui_get_object(builder, "vbox_list")); gui.hbox_input = GTK_BOX(gui_get_object(builder, "hbox_input")); gui.hbox_output = GTK_BOX(gui_get_object(builder, "hbox_output")); gui.vbox_outputlabels = GTK_BOX(gui_get_object(builder, "vbox_outputlabels")); gui.vbox_digests_file = GTK_BOX(gui_get_object(builder, "vbox_digests_file")); gui.vbox_digests_text = GTK_BOX(gui_get_object(builder, "vbox_digests_text")); // Inputs gui.filechooserbutton = GTK_FILE_CHOOSER_BUTTON(gui_get_object(builder, "filechooserbutton")); gui.entry_text = GTK_ENTRY(gui_get_object(builder, "entry_text")); gui.entry_check_file = GTK_ENTRY(gui_get_object(builder, "entry_check_file")); gui.entry_check_text = GTK_ENTRY(gui_get_object(builder, "entry_check_text")); gui.togglebutton_hmac_file = GTK_TOGGLE_BUTTON(gui_get_object(builder, "togglebutton_hmac_file")); gui.togglebutton_hmac_text = GTK_TOGGLE_BUTTON(gui_get_object(builder, "togglebutton_hmac_text")); gui.entry_hmac_file = GTK_ENTRY(gui_get_object(builder, "entry_hmac_file")); gui.entry_hmac_text = GTK_ENTRY(gui_get_object(builder, "entry_hmac_text")); // Labels gui.label_file = GTK_LABEL(gui_get_object(builder, "label_file")); gui.label_text = GTK_LABEL(gui_get_object(builder, "label_text")); // Tree View gui.treeview = GTK_TREE_VIEW(gui_get_object(builder, "treeview")); gui.treeselection = GTK_TREE_SELECTION(gui_get_object(builder, "treeselection")); gui.menu_treeview = GTK_MENU(gui_get_object(builder, "menu_treeview")); g_object_ref(gui.menu_treeview); gui.menuitem_treeview_add = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_treeview_add")); gui.menuitem_treeview_remove = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_treeview_remove")); gui.menuitem_treeview_clear = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_treeview_clear")); gui.menu_treeview_copy = GTK_MENU(gui_get_object(builder, "menu_treeview_copy")); gui.menuitem_treeview_copy = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_treeview_copy")); gui.menuitem_treeview_show_toolbar = GTK_MENU_ITEM(gui_get_object(builder, "menuitem_treeview_show_toolbar")); // Buttons gui.hseparator_buttons = GTK_SEPARATOR(gui_get_object(builder, "hseparator_buttons")); gui.button_hash = GTK_BUTTON(gui_get_object(builder, "button_hash")); gui.button_stop = GTK_BUTTON(gui_get_object(builder, "button_stop")); // Progress Bar gui.progressbar = GTK_PROGRESS_BAR(gui_get_object(builder, "progressbar")); // Dialog gui.dialog = GTK_DIALOG(gui_get_object(builder, "dialog")); gui.dialog_grid = GTK_GRID(gui_get_object(builder, "dialog_grid")); gui.dialog_togglebutton_show_hmac = GTK_TOGGLE_BUTTON(gui_get_object(builder, "dialog_togglebutton_show_hmac")); gui.dialog_combobox = GTK_COMBO_BOX(gui_get_object(builder, "dialog_combobox")); gui.dialog_button_close = GTK_BUTTON(gui_get_object(builder, "dialog_button_close")); } static void gui_init_hash_funcs(void) { for (int i = 0, supported = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; // File view func labels gui.hash_widgets[i].label_file = GTK_MODEL_BUTTON(gtk_model_button_new()); gtk_button_set_relief(GTK_BUTTON(gui.hash_widgets[i].label_file), GTK_RELIEF_NORMAL); gtk_widget_set_can_focus(GTK_WIDGET(gui.hash_widgets[i].label_file), false); gtk_container_add(GTK_CONTAINER(gui.vbox_outputlabels), GTK_WIDGET(gui.hash_widgets[i].label_file)); GValue xalign = G_VALUE_INIT; g_value_init(&xalign, G_TYPE_FLOAT); g_value_set_float(&xalign, 0); g_object_set_property(G_OBJECT(gui.hash_widgets[i].label_file), "xalign", &xalign); // Text view func labels gui.hash_widgets[i].label_text = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_halign(GTK_WIDGET(gui.hash_widgets[i].label_text), GTK_ALIGN_START); gtk_container_add(GTK_CONTAINER(gui.vbox_outputlabels), GTK_WIDGET(gui.hash_widgets[i].label_text)); // File view digests gui.hash_widgets[i].entry_file = GTK_ENTRY(gtk_entry_new()); gtk_container_add(GTK_CONTAINER(gui.vbox_digests_file), GTK_WIDGET(gui.hash_widgets[i].entry_file)); gtk_editable_set_editable(GTK_EDITABLE(gui.hash_widgets[i].entry_file), false); gtk_entry_set_icon_activatable(gui.hash_widgets[i].entry_file, GTK_ENTRY_ICON_SECONDARY, false); // Text view digests gui.hash_widgets[i].entry_text = GTK_ENTRY(gtk_entry_new()); gtk_container_add(GTK_CONTAINER(gui.vbox_digests_text), GTK_WIDGET(gui.hash_widgets[i].entry_text)); gtk_editable_set_editable(GTK_EDITABLE(gui.hash_widgets[i].entry_text), false); gtk_entry_set_icon_activatable(gui.hash_widgets[i].entry_text, GTK_ENTRY_ICON_SECONDARY, false); // File list treeview popup menu gui.hash_widgets[i].menuitem_treeview_copy = GTK_MENU_ITEM(gtk_menu_item_new_with_label(hash.funcs[i].name)); gtk_menu_shell_append(GTK_MENU_SHELL(gui.menu_treeview_copy), GTK_WIDGET(gui.hash_widgets[i].menuitem_treeview_copy)); // Dialog checkbuttons gui.hash_widgets[i].button = GTK_TOGGLE_BUTTON( gtk_check_button_new_with_label(hash.funcs[i].name)); gtk_grid_attach(gui.dialog_grid, GTK_WIDGET(gui.hash_widgets[i].button), supported % 3, // column supported / 3, // row 1, 1); // width, height // Could be enabled already by cmdline arg if (hash.funcs[i].enabled) gui_enable_hash_func(i); gtk_widget_show(GTK_WIDGET(gui.hash_widgets[i].button)); supported++; } } void gui_init(void) { // Override user icon theme when running in confined snap environment if (g_strcmp0(g_getenv("SNAP_NAME"), PACKAGE) == 0) { g_object_set(gtk_settings_get_default(), "gtk-icon-theme-name", "Yaru", NULL); } resources_register_resource(); GtkBuilder *builder = gtk_builder_new_from_resource(GUI_XML_RESOURCE); gui_init_objects(builder); g_object_unref(builder); resources_unregister_resource(); gui_init_hash_funcs(); list_init(); gui_set_state(GUI_STATE_IDLE); } static char *gui_try_uri(const char *uri) { g_assert(uri); char *error_str = NULL; GFile *file = g_file_new_for_uri(uri); GError *error = NULL; GFileInfo *info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, &error); if (info) { bool can_read = g_file_info_get_attribute_boolean(info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ); GFileType type = g_file_info_get_file_type(info); g_object_unref(info); if (!can_read) error_str = g_strdup(g_strerror(EACCES)); else if (type == G_FILE_TYPE_DIRECTORY) // TODO error_str = g_strdup(g_strerror(EISDIR)); else if (type != G_FILE_TYPE_REGULAR) error_str = g_strdup(_("Not a regular file")); } else { error_str = g_strdup(error->message); g_error_free(error); } g_object_unref(file); return error_str; } unsigned int gui_add_ud_list(GSList *ud_list, const enum gui_view_e view) { g_assert(ud_list); GSList *readable = NULL; unsigned int readable_len = 0; { GSList *tmp = ud_list; do { char *error = NULL; struct uri_digest_s *ud = tmp->data; if ((error = gui_try_uri(ud->uri))) { g_message(_("Failed to add file \"%s\": %s"), ud->uri, error); g_free(error); continue; } readable = g_slist_prepend(readable, tmp->data); readable_len++; } while ((tmp = tmp->next)); } readable = g_slist_reverse(readable); if (!GUI_VIEW_IS_VALID(view)) { if (readable_len == 1) gui_set_view(GUI_VIEW_FILE); else if (readable_len > 1) gui_set_view(GUI_VIEW_FILE_LIST); } if (readable_len && (gui.view == GUI_VIEW_FILE)) { struct uri_digest_s *ud = readable->data; gtk_file_chooser_set_uri(GTK_FILE_CHOOSER(gui.filechooserbutton), ud->uri); if (ud->digest) gtk_entry_set_text(gui.entry_check_file, ud->digest); } else if (readable_len && (gui.view == GUI_VIEW_FILE_LIST)) { GSList *tmp = readable; do { struct uri_digest_s *ud = tmp->data; list_append_row(ud->uri, ud->digest); } while ((tmp = tmp->next)); list_update(); } g_slist_free(readable); return readable_len; } void gui_add_check(const char *check) { g_assert(check && *check); gtk_entry_set_text(gui.entry_check_file, check); gtk_entry_set_text(gui.entry_check_text, check); } void gui_add_text(const char *text) { g_assert(text); gtk_entry_set_text(gui.entry_text, text); gui_set_view(GUI_VIEW_TEXT); gui_update(); gtk_editable_set_position(GTK_EDITABLE(gui.entry_text), -1); } void gui_error(const char *message) { GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message); gtk_window_set_title(GTK_WINDOW(dialog), PACKAGE_NAME); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void gui_run(void) { // Set default view if (!GUI_VIEW_IS_VALID(gui.view)) { gui_set_view(GUI_VIEW_FILE); gui_update(); } gtk_widget_show_now(GTK_WIDGET(gui.window)); // Connect signals to start handling events callbacks_init(); gtk_main(); hash_file_stop(); while (gui_priv.state != GUI_STATE_IDLE) gtk_main_iteration(); } void gui_deinit(void) { gtk_widget_destroy(GTK_WIDGET(gui.window)); g_object_unref(gui.menu_treeview); while (gtk_events_pending()) gtk_main_iteration(); } void gui_set_view(const enum gui_view_e view) { g_assert(GUI_VIEW_IS_VALID(view)); if (view == gui.view) return; gui.view = view; switch (view) { case GUI_VIEW_FILE: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_file), true); break; case GUI_VIEW_TEXT: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_text), true); break; case GUI_VIEW_FILE_LIST: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( gui.radiomenuitem_file_list), true); break; default: g_assert_not_reached(); } } void gui_set_digest_format(const enum digest_format_e format) { g_assert(DIGEST_FORMAT_IS_VALID(format)); gtk_combo_box_set_active(gui.dialog_combobox, format); } enum digest_format_e gui_get_digest_format(void) { enum digest_format_e format = gtk_combo_box_get_active(gui.dialog_combobox); g_assert(DIGEST_FORMAT_IS_VALID(format)); return format; } const uint8_t *gui_get_hmac_key(size_t *key_size) { g_assert(key_size); const uint8_t *hmac_key = NULL; *key_size = 0; switch (gui.view) { case GUI_VIEW_FILE: if (gtk_toggle_button_get_active(gui.togglebutton_hmac_file)) { GtkEntryBuffer *buffer = gtk_entry_get_buffer( gui.entry_hmac_file); hmac_key = (uint8_t *)gtk_entry_get_text(gui.entry_hmac_file); *key_size = gtk_entry_buffer_get_bytes(buffer); } break; case GUI_VIEW_TEXT: if (gtk_toggle_button_get_active(gui.togglebutton_hmac_text)) { GtkEntryBuffer *buffer = gtk_entry_get_buffer( gui.entry_hmac_text); hmac_key = (uint8_t *)gtk_entry_get_text(gui.entry_hmac_text); *key_size = gtk_entry_buffer_get_bytes(buffer); } break; case GUI_VIEW_FILE_LIST: // TODO break; default: g_assert_not_reached(); } return hmac_key; } static void gui_menuitem_save_as_set_sensitive(void) { if (gui_priv.state == GUI_STATE_BUSY) { gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_save_as), false); return; } bool sensitive = false; switch (gui.view) { case GUI_VIEW_FILE: for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].enabled && *gtk_entry_get_text(gui.hash_widgets[i].entry_file)) { sensitive = true; break; } } break; case GUI_VIEW_TEXT: for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].enabled) { sensitive = true; break; } } break; case GUI_VIEW_FILE_LIST: for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].enabled) { char *digest = list_get_digest(0, i); if (digest != NULL && *digest) { g_free(digest); sensitive = true; break; } } } break; default: sensitive = false; } gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_save_as), sensitive); } void gui_enable_hash_func(const enum hash_func_e id) { g_assert(HASH_FUNC_IS_VALID(id)); if (hash.funcs[id].supported) gtk_toggle_button_set_active(gui.hash_widgets[id].button, true); } void gui_update_hash_func_labels(const bool hmac_enabled) { g_assert(gui.view != GUI_VIEW_FILE_LIST); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].enabled) continue; char *str = NULL; // FIXME: different labels for RTL? if (hmac_enabled && hash.funcs[i].hmac_supported) str = g_strdup_printf("HMAC-%s:", hash.funcs[i].name); else str = g_strdup_printf("%s:", hash.funcs[i].name); if (gui.view == GUI_VIEW_FILE) gtk_button_set_label(GTK_BUTTON(gui.hash_widgets[i].label_file), str); else gtk_label_set_text(gui.hash_widgets[i].label_text, str); g_free(str); } } void gui_update_hash_funcs(void) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; hash.funcs[i].enabled = gtk_toggle_button_get_active( gui.hash_widgets[i].button); gtk_widget_set_visible(GTK_WIDGET(gui.hash_widgets[i].label_file), hash.funcs[i].enabled && gui.view == GUI_VIEW_FILE); gtk_widget_set_visible(GTK_WIDGET(gui.hash_widgets[i].label_text), hash.funcs[i].enabled && gui.view == GUI_VIEW_TEXT); gtk_widget_set_visible(GTK_WIDGET(gui.hash_widgets[i].entry_file), hash.funcs[i].enabled); gtk_widget_set_visible(GTK_WIDGET(gui.hash_widgets[i].entry_text), hash.funcs[i].enabled); gtk_widget_set_visible(GTK_WIDGET(gui.hash_widgets[i].menuitem_treeview_copy), hash.funcs[i].enabled); } } static void gui_update_hmac(void) { bool enabled = gtk_toggle_button_get_active(gui.dialog_togglebutton_show_hmac); bool active = false; switch (gui.view) { case GUI_VIEW_FILE: gtk_widget_hide(GTK_WIDGET(gui.entry_hmac_text)); gtk_widget_hide(GTK_WIDGET(gui.togglebutton_hmac_text)); gtk_widget_set_visible(GTK_WIDGET(gui.entry_hmac_file), enabled); gtk_widget_set_visible(GTK_WIDGET(gui.togglebutton_hmac_file), enabled); active = gtk_toggle_button_get_active(gui.togglebutton_hmac_file); gtk_widget_set_sensitive(GTK_WIDGET(gui.entry_hmac_file), active); if (active && !enabled) { gtk_toggle_button_set_active(gui.togglebutton_hmac_file, false); active = false; } break; case GUI_VIEW_TEXT: gtk_widget_hide(GTK_WIDGET(gui.entry_hmac_file)); gtk_widget_hide(GTK_WIDGET(gui.togglebutton_hmac_file)); gtk_widget_set_visible(GTK_WIDGET(gui.entry_hmac_text), enabled); gtk_widget_set_visible(GTK_WIDGET(gui.togglebutton_hmac_text), enabled); active = gtk_toggle_button_get_active(gui.togglebutton_hmac_text); gtk_widget_set_sensitive(GTK_WIDGET(gui.entry_hmac_text), active); if (active && !enabled) { gtk_toggle_button_set_active(gui.togglebutton_hmac_text, false); active = false; } break; default: g_assert_not_reached(); } gui_update_hash_func_labels(active); } void gui_update(void) { // Must call gui_set_view() before this g_assert(GUI_VIEW_IS_VALID(gui.view)); g_assert(gui_priv.state == GUI_STATE_IDLE); gui_update_hash_funcs(); const unsigned int funcs_enabled = hash_funcs_count_enabled(); if ((gui.view == GUI_VIEW_FILE) || (gui.view == GUI_VIEW_TEXT)) { gui_update_hmac(); gtk_widget_hide(GTK_WIDGET(gui.toolbar)); gtk_widget_hide(GTK_WIDGET(gui.vbox_list)); gtk_widget_show(GTK_WIDGET(gui.vbox_single)); } switch (gui.view) { case GUI_VIEW_FILE: { gtk_widget_hide(GTK_WIDGET(gui.label_text)); gtk_widget_hide(GTK_WIDGET(gui.entry_text)); gtk_widget_hide(GTK_WIDGET(gui.entry_check_text)); gtk_widget_hide(GTK_WIDGET(gui.vbox_digests_text)); gtk_widget_show(GTK_WIDGET(gui.label_file)); gtk_widget_show(GTK_WIDGET(gui.filechooserbutton)); gtk_widget_show(GTK_WIDGET(gui.entry_check_file)); gtk_widget_show(GTK_WIDGET(gui.vbox_digests_file)); gtk_widget_show(GTK_WIDGET(gui.hseparator_buttons)); gtk_widget_show(GTK_WIDGET(gui.button_hash)); char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER( gui.filechooserbutton)); if (uri) { gtk_widget_set_sensitive(GTK_WIDGET(gui.button_hash), funcs_enabled); g_free(uri); } else gtk_widget_set_sensitive(GTK_WIDGET(gui.button_hash), false); break; } case GUI_VIEW_TEXT: gtk_widget_hide(GTK_WIDGET(gui.label_file)); gtk_widget_hide(GTK_WIDGET(gui.filechooserbutton)); gtk_widget_hide(GTK_WIDGET(gui.entry_check_file)); gtk_widget_hide(GTK_WIDGET(gui.vbox_digests_file)); gtk_widget_hide(GTK_WIDGET(gui.hseparator_buttons)); gtk_widget_hide(GTK_WIDGET(gui.button_hash)); gtk_widget_show(GTK_WIDGET(gui.label_text)); gtk_widget_show(GTK_WIDGET(gui.entry_text)); gtk_widget_show(GTK_WIDGET(gui.entry_check_text)); gtk_widget_show(GTK_WIDGET(gui.vbox_digests_text)); gtk_widget_grab_focus(GTK_WIDGET(gui.entry_text)); if (funcs_enabled) hash_string(); break; case GUI_VIEW_FILE_LIST: list_update(); gtk_widget_hide(GTK_WIDGET(gui.vbox_single)); gtk_widget_hide(GTK_WIDGET(gui.hseparator_buttons)); gtk_widget_show(GTK_WIDGET(gui.vbox_list)); gtk_widget_show(GTK_WIDGET(gui.button_hash)); gtk_widget_set_visible(GTK_WIDGET(gui.toolbar), gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM( gui.menuitem_treeview_show_toolbar))); break; default: g_assert_not_reached(); } gui_check_digests(); gui_menuitem_save_as_set_sensitive(); } void gui_clear_digests(void) { switch (gui.view) { case GUI_VIEW_FILE: for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; gtk_entry_set_text(gui.hash_widgets[i].entry_file, ""); } gui_check_digests(); break; case GUI_VIEW_TEXT: for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; gtk_entry_set_text(gui.hash_widgets[i].entry_text, ""); } gui_check_digests(); break; case GUI_VIEW_FILE_LIST: list_clear_digests(); break; default: g_assert_not_reached(); } gui_menuitem_save_as_set_sensitive(); } void gui_check_digests(void) { const char *icon_in = NULL; GtkEntry *entry_check = NULL; switch (gui.view) { case GUI_VIEW_TEXT: entry_check = gui.entry_check_text; break; case GUI_VIEW_FILE: entry_check = gui.entry_check_file; break; case GUI_VIEW_FILE_LIST: // TODO return; default: g_assert_not_reached(); } const enum digest_format_e format = gui_get_digest_format(); const char *str_in = gtk_entry_get_text(entry_check); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].enabled) continue; GtkEntry *entry = NULL; switch (gui.view) { case GUI_VIEW_TEXT: entry = gui.hash_widgets[i].entry_text; break; case GUI_VIEW_FILE: entry = gui.hash_widgets[i].entry_file; break; default: g_assert_not_reached(); } const char *str_out = gtk_entry_get_text(entry); const char *icon_out = NULL; if (*str_in && gtkhash_digest_format_compare(str_in, str_out, format)) { // FIXME: find a real alternative for GTK_STOCK_YES icon_out = "gtk-yes"; icon_in = "gtk-yes"; } gtk_entry_set_icon_from_icon_name(entry, GTK_ENTRY_ICON_SECONDARY, icon_out); } gtk_entry_set_icon_from_icon_name(entry_check, GTK_ENTRY_ICON_SECONDARY, icon_in); } void gui_set_state(const enum gui_state_e state) { g_assert(GUI_STATE_IS_VALID(state)); g_assert(state != gui_priv.state); if (gui.view == GUI_VIEW_TEXT) g_assert(state != GUI_STATE_BUSY); gui_priv.state = state; const bool busy = (state == GUI_STATE_BUSY); gtk_widget_set_visible(GTK_WIDGET(gui.button_hash), !busy); gtk_widget_set_visible(GTK_WIDGET(gui.button_stop), busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.button_stop), busy); gtk_progress_bar_set_fraction(gui.progressbar, 0.0); gtk_progress_bar_set_text(gui.progressbar, " "); gtk_widget_set_visible(GTK_WIDGET(gui.progressbar), busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.hbox_input), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.hbox_output), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.toolbar), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.treeview), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_open), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.radiomenuitem_text), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.radiomenuitem_file), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.radiomenuitem_file_list), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.dialog_grid), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.dialog_togglebutton_show_hmac), !busy); gtk_widget_set_sensitive(GTK_WIDGET(gui.dialog_combobox), !busy); if (busy) gtk_window_set_default(gui.window, GTK_WIDGET(gui.button_stop)); else gtk_window_set_default(gui.window, GTK_WIDGET(gui.button_hash)); gui_menuitem_save_as_set_sensitive(); } bool gui_is_maximised(void) { GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(gui.window)); if (!window) return false; GdkWindowState state = gdk_window_get_state(window); return (state & GDK_WINDOW_STATE_MAXIMIZED); } void gui_start_hash(void) { switch (gui.view) { case GUI_VIEW_FILE: { gui_clear_digests(); gui_set_state(GUI_STATE_BUSY); char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER( gui.filechooserbutton)); hash_file_start(uri); break; } case GUI_VIEW_FILE_LIST: gui_clear_digests(); gui_set_state(GUI_STATE_BUSY); hash_file_list_start(); break; default: g_assert_not_reached(); } } void gui_stop_hash(void) { g_assert(gui.view != GUI_VIEW_TEXT); gtk_widget_set_sensitive(GTK_WIDGET(gui.button_stop), false); hash_file_stop(); } gtkhash-1.5/src/gui.h000066400000000000000000000072641431266303500145500ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_GUI_H #define GTKHASH_GUI_H #include #include #include "hash.h" #include "uri-digest.h" #include "hash/hash-func.h" #define GUI_VIEW_IS_VALID(X) (((X) >= 0) && ((X) <= GUI_VIEW_FILE_LIST)) #define GUI_STATE_IS_VALID(X) (((X) >= 0) && ((X) <= GUI_STATE_BUSY)) enum gui_view_e { GUI_VIEW_INVALID = -1, GUI_VIEW_FILE, GUI_VIEW_TEXT, GUI_VIEW_FILE_LIST, }; enum gui_state_e { GUI_STATE_INVALID = -1, GUI_STATE_IDLE, GUI_STATE_BUSY, }; extern struct gui_s { GtkWindow *window; GtkMenuItem *menuitem_open, *menuitem_save_as, *menuitem_quit; GtkMenuItem *menuitem_edit; GtkMenuItem *menuitem_cut, *menuitem_copy, *menuitem_paste; GtkMenuItem *menuitem_delete, *menuitem_select_all, *menuitem_prefs; GtkMenuItem *menuitem_about; GtkRadioMenuItem *radiomenuitem_file, *radiomenuitem_text, *radiomenuitem_file_list; GtkToolbar *toolbar; GtkToolButton *toolbutton_add, *toolbutton_remove, *toolbutton_clear; GtkBox *vbox_single, *vbox_list; GtkBox *hbox_input, *hbox_output; GtkBox *vbox_outputlabels, *vbox_digests_file, *vbox_digests_text; GtkEntry *entry_text, *entry_check_file, *entry_check_text; GtkEntry *entry_hmac_file, *entry_hmac_text; GtkFileChooserButton *filechooserbutton; GtkToggleButton *togglebutton_hmac_file, *togglebutton_hmac_text; GtkLabel *label_file, *label_text; GtkTreeView *treeview; GtkTreeSelection *treeselection; GtkTreeModel *treemodel; GtkListStore *liststore; GtkMenu *menu_treeview; GtkMenuItem *menuitem_treeview_add, *menuitem_treeview_remove; GtkMenuItem *menuitem_treeview_clear; GtkMenu *menu_treeview_copy; GtkMenuItem *menuitem_treeview_copy; GtkMenuItem *menuitem_treeview_show_toolbar; GtkSeparator *hseparator_buttons; GtkProgressBar *progressbar; GtkButton *button_hash, *button_stop; GtkDialog *dialog; GtkGrid *dialog_grid; GtkToggleButton *dialog_togglebutton_show_hmac; GtkComboBox *dialog_combobox; GtkButton *dialog_button_close; enum gui_view_e view; struct { GtkToggleButton *button; GtkModelButton *label_file; GtkLabel *label_text; GtkEntry *entry_file, *entry_text; GtkMenuItem *menuitem_treeview_copy; } hash_widgets[HASH_FUNCS_N]; } gui; void gui_init(void); unsigned int gui_add_ud_list(GSList *ud_list, enum gui_view_e view); void gui_add_check(const char *check); void gui_add_text(const char *text); void gui_error(const char *message); void gui_run(void); void gui_deinit(void); void gui_set_view(enum gui_view_e view); void gui_set_digest_format(enum digest_format_e format); enum digest_format_e gui_get_digest_format(void); const uint8_t *gui_get_hmac_key(size_t *key_size); void gui_enable_hash_func(enum hash_func_e id); void gui_update_hash_func_labels(bool hmac_enabled); void gui_update_hash_funcs(void); void gui_update(void); void gui_clear_digests(void); void gui_check_digests(void); void gui_set_state(enum gui_state_e state); bool gui_is_maximised(void); void gui_start_hash(void); void gui_stop_hash(void); #endif gtkhash-1.5/src/hash.c000066400000000000000000000111561431266303500146750ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "hash.h" #include "main.h" #include "gui.h" #include "list.h" #include "hash/hash-func.h" #include "hash/hash-string.h" #include "hash/hash-file.h" #include "util/util.h" struct hash_s hash; static struct { struct hash_file_s *hfile; unsigned int list_row; } hash_priv = { .hfile = NULL, .list_row = 0, }; void gtkhash_hash_string_finish_cb(void) { gui_check_digests(); } void gtkhash_hash_string_digest_cb(const enum hash_func_e id, const char *digest) { gtk_entry_set_text(gui.hash_widgets[id].entry_text, digest); } void gtkhash_hash_file_report_cb(G_GNUC_UNUSED void *data, const goffset file_size, const goffset total_read, GTimer *timer) { gtk_progress_bar_set_fraction(gui.progressbar, (double)total_read / (double)file_size); const double elapsed = g_timer_elapsed(timer, NULL); if (elapsed <= 1) return; char *text = gtkhash_format_progress(file_size, total_read, elapsed); gtk_progress_bar_set_text(gui.progressbar, text); g_free(text); } void gtkhash_hash_file_digest_cb(const enum hash_func_e id, const char *digest, G_GNUC_UNUSED void *data) { switch (gui.view) { case GUI_VIEW_FILE: gtk_entry_set_text(gui.hash_widgets[id].entry_file, digest); break; case GUI_VIEW_FILE_LIST: list_set_digest(hash_priv.list_row, id, digest); break; default: g_assert_not_reached(); } } void gtkhash_hash_file_finish_cb(void *uri) { g_free(uri); if (gui.view == GUI_VIEW_FILE_LIST) { list_check_digests(hash_priv.list_row); if (++hash_priv.list_row < list.rows) { gtk_progress_bar_set_fraction(gui.progressbar, 0.0); gtk_progress_bar_set_text(gui.progressbar, " "); // Next file hash_file_start(list_get_uri(hash_priv.list_row)); return; } else hash_priv.list_row = 0; } else { // Reset enabled state following single-function hash gui_update_hash_funcs(); } gui_check_digests(); gui_set_state(GUI_STATE_IDLE); } void gtkhash_hash_file_stop_cb(void *uri) { g_free(uri); if (gui.view == GUI_VIEW_FILE_LIST) hash_priv.list_row = 0; else { // Reset enabled state following single-function hash gui_update_hash_funcs(); } gui_set_state(GUI_STATE_IDLE); } void hash_file_start(const char *uri) { g_assert(hash_funcs_count_enabled()); const enum digest_format_e format = gui_get_digest_format(); size_t key_size = 0; const uint8_t *hmac_key = gui_get_hmac_key(&key_size); gtkhash_hash_file(hash_priv.hfile, uri, format, hmac_key, key_size, uri); } void hash_file_list_start(void) { g_assert(hash_funcs_count_enabled()); g_assert(!hash_priv.list_row); char *uri = list_get_uri(hash_priv.list_row); hash_file_start(uri); } void hash_file_stop(void) { gtkhash_hash_file_cancel(hash_priv.hfile); } void hash_string(void) { if (!hash_funcs_count_enabled()) return; const char *str = gtk_entry_get_text(gui.entry_text); const enum digest_format_e format = gui_get_digest_format(); size_t key_size = 0; const uint8_t *hmac_key = gui_get_hmac_key(&key_size); gtkhash_hash_string(hash.funcs, str, format, hmac_key, key_size); } unsigned int hash_funcs_count_enabled(void) { unsigned int ret = 0; for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].enabled) ret++; } return ret; } void hash_funcs_enable_strv(const char **funcs) { for (int i = 0; funcs[i]; i++) { enum hash_func_e id = gtkhash_hash_func_get_id_from_name(funcs[i]); if (HASH_FUNC_IS_VALID(id) && hash.funcs[id].supported) hash.funcs[id].enabled = true; else g_message(_("Unknown Hash Function name \"%s\""), funcs[i]); } } void hash_init(void) { gtkhash_hash_func_init_all(hash.funcs); hash_priv.hfile = gtkhash_hash_file_new(hash.funcs); } void hash_deinit(void) { gtkhash_hash_file_free(hash_priv.hfile); hash_priv.hfile = NULL; gtkhash_hash_func_deinit_all(hash.funcs); } gtkhash-1.5/src/hash.h000066400000000000000000000023121431266303500146740ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_H #define GTKHASH_HASH_H #include "hash/hash-func.h" #include "hash/hash-file.h" extern struct hash_s { struct hash_func_s funcs[HASH_FUNCS_N]; } hash; void hash_file_start(const char *uri); void hash_file_list_start(void); void hash_file_stop(void); void hash_string(void); unsigned int hash_funcs_count_enabled(void); void hash_funcs_enable_strv(const char **funcs); void hash_init(void); void hash_deinit(void); #endif gtkhash-1.5/src/hash/000077500000000000000000000000001431266303500145255ustar00rootroot00000000000000gtkhash-1.5/src/hash/Makefile.am000066400000000000000000000027111431266303500165620ustar00rootroot00000000000000noinst_LTLIBRARIES = hash.la hash_la_SOURCES = \ digest.c digest.h \ digest-format.c digest-format.h \ hash-file.c hash-file.h \ hash-func.c hash-func.h \ hash-lib.c hash-lib.h \ hash-string.c hash-string.h \ hmac.c hmac.h hash_la_CPPFLAGS = \ -DIN_HASH_LIB \ $(GLIB_CFLAGS) \ $(GIO_CFLAGS) hash_la_CFLAGS = $(GTKHASH_CFLAGS) hash_la_LDFLAGS = -avoid-version -module hash_la_LIBADD = \ $(GLIB_LIBS) \ $(GIO_LIBS) EXTRA_DIST = \ md6/md6.h \ md6/md6_compress.c \ md6/md6_mode.c \ meson.build if ENABLE_BLAKE2 hash_la_SOURCES += hash-lib-blake2.c hash_la_LIBADD += $(BLAKE2_LIBS) endif if ENABLE_GCRYPT hash_la_SOURCES += hash-lib-gcrypt.c hash_la_CPPFLAGS += $(LIBGCRYPT_CFLAGS) hash_la_LIBADD += $(LIBGCRYPT_LIBS) endif if ENABLE_GLIB_CHECKSUMS hash_la_SOURCES += hash-lib-glib.c endif if ENABLE_LIBCRYPTO hash_la_SOURCES += hash-lib-crypto.c hash_la_CPPFLAGS += $(LIBCRYPTO_CFLAGS) hash_la_LIBADD += $(LIBCRYPTO_LIBS) endif if ENABLE_LINUX_CRYPTO hash_la_SOURCES += hash-lib-linux.c endif if ENABLE_MBEDTLS hash_la_SOURCES += hash-lib-mbedtls.c hash_la_LIBADD += $(MBEDTLS_LIBS) endif if ENABLE_INTERNAL_MD6 hash_la_SOURCES += hash-lib-md6.c endif if ENABLE_NETTLE hash_la_SOURCES += hash-lib-nettle.c hash_la_CPPFLAGS += $(NETTLE_CFLAGS) hash_la_LIBADD += $(NETTLE_LIBS) endif if ENABLE_ZLIB hash_la_SOURCES += hash-lib-zlib.c hash_la_CPPFLAGS += $(ZLIB_CFLAGS) hash_la_LIBADD += $(ZLIB_LIBS) endif CLEANFILES = *.gcda *.gcno md6/*.gcda md6/*.gcno gtkhash-1.5/src/hash/digest-format.c000066400000000000000000000027331431266303500174430ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "digest-format.h" // Returns true if the two digests are equivalent in the specified format bool gtkhash_digest_format_compare(char const *digest1, const char *digest2, enum digest_format_e format) { g_assert(DIGEST_FORMAT_IS_VALID(format)); if (!digest1 || !digest2 || !*digest1 || !*digest2) return false; switch (format) { case DIGEST_FORMAT_HEX_LOWER: case DIGEST_FORMAT_HEX_UPPER: return g_ascii_strcasecmp(digest1, digest2) == 0; case DIGEST_FORMAT_BASE64: return strcmp(digest1, digest2) == 0; default: g_assert_not_reached(); return false; } } gtkhash-1.5/src/hash/digest-format.h000066400000000000000000000023031431266303500174410ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_DIGEST_FORMAT_H #define GTKHASH_HASH_DIGEST_FORMAT_H #include #define DIGEST_FORMATS_N 3 #define DIGEST_FORMAT_IS_VALID(X) (((X) >= 0) && ((X) < DIGEST_FORMATS_N)) enum digest_format_e { DIGEST_FORMAT_INVALID = -1, DIGEST_FORMAT_HEX_LOWER, DIGEST_FORMAT_HEX_UPPER, DIGEST_FORMAT_BASE64, }; bool gtkhash_digest_format_compare(const char *str1, const char *str2, enum digest_format_e format); #endif gtkhash-1.5/src/hash/digest.c000066400000000000000000000056341431266303500161600ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "digest.h" // Returns a newly-allocated lowercase hexadecimal digest string static char *gtkhash_digest_get_hex_lower(struct digest_s *digest) { char *ret = g_malloc((digest->size * 2) + 1); for (uint8_t i = 0; i < digest->size; i++) snprintf(&ret[i * 2], 3, "%.2x", digest->bin[i]); return ret; } // Returns a newly-allocated uppercase hexadecimal digest string static char *gtkhash_digest_get_hex_upper(struct digest_s *digest) { char *ret = g_malloc((digest->size * 2) + 1); for (uint8_t i = 0; i < digest->size; i++) snprintf(&ret[i * 2], 3, "%.2X", digest->bin[i]); return ret; } // Returns a newly-allocated digest_s structure struct digest_s *gtkhash_digest_new(void) { struct digest_s *digest = g_new(struct digest_s, 1); digest->bin = NULL; digest->size = 0; return digest; } // Sets the stored digest using the given binary value void gtkhash_digest_set_data(struct digest_s *digest, uint8_t *bin, const size_t size) { g_assert(digest); g_assert(bin); g_assert(size); gtkhash_digest_free_data(digest); digest->bin = bin; digest->size = size; } // Returns a newly-allocated digest string in the requested format char *gtkhash_digest_get_data(struct digest_s *digest, const enum digest_format_e format) { g_assert(digest); g_assert(DIGEST_FORMAT_IS_VALID(format)); switch (format) { case DIGEST_FORMAT_HEX_LOWER: return gtkhash_digest_get_hex_lower(digest); case DIGEST_FORMAT_HEX_UPPER: return gtkhash_digest_get_hex_upper(digest); case DIGEST_FORMAT_BASE64: return g_base64_encode(digest->bin, digest->size); default: g_assert_not_reached(); return NULL; } } // Resets a digest_s structure back to its original state void gtkhash_digest_free_data(struct digest_s *digest) { g_assert(digest); if (digest->bin) { g_free(digest->bin); digest->bin = NULL; } digest->size = 0; } // Frees a digest_s structure void gtkhash_digest_free(struct digest_s *digest) { g_assert(digest); gtkhash_digest_free_data(digest); g_free(digest); } gtkhash-1.5/src/hash/digest.h000066400000000000000000000024771431266303500161670ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_DIGEST_H #define GTKHASH_HASH_DIGEST_H #ifndef IN_HASH_LIB #error "don't use directly" #endif #include #include #include "digest-format.h" struct digest_s { uint8_t *bin; size_t size; }; struct digest_s *gtkhash_digest_new(void); void gtkhash_digest_set_data(struct digest_s *digest, uint8_t *bin, size_t size); char *gtkhash_digest_get_data(struct digest_s *digest, enum digest_format_e format); void gtkhash_digest_free_data(struct digest_s *digest); void gtkhash_digest_free(struct digest_s *digest); #endif gtkhash-1.5/src/hash/hash-file.c000066400000000000000000000332631431266303500165400ustar00rootroot00000000000000/* * Copyright (C) 2007-2019 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "hash-file.h" #include "hash-func.h" #include "hash-lib.h" #include "digest-format.h" #ifndef G_SOURCE_FUNC #define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f)) #endif // This lib can use GDK 2 or 3, but doesn't link either directly. // Try to avoid potential ABI/API mismatch issues by only declaring // necessary gdk.h functions... guint gdk_threads_add_idle(GSourceFunc, gpointer); guint gdk_threads_add_timeout(guint, GSourceFunc, gpointer); // (this might cause other problems) static gboolean gtkhash_hash_file_source_func(struct hash_file_s *data); static void gtkhash_hash_file_hash_thread_func(struct hash_func_s *func, struct hash_file_s *data); enum hash_file_state_e { HASH_FILE_STATE_IDLE, HASH_FILE_STATE_START, HASH_FILE_STATE_OPEN, HASH_FILE_STATE_GET_SIZE, HASH_FILE_STATE_READ, HASH_FILE_STATE_HASH, HASH_FILE_STATE_HASH_FINISH, HASH_FILE_STATE_CLOSE, HASH_FILE_STATE_FINISH, HASH_FILE_STATE_CALLBACK, }; struct hash_file_s { goffset file_size, total_read; const void *cb_data; const char *uri; GFile *file; const uint8_t *hmac_key; size_t key_size; GCancellable *cancellable; GFileInputStream *stream; gssize just_read; uint8_t *buffer; GTimer *timer; GThreadPool *thread_pool; struct hash_func_s *funcs; enum hash_file_state_e state; enum digest_format_e format; int threads; unsigned int report_source; unsigned int source; GMutex mtx; }; static void gtkhash_hash_file_add_source(struct hash_file_s *data) { g_mutex_lock(&data->mtx); g_assert(!data->source); data->source = g_idle_add(G_SOURCE_FUNC(gtkhash_hash_file_source_func), data); g_mutex_unlock(&data->mtx); } static void gtkhash_hash_file_remove_source(struct hash_file_s *data) { g_mutex_lock(&data->mtx); if (G_UNLIKELY(!g_source_remove(data->source))) g_assert_not_reached(); data->source = 0; g_mutex_unlock(&data->mtx); } void gtkhash_hash_file_cancel(struct hash_file_s *data) { g_cancellable_cancel(data->cancellable); } static gboolean gtkhash_hash_file_report_source_func(struct hash_file_s *data) { if (data->report_source && data->total_read) gtkhash_hash_file_report_cb((void *)data->cb_data, data->file_size, data->total_read, data->timer); return true; } static void gtkhash_hash_file_add_report_source(struct hash_file_s *data) { g_assert(!data->report_source); data->report_source = gdk_threads_add_timeout(HASH_FILE_REPORT_INTERVAL, G_SOURCE_FUNC(gtkhash_hash_file_report_source_func), data); } static void gtkhash_hash_file_remove_report_source(struct hash_file_s *data) { if (data->report_source) { if (G_UNLIKELY(!g_source_remove(data->report_source))) g_assert_not_reached(); data->report_source = 0; } } static void gtkhash_hash_file_start(struct hash_file_s *data) { g_assert(data->uri); int funcs_enabled = 0; for (int i = 0; i < HASH_FUNCS_N; i++) { if (data->funcs[i].enabled) { gtkhash_hash_lib_start(&data->funcs[i], data->hmac_key, data->key_size); funcs_enabled++; } } g_assert(funcs_enabled > 0); // Determine max number of threads to use const int cpus = g_get_num_processors(); const int threads = CLAMP(MIN(funcs_enabled, cpus), 1, HASH_FUNCS_N); g_atomic_int_set(&data->threads, 0); data->thread_pool = g_thread_pool_new( (GFunc)gtkhash_hash_file_hash_thread_func, data, threads, true, NULL); data->file = g_file_new_for_uri(data->uri); data->just_read = 0; data->buffer = g_malloc(HASH_FILE_BUFFER_SIZE); data->timer = g_timer_new(); data->total_read = 0; data->state = HASH_FILE_STATE_OPEN; } static void gtkhash_hash_file_open_finish(G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { data->stream = g_file_read_finish(data->file, res, NULL); if (G_UNLIKELY(!data->stream && !g_cancellable_is_cancelled(data->cancellable))) { g_warning("failed to open file (%s)", data->uri); g_cancellable_cancel(data->cancellable); } if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { if (data->stream) data->state = HASH_FILE_STATE_CLOSE; else data->state = HASH_FILE_STATE_FINISH; } else data->state = HASH_FILE_STATE_GET_SIZE; gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_open(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { data->state = HASH_FILE_STATE_FINISH; return; } gtkhash_hash_file_remove_source(data); g_file_read_async(data->file, G_PRIORITY_DEFAULT, data->cancellable, (GAsyncReadyCallback)gtkhash_hash_file_open_finish, data); } static void gtkhash_hash_file_get_size_finish(G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { GError *error = NULL; GFileInfo *info = g_file_input_stream_query_info_finish( data->stream, res, &error); if (G_UNLIKELY(!info)) { g_warning("query info: %s", error->message); g_error_free(error); data->state = HASH_FILE_STATE_CLOSE; g_cancellable_cancel(data->cancellable); } else { data->file_size = g_file_info_get_size(info); g_object_unref(info); if (data->file_size == 0) data->state = HASH_FILE_STATE_HASH; else { data->state = HASH_FILE_STATE_READ; gtkhash_hash_file_add_report_source(data); } } gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_get_size(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { data->state = HASH_FILE_STATE_CLOSE; return; } gtkhash_hash_file_remove_source(data); g_file_input_stream_query_info_async(data->stream, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_PRIORITY_DEFAULT, data->cancellable, (GAsyncReadyCallback)gtkhash_hash_file_get_size_finish, data); } static void gtkhash_hash_file_read_finish(G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { data->just_read = g_input_stream_read_finish( G_INPUT_STREAM(data->stream), res, NULL); if (G_UNLIKELY(data->just_read == -1) && !g_cancellable_is_cancelled(data->cancellable)) { g_warning("failed to read file (%s)", data->uri); g_cancellable_cancel(data->cancellable); } else if (G_UNLIKELY(data->just_read == 0)) { g_warning("unexpected EOF (%s)", data->uri); g_cancellable_cancel(data->cancellable); } else { data->total_read += data->just_read; if (G_UNLIKELY(data->total_read > data->file_size)) { g_warning("read %" G_GOFFSET_FORMAT " more bytes than expected (%s)", data->total_read - data->file_size, data->uri); g_cancellable_cancel(data->cancellable); } else data->state = HASH_FILE_STATE_HASH; } if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) data->state = HASH_FILE_STATE_CLOSE; gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_read(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { data->state = HASH_FILE_STATE_CLOSE; return; } gtkhash_hash_file_remove_source(data); g_input_stream_read_async(G_INPUT_STREAM(data->stream), data->buffer, HASH_FILE_BUFFER_SIZE, G_PRIORITY_DEFAULT, data->cancellable, (GAsyncReadyCallback)gtkhash_hash_file_read_finish, data); } static void gtkhash_hash_file_hash_thread_func(struct hash_func_s *func, struct hash_file_s *data) { gtkhash_hash_lib_update(func, data->buffer, data->just_read); if (g_atomic_int_dec_and_test(&data->threads)) gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_hash(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { data->state = HASH_FILE_STATE_CLOSE; return; } gtkhash_hash_file_remove_source(data); data->state = HASH_FILE_STATE_HASH_FINISH; g_atomic_int_inc(&data->threads); for (int i = 0; i < HASH_FUNCS_N; i++) { if (data->funcs[i].enabled) { g_atomic_int_inc(&data->threads); g_thread_pool_push(data->thread_pool, &data->funcs[i], NULL); } } if (g_atomic_int_dec_and_test(&data->threads)) gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_hash_finish(struct hash_file_s *data) { g_assert(g_atomic_int_get(&data->threads) == 0); if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { data->state = HASH_FILE_STATE_CLOSE; return; } if (data->total_read >= data->file_size) data->state = HASH_FILE_STATE_CLOSE; else data->state = HASH_FILE_STATE_READ; } static void gtkhash_hash_file_close_finish(G_GNUC_UNUSED GObject *source, GAsyncResult *res, struct hash_file_s *data) { if (G_UNLIKELY(!g_input_stream_close_finish(G_INPUT_STREAM(data->stream), res, NULL) && !g_cancellable_is_cancelled(data->cancellable))) { g_warning("failed to close file (%s)", data->uri); } g_object_unref(data->stream); gtkhash_hash_file_remove_report_source(data); data->state = HASH_FILE_STATE_FINISH; gtkhash_hash_file_add_source(data); } static void gtkhash_hash_file_close(struct hash_file_s *data) { gtkhash_hash_file_remove_source(data); g_input_stream_close_async(G_INPUT_STREAM(data->stream), G_PRIORITY_DEFAULT, data->cancellable, (GAsyncReadyCallback)gtkhash_hash_file_close_finish, data); } static void gtkhash_hash_file_finish(struct hash_file_s *data) { if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { for (int i = 0; i < HASH_FUNCS_N; i++) if (data->funcs[i].enabled) gtkhash_hash_lib_stop(&data->funcs[i]); } else { for (int i = 0; i < HASH_FUNCS_N; i++) if (data->funcs[i].enabled) gtkhash_hash_lib_finish(&data->funcs[i]); } g_object_unref(data->file); data->file = NULL; g_free(data->buffer); data->buffer = NULL; g_timer_destroy(data->timer); data->timer = NULL; g_thread_pool_free(data->thread_pool, true, false); data->thread_pool = NULL; data->state = HASH_FILE_STATE_CALLBACK; } static gboolean gtkhash_hash_file_callback_stop_func(void *cb_data) { gtkhash_hash_file_stop_cb(cb_data); return false; } static gboolean gtkhash_hash_file_callback_finish_func( struct hash_file_s *data) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!data->funcs[i].enabled) continue; char *digest = gtkhash_hash_func_get_digest(&data->funcs[i], data->format); gtkhash_hash_file_digest_cb(i, digest, (void *)data->cb_data); g_free(digest); gtkhash_hash_func_clear_digest(&data->funcs[i]); } gtkhash_hash_file_finish_cb((void *)data->cb_data); return false; } static void gtkhash_hash_file_callback(struct hash_file_s *data) { gtkhash_hash_file_remove_source(data); data->state = HASH_FILE_STATE_IDLE; if (G_UNLIKELY(g_cancellable_is_cancelled(data->cancellable))) { gdk_threads_add_idle(gtkhash_hash_file_callback_stop_func, (void *)data->cb_data); } else { gdk_threads_add_idle( G_SOURCE_FUNC(gtkhash_hash_file_callback_finish_func), data); } g_object_unref(data->cancellable); data->cancellable = NULL; } static gboolean gtkhash_hash_file_source_func(struct hash_file_s *data) { static void (* const state_funcs[])(struct hash_file_s *) = { [HASH_FILE_STATE_IDLE] = NULL, [HASH_FILE_STATE_START] = gtkhash_hash_file_start, [HASH_FILE_STATE_OPEN] = gtkhash_hash_file_open, [HASH_FILE_STATE_GET_SIZE] = gtkhash_hash_file_get_size, [HASH_FILE_STATE_READ] = gtkhash_hash_file_read, [HASH_FILE_STATE_HASH] = gtkhash_hash_file_hash, [HASH_FILE_STATE_HASH_FINISH] = gtkhash_hash_file_hash_finish, [HASH_FILE_STATE_CLOSE] = gtkhash_hash_file_close, [HASH_FILE_STATE_FINISH] = gtkhash_hash_file_finish, [HASH_FILE_STATE_CALLBACK] = gtkhash_hash_file_callback, }; state_funcs[data->state](data); return true; } void gtkhash_hash_file(struct hash_file_s *data, const char *uri, const enum digest_format_e format, const uint8_t *hmac_key, const size_t key_size, const void *cb_data) { g_assert(data); g_assert(uri && *uri); g_assert(DIGEST_FORMAT_IS_VALID(format)); g_assert(data->state == HASH_FILE_STATE_IDLE); g_assert(data->report_source == 0); g_assert(data->source == 0); g_assert(!data->cancellable); data->uri = uri; data->format = format; data->hmac_key = hmac_key; data->key_size = key_size; data->cb_data = cb_data; data->cancellable = g_cancellable_new(); data->state = HASH_FILE_STATE_START; gtkhash_hash_file_add_source(data); } struct hash_file_s *gtkhash_hash_file_new(struct hash_func_s *funcs) { struct hash_file_s *data = g_new(struct hash_file_s, 1); data->file_size = 0; data->total_read = 0; data->cb_data = NULL; data->uri = NULL; data->file = NULL; data->hmac_key = NULL; data->key_size = 0; data->cancellable = NULL; data->stream = NULL; data->just_read = 0; data->buffer = NULL; data->timer = NULL; data->thread_pool = NULL; data->funcs = funcs; data->state = HASH_FILE_STATE_IDLE; data->format = DIGEST_FORMAT_INVALID; g_atomic_int_set(&data->threads, 0); data->report_source = 0; data->source = 0; g_mutex_init(&data->mtx); return data; } void gtkhash_hash_file_free(struct hash_file_s *data) { g_assert(data); // Shouldn't still be running g_assert(data->state == HASH_FILE_STATE_IDLE); g_assert(data->report_source == 0); g_assert(data->source == 0); g_mutex_clear(&data->mtx); g_free(data); } gtkhash-1.5/src/hash/hash-file.h000066400000000000000000000034541431266303500165440ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_HASH_FILE_H #define GTKHASH_HASH_HASH_FILE_H #include #include #include #include #include "hash-func.h" #include "digest-format.h" struct hash_file_s; void gtkhash_hash_file_cancel(struct hash_file_s *data); struct hash_file_s *gtkhash_hash_file_new(struct hash_func_s *funcs); void gtkhash_hash_file_free(struct hash_file_s *data); void gtkhash_hash_file(struct hash_file_s *data, const char *uri, enum digest_format_e format, const uint8_t *hmac_key, size_t key_size, const void *cb_data); // // Callbacks // // Called periodically to report file hash progress void gtkhash_hash_file_report_cb(void *data, goffset file_size, goffset total_read, GTimer *timer); // Called with digest result for each enabled hash function void gtkhash_hash_file_digest_cb(enum hash_func_e id, const char *digest, void *data); // Called after hashing is complete void gtkhash_hash_file_finish_cb(void *data); // Called after hashing is canceled void gtkhash_hash_file_stop_cb(void *data); #endif gtkhash-1.5/src/hash/hash-func.c000066400000000000000000000112671431266303500165540ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "hash-func.h" #include "hash-lib.h" #include "digest.h" static const struct { const char * const name; const uint8_t digest_size; const uint8_t block_size; // for HMAC } hash_func_data[HASH_FUNCS_N] = { [HASH_FUNC_ADLER32] = { "ADLER32", 4, 0, }, [HASH_FUNC_BLAKE2B] = { "BLAKE2b", 64, 128, }, [HASH_FUNC_BLAKE2BP] = { "BLAKE2bp", 64, 0, }, [HASH_FUNC_BLAKE2S] = { "BLAKE2s", 32, 64, }, [HASH_FUNC_BLAKE2SP] = { "BLAKE2sp", 32, 0, }, [HASH_FUNC_CRC32] = { "CRC32", 4, 0, }, [HASH_FUNC_CRC32C] = { "CRC32C", 4, 0, }, [HASH_FUNC_GOST] = { "GOST", 32, 0, }, [HASH_FUNC_MD2] = { "MD2", 16, 0, }, [HASH_FUNC_MD4] = { "MD4", 16, 0, }, [HASH_FUNC_MD5] = { "MD5", 16, 64, }, [HASH_FUNC_MD6_224] = { "MD6-224", 28, 0, }, [HASH_FUNC_MD6_256] = { "MD6-256", 32, 0, }, [HASH_FUNC_MD6_384] = { "MD6-384", 48, 0, }, [HASH_FUNC_MD6_512] = { "MD6-512", 64, 0, }, [HASH_FUNC_MDC2] = { "MDC2", 16, 0, }, [HASH_FUNC_RIPEMD128] = { "RIPEMD128", 16, 64, }, [HASH_FUNC_RIPEMD160] = { "RIPEMD160", 20, 64, }, [HASH_FUNC_RIPEMD256] = { "RIPEMD256", 32, 0, }, [HASH_FUNC_RIPEMD320] = { "RIPEMD320", 40, 0, }, [HASH_FUNC_SHA1] = { "SHA1", 20, 64, }, [HASH_FUNC_SHA224] = { "SHA224", 28, 64, }, [HASH_FUNC_SHA256] = { "SHA256", 32, 64, }, [HASH_FUNC_SHA384] = { "SHA384", 48, 128, }, [HASH_FUNC_SHA512] = { "SHA512", 64, 128, }, [HASH_FUNC_SHA3_224] = { "SHA3-224", 28, 144, }, [HASH_FUNC_SHA3_256] = { "SHA3-256", 32, 136, }, [HASH_FUNC_SHA3_384] = { "SHA3-384", 48, 104, }, [HASH_FUNC_SHA3_512] = { "SHA3-512", 64, 72, }, [HASH_FUNC_SM3] = { "SM3", 32, 0, }, [HASH_FUNC_TIGER192] = { "TIGER192", 24, 0, }, [HASH_FUNC_WHIRLPOOL] = { "WHIRLPOOL", 64, 0, }, [HASH_FUNC_XXH64] = { "XXH64", 8, 0, }, }; enum hash_func_e gtkhash_hash_func_get_id_from_name(const char *name) { g_assert(name); for (int i = 0; i < HASH_FUNCS_N; i++) if (g_ascii_strcasecmp(name, hash_func_data[i].name) == 0) return i; return HASH_FUNC_INVALID; } void gtkhash_hash_func_set_digest(struct hash_func_s *func, uint8_t *digest, size_t size) { g_assert(func); g_assert(digest); g_assert(size == func->digest_size); gtkhash_digest_set_data(func->digest, digest, size); } char *gtkhash_hash_func_get_digest(struct hash_func_s *func, const enum digest_format_e format) { g_assert(func); g_assert(DIGEST_FORMAT_IS_VALID(format)); char *digest = gtkhash_digest_get_data(func->digest, format); g_assert(digest); return digest; } void gtkhash_hash_func_clear_digest(struct hash_func_s *func) { g_assert(func); gtkhash_digest_free_data(func->digest); } void gtkhash_hash_func_init(struct hash_func_s *func, const enum hash_func_e id) { g_assert(func); g_assert(HASH_FUNC_IS_VALID(id)); func->id = id; func->supported = gtkhash_hash_lib_is_supported(id); func->enabled = false; func->name = hash_func_data[id].name; func->digest = gtkhash_digest_new(); func->lib_data = NULL; func->hmac_data = NULL; func->digest_size = hash_func_data[id].digest_size; func->block_size = hash_func_data[id].block_size; func->hmac_supported = (hash_func_data[id].block_size > 0); } void gtkhash_hash_func_init_all(struct hash_func_s *funcs) { g_assert(funcs); for (int i = 0; i < HASH_FUNCS_N; i++) gtkhash_hash_func_init(&funcs[i], i); } void gtkhash_hash_func_deinit(struct hash_func_s *func) { g_assert(func); gtkhash_digest_free(func->digest); func->digest = NULL; } void gtkhash_hash_func_deinit_all(struct hash_func_s *funcs) { g_assert(funcs); for (int i = 0; i < HASH_FUNCS_N; i++) gtkhash_hash_func_deinit(&funcs[i]); } gtkhash-1.5/src/hash/hash-func.h000066400000000000000000000053371431266303500165620ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_HASH_FUNC_H #define GTKHASH_HASH_HASH_FUNC_H #include #include #include #include "digest-format.h" #define HASH_FUNCS_N (HASH_FUNC_XXH64 + 1) #define HASH_FUNC_IS_VALID(X) (((X) >= 0) && ((X) < HASH_FUNCS_N)) #define HASH_FUNC_IS_DEFAULT(X) ( \ (X) == HASH_FUNC_MD5 || \ (X) == HASH_FUNC_SHA1 || \ (X) == HASH_FUNC_SHA256 || \ (X) == HASH_FUNC_CRC32) // All supported hash functions // Note: Default ordering is defined here enum hash_func_e { HASH_FUNC_INVALID = -1, HASH_FUNC_MD2, HASH_FUNC_MD4, HASH_FUNC_MD5, HASH_FUNC_MD6_224, HASH_FUNC_MD6_256, HASH_FUNC_MD6_384, HASH_FUNC_MD6_512, HASH_FUNC_SHA1, HASH_FUNC_SHA224, HASH_FUNC_SHA256, HASH_FUNC_SHA384, HASH_FUNC_SHA512, HASH_FUNC_SHA3_224, HASH_FUNC_SHA3_256, HASH_FUNC_SHA3_384, HASH_FUNC_SHA3_512, HASH_FUNC_BLAKE2B, HASH_FUNC_BLAKE2S, HASH_FUNC_BLAKE2BP, HASH_FUNC_BLAKE2SP, HASH_FUNC_RIPEMD128, HASH_FUNC_RIPEMD160, HASH_FUNC_RIPEMD256, HASH_FUNC_RIPEMD320, HASH_FUNC_TIGER192, HASH_FUNC_WHIRLPOOL, HASH_FUNC_SM3, HASH_FUNC_GOST, HASH_FUNC_MDC2, HASH_FUNC_CRC32, HASH_FUNC_CRC32C, HASH_FUNC_ADLER32, HASH_FUNC_XXH64, }; struct hash_func_s { const char *name; struct digest_s *digest; void *lib_data; struct hash_func_s *hmac_data; enum hash_func_e id; uint8_t digest_size; uint8_t block_size; bool supported:1; bool hmac_supported:1; bool enabled:1; }; enum hash_func_e gtkhash_hash_func_get_id_from_name(const char *name); void gtkhash_hash_func_set_digest(struct hash_func_s *func, uint8_t *digest, size_t size); char *gtkhash_hash_func_get_digest(struct hash_func_s *func, enum digest_format_e format); void gtkhash_hash_func_clear_digest(struct hash_func_s *func); void gtkhash_hash_func_init(struct hash_func_s *func, enum hash_func_e id); void gtkhash_hash_func_init_all(struct hash_func_s *funcs); void gtkhash_hash_func_deinit(struct hash_func_s *func); void gtkhash_hash_func_deinit_all(struct hash_func_s *funcs); #endif gtkhash-1.5/src/hash/hash-lib-blake2.c000066400000000000000000000065071431266303500175260ustar00rootroot00000000000000/* * Copyright (C) 2007-2017 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(blake2) #define LIB_DATA ((union hash_lib_blake2_u *)func->lib_data) union hash_lib_blake2_u { blake2b_state b; blake2s_state s; blake2bp_state bp; blake2sp_state sp; }; bool gtkhash_hash_lib_blake2_is_supported(const enum hash_func_e id) { switch (id) { case HASH_FUNC_BLAKE2B: case HASH_FUNC_BLAKE2S: case HASH_FUNC_BLAKE2BP: case HASH_FUNC_BLAKE2SP: return true; default: return false; } } void gtkhash_hash_lib_blake2_start(struct hash_func_s *func) { func->lib_data = g_new(union hash_lib_blake2_u, 1); int res = -1; switch (func->id) { case HASH_FUNC_BLAKE2B: res = blake2b_init(&LIB_DATA->b, func->digest_size); break; case HASH_FUNC_BLAKE2S: res = blake2s_init(&LIB_DATA->s, func->digest_size); break; case HASH_FUNC_BLAKE2BP: res = blake2bp_init(&LIB_DATA->bp, func->digest_size); break; case HASH_FUNC_BLAKE2SP: res = blake2sp_init(&LIB_DATA->sp, func->digest_size); break; default: g_assert_not_reached(); } g_assert(res == 0); (void)res; } void gtkhash_hash_lib_blake2_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { int res = -1; switch (func->id) { case HASH_FUNC_BLAKE2B: res = blake2b_update(&LIB_DATA->b, buffer, size); break; case HASH_FUNC_BLAKE2S: res = blake2s_update(&LIB_DATA->s, buffer, size); break; case HASH_FUNC_BLAKE2BP: res = blake2bp_update(&LIB_DATA->bp, buffer, size); break; case HASH_FUNC_BLAKE2SP: res = blake2sp_update(&LIB_DATA->sp, buffer, size); break; default: g_assert_not_reached(); } g_assert(res == 0); (void)res; } void gtkhash_hash_lib_blake2_stop(struct hash_func_s *func) { g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_blake2_finish(struct hash_func_s *func, size_t *size) { uint8_t *digest = g_malloc(func->digest_size); int res = -1; switch (func->id) { case HASH_FUNC_BLAKE2B: res = blake2b_final(&LIB_DATA->b, digest, func->digest_size); break; case HASH_FUNC_BLAKE2S: res = blake2s_final(&LIB_DATA->s, digest, func->digest_size); break; case HASH_FUNC_BLAKE2BP: res = blake2bp_final(&LIB_DATA->bp, digest, func->digest_size); break; case HASH_FUNC_BLAKE2SP: res = blake2sp_final(&LIB_DATA->sp, digest, func->digest_size); break; default: g_assert_not_reached(); } g_assert(res == 0); (void)res; g_free(LIB_DATA); *size = func->digest_size; return digest; } gtkhash-1.5/src/hash/hash-lib-crypto.c000066400000000000000000000114011431266303500176730ustar00rootroot00000000000000/* * Copyright (C) 2007-2022 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . * * In addition, as a special exception, the copyright holders give * permission to link the code of GtkHash with the OpenSSL library (or * with modified versions of it that use the same license as the OpenSSL * library), and distribute the linked executables. You must obey the GNU * General Public License in all respects for all of the code used other * than OpenSSL. If you modify this file, you may extend this exception to * your version of the file, but you are not obligated to do so. If you do * not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(crypto) #define LIB_DATA ((struct hash_lib_crypto_s *)func->lib_data) struct hash_lib_crypto_s { const EVP_MD *md; EVP_MD_CTX *ctx; }; static const EVP_MD *gtkhash_hash_lib_crypto_get_md(const enum hash_func_e id) { switch (id) { #ifndef OPENSSL_NO_BLAKE2 case HASH_FUNC_BLAKE2B: return EVP_blake2b512(); case HASH_FUNC_BLAKE2S: return EVP_blake2s256(); #else #warning "BLAKE2 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_MD2 case HASH_FUNC_MD2: return EVP_md2(); #else #warning "MD2 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_MD4 case HASH_FUNC_MD4: return EVP_md4(); #else #warning "MD4 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_MD5 case HASH_FUNC_MD5: return EVP_md5(); #else #warning "MD5 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_MDC2 case HASH_FUNC_MDC2: return EVP_mdc2(); #else #warning "MDC2 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_RMD160 case HASH_FUNC_RIPEMD160: return EVP_ripemd160(); #else #warning "RIPEMD160 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_SM3 case HASH_FUNC_SM3: return EVP_sm3(); #else #warning "SM3 is disabled in OpenSSL" #endif #ifndef OPENSSL_NO_WHIRLPOOL case HASH_FUNC_WHIRLPOOL: return EVP_whirlpool(); #else #warning "WHIRLPOOL is disabled in OpenSSL" #endif case HASH_FUNC_SHA1: return EVP_sha1(); case HASH_FUNC_SHA224: return EVP_sha224(); case HASH_FUNC_SHA256: return EVP_sha256(); case HASH_FUNC_SHA384: return EVP_sha384(); case HASH_FUNC_SHA512: return EVP_sha512(); case HASH_FUNC_SHA3_224: return EVP_sha3_224(); case HASH_FUNC_SHA3_256: return EVP_sha3_256(); case HASH_FUNC_SHA3_384: return EVP_sha3_384(); case HASH_FUNC_SHA3_512: return EVP_sha3_512(); default: return NULL; } g_assert_not_reached(); } bool gtkhash_hash_lib_crypto_is_supported(const enum hash_func_e id) { struct hash_lib_crypto_s data; uint8_t digest[EVP_MAX_MD_SIZE]; if (!(data.md = gtkhash_hash_lib_crypto_get_md(id))) return false; if (EVP_MD_size(data.md) < 1) return false; if (!(data.ctx = EVP_MD_CTX_new())) return false; if (EVP_Digest("", 0, digest, NULL, data.md, NULL) != 1) { EVP_MD_CTX_free(data.ctx); return false; } EVP_MD_CTX_free(data.ctx); return true; } void gtkhash_hash_lib_crypto_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_crypto_s, 1); if (!(LIB_DATA->md = gtkhash_hash_lib_crypto_get_md(func->id))) g_assert_not_reached(); if (!(LIB_DATA->ctx = EVP_MD_CTX_new())) g_assert_not_reached(); if (EVP_DigestInit_ex(LIB_DATA->ctx, LIB_DATA->md, NULL) != 1) g_assert_not_reached(); } void gtkhash_hash_lib_crypto_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { EVP_DigestUpdate(LIB_DATA->ctx, buffer, size); } void gtkhash_hash_lib_crypto_stop(struct hash_func_s *func) { EVP_MD_CTX_free(LIB_DATA->ctx); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_crypto_finish(struct hash_func_s *func, size_t *size) { *size = EVP_MD_size(LIB_DATA->md); g_assert(*size > 0); uint8_t *digest = g_malloc(*size); unsigned int len; if (EVP_DigestFinal_ex(LIB_DATA->ctx, digest, &len) != 1) g_assert_not_reached(); g_assert(*size == len); EVP_MD_CTX_free(LIB_DATA->ctx); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-gcrypt.c000066400000000000000000000077031431266303500176750ustar00rootroot00000000000000/* * Copyright (C) 2007-2022 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(gcrypt) #define LIB_DATA ((struct hash_lib_gcrypt_s *)func->lib_data) struct hash_lib_gcrypt_s { gcry_md_hd_t h; int algo; }; static bool gtkhash_hash_lib_gcrypt_set_algo(const enum hash_func_e id, int *algo) { switch (id) { #if (GCRYPT_VERSION_NUMBER >= 0x010800) case HASH_FUNC_BLAKE2B: *algo = GCRY_MD_BLAKE2B_512; break; case HASH_FUNC_BLAKE2S: *algo = GCRY_MD_BLAKE2S_256; break; #endif case HASH_FUNC_CRC32: *algo = GCRY_MD_CRC32; break; case HASH_FUNC_GOST: *algo = GCRY_MD_GOSTR3411_94; break; case HASH_FUNC_MD4: *algo = GCRY_MD_MD4; break; case HASH_FUNC_MD5: *algo = GCRY_MD_MD5; break; case HASH_FUNC_RIPEMD160: *algo = GCRY_MD_RMD160; break; case HASH_FUNC_SHA1: *algo = GCRY_MD_SHA1; break; case HASH_FUNC_SHA224: *algo = GCRY_MD_SHA224; break; case HASH_FUNC_SHA256: *algo = GCRY_MD_SHA256; break; case HASH_FUNC_SHA384: *algo = GCRY_MD_SHA384; break; case HASH_FUNC_SHA512: *algo = GCRY_MD_SHA512; break; #if (GCRYPT_VERSION_NUMBER >= 0x010700) case HASH_FUNC_SHA3_224: *algo = GCRY_MD_SHA3_224; break; case HASH_FUNC_SHA3_256: *algo = GCRY_MD_SHA3_256; break; case HASH_FUNC_SHA3_384: *algo = GCRY_MD_SHA3_384; break; case HASH_FUNC_SHA3_512: *algo = GCRY_MD_SHA3_512; break; #endif #if (GCRYPT_VERSION_NUMBER >= 0x010900) case HASH_FUNC_SM3: *algo = GCRY_MD_SM3; break; #endif case HASH_FUNC_TIGER192: *algo = GCRY_MD_TIGER; break; case HASH_FUNC_WHIRLPOOL: *algo = GCRY_MD_WHIRLPOOL; break; default: return false; } return true; } bool gtkhash_hash_lib_gcrypt_is_supported(const enum hash_func_e id) { struct hash_lib_gcrypt_s data; if (!gtkhash_hash_lib_gcrypt_set_algo(id, &data.algo)) return false; if (!gcry_check_version(HASH_LIB_GCRYPT_MIN_VER)) { g_debug("gcrypt-" HASH_LIB_GCRYPT_MIN_VER " is required"); return false; } if (G_UNLIKELY(gcry_md_open(&data.h, data.algo, 0) != GPG_ERR_NO_ERROR)) { g_debug("gcry_md_open failed (%d)", id); return false; } gcry_md_close(data.h); return true; } void gtkhash_hash_lib_gcrypt_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_gcrypt_s, 1); if (!gtkhash_hash_lib_gcrypt_set_algo(func->id, &LIB_DATA->algo)) g_assert_not_reached(); if (gcry_md_open(&LIB_DATA->h, LIB_DATA->algo, 0) != GPG_ERR_NO_ERROR) g_assert_not_reached(); } void gtkhash_hash_lib_gcrypt_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { gcry_md_write(LIB_DATA->h, buffer, size); } void gtkhash_hash_lib_gcrypt_stop(struct hash_func_s *func) { gcry_md_close(LIB_DATA->h); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_gcrypt_finish(struct hash_func_s *func, size_t *size) { unsigned char *digest_tmp = gcry_md_read(LIB_DATA->h, LIB_DATA->algo); *size = gcry_md_get_algo_dlen(LIB_DATA->algo); uint8_t *digest = g_memdup(digest_tmp, *size); gcry_md_close(LIB_DATA->h); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-glib.c000066400000000000000000000054131431266303500172760ustar00rootroot00000000000000/* * Copyright (C) 2007-2022 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(glib) #define LIB_DATA ((struct hash_lib_glib_s *)func->lib_data) struct hash_lib_glib_s { GChecksum *checksum; GChecksumType type; }; static bool gtkhash_hash_lib_glib_set_type(const enum hash_func_e id, GChecksumType *type) { switch (id) { case HASH_FUNC_MD5: *type = G_CHECKSUM_MD5; break; case HASH_FUNC_SHA1: *type = G_CHECKSUM_SHA1; break; case HASH_FUNC_SHA256: *type = G_CHECKSUM_SHA256; break; #if GLIB_CHECK_VERSION(2,51,3) case HASH_FUNC_SHA384: *type = G_CHECKSUM_SHA384; break; #endif case HASH_FUNC_SHA512: *type = G_CHECKSUM_SHA512; break; default: return false; } return true; } bool gtkhash_hash_lib_glib_is_supported(const enum hash_func_e id) { GChecksumType type; if (!gtkhash_hash_lib_glib_set_type(id, &type)) return false; if (G_UNLIKELY(g_checksum_type_get_length(type) < 0)) { g_debug("g_checksum_type_get_length() failed (%d)", id); return false; } return true; } void gtkhash_hash_lib_glib_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_glib_s, 1); if (!gtkhash_hash_lib_glib_set_type(func->id, &LIB_DATA->type)) g_assert_not_reached(); LIB_DATA->checksum = g_checksum_new(LIB_DATA->type); g_assert(LIB_DATA->checksum); } void gtkhash_hash_lib_glib_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { g_checksum_update(LIB_DATA->checksum, buffer, size); } void gtkhash_hash_lib_glib_stop(struct hash_func_s *func) { g_checksum_free(LIB_DATA->checksum); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_glib_finish(struct hash_func_s *func, size_t *size) { gsize len = g_checksum_type_get_length(LIB_DATA->type); g_assert(len > 0); uint8_t *digest = g_malloc(len); g_checksum_get_digest(LIB_DATA->checksum, digest, &len); g_checksum_free(LIB_DATA->checksum); g_free(LIB_DATA); *size = len; return digest; } gtkhash-1.5/src/hash/hash-lib-linux.c000066400000000000000000000124031431266303500175150ustar00rootroot00000000000000/* * Copyright (C) 2007-2021 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(linux) #define LIB_DATA ((struct hash_lib_linux_s *)func->lib_data) struct hash_lib_linux_s { const char *name; int sockfd, connfd; }; static const char *gtkhash_hash_lib_linux_get_name(const enum hash_func_e id) { switch (id) { case HASH_FUNC_BLAKE2B: return "blake2b-512"; case HASH_FUNC_BLAKE2S: return "blake2s-256"; case HASH_FUNC_CRC32C: return "crc32c"; case HASH_FUNC_MD4: return "md4"; case HASH_FUNC_MD5: return "md5"; case HASH_FUNC_RIPEMD128: return "rmd128"; case HASH_FUNC_RIPEMD160: return "rmd160"; case HASH_FUNC_RIPEMD256: return "rmd256"; case HASH_FUNC_RIPEMD320: return "rmd320"; case HASH_FUNC_SHA1: return "sha1"; case HASH_FUNC_SHA224: return "sha224"; case HASH_FUNC_SHA256: return "sha256"; case HASH_FUNC_SHA384: return "sha384"; case HASH_FUNC_SHA512: return "sha512"; case HASH_FUNC_SHA3_224: return "sha3-224"; case HASH_FUNC_SHA3_256: return "sha3-256"; case HASH_FUNC_SHA3_384: return "sha3-384"; case HASH_FUNC_SHA3_512: return "sha3-512"; case HASH_FUNC_TIGER192: return "tgr192"; case HASH_FUNC_WHIRLPOOL: return "wp512"; case HASH_FUNC_XXH64: return "xxhash64"; default: return NULL; } } bool gtkhash_hash_lib_linux_is_supported(const enum hash_func_e id) { struct hash_lib_linux_s data; if (!(data.name = gtkhash_hash_lib_linux_get_name(id))) return false; if ((data.sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0)) == -1) { g_debug("Kernel AF_ALG: %s", g_strerror(errno)); return false; } struct sockaddr_alg addr = { .salg_family = AF_ALG, .salg_type = "hash", }; strcpy((char *)addr.salg_name, data.name); if (bind(data.sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { g_debug("Kernel AF_ALG '%s': %s", data.name, g_strerror(errno)); close(data.sockfd); return false; } if ((data.connfd = accept(data.sockfd, NULL, NULL)) == -1) { g_debug("Kernel AF_ALG '%s': %s", data.name, g_strerror(errno)); close(data.sockfd); return false; } // Update ssize_t bytes = 0; if ((bytes = send(data.connfd, "1234567", 8, MSG_MORE)) != 8) { if (bytes < 0) g_debug("Kernel AF_ALG '%s': %s", data.name, g_strerror(errno)); close(data.connfd); close(data.sockfd); return false; } // Finish uint8_t digest[4]; if ((bytes = read(data.connfd, &digest, 4)) != 4) { if (bytes < 0) g_debug("Kernel AF_ALG '%s': %s", data.name, g_strerror(errno)); close(data.connfd); close(data.sockfd); return false; } close(data.connfd); close(data.sockfd); return true; } void gtkhash_hash_lib_linux_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_linux_s, 1); struct sockaddr_alg addr = { .salg_family = AF_ALG, .salg_type = "hash", }; LIB_DATA->name = gtkhash_hash_lib_linux_get_name(func->id); g_assert(LIB_DATA->name); strcpy((char *)addr.salg_name, LIB_DATA->name); LIB_DATA->sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0); g_assert(LIB_DATA->sockfd != -1); int res = bind(LIB_DATA->sockfd, (struct sockaddr *)&addr, sizeof(addr)); g_assert(res != -1); (void)res; LIB_DATA->connfd = accept(LIB_DATA->sockfd, NULL, NULL); g_assert(LIB_DATA->connfd != -1); } void gtkhash_hash_lib_linux_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { ssize_t send_size = send(LIB_DATA->connfd, buffer, size, MSG_MORE); g_assert(send_size == (ssize_t)size); (void)send_size; } void gtkhash_hash_lib_linux_stop(struct hash_func_s *func) { close(LIB_DATA->connfd); close(LIB_DATA->sockfd); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_linux_finish(struct hash_func_s *func, size_t *size) { uint8_t *digest = NULL; // Kernel CRC32C, XXH64 are little-endian if (func->id == HASH_FUNC_CRC32C || func->id == HASH_FUNC_XXH64) { union { uint64_t u64; uint32_t u32; } digest_u; *size = read(LIB_DATA->connfd, &digest_u, func->digest_size); if (func->digest_size == 8) digest_u.u64 = GUINT64_SWAP_LE_BE(digest_u.u64); else if (func->digest_size == 4) digest_u.u32 = GUINT32_SWAP_LE_BE(digest_u.u32); digest = g_memdup(&digest_u, func->digest_size); } else { digest = g_malloc(func->digest_size); *size = read(LIB_DATA->connfd, digest, func->digest_size); } close(LIB_DATA->connfd); close(LIB_DATA->sockfd); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-mbedtls.c000066400000000000000000000065001431266303500200110ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(mbedtls) #define LIB_DATA ((struct hash_lib_mbedtls_s *)func->lib_data) struct hash_lib_mbedtls_s { mbedtls_md_context_t ctx; }; static bool gtkhash_hash_lib_mbedtls_set_type(const enum hash_func_e id, mbedtls_md_type_t *type) { switch (id) { case HASH_FUNC_MD2: *type = MBEDTLS_MD_MD2; break; case HASH_FUNC_MD4: *type = MBEDTLS_MD_MD4; break; case HASH_FUNC_MD5: *type = MBEDTLS_MD_MD5; break; case HASH_FUNC_RIPEMD160: *type = MBEDTLS_MD_RIPEMD160; break; case HASH_FUNC_SHA1: *type = MBEDTLS_MD_SHA1; break; case HASH_FUNC_SHA224: *type = MBEDTLS_MD_SHA224; break; case HASH_FUNC_SHA256: *type = MBEDTLS_MD_SHA256; break; case HASH_FUNC_SHA384: *type = MBEDTLS_MD_SHA384; break; case HASH_FUNC_SHA512: *type = MBEDTLS_MD_SHA512; break; default: return false; } return true; } bool gtkhash_hash_lib_mbedtls_is_supported(const enum hash_func_e id) { mbedtls_md_type_t type; if (!gtkhash_hash_lib_mbedtls_set_type(id, &type)) return false; struct hash_lib_mbedtls_s data; mbedtls_md_init(&data.ctx); const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type); if (mbedtls_md_setup(&data.ctx, info, 0) != 0) { mbedtls_md_free(&data.ctx); return false; } mbedtls_md_free(&data.ctx); return true; } void gtkhash_hash_lib_mbedtls_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_mbedtls_s, 1); mbedtls_md_type_t type; if (!gtkhash_hash_lib_mbedtls_set_type(func->id, &type)) g_assert_not_reached(); mbedtls_md_init(&LIB_DATA->ctx); const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type); if (mbedtls_md_setup(&LIB_DATA->ctx, info, 0) != 0) g_assert_not_reached(); if (mbedtls_md_starts(&LIB_DATA->ctx) != 0) g_assert_not_reached(); } void gtkhash_hash_lib_mbedtls_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { mbedtls_md_update(&LIB_DATA->ctx, buffer, size); } void gtkhash_hash_lib_mbedtls_stop(struct hash_func_s *func) { mbedtls_md_free(&LIB_DATA->ctx); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_mbedtls_finish(struct hash_func_s *func, size_t *size) { *size = mbedtls_md_get_size(LIB_DATA->ctx.md_info); uint8_t *digest = g_malloc(*size); if (mbedtls_md_finish(&LIB_DATA->ctx, digest) != 0) g_assert_not_reached(); mbedtls_md_free(&LIB_DATA->ctx); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-md6.c000066400000000000000000000042131431266303500170440ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #define MD6_LITTLE_ENDIAN (G_BYTE_ORDER == G_LITTLE_ENDIAN) #include "md6/md6.h" #include "md6/md6_compress.c" #include "md6/md6_mode.c" #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(md6) #define LIB_DATA ((struct hash_lib_md6_s *)func->lib_data) struct hash_lib_md6_s { md6_state state; }; bool gtkhash_hash_lib_md6_is_supported(const enum hash_func_e id) { switch (id) { case HASH_FUNC_MD6_224: case HASH_FUNC_MD6_256: case HASH_FUNC_MD6_384: case HASH_FUNC_MD6_512: return true; default: return false; } } void gtkhash_hash_lib_md6_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_md6_s, 1); md6_init(&LIB_DATA->state, func->digest_size * 8); LIB_DATA->state.hashbitlen = func->digest_size * 8; } void gtkhash_hash_lib_md6_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { md6_update(&LIB_DATA->state, (unsigned char *)buffer, size * 8); } void gtkhash_hash_lib_md6_stop(struct hash_func_s *func) { g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_md6_finish(struct hash_func_s *func, size_t *size) { md6_final(&LIB_DATA->state, NULL); *size = LIB_DATA->state.hashbitlen / 8; uint8_t *digest = g_memdup(&LIB_DATA->state.hashval, *size); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-nettle.c000066400000000000000000000062621431266303500176570ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(nettle) #define LIB_DATA ((struct hash_lib_nettle_s *)func->lib_data) struct hash_lib_nettle_s { const struct nettle_hash *meta; void *ctx; }; static bool gtkhash_hash_lib_nettle_set_meta(const enum hash_func_e id, const struct nettle_hash **meta) { switch (id) { case HASH_FUNC_GOST: *meta = &nettle_gosthash94; break; case HASH_FUNC_MD2: *meta = &nettle_md2; break; case HASH_FUNC_MD4: *meta = &nettle_md4; break; case HASH_FUNC_MD5: *meta = &nettle_md5; break; case HASH_FUNC_RIPEMD160: *meta = &nettle_ripemd160; break; case HASH_FUNC_SHA1: *meta = &nettle_sha1; break; case HASH_FUNC_SHA224: *meta = &nettle_sha224; break; case HASH_FUNC_SHA256: *meta = &nettle_sha256; break; case HASH_FUNC_SHA384: *meta = &nettle_sha384; break; case HASH_FUNC_SHA512: *meta = &nettle_sha512; break; #ifdef NETTLE_SHA3_FIPS202 case HASH_FUNC_SHA3_224: *meta = &nettle_sha3_224; break; case HASH_FUNC_SHA3_256: *meta = &nettle_sha3_256; break; case HASH_FUNC_SHA3_384: *meta = &nettle_sha3_384; break; case HASH_FUNC_SHA3_512: *meta = &nettle_sha3_512; break; #endif default: return false; } return true; } bool gtkhash_hash_lib_nettle_is_supported(const enum hash_func_e id) { const struct nettle_hash *meta; return gtkhash_hash_lib_nettle_set_meta(id, &meta); } void gtkhash_hash_lib_nettle_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_nettle_s, 1); gtkhash_hash_lib_nettle_set_meta(func->id, &LIB_DATA->meta); LIB_DATA->ctx = g_malloc(LIB_DATA->meta->context_size); LIB_DATA->meta->init(LIB_DATA->ctx); } void gtkhash_hash_lib_nettle_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { LIB_DATA->meta->update(LIB_DATA->ctx, size, buffer); } void gtkhash_hash_lib_nettle_stop(struct hash_func_s *func) { g_free(LIB_DATA->ctx); g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_nettle_finish(struct hash_func_s *func, size_t *size) { *size = LIB_DATA->meta->digest_size; uint8_t *digest = g_malloc(*size); LIB_DATA->meta->digest(LIB_DATA->ctx, *size, digest); g_free(LIB_DATA->ctx); g_free(LIB_DATA); return digest; } gtkhash-1.5/src/hash/hash-lib-zlib.c000066400000000000000000000044161431266303500173230ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" HASH_LIB_DECL(zlib) #define LIB_DATA ((struct hash_lib_zlib_s *)func->lib_data) struct hash_lib_zlib_s { uLong csum; }; static uLong gtkhash_hash_lib_zlib_checksum(const enum hash_func_e id, const uLong csum, const uint8_t *buffer, const size_t size) { switch (id) { case HASH_FUNC_CRC32: return crc32(csum, buffer, size); case HASH_FUNC_ADLER32: return adler32(csum, buffer, size); default: g_assert_not_reached(); } return 0; } bool gtkhash_hash_lib_zlib_is_supported(const enum hash_func_e id) { switch (id) { case HASH_FUNC_CRC32: case HASH_FUNC_ADLER32: return true; default: return false; } } void gtkhash_hash_lib_zlib_start(struct hash_func_s *func) { func->lib_data = g_new(struct hash_lib_zlib_s, 1); LIB_DATA->csum = gtkhash_hash_lib_zlib_checksum(func->id, 0L, Z_NULL, 0); } void gtkhash_hash_lib_zlib_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { LIB_DATA->csum = gtkhash_hash_lib_zlib_checksum(func->id, LIB_DATA->csum, buffer, size); } void gtkhash_hash_lib_zlib_stop(struct hash_func_s *func) { g_free(LIB_DATA); } uint8_t *gtkhash_hash_lib_zlib_finish(struct hash_func_s *func, size_t *size) { uint32_t csum = GUINT32_TO_BE(LIB_DATA->csum); g_free(LIB_DATA); *size = sizeof(csum); uint8_t *digest = g_memdup(&csum, *size); return digest; } gtkhash-1.5/src/hash/hash-lib.c000066400000000000000000000215241431266303500163640ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "hash-lib.h" #include "hash-func.h" #include "hmac.h" #if ENABLE_BLAKE2 HASH_LIB_DECL(blake2) #endif #if ENABLE_GCRYPT HASH_LIB_DECL(gcrypt) #endif #if ENABLE_GLIB_CHECKSUMS HASH_LIB_DECL(glib) #endif #if ENABLE_LIBCRYPTO HASH_LIB_DECL(crypto) #endif #if ENABLE_LINUX_CRYPTO HASH_LIB_DECL(linux) #endif #if ENABLE_MBEDTLS HASH_LIB_DECL(mbedtls) #endif #if ENABLE_INTERNAL_MD6 HASH_LIB_DECL(md6) #endif #if ENABLE_NETTLE HASH_LIB_DECL(nettle) #endif #if ENABLE_ZLIB HASH_LIB_DECL(zlib) #endif enum hash_lib_e { HASH_LIB_INVALID = -1, #if ENABLE_BLAKE2 HASH_LIB_BLAKE2, #endif #if ENABLE_GCRYPT HASH_LIB_GCRYPT, #endif #if ENABLE_GLIB_CHECKSUMS HASH_LIB_GLIB, #endif #if ENABLE_LIBCRYPTO HASH_LIB_CRYPTO, #endif #if ENABLE_LINUX_CRYPTO HASH_LIB_LINUX, #endif #if ENABLE_MBEDTLS HASH_LIB_MBEDTLS, #endif #if ENABLE_INTERNAL_MD6 HASH_LIB_MD6, #endif #if ENABLE_NETTLE HASH_LIB_NETTLE, #endif #if ENABLE_ZLIB HASH_LIB_ZLIB, #endif }; // Currently selected lib for each hash func static enum hash_lib_e hash_libs[HASH_FUNCS_N]; static void gtkhash_hash_lib_init_once(void) { // Init all lib selections to be invalid for (enum hash_func_e i = 0; i < HASH_FUNCS_N; i++) hash_libs[i] = HASH_LIB_INVALID; const char * const test_lib = g_getenv("GTKHASH_TEST_LIB"); // Note: Preferred lib selections are defined by the order used here for (enum hash_func_e i = 0; i < HASH_FUNCS_N; i++) { #if ENABLE_BLAKE2 if (!test_lib || (test_lib && strcmp(test_lib, "blake2") == 0)) { if (gtkhash_hash_lib_blake2_is_supported(i)) { hash_libs[i] = HASH_LIB_BLAKE2; continue; } } #endif #if ENABLE_GCRYPT if (!test_lib || (test_lib && strcmp(test_lib, "gcrypt") == 0)) { if (gtkhash_hash_lib_gcrypt_is_supported(i)) { hash_libs[i] = HASH_LIB_GCRYPT; continue; } } #endif #if ENABLE_LIBCRYPTO if (!test_lib || (test_lib && strcmp(test_lib, "libcrypto") == 0)) { if (gtkhash_hash_lib_crypto_is_supported(i)) { hash_libs[i] = HASH_LIB_CRYPTO; continue; } } #endif #if ENABLE_MBEDTLS if (!test_lib || (test_lib && strcmp(test_lib, "mbedtls") == 0)) { if (gtkhash_hash_lib_mbedtls_is_supported(i)) { hash_libs[i] = HASH_LIB_MBEDTLS; continue; } } #endif #if ENABLE_NETTLE if (!test_lib || (test_lib && strcmp(test_lib, "nettle") == 0)) { if (gtkhash_hash_lib_nettle_is_supported(i)) { hash_libs[i] = HASH_LIB_NETTLE; continue; } } #endif #if ENABLE_LINUX_CRYPTO if (!test_lib || (test_lib && strcmp(test_lib, "linux_crypto") == 0)) { if (gtkhash_hash_lib_linux_is_supported(i)) { hash_libs[i] = HASH_LIB_LINUX; continue; } } #endif #if ENABLE_ZLIB if (!test_lib || (test_lib && strcmp(test_lib, "zlib") == 0)) { if (gtkhash_hash_lib_zlib_is_supported(i)) { hash_libs[i] = HASH_LIB_ZLIB; continue; } } #endif #if ENABLE_GLIB_CHECKSUMS if (!test_lib || (test_lib && strcmp(test_lib, "glib_checksums") == 0)) { if (gtkhash_hash_lib_glib_is_supported(i)) { hash_libs[i] = HASH_LIB_GLIB; continue; } } #endif #if ENABLE_INTERNAL_MD6 if (!test_lib || (test_lib && strcmp(test_lib, "internal_md6") == 0)) { if (gtkhash_hash_lib_md6_is_supported(i)) { hash_libs[i] = HASH_LIB_MD6; continue; } } #endif } } bool gtkhash_hash_lib_is_supported(const enum hash_func_e id) { static GOnce once = G_ONCE_INIT; g_once(&once, (GThreadFunc)gtkhash_hash_lib_init_once, NULL); return (hash_libs[id] != HASH_LIB_INVALID); } void gtkhash_hash_lib_start(struct hash_func_s *func, const uint8_t *hmac_key, const size_t key_size) { g_assert(func); g_assert(func->supported); g_assert(func->enabled); g_assert(!func->lib_data); g_assert(hash_libs[func->id] != HASH_LIB_INVALID); static void (* const start_funcs[])(struct hash_func_s *) = { #if ENABLE_BLAKE2 [HASH_LIB_BLAKE2] = gtkhash_hash_lib_blake2_start, #endif #if ENABLE_GCRYPT [HASH_LIB_GCRYPT] = gtkhash_hash_lib_gcrypt_start, #endif #if ENABLE_GLIB_CHECKSUMS [HASH_LIB_GLIB] = gtkhash_hash_lib_glib_start, #endif #if ENABLE_LIBCRYPTO [HASH_LIB_CRYPTO] = gtkhash_hash_lib_crypto_start, #endif #if ENABLE_LINUX_CRYPTO [HASH_LIB_LINUX] = gtkhash_hash_lib_linux_start, #endif #if ENABLE_MBEDTLS [HASH_LIB_MBEDTLS] = gtkhash_hash_lib_mbedtls_start, #endif #if ENABLE_INTERNAL_MD6 [HASH_LIB_MD6] = gtkhash_hash_lib_md6_start, #endif #if ENABLE_NETTLE [HASH_LIB_NETTLE] = gtkhash_hash_lib_nettle_start, #endif #if ENABLE_ZLIB [HASH_LIB_ZLIB] = gtkhash_hash_lib_zlib_start, #endif }; start_funcs[hash_libs[func->id]](func); if (hmac_key && func->hmac_supported) gtkhash_hmac_start(func, hmac_key, key_size); } void gtkhash_hash_lib_update(struct hash_func_s *func, const uint8_t *buffer, const size_t size) { g_assert(func); g_assert(func->supported); g_assert(func->enabled); g_assert(func->lib_data); g_assert(buffer); g_assert(hash_libs[func->id] != HASH_LIB_INVALID); static void (* const update_funcs[])(struct hash_func_s *, const uint8_t *, const size_t) = { #if ENABLE_BLAKE2 [HASH_LIB_BLAKE2] = gtkhash_hash_lib_blake2_update, #endif #if ENABLE_GCRYPT [HASH_LIB_GCRYPT] = gtkhash_hash_lib_gcrypt_update, #endif #if ENABLE_GLIB_CHECKSUMS [HASH_LIB_GLIB] = gtkhash_hash_lib_glib_update, #endif #if ENABLE_LIBCRYPTO [HASH_LIB_CRYPTO] = gtkhash_hash_lib_crypto_update, #endif #if ENABLE_LINUX_CRYPTO [HASH_LIB_LINUX] = gtkhash_hash_lib_linux_update, #endif #if ENABLE_MBEDTLS [HASH_LIB_MBEDTLS] = gtkhash_hash_lib_mbedtls_update, #endif #if ENABLE_INTERNAL_MD6 [HASH_LIB_MD6] = gtkhash_hash_lib_md6_update, #endif #if ENABLE_NETTLE [HASH_LIB_NETTLE] = gtkhash_hash_lib_nettle_update, #endif #if ENABLE_ZLIB [HASH_LIB_ZLIB] = gtkhash_hash_lib_zlib_update, #endif }; update_funcs[hash_libs[func->id]](func, buffer, size); } void gtkhash_hash_lib_stop(struct hash_func_s *func) { g_assert(func); g_assert(func->supported); g_assert(func->enabled); g_assert(func->lib_data); g_assert(hash_libs[func->id] != HASH_LIB_INVALID); static void (* const stop_funcs[])(struct hash_func_s *) = { #if ENABLE_BLAKE2 [HASH_LIB_BLAKE2] = gtkhash_hash_lib_blake2_stop, #endif #if ENABLE_GCRYPT [HASH_LIB_GCRYPT] = gtkhash_hash_lib_gcrypt_stop, #endif #if ENABLE_GLIB_CHECKSUMS [HASH_LIB_GLIB] = gtkhash_hash_lib_glib_stop, #endif #if ENABLE_LIBCRYPTO [HASH_LIB_CRYPTO] = gtkhash_hash_lib_crypto_stop, #endif #if ENABLE_LINUX_CRYPTO [HASH_LIB_LINUX] = gtkhash_hash_lib_linux_stop, #endif #if ENABLE_MBEDTLS [HASH_LIB_MBEDTLS] = gtkhash_hash_lib_mbedtls_stop, #endif #if ENABLE_INTERNAL_MD6 [HASH_LIB_MD6] = gtkhash_hash_lib_md6_stop, #endif #if ENABLE_NETTLE [HASH_LIB_NETTLE] = gtkhash_hash_lib_nettle_stop, #endif #if ENABLE_ZLIB [HASH_LIB_ZLIB] = gtkhash_hash_lib_zlib_stop, #endif }; stop_funcs[hash_libs[func->id]](func); func->lib_data = NULL; if (func->hmac_data) gtkhash_hmac_stop(func); } void gtkhash_hash_lib_finish(struct hash_func_s *func) { g_assert(func); g_assert(func->supported); g_assert(func->enabled); g_assert(func->lib_data); g_assert(hash_libs[func->id] != HASH_LIB_INVALID); static uint8_t *(* const finish_libs[])(struct hash_func_s *, size_t *) = { #if ENABLE_BLAKE2 [HASH_LIB_BLAKE2] = gtkhash_hash_lib_blake2_finish, #endif #if ENABLE_GCRYPT [HASH_LIB_GCRYPT] = gtkhash_hash_lib_gcrypt_finish, #endif #if ENABLE_GLIB_CHECKSUMS [HASH_LIB_GLIB] = gtkhash_hash_lib_glib_finish, #endif #if ENABLE_LIBCRYPTO [HASH_LIB_CRYPTO] = gtkhash_hash_lib_crypto_finish, #endif #if ENABLE_LINUX_CRYPTO [HASH_LIB_LINUX] = gtkhash_hash_lib_linux_finish, #endif #if ENABLE_MBEDTLS [HASH_LIB_MBEDTLS] = gtkhash_hash_lib_mbedtls_finish, #endif #if ENABLE_INTERNAL_MD6 [HASH_LIB_MD6] = gtkhash_hash_lib_md6_finish, #endif #if ENABLE_NETTLE [HASH_LIB_NETTLE] = gtkhash_hash_lib_nettle_finish, #endif #if ENABLE_ZLIB [HASH_LIB_ZLIB] = gtkhash_hash_lib_zlib_finish, #endif }; size_t size = 0; uint8_t *digest = finish_libs[hash_libs[func->id]](func, &size); gtkhash_hash_func_set_digest(func, digest, size); if (func->hmac_data) gtkhash_hmac_finish(func); func->lib_data = NULL; } gtkhash-1.5/src/hash/hash-lib.h000066400000000000000000000035241431266303500163710ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_HASH_LIB_H #define GTKHASH_HASH_HASH_LIB_H #ifndef IN_HASH_LIB #error "don't use directly" #endif #include #include #include #if GLIB_CHECK_VERSION(2,68,0) #undef g_memdup #define g_memdup g_memdup2 #endif #include "hash-func.h" bool gtkhash_hash_lib_is_supported(enum hash_func_e id); void gtkhash_hash_lib_start(struct hash_func_s *func, const uint8_t *hmac_key, size_t key_size); void gtkhash_hash_lib_update(struct hash_func_s *func, const uint8_t *buffer, size_t size); void gtkhash_hash_lib_stop(struct hash_func_s *func); void gtkhash_hash_lib_finish(struct hash_func_s *func); #define HASH_LIB_DECL(LIB) \ bool gtkhash_hash_lib_ ## LIB ## _is_supported(enum hash_func_e id); \ void gtkhash_hash_lib_ ## LIB ## _start(struct hash_func_s *func); \ void gtkhash_hash_lib_ ## LIB ## _update(struct hash_func_s *func, \ const uint8_t *buffer, size_t size); \ void gtkhash_hash_lib_ ## LIB ## _stop(struct hash_func_s *func); \ uint8_t *gtkhash_hash_lib_ ## LIB ## _finish(struct hash_func_s *func, \ size_t *size); #endif gtkhash-1.5/src/hash/hash-string.c000066400000000000000000000033251431266303500171230ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "hash-string.h" #include "hash-func.h" #include "hash-lib.h" void gtkhash_hash_string(struct hash_func_s *funcs, const char * const str, const enum digest_format_e format, const uint8_t * const hmac_key, const size_t key_size) { g_assert(str); g_assert(DIGEST_FORMAT_IS_VALID(format)); const size_t len = strlen(str); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!funcs[i].enabled) continue; gtkhash_hash_lib_start(&funcs[i], hmac_key, key_size); // Assuming this won't take too long gtkhash_hash_lib_update(&funcs[i], (const uint8_t *)str, len); gtkhash_hash_lib_finish(&funcs[i]); char *digest = gtkhash_hash_func_get_digest(&funcs[i], format); gtkhash_hash_string_digest_cb(funcs[i].id, digest); g_free(digest); gtkhash_hash_func_clear_digest(&funcs[i]); } gtkhash_hash_string_finish_cb(); } gtkhash-1.5/src/hash/hash-string.h000066400000000000000000000021671431266303500171330ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_HASH_STRING_H #define GTKHASH_HASH_HASH_STRING_H #include "hash-func.h" void gtkhash_hash_string(struct hash_func_s *funcs, const char *str, enum digest_format_e format, const uint8_t *hmac_key, size_t key_size); void gtkhash_hash_string_digest_cb(enum hash_func_e id, const char *digest); void gtkhash_hash_string_finish_cb(void); #endif gtkhash-1.5/src/hash/hmac.c000066400000000000000000000061161431266303500156050ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "hmac.h" #include "hash-func.h" #include "hash-lib.h" #include "digest.h" void gtkhash_hmac_start(struct hash_func_s *func, const uint8_t *key, const size_t key_size) { g_assert(func); g_assert(func->hmac_supported); g_assert(func->block_size > 0); g_assert(key); func->hmac_data = g_new(struct hash_func_s, 1); uint8_t padded_key[func->block_size]; memset(padded_key, 0, func->block_size); if (key_size > func->block_size) { gtkhash_hash_func_init(func->hmac_data, func->id); func->hmac_data->enabled = true; gtkhash_hash_lib_start(func->hmac_data, NULL, 0); gtkhash_hash_lib_update(func->hmac_data, key, key_size); gtkhash_hash_lib_finish(func->hmac_data); size_t newsize = func->hmac_data->digest_size; g_assert((newsize > 0) && (newsize <= func->block_size)); memcpy(padded_key, func->hmac_data->digest->bin, newsize); gtkhash_hash_func_deinit(func->hmac_data); } else memcpy(padded_key, key, key_size); uint8_t pad[func->block_size]; for (int i = 0; i < func->block_size; i++) pad[i] = 0x36 ^ padded_key[i]; gtkhash_hash_lib_update(func, pad, func->block_size); gtkhash_hash_func_init(func->hmac_data, func->id); func->hmac_data->enabled = true; gtkhash_hash_lib_start(func->hmac_data, NULL, 0); for (int i = 0; i < func->block_size; i++) pad[i] = 0x5c ^ padded_key[i]; gtkhash_hash_lib_update(func->hmac_data, pad, func->block_size); } static void gtkhash_hmac_deinit(struct hash_func_s *func) { gtkhash_hash_func_deinit(func->hmac_data); g_free(func->hmac_data); func->hmac_data = NULL; } void gtkhash_hmac_stop(struct hash_func_s *func) { g_assert(func); g_assert(func->hmac_supported); g_assert(func->block_size > 0); g_assert(func->hmac_data); gtkhash_hmac_deinit(func); } void gtkhash_hmac_finish(struct hash_func_s *func) { g_assert(func); g_assert(func->hmac_supported); g_assert(func->block_size > 0); g_assert(func->hmac_data); gtkhash_hash_lib_update(func->hmac_data, func->digest->bin, func->digest_size); gtkhash_hash_lib_finish(func->hmac_data); uint8_t *digest = g_memdup(func->hmac_data->digest->bin, func->hmac_data->digest_size); gtkhash_hash_func_set_digest(func, digest, func->hmac_data->digest_size); gtkhash_hmac_deinit(func); } gtkhash-1.5/src/hash/hmac.h000066400000000000000000000022041431266303500156040ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_HASH_HMAC_H #define GTKHASH_HASH_HMAC_H #ifndef IN_HASH_LIB #error "don't use directly" #endif #include #include #include "hash-func.h" void gtkhash_hmac_start(struct hash_func_s *func, const uint8_t *key, size_t key_size); void gtkhash_hmac_stop(struct hash_func_s *func); void gtkhash_hmac_finish(struct hash_func_s *func); #endif gtkhash-1.5/src/hash/md6/000077500000000000000000000000001431266303500152135ustar00rootroot00000000000000gtkhash-1.5/src/hash/md6/md6.h000066400000000000000000000426271431266303500160650ustar00rootroot00000000000000/* File: md6.h ** Author: Ronald L. Rivest ** Address: Room 32G-692 Stata Center ** 32 Vassar Street ** Cambridge, MA 02139 ** Email: rivest@mit.edu ** Date: 1/15/2009 (see changelog below) ** ** (The following license is known as "The MIT License") ** ** Copyright (c) 2008 Ronald L. Rivest ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and associated documentation files (the "Software"), to deal ** in the Software without restriction, including without limitation the rights ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ** THE SOFTWARE. ** ** (end of license) ** ** This file is part of the definition of the MD6 hash function. ** The files defining the MD6 hash function are: ** md6.h ** md6_compress.c ** md6_mode. ** (Note that md6.h includes inttypes.h, which includes stdint.h; ** versions of these header files compatible with MS Visual Studio ** are available, as noted below.) ** ** The files defining the interface between MD6 and the NIST SHA-3 ** API are: ** md6_nist.h ** md6_nist.c ** The NIST SHA-3 API is defined in: ** http://www.csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf ** ** See http://groups.csail.mit.edu/cis/md6 for more information. ** ** These files define the ``standard'' version of MD6. However, ** they are written in such a way that one may relatively easily ** define and experiment with ``variant'' versions. ** ** Changelog: ** 1/15/2009: length of md6_state.hashval doubled (to 128 bytes) ** to avoid buffer overflow issue found by Fortify. ** (Change does not affect hash values computed, though.) */ /* Prevent multiple includes ** Matching endif is at end of md6.h */ #ifndef MD6_H_INCLUDED #define MD6_H_INCLUDED /* inttypes.h (which includes stdint.h) ** inttypes.h and stdint.h are part of the normal environment ** for gcc, but not for MS Visual Studio. Fortunately, ** compatible implementations are available from Google at: ** http://msinttypes.googlecode.com/svn/trunk/stdint.h ** http://msinttypes.googlecode.com/svn/trunk/inttypes.h ** If these two files are in the same directory as md6.h, then ** MD6 will compile OK with MS Visual Studio. */ #if defined _MSC_VER #include "inttypes.h" #else #include #endif /* MD6 wordsize. ** ** Define md6 wordsize md6_w, in bits. ** Note that this is the "word size" relevant to the ** definition of md6 (it defines how many bits in an ** "md6_word"); it does *not* refer to the word size ** on the platform for which this is being compiled. */ #define md6_w 64 /* Define "md6_word" appropriately for given value of md6_w. ** Also define PR_MD6_WORD to be the appropriate hex format string, ** using the format strings from inttypes.h . ** The term `word' in comments means an `md6_word'. */ #if (md6_w==64) /* standard md6 */ typedef uint64_t md6_word; #define PR_MD6_WORD "%.16" PRIx64 #elif (md6_w==32) /* nonstandard variant */ typedef uint32_t md6_word; #define PR_MD6_WORD "%.8" PRIx32 #elif (md6_w==16) /* nonstandard variant */ typedef uint16_t md6_word; #define PR_MD6_WORD "%.4" PRIx16 #elif (md6_w==8) /* nonstandard variant */ typedef uint8_t md6_word; #define PR_MD6_WORD "%.2" PRIx8 #endif /* MD6 compression function. ** ** MD6 compression function is defined in file md6_compress.c */ /* MD6 compression function constants */ #define md6_n 89 /* size of compression input block, in words */ #define md6_c 16 /* size of compression output, in words */ /* a c-word block is also called a "chunk" */ #define md6_max_r 255 /* max allowable value for number r of rounds */ /* Compression function routines ** These are ``internal'' routines that need not be called for ** ordinary md6 usage. */ #if 0 extern int md6_default_r( int d, /* returns default r for given d */ int keylen /* and keylen */ ); void md6_main_compression_loop( md6_word *A, /* working array */ int r /* number of rounds */ ); int md6_compress( md6_word *C, /* output */ md6_word *N, /* input */ int r, /* number rounds */ md6_word *A /* (optional) working array, may be NULL */ ); typedef uint64_t md6_control_word; /* (r,L,z,p,d) */ md6_control_word md6_make_control_word( int r, /* number rounds */ int L, /* parallel passes */ int z, /* final node flag */ int p, /* padding bits */ int keylen, /* bytes in key */ int d /* digest size */ ); typedef uint64_t md6_nodeID; /* (ell,i) */ md6_nodeID md6_make_nodeID( int ell, /* level number */ int i /* index (0,1,2,...) within level */ ); void md6_pack( md6_word* N, /* output */ const md6_word* Q, /* fractional part sqrt(6) */ md6_word* K, /* key */ int ell, int i, /* for U */ int r, int L, int z, int p, int keylen, int d, /* for V */ md6_word* B /* data input */ ); int md6_standard_compress( md6_word *C, /* output */ const md6_word *Q, /* fractional part sqrt(6) */ md6_word *K, /* key */ int ell, int i, /* for U */ int r, int L, int z, int p, int keylen, int d, /* for V */ md6_word* B /* data input */ ); #else typedef uint64_t md6_control_word; typedef uint64_t md6_nodeID; #endif /* MD6 mode of operation. ** ** MD6 mode of operation is defined in file md6_mode.c */ /* MD6 constants related to standard mode of operation */ /* These five values give lengths of the components of compression */ /* input block; they should sum to md6_n. */ #define md6_q 15 /* # Q words in compression block (>=0) */ #define md6_k 8 /* # key words per compression block (>=0) */ #define md6_u (64/md6_w) /* # words for unique node ID (0 or 64/w) */ #define md6_v (64/md6_w) /* # words for control word (0 or 64/w) */ #define md6_b 64 /* # data words per compression block (>0) */ #define md6_default_L 64 /* large so that MD6 is fully hierarchical */ #define md6_max_stack_height 29 /* max_stack_height determines the maximum number of bits that ** can be processed by this implementation (with default L) to be: ** (b*w) * ((b/c) ** (max_stack_height-3) ** = 2 ** 64 for b = 64, w = 64, c = 16, and max_stack_height = 29 ** (We lose three off the height since level 0 is unused, ** level 1 contains the input data, and C has 0-origin indexing.) ** The smallest workable value for md6_max_stack_height is 3. ** (To avoid stack overflow for non-default L values, ** we should have max_stack_height >= L + 2.) ** (One level of storage could be saved by letting st->N[] use ** 1-origin indexing, since st->N[0] is now unused.) */ /* MD6 state. ** ** md6_state is the main data structure for the MD6 hash function. */ typedef struct { int d; /* desired hash bit length. 1 <= d <= 512. */ int hashbitlen; /* hashbitlen is the same as d; for NIST API */ unsigned char hashval[ md6_c*(md6_w/8) ]; /* e.g. unsigned char hashval[128] */ /* contains hashval after call to md6_final */ /* hashval appears in first floor(d/8) bytes, with */ /* remaining (d mod 8) bits (if any) appearing in */ /* high-order bit positions of hashval[1+floor(d/8)]. */ unsigned char hexhashval[(md6_c*(md6_w/8))+1]; /* e.g. unsigned char hexhashval[129]; */ /* zero-terminated string representing hex value of hashval */ int initialized; /* zero, then one after md6_init called */ uint64_t bits_processed; /* bits processed so far */ uint64_t compression_calls; /* compression function calls made*/ int finalized; /* zero, then one after md6_final called */ md6_word K[ md6_k ]; /* k-word (8 word) key (aka "salt") for this instance of md6 */ int keylen; /* number of bytes in key K. 0<=keylen<=k*(w/8) */ int L; /* md6 mode specification parameter. 0 <= L <= 255 */ /* L == 0 means purely sequential (Merkle-Damgaard) */ /* L >= 29 means purely tree-based */ /* Default is md6_default_L = 64 (hierarchical) */ int r; /* Number of rounds. 0 <= r <= 255 */ int top; /* index of block corresponding to top of stack */ md6_word B[ md6_max_stack_height ][ md6_b ]; /* md6_word B[29][64] */ /* stack of 29 64-word partial blocks waiting to be */ /* completed and compressed. */ /* B[1] is for compressing text data (input); */ /* B[ell] corresponds to node at level ell in the tree. */ unsigned int bits[ md6_max_stack_height ]; /* bits[ell] = */ /* number of bits already placed in B[ell] */ /* for 1 <= ell < max_stack_height */ /* 0 <= bits[ell] <= b*w */ uint64_t i_for_level[ md6_max_stack_height ]; /* i_for_level[ell] = */ /* index of the node B[ ell ] on this level (0,1,...) */ /* when it is output */ } md6_state; /* MD6 main interface routines ** ** These routines are defined in md6_mode.c */ /* The next routines are used according to the pattern: ** md6_init (or md6_full_init if you use additional parameters) ** md6_update (once for each portion of the data to be hashed) ** md6_final (to finish up hash computation) ** Note: md6_final can return the hash value to a desired location, but ** hash value also remains available inside the md6_state, in both binary ** and hex formats (st->hashval and st->hexhashval). */ #if 0 extern int md6_init( md6_state *st, /* state to initialize */ int d /* hash bit length */ ); extern int md6_full_init( md6_state *st, /* state to initialize */ int d, /* hash bit length */ unsigned char *key, /* OK to give NULL */ int keylen, /* (in bytes) OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r /* number of rounds */ ); extern int md6_update( md6_state *st, /* initialized state */ unsigned char *data, /* data portion */ uint64_t databitlen /* its length in bits */ ); extern int md6_final( md6_state *st, /* initialized/updated */ unsigned char *hashval /* output; NULL OK */ ); #endif /* MD6 main interface routines ** ** These routines are defined in md6_mode.c ** ** These routines compute a hash for a message given all at once. ** The resulting hash value is returned to a specified location. ** Only one call is needed. Use md6_hash for the standard md6 hash, ** and md6_full_hash if you want to specify additional parameters. */ #if 0 extern int md6_hash( int d, /* hash bit length */ unsigned char *data, /* complete data to hash */ uint64_t databitlen, /* its length in bits */ unsigned char *hashval /* output */ ); extern int md6_full_hash( int d, /* hash bit length */ unsigned char *data,/* complete data to hash */ uint64_t databitlen, /* its length in bits */ unsigned char *key, /* OK to give NULL */ int keylen, /* (in bytes) OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r, /* number of rounds */ unsigned char *hashval /* output */ ); #endif /* MD6 return codes. ** ** The interface routines defined in md6_mode.c always return a ** "return code": an integer giving the status of the call. ** The codes ** SUCCESS, FAIL, and BADHASHLEN same as for NIST API */ /* SUCCESS: */ #define MD6_SUCCESS 0 /* ERROR CODES: */ #define MD6_FAIL 1 /* some other problem */ #define MD6_BADHASHLEN 2 /* hashbitlen<1 or >512 bits */ #define MD6_NULLSTATE 3 /* null state passed to MD6 */ #define MD6_BADKEYLEN 4 /* key length is <0 or >512 bits */ #define MD6_STATENOTINIT 5 /* state was never initialized */ #define MD6_STACKUNDERFLOW 6 /* MD6 stack underflows (shouldn't happen)*/ #define MD6_STACKOVERFLOW 7 /* MD6 stack overflow (message too long) */ #define MD6_NULLDATA 8 /* null data pointer */ #define MD6_NULL_N 9 /* compress: N is null */ #define MD6_NULL_B 10 /* standard compress: null B pointer */ #define MD6_BAD_ELL 11 /* standard compress: ell not in {0,255} */ #define MD6_BAD_p 12 /* standard compress: p<0 or p>b*w */ #define MD6_NULL_K 13 /* standard compress: K is null */ #define MD6_NULL_Q 14 /* standard compress: Q is null */ #define MD6_NULL_C 15 /* standard compress: C is null */ #define MD6_BAD_L 16 /* standard compress: L <0 or > 255 */ /* md6_init: L<0 or L>255 */ #define MD6_BAD_r 17 /* compress: r<0 or r>255 */ /* md6_init: r<0 or r>255 */ #define MD6_OUT_OF_MEMORY 18 /* compress: storage allocation failed */ /* The following code confirms that the defined MD6 constants satisfy ** some expected properties. These tests should never fail; consider ** these tests to be documentation. Failure of these tests would cause ** compilation to fail. */ #if ( (md6_w!=8) && (md6_w!=16) && (md6_w!=32) && (md6_w!=64) ) #error "md6.h Fatal error: md6_w must be one of 8,16,32, or 64." #elif ( md6_n<=0 ) #error "md6.h Fatal error: md6_n must be positive." #elif ( md6_b<=0 ) #error "md6.h Fatal error: md6_b must be positive." #elif ( md6_c<=0 ) #error "md6.h Fatal error: md6_c must be positive." #elif ( md6_v<0 ) #error "md6.h Fatal error: md6_v must be nonnegative." #elif ( md6_u<0 ) #error "md6.h Fatal error: md6_u must be nonnegative." #elif ( md6_k<0 ) #error "md6.h Fatal error: md6_k must be nonnegative." #elif ( md6_q<0 ) #error "md6.h Fatal error: md6_q must be nonnegative." #elif ( md6_b>=md6_n ) #error "md6.h Fatal error: md6_b must be smaller than md6_n." #elif ( md6_c>=md6_b ) #error "md6.h Fatal error: md6_c must be smaller than md6_b." #elif ( (md6_b%md6_c)!=0 ) #error "md6.h Fatal error: md6_b must be a multiple of md6_c." #elif ( md6_n != md6_b + md6_v + md6_u + md6_k + md6_q ) #error "md6.h Fatal error: md6_n must = md6_b + md6_v + md6_u + md6_k + md6_q." #elif ( md6_max_stack_height < 3 ) #error "md6.h Fatal error: md6_max_stack_height must be at least 3." #elif ( md6_max_r * md6_c + md6_n >= 5000 ) /* since md6_standard_compress allocates fixed-size array A[5000] */ #error "md6.h Fatal error: r*c+n must be < 5000." #if 0 /* "sizeof" doesn't work in preprocessor, these checks don't work */ #elif ( (md6_v != 0) && (md6_v != (sizeof(md6_control_word)/(md6_w/8))) ) #error "md6.h Fatal error: md6_v must be 0 or match md6_control_word size." #elif ( (md6_u != 0) && (md6_u != (sizeof(md6_nodeID)/(md6_w/8))) ) #error "md6.h Fatal error: md6_u must be 0 or match md6_nodeID size." #endif #endif /* Debugging and testing. */ /* compression hook, if defined, points to a function that is ** called after each compression operation. ** ** compression hook must be set *after* md6_init or md6_full_init ** is called. */ #if 0 void (* compression_hook)(md6_word *C, const md6_word *Q, md6_word *K, int ell, int i, int r, int L, int z, int p, int keylen, int d, md6_word *N ); #endif /* end of #ifndef MD6_H_INCLUDED for multiple inclusion protection */ #endif /* end of md6.h */ gtkhash-1.5/src/hash/md6/md6_compress.c000066400000000000000000000341731431266303500177700ustar00rootroot00000000000000/* File: md6_compress.c ** Author: Ronald L. Rivest ** (with optimizations by Jayant Krishnamurthy) ** Address: Room 32G-692 Stata Center ** 32 Vassar Street ** Cambridge, MA 02139 ** Email: rivest@mit.edu ** Date: 9/25/2008 ** ** (The following license is known as "The MIT License") ** ** Copyright (c) 2008 Ronald L. Rivest and Jayant Krishnamurthy ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and associated documentation files (the "Software"), to deal ** in the Software without restriction, including without limitation the rights ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ** THE SOFTWARE. ** ** (end of license) ** ** This is part of the definition of the MD6 hash function. ** The files defining the md6 hash function are: ** md6.h ** md6_compress.c ** md6_mode.c ** ** The files defining the interface between MD6 and the NIST SHA-3 ** API are: ** md6_nist.h ** md6_nist.c ** The NIST SHA-3 API is defined in: ** http://www.csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf ** ** See http://groups.csail.mit.edu/cis/md6 for more information. ** */ #include #include #include #include "md6.h" /* Useful macros: min and max */ #ifndef min #define min(a,b) ((a)<(b)? (a) : (b)) #endif #ifndef max #define max(a,b) ((a)>(b)? (a) : (b)) #endif /* Variables defining lengths of various values */ #define w md6_w /* # bits in a word (64) */ #define n md6_n /* # words in compression input (89) */ #define c md6_c /* # words in compression output (16) */ #define b md6_b /* # message words per compression input block (64) */ #define v md6_v /* # words in control word (1) */ #define u md6_u /* # words in unique nodeID (1) */ #define k md6_k /* # key words per compression input block (8) */ #define q md6_q /* # Q words per compression input block (15) */ /* "Tap positions" for feedback shift-register */ #if (n==89) #define t0 17 /* index for linear feedback */ #define t1 18 /* index for first input to first and */ #define t2 21 /* index for second input to first and */ #define t3 31 /* index for first input to second and */ #define t4 67 /* index for second input to second and */ #define t5 89 /* last tap */ #endif /* Loop-unrolling setup. ** ** Define macros for loop-unrolling within compression function ** These expand to: loop_body(right-shift,left-shift,step) ** These are given for word sizes 64, 32, 16, and 8, although ** only w=64 is needed for the standard MD6 definition. ** ** Also given for each word size are the constants S0 and Smask ** needed in the recurrence for round constants. */ #if (w==64) /* for standard word size */ #define RL00 loop_body(10,11, 0) #define RL01 loop_body( 5,24, 1) #define RL02 loop_body(13, 9, 2) #define RL03 loop_body(10,16, 3) #define RL04 loop_body(11,15, 4) #define RL05 loop_body(12, 9, 5) #define RL06 loop_body( 2,27, 6) #define RL07 loop_body( 7,15, 7) #define RL08 loop_body(14, 6, 8) #define RL09 loop_body(15, 2, 9) #define RL10 loop_body( 7,29,10) #define RL11 loop_body(13, 8,11) #define RL12 loop_body(11,15,12) #define RL13 loop_body( 7, 5,13) #define RL14 loop_body( 6,31,14) #define RL15 loop_body(12, 9,15) const md6_word S0 = (md6_word)0x0123456789abcdefULL; const md6_word Smask = (md6_word)0x7311c2812425cfa0ULL; #elif (w==32) /* for variant word size */ #define RL00 loop_body( 5, 4, 0) #define RL01 loop_body( 3, 7, 1) #define RL02 loop_body( 6, 7, 2) #define RL03 loop_body( 5, 9, 3) #define RL04 loop_body( 4,13, 4) #define RL05 loop_body( 6, 8, 5) #define RL06 loop_body( 7, 4, 6) #define RL07 loop_body( 3,14, 7) #define RL08 loop_body( 5, 7, 8) #define RL09 loop_body( 6, 4, 9) #define RL10 loop_body( 5, 8,10) #define RL11 loop_body( 5,11,11) #define RL12 loop_body( 4, 5,12) #define RL13 loop_body( 6, 8,13) #define RL14 loop_body( 7, 2,14) #define RL15 loop_body( 5,11,15) const md6_word S0 = (md6_word)0x01234567UL; const md6_word Smask = (md6_word)0x7311c281UL; /* Loop-unrolling setup (continued). ** */ #elif (w==16) /* for variant word size */ #define RL00 loop_body( 5, 6, 0) #define RL01 loop_body( 4, 7, 1) #define RL02 loop_body( 3, 2, 2) #define RL03 loop_body( 5, 4, 3) #define RL04 loop_body( 7, 2, 4) #define RL05 loop_body( 5, 6, 5) #define RL06 loop_body( 5, 3, 6) #define RL07 loop_body( 2, 7, 7) #define RL08 loop_body( 4, 5, 8) #define RL09 loop_body( 3, 7, 9) #define RL10 loop_body( 4, 6,10) #define RL11 loop_body( 3, 5,11) #define RL12 loop_body( 4, 5,12) #define RL13 loop_body( 7, 6,13) #define RL14 loop_body( 7, 4,14) #define RL15 loop_body( 2, 3,15) const md6_word S0 = (md6_word)0x01234; const md6_word Smask = (md6_word)0x7311; #elif (w==8) /* for variant word size */ #define RL00 loop_body( 3, 2, 0) #define RL01 loop_body( 3, 4, 1) #define RL02 loop_body( 3, 2, 2) #define RL03 loop_body( 4, 3, 3) #define RL04 loop_body( 3, 2, 4) #define RL05 loop_body( 3, 2, 5) #define RL06 loop_body( 3, 2, 6) #define RL07 loop_body( 3, 4, 7) #define RL08 loop_body( 2, 3, 8) #define RL09 loop_body( 2, 3, 9) #define RL10 loop_body( 3, 2,10) #define RL11 loop_body( 2, 3,11) #define RL12 loop_body( 2, 3,12) #define RL13 loop_body( 3, 4,13) #define RL14 loop_body( 2, 3,14) #define RL15 loop_body( 3, 4,15) const md6_word S0 = (md6_word)0x01; const md6_word Smask = (md6_word)0x73; #endif /* Main compression loop. ** */ static void md6_main_compression_loop( md6_word* A , int r ) /* ** Perform the md6 "main compression loop" on the array A. ** This is where most of the computation occurs; it is the "heart" ** of the md6 compression algorithm. ** Input: ** A input array of length t+n already set up ** with input in the first n words. ** r number of rounds to run (178); each is c steps ** Modifies: ** A A[n..r*c+n-1] filled in. */ { md6_word x, S; int i,j; /* ** main computation loop for md6 compression */ S = S0; for (j = 0, i = n; j> rs); /* right-shift */ \ A[i+step] = x ^ (x << ls); /* left-shift */ /* ***************************************************************** */ /* ** Unroll loop c=16 times. (One "round" of computation.) ** Shift amounts are embedded in macros RLnn. */ RL00 RL01 RL02 RL03 RL04 RL05 RL06 RL07 RL08 RL09 RL10 RL11 RL12 RL13 RL14 RL15 /* Advance round constant S to the next round constant. */ S = (S << 1) ^ (S >> (w-1)) ^ (S & Smask); i += 16; } } /* ``Bare'' compression routine. ** ** Compresses n-word input to c-word output. */ static int md6_compress( md6_word *C, md6_word *N, int r, md6_word *A ) /* Assumes n-word input array N has been fully set up. ** Input: ** N input array of n w-bit words (n=89) ** A working array of a = rc+n w-bit words ** A is OPTIONAL, may be given as NULL ** (then md6_compress allocates and uses its own A). ** r number of rounds ** Modifies: ** C output array of c w-bit words (c=16) ** Returns one of the following: ** MD6_SUCCESS (0) ** MD6_NULL_N ** MD6_NULL_C ** MD6_BAD_r ** MD6_OUT_OF_MEMORY */ { md6_word* A_as_given = A; /* check that input is sensible */ if ( N == NULL) return MD6_NULL_N; if ( C == NULL) return MD6_NULL_C; if ( r<0 || r > md6_max_r) return MD6_BAD_r; if ( A == NULL) A = calloc(r*c+n,sizeof(md6_word)); if ( A == NULL) return MD6_OUT_OF_MEMORY; memcpy( A, N, n*sizeof(md6_word) ); /* copy N to front of A */ md6_main_compression_loop( A, r ); /* do all the work */ memcpy( C, A+(r-1)*c+n, c*sizeof(md6_word) ); /* output into C */ if ( A_as_given == NULL ) /* zero and free A if nec. */ { memset(A,0,(r*c+n)*sizeof(md6_word)); /* contains key info */ free(A); } return MD6_SUCCESS; } /* Control words. */ static md6_control_word md6_make_control_word( int r, int L, int z, int p, int keylen, int d ) /* Construct control word V for given inputs. ** Input: ** r = number of rounds ** L = mode parameter (maximum tree height) ** z = 1 iff this is final compression operation ** p = number of pad bits in a block to be compressed ** keylen = number of bytes in key ** d = desired hash output length ** Does not check inputs for validity. ** Returns: ** V = constructed control word */ { md6_control_word V; V = ( (((md6_control_word) 0) << 60) | /* reserved, width 4 bits */ (((md6_control_word) r) << 48) | /* width 12 bits */ (((md6_control_word) L) << 40) | /* width 8 bits */ (((md6_control_word) z) << 36) | /* width 4 bits */ (((md6_control_word) p) << 20) | /* width 16 bits */ (((md6_control_word) keylen) << 12 ) | /* width 8 bits */ (((md6_control_word) d)) ); /* width 12 bits */ return V; } /* Node ID's. */ static md6_nodeID md6_make_nodeID( int ell, /* level number */ int i /* index (0,1,2,...) within level */ ) /* Make "unique nodeID" U based on level ell and position i ** within level; place it at specified destination. ** Inputs: ** dest = address of where nodeID U should be placed ** ell = integer level number, 1 <= ell <= ... ** i = index within level, i = 0, 1, 2,... ** Returns ** U = constructed nodeID */ { md6_nodeID U; U = ( (((md6_nodeID) ell) << 56) | ((md6_nodeID) i) ); return U; } /* Assembling components of compression input. */ static void md6_pack( md6_word*N, const md6_word* Q, md6_word* K, int ell, int i, int r, int L, int z, int p, int keylen, int d, md6_word* B ) /* Pack data before compression into n-word array N. */ { int j; int ni; md6_nodeID U; md6_control_word V; ni = 0; for (j=0;jmd6_max_r) ) return MD6_BAD_r; if ( (L<0) | (L>255) ) return MD6_BAD_L; if ( (ell < 0) || (ell > 255) ) return MD6_BAD_ELL; if ( (p < 0) || (p > b*w ) ) return MD6_BAD_p; if ( (d <= 0) || (d > c*w/2) ) return MD6_BADHASHLEN; if ( (K == NULL) ) return MD6_NULL_K; if ( (Q == NULL) ) return MD6_NULL_Q; /* pack components into N for compression */ md6_pack(N,Q,K,ell,i,r,L,z,p,keylen,d,B); /* call compression hook if it is defined. */ /* -- for testing and debugging. */ #if 0 if (compression_hook != NULL) compression_hook(C,Q,K,ell,i,r,L,z,p,keylen,d,B); #endif return md6_compress(C,N,r,A); } /* end of md6_compress.c */ gtkhash-1.5/src/hash/md6/md6_mode.c000066400000000000000000000737571431266303500170740ustar00rootroot00000000000000/* File: md6_mode.c ** Author: Ronald L. Rivest ** Address: Room 32G-692 Stata Center ** 32 Vassar Street ** Cambridge, MA 02139 ** Email: rivest@mit.edu ** Date: 9/25/2008 ** revised 4/15/09 (see changelog below) ** ** (The following license is known as "The MIT License") ** ** Copyright (c) 2008 Ronald L. Rivest ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and associated documentation files (the "Software"), to deal ** in the Software without restriction, including without limitation the rights ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ** THE SOFTWARE. ** ** (end of license) ** ** This is part of the definition of the MD6 hash function. ** The files defining the md6 hash function are: ** md6.h ** md6_compress.c ** md6_mode.c ** ** The files defining the interface between MD6 and the NIST SHA-3 ** API are: ** md6_nist.h ** md6_nist.c ** The NIST SHA-3 API is defined in: ** http://www.csrc.nist.gov/groups/ST/hash/documents/SHA3-C-API.pdf ** ** See http://groups.csail.mit.edu/cis/md6 for more information. ** ** Changelog: ** 4/15/09: In routine "md6_final", transposed two lines so that ** they are now in the correct order, which is: ** ** trim_hashval( st ); ** if (hashval != NULL) memcpy( hashval, st->hashval, (st->d+7)/8 ); ** ** This fixes problem that caller could get incorrect output ** if it took output from parameter hashval rather than from ** state variable st->hashval. If caller used the nist api ** (md6_nist.c), or used the md6 api with a non-NULL second ** argument to md6_final, or used md6_hash or md6_full_hash, ** caller would have obtained an incorrect value (basically, ** the first d bits of the final root chaining value rather ** than the last d bits). If the caller used md6sum, or used ** md6_final with a NULL second argument, the correct value ** is obtained. See changelog file for more discussion. ** ** Thanks to Piotr Krysiuk for finding and reporting ** this error! */ /* MD6 standard mode of operation ** ** Defines the following interfaces (documentation copied from md6.h) */ #if 0 /* The next routines are used according to the pattern: ** md6_init (or md6_full_init if you use additional parameters) ** md6_update (once for each portion of the data to be hashed) ** md6_final (to finish up hash computation) ** Note: md6_final can return the hash value to a desired location, but ** hash value also remains available inside the md6_state, in both binary ** and hex formats (state->hashval and state->hexhashval). */ extern int md6_init( md6_state *st, /* state to initialize */ int d /* hash bit length */ ); extern int md6_full_init( md6_state *st, /* state to initialize */ int d, /* hash bit length */ unsigned char *key, /* OK to give NULL */ int keylen, /* (in bytes) OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r /* number of rounds */ ); extern int md6_update( md6_state *st, /* initialized state */ unsigned char *data, /* data portion */ uint64_t datalen /* its length in bits */ ); extern int md6_final( md6_state *st, /* initialized/updated */ unsigned char *hashval, /* output; NULL OK */ ); /* The next routines compute a hash for a message given all at once. ** The resulting hash value is returned to a specified location. ** Only one call is needed. Use md6_hash for the standard md6 hash, ** and md6_full_hash if you want to specify additional parameters. */ extern int md6_hash( int d, /* hash bit length */ unsigned char *data, /* complete data to hash */ uint64_t datalen /* its length in bits */ unsigned char *hashval, /* output */ ); extern int md6_full_hash( int d, /* hash bit length */ unsigned char *data,/* complete data to hash */ uint64_t datalen, /* its length in bits */ unsigned char *key, /* OK to give NULL */ int keylen, /* (in bytes) OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r, /* number of rounds */ unsigned char *hashval, /* output */ ); #endif #include #include #include #include "md6.h" /* MD6 constants independent of mode of operation (from md6.h) */ #define w md6_w /* # bits in a word (64) */ #define n md6_n /* # words in compression input (89) */ #define c md6_c /* # words in compression output (16) */ /* MD6 constants needed for mode of operation */ #define q md6_q /* # words in Q (15) */ #define k md6_k /* # words in key (aka salt) (8) */ #define u md6_u /* # words in unique node ID (1) */ #define v md6_v /* # words in control word (1) */ #define b md6_b /* # data words per compression block (64) */ /* Useful macros: min and max */ #ifndef min #define min(a,b) ((a)<(b)? (a) : (b)) #endif #ifndef max #define max(a,b) ((a)>(b)? (a) : (b)) #endif /* Default number of rounds */ /* (as a function of digest size d and keylen */ static int md6_default_r( int d , int keylen ) { int r; /* Default number of rounds is forty plus floor(d/4) */ r = 40 + (d/4); /* unless keylen > 0, in which case it must be >= 80 as well */ if (keylen>0) r = max(80,r); return r; } /* MD6 Constant Vector Q ** Q = initial 960 bits of fractional part of sqrt(6) ** ** Given here for w = 64, 32, 16, and 8, although only ** w = 64 is needed for the standard version of MD6. */ #if (w==64) /* for standard version */ /* 15 64-bit words */ static const md6_word Q[15] = { 0x7311c2812425cfa0ULL, 0x6432286434aac8e7ULL, 0xb60450e9ef68b7c1ULL, 0xe8fb23908d9f06f1ULL, 0xdd2e76cba691e5bfULL, 0x0cd0d63b2c30bc41ULL, 0x1f8ccf6823058f8aULL, 0x54e5ed5b88e3775dULL, 0x4ad12aae0a6d6031ULL, 0x3e7f16bb88222e0dULL, 0x8af8671d3fb50c2cULL, 0x995ad1178bd25c31ULL, 0xc878c1dd04c4b633ULL, 0x3b72066c7a1552acULL, 0x0d6f3522631effcbULL, }; #endif #if (w==32) /* for variant version */ /* 30 32-bit words */ static const md6_word Q[30] = { 0x7311c281UL, 0x2425cfa0UL, 0x64322864UL, 0x34aac8e7UL, 0xb60450e9UL, 0xef68b7c1UL, 0xe8fb2390UL, 0x8d9f06f1UL, 0xdd2e76cbUL, 0xa691e5bfUL, 0x0cd0d63bUL, 0x2c30bc41UL, 0x1f8ccf68UL, 0x23058f8aUL, 0x54e5ed5bUL, 0x88e3775dUL, 0x4ad12aaeUL, 0x0a6d6031UL, 0x3e7f16bbUL, 0x88222e0dUL, 0x8af8671dUL, 0x3fb50c2cUL, 0x995ad117UL, 0x8bd25c31UL, 0xc878c1ddUL, 0x04c4b633UL, 0x3b72066cUL, 0x7a1552acUL, 0x0d6f3522UL, 0x631effcbUL, }; #endif /* MD6 Constant Vector Q (continued). */ #if (w==16) /* for variant version */ /* 60 16-bit words */ static const md6_word Q[60] = { 0x7311, 0xc281, 0x2425, 0xcfa0, 0x6432, 0x2864, 0x34aa, 0xc8e7, 0xb604, 0x50e9, 0xef68, 0xb7c1, 0xe8fb, 0x2390, 0x8d9f, 0x06f1, 0xdd2e, 0x76cb, 0xa691, 0xe5bf, 0x0cd0, 0xd63b, 0x2c30, 0xbc41, 0x1f8c, 0xcf68, 0x2305, 0x8f8a, 0x54e5, 0xed5b, 0x88e3, 0x775d, 0x4ad1, 0x2aae, 0x0a6d, 0x6031, 0x3e7f, 0x16bb, 0x8822, 0x2e0d, 0x8af8, 0x671d, 0x3fb5, 0x0c2c, 0x995a, 0xd117, 0x8bd2, 0x5c31, 0xc878, 0xc1dd, 0x04c4, 0xb633, 0x3b72, 0x066c, 0x7a15, 0x52ac, 0x0d6f, 0x3522, 0x631e, 0xffcb, }; #endif #if (w==8) /* for variant version */ /* 120 8-bit words */ static const md6_word Q[120] = { 0x73, 0x11, 0xc2, 0x81, 0x24, 0x25, 0xcf, 0xa0, 0x64, 0x32, 0x28, 0x64, 0x34, 0xaa, 0xc8, 0xe7, 0xb6, 0x04, 0x50, 0xe9, 0xef, 0x68, 0xb7, 0xc1, 0xe8, 0xfb, 0x23, 0x90, 0x8d, 0x9f, 0x06, 0xf1, 0xdd, 0x2e, 0x76, 0xcb, 0xa6, 0x91, 0xe5, 0xbf, 0x0c, 0xd0, 0xd6, 0x3b, 0x2c, 0x30, 0xbc, 0x41, 0x1f, 0x8c, 0xcf, 0x68, 0x23, 0x05, 0x8f, 0x8a, 0x54, 0xe5, 0xed, 0x5b, 0x88, 0xe3, 0x77, 0x5d, 0x4a, 0xd1, 0x2a, 0xae, 0x0a, 0x6d, 0x60, 0x31, 0x3e, 0x7f, 0x16, 0xbb, 0x88, 0x22, 0x2e, 0x0d, 0x8a, 0xf8, 0x67, 0x1d, 0x3f, 0xb5, 0x0c, 0x2c, 0x99, 0x5a, 0xd1, 0x17, 0x8b, 0xd2, 0x5c, 0x31, 0xc8, 0x78, 0xc1, 0xdd, 0x04, 0xc4, 0xb6, 0x33, 0x3b, 0x72, 0x06, 0x6c, 0x7a, 0x15, 0x52, 0xac, 0x0d, 0x6f, 0x35, 0x22, 0x63, 0x1e, 0xff, 0xcb, }; #endif /* Endianness. */ /* routines for dealing with byte ordering */ #if 0 int md6_byte_order = 0; /* md6_byte_order describes the endianness of the ** underlying machine: ** 0 = unknown ** 1 = little-endian ** 2 = big-endian */ /* Macros to detect machine byte order; these ** presume that md6_byte_order has been setup by ** md6_detect_byte_order() */ #define MD6_LITTLE_ENDIAN (md6_byte_order == 1) #define MD6_BIG_ENDIAN (md6_byte_order == 2) void md6_detect_byte_order( void ) /* determine if underlying machine is little-endian or big-endian ** set global variable md6_byte_order to reflect result ** Written to work for any w. */ { md6_word x = 1 | (((md6_word)2)<<(w-8)); unsigned char *cp = (unsigned char *)&x; if ( *cp == 1 ) md6_byte_order = 1; /* little-endian */ else if ( *cp == 2 ) md6_byte_order = 2; /* big-endian */ else md6_byte_order = 0; /* unknown */ } #endif static md6_word md6_byte_reverse( md6_word x ) /* return byte-reversal of md6_word x. ** Written to work for any w, w=8,16,32,64. */ { #define mask8 ((md6_word)0x00ff00ff00ff00ffULL) #define mask16 ((md6_word)0x0000ffff0000ffffULL) #if (w==64) x = (x << 32) | (x >> 32); #endif #if (w >= 32) x = ((x & mask16) << 16) | ((x & ~mask16) >> 16); #endif #if (w >= 16) x = ((x & mask8) << 8) | ((x & ~mask8) >> 8); #endif return x; } static void md6_reverse_little_endian( md6_word *x, int count ) /* Byte-reverse words x[0...count-1] if machine is little_endian */ { int i; if (MD6_LITTLE_ENDIAN) for (i=0;i> (8-accumlen); /* right-justify it in accumulator */ } di = destlen/8; /* index of where next byte will go within dest */ /* Now process each byte of src */ srcbytes = (srclen+7)/8; /* number of bytes (full or partial) in src */ for (i=0;i> (8-newbits)); accumlen += newbits; } /* do as many high-order bits of accum as you can (or need to) */ while ( ( (i != srcbytes-1) & (accumlen >= 8) ) || ( (i == srcbytes-1) & (accumlen > 0) ) ) { int numbits = min(8,accumlen); unsigned char bits; bits = accum >> (accumlen - numbits); /* right justified */ bits = bits << (8-numbits); /* left justified */ bits &= (0xff00 >> numbits); /* mask */ dest[di++] = bits; /* save */ accumlen -= numbits; } } } /* State initialization. (md6_full_init, with all parameters specified) ** */ static int md6_full_init( md6_state *st, /* uninitialized state to use */ int d, /* hash bit length */ unsigned char *key, /* key; OK to give NULL */ int keylen, /* keylength (bytes); OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r /* number of rounds */ ) /* Initialize md6_state ** Input: ** st md6_state to be initialized ** d desired hash bit length 1 <= d <= w*(c/2) (<=512 bits) ** key key (aka salt) for this hash computation (byte array) ** defaults to all-zero key if key==NULL or keylen==0 ** keylen length of key in bytes; 0 <= keylen <= (k*8) (<=64 bytes) ** L md6 mode parameter; 0 <= L <= 255 ** md6.h defines md6_default_L for when you want default ** r number of rounds; 0 <= r <= 255 ** Output: ** updates components of state ** returns one of the following: ** MD6_SUCCESS ** MD6_NULLSTATE ** MD6_BADKEYLEN ** MD6_BADHASHLEN */ { /* check that md6_full_init input parameters make some sense */ if (st == NULL) return MD6_NULLSTATE; if ( (key != NULL) && ((keylen < 0) || (keylen > k*(w/8))) ) return MD6_BADKEYLEN; if ( d < 1 || d > 512 || d > w*c/2 ) return MD6_BADHASHLEN; #if 0 md6_detect_byte_order(); #endif memset(st,0,sizeof(md6_state)); /* clear state to zero */ st->d = d; /* save hashbitlen */ if (key != NULL && keylen > 0) /* if no key given, use memset zeros*/ { memcpy(st->K,key,keylen); /* else save key (with zeros added) */ st->keylen = keylen; /* handle endian-ness */ /* first byte went into high end */ md6_reverse_little_endian(st->K,k); } else st->keylen = 0; if ( (L<0) | (L>255) ) return MD6_BAD_L; st->L = L; if ( (r<0) | (r>255) ) return MD6_BAD_r; st->r = r; st->initialized = 1; st->top = 1; /* if SEQ mode for level 1; use IV=0 */ /* zero bits already there by memset; */ /* we just need to set st->bits[1] */ if (L==0) st->bits[1] = c*w; #if 0 compression_hook = NULL; /* just to be sure default is "not set" */ #endif return MD6_SUCCESS; } /* State initialization. (md6_init, which defaults most parameters.) ** */ static int md6_init( md6_state *st, int d ) /* Same as md6_full_init, but with default key, L, and r */ { return md6_full_init(st, d, NULL, 0, md6_default_L, md6_default_r(d,0) ); } /* Data structure notes. */ /* Here are some notes on the data structures used (inside state). * The variable B[] is a stack of length-b (b-64) word records, each corresponding to a node in the tree. B[ell] corresponds to a node at level ell. Specifically, it represents the record which, when compressed, will yield the value at that level. (It only contains the data payload, not the auxiliary information.) Note that B[i] is used to store the *inputs* to the computation at level i, not the output for the node at that level. Thus, for example, the message input is stored in B[1], not B[0]. * Level 0 is not used. The message bytes are placed into B[1]. * top is the largest ell for which B[ell] has received data, or is equal to 1 in case no data has been received yet at all. * top is never greater than L+1. If B[L+1] is compressed, the result is put back into B[L+1] (this is SEQ). * bits[ell] says how many bits have been placed into B[ell]. An invariant maintained is that of the bits in B[ell], only the first bits[ell] may be nonzero; the following bits must be zero. * The B nodes may have somewhat different formats, depending on the level: -- Level 1 node contains a variable-length bit-string, and so 0 <= bits[1] <= b*w is all we can say. -- Levels 2...top always receive data in c-word chunks (from children), so for them bits[ell] is between 0 and b*w, inclusive, but is also a multiple of cw. We can think of these nodes as have (b/c) (i.e. 4) "slots" for chunks. -- Level L+1 is special, in that the first c words of B are dedicated to the "chaining variable" (or IV, for the first node on the level). * When the hashing is over, B[top] will contain the final hash value, in the first or second (if top = L+1) slot. */ /* Compress one block -- compress data at a node (md6_compress_block). */ static int md6_compress_block( md6_word *C, md6_state *st, int ell, int z ) /* compress block at level ell, and put c-word result into C. ** Input: ** st current md6 computation state ** ell 0 <= ell < max_stack_height-1 ** z z = 1 if this is very last compression; else 0 ** Output: ** C c-word array to put result in ** Modifies: ** st->bits[ell] (zeroed) ** st->i_for_level[ell] (incremented) ** st->B[ell] (zeroed) ** st->compression_calls (incremented) ** Returns one of the following: ** MD6_SUCCESS ** MD6_NULLSTATE ** MD6_STATENOTINIT ** MD6_STACKUNDERFLOW ** MD6_STACKOVERFLOW */ { int p, err; /* check that input values are sensible */ if ( st == NULL) return MD6_NULLSTATE; if ( st->initialized == 0 ) return MD6_STATENOTINIT; if ( ell < 0 ) return MD6_STACKUNDERFLOW; if ( ell >= md6_max_stack_height-1 ) return MD6_STACKOVERFLOW; st->compression_calls++; if (ell==1) /* leaf; hashing data; reverse bytes if nec. */ { if (ell<(st->L + 1)) /* PAR (tree) node */ md6_reverse_little_endian(&(st->B[ell][0]),b); else /* SEQ (sequential) node; don't reverse chaining vars */ md6_reverse_little_endian(&(st->B[ell][c]),b-c); } p = b*w - st->bits[ell]; /* number of pad bits */ err = md6_standard_compress( C, /* C */ Q, /* Q */ st->K, /* K */ ell, st->i_for_level[ell], /* -> U */ st->r, st->L, z, p, st->keylen, st->d, /* -> V */ st->B[ell] /* B */ ); if (err) return err; st->bits[ell] = 0; /* clear bits used count this level */ st->i_for_level[ell]++; memset(&(st->B[ell][0]),0,b*sizeof(md6_word)); /* clear B[ell] */ return MD6_SUCCESS; } /* Process (compress) a node and its compressible ancestors. */ static int md6_process( md6_state *st, int ell, int final ) /* ** Do processing of level ell (and higher, if necessary) blocks. ** ** Input: ** st md6 state that has been accumulating message bits ** and/or intermediate results ** ell level number of block to process ** final true if this routine called from md6_final ** (no more input will come) ** false if more input will be coming ** (This is not same notion as "final bit" (i.e. z) ** indicating the last compression operation.) ** Output (by side effect on state): ** Sets st->hashval to final chaining value on final compression. ** Returns one of the following: ** MD6_SUCCESS ** MD6_NULLSTATE ** MD6_STATENOTINIT */ { int err, z, next_level; md6_word C[c]; /* check that input values are sensible */ if ( st == NULL) return MD6_NULLSTATE; if ( st->initialized == 0 ) return MD6_STATENOTINIT; if (!final) /* not final -- more input will be coming */ { /* if not final and block on this level not full, nothing to do */ if ( st->bits[ell] < b*w ) return MD6_SUCCESS; /* else fall through to compress this full block, ** since more input will be coming */ } else /* final -- no more input will be coming */ { if ( ell == st->top ) { if (ell == (st->L + 1)) /* SEQ node */ { if ( st->bits[ell]==c*w && st->i_for_level[ell]>0 ) return MD6_SUCCESS; /* else (bits>cw or i==0, so fall thru to compress */ } else /* st->top == ell <= st->L so we are at top tree node */ { if ( ell>1 && st->bits[ell]==c*w) return MD6_SUCCESS; /* else (ell==1 or bits>cw, so fall thru to compress */ } } /* else (here ell < st->top so fall through to compress */ } /* compress block at this level; result goes into C */ /* first set z to 1 iff this is the very last compression */ z = 0; if (final && (ell == st->top)) z = 1; if ((err = md6_compress_block(C,st,ell,z))) return err; if (z==1) /* save final chaining value in st->hashval */ { memcpy( st->hashval, C, md6_c*(w/8) ); return MD6_SUCCESS; } /* where should result go? To "next level" */ next_level = min(ell+1,st->L+1); /* Start sequential mode with IV=0 at that level if necessary ** (All that is needed is to set bits[next_level] to c*w, ** since the bits themselves are already zeroed, either ** initially, or at the end of md6_compress_block.) */ if (next_level == st->L + 1 && st->i_for_level[next_level]==0 && st->bits[next_level]==0 ) st->bits[next_level] = c*w; /* now copy C onto next level */ memcpy((char *)st->B[next_level] + st->bits[next_level]/8, C, c*(w/8)); st->bits[next_level] += c*w; if (next_level > st->top) st->top = next_level; return md6_process(st,next_level,final); } /* Update -- incorporate data string into hash computation. */ static int md6_update( md6_state *st, unsigned char *data, uint64_t databitlen ) /* Process input byte string data, updating state to reflect result ** Input: ** st already initialized state to be updated ** data byte string of length databitlen bits ** to be processed (aka "M") ** databitlen number of bits in string data (aka "m") ** Modifies: ** st updated to reflect input of data */ { unsigned int j, portion_size; int err; /* check that input values are sensible */ if ( st == NULL ) return MD6_NULLSTATE; if ( st->initialized == 0 ) return MD6_STATENOTINIT; if ( data == NULL ) return MD6_NULLDATA; j = 0; /* j = number of bits processed so far with this update */ while (jbits[1]))); if ((portion_size % 8 == 0) && (st->bits[1] % 8 == 0) && (j % 8 == 0)) { /* use mempy to handle easy, but most common, case */ memcpy((char *)st->B[1] + st->bits[1]/8, &(data[j/8]), portion_size/8); } else /* handle messy case where shifting is needed */ { append_bits((unsigned char *)st->B[1], /* dest */ st->bits[1], /* dest current bit size */ &(data[j/8]), /* src */ portion_size); /* src size in bits */ } j += portion_size; st->bits[1] += portion_size; st->bits_processed += portion_size; /* compress level-1 block if it is now full but we're not done yet */ if (st->bits[1] == b*w && jhashval into hexadecimal, and ** save result in st->hexhashval ** This will be a zero-terminated string of length ceil(d/4). ** Assumes that hashval has already been "trimmed" to correct ** length. ** ** Returns one of the following: ** MD6_SUCCESS ** MD6_NULLSTATE (if input state pointer was NULL) */ { int i; static unsigned char hex_digits[] = "0123456789abcdef"; /* check that input is sensible */ if ( st == NULL ) return MD6_NULLSTATE; for (i=0;i<((st->d+7)/8);i++) { st->hexhashval[2*i] = hex_digits[ ((st->hashval[i])>>4) & 0xf ]; st->hexhashval[2*i+1] = hex_digits[ (st->hashval[i]) & 0xf ]; } /* insert zero string termination byte at position ceil(d/4) */ st->hexhashval[(st->d+3)/4] = 0; return MD6_SUCCESS; } /* Extract last d bits of chaining variable as hash value. */ static void trim_hashval(md6_state *st) { /* trim hashval to desired length d bits by taking only last d bits */ /* note that high-order bit of a byte is considered its *first* bit */ int full_or_partial_bytes = (st->d+7)/8; int bits = st->d % 8; /* bits in partial byte */ int i; /* move relevant bytes to the front */ for ( i=0; ihashval[i] = st->hashval[c*(w/8)-full_or_partial_bytes+i]; /* zero out following bytes */ for ( i=full_or_partial_bytes; ihashval[i] = 0; /* shift result left by (8-bits) bit positions, per byte, if needed */ if (bits>0) { for ( i=0; ihashval[i] = (st->hashval[i] << (8-bits)); if ( (i+1) < c*(w/8) ) st->hashval[i] |= (st->hashval[i+1] >> bits); } } } /* Final -- no more data; finish up and produce hash value. */ static int md6_final( md6_state *st , unsigned char *hashval) /* Do final processing to produce md6 hash value ** Input: ** st md6 state that has been accumulating message bits ** and/or intermediate results ** Output (by side effect on state): ** hashval If this is non-NULL, final hash value copied here. ** (NULL means don't copy.) In any case, the hash ** value remains in st->hashval. ** st->hashval this is a 64-byte array; the first st->d ** bits of which will be the desired hash value ** (with high-order bits of a byte used first), and ** remaining bits set to zero (same as hashval) ** st->hexhashval this is a 129-byte array which contains the ** zero-terminated hexadecimal version of the hash ** Returns one of the following: ** MD6_SUCCESS ** MD6_NULLSTATE ** MD6_STATENOTINIT */ { int ell, err; /* check that input values are sensible */ if ( st == NULL) return MD6_NULLSTATE; if ( st->initialized == 0 ) return MD6_STATENOTINIT; /* md6_final was previously called */ if ( st->finalized == 1 ) return MD6_SUCCESS; /* force any processing that needs doing */ if (st->top == 1) ell = 1; else for (ell=1; ell<=st->top; ell++) if (st->bits[ell]>0) break; /* process starting at level ell, up to root */ err = md6_process(st,ell,1); if (err) return err; /* md6_process has saved final chaining value in st->hashval */ { uint8_t tmp[sizeof(st->hashval)]; memcpy(&tmp, st->hashval, sizeof(tmp)); md6_reverse_little_endian( (md6_word*)&tmp, c ); memcpy(&st->hashval, &tmp, sizeof(tmp)); } /* 4/15/09: Following two lines were previously out of order, which ** caused errors depending on whether caller took hash output ** from st->hashval (which was correct) or from ** hashval parameter (which was incorrect, since it ** missed getting "trimmed".) */ trim_hashval( st ); if (hashval != NULL) memcpy( hashval, st->hashval, (st->d+7)/8 ); md6_compute_hex_hashval( st ); st->finalized = 1; return MD6_SUCCESS; } /* Routines for hashing message given "all at once". */ #if 0 int md6_full_hash( int d, /* hash bit length */ unsigned char *data,/* complete data to hash */ uint64_t databitlen, /* its length in bits */ unsigned char *key, /* OK to give NULL */ int keylen, /* (in bytes) OK to give 0 */ int L, /* mode; OK to give md6_default_L */ int r, /* number of rounds */ unsigned char *hashval /* output */ ) { md6_state st; int err; err = md6_full_init(&st,d,key,keylen,L,r); if (err) return err; err = md6_update(&st,data,databitlen); if (err) return err; md6_final(&st,hashval); if (err) return err; return MD6_SUCCESS; } int md6_hash( int d, /* hash bit length */ unsigned char *data, /* complete data to hash */ uint64_t databitlen, /* its length in bits */ unsigned char *hashval /* output */ ) { int err; err = md6_full_hash(d,data,databitlen, NULL,0,md6_default_L,md6_default_r(d,0),hashval); if (err) return err; return MD6_SUCCESS; } #endif /* ** end of md6_mode.c */ gtkhash-1.5/src/hash/meson.build000066400000000000000000000022171431266303500166710ustar00rootroot00000000000000libhash_sources = [ 'digest-format.c', 'digest.c', 'hash-file.c', 'hash-func.c', 'hash-lib.c', 'hash-string.c', 'hmac.c', ] if get_option('blake2') libhash_sources += 'hash-lib-blake2.c' endif if get_option('gcrypt') libhash_sources += 'hash-lib-gcrypt.c' endif if get_option('glib-checksums') libhash_sources += 'hash-lib-glib.c' endif if get_option('libcrypto') libhash_sources += 'hash-lib-crypto.c' endif if get_option('linux-crypto') libhash_sources += 'hash-lib-linux.c' endif if get_option('mbedtls') libhash_sources += 'hash-lib-mbedtls.c' endif if get_option('internal-md6') libhash_sources += 'hash-lib-md6.c' endif if get_option('nettle') libhash_sources += 'hash-lib-nettle.c' endif if get_option('zlib') libhash_sources += 'hash-lib-zlib.c' endif libhash = static_library('hash', libhash_sources, include_directories: root_include, c_args: [ '-DIN_HASH_LIB', ], dependencies: [ blake2, gio, glib, libcrypto, libgcrypt, mbedtls, nettle, zlib, ], ) # hash_la_LDFLAGS = -avoid-version -module gtkhash-1.5/src/list.c000066400000000000000000000206751431266303500147330ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "list.h" #include "main.h" #include "hash.h" #include "gui.h" #include "hash/digest-format.h" enum { COL_STATUS, // 0 COL_ICON_NAME, // 1 COL_PNAME, // 2 COL_TOOLTIP, // 3 COL_CHECK, // 4 COL_DIGESTS, // 5+ }; struct list_s list; struct { int hash_cols[HASH_FUNCS_N]; bool show_status; } list_priv = { .show_status = false, }; void list_init(void) { list.rows = 0; int cols = COL_DIGESTS; for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; list_priv.hash_cols[i] = cols; cols = gtk_tree_view_insert_column_with_attributes(gui.treeview, -1, hash.funcs[i].name, gtk_cell_renderer_text_new(), "text", cols, NULL); } GType types[cols]; types[COL_STATUS] = G_TYPE_CHAR; types[COL_ICON_NAME] = G_TYPE_STRING; types[COL_PNAME] = G_TYPE_STRING; types[COL_TOOLTIP] = G_TYPE_STRING; types[COL_CHECK] = G_TYPE_STRING; for (int i = COL_DIGESTS; i < cols; i++) { types[i] = G_TYPE_STRING; GtkTreeViewColumn *col = gtk_tree_view_get_column(gui.treeview, i); gtk_tree_view_column_set_resizable(col, true); gtk_tree_view_column_set_min_width(col, 10); } gui.liststore = gtk_list_store_newv(cols, types); gui.treemodel = GTK_TREE_MODEL(gui.liststore); gtk_tree_view_set_model(gui.treeview, gui.treemodel); const GtkTargetEntry targets[] = { { (char *)"text/uri-list", 0, 0 } }; gtk_drag_dest_set(GTK_WIDGET(gui.treeview), GTK_DEST_DEFAULT_ALL, targets, G_N_ELEMENTS(targets), GDK_ACTION_COPY); } void list_update(void) { bool enabled = false; for (int i = 0; i < HASH_FUNCS_N; i++) { if (!hash.funcs[i].supported) continue; if (hash.funcs[i].enabled) enabled = true; GtkTreeViewColumn *col = gtk_tree_view_get_column(gui.treeview, list_priv.hash_cols[i]); gtk_tree_view_column_set_visible(col, hash.funcs[i].enabled); } GtkTreeViewColumn *col = gtk_tree_view_get_column(gui.treeview, COL_STATUS); gtk_tree_view_column_set_visible(col, list_priv.show_status); gtk_widget_set_sensitive(GTK_WIDGET(gui.toolbutton_clear), list.rows); gtk_widget_set_sensitive(GTK_WIDGET(gui.menuitem_treeview_clear), list.rows); gtk_widget_set_sensitive(GTK_WIDGET(gui.button_hash), list.rows && enabled); } void list_append_row(const char * const uri, const char * const check) { g_assert(uri); GFile *file = g_file_new_for_uri(uri); char *pname = g_file_get_parse_name(file); char *basename = g_filename_display_basename(pname); char *tooltip = g_markup_escape_text(basename, -1); gtk_list_store_insert_with_values(gui.liststore, NULL, list.rows + 1, COL_PNAME, pname, COL_TOOLTIP, tooltip, COL_CHECK, check ? check : "", -1); list.rows++; g_free(tooltip); g_free(basename); g_free(pname); g_object_unref(file); if (check) list_priv.show_status = true; } void list_remove_selection(void) { if (gtk_tree_selection_count_selected_rows(gui.treeselection) == (int)list.rows) { list_clear(); return; } GList *rows = gtk_tree_selection_get_selected_rows(gui.treeselection, &gui.treemodel); for (GList *i = rows; i != NULL; i = i->next) { GtkTreePath *path = i->data; GtkTreeRowReference *ref = gtk_tree_row_reference_new(gui.treemodel, i->data); i->data = ref; gtk_tree_path_free(path); } for (GList *i = rows; i != NULL; i = i->next) { GtkTreeRowReference *ref = i->data; GtkTreePath *path = gtk_tree_row_reference_get_path(ref); GtkTreeIter iter; if (gtk_tree_model_get_iter(gui.treemodel, &iter, path)) { gtk_list_store_remove(gui.liststore, &iter); list.rows--; } gtk_tree_path_free(path); gtk_tree_row_reference_free(ref); } g_list_free(rows); gtk_tree_selection_unselect_all(gui.treeselection); } static GFile *list_get_file(const unsigned int row) { g_assert(row <= list.rows); GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(gui.treemodel, &iter, NULL, row)) g_assert_not_reached(); GValue value = G_VALUE_INIT; gtk_tree_model_get_value(gui.treemodel, &iter, COL_PNAME, &value); GFile *file = g_file_parse_name(g_value_get_string(&value)); g_value_unset(&value); return file; } char *list_get_uri(const unsigned int row) { GFile *file = list_get_file(row); char *uri = g_file_get_uri(file); g_object_unref(file); return uri; } char *list_get_basename(const unsigned int row) { GFile *file = list_get_file(row); char *basename = g_file_get_basename(file); g_object_unref(file); return basename; } static void list_scroll_to_next_row(GtkTreeIter iter) { if (!gtk_tree_model_iter_next(gui.treemodel, &iter)) return; GtkTreePath *path = gtk_tree_model_get_path(gui.treemodel, &iter); gtk_tree_view_scroll_to_cell(gui.treeview, path, NULL, false, 0, 0); gtk_tree_path_free(path); } void list_set_digest(const unsigned int row, const enum hash_func_e id, const char * const digest) { g_assert(row <= list.rows); g_assert(HASH_FUNC_IS_VALID(id)); GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(gui.treemodel, &iter, NULL, row)) g_assert_not_reached(); list_scroll_to_next_row(iter); gtk_list_store_set(gui.liststore, &iter, list_priv.hash_cols[id], digest, -1); } char *list_get_digest(const unsigned int row, const enum hash_func_e id) { g_assert(row <= list.rows); g_assert(HASH_FUNC_IS_VALID(id)); GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(gui.treemodel, &iter, NULL, row)) return NULL; char *digest; GValue value = G_VALUE_INIT; gtk_tree_model_get_value(gui.treemodel, &iter, list_priv.hash_cols[id], &value); digest = g_value_dup_string(&value); g_value_unset(&value); return digest; } char *list_get_selected_digest(const enum hash_func_e id) { GList *rows = gtk_tree_selection_get_selected_rows(gui.treeselection, &gui.treemodel); // Should only have one row selected g_assert(rows); g_assert(!rows->next); GtkTreePath *path = rows->data; unsigned int row = *gtk_tree_path_get_indices(path); gtk_tree_path_free(path); g_list_free(rows); return list_get_digest(row, id); } void list_check_digests(const unsigned int row) { GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(gui.treemodel, &iter, NULL, row)) return; GValue value = G_VALUE_INIT; gtk_tree_model_get_value(gui.treemodel, &iter, COL_CHECK, &value); const char *check = g_value_get_string(&value); if (!*check) { g_value_unset(&value); gtk_list_store_set(gui.liststore, &iter, COL_ICON_NAME, "", -1); return; } const enum digest_format_e format = gui_get_digest_format(); bool match = false; for (int i = 0; (i < HASH_FUNCS_N) && !match; i++) { if (!hash.funcs[i].enabled) continue; GValue digest = G_VALUE_INIT; gtk_tree_model_get_value(gui.treemodel, &iter, list_priv.hash_cols[i], &digest); const char *digest_str = g_value_get_string(&digest); match = gtkhash_digest_format_compare(digest_str, check, format); g_value_unset(&digest); } g_value_unset(&value); // XXX: maybe use ✓ and ✖ instead gtk_list_store_set(gui.liststore, &iter, COL_ICON_NAME, match ? "gtk-yes" : "gtk-no", -1); } void list_clear_digests(void) { GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(gui.treemodel, &iter)) return; int cols_n = 0; for (int i = 0; i < HASH_FUNCS_N; i++) if (hash.funcs[i].supported) cols_n++; gint cols[cols_n]; GValue vals[HASH_FUNCS_N] = { G_VALUE_INIT }; for (int i = 0; i < cols_n; i++) { cols[i] = COL_DIGESTS + i; g_value_init(&vals[i], G_TYPE_STRING); } do { gtk_list_store_set_valuesv(gui.liststore, &iter, cols, vals, cols_n); } while (gtk_tree_model_iter_next(gui.treemodel, &iter)); } void list_clear(void) { gtk_list_store_clear(gui.liststore); list.rows = 0; list_priv.show_status = false; list_update(); } gtkhash-1.5/src/list.h000066400000000000000000000026221431266303500147300ustar00rootroot00000000000000/* * Copyright (C) 2007-2018 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_LIST_H #define GTKHASH_LIST_H #include "hash/hash-func.h" extern struct list_s { unsigned int rows; } list; void list_init(void); void list_update(void); void list_append_row(const char *uri, const char *check); void list_remove_selection(void); char *list_get_uri(unsigned int row); char *list_get_basename(unsigned int row); void list_set_digest(unsigned int row, enum hash_func_e id, const char *digest); char *list_get_digest(unsigned int row, enum hash_func_e id); char *list_get_selected_digest(enum hash_func_e id); void list_check_digests(unsigned int row); void list_clear_digests(void); void list_clear(void); #endif gtkhash-1.5/src/main.c000066400000000000000000000033461431266303500147000ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "main.h" #include "opts.h" #include "hash.h" #include "gui.h" #include "prefs.h" #include "check.h" #if ENABLE_NLS static void nls_init(void) { #ifdef G_OS_WIN32 char *pkgdir = g_win32_get_package_installation_directory_of_module(NULL); char *localedir = g_build_filename(pkgdir, "share", "locale", NULL); bindtextdomain(GETTEXT_PACKAGE, localedir); g_free(localedir); g_free(pkgdir); #else bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); #endif bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); } #endif int main(int argc, char **argv) { #if ENABLE_NLS nls_init(); #endif hash_init(); opts_preinit(&argc, &argv); gtk_init(NULL, NULL); gui_init(); prefs_init(); check_init(); opts_postinit(); gui_run(); check_deinit(); prefs_deinit(); gui_deinit(); hash_deinit(); return EXIT_SUCCESS; } gtkhash-1.5/src/main.h000066400000000000000000000016541431266303500147050ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_MAIN_H #define GTKHASH_MAIN_H #if ENABLE_NLS #include #else #define _(STR) (STR) #define C_(CONTEXT, STR) (STR) #endif #endif gtkhash-1.5/src/meson.build000066400000000000000000000042041431266303500157440ustar00rootroot00000000000000subdir('hash') subdir('util') if enable_nautilus_data subdir('nautilus') endif if build_gtkhash gtkhash_common_sources = [ 'callbacks.c', 'check.c', 'gui.c', 'hash.c', 'list.c', 'opts.c', 'uri-digest.c', ] gtkhash_common_sources += gnome.compile_resources('resources', gtkhash_gtk3_gresource, c_name: 'resources', source_dir: meson.current_source_dir() / '..' / 'data', extra_args: [ '--internal', '--manual-register', ], ) gtkhash = executable('gtkhash', gtkhash_common_sources, 'main.c', 'prefs.c', include_directories: root_include, dependencies: [ glib, gtk, ], link_with: [ libhash, libutil, ], install: true, ) # Test executable. gtkhash_test = executable('gtkhash-test', gtkhash_common_sources, 'test.c', include_directories: root_include, dependencies: [ glib, gtk, ], link_with: [ libhash, libutil, ], ) test_files = [] configure_file( input : 'test.md5sum.in', output: 'test.md5sum', configuration: { 'builddir': meson.current_build_dir(), }, ) bytes_tests_values = [ '0', '1', '10M', '5G', ] foreach bytes_test : bytes_tests_values filename = '@0@.bytes'.format(bytes_test) test_files += custom_target(filename, output: filename, command: [ 'truncate', '-s', '@0@'.format(bytes_test), '@OUTPUT@', ], ) endforeach foreach lib, functions : hash_libs lib_enabled = config.get('ENABLE_' + lib.to_upper()) == 1 test('gtkhash-test-@0@'.format(lib), gtkhash_test, depends: test_files, env: [ 'GTKHASH_TEST_LIB=@0@'.format(lib) ], protocol: 'tap', ) endforeach test('gtkhash-test', gtkhash_test, depends: test_files, protocol: 'tap', ) endif gtkhash-1.5/src/nautilus/000077500000000000000000000000001431266303500154465ustar00rootroot00000000000000gtkhash-1.5/src/nautilus/Makefile.am000066400000000000000000000067271431266303500175160ustar00rootroot00000000000000common_cppflags = -DLOCALEDIR="\"$(localedir)\"" common_ldflags = \ -avoid-version \ -module \ -shared common_libadd = \ ../hash/hash.la \ ../util/util.la BUILT_SOURCES = properties-resources.c CLEANFILES = properties-resources.c *.gcda *.gcno EXTRA_DIST = \ meson.build \ extension.map.in if ENABLE_CAJA cajadir = $(CAJA_EXTENSION_DIR) caja_LTLIBRARIES = libgtkhash-properties-caja.la nodist_libgtkhash_properties_caja_la_SOURCES = \ properties-resources.c libgtkhash_properties_caja_la_SOURCES = \ properties.c properties.h \ properties-hash.c properties-hash.h \ properties-list.c properties-list.h \ properties-prefs.c properties-prefs.h libgtkhash_properties_caja_la_CPPFLAGS = \ $(common_cppflags) \ $(CAJA_CFLAGS) \ -DIN_CAJA_EXTENSION libgtkhash_properties_caja_la_CFLAGS = $(GTKHASH_CFLAGS) libgtkhash_properties_caja_la_LDFLAGS = \ $(common_ldflags) \ -export-symbols-regex ^caja_module_ libgtkhash_properties_caja_la_LIBADD = \ $(common_libadd) \ $(CAJA_LIBS) endif if ENABLE_NAUTILUS nautilusdir = $(NAUTILUS_EXTENSION_DIR) nautilus_LTLIBRARIES = libgtkhash-properties-nautilus.la nodist_libgtkhash_properties_nautilus_la_SOURCES = \ properties-resources.c libgtkhash_properties_nautilus_la_SOURCES = \ properties.c properties.h \ properties-hash.c properties-hash.h \ properties-list.c properties-list.h \ properties-prefs.c properties-prefs.h libgtkhash_properties_nautilus_la_CPPFLAGS = \ $(common_cppflags) \ $(NAUTILUS_CFLAGS) \ -DIN_NAUTILUS_EXTENSION libgtkhash_properties_nautilus_la_CFLAGS = $(GTKHASH_CFLAGS) libgtkhash_properties_nautilus_la_LDFLAGS = \ $(common_ldflags) \ -export-symbols-regex ^nautilus_module_ libgtkhash_properties_nautilus_la_LIBADD = \ $(common_libadd) \ $(NAUTILUS_LIBS) endif if ENABLE_NEMO nemodir = $(NEMO_EXTENSION_DIR) nemo_LTLIBRARIES = libgtkhash-properties-nemo.la nodist_libgtkhash_properties_nemo_la_SOURCES = \ properties-resources.c libgtkhash_properties_nemo_la_SOURCES = \ properties.c properties.h \ properties-hash.c properties-hash.h \ properties-list.c properties-list.h \ properties-prefs.c properties-prefs.h libgtkhash_properties_nemo_la_CPPFLAGS = \ $(common_cppflags) \ $(NEMO_CFLAGS) \ -DIN_NEMO_EXTENSION libgtkhash_properties_nemo_la_CFLAGS = $(GTKHASH_CFLAGS) libgtkhash_properties_nemo_la_LDFLAGS = \ $(common_ldflags) \ -export-symbols-regex ^nemo_module_ libgtkhash_properties_nemo_la_LIBADD = \ $(common_libadd) \ $(NEMO_LIBS) endif if ENABLE_THUNAR thunardir = $(THUNAR_EXTENSION_DIR) thunar_LTLIBRARIES = libgtkhash-properties-thunar.la nodist_libgtkhash_properties_thunar_la_SOURCES = \ properties-resources.c libgtkhash_properties_thunar_la_SOURCES = \ properties.c properties.h \ properties-hash.c properties-hash.h \ properties-list.c properties-list.h \ properties-prefs.c properties-prefs.h libgtkhash_properties_thunar_la_CPPFLAGS = \ $(common_cppflags) \ $(THUNAR_CFLAGS) \ -DIN_THUNAR_EXTENSION libgtkhash_properties_thunar_la_CFLAGS = $(GTKHASH_CFLAGS) libgtkhash_properties_thunar_la_LDFLAGS = \ $(common_ldflags) \ -export-symbols-regex ^thunar_extension_ libgtkhash_properties_thunar_la_LIBADD = \ $(common_libadd) \ $(THUNAR_LIBS) endif properties-resources.c: \ ../../data/nautilus/gtkhash-properties.gresource.xml \ ../../data/nautilus/gtkhash-properties.ui $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) \ --c-name gtkhash_properties_resources \ --internal \ --generate-source \ --sourcedir="$(srcdir)"/../../data/nautilus/ \ --target=$@ \ $< gtkhash-1.5/src/nautilus/extension.map.in000066400000000000000000000000611431266303500205630ustar00rootroot00000000000000{ global: @symbol_prefix@*; local: *; }; gtkhash-1.5/src/nautilus/meson.build000066400000000000000000000034261431266303500176150ustar00rootroot00000000000000properties_resources = gnome.compile_resources( 'resources', gtkhash_properties_gresource, c_name: 'gtkhash_properties_resources', source_dir: meson.current_source_dir() / '..' / '..' / 'data' / 'nautilus', ) extensions_sources = [ 'properties.c', 'properties-hash.c', 'properties-list.c', 'properties-prefs.c', properties_resources, ] extensions = [] if build_caja extensions += { 'name': 'caja', 'dep': caja, 'dir': caja_extension_dir, 'symbol_prefix': 'caja_module_', } endif if build_nautilus extensions += { 'name': 'nautilus', 'dep': nautilus, 'dir': nautilus_extension_dir, 'symbol_prefix': 'nautilus_module_', } endif if build_nemo extensions += { 'name': 'nemo', 'dep': nemo, 'dir': nemo_extension_dir, 'symbol_prefix': 'nemo_module_', } endif if build_thunar extensions += { 'name': 'thunar', 'dep': thunar, 'dir': thunar_extension_dir, 'symbol_prefix': 'thunar_extension_', } endif foreach extension : extensions name = extension.get('name') extension_map_file = configure_file( input: 'extension.map.in', output: 'extension_@0@.map'.format(name), configuration: { 'symbol_prefix': extension.get('symbol_prefix')}, ) shared_library('gtkhash-properties-@0@'.format(name), extensions_sources, include_directories: root_include, c_args: [ '-DIN_@0@_EXTENSION'.format(name.to_upper()), ], link_with: [ libhash, libutil, ], link_args: [ '-Wl,--version-script,@0@'.format(extension_map_file), ], dependencies: extension.get('dep'), install: true, install_dir: extension.get('dir'), ) endforeach gtkhash-1.5/src/nautilus/properties-hash.c000066400000000000000000000063461431266303500207400ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "properties.h" #include "properties-hash.h" #include "properties-list.h" #include "../hash/hash-string.h" #include "../hash/hash-file.h" #include "../hash/digest-format.h" #include "../util/util.h" void gtkhash_hash_string_digest_cb(G_GNUC_UNUSED enum hash_func_e id, G_GNUC_UNUSED const char *digest) { } void gtkhash_hash_string_finish_cb(void) { } void gtkhash_hash_file_report_cb(void *data, const goffset file_size, const goffset total_read, GTimer *timer) { struct page_s *page = data; gtk_progress_bar_set_fraction(page->progressbar, (double)total_read / (double)file_size); const double elapsed = g_timer_elapsed(timer, NULL); if (elapsed <= 1) return; char *text = gtkhash_format_progress(file_size, total_read, elapsed); gtk_progress_bar_set_text(page->progressbar, text); g_free(text); } void gtkhash_hash_file_digest_cb(const enum hash_func_e id, const char *digest, void *data) { gtkhash_properties_list_set_digest(data, id, digest); } void gtkhash_hash_file_finish_cb(void *data) { // Reset enabled state following single-function hash gtkhash_properties_list_reset_enabled(data); gtkhash_properties_idle(data); } void gtkhash_hash_file_stop_cb(void *data) { // Reset enabled state following single-function hash gtkhash_properties_list_reset_enabled(data); gtkhash_properties_idle((struct page_s *)data); } void gtkhash_properties_hash_start(struct page_s *page, struct hash_func_s *func, const uint8_t *hmac_key, const size_t key_size) { // Single-function hash if (func) { for (int i = 0; i < HASH_FUNCS_N; i++) { if (!page->funcs[i].supported || i == func->id) continue; page->funcs[i].enabled = false; } } gtkhash_hash_file(page->hfile, page->uri, DIGEST_FORMAT_HEX_LOWER, hmac_key, key_size, page); } void gtkhash_properties_hash_stop(struct page_s *page) { gtkhash_hash_file_cancel(page->hfile); } int gtkhash_properties_hash_funcs_supported(struct page_s *page) { int supported = 0; for (int i = 0; i < HASH_FUNCS_N; i++) { if (page->funcs[i].supported) supported++; } return supported; } void gtkhash_properties_hash_init(struct page_s *page) { gtkhash_hash_func_init_all(page->funcs); page->hfile = gtkhash_hash_file_new(page->funcs); } void gtkhash_properties_hash_deinit(struct page_s *page) { gtkhash_hash_file_free(page->hfile); page->hfile = NULL; gtkhash_hash_func_deinit_all(page->funcs); } gtkhash-1.5/src/nautilus/properties-hash.h000066400000000000000000000023541431266303500207400ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_NAUTILUS_PROPERTIES_HASH_H #define GTKHASH_NAUTILUS_PROPERTIES_HASH_H #include "properties.h" void gtkhash_properties_hash_start(struct page_s *page, struct hash_func_s *func, const uint8_t *hmac_key, size_t key_size); void gtkhash_properties_hash_stop(struct page_s *page); int gtkhash_properties_hash_funcs_supported(struct page_s *page); void gtkhash_properties_hash_init(struct page_s *page); void gtkhash_properties_hash_deinit(struct page_s *page); #endif gtkhash-1.5/src/nautilus/properties-list.c000066400000000000000000000173641431266303500207720ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "properties.h" #include "properties-list.h" #include "properties-hash.h" #include "../hash/hash-func.h" #include "../hash/digest-format.h" enum { COL_ID, COL_ENABLED, COL_HASH_FUNC, COL_DIGEST }; inline static GtkTreeModelFilter *gtkhash_properties_list_get_filter( struct page_s *page) { return GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(page->treeview)); } inline static GtkTreeModel *gtkhash_properties_list_get_model( struct page_s *page) { GtkTreeModelFilter *filter = gtkhash_properties_list_get_filter(page); return gtk_tree_model_filter_get_model(filter); } inline static GtkListStore *gtkhash_properties_list_get_store( struct page_s *page) { return GTK_LIST_STORE(gtkhash_properties_list_get_model(page)); } void gtkhash_properties_list_update_enabled(struct page_s *page, char *path_str) { GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkListStore *store = gtkhash_properties_list_get_store(page); GtkTreeIter iter; gtk_tree_model_get_iter_from_string(model, &iter, path_str); int id; gboolean enabled; gtk_tree_model_get(model, &iter, COL_ID, &id, COL_ENABLED, &enabled, -1); enabled = !enabled; gtk_list_store_set(store, &iter, COL_ENABLED, enabled, -1); if (!enabled) { // Clear digest for disabled func gtk_list_store_set(store, &iter, COL_DIGEST, "", -1); } page->funcs[id].enabled = enabled; } void gtkhash_properties_list_reset_enabled(struct page_s *page) { GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(model, &iter)) return; do { int id; gboolean enabled; gtk_tree_model_get(model, &iter, COL_ID, &id, -1); gtk_tree_model_get(model, &iter, COL_ENABLED, &enabled, -1); page->funcs[id].enabled = enabled; } while (gtk_tree_model_iter_next(model, &iter)); } void gtkhash_properties_list_update_hash_func_names(struct page_s *page) { GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(model, &iter)) return; GtkListStore *store = gtkhash_properties_list_get_store(page); const bool hmac = gtk_toggle_button_get_active(page->togglebutton_hmac); do { int id; gtk_tree_model_get(model, &iter, COL_ID, &id, -1); if (!page->funcs[id].hmac_supported) continue; if (hmac) { char *name = g_strdup_printf("HMAC-%s", page->funcs[id].name); gtk_list_store_set(store, &iter, COL_HASH_FUNC, name, -1); g_free(name); } else { gtk_list_store_set(store, &iter, COL_HASH_FUNC, page->funcs[id].name, -1); } // Digest is invalid now, so clear it gtk_list_store_set(store, &iter, COL_DIGEST, "", -1); } while (gtk_tree_model_iter_next(model, &iter)); gtk_tree_view_columns_autosize(page->treeview); } void gtkhash_properties_list_clear_digests(struct page_s *page) { GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(model, &iter)) return; GtkListStore *store = gtkhash_properties_list_get_store(page); do { gtk_list_store_set(store, &iter, COL_DIGEST, "", -1); } while (gtk_tree_model_iter_next(model, &iter)); gtk_tree_view_columns_autosize(page->treeview); } void gtkhash_properties_list_check_digests(struct page_s *page) { const char *check = gtk_entry_get_text(page->entry_check); const char *icon = NULL; GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkTreeIter iter; if (*check && gtk_tree_model_get_iter_first(model, &iter)) { do { char *digest = NULL;; gtk_tree_model_get(model, &iter, COL_DIGEST, &digest, -1); if (gtkhash_digest_format_compare(check, digest, DIGEST_FORMAT_HEX_LOWER)) icon = "gtk-yes"; g_free(digest); } while (!icon && gtk_tree_model_iter_next(model, &iter)); } gtk_entry_set_icon_from_icon_name(page->entry_check, GTK_ENTRY_ICON_SECONDARY, icon); } void gtkhash_properties_list_set_digest(struct page_s *page, const enum hash_func_e id, const char *digest) { GtkTreeModel *model = gtkhash_properties_list_get_model(page); GtkListStore *store = gtkhash_properties_list_get_store(page); GtkTreeIter iter; if (!gtk_tree_model_get_iter_first(model, &iter)) g_assert_not_reached(); do { int row_id; gtk_tree_model_get(model, &iter, COL_ID, &row_id, -1); if (row_id == id) { gtk_list_store_set(store, &iter, COL_DIGEST, digest, -1); return; } } while (gtk_tree_model_iter_next(model, &iter)); g_assert_not_reached(); } char *gtkhash_properties_list_get_selected_digest(struct page_s *page) { GtkTreeIter iter; GtkTreeModel *model; if (!gtk_tree_selection_get_selected(page->treeselection, &model, &iter)) return NULL; char *digest = NULL;; gtk_tree_model_get(model, &iter, COL_DIGEST, &digest, -1); if (digest && *digest) return digest; else { g_free(digest); return NULL; } } bool gtkhash_properties_list_hash_selected(struct page_s *page) { GtkTreeIter iter; GtkTreeModel *model; if (!gtk_tree_selection_get_selected(page->treeselection, &model, &iter)) return false; gboolean enabled; gtk_tree_model_get(model, &iter, COL_ENABLED, &enabled, -1); if (!enabled) return false; int id; gtk_tree_model_get(model, &iter, COL_ID, &id, -1); if (gtk_toggle_button_get_active(page->togglebutton_hmac)) { const uint8_t *hmac_key = (uint8_t *)gtk_entry_get_text( page->entry_hmac); GtkEntryBuffer *buffer = gtk_entry_get_buffer(page->entry_hmac); const size_t key_size = gtk_entry_buffer_get_bytes(buffer); gtkhash_properties_hash_start(page, &page->funcs[id], hmac_key, key_size); } else gtkhash_properties_hash_start(page, &page->funcs[id], NULL, 0); return true; } void gtkhash_properties_list_refilter(struct page_s *page) { GtkTreeModelFilter *filter = gtkhash_properties_list_get_filter(page); gtk_tree_model_filter_refilter(filter); bool active = gtk_check_menu_item_get_active(page->menuitem_show_funcs); GtkTreeViewColumn *col = gtk_tree_view_get_column(page->treeview, 0); gtk_tree_view_column_set_visible(col, active); gtk_tree_view_columns_autosize(page->treeview); } static gboolean gtkhash_properties_list_filter(GtkTreeModel *model, GtkTreeIter *iter, struct page_s *page) { gboolean enabled; gtk_tree_model_get(model, iter, COL_ENABLED, &enabled, -1); if (!enabled && !gtk_check_menu_item_get_active(page->menuitem_show_funcs)) return false; return true; } void gtkhash_properties_list_init(struct page_s *page) { GtkListStore *store = gtkhash_properties_list_get_store(page); for (int i = 0; i < HASH_FUNCS_N; i++) { if (!page->funcs[i].supported) continue; gtk_list_store_insert_with_values(store, NULL, i, COL_ID, i, COL_ENABLED, page->funcs[i].enabled, COL_HASH_FUNC, page->funcs[i].name, COL_DIGEST, "", -1); } GtkTreeModelFilter *filter = gtkhash_properties_list_get_filter(page); gtk_tree_model_filter_set_visible_func(filter, (GtkTreeModelFilterVisibleFunc)gtkhash_properties_list_filter, page, NULL); gtkhash_properties_list_refilter(page); } gtkhash-1.5/src/nautilus/properties-list.h000066400000000000000000000031071431266303500207650ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_NAUTILUS_PROPERTIES_LIST_H #define GTKHASH_NAUTILUS_PROPERTIES_LIST_H #include "properties.h" void gtkhash_properties_list_update_enabled(struct page_s *page, char *path_str); void gtkhash_properties_list_reset_enabled(struct page_s *page); void gtkhash_properties_list_update_hash_func_names(struct page_s *page); void gtkhash_properties_list_clear_digests(struct page_s *page); void gtkhash_properties_list_check_digests(struct page_s *page); void gtkhash_properties_list_set_digest(struct page_s *page, enum hash_func_e id, const char *digest); char *gtkhash_properties_list_get_selected_digest(struct page_s *page); bool gtkhash_properties_list_hash_selected(struct page_s *page); void gtkhash_properties_list_refilter(struct page_s *page); void gtkhash_properties_list_init(struct page_s *page); #endif gtkhash-1.5/src/nautilus/properties-prefs.c000066400000000000000000000070241431266303500211260ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "properties.h" #include "properties-prefs.h" #include "properties-hash.h" #include "../hash/hash-func.h" #define PREFS_SCHEMA "org.gtkhash.plugin" #define PREFS_KEY_HASH_FUNCS "hash-functions" #define PREFS_KEY_SHOW_DISABLED_FUNCS "show-disabled-hash-functions" #define PREFS_BIND_FLAGS \ (G_SETTINGS_BIND_DEFAULT | \ G_SETTINGS_BIND_GET_NO_CHANGES) static void gtkhash_properties_prefs_default_hash_funcs(struct page_s *page) { for (int i = 0; i < HASH_FUNCS_N; i++) if (HASH_FUNC_IS_DEFAULT(i) && page->funcs[i].supported) page->funcs[i].enabled = true; } static void gtkhash_properties_prefs_load_hash_funcs(struct page_s *page) { char **strv = g_settings_get_strv(page->settings, PREFS_KEY_HASH_FUNCS); for (int i = 0; strv[i]; i++) { enum hash_func_e id = gtkhash_hash_func_get_id_from_name(strv[i]); if (id != HASH_FUNC_INVALID && page->funcs[id].supported) page->funcs[id].enabled = true; } g_strfreev(strv); } static void gtkhash_properties_prefs_load_show_disabled_funcs(struct page_s *page) { g_settings_bind(page->settings, PREFS_KEY_SHOW_DISABLED_FUNCS, page->menuitem_show_funcs, "active", PREFS_BIND_FLAGS); } static void gtkhash_properties_prefs_load(struct page_s *page) { g_assert(page->settings); gtkhash_properties_prefs_load_hash_funcs(page); gtkhash_properties_prefs_load_show_disabled_funcs(page); } static void gtkhash_properties_prefs_save_hash_funcs(struct page_s *page) { const char **strv = NULL; int enabled = 0; for (int i = 0; i < HASH_FUNCS_N; i++) { if (page->funcs[i].enabled) enabled++; } if (enabled > 0) { strv = g_new0(const char *, enabled + 1); for (int i = 0, j = 0; (i < HASH_FUNCS_N) && (j < enabled); i++) { if (page->funcs[i].enabled) { strv[j] = page->funcs[i].name; j++; } } } g_settings_set_strv(page->settings, PREFS_KEY_HASH_FUNCS, strv); if (strv) g_free(strv); } static void gtkhash_properties_prefs_save(struct page_s *page) { g_assert(page->settings); gtkhash_properties_prefs_save_hash_funcs(page); } void gtkhash_properties_prefs_init(struct page_s *page) { page->settings = NULL; GSettingsSchema *schema = g_settings_schema_source_lookup( g_settings_schema_source_get_default(), PREFS_SCHEMA, true); if (schema) { g_settings_schema_unref(schema); page->settings = g_settings_new(PREFS_SCHEMA); gtkhash_properties_prefs_load(page); } else { g_warning("GSettings schema \"" PREFS_SCHEMA "\" not found"); gtkhash_properties_prefs_default_hash_funcs(page); } } void gtkhash_properties_prefs_deinit(struct page_s *page) { if (!page->settings) return; gtkhash_properties_prefs_save(page); g_object_unref(page->settings); page->settings = NULL; } gtkhash-1.5/src/nautilus/properties-prefs.h000066400000000000000000000017701431266303500211350ustar00rootroot00000000000000/* * Copyright (C) 2007-2013 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_NAUTILUS_PROPERTIES_PREFS_H #define GTKHASH_NAUTILUS_PROPERTIES_PREFS_H #include "properties.h" void gtkhash_properties_prefs_init(struct page_s *page); void gtkhash_properties_prefs_deinit(struct page_s *page); #endif gtkhash-1.5/src/nautilus/properties.c000066400000000000000000000454171431266303500200210ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(IN_NAUTILUS_EXTENSION) #if HAVE_NAUTILUS_EXTENSION_H #include #else #include #include #endif #elif defined(IN_CAJA_EXTENSION) #include #include #elif defined(IN_NEMO_EXTENSION) #include #include #include #elif defined(IN_THUNAR_EXTENSION) #undef GTK_DISABLE_DEPRECATED // thunarx-3 doesn't build with this #include #endif #include #include #include #include #include "properties.h" #include "properties-list.h" #include "properties-hash.h" #include "properties-prefs.h" #include "../hash/hash-func.h" #include "../hash/hash-file.h" #define PROPERTIES_XML_RESOURCE "/org/gtkhash/plugin/gtkhash-properties.ui" static GType page_type; static GObject *gtkhash_properties_get_object(GtkBuilder *builder, const char *name) { GObject *obj = gtk_builder_get_object(builder, name); if (!obj) g_warning("unknown object: \"%s\"", name); return obj; } static void gtkhash_properties_busy(struct page_s *page) { page->busy = true; gtk_widget_set_sensitive(GTK_WIDGET(page->treeview), false); gtk_widget_set_sensitive(GTK_WIDGET(page->hbox_inputs), false); // Reset progress bar gtk_progress_bar_set_fraction(page->progressbar, 0.0); gtk_progress_bar_set_text(page->progressbar, " "); gtk_widget_show(GTK_WIDGET(page->progressbar)); // Hash button gtk_widget_hide(GTK_WIDGET(page->button_hash)); gtk_widget_set_sensitive(GTK_WIDGET(page->button_hash), false); // Stop button gtk_widget_set_sensitive(GTK_WIDGET(page->button_stop), true); gtk_widget_show(GTK_WIDGET(page->button_stop)); } static void gtkhash_properties_button_hash_set_sensitive(struct page_s *page) { bool has_enabled = false; for (int i = 0; i < HASH_FUNCS_N; i++) { if (page->funcs[i].enabled) { has_enabled = true; break; } } gtk_widget_set_sensitive(GTK_WIDGET(page->button_hash), has_enabled); } static void gtkhash_properties_entry_hmac_set_sensitive(struct page_s *page) { bool active = gtk_toggle_button_get_active(page->togglebutton_hmac); gtk_widget_set_sensitive(GTK_WIDGET(page->entry_hmac), active); } void gtkhash_properties_idle(struct page_s *page) { page->busy = false; gtk_widget_hide(GTK_WIDGET(page->progressbar)); // Stop button gtk_widget_hide(GTK_WIDGET(page->button_stop)); gtk_widget_set_sensitive(GTK_WIDGET(page->button_stop), false); // Hash button gtkhash_properties_button_hash_set_sensitive(page); gtk_widget_show(GTK_WIDGET(page->button_hash)); gtk_widget_set_sensitive(GTK_WIDGET(page->treeview), true); gtk_widget_set_sensitive(GTK_WIDGET(page->hbox_inputs), true); gtkhash_properties_entry_hmac_set_sensitive(page); gtkhash_properties_list_check_digests(page); } static void gtkhash_properties_on_cell_toggled(struct page_s *page, char *path_str) { gtkhash_properties_list_update_enabled(page, path_str); gtkhash_properties_list_check_digests(page); gtkhash_properties_button_hash_set_sensitive(page); } static void gtkhash_properties_on_treeview_popup_menu(struct page_s *page) { /* Note: Shift+F10 can trigger this, so it's possible for the pointer to be outside the window */ #if GTK_CHECK_VERSION(3,22,0) gtk_menu_popup_at_pointer(page->menu, NULL); #else gtk_menu_popup(page->menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); #endif } static bool gtkhash_properties_on_treeview_button_press_event( struct page_s *page, GdkEventButton *event) { if (gdk_event_triggers_context_menu((GdkEvent *)event)) #if GTK_CHECK_VERSION(3,22,0) gtk_menu_popup_at_pointer(page->menu, (GdkEvent *)event); #else gtk_menu_popup(page->menu, NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent *)event)); #endif return false; } static void gtkhash_properties_on_treeview_row_activated( struct page_s *page, GtkTreePath *path, GtkTreeViewColumn *column, G_GNUC_UNUSED GtkTreeView *treeview) { // Ignore checkbutton column if (!*gtk_tree_view_column_get_title(column)) return; if (!gtk_tree_selection_path_is_selected(page->treeselection, path)) return; if (gtkhash_properties_list_hash_selected(page)) gtkhash_properties_busy(page); } static void gtkhash_properties_on_menu_map_event(struct page_s *page) { bool sensitive = false; char *digest = gtkhash_properties_list_get_selected_digest(page); if (digest) { sensitive = true; g_free(digest); } gtk_widget_set_sensitive(GTK_WIDGET(page->menuitem_copy), sensitive); } static void gtkhash_properties_on_menuitem_copy_activate(struct page_s *page) { GtkClipboard *clipboard = gtk_clipboard_get(GDK_NONE); char *digest = gtkhash_properties_list_get_selected_digest(page); gtk_clipboard_set_text(clipboard, digest, -1); g_free(digest); } static void gtkhash_properties_on_menuitem_show_funcs_toggled( struct page_s *page) { gtkhash_properties_list_refilter(page); } static void gtkhash_properties_on_entry_check_changed(struct page_s *page) { gtkhash_properties_list_check_digests(page); } static void gtkhash_properties_on_entry_check_icon_press(GtkEntry *entry, GtkEntryIconPosition pos, GdkEventButton *event) { if (pos != GTK_ENTRY_ICON_PRIMARY) return; if (event->type != GDK_BUTTON_PRESS) return; if (event->button != 1) return; gtk_entry_set_text(entry, ""); gtk_editable_paste_clipboard(GTK_EDITABLE(entry)); } static void gtkhash_properties_on_entry_hmac_changed(struct page_s *page) { gtkhash_properties_list_clear_digests(page); gtkhash_properties_list_check_digests(page); } static void gtkhash_properties_on_menuitem_show_hmac_key_toggled( GtkCheckMenuItem *item, GtkEntry *entry) { const bool active = gtk_check_menu_item_get_active(item); gtk_entry_set_visibility(entry, active); } static void gtkhash_properties_on_entry_hmac_populate_popup(GtkEntry *entry, GtkMenu *menu) { GtkWidget *item; // Add separator item = gtk_separator_menu_item_new(); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); item = gtk_check_menu_item_new_with_mnemonic(_("_Show HMAC Key")); // Add checkbutton gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), gtk_entry_get_visibility(entry)); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(item, "toggled", G_CALLBACK( gtkhash_properties_on_menuitem_show_hmac_key_toggled), entry); } static void gtkhash_properties_on_togglebutton_hmac_toggled(struct page_s *page) { gtkhash_properties_entry_hmac_set_sensitive(page); gtkhash_properties_list_update_hash_func_names(page); gtkhash_properties_list_check_digests(page); } static void gtkhash_properties_on_button_hash_clicked(struct page_s *page) { gtkhash_properties_busy(page); gtkhash_properties_list_clear_digests(page); if (gtk_toggle_button_get_active(page->togglebutton_hmac)) { const uint8_t *hmac_key = (uint8_t *)gtk_entry_get_text( page->entry_hmac); GtkEntryBuffer *buffer = gtk_entry_get_buffer(page->entry_hmac); const size_t key_size = gtk_entry_buffer_get_bytes(buffer); gtkhash_properties_hash_start(page, NULL, hmac_key, key_size); } else gtkhash_properties_hash_start(page, NULL, NULL, 0); } static void gtkhash_properties_on_button_stop_clicked(struct page_s *page) { gtk_widget_set_sensitive(GTK_WIDGET(page->button_stop), false); gtkhash_properties_hash_stop(page); } static void gtkhash_properties_free_page(struct page_s *page) { gtkhash_properties_hash_stop(page); while (page->busy) gtk_main_iteration(); gtkhash_properties_prefs_deinit(page); gtkhash_properties_hash_deinit(page); g_free(page->uri); g_object_unref(page->menu); g_object_unref(page->box); g_free(page); } static void gtkhash_properties_init_objects(struct page_s *page, GtkBuilder *builder) { // Main container page->box = GTK_WIDGET(gtkhash_properties_get_object(builder, "vbox")); g_object_ref(page->box); // Progress bar page->progressbar = GTK_PROGRESS_BAR(gtkhash_properties_get_object(builder, "progressbar")); // Treeview page->treeview = GTK_TREE_VIEW(gtkhash_properties_get_object(builder, "treeview")); page->treeselection = GTK_TREE_SELECTION(gtkhash_properties_get_object(builder, "treeselection")); page->cellrendtoggle = GTK_CELL_RENDERER_TOGGLE(gtkhash_properties_get_object(builder, "cellrenderertoggle")); // Popup menu page->menu = GTK_MENU(gtkhash_properties_get_object(builder, "menu")); g_object_ref(page->menu); page->menuitem_copy = GTK_MENU_ITEM(gtkhash_properties_get_object(builder, "imagemenuitem_copy")); page->menuitem_show_funcs = GTK_CHECK_MENU_ITEM(gtkhash_properties_get_object(builder, "checkmenuitem_show_funcs")); // Check/MAC inputs page->hbox_inputs = GTK_WIDGET(gtkhash_properties_get_object(builder, "hbox_inputs")); page->entry_check = GTK_ENTRY(gtkhash_properties_get_object(builder, "entry_check")); page->togglebutton_hmac = GTK_TOGGLE_BUTTON(gtkhash_properties_get_object(builder, "togglebutton_hmac")); page->entry_hmac = GTK_ENTRY(gtkhash_properties_get_object(builder, "entry_hmac")); // Buttons page->button_hash = GTK_BUTTON(gtkhash_properties_get_object(builder, "button_hash")); page->button_stop = GTK_BUTTON(gtkhash_properties_get_object(builder, "button_stop")); } static void gtkhash_properties_connect_signals(struct page_s *page) { // Main container g_signal_connect_swapped(page->box, "realize", G_CALLBACK(gtkhash_properties_on_button_hash_clicked), page); g_signal_connect_swapped(page->box, "destroy", G_CALLBACK(gtkhash_properties_free_page), page); // Treeview g_signal_connect_swapped(page->cellrendtoggle, "toggled", G_CALLBACK(gtkhash_properties_on_cell_toggled), page); g_signal_connect_swapped(page->treeview, "popup-menu", G_CALLBACK(gtkhash_properties_on_treeview_popup_menu), page); g_signal_connect_swapped(page->treeview, "button-press-event", G_CALLBACK(gtkhash_properties_on_treeview_button_press_event), page); g_signal_connect_swapped(page->treeview, "row-activated", G_CALLBACK(gtkhash_properties_on_treeview_row_activated), page); // Popup menu g_signal_connect_swapped(page->menu, "map-event", G_CALLBACK(gtkhash_properties_on_menu_map_event), page); g_signal_connect_swapped(page->menuitem_copy, "activate", G_CALLBACK(gtkhash_properties_on_menuitem_copy_activate), page); g_signal_connect_swapped(page->menuitem_show_funcs, "toggled", G_CALLBACK(gtkhash_properties_on_menuitem_show_funcs_toggled), page); // Check g_signal_connect_swapped(page->entry_check, "changed", G_CALLBACK(gtkhash_properties_on_entry_check_changed), page); g_signal_connect(page->entry_check, "icon-press", G_CALLBACK(gtkhash_properties_on_entry_check_icon_press), NULL); // HMAC g_signal_connect_swapped(page->togglebutton_hmac, "toggled", G_CALLBACK(gtkhash_properties_on_togglebutton_hmac_toggled), page); g_signal_connect_swapped(page->entry_hmac, "changed", G_CALLBACK(gtkhash_properties_on_entry_hmac_changed), page); g_signal_connect(page->entry_hmac, "populate-popup", G_CALLBACK(gtkhash_properties_on_entry_hmac_populate_popup), NULL); // Buttons g_signal_connect_swapped(page->button_hash, "clicked", G_CALLBACK(gtkhash_properties_on_button_hash_clicked), page); g_signal_connect_swapped(page->button_stop, "clicked", G_CALLBACK(gtkhash_properties_on_button_stop_clicked), page); } static struct page_s *gtkhash_properties_new_page(char *uri) { GtkBuilder *builder = gtk_builder_new_from_resource(PROPERTIES_XML_RESOURCE); if (!builder) return NULL; struct page_s *page = g_new(struct page_s, 1); page->uri = uri; gtkhash_properties_hash_init(page); if (gtkhash_properties_hash_funcs_supported(page) == 0) { g_warning("no hash functions available"); gtkhash_properties_hash_deinit(page); g_free(page); return NULL; } gtkhash_properties_init_objects(page, builder); g_object_unref(builder); gtkhash_properties_prefs_init(page); gtkhash_properties_list_init(page); gtkhash_properties_idle(page); gtkhash_properties_connect_signals(page); return page; } static GList *gtkhash_properties_get_pages( #if defined(IN_NAUTILUS_EXTENSION) G_GNUC_UNUSED NautilusPropertyPageProvider *provider, #elif defined(IN_CAJA_EXTENSION) G_GNUC_UNUSED CajaPropertyPageProvider *provider, #elif defined(IN_NEMO_EXTENSION) G_GNUC_UNUSED NemoPropertyPageProvider *provider, #elif defined(IN_THUNAR_EXTENSION) G_GNUC_UNUSED ThunarxPropertyPageProvider *provider, #endif GList *files) { // Only display page for a single file if (!files || files->next) return NULL; #if defined(IN_NAUTILUS_EXTENSION) GFileType type = nautilus_file_info_get_file_type(files->data); char *uri = nautilus_file_info_get_uri(files->data); #elif defined(IN_CAJA_EXTENSION) GFileType type = caja_file_info_get_file_type(files->data); char *uri = caja_file_info_get_uri(files->data); #elif defined(IN_NEMO_EXTENSION) GFileType type = nemo_file_info_get_file_type(files->data); char *uri = nemo_file_info_get_uri(files->data); #elif defined(IN_THUNAR_EXTENSION) GFileInfo *info = thunarx_file_info_get_file_info(files->data); GFileType type = g_file_info_get_file_type(info); g_object_unref(info); char *uri = thunarx_file_info_get_uri(files->data); #endif // Only display page for regular files if (type != G_FILE_TYPE_REGULAR) return NULL; struct page_s *page = gtkhash_properties_new_page(uri); if (!page) return NULL; #if defined(IN_NAUTILUS_EXTENSION) NautilusPropertyPage *ppage = nautilus_property_page_new( "GtkHash::properties", gtk_label_new(_("Checksums")), page->box); #elif defined(IN_CAJA_EXTENSION) CajaPropertyPage *ppage = caja_property_page_new( "GtkHash::properties", gtk_label_new(_("Checksums")), page->box); #elif defined(IN_NEMO_EXTENSION) NemoPropertyPage *ppage = nemo_property_page_new( "GtkHash::properties", gtk_label_new(_("Checksums")), page->box); #elif defined(IN_THUNAR_EXTENSION) GtkWidget *ppage = thunarx_property_page_new(_("Checksums")); gtk_container_add(GTK_CONTAINER(ppage), page->box); #endif GList *pages = g_list_append(NULL, ppage); return pages; } static void gtkhash_properties_pp_iface_init( #if defined(IN_NAUTILUS_EXTENSION) NautilusPropertyPageProviderIface *iface, #elif defined(IN_CAJA_EXTENSION) CajaPropertyPageProviderIface *iface, #elif defined(IN_NEMO_EXTENSION) NemoPropertyPageProviderIface *iface, #elif defined(IN_THUNAR_EXTENSION) ThunarxPropertyPageProviderIface *iface, #endif G_GNUC_UNUSED void *data) { iface->get_pages = gtkhash_properties_get_pages; } #ifdef IN_NEMO_EXTENSION static char *gtkhash_properties_nd_string = NULL; static GList *gtkhash_properties_get_name_desc( G_GNUC_UNUSED NemoNameAndDescProvider *provider) { return g_list_append(NULL, gtkhash_properties_nd_string); } static void gtkhash_properties_nd_iface_init(NemoNameAndDescProviderIface *iface, G_GNUC_UNUSED void *data) { iface->get_name_and_desc = gtkhash_properties_get_name_desc; } #endif static void gtkhash_properties_register_type(GTypeModule *module) { const GTypeInfo info = { sizeof(GObjectClass), (GBaseInitFunc)NULL, (GBaseFinalizeFunc)NULL, (GClassInitFunc)NULL, (GClassFinalizeFunc)NULL, NULL, sizeof(GObject), 0, (GInstanceInitFunc)NULL, (GTypeValueTable *)NULL }; page_type = g_type_module_register_type(module, G_TYPE_OBJECT, "GtkHash", &info, 0); const GInterfaceInfo pp_iface_info = { (GInterfaceInitFunc)gtkhash_properties_pp_iface_init, (GInterfaceFinalizeFunc)NULL, NULL }; g_type_module_add_interface(module, page_type, #if defined(IN_NAUTILUS_EXTENSION) NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER, #elif defined(IN_CAJA_EXTENSION) CAJA_TYPE_PROPERTY_PAGE_PROVIDER, #elif defined(IN_NEMO_EXTENSION) NEMO_TYPE_PROPERTY_PAGE_PROVIDER, #elif defined(IN_THUNAR_EXTENSION) THUNARX_TYPE_PROPERTY_PAGE_PROVIDER, #endif &pp_iface_info); #ifdef IN_NEMO_EXTENSION const GInterfaceInfo nd_iface_info = { (GInterfaceInitFunc)gtkhash_properties_nd_iface_init, (GInterfaceFinalizeFunc)NULL, NULL }; g_type_module_add_interface(module, page_type, NEMO_TYPE_NAME_AND_DESC_PROVIDER, &nd_iface_info); #endif } #if __GNUC__ #define PUBLIC __attribute__((visibility("default"))) #else #define PUBLIC G_MODULE_EXPORT #endif #if defined(IN_NAUTILUS_EXTENSION) PUBLIC void nautilus_module_initialize(GTypeModule *module) #elif defined(IN_CAJA_EXTENSION) PUBLIC void caja_module_initialize(GTypeModule *module) #elif defined(IN_NEMO_EXTENSION) PUBLIC void nemo_module_initialize(GTypeModule *module) #elif defined(IN_THUNAR_EXTENSION) PUBLIC void thunar_extension_initialize(GTypeModule *module); PUBLIC void thunar_extension_initialize(GTypeModule *module) #endif { gtkhash_properties_register_type(module); #if ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); #endif #ifdef IN_NEMO_EXTENSION gtkhash_properties_nd_string = g_strdup_printf("GtkHash:::%s", _("Calculate message digests or checksums")); #endif } #if defined(IN_NAUTILUS_EXTENSION) PUBLIC void nautilus_module_shutdown(void) #elif defined(IN_CAJA_EXTENSION) PUBLIC void caja_module_shutdown(void) #elif defined(IN_NEMO_EXTENSION) PUBLIC void nemo_module_shutdown(void) #elif defined(IN_THUNAR_EXTENSION) PUBLIC void thunar_extension_shutdown(void); PUBLIC void thunar_extension_shutdown(void) #endif { #ifdef IN_NEMO_EXTENSION g_free(gtkhash_properties_nd_string); gtkhash_properties_nd_string = NULL; #endif } #if defined(IN_NAUTILUS_EXTENSION) PUBLIC void nautilus_module_list_types(const GType **types, int *num_types) #elif defined(IN_CAJA_EXTENSION) PUBLIC void caja_module_list_types(const GType **types, int *num_types) #elif defined(IN_NEMO_EXTENSION) PUBLIC void nemo_module_list_types(const GType **types, int *num_types) #elif defined(IN_THUNAR_EXTENSION) PUBLIC void thunar_extension_list_types(const GType **types, int *num_types); PUBLIC void thunar_extension_list_types(const GType **types, int *num_types) #endif { static GType type_list[1]; type_list[0] = page_type; *types = type_list; *num_types = G_N_ELEMENTS(type_list); } gtkhash-1.5/src/nautilus/properties.h000066400000000000000000000030041431266303500200100ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_NAUTILUS_PROPERTIES_H #define GTKHASH_NAUTILUS_PROPERTIES_H #include #include "../hash/hash-file.h" #if ENABLE_NLS #include #else #define _(STR) (STR) #endif struct page_s { GSettings *settings; char *uri; GtkWidget *box, *hbox_inputs; GtkProgressBar *progressbar; GtkTreeView *treeview; GtkTreeSelection *treeselection; GtkCellRendererToggle *cellrendtoggle; GtkMenu *menu; GtkMenuItem *menuitem_copy; GtkCheckMenuItem *menuitem_show_funcs; GtkToggleButton *togglebutton_hmac; GtkEntry *entry_check, *entry_hmac; GtkButton *button_hash, *button_stop; struct hash_file_s *hfile; struct hash_func_s funcs[HASH_FUNCS_N]; bool busy; }; void gtkhash_properties_idle(struct page_s *page); #endif gtkhash-1.5/src/opts.c000066400000000000000000000112361431266303500147360ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "opts.h" #include "main.h" #include "hash.h" #include "gui.h" #include "list.h" #include "prefs.h" #include "check.h" #include "uri-digest.h" static struct { const char *check; const char **check_files; const char *text; const char **funcs; const char **files; gboolean version; } opts = { .check = NULL, .check_files = NULL, .text = NULL, .funcs = NULL, .files = NULL, .version = false, }; static void free_opts(void) { if (opts.check) { g_free((void *)opts.check); opts.check = NULL; } if (opts.check_files) { g_strfreev((char **)opts.check_files); opts.check_files = NULL; } if (opts.text) { g_free((void *)opts.text); opts.text = NULL; } if (opts.funcs) { g_strfreev((char **)opts.funcs); opts.funcs = NULL; } if (opts.files) { g_strfreev((char **)opts.files); opts.files = NULL; } } static char *filename_arg_to_uri(const char * const arg) { GFile *file = g_file_new_for_commandline_arg(arg); char *uri = g_file_get_uri(file); g_object_unref(file); return uri; } void opts_preinit(int *argc, char ***argv) { GOptionEntry entries[] = { { "check", 'c', 0, G_OPTION_ARG_STRING, &opts.check, C_(PACKAGE " --help", "Check against the specified digest or checksum"), C_(PACKAGE " --help", "DIGEST") }, { "check-file", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &opts.check_files, C_(PACKAGE " --help", "Check digests or checksums from the specified file"), C_(PACKAGE " --help", "FILE|URI") }, { "function", 'f', 0, G_OPTION_ARG_STRING_ARRAY, &opts.funcs, C_(PACKAGE " --help", "Enable the specified Hash Function (e.g. MD5)"), C_(PACKAGE " --help", "FUNCTION") }, { "text", 't', 0, G_OPTION_ARG_STRING, &opts.text, C_(PACKAGE " --help", "Hash the specified text"), C_(PACKAGE " --help", "TEXT") }, { "version", 'v', 0, G_OPTION_ARG_NONE, &opts.version, C_(PACKAGE " --help", "Show version information"), NULL }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opts.files, // Translators: Unicode ellipsis(…) can be used here NULL, C_(PACKAGE " --help", "[FILE|URI...]") }, { NULL, 0, 0, 0, NULL, NULL, NULL } }; GOptionContext *context = g_option_context_new(NULL); GError *error = NULL; g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); g_option_context_add_group(context, gtk_get_option_group(false)); g_option_context_parse(context, argc, argv, &error); g_option_context_free(context); if (error) { g_warning("%s", error->message); g_error_free(error); free_opts(); exit(EXIT_FAILURE); } if (opts.version) { const char *snap_version = NULL; if (g_strcmp0(g_getenv("SNAP_NAME"), PACKAGE) == 0) snap_version = g_getenv("SNAP_VERSION"); printf("%s %s\n", PACKAGE_NAME, snap_version ? snap_version : VERSION); free_opts(); exit(EXIT_SUCCESS); } if (opts.funcs) hash_funcs_enable_strv(opts.funcs); } void opts_postinit(void) { if (opts.check && *opts.check) gui_add_check(opts.check); GSList *ud_list = NULL; if (opts.check_files) { for (int i = 0; opts.check_files[i]; i++) { GFile *file = g_file_new_for_commandline_arg(opts.check_files[i]); ud_list = check_file_load(ud_list, file); g_object_unref(file); } } if (opts.files) { for (int i = 0; opts.files[i]; i++) { struct uri_digest_s *ud = uri_digest_new(filename_arg_to_uri(opts.files[i]), NULL); ud_list = g_slist_prepend(ud_list, ud); } } bool files_added = false; if (ud_list) { ud_list = g_slist_reverse(ud_list); files_added = gui_add_ud_list(ud_list, GUI_VIEW_INVALID); uri_digest_list_free_full(ud_list); } if (files_added) { gui_update(); gui_start_hash(); } else if (opts.text) { gui_add_text(opts.text); } else if (GUI_VIEW_IS_VALID(gui.view)) { // view was loaded from prefs gui_update(); } free_opts(); } gtkhash-1.5/src/opts.h000066400000000000000000000016071431266303500147440ustar00rootroot00000000000000/* * Copyright (C) 2007-2019 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_OPTS_H #define GTKHASH_OPTS_H void opts_preinit(int *argc, char ***argv); void opts_postinit(void); #endif gtkhash-1.5/src/prefs.c000066400000000000000000000156371431266303500151010ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "prefs.h" #include "main.h" #include "hash.h" #include "gui.h" #include "hash/digest-format.h" #include "hash/hash-func.h" #define PREFS_SCHEMA "org.gtkhash" #define PREFS_KEY_DIGEST_FORMAT "digest-format" #define PREFS_KEY_HASH_FUNCS "hash-functions" #define PREFS_KEY_SHOW_HMAC "show-hmac" #define PREFS_KEY_SHOW_TOOLBAR "show-toolbar" #define PREFS_KEY_VIEW "view" #define PREFS_KEY_WINDOW_HEIGHT "window-height" #define PREFS_KEY_WINDOW_MAX "window-max" #define PREFS_KEY_WINDOW_WIDTH "window-width" #define PREFS_BIND_FLAGS \ (G_SETTINGS_BIND_DEFAULT | \ G_SETTINGS_BIND_GET_NO_CHANGES) static struct { GSettings *settings; } prefs_priv = { .settings = NULL, }; static void default_hash_funcs(void) { // Some funcs could already be enabled by cmdline arg if (hash_funcs_count_enabled()) return; bool has_enabled = false; // Try to enable default functions for (int i = 0; i < HASH_FUNCS_N; i++) { if (HASH_FUNC_IS_DEFAULT(i) && hash.funcs[i].supported) { gui_enable_hash_func(i); has_enabled = true; } } if (has_enabled) return; // Try to enable any supported function for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].supported) { gui_enable_hash_func(i); return; } } gui_error(_("Failed to enable any supported hash functions.")); exit(EXIT_FAILURE); } static void default_show_widgets(void) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( gui.dialog_togglebutton_show_hmac), false); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM( gui.menuitem_treeview_show_toolbar), true); } static void prefs_default(void) { default_hash_funcs(); default_show_widgets(); } static void load_hash_funcs(void) { char **strv = g_settings_get_strv(prefs_priv.settings, PREFS_KEY_HASH_FUNCS); bool enabled = false; for (int i = 0; strv[i]; i++) { enum hash_func_e id = gtkhash_hash_func_get_id_from_name(strv[i]); if (HASH_FUNC_IS_VALID(id) && hash.funcs[id].supported) { gui_enable_hash_func(id); enabled = true; } else g_message(_("Unknown Hash Function name \"%s\""), strv[i]); } g_strfreev(strv); if (!enabled) default_hash_funcs(); } static void load_digest_format(void) { char *str = g_settings_get_string(prefs_priv.settings, PREFS_KEY_DIGEST_FORMAT); if (!str) return; enum digest_format_e format = DIGEST_FORMAT_INVALID; if (strcmp(str, "hex-lower") == 0) format = DIGEST_FORMAT_HEX_LOWER; else if (strcmp(str, "hex-upper") == 0) format = DIGEST_FORMAT_HEX_UPPER; else if (strcmp(str, "base64") == 0) format = DIGEST_FORMAT_BASE64; g_free(str); if (DIGEST_FORMAT_IS_VALID(format)) gui_set_digest_format(format); } static void load_view(void) { char *str = g_settings_get_string(prefs_priv.settings, PREFS_KEY_VIEW); if (!str) return; if (strcmp(str, "file") == 0) gui_set_view(GUI_VIEW_FILE); else if (strcmp(str, "text") == 0) gui_set_view(GUI_VIEW_TEXT); else if (strcmp(str, "file-list") == 0) gui_set_view(GUI_VIEW_FILE_LIST); g_free(str); } static void load_show_widgets(void) { g_settings_bind(prefs_priv.settings, PREFS_KEY_SHOW_HMAC, gui.dialog_togglebutton_show_hmac, "active", PREFS_BIND_FLAGS); g_settings_bind(prefs_priv.settings, PREFS_KEY_SHOW_TOOLBAR, gui.menuitem_treeview_show_toolbar, "active", PREFS_BIND_FLAGS); } static void load_window_size(void) { if (g_settings_get_boolean(prefs_priv.settings, PREFS_KEY_WINDOW_MAX)) { gtk_window_maximize(gui.window); return; } int width = g_settings_get_int(prefs_priv.settings, PREFS_KEY_WINDOW_WIDTH); int height = g_settings_get_int(prefs_priv.settings, PREFS_KEY_WINDOW_HEIGHT); if ((width > 0) && (height > 0)) gtk_window_resize(gui.window, width, height); } static void prefs_load(void) { g_assert(prefs_priv.settings); load_hash_funcs(); load_digest_format(); load_view(); load_show_widgets(); load_window_size(); } static void save_hash_funcs(void) { const char **strv = NULL; int enabled = hash_funcs_count_enabled(); if (enabled > 0) { strv = g_new0(const char *, enabled + 1); for (int i = 0, j = 0; (i < HASH_FUNCS_N) && (j < enabled); i++) { if (hash.funcs[i].enabled) { strv[j] = hash.funcs[i].name; j++; } } } g_settings_set_strv(prefs_priv.settings, PREFS_KEY_HASH_FUNCS, strv); if (strv) g_free(strv); } static void save_digest_format(void) { const char *str = NULL; switch (gui_get_digest_format()) { case DIGEST_FORMAT_HEX_LOWER: str = "hex-lower"; break; case DIGEST_FORMAT_HEX_UPPER: str = "hex-upper"; break; case DIGEST_FORMAT_BASE64: str = "base64"; break; default: g_assert_not_reached(); } g_settings_set_string(prefs_priv.settings, PREFS_KEY_DIGEST_FORMAT, str); } static void save_view(void) { const char *str = NULL; switch (gui.view) { case GUI_VIEW_FILE: str = "file"; break; case GUI_VIEW_TEXT: str = "text"; break; case GUI_VIEW_FILE_LIST: str = "file-list"; break; default: g_assert_not_reached(); } g_settings_set_string(prefs_priv.settings, PREFS_KEY_VIEW, str); } static void save_window_size(void) { bool max = gui_is_maximised(); g_settings_set_boolean(prefs_priv.settings, PREFS_KEY_WINDOW_MAX, max); if (max) return; int width, height; gtk_window_get_size(gui.window, &width, &height); g_settings_set_int(prefs_priv.settings, PREFS_KEY_WINDOW_HEIGHT, height); g_settings_set_int(prefs_priv.settings, PREFS_KEY_WINDOW_WIDTH, width); } static void prefs_save(void) { g_assert(prefs_priv.settings); save_hash_funcs(); save_digest_format(); save_view(); save_window_size(); } void prefs_init(void) { g_assert(!prefs_priv.settings); GSettingsSchema *schema = g_settings_schema_source_lookup( g_settings_schema_source_get_default(), PREFS_SCHEMA, true); if (schema) { g_settings_schema_unref(schema); prefs_priv.settings = g_settings_new(PREFS_SCHEMA); prefs_load(); } else { g_warning("GSettings schema \"" PREFS_SCHEMA "\" not found - using default preferences"); prefs_default(); } } void prefs_deinit(void) { if (!prefs_priv.settings) return; prefs_save(); g_object_unref(prefs_priv.settings); prefs_priv.settings = NULL; } gtkhash-1.5/src/prefs.h000066400000000000000000000015631431266303500150770ustar00rootroot00000000000000/* * Copyright (C) 2007-2013 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_PREFS_H #define GTKHASH_PREFS_H void prefs_init(void); void prefs_deinit(void); #endif gtkhash-1.5/src/test.c000066400000000000000000000655101431266303500147340ustar00rootroot00000000000000/* * Copyright (C) 2007-2021 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #undef G_DISABLE_ASSERT #undef G_DISABLE_CAST_CHECKS #include #include #include "callbacks.h" #include "check.h" #include "gui.h" #include "hash.h" #include "list.h" #include "opts.h" #include "hash/hash-func.h" #ifndef G_SOURCE_FUNC #define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f)) #endif static void delay(void) { for (int i = 0; i < 10; i++) { while (gtk_events_pending()) gtk_main_iteration(); g_usleep(G_USEC_PER_SEC / 250); } } static void select_gui_view(const enum gui_view_e view) { gui_set_view(view); delay(); } static void select_hash_func(const enum hash_func_e id, const bool active) { if (hash.funcs[id].enabled == active) return; gtk_toggle_button_set_active(gui.hash_widgets[id].button, active); delay(); g_assert_true(hash.funcs[id].enabled == active); } static void select_digest_format(const enum digest_format_e format) { gui_set_digest_format(format); delay(); g_assert_true(gui_get_digest_format() == format); } static void test_hash_func_digest(const enum hash_func_e id, const char *text, const char *hmac, const char *digest) { gtk_entry_set_text(gui.entry_check_text, digest); gtk_entry_set_text(gui.entry_text, text); if (hmac) { gtk_toggle_button_set_active(gui.dialog_togglebutton_show_hmac, true); gtk_toggle_button_set_active(gui.togglebutton_hmac_text, true); gtk_entry_set_text(gui.entry_hmac_text, hmac); } else { gtk_toggle_button_set_active(gui.dialog_togglebutton_show_hmac, false); gtk_toggle_button_set_active(gui.togglebutton_hmac_text, false); gtk_entry_set_text(gui.entry_hmac_text, ""); } delay(); const char *output = gtk_entry_get_text(gui.hash_widgets[id].entry_text); g_assert_cmpstr(output, ==, digest); } static void test_hash_func(const struct hash_func_s *func) { if (!func->supported) { g_test_skip("not supported"); return; } bool tested = false; #define t(FUNC, TEXT, DIGEST) \ if (func->id == G_PASTE(HASH_FUNC_, FUNC)) { \ select_hash_func(func->id, true); \ test_hash_func_digest(func->id, TEXT, NULL, DIGEST); \ tested = true; \ } t(ADLER32, "", "00000001"); t(BLAKE2B, "", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"); t(BLAKE2S, "", "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"); t(BLAKE2BP, "", "b5ef811a8038f70b628fa8b294daae7492b1ebe343a80eaabbf1f6ae664dd67b9d90b0120791eab81dc96985f28849f6a305186a85501b405114bfa678df9380"); t(BLAKE2SP, "", "dd0e891776933f43c7d032b08a917e25741f8aa9a12c12e1cac8801500f2ca4f"); t(CRC32, "", "00000000"); t(CRC32C, "", "00000000"); t(GOST, "", "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d"); t(MD2, "", "8350e5a3e24c153df2275c9f80692773"); t(MD4, "", "31d6cfe0d16ae931b73c59d7e0c089c0"); t(MD5, "", "d41d8cd98f00b204e9800998ecf8427e"); t(MD6_224, "", "d2091aa2ad17f38c51ade2697f24cafc3894c617c77ffe10fdc7abcb"); t(MD6_256, "", "bca38b24a804aa37d821d31af00f5598230122c5bbfc4c4ad5ed40e4258f04ca"); t(MD6_384, "", "b0bafffceebe856c1eff7e1ba2f539693f828b532ebf60ae9c16cbc3499020401b942ac25b310b2227b2954ccacc2f1f"); t(MD6_512, "", "6b7f33821a2c060ecdd81aefddea2fd3c4720270e18654f4cb08ece49ccb469f8beeee7c831206bd577f9f2630d9177979203a9489e47e04df4e6deaa0f8e0c0"); t(RIPEMD128, "", "cdf26213a150dc3ecb610f18f6b38b46"); t(RIPEMD160, "", "9c1185a5c5e9fc54612808977ee8f548b2258d31"); t(RIPEMD256, "", "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"); t(RIPEMD320, "", "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"); t(SHA1, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); t(SHA224, "", "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"); t(SHA256, "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); t(SHA384, "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"); t(SHA512, "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"); t(SHA3_224, "", "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"); t(SHA3_256, "", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); t(SHA3_384, "", "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"); t(SHA3_512, "", "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"); t(SM3, "", "1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b"); t(TIGER192, "", "24f0130c63ac933216166e76b1bb925ff373de2d49584e7a"); t(WHIRLPOOL, "", "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"); t(XXH64, "", "ef46db3751d8e999"); t(CRC32, "The quick brown fox jumps over the lazy dog", "414fa339"); t(CRC32C, "The quick brown fox jumps over the lazy dog", "22620404"); t(BLAKE2B, "The quick brown fox jumps over the lazy dog", "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918"); t(GOST, "The quick brown fox jumps over the lazy dog", "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294"); t(MD2, "The quick brown fox jumps over the lazy dog", "03d85a0d629d2c442e987525319fc471"); t(MD4, "The quick brown fox jumps over the lazy dog", "1bee69a46ba811185c194762abaeae90"); t(MD5, "The quick brown fox jumps over the lazy dog", "9e107d9d372bb6826bd81d3542a419d6"); t(RIPEMD160, "The quick brown fox jumps over the lazy dog", "37f332f68db77bd9d7edd4969571ad671cf9dd3b"); t(SHA1, "The quick brown fox jumps over the lazy dog", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"); t(SHA224, "The quick brown fox jumps over the lazy dog", "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525"); t(SHA256, "The quick brown fox jumps over the lazy dog", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"); t(SHA384, "The quick brown fox jumps over the lazy dog", "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1"); t(SHA512, "The quick brown fox jumps over the lazy dog", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6"); t(SHA3_224, "The quick brown fox jumps over the lazy dog", "d15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795"); t(SHA3_256, "The quick brown fox jumps over the lazy dog", "69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04"); t(SHA3_384, "The quick brown fox jumps over the lazy dog", "7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41"); t(SHA3_512, "The quick brown fox jumps over the lazy dog", "01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450"); t(WHIRLPOOL, "The quick brown fox jumps over the lazy dog", "b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35"); t(XXH64, "The quick brown fox jumps over the lazy dog", "0b242d361fda71bc"); t(RIPEMD128, "message digest", "9e327b3d6e523062afc1132d7df9d1b8"); t(RIPEMD160, "message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"); t(RIPEMD256, "message digest", "87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e"); t(RIPEMD320, "message digest", "3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197"); t(WHIRLPOOL, "message digest", "378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b8421557659ef55c106b4b52ac5a4aaa692ed920052838f3362e86dbd37a8903e"); t(ADLER32, "abc", "024d0127"); t(CRC32, "abc", "352441c2"); t(SM3, "abc", "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0"); t(TIGER192, "abc", "f258c1e88414ab2a527ab541ffc5b8bf935f7b951c132951"); t(CRC32, "123456789", "cbf43926"); t(CRC32C, "123456789", "e3069283"); t(SM3, "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", "debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732"); #undef t if (!tested) g_test_incomplete("not implemented"); select_hash_func(func->id, false); } static void test_hash_func_hmac(const struct hash_func_s *func) { if (!func->supported || !func->hmac_supported) { g_test_skip("not supported"); return; } bool tested = false; #define t(FUNC, TEXT, HMAC, DIGEST) \ if (func->id == G_PASTE(HASH_FUNC_, FUNC)) { \ select_hash_func(func->id, true); \ test_hash_func_digest(func->id, TEXT, HMAC, DIGEST); \ tested = true; \ } // RFC 2202 t(MD5, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "9294727a3638bb1c13f48ef8158bfc9d"); t(MD5, "what do ya want for nothing?", "Jefe", "750c783e6ab0b503eaa86e310a5db738"); t(SHA1, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "b617318655057264e28bc0b6fb378c8ef146be00"); t(SHA1, "what do ya want for nothing?", "Jefe", "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"); // RFC 2286 t(RIPEMD128, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "fbf61f9492aa4bbf81c172e84e0734db"); t(RIPEMD128, "what do ya want for nothing?", "Jefe", "875f828862b6b334b427c55f9f7ff09b"); t(RIPEMD160, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "24cb4bd67d20fc1a5d2ed7732dcc39377f0a5668"); t(RIPEMD160, "what do ya want for nothing?", "Jefe", "dda6c0213a485a9e24f4742064a7f033b43c4069"); // RFC 4231 t(SHA224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"); t(SHA224, "what do ya want for nothing?", "Jefe", "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44"); t(SHA224, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1"); t(SHA256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); t(SHA256, "what do ya want for nothing?", "Jefe", "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); t(SHA256, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"); t(SHA384, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"); t(SHA384, "what do ya want for nothing?", "Jefe", "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649"); t(SHA384, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e"); t(SHA512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"); t(SHA512, "what do ya want for nothing?", "Jefe", "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737"); t(SHA512, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); // http://wolfgang-ehrhardt.de/hmac-sha3-testvectors.html t(SHA3_224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "3b16546bbc7be2706a031dcafd56373d9884367641d8c59af3c860f7"); t(SHA3_224, "what do ya want for nothing?", "Jefe", "7fdb8dd88bd2f60d1b798634ad386811c2cfc85bfaf5d52bbace5e66"); t(SHA3_256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "ba85192310dffa96e2a3a40e69774351140bb7185e1202cdcc917589f95e16bb"); t(SHA3_256, "what do ya want for nothing?", "Jefe", "c7d4072e788877ae3596bbb0da73b887c9171f93095b294ae857fbe2645e1ba5"); t(SHA3_384, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "68d2dcf7fd4ddd0a2240c8a437305f61fb7334cfb5d0226e1bc27dc10a2e723a20d370b47743130e26ac7e3d532886bd"); t(SHA3_384, "what do ya want for nothing?", "Jefe", "f1101f8cbf9766fd6764d2ed61903f21ca9b18f57cf3e1a23ca13508a93243ce48c045dc007f26a21b3f5e0e9df4c20a"); t(SHA3_512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "eb3fbd4b2eaab8f5c504bd3a41465aacec15770a7cabac531e482f860b5ec7ba47ccb2c6f2afce8f88d22b6dc61380f23a668fd3888bb80537c0a0b86407689e"); t(SHA3_512, "what do ya want for nothing?", "Jefe", "5a4bfeab6166427c7a3647b747292b8384537cdb89afb3bf5665e4c5e709350b287baec921fd7ca0ee7a0c31d022a95e1fc92ba9d77df883960275beb4e62024"); // https://docs.python.org/3/library/hashlib.html t(BLAKE2S, "message", "secret key", "e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142"); t(BLAKE2S, "", "", "eaf4bb25938f4d20e72656bbbc7a9bf63c0c18537333c35bdb67db1402661acd"); t(BLAKE2S, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "cb60f6a791f140bf8aa2e51ff358cdb2cc5c0333045b7fb77aba7ab3b0cfb237"); t(BLAKE2B, "", "", "198cd2006f66ff83fbbd913f78aca2251caf4f19fe9475aade8cf2091b99a68466775177424f58286886cbae8229644cec747237d4b721735485e17372fdf59c"); t(BLAKE2B, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", "ab347980a64b5e825dd10e7d32fd43a01a8e6dea267ab9ad7d913524526618925311afbcb0c49519cbebdd709540a8d725fb911ac2aee9b2a3aa43d796123393"); #undef t if (!tested) g_test_incomplete("not implemented"); select_hash_func(func->id, false); } static void test_opt_help(void) { if (g_test_subprocess()) { gint argc; char **argv; g_shell_parse_argv("t --help", &argc, &argv, NULL); opts_preinit(&argc, &argv); exit(EXIT_FAILURE); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("*--help*"); g_test_trap_assert_stdout("*--version*"); } static void test_opt_version(void) { if (g_test_subprocess()) { gint argc; char **argv; g_shell_parse_argv("t --version", &argc, &argv, NULL); opts_preinit(&argc, &argv); exit(EXIT_FAILURE); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout(PACKAGE_STRING "*"); } static void test_opt_check_text(void) { if (g_test_subprocess()) { gint argc; char **argv; g_shell_parse_argv("t -c fail -t aa --check 0123abcdef", &argc, &argv, NULL); opts_preinit(&argc, &argv); opts_postinit(); delay(); puts(gtk_entry_get_text(gui.entry_check_text)); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("0123abcdef*"); } static void test_opt_check_file(void) { if (g_test_subprocess()) { gint argc; char **argv; char *args = g_strdup_printf("t --check-file '%s'", g_test_get_filename(G_TEST_BUILT, "test.md5sum", NULL)); g_shell_parse_argv(args, &argc, &argv, NULL); g_free(args); opts_preinit(&argc, &argv); opts_postinit(); delay(); g_assert(hash.funcs[HASH_FUNC_MD5].supported); g_assert(hash.funcs[HASH_FUNC_MD5].enabled); g_assert(gui.view == GUI_VIEW_FILE_LIST); g_assert(list.rows == 9); // OK to exit before finish, with warnings g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*"); gdk_threads_add_timeout_seconds(2, G_SOURCE_FUNC(exit), NULL); for (;;) gtk_main_iteration_do(false); exit(EXIT_FAILURE); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stderr("*notfound.bytes*"); } static void test_opt_function(void) { if (g_test_subprocess()) { enum hash_func_e id = HASH_FUNC_INVALID; // Select first available function for the test for (int i = 0; i < HASH_FUNCS_N; i++) { if (hash.funcs[i].supported) { id = i; break; } } if (id == HASH_FUNC_INVALID) exit(EXIT_FAILURE); // Disable the function gtk_toggle_button_set_active(gui.hash_widgets[id].button, false); delay(); if (hash.funcs[id].enabled) exit(EXIT_FAILURE); // Enable the function from cmdline char *str = g_strdup_printf("%s %s", "t --function XX -f", hash.funcs[id].name); gint argc; char **argv; g_shell_parse_argv(str, &argc, &argv, NULL); opts_preinit(&argc, &argv); if (hash.funcs[id].enabled) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stderr("*Unknown*XX*"); } static void test_opt_file(void) { if (g_test_subprocess()) { gint argc; char **argv; char *args = g_strdup_printf("t -- '%s'", g_test_get_filename(G_TEST_BUILT, "10M.bytes", NULL)); g_shell_parse_argv(args, &argc, &argv, NULL); g_free(args); select_hash_func(HASH_FUNC_MD5, true); opts_preinit(&argc, &argv); opts_postinit(); delay(); g_assert(gui.view == GUI_VIEW_FILE); // Started from cmdline while (!*gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)) gtk_main_iteration_do(false); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)); // Started from Hash button gtk_button_clicked(gui.button_hash); delay(); while (!*gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)) gtk_main_iteration_do(false); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)); // Started from function label gtk_button_clicked(GTK_BUTTON(gui.hash_widgets[HASH_FUNC_MD5].label_file)); delay(); while (!*gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)) gtk_main_iteration_do(false); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_file)); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout( "*f1c9645dbc14efddc7d8a322685f26eb*" "*f1c9645dbc14efddc7d8a322685f26eb*" "*f1c9645dbc14efddc7d8a322685f26eb*"); } static void test_opt_file_list(void) { if (g_test_subprocess()) { gint argc; char **argv; char *args = g_strdup_printf("t -- '%s' '%s'", g_test_get_filename(G_TEST_BUILT, "0.bytes", NULL), g_test_get_filename(G_TEST_BUILT, "0.bytes", NULL)); g_shell_parse_argv(args, &argc, &argv, NULL); g_free(args); select_hash_func(HASH_FUNC_MD5, true); opts_preinit(&argc, &argv); opts_postinit(); delay(); g_assert(gui.view == GUI_VIEW_FILE_LIST); g_assert(list.rows == 2); char *digest; while (!(digest = list_get_digest(1, HASH_FUNC_MD5)) || !*digest) gtk_main_iteration_do(false); puts(digest); g_free(digest); gtk_tree_selection_select_all(gui.treeselection); delay(); list_remove_selection(); delay(); g_assert(list.rows == 0); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("*d41d8cd98f00b204e9800998ecf8427e*"); } static void test_digest_format_hex_lower() { if (g_test_subprocess()) { select_gui_view(GUI_VIEW_TEXT); select_hash_func(HASH_FUNC_MD5, true); select_digest_format(DIGEST_FORMAT_HEX_LOWER); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_text)); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("*d41d8cd98f00b204e9800998ecf8427e*"); } static void test_digest_format_hex_upper() { if (g_test_subprocess()) { select_gui_view(GUI_VIEW_TEXT); select_hash_func(HASH_FUNC_MD5, true); select_digest_format(DIGEST_FORMAT_HEX_UPPER); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_text)); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("*D41D8CD98F00B204E9800998ECF8427E*"); } static void test_digest_format_base64() { if (g_test_subprocess()) { select_gui_view(GUI_VIEW_TEXT); select_hash_func(HASH_FUNC_MD5, true); select_digest_format(DIGEST_FORMAT_BASE64); puts(gtk_entry_get_text(gui.hash_widgets[HASH_FUNC_MD5].entry_text)); exit(EXIT_SUCCESS); } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_passed(); g_test_trap_assert_stdout("*1B2M2Y8AsgTpgAmY7PhCfg==*"); } static void test_init(void) { select_gui_view(GUI_VIEW_TEXT); const char * const lib = g_getenv("GTKHASH_TEST_LIB"); // Test plain hash for (int i = 0; i < HASH_FUNCS_N; i++) { if (lib && !hash.funcs[i].supported) continue; char *path = g_strdup_printf("/hash/lib/%s/%s", lib ? lib : "any", hash.funcs[i].name); g_test_add_data_func(path, &hash.funcs[i], (GTestDataFunc)test_hash_func); g_free(path); } // Test HMAC for (int i = 0; i < HASH_FUNCS_N; i++) { if (lib && (!hash.funcs[i].supported || !hash.funcs[i].hmac_supported)) continue; char *path = g_strdup_printf("/hash/lib/%s/HMAC-%s", lib ? lib : "any", hash.funcs[i].name); g_test_add_data_func(path, &hash.funcs[i], (GTestDataFunc)test_hash_func_hmac); g_free(path); } if (lib) return; // Test cmdline options g_test_add_func("/opt/help", test_opt_help); g_test_add_func("/opt/version", test_opt_version); g_test_add_func("/opt/check/text", test_opt_check_text); g_test_add_func("/opt/check/file", test_opt_check_file); g_test_add_func("/opt/function", test_opt_function); g_test_add_func("/opt/file", test_opt_file); g_test_add_func("/opt/file-list", test_opt_file_list); // Test digest formats g_test_add_func("/digest-format/base64", test_digest_format_base64); g_test_add_func("/digest-format/hex-lower", test_digest_format_hex_lower); g_test_add_func("/digest-format/hex-upper", test_digest_format_hex_upper); } int main(int argc, char **argv) { gtk_test_init(&argc, &argv); hash_init(); gui_init(); check_init(); // Ignore user input during testing gtk_widget_set_sensitive(GTK_WIDGET(gui.window), false); gtk_widget_set_sensitive(GTK_WIDGET(gui.dialog), false); gtk_widget_show_now(GTK_WIDGET(gui.window)); gtk_widget_show_now(GTK_WIDGET(gui.dialog)); callbacks_init(); test_init(); g_test_set_nonfatal_assertions(); const int status = g_test_run(); check_deinit(); gui_deinit(); hash_deinit(); return status; } gtkhash-1.5/src/test.md5sum.in000066400000000000000000000011041431266303500163160ustar00rootroot00000000000000# GNU d41d8cd98f00b204e9800998ecf8427e @builddir@/0.bytes 93b885adfe0da089cdf634904fd59f71 @builddir@/1.bytes f1c9645dbc14efddc7d8a322685f26eb @builddir@/10M.bytes ec4bcc8776ea04479b786e063a9ace45 @builddir@/5G.bytes # GNU (binary) badbadbadbadbadbadbadbadbadbadbad *@builddir@/0.bytes 93b885adfe0da089cdf634904fd59f71 *@builddir@/1.bytes f1c9645dbc14efddc7d8a322685f26eb *@builddir@/10M.bytes # BSD MD5 (@builddir@/0.bytes) = d41d8cd98f00b204e9800998ecf8427e MD5 (@builddir@/1.bytes) = 93b885adfe0da089cdf634904fd59f71 MD5 (notfound.bytes) = d41d8cd98f00b204e9800998ecf8427e gtkhash-1.5/src/uri-digest.c000066400000000000000000000037101431266303500160230ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "uri-digest.h" struct uri_digest_s *uri_digest_new(char *uri, char *digest) { struct uri_digest_s *ud = g_new(struct uri_digest_s, 1); ud->uri = uri; ud->digest = digest; return ud; } void uri_digest_free_full(struct uri_digest_s *ud) { if (!ud) return; if (ud->uri) { g_free(ud->uri); ud->uri = NULL; } if (ud->digest) { g_free(ud->digest); ud->digest = NULL; } g_free(ud); } GSList *uri_digest_list_from_uri_list(GSList *uris) { if (!uris) return NULL; GSList *ud_list = NULL; do { ud_list = g_slist_prepend(ud_list, uri_digest_new(uris->data, NULL)); } while ((uris = g_slist_next(uris))); return g_slist_reverse(ud_list); } GSList *uri_digest_list_from_uri_strv(char **uris) { if (!uris) return NULL; GSList *ud_list = NULL; for (int i = 0; uris[i]; i++) ud_list = g_slist_prepend(ud_list, uri_digest_new(uris[i], NULL)); return g_slist_reverse(ud_list); } void uri_digest_list_free(GSList *ud_list) { g_slist_free_full(ud_list, g_free); } void uri_digest_list_free_full(GSList *ud_list) { g_slist_free_full(ud_list, (GDestroyNotify)uri_digest_free_full); } gtkhash-1.5/src/uri-digest.h000066400000000000000000000023151431266303500160300ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_URI_DIGEST_H #define GTKHASH_URI_DIGEST_H #include struct uri_digest_s { char *uri; char *digest; }; struct uri_digest_s *uri_digest_new(char *uri, char *digest); void uri_digest_free_full(struct uri_digest_s *ud); GSList *uri_digest_list_from_uri_list(GSList *uris); GSList *uri_digest_list_from_uri_strv(char **uris); void uri_digest_list_free(GSList *ud_list); void uri_digest_list_free_full(GSList *ud_list); #endif gtkhash-1.5/src/util/000077500000000000000000000000001431266303500145575ustar00rootroot00000000000000gtkhash-1.5/src/util/Makefile.am000066400000000000000000000004521431266303500166140ustar00rootroot00000000000000noinst_LTLIBRARIES = util.la util_la_SOURCES = util.c util.h util_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(GIO_CFLAGS) util_la_CFLAGS = $(GTKHASH_CFLAGS) util_la_LDFLAGS = -avoid-version -module util_la_LIBADD = \ $(GLIB_LIBS) \ $(GIO_LIBS) CLEANFILES = *.gcda *.gcno EXTRA_DIST = meson.build gtkhash-1.5/src/util/meson.build000066400000000000000000000002721431266303500167220ustar00rootroot00000000000000libutil = static_library('util', 'util.c', include_directories: root_include, dependencies: [ glib, gio, ], ) # util_la_LDFLAGS = -avoid-version -module gtkhash-1.5/src/util/util.c000066400000000000000000000036321431266303500157040ustar00rootroot00000000000000/* * Copyright (C) 2007-2020 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "util.h" #include "../main.h" static char *gtkhash_format_time_left(const unsigned int s) { if (s > 60) { const unsigned int m = s / 60; return g_strdup_printf(g_dngettext(GETTEXT_PACKAGE, "%u minute left", "%u minutes left", m), m); } else { return g_strdup_printf(g_dngettext(GETTEXT_PACKAGE, "%u second left", "%u seconds left", s), s); } } char *gtkhash_format_progress(const goffset file_size, const goffset total_read, const double elapsed) { g_assert(file_size > 0); g_assert(total_read > 0); g_assert(elapsed > 0); const unsigned int s = elapsed / total_read * (file_size - total_read); char *time_left_str = gtkhash_format_time_left(s); char *total_read_str = g_format_size(total_read); char *file_size_str = g_format_size(file_size); char *speed_str = g_format_size(total_read / elapsed); char *text; text = g_strdup_printf(_("%s of %s - %s (%s/sec)"), total_read_str, file_size_str, time_left_str, speed_str); g_free(speed_str); g_free(file_size_str); g_free(total_read_str); g_free(time_left_str); return text; } gtkhash-1.5/src/util/util.h000066400000000000000000000016651431266303500157150ustar00rootroot00000000000000/* * Copyright (C) 2007-2016 Tristan Heaven * * This file is part of GtkHash. * * GtkHash is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * GtkHash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GtkHash. If not, see . */ #ifndef GTKHASH_UTIL_UTIL_H #define GTKHASH_UTIL_UTIL_H #include char *gtkhash_format_progress(goffset file_size, goffset total_read, double elapsed); #endif