@ -1,34 +0,0 @@
|
||||
os: Visual Studio 2015
|
||||
|
||||
clone_folder: C:\calibre
|
||||
clone_depth: 5
|
||||
|
||||
cache:
|
||||
- .build-cache
|
||||
- node_modules -> .appveyor.yml
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 7
|
||||
- node --version
|
||||
- npm --version
|
||||
- appveyor-retry npm install --no-optional rapydscript-ng regenerator uglify-js
|
||||
- set PATH=node_modules\.bin;%PATH%
|
||||
- rapydscript --version
|
||||
|
||||
environment:
|
||||
SW: C:\sw
|
||||
QMAKE: C:\sw\qt\bin\qmake.exe
|
||||
QT_PLUGIN_PATH: C:\sw\qt\plugins
|
||||
|
||||
platform:
|
||||
- x64
|
||||
- x86
|
||||
|
||||
before_build:
|
||||
- C:\Python36-x64\python.exe setup/win-ci.py sw
|
||||
|
||||
build_script:
|
||||
- C:\sw\private\python\python.exe setup/win-ci.py build
|
||||
|
||||
test_script:
|
||||
- C:\sw\private\python\python.exe setup/win-ci.py test
|
14
.gitattributes
vendored
@ -38,3 +38,17 @@
|
||||
# Prevent certain files from being exported:
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
|
||||
# Mark vendored files
|
||||
resources/mathjax/* linguist-vendored=true
|
||||
resources/coffee-script.js linguist-vendored=true
|
||||
resources/csscolorparser.js linguist-vendored=true
|
||||
resources/viewer/hyphen* linguist-vendored=true
|
||||
resources/viewer/jquery* linguist-vendored=true
|
||||
src/hunspell linguist-vendored=true
|
||||
|
||||
# Mark generated files
|
||||
resources/content-server/index-generated.html linguist-generated=true
|
||||
resources/editor.js linguist-generated=true
|
||||
resources/viewer.js linguist-generated=true
|
||||
resources/viewer.html linguist-generated=true
|
||||
|
3
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
patreon: kovidgoyal
|
||||
liberapay: kovidgoyal
|
||||
custom: https://calibre-ebook.com/donate
|
63
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-2016]
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
fetch-depth: 10
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@master
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- name: Install calibre dependencies
|
||||
run:
|
||||
python setup/unix-ci.py install
|
||||
|
||||
- name: Bootstrap calibre
|
||||
run:
|
||||
python setup/unix-ci.py bootstrap
|
||||
|
||||
- name: Test calibre
|
||||
run:
|
||||
python setup/unix-ci.py test
|
||||
|
||||
archtest:
|
||||
name: Test on Arch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: 'archlinux/base:latest'
|
||||
env:
|
||||
CI: 'true'
|
||||
CALIBRE_PY3_PORT: '1'
|
||||
steps:
|
||||
- name: Install calibre dependencies
|
||||
run: |
|
||||
set -xe
|
||||
useradd -m ci
|
||||
pacman -Syu --noconfirm
|
||||
pacman -S --noconfirm --needed base-devel sudo git sip chmlib icu jxrlib hunspell libmtp libusbx libwmf optipng podofo python-apsw python-beautifulsoup4 python-cssselect python-css-parser python-dateutil python-dbus python-dnspython python-dukpy python-feedparser python-html2text python-html5-parser python-lxml python-markdown python-mechanize python-msgpack python-netifaces python-unrardll python-pillow python-psutil python-pygments python-pyqt5 python-regex python-zeroconf python-pyqtwebengine qt5-x11extras qt5-svg qt5-imageformats udisks2 hyphen
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
fetch-depth: 10
|
||||
|
||||
- name: Bootstrap calibre
|
||||
run: |
|
||||
chown -R ci:users $GITHUB_WORKSPACE
|
||||
runuser -u ci -- python setup.py bootstrap --ephemeral
|
||||
|
||||
- name: Test calibre
|
||||
run: |
|
||||
runuser -u ci -- python setup.py test
|
||||
chmod +777 .git .git/config
|
6
.gitignore
vendored
@ -15,6 +15,7 @@ build
|
||||
dist
|
||||
docs
|
||||
resources/localization
|
||||
resources/hyphenation
|
||||
resources/scripts.calibre_msgpack
|
||||
resources/ebook-convert-complete.calibre_msgpack
|
||||
resources/builtin_recipes.xml
|
||||
@ -28,8 +29,7 @@ resources/viewer.html
|
||||
resources/content-server/index-generated.html
|
||||
resources/content-server/calibre.appcache
|
||||
resources/content-server/locales.zip
|
||||
resources/content-server/mathjax.zip.xz
|
||||
resources/content-server/mathjax.version
|
||||
resources/mathjax
|
||||
resources/mozilla-ca-certs.pem
|
||||
resources/user-agent-data.json
|
||||
icons/icns/*.iconset
|
||||
@ -52,3 +52,5 @@ recipes/debug
|
||||
/.metadata/
|
||||
.idea
|
||||
/*env*/
|
||||
cmake-build-*
|
||||
bypy/b
|
||||
|
19
.travis.yml
@ -1,19 +0,0 @@
|
||||
language: node_js
|
||||
nodejs:
|
||||
- node
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- .build-cache
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: false
|
||||
- os: osx
|
||||
|
||||
before_install:
|
||||
- python setup/unix-ci.py install
|
||||
- python setup/unix-ci.py bootstrap
|
||||
|
||||
script: python setup/unix-ci.py test
|
138
COPYRIGHT
@ -1,13 +1,9 @@
|
||||
Files: *
|
||||
Copyright: Copyright (C) 2008-2017 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
Copyright: Copyright (C) 2008-2020 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
License: GPL-3
|
||||
The full text of the GPL is distributed as in
|
||||
/usr/share/common-licenses/GPL-3 on Debian systems.
|
||||
|
||||
Files: src/duktape/*
|
||||
Copyright: Various
|
||||
License: MIT
|
||||
|
||||
Files: resources/content-server/font-awesome/*
|
||||
Copyright: Various
|
||||
License: MIT and SIL OFL
|
||||
@ -202,12 +198,6 @@ License: GPL-3
|
||||
The full text of the GPL is distributed as in
|
||||
/usr/share/common-licenses/GPL-3 on Debian systems.
|
||||
|
||||
Files: src/calibre/ebooks/textile/unsmarten.py
|
||||
Copyright: 2011, Leigh Parry <leighparry@blueyonder.co.uk>
|
||||
License: GPL-3
|
||||
The full text of the GPL is distributed as in
|
||||
/usr/share/common-licenses/GPL-3 on Debian systems.
|
||||
|
||||
Files: src/calibre/ebooks/textile/functions.py
|
||||
Copyright: 2011, Leigh Parry <leighparry@blueyonder.co.uk>
|
||||
License: BSD-3-clause-like
|
||||
@ -252,16 +242,6 @@ License: LGPL 2.1
|
||||
The full text of the LGPL is distributed as in
|
||||
/usr/share/common-licenses/LGPL-2.1 on Debian systems.
|
||||
|
||||
Files: src/calibre/ebooks/BeautifulSoup.py
|
||||
Copyright: Copyright (c) 2004-2007, Leonard Richardson
|
||||
License: BSD
|
||||
The full text of the BSD license is distributed as in
|
||||
/usr/share/common-licenses/BSD on Debian systems.
|
||||
|
||||
Files: src/hunspell/*
|
||||
Copyright: Various
|
||||
License: GPL-2+
|
||||
|
||||
Files: src/calibre/gui2/tweak_book/diff/_patiencediff_c.c
|
||||
Copyright: Canonical
|
||||
License: GPL-2+
|
||||
@ -348,12 +328,6 @@ License: GPL-3
|
||||
The full text of the GPL is distributed as in
|
||||
/usr/share/common-licenses/GPL-3 on Debian systems.
|
||||
|
||||
Files: src/calibre/ebooks/BeautifulSoup.py
|
||||
Copyright: Copyright (c) 2004-2007, Leonard Richardson
|
||||
License: BSD
|
||||
The full text of the BSD license is distributed as in
|
||||
/usr/share/common-licenses/BSD on Debian systems.
|
||||
|
||||
Files: src/calibre/ebooks/rtf2xml/*
|
||||
Copyright: copyright 2002 Paul Henry Tremblay
|
||||
License: GPL
|
||||
@ -399,6 +373,9 @@ Files: src/calibre/translations/msgfmt.py
|
||||
Copyright: Martin v. Loewis
|
||||
License: Python Software Foundation License
|
||||
|
||||
Files: src/calibre/utils/imageops/ordered_dither.cpp
|
||||
Copyright: Copyright 1999-2019 ImageMagick Studio LLC
|
||||
License: ImageMagick License
|
||||
|
||||
BSD License (for all the BSD licensed code indicated above)
|
||||
-----------------------------------------------------------
|
||||
@ -581,3 +558,110 @@ whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
ImageMagick License (for all the ImageMagick licensed code indicated above)
|
||||
-----------------------------------------------------------
|
||||
|
||||
Before we get to the text of the license, lets just review what the license says in simple terms:
|
||||
|
||||
It allows you to:
|
||||
|
||||
* freely download and use ImageMagick software, in whole or in part, for personal, company internal, or commercial purposes;
|
||||
* use ImageMagick software in packages or distributions that you create;
|
||||
* link against a library under a different license;
|
||||
* link code under a different license against a library under this license;
|
||||
* merge code into a work under a different license;
|
||||
* extend patent grants to any code using code under this license;
|
||||
* and extend patent protection.
|
||||
|
||||
It forbids you to:
|
||||
|
||||
* redistribute any piece of ImageMagick-originated software without proper attribution;
|
||||
* use any marks owned by ImageMagick Studio LLC in any way that might state or imply that ImageMagick Studio LLC endorses your distribution;
|
||||
* use any marks owned by ImageMagick Studio LLC in any way that might state or imply that you created the ImageMagick software in question.
|
||||
|
||||
It requires you to:
|
||||
|
||||
* include a copy of the license in any redistribution you may make that includes ImageMagick software;
|
||||
* provide clear attribution to ImageMagick Studio LLC for any distributions that include ImageMagick software.
|
||||
|
||||
It does not require you to:
|
||||
|
||||
* include the source of the ImageMagick software itself, or of any modifications you may have made to it, in any redistribution you may assemble that includes it;
|
||||
* submit changes that you make to the software back to the ImageMagick Studio LLC (though such feedback is encouraged).
|
||||
|
||||
A few other clarifications include:
|
||||
|
||||
* ImageMagick is freely available without charge;
|
||||
* you may include ImageMagick on a DVD as long as you comply with the terms of the license;
|
||||
* you can give modified code away for free or sell it under the terms of the ImageMagick license or distribute the result under a different license, but you need to acknowledge the use of the ImageMagick software;
|
||||
* the license is compatible with the GPL V3.
|
||||
* when exporting the ImageMagick software, review its export classification.
|
||||
|
||||
Terms and Conditions for Use, Reproduction, and Distribution
|
||||
|
||||
The legally binding and authoritative terms and conditions for use, reproduction, and distribution of ImageMagick follow:
|
||||
|
||||
Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization dedicated to making software imaging solutions freely available.
|
||||
|
||||
1. Definitions.
|
||||
|
||||
License shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
Legal Entity shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, control means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
You (or Your) shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
Source form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
Object form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
Work shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
Derivative Works shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
Contribution shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as Not a Contribution.
|
||||
|
||||
Contributor shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
* You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
* You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
* You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
* If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
How to Apply the License to your Work
|
||||
|
||||
To apply the ImageMagick License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information (don't include the brackets). The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the ImageMagick License (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy
|
||||
of the License at
|
||||
|
||||
https://imagemagick.org/script/license.php
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
1232
Changelog.yaml
8
LICENSE
@ -1,7 +1,7 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU 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. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
<https://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
@ -18,7 +18,7 @@
|
||||
\pard\plain \ltrpar\s9\cf0\qc{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af4\afs28\lang1081\ab\ltrch\dbch\af4\langfe255\hich\f4\fs28\lang9226\b\loch\f4\fs28\lang9226\b {\rtlch \ltrch\loch\f4\fs28\lang9226\i0\b GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007}
|
||||
\par \pard\plain \ltrpar\s9\cf0\qc{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af4\afs28\lang1081\ab\ltrch\dbch\af4\langfe255\hich\f4\fs28\lang9226\b\loch\f4\fs28\lang9226\b
|
||||
\par \pard\plain \ltrpar\s9\cf0\qc{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af4\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f4\fs20\lang9226\loch\f4\fs20\lang9226
|
||||
\par \pard\plain \ltrpar\s9\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af5\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f5\fs20\lang9226\loch\f5\fs20\lang9226 {\rtlch \ltrch\loch\f5\fs20\lang9226\i0\b0 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>}
|
||||
\par \pard\plain \ltrpar\s9\cf0\qj{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af5\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f5\fs20\lang9226\loch\f5\fs20\lang9226 {\rtlch \ltrch\loch\f5\fs20\lang9226\i0\b0 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>}
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af5\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f5\fs20\lang9226\loch\f5\fs20\lang9226 {\rtlch \ltrch\loch\f5\fs20\lang9226\i0\b0 Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.}
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af4\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f4\fs20\lang9226\loch\f4\fs20\lang9226
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af5\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f5\fs20\lang9226\loch\f5\fs20\lang9226 {\rtlch \ltrch\loch\f5\fs20\lang9226\i0\b0 Preamble}
|
||||
@ -330,4 +330,4 @@ ction with the Program, unless a warranty or assumption of liability accompanies
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af4\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f4\fs20\lang9226\loch\f4\fs20\lang9226 {\rtlch \ltrch\loch }{\rtlch \ltrch\loch\f4\fs20\lang9226\i0\b0\rtlch\ltrch\hich\f5\loch\f5 END OF TERMS AND CONDITIONS}
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af4\afs20\lang1081\ltrch\dbch\af4\langfe255\hich\f4\fs20\lang9226\loch\f4\fs20\lang9226
|
||||
\par \pard\plain \ltrpar\s9\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af4\afs22\lang1081\ltrch\dbch\af4\langfe255\hich\f4\fs22\lang9226\loch\f4\fs22\lang9226{\rtlch\ltrch\dbch\hich\fs20\loch\fs20}{\rtlch \ltrch\loch }
|
||||
\par }
|
||||
\par }
|
||||
|
@ -10,8 +10,7 @@ reading. It is cross platform, running on Linux, Windows and macOS.
|
||||
|
||||
For more information, see the [calibre About page](https://calibre-ebook.com/about)
|
||||
|
||||
[](https://travis-ci.org/kovidgoyal/calibre)
|
||||
[](https://ci.appveyor.com/project/kovidgoyal/calibre)
|
||||
[](https://github.com/kovidgoyal/calibre/actions?workflow=Continuous+Integration)
|
||||
|
||||
## Screenshots
|
||||
|
||||
@ -39,3 +38,7 @@ calibre is a result of the efforts of many volunteers from all over the world.
|
||||
If you find it useful, please consider contributing to support its development.
|
||||
[Donate to support calibre development](https://calibre-ebook.com/donate).
|
||||
|
||||
## Building calibre binaries
|
||||
|
||||
See [Build instructions](bypy/README.rst) for instructions on how to build the
|
||||
calibre binaries and installers for all the platforms calibre supports.
|
||||
|
29
README.python3
Normal file
@ -0,0 +1,29 @@
|
||||
Efforts to port calibre to python 3 are ongoing. calibre can be run
|
||||
using python3 under Linux. To do so, install python 3, checkout calibre
|
||||
from source with
|
||||
|
||||
git clone git@github.com:kovidgoyal/calibre.git && cd calibre
|
||||
|
||||
Then, setup calibre to run under python2, with:
|
||||
|
||||
python2 setup.py bootstrap
|
||||
|
||||
Check that calibre works, with:
|
||||
|
||||
python2 run-local calibre
|
||||
|
||||
Now build the calibre C extensions for python 3 with:
|
||||
|
||||
CALIBRE_PY3_PORT=1 python3 setup.py build
|
||||
|
||||
You should now be able to run the calibre test suite using:
|
||||
|
||||
CALIBRE_PY3_PORT=1 python3 setup.py test
|
||||
|
||||
And run calibre itself (which may not work) with:
|
||||
|
||||
python3 run-local calibre
|
||||
|
||||
|
||||
For the status of the port, and discussion of its design, see
|
||||
https://github.com/kovidgoyal/calibre/pull/870
|
134
bypy/README.rst
Normal file
@ -0,0 +1,134 @@
|
||||
Build the calibre installers, including all dependencies from scratch
|
||||
=======================================================================
|
||||
|
||||
This folder contains code to automate the process of building calibre,
|
||||
including all its dependencies, from scratch, for all platforms that calibre
|
||||
supports.
|
||||
|
||||
In general builds proceed in two steps, first build all the dependencies, then
|
||||
build the calibre installer itself.
|
||||
|
||||
Requirements
|
||||
---------------
|
||||
|
||||
Building *must* run on a Linux computer.
|
||||
|
||||
First create some empty top level directory and run the following commands::
|
||||
|
||||
git clone https://github.com/kovidgoyal/bypy.git
|
||||
git clone https://github.com/kovidgoyal/calibre.git
|
||||
cd calibre
|
||||
./setup.py bootstrap
|
||||
|
||||
To make the Windows and macOS builds it uses VirtualBox VMs. Instructions on
|
||||
creating the VMs are in their respective sections below.
|
||||
|
||||
Linux
|
||||
-------
|
||||
|
||||
To build the 64bit and 32bit dependencies for calibre, run::
|
||||
|
||||
./setup.py build_dep linux
|
||||
./setup.py build_dep linux 32
|
||||
|
||||
The output (after a very long time) will be in :literal:`bypy/b/linux/[32|64]`
|
||||
|
||||
Now you can build the calibre Linux tarballs with::
|
||||
|
||||
./setup.py linux
|
||||
|
||||
The output will be in :literal:`dist`
|
||||
|
||||
|
||||
macOS
|
||||
--------------
|
||||
|
||||
You need a VirtualBox virtual machine of macOS 10.14 (Mojave). Name the
|
||||
VM using ``vm_name`` from :literal:`bypy/macos.conf`. To setup macOS inside the VM,
|
||||
follow the steps:
|
||||
|
||||
* Turn on Remote Login under Network (SSHD)
|
||||
* Create a user account named ``kovid`` and enable password-less login for SSH
|
||||
for that account (setup ``~/.ssh/authorized_keys``)
|
||||
* Setup ssh into the VM from the host using the ``vm_name`` from above.
|
||||
* Install the needed software mentioned in :literal:`bypy/macos.conf`.
|
||||
|
||||
To build the dependencies for calibre, run::
|
||||
|
||||
./setup.py build_dep macos
|
||||
|
||||
The output (after a very long time) will be in :literal:`bypy/b/macos`.
|
||||
Now you can build the calibre ``.dmg`` with::
|
||||
|
||||
./setup.py osx --dont-sign --dont-notarize
|
||||
|
||||
The output will be in :literal:`dist`
|
||||
|
||||
|
||||
Windows
|
||||
-------------
|
||||
|
||||
You need a VirtualBox virtual machine of Windows 7 64bit. Name the
|
||||
VM using ``vm_name`` from :literal:`bypy/windows.conf`. To setup windows inside the VM,
|
||||
follow the steps:
|
||||
|
||||
* Install all the software mentioned in :literal:`bypy/windows.conf`
|
||||
|
||||
* Install cygwin, with the: vim, dos2unix, rsync, openssh, unzip, wget, make, zsh, patch, bash-completion, curl
|
||||
packages
|
||||
|
||||
* Edit ``/etc/passwd`` and replace all occurrences of ``/bin/bash`` with ``/bin/zsh`` (in
|
||||
a cygwin prompt)
|
||||
|
||||
* Setup a password for your windows user account
|
||||
|
||||
* Follow the steps here: http://pcsupport.about.com/od/windows7/ht/auto-logon-windows-7.htm to allow the
|
||||
machine to bootup without having to enter the password
|
||||
|
||||
* The following steps must all be run in an administrator cygwin shell, to
|
||||
enable SSH logins to the machine
|
||||
|
||||
* First clean out any existing cygwin ssh setup with::
|
||||
|
||||
net stop sshd
|
||||
cygrunsrv -R sshd
|
||||
net user sshd /DELETE
|
||||
net user cyg_server /DELETE (delete any other cygwin users account you
|
||||
can list them with net user)
|
||||
rm -R /etc/ssh*
|
||||
mkpasswd -cl > /etc/passwd
|
||||
mkgroup --local > /etc/group
|
||||
|
||||
* Assign the necessary rights to the normal user account (administrator
|
||||
cygwin command prompt needed - editrights is available in ``\cygwin\bin``)::
|
||||
|
||||
editrights.exe -a SeAssignPrimaryTokenPrivilege -u kovid
|
||||
editrights.exe -a SeCreateTokenPrivilege -u kovid
|
||||
editrights.exe -a SeTcbPrivilege -u kovid
|
||||
editrights.exe -a SeServiceLogonRight -u kovid
|
||||
|
||||
* Run::
|
||||
|
||||
ssh-host-config
|
||||
And answer (yes) to all questions. If it asks do you want to use a
|
||||
different user name, specify the name of your user account and enter
|
||||
username and password
|
||||
|
||||
* Start sshd with::
|
||||
|
||||
net start sshd
|
||||
|
||||
* See http://www.kgx.net.nz/2010/03/cygwin-sshd-and-windows-7/ for details
|
||||
|
||||
|
||||
To build the dependencies for calibre, run::
|
||||
|
||||
./setup.py build_dep windows
|
||||
./setup.py build_dep windows 32
|
||||
|
||||
The output (after a very long time) will be in :literal:`bypy/b/windows/[32|64]`.
|
||||
Now you can build the calibre windows installers with::
|
||||
|
||||
./setup.py win --dont-sign
|
||||
|
||||
The output will be in :literal:`dist`
|
195
bypy/init_env.py
Normal file
@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from bypy.constants import (
|
||||
LIBDIR, PREFIX, PYTHON, SRC as CALIBRE_DIR, build_dir, islinux, ismacos,
|
||||
iswindows, worker_env
|
||||
)
|
||||
from bypy.utils import run_shell
|
||||
|
||||
dlls = [
|
||||
'Core',
|
||||
'Concurrent',
|
||||
'Gui',
|
||||
'Network',
|
||||
# 'NetworkAuth',
|
||||
'Location',
|
||||
'PrintSupport',
|
||||
'WebChannel',
|
||||
# 'WebSockets',
|
||||
# 'WebView',
|
||||
'Positioning',
|
||||
'PositioningQuick',
|
||||
'Sensors',
|
||||
'Sql',
|
||||
'Svg',
|
||||
'WebEngineCore',
|
||||
'WebEngine',
|
||||
'WebEngineWidgets',
|
||||
'Widgets',
|
||||
# 'Multimedia',
|
||||
'OpenGL',
|
||||
'Quick',
|
||||
'QuickWidgets',
|
||||
'Qml',
|
||||
'QmlModels',
|
||||
# 'MultimediaWidgets',
|
||||
'Xml',
|
||||
# 'XmlPatterns',
|
||||
]
|
||||
|
||||
if islinux:
|
||||
dlls += ['X11Extras', 'XcbQpa', 'WaylandClient', 'DBus']
|
||||
elif ismacos:
|
||||
dlls += ['MacExtras', 'DBus']
|
||||
elif iswindows:
|
||||
dlls += ['WinExtras']
|
||||
|
||||
QT_DLLS = frozenset(
|
||||
'Qt5' + x for x in dlls
|
||||
)
|
||||
|
||||
QT_PLUGINS = [
|
||||
'imageformats',
|
||||
'iconengines',
|
||||
# 'mediaservice',
|
||||
'platforms',
|
||||
'platformthemes',
|
||||
# 'playlistformats',
|
||||
'sqldrivers',
|
||||
# 'webview',
|
||||
# 'audio', 'printsupport', 'bearer', 'position',
|
||||
]
|
||||
|
||||
if islinux:
|
||||
QT_PLUGINS += [
|
||||
'platforminputcontexts',
|
||||
'wayland-decoration-client',
|
||||
'wayland-graphics-integration-client',
|
||||
'wayland-shell-integration',
|
||||
'xcbglintegrations',
|
||||
]
|
||||
else:
|
||||
QT_PLUGINS.append('styles')
|
||||
|
||||
PYQT_MODULES = (
|
||||
'Qt',
|
||||
'QtCore',
|
||||
'QtGui',
|
||||
'QtNetwork',
|
||||
# 'QtMultimedia', 'QtMultimediaWidgets',
|
||||
'QtPrintSupport',
|
||||
'QtSensors',
|
||||
'QtSvg',
|
||||
'QtWidgets',
|
||||
'QtWebEngine',
|
||||
'QtWebEngineCore',
|
||||
'QtWebEngineWidgets',
|
||||
'QtWebChannel',
|
||||
)
|
||||
del dlls
|
||||
|
||||
if iswindows:
|
||||
PYQT_MODULES += ('QtWinExtras',)
|
||||
|
||||
|
||||
def read_cal_file(name):
|
||||
with open(os.path.join(CALIBRE_DIR, 'src', 'calibre', name), 'rb') as f:
|
||||
return f.read().decode('utf-8')
|
||||
|
||||
|
||||
def initialize_constants():
|
||||
calibre_constants = {}
|
||||
src = read_cal_file('constants.py')
|
||||
nv = re.search(r'numeric_version\s+=\s+\((\d+), (\d+), (\d+)\)', src)
|
||||
calibre_constants['version'
|
||||
] = '%s.%s.%s' % (nv.group(1), nv.group(2), nv.group(3))
|
||||
calibre_constants['appname'] = re.search(
|
||||
r'__appname__\s+=\s+(u{0,1})[\'"]([^\'"]+)[\'"]', src
|
||||
).group(2)
|
||||
epsrc = re.compile(r'entry_points = (\{.*?\})',
|
||||
re.DOTALL).search(read_cal_file('linux.py')).group(1)
|
||||
entry_points = eval(epsrc, {'__appname__': calibre_constants['appname']})
|
||||
|
||||
def e2b(ep):
|
||||
return re.search(r'\s*(.*?)\s*=', ep).group(1).strip()
|
||||
|
||||
def e2s(ep, base='src'):
|
||||
return (
|
||||
base + os.path.sep +
|
||||
re.search(r'.*=\s*(.*?):', ep).group(1).replace('.', '/') + '.py'
|
||||
).strip()
|
||||
|
||||
def e2m(ep):
|
||||
return re.search(r'.*=\s*(.*?)\s*:', ep).group(1).strip()
|
||||
|
||||
def e2f(ep):
|
||||
return ep[ep.rindex(':') + 1:].strip()
|
||||
|
||||
calibre_constants['basenames'] = basenames = {}
|
||||
calibre_constants['functions'] = functions = {}
|
||||
calibre_constants['modules'] = modules = {}
|
||||
calibre_constants['scripts'] = scripts = {}
|
||||
for x in ('console', 'gui'):
|
||||
y = x + '_scripts'
|
||||
basenames[x] = list(map(e2b, entry_points[y]))
|
||||
functions[x] = list(map(e2f, entry_points[y]))
|
||||
modules[x] = list(map(e2m, entry_points[y]))
|
||||
scripts[x] = list(map(e2s, entry_points[y]))
|
||||
|
||||
src = read_cal_file('ebooks/__init__.py')
|
||||
be = re.search(
|
||||
r'^BOOK_EXTENSIONS\s*=\s*(\[.+?\])', src, flags=re.DOTALL | re.MULTILINE
|
||||
).group(1)
|
||||
calibre_constants['book_extensions'] = json.loads(be.replace("'", '"'))
|
||||
return calibre_constants
|
||||
|
||||
|
||||
def run(*args, **extra_env):
|
||||
env = os.environ.copy()
|
||||
env.update(worker_env)
|
||||
env.update(extra_env)
|
||||
env['SW'] = PREFIX
|
||||
env['LD_LIBRARY_PATH'] = LIBDIR
|
||||
env['SIP_BIN'] = os.path.join(PREFIX, 'bin', 'sip')
|
||||
env['QMAKE'] = os.path.join(PREFIX, 'qt', 'bin', 'qmake')
|
||||
return subprocess.call(list(args), env=env, cwd=CALIBRE_DIR)
|
||||
|
||||
|
||||
def build_c_extensions(ext_dir, args):
|
||||
bdir = os.path.join(build_dir(), 'calibre-extension-objects')
|
||||
cmd = [
|
||||
PYTHON, 'setup.py', 'build',
|
||||
'--output-dir', ext_dir, '--build-dir', bdir,
|
||||
]
|
||||
if args.build_only:
|
||||
cmd.extend(('--only', args.build_only))
|
||||
if run(*cmd, COMPILER_CWD=bdir) != 0:
|
||||
print('Building of calibre C extensions failed', file=sys.stderr)
|
||||
os.chdir(CALIBRE_DIR)
|
||||
run_shell()
|
||||
raise SystemExit('Building of calibre C extensions failed')
|
||||
return ext_dir
|
||||
|
||||
|
||||
def run_tests(path_to_calibre_debug, cwd_on_failure):
|
||||
ret = run(path_to_calibre_debug, '--test-build')
|
||||
if ret != 0:
|
||||
os.chdir(cwd_on_failure)
|
||||
print(
|
||||
'running calibre build tests failed with return code:', ret, 'and exe:', path_to_calibre_debug, file=sys.stderr)
|
||||
run_shell()
|
||||
raise SystemExit('running calibre build tests failed')
|
||||
|
||||
|
||||
if __name__ == 'program':
|
||||
calibre_constants = initialize_constants()
|
4
bypy/linux.conf
Normal file
@ -0,0 +1,4 @@
|
||||
image 'https://partner-images.canonical.com/core/xenial/current/ubuntu-xenial-core-cloudimg-{}-root.tar.gz'
|
||||
|
||||
# Build time deps for Qt. See http://doc.qt.io/qt-5/linux-requirements.html and https://wiki.qt.io/Building_Qt_5_from_Git
|
||||
deps 'flex bison gperf ruby libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev xkb-data libglu1-mesa-dev libxkbcommon-dev libinput-dev libxkbcommon-x11-dev libgtk2.0-dev libvulkan-dev libwayland-dev libwayland-egl1-mesa libegl1-mesa-dev libxtst-dev libnss3-dev libfreetype6-dev libfontconfig-dev'
|
308
bypy/linux/__main__.py
Normal file
@ -0,0 +1,308 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import errno
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import tarfile
|
||||
import time
|
||||
from functools import partial
|
||||
|
||||
from bypy.constants import (
|
||||
OUTPUT_DIR, PREFIX, SRC as CALIBRE_DIR, is64bit, python_major_minor_version
|
||||
)
|
||||
from bypy.utils import (
|
||||
create_job, get_dll_path, mkdtemp, parallel_build, py_compile, run, walk
|
||||
)
|
||||
|
||||
j = os.path.join
|
||||
self_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
arch = 'x86_64' if is64bit else 'i686'
|
||||
|
||||
py_ver = '.'.join(map(str, python_major_minor_version()))
|
||||
QT_PREFIX = os.path.join(PREFIX, 'qt')
|
||||
iv = globals()['init_env']
|
||||
calibre_constants = iv['calibre_constants']
|
||||
QT_DLLS, QT_PLUGINS, PYQT_MODULES = iv['QT_DLLS'], iv['QT_PLUGINS'], iv['PYQT_MODULES']
|
||||
qt_get_dll_path = partial(get_dll_path, loc=os.path.join(QT_PREFIX, 'lib'))
|
||||
|
||||
|
||||
def binary_includes():
|
||||
return [
|
||||
j(PREFIX, 'bin', x) for x in ('pdftohtml', 'pdfinfo', 'pdftoppm', 'optipng', 'JxrDecApp')] + [
|
||||
|
||||
j(PREFIX, 'private', 'mozjpeg', 'bin', x) for x in ('jpegtran', 'cjpeg')] + [
|
||||
] + list(map(
|
||||
get_dll_path,
|
||||
('usb-1.0 mtp expat sqlite3 ffi z openjp2 poppler dbus-1 iconv xml2 xslt jpeg png16'
|
||||
' webp webpmux webpdemux exslt ncursesw readline chm hunspell-1.7 hyphen'
|
||||
' icudata icui18n icuuc icuio gcrypt gpg-error'
|
||||
' gobject-2.0 glib-2.0 gthread-2.0 gmodule-2.0 gio-2.0 dbus-glib-1').split()
|
||||
)) + [
|
||||
get_dll_path('podofo', 3), get_dll_path('bz2', 2), j(PREFIX, 'lib', 'libunrar.so'),
|
||||
get_dll_path('ssl', 3), get_dll_path('crypto', 3), get_dll_path('python' + py_ver, 2),
|
||||
# We dont include libstdc++.so as the OpenGL dlls on the target
|
||||
# computer fail to load in the QPA xcb plugin if they were compiled
|
||||
# with a newer version of gcc than the one on the build computer.
|
||||
# libstdc++, like glibc is forward compatible and I dont think any
|
||||
# distros do not have libstdc++.so.6, so it should be safe to leave it out.
|
||||
# https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html (The current
|
||||
# debian stable libstdc++ is libstdc++.so.6.0.17)
|
||||
] + list(map(qt_get_dll_path, QT_DLLS))
|
||||
|
||||
|
||||
class Env(object):
|
||||
|
||||
def __init__(self):
|
||||
self.src_root = CALIBRE_DIR
|
||||
self.base = mkdtemp('frozen-')
|
||||
self.lib_dir = j(self.base, 'lib')
|
||||
self.py_dir = j(self.lib_dir, 'python' + py_ver)
|
||||
os.makedirs(self.py_dir)
|
||||
self.bin_dir = j(self.base, 'bin')
|
||||
os.mkdir(self.bin_dir)
|
||||
self.SRC = j(self.src_root, 'src')
|
||||
self.obj_dir = mkdtemp('launchers-')
|
||||
|
||||
|
||||
def ignore_in_lib(base, items, ignored_dirs=None):
|
||||
ans = []
|
||||
if ignored_dirs is None:
|
||||
ignored_dirs = {'.svn', '.bzr', '.git', 'test', 'tests', 'testing'}
|
||||
for name in items:
|
||||
path = j(base, name)
|
||||
if os.path.isdir(path):
|
||||
if name in ignored_dirs or not os.path.exists(j(path, '__init__.py')):
|
||||
if name != 'plugins':
|
||||
ans.append(name)
|
||||
else:
|
||||
if name.rpartition('.')[-1] not in ('so', 'py'):
|
||||
ans.append(name)
|
||||
return ans
|
||||
|
||||
|
||||
def import_site_packages(srcdir, dest):
|
||||
if not os.path.exists(dest):
|
||||
os.mkdir(dest)
|
||||
for x in os.listdir(srcdir):
|
||||
ext = x.rpartition('.')[-1]
|
||||
f = j(srcdir, x)
|
||||
if ext in ('py', 'so'):
|
||||
shutil.copy2(f, dest)
|
||||
elif ext == 'pth' and x != 'setuptools.pth':
|
||||
for line in open(f, 'rb').read().splitlines():
|
||||
src = os.path.abspath(j(srcdir, line))
|
||||
if os.path.exists(src) and os.path.isdir(src):
|
||||
import_site_packages(src, dest)
|
||||
elif os.path.exists(j(f, '__init__.py')):
|
||||
shutil.copytree(f, j(dest, x), ignore=ignore_in_lib)
|
||||
|
||||
|
||||
def copy_libs(env):
|
||||
print('Copying libs...')
|
||||
|
||||
for x in binary_includes():
|
||||
dest = env.bin_dir if '/bin/' in x else env.lib_dir
|
||||
shutil.copy2(x, dest)
|
||||
os.chmod(j(
|
||||
dest, os.path.basename(x)),
|
||||
stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
|
||||
|
||||
base = j(QT_PREFIX, 'plugins')
|
||||
dest = j(env.lib_dir, '..', 'plugins')
|
||||
os.mkdir(dest)
|
||||
for x in QT_PLUGINS:
|
||||
if x not in ('audio', 'printsupport'):
|
||||
shutil.copytree(j(base, x), j(dest, x))
|
||||
dest = j(env.lib_dir, '..', 'libexec')
|
||||
os.mkdir(dest)
|
||||
shutil.copy2(os.path.join(QT_PREFIX, 'libexec', 'QtWebEngineProcess'), dest)
|
||||
|
||||
|
||||
def copy_python(env, ext_dir):
|
||||
print('Copying python...')
|
||||
srcdir = j(PREFIX, 'lib/python' + py_ver)
|
||||
|
||||
for x in os.listdir(srcdir):
|
||||
y = j(srcdir, x)
|
||||
ext = os.path.splitext(x)[1]
|
||||
if os.path.isdir(y) and x not in ('test', 'hotshot',
|
||||
'site-packages', 'idlelib', 'lib2to3', 'dist-packages'):
|
||||
shutil.copytree(y, j(env.py_dir, x), ignore=ignore_in_lib)
|
||||
if os.path.isfile(y) and ext in ('.py', '.so'):
|
||||
shutil.copy2(y, env.py_dir)
|
||||
|
||||
srcdir = j(srcdir, 'site-packages')
|
||||
dest = j(env.py_dir, 'site-packages')
|
||||
import_site_packages(srcdir, dest)
|
||||
shutil.rmtree(j(dest, 'PyQt5/uic/port_v3'))
|
||||
|
||||
filter_pyqt = {x + '.so' for x in PYQT_MODULES} | {'sip.so'}
|
||||
pyqt = j(dest, 'PyQt5')
|
||||
for x in os.listdir(pyqt):
|
||||
if x.endswith('.so') and x not in filter_pyqt:
|
||||
os.remove(j(pyqt, x))
|
||||
|
||||
for x in os.listdir(env.SRC):
|
||||
c = j(env.SRC, x)
|
||||
if os.path.exists(j(c, '__init__.py')):
|
||||
shutil.copytree(c, j(dest, x), ignore=partial(ignore_in_lib, ignored_dirs={}))
|
||||
elif os.path.isfile(c):
|
||||
shutil.copy2(c, j(dest, x))
|
||||
pdir = j(dest, 'calibre', 'plugins')
|
||||
if not os.path.exists(pdir):
|
||||
os.mkdir(pdir)
|
||||
for x in glob.glob(j(ext_dir, '*.so')):
|
||||
shutil.copy2(x, j(pdir, os.path.basename(x)))
|
||||
|
||||
shutil.copytree(j(env.src_root, 'resources'), j(env.base, 'resources'))
|
||||
for pak in glob.glob(j(QT_PREFIX, 'resources', '*.pak')):
|
||||
shutil.copy2(pak, j(env.base, 'resources'))
|
||||
os.mkdir(j(env.base, 'translations'))
|
||||
shutil.copytree(j(QT_PREFIX, 'translations', 'qtwebengine_locales'), j(env.base, 'translations', 'qtwebengine_locales'))
|
||||
sitepy = j(self_dir, 'site.py')
|
||||
shutil.copy2(sitepy, j(env.py_dir, 'site.py'))
|
||||
|
||||
py_compile(env.py_dir)
|
||||
|
||||
|
||||
def build_launchers(env):
|
||||
base = self_dir
|
||||
sources = [j(base, x) for x in ['util.c']]
|
||||
objects = [j(env.obj_dir, os.path.basename(x) + '.o') for x in sources]
|
||||
cflags = '-fno-strict-aliasing -W -Wall -c -O2 -pipe -DPYTHON_VER="python%s"' % py_ver
|
||||
cflags = cflags.split() + ['-I%s/include/python%s' % (PREFIX, py_ver)]
|
||||
for src, obj in zip(sources, objects):
|
||||
cmd = ['gcc'] + cflags + ['-fPIC', '-o', obj, src]
|
||||
run(*cmd)
|
||||
|
||||
dll = j(env.lib_dir, 'libcalibre-launcher.so')
|
||||
cmd = ['gcc', '-O2', '-Wl,--rpath=$ORIGIN/../lib', '-fPIC', '-o', dll, '-shared'] + objects + \
|
||||
['-L%s/lib' % PREFIX, '-lpython' + py_ver]
|
||||
run(*cmd)
|
||||
|
||||
src = j(base, 'main.c')
|
||||
|
||||
modules, basenames, functions = calibre_constants['modules'].copy(), calibre_constants['basenames'].copy(), calibre_constants['functions'].copy()
|
||||
modules['console'].append('calibre.linux')
|
||||
basenames['console'].append('calibre_postinstall')
|
||||
functions['console'].append('main')
|
||||
c_launcher = '/tmp/calibre-c-launcher'
|
||||
lsrc = os.path.join(base, 'launcher.c')
|
||||
cmd = ['gcc', '-O2', '-o', c_launcher, lsrc, ]
|
||||
run(*cmd)
|
||||
|
||||
jobs = []
|
||||
for typ in ('console', 'gui', ):
|
||||
for mod, bname, func in zip(modules[typ], basenames[typ], functions[typ]):
|
||||
xflags = list(cflags)
|
||||
xflags.remove('-c')
|
||||
xflags += ['-DGUI_APP=' + ('1' if typ == 'gui' else '0')]
|
||||
xflags += ['-DMODULE="%s"' % mod, '-DBASENAME="%s"' % bname,
|
||||
'-DFUNCTION="%s"' % func]
|
||||
|
||||
exe = j(env.bin_dir, bname)
|
||||
cmd = ['gcc'] + xflags + [src, '-o', exe, '-L' + env.lib_dir, '-lcalibre-launcher']
|
||||
jobs.append(create_job(cmd))
|
||||
sh = j(env.base, bname)
|
||||
shutil.copy2(c_launcher, sh)
|
||||
os.chmod(sh,
|
||||
stat.S_IREAD | stat.S_IEXEC | stat.S_IWRITE | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
|
||||
if jobs:
|
||||
if not parallel_build(jobs, verbose=False):
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def is_elf(path):
|
||||
with open(path, 'rb') as f:
|
||||
return f.read(4) == b'\x7fELF'
|
||||
|
||||
|
||||
STRIPCMD = ['strip']
|
||||
|
||||
|
||||
def strip_files(files, argv_max=(256 * 1024)):
|
||||
""" Strip a list of files """
|
||||
while files:
|
||||
cmd = list(STRIPCMD)
|
||||
pathlen = sum(len(s) + 1 for s in cmd)
|
||||
while pathlen < argv_max and files:
|
||||
f = files.pop()
|
||||
cmd.append(f)
|
||||
pathlen += len(f) + 1
|
||||
if len(cmd) > len(STRIPCMD):
|
||||
all_files = cmd[len(STRIPCMD):]
|
||||
unwritable_files = tuple(filter(None, (None if os.access(x, os.W_OK) else (x, os.stat(x).st_mode) for x in all_files)))
|
||||
[os.chmod(x, stat.S_IWRITE | old_mode) for x, old_mode in unwritable_files]
|
||||
subprocess.check_call(cmd)
|
||||
[os.chmod(x, old_mode) for x, old_mode in unwritable_files]
|
||||
|
||||
|
||||
def strip_binaries(env):
|
||||
files = {j(env.bin_dir, x) for x in os.listdir(env.bin_dir)} | {
|
||||
x for x in {
|
||||
j(os.path.dirname(env.bin_dir), x) for x in os.listdir(env.bin_dir)} if os.path.exists(x)}
|
||||
for x in walk(env.lib_dir):
|
||||
x = os.path.realpath(x)
|
||||
if x not in files and is_elf(x):
|
||||
files.add(x)
|
||||
files.add(j(env.lib_dir, '..', 'libexec', 'QtWebEngineProcess'))
|
||||
print('Stripping %d files...' % len(files))
|
||||
before = sum(os.path.getsize(x) for x in files)
|
||||
strip_files(files)
|
||||
after = sum(os.path.getsize(x) for x in files)
|
||||
print('Stripped %.1f MB' % ((before - after) / (1024 * 1024.)))
|
||||
|
||||
|
||||
def create_tarfile(env, compression_level='9'):
|
||||
print('Creating archive...')
|
||||
base = OUTPUT_DIR
|
||||
try:
|
||||
shutil.rmtree(base)
|
||||
except EnvironmentError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
os.mkdir(base)
|
||||
dist = os.path.join(base, '%s-%s-%s.tar' % (calibre_constants['appname'], calibre_constants['version'], arch))
|
||||
with tarfile.open(dist, mode='w', format=tarfile.PAX_FORMAT) as tf:
|
||||
cwd = os.getcwd()
|
||||
os.chdir(env.base)
|
||||
try:
|
||||
for x in os.listdir('.'):
|
||||
tf.add(x)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
print('Compressing archive...')
|
||||
ans = dist.rpartition('.')[0] + '.txz'
|
||||
start_time = time.time()
|
||||
subprocess.check_call(['xz', '--threads=0', '-f', '-' + compression_level, dist])
|
||||
secs = time.time() - start_time
|
||||
print('Compressed in %d minutes %d seconds' % (secs // 60, secs % 60))
|
||||
os.rename(dist + '.xz', ans)
|
||||
print('Archive %s created: %.2f MB' % (
|
||||
os.path.basename(ans), os.stat(ans).st_size / (1024.**2)))
|
||||
|
||||
|
||||
def main():
|
||||
args = globals()['args']
|
||||
ext_dir = globals()['ext_dir']
|
||||
run_tests = iv['run_tests']
|
||||
env = Env()
|
||||
copy_libs(env)
|
||||
copy_python(env, ext_dir)
|
||||
build_launchers(env)
|
||||
if not args.skip_tests:
|
||||
run_tests(j(env.base, 'calibre-debug'), env.base)
|
||||
if not args.dont_strip:
|
||||
strip_binaries(env)
|
||||
create_tarfile(env, args.compression_level)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
49
bypy/linux/launcher.c
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* launcher.c
|
||||
* Copyright (C) 2014 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PATHLEN 1023
|
||||
|
||||
#define SET(x, y) if (setenv(x, y, 1) != 0) { fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); return 1; }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
static char buf[PATHLEN+1] = {0}, lib[PATHLEN+1] = {0}, base[PATHLEN+1] = {0}, exe[PATHLEN+1] = {0}, *ldp = NULL;
|
||||
|
||||
if (readlink("/proc/self/exe", buf, PATHLEN) == -1) {
|
||||
fprintf(stderr, "Failed to read path of executable with error: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
strncpy(lib, buf, PATHLEN);
|
||||
strncpy(base, dirname(lib), PATHLEN);
|
||||
snprintf(exe, PATHLEN, "%s/bin/%s", base, basename(buf));
|
||||
memset(lib, 0, PATHLEN);
|
||||
snprintf(lib, PATHLEN, "%s/lib", base);
|
||||
|
||||
/* qt-at-spi causes crashes and performance issues in various distros, so disable it */
|
||||
SET("QT_ACCESSIBILITY", "0")
|
||||
SET("CALIBRE_QT_PREFIX", base)
|
||||
|
||||
memset(buf, 0, PATHLEN);
|
||||
ldp = getenv("LD_LIBRARY_PATH");
|
||||
if (ldp == NULL) strncpy(buf, lib, PATHLEN);
|
||||
else snprintf(buf, PATHLEN, "%s:%s", lib, ldp);
|
||||
SET("LD_LIBRARY_PATH", buf)
|
||||
|
||||
argv[0] = exe;
|
||||
if (execv(exe, argv) == -1) {
|
||||
fprintf(stderr, "Failed to execute binary: %s with error: %s\n", exe, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
13
bypy/linux/main.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int ret = 0;
|
||||
set_gui_app(GUI_APP);
|
||||
ret = execute_python_entrypoint(argc, argv, BASENAME, MODULE, FUNCTION, NULL, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
88
bypy/linux/site.py
Normal file
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import sys
|
||||
import encodings # noqa
|
||||
import __builtin__
|
||||
import locale
|
||||
import os
|
||||
import codecs
|
||||
|
||||
|
||||
def set_default_encoding():
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except:
|
||||
print ('WARNING: Failed to set default libc locale, using en_US.UTF-8')
|
||||
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
|
||||
try:
|
||||
enc = locale.getdefaultlocale()[1]
|
||||
except Exception:
|
||||
enc = None
|
||||
if not enc:
|
||||
enc = locale.nl_langinfo(locale.CODESET)
|
||||
if not enc or enc.lower() == 'ascii':
|
||||
enc = 'UTF-8'
|
||||
try:
|
||||
enc = codecs.lookup(enc).name
|
||||
except LookupError:
|
||||
enc = 'UTF-8'
|
||||
sys.setdefaultencoding(enc)
|
||||
del sys.setdefaultencoding
|
||||
|
||||
|
||||
class _Helper(object):
|
||||
"""Define the builtin 'help'.
|
||||
This is a wrapper around pydoc.help (with a twist).
|
||||
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return "Type help() for interactive help, " \
|
||||
"or help(object) for help about object."
|
||||
|
||||
def __call__(self, *args, **kwds):
|
||||
import pydoc
|
||||
return pydoc.help(*args, **kwds)
|
||||
|
||||
|
||||
def set_helper():
|
||||
__builtin__.help = _Helper()
|
||||
|
||||
|
||||
def setup_openssl_environment():
|
||||
# Workaround for Linux distros that have still failed to get their heads
|
||||
# out of their asses and implement a common location for SSL certificates.
|
||||
# It's not that hard people, there exists a wonderful tool called the symlink
|
||||
# See http://www.mobileread.com/forums/showthread.php?t=256095
|
||||
if b'SSL_CERT_FILE' not in os.environ and b'SSL_CERT_DIR' not in os.environ:
|
||||
if os.access('/etc/pki/tls/certs/ca-bundle.crt', os.R_OK):
|
||||
os.environ['SSL_CERT_FILE'] = '/etc/pki/tls/certs/ca-bundle.crt'
|
||||
elif os.path.isdir('/etc/ssl/certs'):
|
||||
os.environ['SSL_CERT_DIR'] = '/etc/ssl/certs'
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
sys.argv[0] = sys.calibre_basename
|
||||
dfv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
||||
if dfv and os.path.exists(dfv):
|
||||
sys.path.insert(0, os.path.abspath(dfv))
|
||||
set_default_encoding()
|
||||
set_helper()
|
||||
setup_openssl_environment()
|
||||
mod = __import__(sys.calibre_module, fromlist=[1])
|
||||
func = getattr(mod, sys.calibre_function)
|
||||
return func()
|
||||
except SystemExit as err:
|
||||
if err.code is None:
|
||||
return 0
|
||||
if isinstance(err.code, int):
|
||||
return err.code
|
||||
print (err.code)
|
||||
return 1
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
262
bypy/linux/util.c
Normal file
@ -0,0 +1,262 @@
|
||||
#include "util.h"
|
||||
#include <Python.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
static bool GUI_APP = False;
|
||||
|
||||
static char exe_path[PATH_MAX];
|
||||
static char base_dir[PATH_MAX];
|
||||
static char bin_dir[PATH_MAX];
|
||||
static char lib_dir[PATH_MAX];
|
||||
static char extensions_dir[PATH_MAX];
|
||||
static char resources_dir[PATH_MAX];
|
||||
|
||||
void set_gui_app(bool yes) { GUI_APP = yes; }
|
||||
|
||||
int report_error(const char *msg, int code) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
return code;
|
||||
}
|
||||
|
||||
int report_libc_error(const char *msg) {
|
||||
char buf[2000];
|
||||
int err = errno;
|
||||
|
||||
snprintf(buf, 2000, "%s::%s", msg, strerror(err));
|
||||
return report_error(buf, err);
|
||||
}
|
||||
|
||||
int pyobject_to_int(PyObject *res) {
|
||||
int ret = 0; PyObject *tmp;
|
||||
if (res != NULL) {
|
||||
tmp = PyNumber_Int(res);
|
||||
if (tmp == NULL) ret = (PyObject_IsTrue(res)) ? 1 : 0;
|
||||
else ret = (int)PyInt_AS_LONG(tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int handle_sysexit(PyObject *e) {
|
||||
PyObject *code;
|
||||
|
||||
code = PyObject_GetAttrString(e, "code");
|
||||
if (!code) return 0;
|
||||
return pyobject_to_int(code);
|
||||
}
|
||||
|
||||
int report_python_error(const char *preamble, int code) {
|
||||
PyObject *exc, *val, *tb, *str;
|
||||
int ret, issysexit = 0; char *i, *buf;
|
||||
|
||||
if (!PyErr_Occurred()) return code;
|
||||
issysexit = PyErr_ExceptionMatches(PyExc_SystemExit);
|
||||
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
|
||||
if (exc != NULL) {
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
|
||||
if (issysexit) {
|
||||
return (val) ? handle_sysexit(val) : 0;
|
||||
}
|
||||
if (val != NULL) {
|
||||
str = PyObject_Unicode(val);
|
||||
if (str == NULL) {
|
||||
PyErr_Clear();
|
||||
str = PyObject_Str(val);
|
||||
}
|
||||
i = PyString_AsString(str);
|
||||
if (i == NULL) OOM;
|
||||
buf = (char*)calloc(strlen(i)+strlen(preamble)+5, sizeof(char));
|
||||
if (buf == NULL) OOM;
|
||||
sprintf(buf, "%s::%s", preamble, i);
|
||||
ret = report_error(buf, code);
|
||||
if (buf) free(buf);
|
||||
if (tb != NULL) {
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyErr_Print();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return report_error(preamble, code);
|
||||
}
|
||||
|
||||
static void get_paths()
|
||||
{
|
||||
char linkname[256]; /* /proc/<pid>/exe */
|
||||
char *p;
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid) < 0)
|
||||
{
|
||||
/* This should only happen on large word systems. I'm not sure
|
||||
what the proper response is here.
|
||||
Since it really is an assert-like condition, aborting the
|
||||
program seems to be in order. */
|
||||
exit(report_error("PID too large", EXIT_FAILURE));
|
||||
}
|
||||
|
||||
|
||||
ret = readlink(linkname, exe_path, sizeof(exe_path));
|
||||
|
||||
if (ret == -1) {
|
||||
exit(report_error("Failed to read exe path.", EXIT_FAILURE));
|
||||
}
|
||||
|
||||
if ((size_t)ret >= sizeof(exe_path)) {
|
||||
exit(report_error("exe path buffer too small.", EXIT_FAILURE));
|
||||
}
|
||||
|
||||
exe_path[ret] = 0;
|
||||
|
||||
p = rindex(exe_path, '/');
|
||||
|
||||
if (p == NULL) {
|
||||
exit(report_error("No path separators in executable path", EXIT_FAILURE));
|
||||
}
|
||||
strncat(base_dir, exe_path, p - exe_path);
|
||||
p = rindex(base_dir, '/');
|
||||
if (p == NULL) {
|
||||
exit(report_error("Only one path separator in executable path", EXIT_FAILURE));
|
||||
}
|
||||
*p = 0;
|
||||
if (strlen(base_dir) == 0) {
|
||||
exit(report_error("base directory empty", EXIT_FAILURE));
|
||||
}
|
||||
|
||||
snprintf(bin_dir, sizeof(bin_dir), "%s/bin", base_dir);
|
||||
snprintf(lib_dir, sizeof(lib_dir), "%s/lib", base_dir);
|
||||
snprintf(resources_dir, sizeof(resources_dir), "%s/resources", base_dir);
|
||||
snprintf(extensions_dir, sizeof(extensions_dir), "%s/%s/site-packages/calibre/plugins", lib_dir, PYTHON_VER);
|
||||
}
|
||||
|
||||
|
||||
void setup_stream(const char *name, const char *errors) {
|
||||
PyObject *stream;
|
||||
char buf[100];
|
||||
|
||||
snprintf(buf, 20, "%s", name);
|
||||
stream = PySys_GetObject(buf);
|
||||
|
||||
snprintf(buf, 20, "%s", "utf-8");
|
||||
snprintf(buf+21, 30, "%s", errors);
|
||||
|
||||
if (!PyFile_SetEncodingAndErrors(stream, buf, buf+21))
|
||||
exit(report_python_error("Failed to set stream encoding", 1));
|
||||
|
||||
}
|
||||
|
||||
void setup_streams() {
|
||||
if (!GUI_APP) { // Remove buffering
|
||||
setvbuf(stdin, NULL, _IONBF, 2);
|
||||
setvbuf(stdout, NULL, _IONBF, 2);
|
||||
setvbuf(stderr, NULL, _IONBF, 2);
|
||||
}
|
||||
|
||||
/*setup_stream("stdin", "strict");
|
||||
setup_stream("stdout", "strict");
|
||||
setup_stream("stderr", "strict");*/
|
||||
}
|
||||
|
||||
void initialize_interpreter(int argc, char **argv, char *outr, char *errr,
|
||||
const char *basename, const char *module, const char *function) {
|
||||
char *encoding, *p;
|
||||
|
||||
get_paths();
|
||||
char path[3*PATH_MAX];
|
||||
|
||||
snprintf(path, sizeof(path),
|
||||
"%s/%s:%s/%s/plat-linux2:%s/%s/lib-dynload:%s/%s/site-packages",
|
||||
lib_dir, PYTHON_VER, lib_dir, PYTHON_VER, lib_dir, PYTHON_VER,
|
||||
lib_dir, PYTHON_VER);
|
||||
|
||||
Py_OptimizeFlag = 2;
|
||||
Py_NoSiteFlag = 1;
|
||||
Py_DontWriteBytecodeFlag = 1;
|
||||
Py_IgnoreEnvironmentFlag = 1;
|
||||
Py_NoUserSiteDirectory = 1;
|
||||
Py_VerboseFlag = 0;
|
||||
Py_DebugFlag = 0;
|
||||
Py_HashRandomizationFlag = 1;
|
||||
|
||||
Py_SetProgramName(exe_path);
|
||||
Py_SetPythonHome(base_dir);
|
||||
|
||||
//printf("Path before Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
Py_Initialize();
|
||||
if (!Py_FileSystemDefaultEncoding) {
|
||||
encoding = getenv("PYTHONIOENCODING");
|
||||
if (encoding != NULL) {
|
||||
Py_FileSystemDefaultEncoding = strndup(encoding, 20);
|
||||
p = index(Py_FileSystemDefaultEncoding, ':');
|
||||
if (p != NULL) *p = 0;
|
||||
} else
|
||||
Py_FileSystemDefaultEncoding = strndup("UTF-8", 10);
|
||||
}
|
||||
|
||||
|
||||
setup_streams();
|
||||
|
||||
PySys_SetArgv(argc, argv);
|
||||
//printf("Path after Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
PySys_SetPath(path);
|
||||
//printf("Path set by me: %s\r\n\n", path);
|
||||
PySys_SetObject("gui_app", PyBool_FromLong((long)GUI_APP));
|
||||
PySys_SetObject("calibre_basename", PyBytes_FromString(basename));
|
||||
PySys_SetObject("calibre_module", PyBytes_FromString(module));
|
||||
PySys_SetObject("calibre_function", PyBytes_FromString(function));
|
||||
PySys_SetObject("extensions_location", PyBytes_FromString(extensions_dir));
|
||||
PySys_SetObject("resources_location", PyBytes_FromString(resources_dir));
|
||||
PySys_SetObject("executables_location", PyBytes_FromString(base_dir));
|
||||
PySys_SetObject("frozen_path", PyBytes_FromString(base_dir));
|
||||
PySys_SetObject("frozen", Py_True);
|
||||
Py_INCREF(Py_True);
|
||||
|
||||
|
||||
if (GUI_APP && outr && errr) {
|
||||
// PySys_SetObject("stdout_redirect", PyUnicode_FromWideChar(outr, wcslen(outr)));
|
||||
// PySys_SetObject("stderr_redirect", PyUnicode_FromWideChar(errr, wcslen(outr)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int execute_python_entrypoint(int argc, char **argv, const char *basename, const char *module, const char *function,
|
||||
char *outr, char *errr) {
|
||||
PyObject *site, *pmain, *res;
|
||||
int ret = 0;
|
||||
|
||||
initialize_interpreter(argc, argv, outr, errr, basename, module, function);
|
||||
|
||||
site = PyImport_ImportModule("site");
|
||||
|
||||
if (site == NULL)
|
||||
ret = report_python_error("Failed to import site module", 1);
|
||||
else {
|
||||
Py_XINCREF(site);
|
||||
|
||||
pmain = PyObject_GetAttrString(site, "main");
|
||||
if (pmain == NULL || !PyCallable_Check(pmain))
|
||||
ret = report_python_error("site module has no main function", 1);
|
||||
else {
|
||||
Py_XINCREF(pmain);
|
||||
res = PyObject_CallObject(pmain, NULL);
|
||||
|
||||
if (res == NULL)
|
||||
ret = report_python_error("Python function terminated unexpectedly", 1);
|
||||
|
||||
ret = pyobject_to_int(res);
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
Py_Finalize();
|
||||
|
||||
//printf("11111 Returning: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
18
bypy/linux/util.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#define UNICODE
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#define OOM exit(report_error("Out of memory", EXIT_FAILURE))
|
||||
#define True 1
|
||||
#define False 0
|
||||
typedef int bool;
|
||||
|
||||
void set_gui_app(bool yes);
|
||||
|
||||
int execute_python_entrypoint(int argc, char **argv, const char *basename,
|
||||
const char *module, const char *function,
|
||||
char *outr, char *errr);
|
6
bypy/macos.conf
Normal file
@ -0,0 +1,6 @@
|
||||
# Requires installation of XCode 10.2 and Python 3.7 and
|
||||
# python3 -m pip install certifi
|
||||
|
||||
vm_name 'calibre-macos-build'
|
||||
root '/Users/Shared/calibre-build'
|
||||
python '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3'
|
782
bypy/macos/__main__.py
Normal file
@ -0,0 +1,782 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import errno
|
||||
import glob
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
import plistlib
|
||||
import runpy
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import zipfile
|
||||
from functools import partial, reduce
|
||||
from itertools import repeat
|
||||
|
||||
from bypy.constants import (
|
||||
OUTPUT_DIR, PREFIX, PYTHON, SRC as CALIBRE_DIR, python_major_minor_version
|
||||
)
|
||||
from bypy.utils import current_dir, mkdtemp, py_compile, timeit, walk
|
||||
|
||||
abspath, join, basename, dirname = os.path.abspath, os.path.join, os.path.basename, os.path.dirname
|
||||
iv = globals()['init_env']
|
||||
calibre_constants = iv['calibre_constants']
|
||||
QT_DLLS, QT_PLUGINS, PYQT_MODULES = iv['QT_DLLS'], iv['QT_PLUGINS'], iv['PYQT_MODULES']
|
||||
py_ver = '.'.join(map(str, python_major_minor_version()))
|
||||
sign_app = runpy.run_path(join(dirname(abspath(__file__)), 'sign.py'))['sign_app']
|
||||
|
||||
QT_PREFIX = join(PREFIX, 'qt')
|
||||
QT_FRAMEWORKS = [x.replace('5', '') for x in QT_DLLS]
|
||||
|
||||
ENV = dict(
|
||||
FONTCONFIG_PATH='@executable_path/../Resources/fonts',
|
||||
FONTCONFIG_FILE='@executable_path/../Resources/fonts/fonts.conf',
|
||||
PYTHONIOENCODING='UTF-8',
|
||||
SSL_CERT_FILE='@executable_path/../Resources/resources/mozilla-ca-certs.pem',
|
||||
)
|
||||
APPNAME, VERSION = calibre_constants['appname'], calibre_constants['version']
|
||||
basenames, main_modules, main_functions = calibre_constants['basenames'], calibre_constants['modules'], calibre_constants['functions']
|
||||
|
||||
|
||||
def compile_launcher_lib(contents_dir, gcc, base):
|
||||
print('\tCompiling calibre_launcher.dylib')
|
||||
fd = join(contents_dir, 'Frameworks')
|
||||
dest = join(fd, 'calibre-launcher.dylib')
|
||||
src = join(base, 'util.c')
|
||||
cmd = [gcc] + '-Wall -dynamiclib -std=gnu99'.split() + [src] + \
|
||||
['-I' + base] + \
|
||||
['-I%s/python/Python.framework/Versions/Current/Headers' % PREFIX] + \
|
||||
'-current_version 1.0 -compatibility_version 1.0'.split() + \
|
||||
'-fvisibility=hidden -o'.split() + [dest] + \
|
||||
['-install_name',
|
||||
'@executable_path/../Frameworks/' + os.path.basename(dest)] + \
|
||||
[('-F%s/python' % PREFIX), '-framework', 'Python', '-framework', 'CoreFoundation', '-headerpad_max_install_names']
|
||||
# print('\t'+' '.join(cmd))
|
||||
sys.stdout.flush()
|
||||
subprocess.check_call(cmd)
|
||||
return dest
|
||||
|
||||
|
||||
gcc = os.environ.get('CC', 'clang')
|
||||
|
||||
|
||||
def compile_launchers(contents_dir, xprograms, pyver):
|
||||
base = dirname(abspath(__file__))
|
||||
lib = compile_launcher_lib(contents_dir, gcc, base)
|
||||
with open(join(base, 'launcher.c'), 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
env, env_vals = [], []
|
||||
for key, val in ENV.items():
|
||||
env.append('"%s"' % key)
|
||||
env_vals.append('"%s"' % val)
|
||||
env = ', '.join(env) + ', '
|
||||
env_vals = ', '.join(env_vals) + ', '
|
||||
src = src.replace('/*ENV_VARS*/', env)
|
||||
src = src.replace('/*ENV_VAR_VALS*/', env_vals)
|
||||
programs = [lib]
|
||||
for program, x in xprograms.items():
|
||||
module, func, ptype = x
|
||||
print('\tCompiling', program)
|
||||
out = join(contents_dir, 'MacOS', program)
|
||||
programs.append(out)
|
||||
psrc = src.replace('**PROGRAM**', program)
|
||||
psrc = psrc.replace('**MODULE**', module)
|
||||
psrc = psrc.replace('**FUNCTION**', func)
|
||||
psrc = psrc.replace('**PYVER**', pyver)
|
||||
psrc = psrc.replace('**IS_GUI**', ('1' if ptype == 'gui' else '0'))
|
||||
fsrc = '/tmp/%s.c' % program
|
||||
with open(fsrc, 'wb') as f:
|
||||
f.write(psrc.encode('utf-8'))
|
||||
cmd = [gcc, '-Wall', '-I' + base, fsrc, lib, '-o', out,
|
||||
'-headerpad_max_install_names']
|
||||
# print('\t'+' '.join(cmd))
|
||||
sys.stdout.flush()
|
||||
subprocess.check_call(cmd)
|
||||
return programs
|
||||
|
||||
|
||||
def flipwritable(fn, mode=None):
|
||||
"""
|
||||
Flip the writability of a file and return the old mode. Returns None
|
||||
if the file is already writable.
|
||||
"""
|
||||
if os.access(fn, os.W_OK):
|
||||
return None
|
||||
old_mode = os.stat(fn).st_mode
|
||||
os.chmod(fn, stat.S_IWRITE | old_mode)
|
||||
return old_mode
|
||||
|
||||
|
||||
STRIPCMD = ['/usr/bin/strip', '-x', '-S', '-']
|
||||
|
||||
|
||||
def strip_files(files, argv_max=(256 * 1024)):
|
||||
"""
|
||||
Strip a list of files
|
||||
"""
|
||||
tostrip = [(fn, flipwritable(fn)) for fn in files if os.path.exists(fn)]
|
||||
while tostrip:
|
||||
cmd = list(STRIPCMD)
|
||||
flips = []
|
||||
pathlen = reduce(operator.add, [len(s) + 1 for s in cmd])
|
||||
while pathlen < argv_max:
|
||||
if not tostrip:
|
||||
break
|
||||
added, flip = tostrip.pop()
|
||||
pathlen += len(added) + 1
|
||||
cmd.append(added)
|
||||
flips.append((added, flip))
|
||||
else:
|
||||
cmd.pop()
|
||||
tostrip.append(flips.pop())
|
||||
os.spawnv(os.P_WAIT, cmd[0], cmd)
|
||||
for args in flips:
|
||||
flipwritable(*args)
|
||||
|
||||
|
||||
def flush(func):
|
||||
def ff(*args, **kwargs):
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
ret = func(*args, **kwargs)
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
return ret
|
||||
return ff
|
||||
|
||||
|
||||
class Freeze(object):
|
||||
|
||||
FID = '@executable_path/../Frameworks'
|
||||
|
||||
def __init__(self, build_dir, ext_dir, test_runner, test_launchers=False, dont_strip=False, sign_installers=False, notarize=False):
|
||||
self.build_dir = os.path.realpath(build_dir)
|
||||
self.sign_installers = sign_installers
|
||||
self.notarize = notarize
|
||||
self.ext_dir = os.path.realpath(ext_dir)
|
||||
self.test_runner = test_runner
|
||||
self.dont_strip = dont_strip
|
||||
self.contents_dir = join(self.build_dir, 'Contents')
|
||||
self.resources_dir = join(self.contents_dir, 'Resources')
|
||||
self.frameworks_dir = join(self.contents_dir, 'Frameworks')
|
||||
self.exe_dir = join(self.contents_dir, 'MacOS')
|
||||
self.helpers_dir = join(self.contents_dir, 'utils.app', 'Contents', 'MacOS')
|
||||
self.site_packages = join(self.resources_dir, 'Python', 'site-packages')
|
||||
self.to_strip = []
|
||||
self.warnings = []
|
||||
|
||||
self.run(test_launchers)
|
||||
|
||||
def run(self, test_launchers):
|
||||
ret = 0
|
||||
if not test_launchers:
|
||||
if os.path.exists(self.build_dir):
|
||||
shutil.rmtree(self.build_dir)
|
||||
os.makedirs(self.build_dir)
|
||||
self.create_skeleton()
|
||||
self.create_plist()
|
||||
|
||||
self.add_python_framework()
|
||||
self.add_site_packages()
|
||||
self.add_stdlib()
|
||||
self.add_qt_frameworks()
|
||||
self.add_calibre_plugins()
|
||||
self.add_podofo()
|
||||
self.add_poppler()
|
||||
self.add_imaging_libs()
|
||||
self.add_fontconfig()
|
||||
self.add_misc_libraries()
|
||||
|
||||
self.add_resources()
|
||||
self.compile_py_modules()
|
||||
|
||||
self.copy_site()
|
||||
self.create_exe()
|
||||
if not test_launchers and not self.dont_strip:
|
||||
self.strip_files()
|
||||
if not test_launchers:
|
||||
self.create_gui_apps()
|
||||
|
||||
self.run_tests()
|
||||
ret = self.makedmg(self.build_dir, APPNAME + '-' + VERSION)
|
||||
|
||||
return ret
|
||||
|
||||
@flush
|
||||
def run_tests(self):
|
||||
self.test_runner(join(self.contents_dir, 'MacOS', 'calibre-debug'), self.contents_dir)
|
||||
|
||||
@flush
|
||||
def add_resources(self):
|
||||
shutil.copytree('resources', join(self.resources_dir,
|
||||
'resources'))
|
||||
|
||||
@flush
|
||||
def strip_files(self):
|
||||
print('\nStripping files...')
|
||||
strip_files(self.to_strip)
|
||||
|
||||
@flush
|
||||
def create_exe(self):
|
||||
print('\nCreating launchers')
|
||||
programs = {}
|
||||
progs = []
|
||||
for x in ('console', 'gui'):
|
||||
progs += list(zip(basenames[x], main_modules[x], main_functions[x], repeat(x)))
|
||||
for program, module, func, ptype in progs:
|
||||
programs[program] = (module, func, ptype)
|
||||
programs = compile_launchers(self.contents_dir, programs, py_ver)
|
||||
for out in programs:
|
||||
self.fix_dependencies_in_lib(out)
|
||||
|
||||
@flush
|
||||
def set_id(self, path_to_lib, new_id):
|
||||
old_mode = flipwritable(path_to_lib)
|
||||
subprocess.check_call(['install_name_tool', '-id', new_id, path_to_lib])
|
||||
if old_mode is not None:
|
||||
flipwritable(path_to_lib, old_mode)
|
||||
|
||||
@flush
|
||||
def get_dependencies(self, path_to_lib):
|
||||
install_name = subprocess.check_output(['otool', '-D', path_to_lib]).splitlines()[-1].strip()
|
||||
raw = subprocess.check_output(['otool', '-L', path_to_lib]).decode('utf-8')
|
||||
for line in raw.splitlines():
|
||||
if 'compatibility' not in line or line.strip().endswith(':'):
|
||||
continue
|
||||
idx = line.find('(')
|
||||
path = line[:idx].strip()
|
||||
yield path, path == install_name
|
||||
|
||||
@flush
|
||||
def get_local_dependencies(self, path_to_lib):
|
||||
for x, is_id in self.get_dependencies(path_to_lib):
|
||||
if x.startswith('@rpath/Qt'):
|
||||
yield x, x[len('@rpath/'):], is_id
|
||||
else:
|
||||
for y in (PREFIX + '/lib/', PREFIX + '/python/Python.framework/'):
|
||||
if x.startswith(y):
|
||||
if y == PREFIX + '/python/Python.framework/':
|
||||
y = PREFIX + '/python/'
|
||||
yield x, x[len(y):], is_id
|
||||
break
|
||||
|
||||
@flush
|
||||
def change_dep(self, old_dep, new_dep, is_id, path_to_lib):
|
||||
cmd = ['-id', new_dep] if is_id else ['-change', old_dep, new_dep]
|
||||
subprocess.check_call(['install_name_tool'] + cmd + [path_to_lib])
|
||||
|
||||
@flush
|
||||
def fix_dependencies_in_lib(self, path_to_lib):
|
||||
self.to_strip.append(path_to_lib)
|
||||
old_mode = flipwritable(path_to_lib)
|
||||
for dep, bname, is_id in self.get_local_dependencies(path_to_lib):
|
||||
ndep = self.FID + '/' + bname
|
||||
self.change_dep(dep, ndep, is_id, path_to_lib)
|
||||
ldeps = list(self.get_local_dependencies(path_to_lib))
|
||||
if ldeps:
|
||||
print('\nFailed to fix dependencies in', path_to_lib)
|
||||
print('Remaining local dependencies:', ldeps)
|
||||
raise SystemExit(1)
|
||||
if old_mode is not None:
|
||||
flipwritable(path_to_lib, old_mode)
|
||||
|
||||
@flush
|
||||
def add_python_framework(self):
|
||||
print('\nAdding Python framework')
|
||||
src = join(PREFIX + '/python', 'Python.framework')
|
||||
x = join(self.frameworks_dir, 'Python.framework')
|
||||
curr = os.path.realpath(join(src, 'Versions', 'Current'))
|
||||
currd = join(x, 'Versions', basename(curr))
|
||||
rd = join(currd, 'Resources')
|
||||
os.makedirs(rd)
|
||||
shutil.copy2(join(curr, 'Resources', 'Info.plist'), rd)
|
||||
shutil.copy2(join(curr, 'Python'), currd)
|
||||
self.set_id(join(currd, 'Python'),
|
||||
self.FID + '/Python.framework/Versions/%s/Python' % basename(curr))
|
||||
# The following is needed for codesign in OS X >= 10.9.5
|
||||
with current_dir(x):
|
||||
os.symlink(basename(curr), 'Versions/Current')
|
||||
for y in ('Python', 'Resources'):
|
||||
os.symlink('Versions/Current/%s' % y, y)
|
||||
|
||||
@flush
|
||||
def add_qt_frameworks(self):
|
||||
print('\nAdding Qt Frameworks')
|
||||
for f in QT_FRAMEWORKS:
|
||||
self.add_qt_framework(f)
|
||||
pdir = join(QT_PREFIX, 'plugins')
|
||||
ddir = join(self.contents_dir, 'PlugIns')
|
||||
os.mkdir(ddir)
|
||||
for x in QT_PLUGINS:
|
||||
shutil.copytree(join(pdir, x), join(ddir, x))
|
||||
for l in glob.glob(join(ddir, '*/*.dylib')):
|
||||
self.fix_dependencies_in_lib(l)
|
||||
x = os.path.relpath(l, ddir)
|
||||
self.set_id(l, '@executable_path/' + x)
|
||||
webengine_process = join(
|
||||
self.frameworks_dir, 'QtWebEngineCore.framework/Versions/5/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess')
|
||||
self.fix_dependencies_in_lib(webengine_process)
|
||||
cdir = dirname(dirname(webengine_process))
|
||||
dest = join(cdir, 'Frameworks')
|
||||
os.symlink(os.path.relpath(self.frameworks_dir, cdir), dest)
|
||||
|
||||
def add_qt_framework(self, f):
|
||||
libname = f
|
||||
f = f + '.framework'
|
||||
src = join(PREFIX, 'qt', 'lib', f)
|
||||
ignore = shutil.ignore_patterns('Headers', '*.h', 'Headers/*')
|
||||
dest = join(self.frameworks_dir, f)
|
||||
shutil.copytree(src, dest, symlinks=True,
|
||||
ignore=ignore)
|
||||
lib = os.path.realpath(join(dest, libname))
|
||||
rpath = os.path.relpath(lib, self.frameworks_dir)
|
||||
self.set_id(lib, self.FID + '/' + rpath)
|
||||
self.fix_dependencies_in_lib(lib)
|
||||
# The following is needed for codesign in OS X >= 10.9.5
|
||||
# The presence of the .prl file in the root of the framework causes
|
||||
# codesign to fail.
|
||||
with current_dir(dest):
|
||||
for x in os.listdir('.'):
|
||||
if x != 'Versions' and not os.path.islink(x):
|
||||
os.remove(x)
|
||||
|
||||
@flush
|
||||
def create_skeleton(self):
|
||||
c = join(self.build_dir, 'Contents')
|
||||
for x in ('Frameworks', 'MacOS', 'Resources'):
|
||||
os.makedirs(join(c, x))
|
||||
icons = glob.glob(join(CALIBRE_DIR, 'icons', 'icns', '*.iconset'))
|
||||
if not icons:
|
||||
raise SystemExit('Failed to find icns format icons')
|
||||
for x in icons:
|
||||
subprocess.check_call([
|
||||
'iconutil', '-c', 'icns', x, '-o', join(
|
||||
self.resources_dir, basename(x).partition('.')[0] + '.icns')])
|
||||
for helpers in (self.helpers_dir,):
|
||||
os.makedirs(helpers)
|
||||
cdir = dirname(helpers)
|
||||
dest = join(cdir, 'Frameworks')
|
||||
src = self.frameworks_dir
|
||||
os.symlink(os.path.relpath(src, cdir), dest)
|
||||
dest = join(cdir, 'Resources')
|
||||
src = self.resources_dir
|
||||
os.symlink(os.path.relpath(src, cdir), dest)
|
||||
pl = dict(
|
||||
CFBundleDevelopmentRegion='English',
|
||||
CFBundleDisplayName=APPNAME + ' - utils',
|
||||
CFBundleName=APPNAME + '-utils',
|
||||
CFBundleIdentifier='com.calibre-ebook.utils',
|
||||
LSBackgroundOnly='1',
|
||||
CFBundleVersion=VERSION,
|
||||
CFBundleShortVersionString=VERSION,
|
||||
CFBundlePackageType='APPL',
|
||||
CFBundleSignature='????',
|
||||
CFBundleExecutable='pdftohtml',
|
||||
LSMinimumSystemVersion='10.14.0',
|
||||
LSRequiresNativeExecution=True,
|
||||
NSAppleScriptEnabled=False,
|
||||
CFBundleIconFile='',
|
||||
)
|
||||
with open(join(cdir, 'Info.plist'), 'wb') as p:
|
||||
plistlib.dump(pl, p)
|
||||
|
||||
@flush
|
||||
def add_calibre_plugins(self):
|
||||
dest = join(self.frameworks_dir, 'plugins')
|
||||
os.mkdir(dest)
|
||||
plugins = glob.glob(self.ext_dir + '/*.so')
|
||||
if not plugins:
|
||||
raise SystemExit('No calibre plugins found in: ' + self.ext_dir)
|
||||
for f in plugins:
|
||||
shutil.copy2(f, dest)
|
||||
self.fix_dependencies_in_lib(join(dest, basename(f)))
|
||||
if f.endswith('/podofo.so'):
|
||||
self.change_dep('libpodofo.0.9.6.dylib',
|
||||
'@executable_path/../Frameworks/libpodofo.0.9.6.dylib', False, join(dest, basename(f)))
|
||||
|
||||
@flush
|
||||
def create_plist(self):
|
||||
BOOK_EXTENSIONS = calibre_constants['book_extensions']
|
||||
env = dict(**ENV)
|
||||
env['CALIBRE_LAUNCHED_FROM_BUNDLE'] = '1'
|
||||
docs = [{'CFBundleTypeName': 'E-book',
|
||||
'CFBundleTypeExtensions': list(BOOK_EXTENSIONS),
|
||||
'CFBundleTypeIconFile': 'book.icns',
|
||||
'CFBundleTypeRole': 'Viewer',
|
||||
}]
|
||||
|
||||
pl = dict(
|
||||
CFBundleDevelopmentRegion='English',
|
||||
CFBundleDisplayName=APPNAME,
|
||||
CFBundleName=APPNAME,
|
||||
CFBundleIdentifier='net.kovidgoyal.calibre',
|
||||
CFBundleVersion=VERSION,
|
||||
CFBundleShortVersionString=VERSION,
|
||||
CFBundlePackageType='APPL',
|
||||
CFBundleSignature='????',
|
||||
CFBundleExecutable='calibre',
|
||||
CFBundleDocumentTypes=docs,
|
||||
LSMinimumSystemVersion='10.14.0',
|
||||
LSRequiresNativeExecution=True,
|
||||
NSAppleScriptEnabled=False,
|
||||
NSSupportsAutomaticGraphicsSwitching=True,
|
||||
NSHumanReadableCopyright=time.strftime('Copyright %Y, Kovid Goyal'),
|
||||
CFBundleGetInfoString=('calibre, an E-book management '
|
||||
'application. Visit https://calibre-ebook.com for details.'),
|
||||
CFBundleIconFile='calibre.icns',
|
||||
NSHighResolutionCapable=True,
|
||||
LSApplicationCategoryType='public.app-category.productivity',
|
||||
LSEnvironment=env
|
||||
)
|
||||
with open(join(self.contents_dir, 'Info.plist'), 'wb') as p:
|
||||
plistlib.dump(pl, p)
|
||||
|
||||
@flush
|
||||
def install_dylib(self, path, set_id=True, dest=None):
|
||||
dest = dest or self.frameworks_dir
|
||||
os.makedirs(dest, exist_ok=True)
|
||||
shutil.copy2(path, dest)
|
||||
if set_id:
|
||||
self.set_id(join(dest, basename(path)),
|
||||
self.FID + '/' + basename(path))
|
||||
self.fix_dependencies_in_lib(join(dest, basename(path)))
|
||||
|
||||
@flush
|
||||
def add_podofo(self):
|
||||
print('\nAdding PoDoFo')
|
||||
pdf = join(PREFIX, 'lib', 'libpodofo.0.9.6.dylib')
|
||||
self.install_dylib(pdf)
|
||||
|
||||
@flush
|
||||
def add_poppler(self):
|
||||
print('\nAdding poppler')
|
||||
for x in ('libopenjp2.7.dylib', 'libpoppler.87.dylib',):
|
||||
self.install_dylib(join(PREFIX, 'lib', x))
|
||||
for x in ('pdftohtml', 'pdftoppm', 'pdfinfo'):
|
||||
self.install_dylib(
|
||||
join(PREFIX, 'bin', x), set_id=False, dest=self.helpers_dir)
|
||||
|
||||
@flush
|
||||
def add_imaging_libs(self):
|
||||
print('\nAdding libjpeg, libpng, libwebp, optipng and mozjpeg')
|
||||
for x in ('jpeg.8', 'png16.16', 'webp.7', 'webpmux.3', 'webpdemux.2'):
|
||||
self.install_dylib(join(PREFIX, 'lib', 'lib%s.dylib' % x))
|
||||
for x in 'optipng', 'JxrDecApp':
|
||||
self.install_dylib(join(PREFIX, 'bin', x), set_id=False, dest=self.helpers_dir)
|
||||
for x in ('jpegtran', 'cjpeg'):
|
||||
self.install_dylib(
|
||||
join(PREFIX, 'private', 'mozjpeg', 'bin', x), set_id=False, dest=self.helpers_dir)
|
||||
|
||||
@flush
|
||||
def add_fontconfig(self):
|
||||
print('\nAdding fontconfig')
|
||||
for x in ('fontconfig.1', 'freetype.6', 'expat.1'):
|
||||
src = join(PREFIX, 'lib', 'lib' + x + '.dylib')
|
||||
self.install_dylib(src)
|
||||
dst = join(self.resources_dir, 'fonts')
|
||||
if os.path.exists(dst):
|
||||
shutil.rmtree(dst)
|
||||
src = join(PREFIX, 'etc', 'fonts')
|
||||
shutil.copytree(src, dst, symlinks=False)
|
||||
fc = join(dst, 'fonts.conf')
|
||||
with open(fc, 'rb') as f:
|
||||
raw = f.read().decode('utf-8')
|
||||
raw = raw.replace('<dir>/usr/share/fonts</dir>', '''\
|
||||
<dir>/Library/Fonts</dir>
|
||||
<dir>/System/Library/Fonts</dir>
|
||||
<dir>/usr/X11R6/lib/X11/fonts</dir>
|
||||
<dir>/usr/share/fonts</dir>
|
||||
<dir>/var/root/Library/Fonts</dir>
|
||||
<dir>/usr/share/fonts</dir>
|
||||
''')
|
||||
open(fc, 'wb').write(raw.encode('utf-8'))
|
||||
|
||||
@flush
|
||||
def add_misc_libraries(self):
|
||||
for x in (
|
||||
'usb-1.0.0', 'mtp.9', 'chm.0', 'sqlite3.0', 'hunspell-1.7.0',
|
||||
'icudata.64', 'icui18n.64', 'icuio.64', 'icuuc.64', 'hyphen.0',
|
||||
'xslt.1', 'exslt.0', 'xml2.2', 'z.1', 'unrar',
|
||||
'crypto.1.0.0', 'ssl.1.0.0', 'iconv.2', # 'ltdl.7'
|
||||
):
|
||||
print('\nAdding', x)
|
||||
x = 'lib%s.dylib' % x
|
||||
src = join(PREFIX, 'lib', x)
|
||||
shutil.copy2(src, self.frameworks_dir)
|
||||
dest = join(self.frameworks_dir, x)
|
||||
self.set_id(dest, self.FID + '/' + x)
|
||||
self.fix_dependencies_in_lib(dest)
|
||||
|
||||
@flush
|
||||
def add_site_packages(self):
|
||||
print('\nAdding site-packages')
|
||||
os.makedirs(self.site_packages)
|
||||
sys_path = json.loads(subprocess.check_output([
|
||||
PYTHON, '-c', 'import sys, json; json.dump(sys.path, sys.stdout)']))
|
||||
paths = reversed(tuple(map(abspath, [x for x in sys_path if x.startswith('/') and not x.startswith('/Library/')])))
|
||||
upaths = []
|
||||
for x in paths:
|
||||
if x not in upaths and (x.endswith('.egg') or x.endswith('/site-packages')):
|
||||
upaths.append(x)
|
||||
upaths.append(join(CALIBRE_DIR, 'src'))
|
||||
for x in upaths:
|
||||
print('\t', x)
|
||||
tdir = None
|
||||
try:
|
||||
if not os.path.isdir(x):
|
||||
zf = zipfile.ZipFile(x)
|
||||
tdir = tempfile.mkdtemp()
|
||||
zf.extractall(tdir)
|
||||
x = tdir
|
||||
self.add_modules_from_dir(x)
|
||||
self.add_packages_from_dir(x)
|
||||
finally:
|
||||
if tdir is not None:
|
||||
shutil.rmtree(tdir)
|
||||
try:
|
||||
shutil.rmtree(join(self.site_packages, 'calibre', 'plugins'))
|
||||
except OSError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
sp = join(self.resources_dir, 'Python', 'site-packages')
|
||||
for x in os.listdir(join(sp, 'PyQt5')):
|
||||
if x.endswith('.so') and x.rpartition('.')[0] not in PYQT_MODULES and x != 'sip.so':
|
||||
os.remove(join(sp, 'PyQt5', x))
|
||||
os.remove(join(sp, 'PyQt5', 'uic/port_v3/proxy_base.py'))
|
||||
self.remove_bytecode(sp)
|
||||
|
||||
@flush
|
||||
def add_modules_from_dir(self, src):
|
||||
for x in glob.glob(join(src, '*.py')) + glob.glob(join(src, '*.so')):
|
||||
dest = join(self.site_packages, os.path.basename(x))
|
||||
shutil.copy2(x, dest)
|
||||
if x.endswith('.so'):
|
||||
self.fix_dependencies_in_lib(dest)
|
||||
|
||||
@flush
|
||||
def add_packages_from_dir(self, src):
|
||||
for x in os.listdir(src):
|
||||
x = join(src, x)
|
||||
if os.path.isdir(x) and os.path.exists(join(x, '__init__.py')):
|
||||
if self.filter_package(basename(x)):
|
||||
continue
|
||||
self.add_package_dir(x)
|
||||
|
||||
@flush
|
||||
def add_package_dir(self, x, dest=None):
|
||||
def ignore(root, files):
|
||||
ans = []
|
||||
for y in files:
|
||||
ext = os.path.splitext(y)[1]
|
||||
if ext not in ('', '.py', '.so') or \
|
||||
(not ext and not os.path.isdir(join(root, y))):
|
||||
ans.append(y)
|
||||
|
||||
return ans
|
||||
if dest is None:
|
||||
dest = self.site_packages
|
||||
dest = join(dest, basename(x))
|
||||
shutil.copytree(x, dest, symlinks=True, ignore=ignore)
|
||||
self.postprocess_package(x, dest)
|
||||
for x in os.walk(dest):
|
||||
for f in x[-1]:
|
||||
if f.endswith('.so'):
|
||||
f = join(x[0], f)
|
||||
self.fix_dependencies_in_lib(f)
|
||||
|
||||
@flush
|
||||
def filter_package(self, name):
|
||||
return name in ('Cython', 'modulegraph', 'macholib', 'py2app',
|
||||
'bdist_mpkg', 'altgraph')
|
||||
|
||||
@flush
|
||||
def postprocess_package(self, src_path, dest_path):
|
||||
pass
|
||||
|
||||
@flush
|
||||
def add_stdlib(self):
|
||||
print('\nAdding python stdlib')
|
||||
src = PREFIX + '/python/Python.framework/Versions/Current/lib/python'
|
||||
src += py_ver
|
||||
dest = join(self.resources_dir, 'Python', 'lib', 'python')
|
||||
dest += py_ver
|
||||
os.makedirs(dest)
|
||||
for x in os.listdir(src):
|
||||
if x in ('site-packages', 'config', 'test', 'lib2to3', 'lib-tk',
|
||||
'lib-old', 'idlelib', 'plat-mac', 'plat-darwin', 'site.py'):
|
||||
continue
|
||||
x = join(src, x)
|
||||
if os.path.isdir(x):
|
||||
self.add_package_dir(x, dest)
|
||||
elif os.path.splitext(x)[1] in ('.so', '.py'):
|
||||
shutil.copy2(x, dest)
|
||||
dest2 = join(dest, basename(x))
|
||||
if dest2.endswith('.so'):
|
||||
self.fix_dependencies_in_lib(dest2)
|
||||
|
||||
target = join(self.resources_dir, 'Python', 'lib')
|
||||
self.remove_bytecode(target)
|
||||
for path in walk(target):
|
||||
if path.endswith('.so'):
|
||||
self.fix_dependencies_in_lib(path)
|
||||
|
||||
@flush
|
||||
def remove_bytecode(self, dest):
|
||||
for x in os.walk(dest):
|
||||
root = x[0]
|
||||
for f in x[-1]:
|
||||
if os.path.splitext(f) in ('.pyc', '.pyo'):
|
||||
os.remove(join(root, f))
|
||||
|
||||
@flush
|
||||
def compile_py_modules(self):
|
||||
print('\nCompiling Python modules')
|
||||
base = join(self.resources_dir, 'Python')
|
||||
py_compile(base)
|
||||
|
||||
def create_app_clone(self, name, specialise_plist, remove_doc_types=False, base_dir=None):
|
||||
print('\nCreating ' + name)
|
||||
base_dir = base_dir or self.contents_dir
|
||||
cc_dir = join(base_dir, name, 'Contents')
|
||||
exe_dir = join(cc_dir, 'MacOS')
|
||||
rel_path = os.path.relpath(join(self.contents_dir, 'MacOS'), exe_dir)
|
||||
os.makedirs(exe_dir)
|
||||
for x in os.listdir(self.contents_dir):
|
||||
if x.endswith('.app'):
|
||||
continue
|
||||
if x == 'Info.plist':
|
||||
with open(join(self.contents_dir, x), 'rb') as r:
|
||||
plist = plistlib.load(r)
|
||||
specialise_plist(plist)
|
||||
if remove_doc_types:
|
||||
plist.pop('CFBundleDocumentTypes')
|
||||
exe = plist['CFBundleExecutable']
|
||||
# We cannot symlink the bundle executable as if we do,
|
||||
# codesigning fails
|
||||
plist['CFBundleExecutable'] = exe + '-placeholder-for-codesigning'
|
||||
nexe = join(exe_dir, plist['CFBundleExecutable'])
|
||||
base = os.path.dirname(abspath(__file__))
|
||||
cmd = [
|
||||
gcc, '-Wall', '-Werror', '-DEXE_NAME="%s"' % exe, '-DREL_PATH="%s"' % rel_path,
|
||||
join(base, 'placeholder.c'), '-o', nexe, '-headerpad_max_install_names'
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
with open(join(cc_dir, x), 'wb') as p:
|
||||
plistlib.dump(plist, p)
|
||||
elif x == 'MacOS':
|
||||
for item in os.listdir(join(self.contents_dir, 'MacOS')):
|
||||
src = join(self.contents_dir, x, item)
|
||||
os.symlink(os.path.relpath(src, exe_dir), join(exe_dir, item))
|
||||
else:
|
||||
src = join(self.contents_dir, x)
|
||||
os.symlink(os.path.relpath(src, cc_dir), join(cc_dir, x))
|
||||
|
||||
@flush
|
||||
def create_gui_apps(self):
|
||||
|
||||
def get_data(cmd):
|
||||
return json.loads(subprocess.check_output([join(self.contents_dir, 'MacOS', 'calibre-debug'), '-c', cmd]))
|
||||
|
||||
data = get_data(
|
||||
'from calibre.customize.ui import all_input_formats; import sys, json; from calibre.ebooks.oeb.polish.main import SUPPORTED;'
|
||||
'sys.stdout.write(json.dumps({"i": tuple(all_input_formats()), "e": tuple(SUPPORTED)}))'
|
||||
)
|
||||
input_formats = sorted(set(data['i']))
|
||||
edit_formats = sorted(set(data['e']))
|
||||
|
||||
def specialise_plist(launcher, formats, plist):
|
||||
plist['CFBundleDisplayName'] = plist['CFBundleName'] = {
|
||||
'ebook-viewer': 'E-book Viewer', 'ebook-edit': 'Edit Book',
|
||||
}[launcher]
|
||||
plist['CFBundleExecutable'] = launcher
|
||||
plist['CFBundleIdentifier'] = 'com.calibre-ebook.' + launcher
|
||||
plist['CFBundleIconFile'] = launcher + '.icns'
|
||||
e = plist['CFBundleDocumentTypes'][0]
|
||||
e['CFBundleTypeExtensions'] = [x.lower() for x in formats]
|
||||
|
||||
self.create_app_clone('ebook-viewer.app', partial(specialise_plist, 'ebook-viewer', input_formats))
|
||||
self.create_app_clone('ebook-edit.app', partial(specialise_plist, 'ebook-edit', edit_formats),
|
||||
base_dir=join(self.contents_dir, 'ebook-viewer.app', 'Contents'))
|
||||
# We need to move the webengine resources into the deepest sub-app
|
||||
# because the sandbox gets set to the nearest enclosing app which
|
||||
# means that WebEngine will fail to access its resources when running
|
||||
# in the sub-apps unless they are present inside the sub app bundle
|
||||
# somewhere
|
||||
base_dest = join(self.contents_dir, 'ebook-viewer.app', 'Contents', 'ebook-edit.app', 'Contents', 'SharedSupport')
|
||||
os.mkdir(base_dest)
|
||||
base_src = os.path.realpath(join(self.frameworks_dir, 'QtWebEngineCore.framework/Resources'))
|
||||
items = [join(base_src, 'qtwebengine_locales')] + glob.glob(join(base_src, '*.pak')) + glob.glob(join(base_src, '*.dat'))
|
||||
for src in items:
|
||||
dest = join(base_dest, os.path.basename(src))
|
||||
os.rename(src, dest)
|
||||
os.symlink(os.path.relpath(dest, base_src), src)
|
||||
|
||||
@flush
|
||||
def copy_site(self):
|
||||
base = os.path.dirname(abspath(__file__))
|
||||
shutil.copy2(join(base, 'site.py'), join(self.resources_dir, 'Python',
|
||||
'lib', 'python' + py_ver))
|
||||
|
||||
@flush
|
||||
def makedmg(self, d, volname, internet_enable=True):
|
||||
''' Copy a directory d into a dmg named volname '''
|
||||
print('\nSigning...')
|
||||
sys.stdout.flush()
|
||||
destdir = OUTPUT_DIR
|
||||
try:
|
||||
shutil.rmtree(destdir)
|
||||
except EnvironmentError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
os.mkdir(destdir)
|
||||
dmg = join(destdir, volname + '.dmg')
|
||||
if os.path.exists(dmg):
|
||||
os.unlink(dmg)
|
||||
tdir = tempfile.mkdtemp()
|
||||
appdir = join(tdir, os.path.basename(d))
|
||||
shutil.copytree(d, appdir, symlinks=True)
|
||||
if self.sign_installers or self.notarize:
|
||||
with timeit() as times:
|
||||
sign_app(appdir, self.notarize)
|
||||
print('Signing completed in %d minutes %d seconds' % tuple(times))
|
||||
os.symlink('/Applications', join(tdir, 'Applications'))
|
||||
size_in_mb = int(subprocess.check_output(['du', '-s', '-k', tdir]).decode('utf-8').split()[0]) / 1024.
|
||||
# UDBZ gives the best compression, better than ULFO
|
||||
cmd = ['/usr/bin/hdiutil', 'create', '-srcfolder', tdir, '-volname', volname, '-format', 'UDBZ']
|
||||
if 190 < size_in_mb < 250:
|
||||
# We need -size 255m because of a bug in hdiutil. When the size of
|
||||
# srcfolder is close to 200MB hdiutil fails with
|
||||
# diskimages-helper: resize request is above maximum size allowed.
|
||||
cmd += ['-size', '255m']
|
||||
print('\nCreating dmg...')
|
||||
with timeit() as times:
|
||||
subprocess.check_call(cmd + [dmg])
|
||||
if internet_enable:
|
||||
subprocess.check_call(['/usr/bin/hdiutil', 'internet-enable', '-yes', dmg])
|
||||
print('dmg created in %d minutes and %d seconds' % tuple(times))
|
||||
shutil.rmtree(tdir)
|
||||
size = os.stat(dmg).st_size / (1024 * 1024.)
|
||||
print('\nInstaller size: %.2fMB\n' % size)
|
||||
return dmg
|
||||
|
||||
|
||||
def main(args, ext_dir, test_runner):
|
||||
build_dir = abspath(join(mkdtemp('frozen-'), APPNAME + '.app'))
|
||||
if args.skip_tests:
|
||||
test_runner = lambda *a: None
|
||||
Freeze(build_dir, ext_dir, test_runner, dont_strip=args.dont_strip, sign_installers=args.sign_installers, notarize=args.notarize)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = globals()['args']
|
||||
ext_dir = globals()['ext_dir']
|
||||
run_tests = iv['run_tests']
|
||||
main(args, ext_dir, run_tests)
|
41
bypy/macos/launcher.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <libproc.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define fatal(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
|
||||
// These variables must be filled in before compiling
|
||||
static const char *ENV_VARS[] = { /*ENV_VARS*/ NULL };
|
||||
static const char *ENV_VAR_VALS[] = { /*ENV_VAR_VALS*/ NULL};
|
||||
static char PROGRAM[] = "**PROGRAM**";
|
||||
static const char MODULE[] = "**MODULE**";
|
||||
static const char FUNCTION[] = "**FUNCTION**";
|
||||
static const char PYVER[] = "**PYVER**";
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* const *argv, const char **envp) {
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE], realpath_buf[PROC_PIDPATHINFO_MAXSIZE * 5];
|
||||
pid_t pid = getpid();
|
||||
int ret = proc_pidpath(pid, pathbuf, arraysz(pathbuf));
|
||||
if (ret <= 0) fatal("failed to get executable path for current pid with error: %s", strerror(errno));
|
||||
char *path = realpath(pathbuf, realpath_buf);
|
||||
if (path == NULL) fatal("failed to get realpath for executable path with error: %s", strerror(errno));
|
||||
// We re-exec using an absolute path because the Qt WebEngine sandbox does not work
|
||||
// when running via symlink
|
||||
const int is_gui = **IS_GUI**;
|
||||
if (!is_gui && strcmp(PROGRAM, "calibre-parallel") != 0 && strcmp(argv[0], path) != 0) {
|
||||
char* new_argv[1024] = {0};
|
||||
new_argv[0] = path;
|
||||
for (int i = 1; i < argc && i < arraysz(new_argv) - 1; i++) new_argv[i] = argv[i];
|
||||
execv(path, new_argv);
|
||||
}
|
||||
|
||||
return run(ENV_VARS, ENV_VAR_VALS, PROGRAM, MODULE, FUNCTION, PYVER, is_gui, argc, argv, envp, path);
|
||||
}
|
41
bypy/macos/placeholder.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* placeholder.c
|
||||
* Copyright (C) 2018 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <libproc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char * const *argv, const char **envp) {
|
||||
int ret;
|
||||
pid_t pid;
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE], realpath_buf[PROC_PIDPATHINFO_MAXSIZE * 5];
|
||||
|
||||
pid = getpid();
|
||||
ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
|
||||
if (ret <= 0) {
|
||||
perror("failed to get executable path for current pid with error");
|
||||
return 1;
|
||||
}
|
||||
char *path = realpath(pathbuf, realpath_buf);
|
||||
if (path == NULL) {
|
||||
perror("failed to get realpath for executable path with error");
|
||||
return 1;
|
||||
}
|
||||
char *t = rindex(path, '/');
|
||||
if (t == NULL) {
|
||||
fprintf(stderr, "No / in executable path: %s\n", path);
|
||||
return 1;
|
||||
}
|
||||
*(t + 1) = 0;
|
||||
snprintf(t + 1, sizeof(realpath_buf) - strlen(path), "%s/%s", REL_PATH, EXE_NAME);
|
||||
execv(path, argv);
|
||||
}
|
253
bypy/macos/sign.py
Normal file
@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import json
|
||||
import os
|
||||
import plistlib
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
from glob import glob
|
||||
from pprint import pprint
|
||||
from urllib.request import urlopen
|
||||
from uuid import uuid4
|
||||
|
||||
from bypy.utils import current_dir, run_shell, timeit
|
||||
|
||||
CODESIGN_CREDS = os.path.expanduser('~/cert-cred')
|
||||
CODESIGN_CERT = os.path.expanduser('~/maccert.p12')
|
||||
# The apple id file contains the apple id and an app specific password which
|
||||
# can be generated from appleid.apple.com
|
||||
# Note that apple accounts require two-factor authentication which is currntly
|
||||
# setup on ox and via SMS on my phone
|
||||
APPLE_ID = os.path.expanduser('~/aid')
|
||||
path_to_entitlements = os.path.expanduser('~/calibre-entitlements.plist')
|
||||
|
||||
|
||||
def run(*args):
|
||||
if len(args) == 1 and isinstance(args[0], str):
|
||||
args = shlex.split(args[0])
|
||||
if subprocess.call(args) != 0:
|
||||
raise SystemExit('Failed: {}'.format(args))
|
||||
|
||||
|
||||
@contextmanager
|
||||
def make_certificate_useable():
|
||||
KEYCHAIN = tempfile.NamedTemporaryFile(suffix='.keychain', dir=os.path.expanduser('~'), delete=False).name
|
||||
os.remove(KEYCHAIN)
|
||||
KEYCHAIN_PASSWORD = '{}'.format(uuid4())
|
||||
# Create temp keychain
|
||||
run('security create-keychain -p "{}" "{}"'.format(KEYCHAIN_PASSWORD, KEYCHAIN))
|
||||
# Append temp keychain to the user domain
|
||||
raw = subprocess.check_output('security list-keychains -d user'.split()).decode('utf-8')
|
||||
existing_keychain = raw.replace('"', '').strip()
|
||||
run('security list-keychains -d user -s "{}" "{}"'.format(KEYCHAIN, existing_keychain))
|
||||
try:
|
||||
# Remove relock timeout
|
||||
run('security set-keychain-settings "{}"'.format(KEYCHAIN))
|
||||
# Unlock keychain
|
||||
run('security unlock-keychain -p "{}" "{}"'.format(KEYCHAIN_PASSWORD, KEYCHAIN))
|
||||
# Add certificate to keychain
|
||||
with open(CODESIGN_CREDS, 'r') as f:
|
||||
cert_pass = f.read().strip()
|
||||
# Add certificate to keychain and allow codesign to use it
|
||||
# Use -A instead of -T /usr/bin/codesign to allow all apps to use it
|
||||
run('security import {} -k "{}" -P "{}" -T "/usr/bin/codesign"'.format(
|
||||
CODESIGN_CERT, KEYCHAIN, cert_pass))
|
||||
raw = subprocess.check_output([
|
||||
'security', 'find-identity', '-v', '-p', 'codesigning', KEYCHAIN]).decode('utf-8')
|
||||
cert_id = re.search(r'"([^"]+)"', raw).group(1)
|
||||
# Enable codesigning from a non user interactive shell
|
||||
run('security set-key-partition-list -S apple-tool:,apple: -s -k "{}" -D "{}" -t private "{}"'.format(
|
||||
KEYCHAIN_PASSWORD, cert_id, KEYCHAIN))
|
||||
yield
|
||||
finally:
|
||||
# Delete temporary keychain
|
||||
run('security delete-keychain "{}"'.format(KEYCHAIN))
|
||||
|
||||
|
||||
def codesign(items):
|
||||
if isinstance(items, str):
|
||||
items = [items]
|
||||
# If you get errors while codesigning that look like "A timestamp was
|
||||
# expected but not found" it means that codesign failed to contact Apple's time
|
||||
# servers, probably due to network congestion
|
||||
#
|
||||
# --options=runtime enables the Hardened Runtime
|
||||
subprocess.check_call([
|
||||
'codesign', '--options=runtime', '--entitlements=' + path_to_entitlements,
|
||||
'--timestamp', '-s', 'Kovid Goyal'
|
||||
] + list(items))
|
||||
|
||||
|
||||
def notarize_app(app_path):
|
||||
# See
|
||||
# https://developer.apple.com/documentation/xcode/notarizing_your_app_before_distribution/customizing_the_notarization_workflow?language=objc
|
||||
# and
|
||||
# https://developer.apple.com/documentation/xcode/notarizing_your_app_before_distribution/resolving_common_notarization_issues?language=objc
|
||||
with open(APPLE_ID) as f:
|
||||
un, pw = f.read().strip().split(':')
|
||||
|
||||
with open(os.path.join(app_path, 'Contents', 'Info.plist'), 'rb') as f:
|
||||
primary_bundle_id = plistlib.load(f)['CFBundleIdentifier']
|
||||
|
||||
zip_path = os.path.join(os.path.dirname(app_path), 'calibre.zip')
|
||||
print('Creating zip file for notarization')
|
||||
with timeit() as times:
|
||||
run('ditto', '-c', '-k', '--zlibCompressionLevel', '9', '--keepParent', app_path, zip_path)
|
||||
print('ZIP file of {} MB created in {} minutes and {} seconds'.format(os.path.getsize(zip_path) // 1024**2, *times))
|
||||
|
||||
def altool(*args):
|
||||
args = ['xcrun', 'altool'] + list(args) + ['--username', un, '--password', pw]
|
||||
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
stdout = stdout.decode('utf-8')
|
||||
stderr = stderr.decode('utf-8')
|
||||
output = stdout + '\n' + stderr
|
||||
print(output)
|
||||
if p.wait() != 0:
|
||||
print('The command {} failed with error code: {}'.format(args, p.returncode))
|
||||
try:
|
||||
run_shell()
|
||||
finally:
|
||||
raise SystemExit(1)
|
||||
return output
|
||||
|
||||
print('Submitting for notarization')
|
||||
with timeit() as times:
|
||||
try:
|
||||
stdout = altool('--notarize-app', '-f', zip_path, '--primary-bundle-id', primary_bundle_id)
|
||||
finally:
|
||||
os.remove(zip_path)
|
||||
request_id = re.search(r'RequestUUID = (\S+)', stdout).group(1)
|
||||
status = 'in progress'
|
||||
print('Submission done in {} minutes and {} seconds'.format(*times))
|
||||
|
||||
print('Waiting for notarization')
|
||||
with timeit() as times:
|
||||
start_time = time.monotonic()
|
||||
while status == 'in progress':
|
||||
time.sleep(30)
|
||||
print('Checking if notarization is complete, time elapsed: {:.1f} seconds'.format(time.monotonic() - start_time))
|
||||
stdout = altool('--notarization-info', request_id)
|
||||
status = re.search(r'Status\s*:\s+(.+)', stdout).group(1).strip()
|
||||
print('Notarization done in {} minutes and {} seconds'.format(*times))
|
||||
|
||||
if status.lower() != 'success':
|
||||
log_url = re.search(r'LogFileURL\s*:\s+(.+)', stdout).group(1).strip()
|
||||
if log_url != '(null)':
|
||||
log = json.loads(urlopen(log_url).read())
|
||||
pprint(log)
|
||||
raise SystemExit('Notarization failed, see JSON log above')
|
||||
with timeit() as times:
|
||||
print('Stapling notarization ticket')
|
||||
run('xcrun', 'stapler', 'staple', '-v', app_path)
|
||||
run('xcrun', 'stapler', 'validate', '-v', app_path)
|
||||
run('spctl', '--verbose=4', '--assess', '--type', 'execute', app_path)
|
||||
print('Stapling took {} minutes and {} seconds'.format(*times))
|
||||
|
||||
|
||||
def files_in(folder):
|
||||
for record in os.walk(folder):
|
||||
for f in record[-1]:
|
||||
yield os.path.join(record[0], f)
|
||||
|
||||
|
||||
def expand_dirs(items, exclude=lambda x: x.endswith('.so')):
|
||||
items = set(items)
|
||||
dirs = set(x for x in items if os.path.isdir(x))
|
||||
items.difference_update(dirs)
|
||||
for x in dirs:
|
||||
items.update({y for y in files_in(x) if not exclude(y)})
|
||||
return items
|
||||
|
||||
|
||||
def get_executable(info_path):
|
||||
with open(info_path, 'rb') as f:
|
||||
return plistlib.load(f)['CFBundleExecutable']
|
||||
|
||||
|
||||
def create_entitlements_file():
|
||||
ans = {
|
||||
# MAP_JIT is used by libpcre which is bundled with Qt
|
||||
'com.apple.security.cs.allow-jit': True,
|
||||
|
||||
# v8 and therefore WebEngine need this as they dont use MAP_JIT
|
||||
'com.apple.security.cs.allow-unsigned-executable-memory': True,
|
||||
|
||||
# calibre itself does not use DYLD env vars, but dont know about its
|
||||
# dependencies.
|
||||
'com.apple.security.cs.allow-dyld-environment-variables': True,
|
||||
|
||||
# Allow loading of unsigned plugins or frameworks
|
||||
# 'com.apple.security.cs.disable-library-validation': True,
|
||||
}
|
||||
with open(path_to_entitlements, 'wb') as f:
|
||||
f.write(plistlib.dumps(ans))
|
||||
|
||||
|
||||
def find_sub_apps(contents_dir='.'):
|
||||
for app in glob(os.path.join(contents_dir, '*.app')):
|
||||
cdir = os.path.join(app, 'Contents')
|
||||
for sapp in find_sub_apps(cdir):
|
||||
yield sapp
|
||||
yield app
|
||||
|
||||
|
||||
def sign_MacOS(contents_dir='.'):
|
||||
# Sign everything in MacOS except the main executable
|
||||
# which will be signed automatically by codesign when
|
||||
# signing the app bundles
|
||||
with current_dir(os.path.join(contents_dir, 'MacOS')):
|
||||
exe = get_executable('../Info.plist')
|
||||
items = {x for x in os.listdir('.') if x != exe and not os.path.islink(x)}
|
||||
if items:
|
||||
codesign(items)
|
||||
|
||||
|
||||
def do_sign_app(appdir):
|
||||
appdir = os.path.abspath(appdir)
|
||||
with current_dir(os.path.join(appdir, 'Contents')):
|
||||
sign_MacOS()
|
||||
# Sign the sub application bundles
|
||||
sub_apps = list(find_sub_apps())
|
||||
sub_apps.append('Frameworks/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app')
|
||||
for sa in sub_apps:
|
||||
sign_MacOS(os.path.join(sa, 'Contents'))
|
||||
codesign(sub_apps)
|
||||
|
||||
# Sign all .so files
|
||||
so_files = {x for x in files_in('.') if x.endswith('.so')}
|
||||
codesign(so_files)
|
||||
|
||||
# Sign everything in PlugIns
|
||||
with current_dir('PlugIns'):
|
||||
items = set(os.listdir('.'))
|
||||
codesign(expand_dirs(items))
|
||||
|
||||
# Sign everything else in Frameworks
|
||||
with current_dir('Frameworks'):
|
||||
fw = set(glob('*.framework'))
|
||||
codesign(fw)
|
||||
items = set(os.listdir('.')) - fw
|
||||
codesign(expand_dirs(items))
|
||||
|
||||
# Now sign the main app
|
||||
codesign(appdir)
|
||||
# Verify the signature
|
||||
run('codesign', '-vvv', '--deep', '--strict', appdir)
|
||||
run('spctl', '--verbose=4', '--assess', '--type', 'execute', appdir)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def sign_app(appdir, notarize):
|
||||
create_entitlements_file()
|
||||
with make_certificate_useable():
|
||||
do_sign_app(appdir)
|
||||
if notarize:
|
||||
notarize_app(appdir)
|
187
bypy/macos/site.py
Normal file
@ -0,0 +1,187 @@
|
||||
"""
|
||||
Append module search paths for third-party packages to sys.path.
|
||||
|
||||
This is stripped down and customized for use in py2app applications
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def makepath(*paths):
|
||||
dir = os.path.abspath(os.path.join(*paths))
|
||||
return dir, os.path.normcase(dir)
|
||||
|
||||
|
||||
def abs__file__():
|
||||
"""Set all module __file__ attribute to an absolute path"""
|
||||
for m in sys.modules.values():
|
||||
if hasattr(m, '__loader__'):
|
||||
continue # don't mess with a PEP 302-supplied __file__
|
||||
try:
|
||||
m.__file__ = os.path.abspath(m.__file__)
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
|
||||
# This ensures that the initial path provided by the interpreter contains
|
||||
# only absolute pathnames, even if we're running from the build directory.
|
||||
L = []
|
||||
_dirs_in_sys_path = {}
|
||||
dir = dircase = None # sys.path may be empty at this point
|
||||
for dir in sys.path:
|
||||
# Filter out duplicate paths (on case-insensitive file systems also
|
||||
# if they only differ in case); turn relative paths into absolute
|
||||
# paths.
|
||||
dir, dircase = makepath(dir)
|
||||
if dircase not in _dirs_in_sys_path:
|
||||
L.append(dir)
|
||||
_dirs_in_sys_path[dircase] = 1
|
||||
sys.path[:] = L
|
||||
del dir, dircase, L
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
|
||||
def _init_pathinfo():
|
||||
global _dirs_in_sys_path
|
||||
_dirs_in_sys_path = d = {}
|
||||
for dir in sys.path:
|
||||
if dir and not os.path.isdir(dir):
|
||||
continue
|
||||
dir, dircase = makepath(dir)
|
||||
d[dircase] = 1
|
||||
|
||||
|
||||
def addsitedir(sitedir):
|
||||
global _dirs_in_sys_path
|
||||
if _dirs_in_sys_path is None:
|
||||
_init_pathinfo()
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
sitedir, sitedircase = makepath(sitedir)
|
||||
if sitedircase not in _dirs_in_sys_path:
|
||||
sys.path.append(sitedir) # Add path component
|
||||
try:
|
||||
names = os.listdir(sitedir)
|
||||
except os.error:
|
||||
return
|
||||
names.sort()
|
||||
for name in names:
|
||||
if name[-4:] == os.extsep + "pth":
|
||||
addpackage(sitedir, name)
|
||||
if reset:
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
|
||||
def addpackage(sitedir, name):
|
||||
global _dirs_in_sys_path
|
||||
if _dirs_in_sys_path is None:
|
||||
_init_pathinfo()
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
fullname = os.path.join(sitedir, name)
|
||||
try:
|
||||
f = open(fullname)
|
||||
except IOError:
|
||||
return
|
||||
while True:
|
||||
dir = f.readline()
|
||||
if not dir:
|
||||
break
|
||||
if dir[0] == '#':
|
||||
continue
|
||||
if dir.startswith("import"):
|
||||
exec dir
|
||||
continue
|
||||
if dir[-1] == '\n':
|
||||
dir = dir[:-1]
|
||||
dir, dircase = makepath(sitedir, dir)
|
||||
if dircase not in _dirs_in_sys_path and os.path.exists(dir):
|
||||
sys.path.append(dir)
|
||||
_dirs_in_sys_path[dircase] = 1
|
||||
if reset:
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
|
||||
# Remove sys.setdefaultencoding() so that users cannot change the
|
||||
# encoding after initialization. The test for presence is needed when
|
||||
# this module is run as a script, because this code is executed twice.
|
||||
#
|
||||
if hasattr(sys, "setdefaultencoding"):
|
||||
sys.setdefaultencoding('utf-8')
|
||||
del sys.setdefaultencoding
|
||||
|
||||
|
||||
def run_entry_point():
|
||||
bname, mod, func = sys.calibre_basename, sys.calibre_module, sys.calibre_function
|
||||
sys.argv[0] = bname
|
||||
pmod = __import__(mod, fromlist=[1], level=0)
|
||||
return getattr(pmod, func)()
|
||||
|
||||
|
||||
def read_user_env_vars():
|
||||
try:
|
||||
with open(os.path.expanduser('~/Library/Preferences/calibre/macos-env.txt'), 'rb') as f:
|
||||
raw = f.read().decode('utf-8', 'replace')
|
||||
except EnvironmentError as err:
|
||||
return
|
||||
for line in raw.splitlines():
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
parts = line.split('=', 1)
|
||||
if len(parts) == 2:
|
||||
key, val = parts
|
||||
os.environ[key] = os.path.expandvars(os.path.expanduser(val))
|
||||
|
||||
|
||||
def add_calibre_vars(base):
|
||||
sys.frameworks_dir = os.path.join(os.path.dirname(base), 'Frameworks')
|
||||
sys.resources_location = os.path.abspath(os.path.join(base, 'resources'))
|
||||
sys.extensions_location = os.path.join(sys.frameworks_dir, 'plugins')
|
||||
sys.binaries_path = os.path.join(os.path.dirname(base), 'MacOS')
|
||||
|
||||
try:
|
||||
read_user_env_vars()
|
||||
except Exception as err:
|
||||
try:
|
||||
sys.stderr.write('Failed to read user env vars with error: {}\n'.format(err))
|
||||
sys.stderr.flush()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
||||
if dv and os.path.exists(dv):
|
||||
sys.path.insert(0, os.path.abspath(dv))
|
||||
|
||||
|
||||
def nuke_stdout():
|
||||
# Redirect stdout, stdin and stderr to /dev/null
|
||||
from calibre.constants import plugins
|
||||
plugins['speedup'][0].detach(os.devnull)
|
||||
|
||||
|
||||
def main():
|
||||
global __file__
|
||||
|
||||
# Needed on OS X <= 10.8, which passes -psn_... as a command line arg when
|
||||
# starting via launch services
|
||||
for arg in tuple(sys.argv[1:]):
|
||||
if arg.startswith('-psn_'):
|
||||
sys.argv.remove(arg)
|
||||
|
||||
base = sys.resourcepath
|
||||
sys.frozen = 'macosx_app'
|
||||
sys.new_app_bundle = True
|
||||
abs__file__()
|
||||
|
||||
add_calibre_vars(base)
|
||||
addsitedir(sys.site_packages)
|
||||
|
||||
if sys.calibre_is_gui_app and not (
|
||||
sys.stdout.isatty() or sys.stderr.isatty() or sys.stdin.isatty()
|
||||
):
|
||||
nuke_stdout()
|
||||
|
||||
return run_entry_point()
|
213
bypy/macos/util.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <Python.h>
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
|
||||
static const char *ERR_OOM = "Out of memory";
|
||||
|
||||
static int
|
||||
report_error(const char *msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
fflush(stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
report_code(const char *preamble, const char* msg, int code) {
|
||||
fprintf(stderr, "%s: %s\n", preamble, msg);
|
||||
fflush(stderr);
|
||||
return code;
|
||||
}
|
||||
|
||||
#define EXE "@executable_path/.."
|
||||
|
||||
static void
|
||||
set_env_vars(const char **ENV_VARS, const char **ENV_VAR_VALS, const char* exe_path) {
|
||||
int i = 0;
|
||||
char buf[3*PATH_MAX];
|
||||
const char *env_var, *val;
|
||||
|
||||
while(1) {
|
||||
env_var = ENV_VARS[i];
|
||||
if (env_var == NULL) break;
|
||||
val = ENV_VAR_VALS[i++];
|
||||
if (strstr(val, EXE) == val && strlen(val) >= strlen(EXE)+1) {
|
||||
strncpy(buf, exe_path, 3*PATH_MAX-150);
|
||||
strncpy(buf+strlen(exe_path), val+strlen(EXE), 150);
|
||||
setenv(env_var, buf, 1);
|
||||
} else
|
||||
setenv(env_var, val, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void initialize_interpreter(const char **ENV_VARS, const char **ENV_VAR_VALS,
|
||||
char *PROGRAM, const char *MODULE, const char *FUNCTION, const char *PYVER, int IS_GUI,
|
||||
const char* exe_path, const char *rpath, int argc, char* const *argv) {
|
||||
PyObject *pargv, *v;
|
||||
int i;
|
||||
Py_OptimizeFlag = 2;
|
||||
Py_NoSiteFlag = 1;
|
||||
Py_DontWriteBytecodeFlag = 1;
|
||||
Py_IgnoreEnvironmentFlag = 1;
|
||||
Py_NoUserSiteDirectory = 1;
|
||||
Py_HashRandomizationFlag = 1;
|
||||
|
||||
//Py_VerboseFlag = 1;
|
||||
//Py_DebugFlag = 1;
|
||||
|
||||
Py_SetProgramName(PROGRAM);
|
||||
|
||||
char pyhome[1000];
|
||||
snprintf(pyhome, 1000, "%s/Python", rpath);
|
||||
Py_SetPythonHome(pyhome);
|
||||
|
||||
set_env_vars(ENV_VARS, ENV_VAR_VALS, exe_path);
|
||||
|
||||
//printf("Path before Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
Py_Initialize();
|
||||
|
||||
char *dummy_argv[1] = {""};
|
||||
PySys_SetArgv(1, dummy_argv);
|
||||
//printf("Path after Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
char path[3000];
|
||||
snprintf(path, 3000, "%s/lib/python%s:%s/lib/python%s/lib-dynload:%s/site-packages", pyhome, PYVER, pyhome, PYVER, pyhome);
|
||||
|
||||
PySys_SetPath(path);
|
||||
//printf("Path set by me: %s\r\n\n", path);
|
||||
|
||||
PySys_SetObject("calibre_basename", PyBytes_FromString(PROGRAM));
|
||||
PySys_SetObject("calibre_module", PyBytes_FromString(MODULE));
|
||||
PySys_SetObject("calibre_function", PyBytes_FromString(FUNCTION));
|
||||
PySys_SetObject("calibre_is_gui_app", ((IS_GUI) ? Py_True : Py_False));
|
||||
PySys_SetObject("resourcepath", PyBytes_FromString(rpath));
|
||||
snprintf(path, 3000, "%s/site-packages", pyhome);
|
||||
PySys_SetObject("site_packages", PyBytes_FromString(pyhome));
|
||||
|
||||
|
||||
pargv = PyList_New(argc);
|
||||
if (pargv == NULL) exit(report_error(ERR_OOM));
|
||||
for (i = 0; i < argc; i++) {
|
||||
v = PyBytes_FromString(argv[i]);
|
||||
if (v == NULL) exit(report_error(ERR_OOM));
|
||||
PyList_SetItem(pargv, i, v);
|
||||
}
|
||||
PySys_SetObject("argv", pargv);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int pyobject_to_int(PyObject *res) {
|
||||
int ret; PyObject *tmp;
|
||||
tmp = PyNumber_Int(res);
|
||||
if (tmp == NULL) ret = (PyObject_IsTrue(res)) ? 1 : 0;
|
||||
else ret = (int)PyInt_AS_LONG(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int handle_sysexit(PyObject *e) {
|
||||
PyObject *code;
|
||||
|
||||
code = PyObject_GetAttrString(e, "code");
|
||||
if (!code) return 0;
|
||||
if (!PyInt_Check(code)) {
|
||||
PyObject_Print(code, stderr, Py_PRINT_RAW);
|
||||
fflush(stderr);
|
||||
}
|
||||
return pyobject_to_int(code);
|
||||
}
|
||||
|
||||
int calibre_show_python_error(const char *preamble, int code) {
|
||||
PyObject *exc, *val, *tb, *str;
|
||||
int ret, issysexit = 0; char *i;
|
||||
|
||||
if (!PyErr_Occurred()) return code;
|
||||
issysexit = PyErr_ExceptionMatches(PyExc_SystemExit);
|
||||
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
|
||||
if (exc != NULL) {
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
|
||||
if (issysexit) {
|
||||
return (val) ? handle_sysexit(val) : 0;
|
||||
}
|
||||
if (val != NULL) {
|
||||
str = PyObject_Unicode(val);
|
||||
if (str == NULL) {
|
||||
PyErr_Clear();
|
||||
str = PyObject_Str(val);
|
||||
}
|
||||
i = PyString_AsString(str);
|
||||
ret = report_code(preamble, (i==NULL)?ERR_OOM:i, code);
|
||||
if (tb != NULL) {
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyErr_Print();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return report_code(preamble, "", code);
|
||||
}
|
||||
|
||||
EXPORT
|
||||
int
|
||||
run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
const char *MODULE, const char *FUNCTION, const char *PYVER,
|
||||
int IS_GUI, int argc, char * const *argv, const char **envp, char *full_exe_path) {
|
||||
char *t = NULL;
|
||||
int ret = 0, i;
|
||||
PyObject *site, *mainf, *res;
|
||||
uint32_t buf_size = PATH_MAX+1;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
t = rindex(full_exe_path, '/');
|
||||
if (t == NULL) return report_error("Failed to determine bundle path.");
|
||||
*t = '\0';
|
||||
}
|
||||
if (strstr(full_exe_path, "/calibre.app/Contents/") != NULL) {
|
||||
// We are one of the duplicate executables created to workaround codesign's limitations
|
||||
for (i = 0; i < 2; i++) {
|
||||
t = rindex(full_exe_path, '/');
|
||||
if (t == NULL) return report_error("Failed to resolve bundle path in dummy executable");
|
||||
*t = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
char rpath[PATH_MAX+1], exe_path[PATH_MAX+1];
|
||||
snprintf(exe_path, PATH_MAX+1, "%s/Contents", full_exe_path);
|
||||
snprintf(rpath, PATH_MAX+1, "%s/Resources", exe_path);
|
||||
initialize_interpreter(ENV_VARS, ENV_VAR_VALS, PROGRAM, MODULE, FUNCTION, PYVER, IS_GUI,
|
||||
exe_path, rpath, argc, argv);
|
||||
|
||||
site = PyImport_ImportModule("site");
|
||||
|
||||
if (site == NULL)
|
||||
ret = calibre_show_python_error("Failed to import site module", -1);
|
||||
else {
|
||||
Py_XINCREF(site);
|
||||
|
||||
mainf = PyObject_GetAttrString(site, "main");
|
||||
if (mainf == NULL || !PyCallable_Check(mainf))
|
||||
ret = calibre_show_python_error("site module has no main function", -1);
|
||||
else {
|
||||
Py_XINCREF(mainf);
|
||||
res = PyObject_CallObject(mainf, NULL);
|
||||
|
||||
if (res == NULL)
|
||||
ret = calibre_show_python_error("Python function terminated unexpectedly", -1);
|
||||
else {
|
||||
}
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
Py_Finalize();
|
||||
|
||||
//printf("11111 Returning: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
5
bypy/macos/util.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
int run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
const char *MODULE, const char *FUNCTION, const char *PYVER, int IS_GUI,
|
||||
int argc, char *const *argv, const char **envp, char *full_exe_path);
|
1
bypy/rsync.conf
Normal file
@ -0,0 +1 @@
|
||||
to_vm_excludes '/imgsrc /build /dist /manual /format_docs /translations /.build-cache /tags /Changelog* *.so *.pyd'
|
824
bypy/sources.json
Normal file
@ -0,0 +1,824 @@
|
||||
[
|
||||
{
|
||||
"name": "nasm",
|
||||
"os": "macos,windows",
|
||||
"unix": {
|
||||
"filename": "nasm-2.14.02.tar.xz",
|
||||
"hash": "sha256:e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5",
|
||||
"urls": ["https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "cmake",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "cmake-3.14.4.tar.gz",
|
||||
"hash": "sha256:00b4dc9b0066079d10f16eed32ec592963a44e7967371d2f5077fd1670ff36d9",
|
||||
"urls": ["https://github.com/Kitware/CMake/releases/download/v3.14.4/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "autoconf",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "autoconf-2.69.tar.xz",
|
||||
"hash": "sha256:64ebcec9f8ac5b2487125a86a7760d2591ac9e1d3dbd59489633f9de62a57684",
|
||||
"urls": ["ftp://ftp.gnu.org/gnu/autoconf/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "automake",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "automake-1.16.tar.xz",
|
||||
"hash": "sha256:f98f2d97b11851cbe7c2d4b4eaef498ae9d17a3c2ef1401609b7b4ca66655b8a",
|
||||
"urls": ["ftp://ftp.gnu.org/gnu/automake/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libtool",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "libtool-2.4.6.tar.xz",
|
||||
"hash": "sha256:7c87a8c2c8c0fc9cd5019e402bed4292462d00a718a7cd5f11218153bf28b26f",
|
||||
"urls": ["ftp://ftp.gnu.org/gnu/libtool/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "easylzma",
|
||||
"os": "windows",
|
||||
"windows": {
|
||||
"filename": "easylzma-1753f61f673abdebc08fcf4a37eedd6da8a67ba1.tar.gz",
|
||||
"hash": "sha256:7664240898fe09bce8b39cd428407dd24ac3b87200e6b40d4007c78f2c725254",
|
||||
"urls": ["github:lloyd/easylzma"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "zlib",
|
||||
"unix": {
|
||||
"filename": "zlib-1.2.11.tar.xz",
|
||||
"hash": "sha256:4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066",
|
||||
"urls": ["https://zlib.net/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "bzip2",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "bzip2-1.0.6.tar.gz",
|
||||
"hash": "md5:00b516f4704d4a7cb50a1d97e6e8e15b",
|
||||
"urls": ["https://sources.archlinux.org/other/packages/bzip2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "unrar",
|
||||
"unix": {
|
||||
"filename": "unrarsrc-5.9.1.tar.gz",
|
||||
"hash": "sha256:0eb1d1b8e02102fccae775a6d6b79336b69e2cf90e2045de92594dcfb58de100",
|
||||
"urls": ["https://www.rarlab.com/rar/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "expat",
|
||||
"unix": {
|
||||
"filename": "expat-2.2.6.tar.bz2",
|
||||
"hash": "sha256:17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2",
|
||||
"urls": ["https://github.com/libexpat/libexpat/releases/download/R_2_2_6/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sqlite",
|
||||
"unix": {
|
||||
"filename": "sqlite-autoconf-3310100.tar.gz",
|
||||
"hash": "sha1:0c30f5b22152a8166aa3bebb0f4bc1f3e9cc508b",
|
||||
"urls": ["https://www.sqlite.org/2020/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libffi",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libffi-3.2.1.tar.gz",
|
||||
"hash": "sha1:280c265b789e041c02e5c97815793dfc283fb1e6",
|
||||
"urls": ["ftp://sourceware.org/pub/libffi/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "hyphen",
|
||||
"unix": {
|
||||
"filename": "hyphen-2.8.8.tar.gz",
|
||||
"hash": "sha1:0556c392beb59433e577e3517575801212201df6",
|
||||
"urls": ["https://downloads.sourceforge.net/hunspell/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "openssl",
|
||||
"unix": {
|
||||
"filename": "openssl-1.0.2r.tar.gz",
|
||||
"hash": "sha256:ae51d08bba8a83958e894946f15303ff894d75c2b8bbd44a852b64e3fe11d0d6",
|
||||
"urls": ["https://www.openssl.org/source/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ncurses",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "ncurses-6.1.tar.gz",
|
||||
"hash": "sha256:aa057eeeb4a14d470101eff4597d5833dcef5965331be3528c08d99cebaa0d17",
|
||||
"urls": ["ftp://ftp.gnu.org/gnu/ncurses/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "readline",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "readline-8.0.tar.gz",
|
||||
"hash": "sha256:e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461",
|
||||
"urls": ["http://ftp.gnu.org/gnu/readline/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "python",
|
||||
"unix": {
|
||||
"filename": "Python-2.7.16.tar.xz",
|
||||
"hash": "sha256:f222ef602647eecb6853681156d32de4450a2c39f4de93bd5b20235f2e660ed7",
|
||||
"urls": ["https://www.python.org/ftp/python/2.7.16/{filename}"]
|
||||
},
|
||||
"windows": {
|
||||
"filename":"python-584870604fd8524e17bc2c067595b0210411319e.tar.gz",
|
||||
"hash":"sha256:4f1833cac526f209de5b428d517cbd7a7923f13b89ba056e239dd8aa15894b7d",
|
||||
"urls":["github:kovidgoyal/cpython"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "icu",
|
||||
"unix": {
|
||||
"filename": "icu4c-64_2-src.tgz",
|
||||
"hash": "sha256:627d5d8478e6d96fc8c90fed4851239079a561a6a8b9e48b0892f24e82d31d6c",
|
||||
"urls": ["http://download.icu-project.org/files/icu4c/64.2/{filename}"]
|
||||
},
|
||||
"windows": {
|
||||
"filename": "icu4c-64_2-src.zip",
|
||||
"hash": "sha256:c8df046a9944003dae744197648e0fa6c745478b7d7b4e2b05f6a390868b5752",
|
||||
"urls": ["http://download.icu-project.org/files/icu4c/64.2/{filename}"]
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libjpeg",
|
||||
"unix": {
|
||||
"filename": "libjpeg-turbo-2.0.2.tar.gz",
|
||||
"hash": "sha256:acb8599fe5399af114287ee5907aea4456f8f2c1cc96d26c28aebfdf5ee82fed",
|
||||
"urls": ["http://downloads.sourceforge.net/project/libjpeg-turbo/2.0.2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libpng",
|
||||
"unix": {
|
||||
"filename": "libpng-1.6.37.tar.xz",
|
||||
"hash": "sha256:505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca",
|
||||
"urls": ["http://downloads.sourceforge.net/sourceforge/libpng/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libwebp",
|
||||
"unix": {
|
||||
"filename": "libwebp-1.0.2.tar.gz",
|
||||
"hash": "sha256:3d47b48c40ed6476e8047b2ddb81d93835e0ca1b8d3e8c679afbb3004dd564b1",
|
||||
"urls": ["http://downloads.webmproject.org/releases/webp/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "jxrlib",
|
||||
"unix": {
|
||||
"filename": "jxrlib-0.2.1.tar.gz",
|
||||
"hash": "sha256:5ae964ae61f301f38a62b8e18eb8d2eee27eaf2b942477b033435ebf38fa4a19",
|
||||
"urls": ["https://github.com/glencoesoftware/jxrlib/archive/v0.2.1.tar.gz"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "freetype",
|
||||
"os": "macos,windows",
|
||||
"unix": {
|
||||
"filename": "freetype-2.10.0.tar.bz2",
|
||||
"hash": "sha256:fccc62928c65192fff6c98847233b28eb7ce05f12d2fea3f6cc90e8b4e5fbe06",
|
||||
"urls": ["https://download.savannah.gnu.org/releases/freetype/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "fontconfig",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "fontconfig-2.13.1.tar.bz2",
|
||||
"hash": "sha256:f655dd2a986d7aa97e052261b36aa67b0a64989496361eca8d604e6414006741",
|
||||
"urls": ["https://www.fontconfig.org/release/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "iconv",
|
||||
"os": "macos, linux",
|
||||
"unix": {
|
||||
"filename": "libiconv-1.15.tar.gz",
|
||||
"hash": "sha256:ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178",
|
||||
"urls": ["https://ftp.gnu.org/pub/gnu/libiconv/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libxml2",
|
||||
"unix": {
|
||||
"filename": "libxml2-2.9.9.tar.gz",
|
||||
"hash": "sha256:94fb70890143e3c6549f265cee93ec064c80a84c42ad0f23e85ee1fd6540a871",
|
||||
"urls": ["ftp://xmlsoft.org/libxml2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libxslt",
|
||||
"unix": {
|
||||
"filename": "libxslt-1.1.33.tar.gz",
|
||||
"hash": "sha256:8e36605144409df979cab43d835002f63988f3dc94d5d3537c12796db90e38c8",
|
||||
"urls": ["ftp://xmlsoft.org/libxml2/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "chmlib",
|
||||
"unix": {
|
||||
"filename": "chmlib-0.40.tar.bz2",
|
||||
"hash": "sha1:5231d7531e8808420d7f89fd1e4fdbac1ed7a167",
|
||||
"urls": ["http://www.jedrea.com/chmlib/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "optipng",
|
||||
"unix": {
|
||||
"filename": "optipng-0.7.7.tar.gz",
|
||||
"hash": "sha256:4f32f233cef870b3f95d3ad6428bfe4224ef34908f1b42b0badf858216654452",
|
||||
"urls": ["https://downloads.sourceforge.net/sourceforge/optipng/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "mozjpeg",
|
||||
"unix": {
|
||||
"filename": "mozjpeg-3.3.1.tar.gz",
|
||||
"hash": "sha256:aebbea60ea038a84a2d1ed3de38fdbca34027e2e54ee2b7d08a97578be72599d",
|
||||
"urls": ["https://github.com/mozilla/mozjpeg/archive/v3.3.1.tar.gz"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libusb",
|
||||
"os": "macos, linux",
|
||||
"unix": {
|
||||
"filename": "libusb-1.0.22.tar.bz2",
|
||||
"hash": "sha256:75aeb9d59a4fdb800d329a545c2e6799f732362193b465ea198f2aa275518157",
|
||||
"urls": ["https://downloads.sourceforge.net/libusb/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libmtp",
|
||||
"os": "macos, linux",
|
||||
"unix": {
|
||||
"filename": "libmtp-1.1.16.tar.gz",
|
||||
"hash": "sha256:5b68f9dd1ed38de558de687f40e255a39e4d5e32ef3de601f0ac19dd5682bba0",
|
||||
"urls": ["https://downloads.sourceforge.net/libmtp/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "openjpeg",
|
||||
"unix": {
|
||||
"filename": "openjpeg-2.3.1.tar.gz",
|
||||
"hash": "sha256:63f5a4713ecafc86de51bfad89cc07bb788e9bba24ebbf0c4ca637621aadb6a9",
|
||||
"urls": ["https://github.com/uclouvain/openjpeg/archive/v2.3.1/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "poppler",
|
||||
"unix": {
|
||||
"filename": "poppler-0.76.1.tar.xz",
|
||||
"hash": "sha256:e62cd4053f851eecc4a6aa2b81d739fbab1d67b3c60b31ebac7049483cc617b1",
|
||||
"urls": ["https://poppler.freedesktop.org/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "podofo",
|
||||
"unix": {
|
||||
"filename": "podofo-0.9.6.tar.gz",
|
||||
"hash": "md5:46336fc4c4ce4be814bb5fbb4d918334",
|
||||
"urls": ["https://downloads.sourceforge.net/podofo/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libgpg-error",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libgpg-error-1.36.tar.bz2",
|
||||
"hash": "sha256:babd98437208c163175c29453f8681094bcaf92968a15cafb1a276076b33c97c",
|
||||
"urls": ["ftp://ftp.gnupg.org/gcrypt/libgpg-error/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "libgcrypt",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "libgcrypt-1.8.4.tar.bz2",
|
||||
"hash": "sha256:f638143a0672628fde0cad745e9b14deb85dffb175709cacc1f4fe24b93f2227",
|
||||
"urls": ["ftp://ftp.gnupg.org/gcrypt/libgcrypt/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "glib",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "glib-2.60.1.tar.xz",
|
||||
"hash": "sha256:89f884f5d5c6126140ec868cef184c42ce72902c13cd08f36e660371779b5560",
|
||||
"urls": ["http://ftp.gnome.org/pub/GNOME/sources/glib/2.60/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dbus",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "dbus-1.12.12.tar.gz",
|
||||
"hash": "sha256:9546f226011a1e5d9d77245fe5549ef25af4694053189d624d0d6ac127ecf5f8",
|
||||
"urls": ["https://dbus.freedesktop.org/releases/dbus/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dbusglib",
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "dbus-glib-0.110.tar.gz",
|
||||
"hash": "sha256:7ce4760cf66c69148f6bd6c92feaabb8812dee30846b24cd0f7395c436d7e825",
|
||||
"urls": ["https://dbus.freedesktop.org/releases/dbus-glib/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "gnuwin32",
|
||||
"os": "windows",
|
||||
"windows": {
|
||||
"filename": "gnuwin32.zip",
|
||||
"hash": "sha256:4a9dc893cc0a1695a16102a42ef47ef2e228652891f4afea67fadd452b63656b",
|
||||
"urls": ["http://download.qt.io/development_releases/gnuwin32/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "hunspell",
|
||||
"unix": {
|
||||
"filename": "hunspell-1.7.0.tar.gz",
|
||||
"hash": "sha256:57be4e03ae9dd62c3471f667a0d81a14513e314d4d92081292b90435944ff951",
|
||||
"urls": ["https://github.com/hunspell/hunspell/files/2573619/{filename}"]
|
||||
},
|
||||
"windows": {
|
||||
"filename": "hunspell-1.7.0.zip",
|
||||
"hash": "sha256:7089cc01ffd9122c960e1f8c7930a75be989ca4e9468773cef1b0a655bfb4368",
|
||||
"urls": ["https://github.com/hunspell/hunspell/archive/v1.7.0.zip"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-base",
|
||||
"version": "5.14.1",
|
||||
"hashes": {
|
||||
"unix": "sha256:d9d423a6e7bcf1055c0372fc029f14a6fe67dd62c67b83095cde68b60b762cf7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-svg",
|
||||
"hashes": {
|
||||
"unix": "sha256:8540a57312f815f81a45b891b49959d776727fde17579bb6bf1a537996bc9359"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-declarative",
|
||||
"hashes": {
|
||||
"unix": "sha256:762fe495d2f97fd70f06dc7d3929506ea3b5e3151ad813e0629209b7bc504c8a"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-imageformats",
|
||||
"hashes": {
|
||||
"unix": "sha256:b8b177ea68df3a99f45740cb3193e3b38738c5e2b272028445bd31a4305c8e5e"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-webchannel",
|
||||
"hashes": {
|
||||
"unix": "sha256:3af5262fde14c7dfe7bcc12d5796a482837bd09f0878851fd8de5db0b1985e6a"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-location",
|
||||
"hashes": {
|
||||
"unix": "sha256:a0dd1712a5b7a0425b57d17318294b6f7e968c4b81d52048696d029b04d2f12f"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-x11extras",
|
||||
"os": "linux",
|
||||
"hashes": {
|
||||
"unix": "sha256:b268907deb06570671c1f584feb1508e7fded129209a268183decc122bfac181"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-wayland",
|
||||
"os": "linux",
|
||||
"hashes": {
|
||||
"unix": "sha256:2a03b9f554e88c5824ef237c814b3dd45844c022e97be0e091f4a502ca4c9520"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-sensors",
|
||||
"hashes": {
|
||||
"unix": "sha256:eda3862cf079ac2357553be4faaae0136aa017e954506ca0c4239995b5be214c"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-macextras",
|
||||
"os": "macos",
|
||||
"hashes": {
|
||||
"unix": "sha256:8c263fdba519d7e04bc64767883283eedede0752aa47cc440670129725696e29"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "qt-winextras",
|
||||
"os": "windows",
|
||||
"hashes": {
|
||||
"unix": "sha256:222b888b89a8fb02948faf985e8614ac543603a000c1cf2e7489f8bf15ccc3cc"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "qt-webengine",
|
||||
"hashes": {
|
||||
"unix": "sha256:4ec77040a876a83aa2a833ebfe7b3e88dcc167ceb317095eb226a0b8d455e887"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "setuptools",
|
||||
"unix": {
|
||||
"filename": "setuptools-41.0.1.zip",
|
||||
"hash": "sha256:a222d126f5471598053c9a77f4b5d4f26eaa1f150ad6e01dcf1a42e185d05613",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "six",
|
||||
"unix": {
|
||||
"filename": "six-1.12.0.tar.gz",
|
||||
"hash": "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pywin32",
|
||||
"os": "windows",
|
||||
"python": 2,
|
||||
"windows": {
|
||||
"filename":"pywin32-224.zip",
|
||||
"hash":"sha256:fa01a3b9f5e6afd0412013b216d40120b92bbc575dbb3d1a0afb45d8bc1c88d8",
|
||||
"urls":["https://github.com/mhammond/pywin32/archive/b224.zip"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "unrardll",
|
||||
"unix": {
|
||||
"filename": "unrardll-0.1.3.tar.gz",
|
||||
"hash": "sha256:5f214ab1ec24208c6ee353f2d836e536968d5379b7140129f04aa3a52bc56a5e",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "lxml",
|
||||
"unix": {
|
||||
"filename": "lxml-4.3.3.tar.gz",
|
||||
"hash": "sha256:4a03dd682f8e35a10234904e0b9508d705ff98cf962c5851ed052e9340df3d90",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "html5-parser",
|
||||
"unix": {
|
||||
"filename": "html5-parser-0.4.9.tar.gz",
|
||||
"hash": "sha256:25fe8f6848cbc15187f6748c0695df32bcf1b37df6420b6a01b4ebe1ec1ed48f",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "css-parser",
|
||||
"unix": {
|
||||
"filename": "css-parser-1.0.4.tar.gz",
|
||||
"hash": "sha256:c7ab355512ae51334ba6791a7e4d553f87bef17ba2026f1cc9bf3b17a7779d44",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dateutil",
|
||||
"unix": {
|
||||
"filename": "python-dateutil-2.8.0.tar.gz",
|
||||
"hash": "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dbuspython",
|
||||
"python": 2,
|
||||
"os": "linux",
|
||||
"unix": {
|
||||
"filename": "dbus-python-1.2.8.tar.gz",
|
||||
"hash": "sha256:abf12bbb765e300bf8e2a1b2f32f85949eab06998dbda127952c31cb63957b6f",
|
||||
"urls": ["https://dbus.freedesktop.org/releases/dbus-python/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "dnspython",
|
||||
"unix": {
|
||||
"filename": "dnspython-1.16.0.zip",
|
||||
"hash": "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "mechanize",
|
||||
"unix": {
|
||||
"filename": "mechanize-0.4.3.tar.gz",
|
||||
"hash": "sha256:d7d7068be5e1b3069575c98c870aaa96dd26603fe8c8697b470e2f65259fddbf",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "feedparser",
|
||||
"unix": {
|
||||
"filename": "feedparser-5.2.1.tar.bz2",
|
||||
"hash": "sha256:ce875495c90ebd74b179855449040003a1beb40cd13d5f037a0654251e260b02",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "markdown",
|
||||
"unix": {
|
||||
"filename": "Markdown-3.1.tar.gz",
|
||||
"hash": "sha256:fc4a6f69a656b8d858d7503bda633f4dd63c2d70cf80abdc6eafa64c4ae8c250",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "html2text",
|
||||
"unix": {
|
||||
"filename": "html2text-2018.1.9.tar.gz",
|
||||
"hash": "sha256:627514fb30e7566b37be6900df26c2c78a030cc9e6211bda604d8181233bcdd4",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "soupsieve",
|
||||
"unix": {
|
||||
"filename": "soupsieve-1.9.1.tar.gz",
|
||||
"hash": "sha256:b20eff5e564529711544066d7dc0f7661df41232ae263619dede5059799cdfca",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "beautifulsoup4",
|
||||
"unix": {
|
||||
"filename": "beautifulsoup4-4.7.1.tar.gz",
|
||||
"hash": "sha256:945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "regex",
|
||||
"unix": {
|
||||
"filename": "regex-2019.04.14.tar.gz",
|
||||
"hash": "sha256:d56ce4c7b1a189094b9bee3b81c4aeb3f1ba3e375e91627ec8561b6ab483d0a8",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "chardet",
|
||||
"unix": {
|
||||
"filename": "chardet-3.0.4.tar.gz",
|
||||
"hash": "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "msgpack",
|
||||
"unix": {
|
||||
"filename": "msgpack-0.6.1.tar.gz",
|
||||
"hash": "sha256:4008c72f5ef2b7936447dcb83db41d97e9791c83221be13d5e19db0796df1972",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pygments",
|
||||
"unix": {
|
||||
"filename": "Pygments-2.3.1.tar.gz",
|
||||
"hash": "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pycrypto",
|
||||
"unix": {
|
||||
"filename": "pycrypto-2.6.1.tar.gz",
|
||||
"hash": "sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "apsw",
|
||||
"python": 2,
|
||||
"unix": {
|
||||
"filename": "apsw-3.30.1-r1.zip",
|
||||
"hash": "sha256:b7be3dca5f95b88ff2285dbfb61e7449c8cb4214d3d18172ffdb163360c7aa2f",
|
||||
"urls": ["https://github.com/rogerbinns/apsw/releases/download/3.30.1-r1/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "webencodings",
|
||||
"unix": {
|
||||
"filename": "webencodings-0.5.1.tar.gz",
|
||||
"hash": "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "html5lib",
|
||||
"unix": {
|
||||
"filename": "html5lib-1.0.1.tar.gz",
|
||||
"hash": "sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pillow",
|
||||
"unix": {
|
||||
"filename": "Pillow-6.0.0.tar.gz",
|
||||
"hash": "sha256:809c0a2ce9032cbcd7b5313f71af4bdc5c8c771cb86eb7559afd954cab82ebb5",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "netifaces",
|
||||
"unix": {
|
||||
"filename": "netifaces-0.10.9.tar.gz",
|
||||
"hash": "sha256:2dee9ffdd16292878336a58d04a20f0ffe95555465fee7c9bd23b3490ef2abf3",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "psutil",
|
||||
"unix": {
|
||||
"filename": "psutil-5.6.2.tar.gz",
|
||||
"hash": "sha256:828e1c3ca6756c54ac00f1427fdac8b12e21b8a068c3bb9b631a1734cada25ed",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ifaddr",
|
||||
"python": 3,
|
||||
"unix": {
|
||||
"filename": "ifaddr-0.1.6.tar.gz",
|
||||
"hash": "sha256:c19c64882a7ad51a394451dabcbbed72e98b5625ec1e79789924d5ea3e3ecb93",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "zeroconf",
|
||||
"python": 3,
|
||||
"unix": {
|
||||
"filename": "zeroconf-0.21.3.tar.gz",
|
||||
"hash": "sha256:5b52dfdf4e665d98a17bf9aa50dea7a8c98e25f972d9c1d7660e2b978a1f5713",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "enum34",
|
||||
"python": "<3",
|
||||
"unix": {
|
||||
"filename": "enum34-1.1.6.tar.gz",
|
||||
"hash": "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sip",
|
||||
"unix": {
|
||||
"filename": "sip-4.19.19.tar.gz",
|
||||
"hash": "sha256:5436b61a78f48c7e8078e93a6b59453ad33780f80c644e5f3af39f94be1ede44",
|
||||
"urls": ["https://www.riverbankcomputing.com/static/Downloads/sip/4.19.19/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pyqt",
|
||||
"unix": {
|
||||
"filename": "PyQt5_gpl-5.13.1.tar.gz",
|
||||
"hash": "sha256:54b7f456341b89eeb3930e786837762ea67f235e886512496c4152ebe106d4af",
|
||||
"urls": ["https://www.riverbankcomputing.com/static/Downloads/PyQt5/5.13.1/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"name": "pyqt-webengine",
|
||||
"unix": {
|
||||
"filename": "PyQtWebEngine_gpl-5.13.1.tar.gz",
|
||||
"hash": "sha256:8d8c1262005d8465653a848bf67327fb338e0d3c2d26090a6f7eb071dbb42092",
|
||||
"urls": ["https://www.riverbankcomputing.com/static/Downloads/PyQtWebEngine/5.13.1/{filename}"]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "macfsevents",
|
||||
"os": "macos",
|
||||
"unix": {
|
||||
"filename": "MacFSEvents-0.7.tar.gz",
|
||||
"hash": "md5:089d52d40a088651302967b1d13c3825",
|
||||
"urls": ["pypi"]
|
||||
}
|
||||
}
|
||||
]
|
16
bypy/windows.conf
Normal file
@ -0,0 +1,16 @@
|
||||
# Requires installation of Visual Studio 2017 Community Edition, WiX Toolset, Git, Ruby, Python 3.7 and Perl
|
||||
# git.exe must be in PATH. Must have ~120GB available disk space and 8GB RAM
|
||||
# Install certifi in python 3 with:
|
||||
# py.exe -m pip install certifi
|
||||
# Copy opengl32sw.dll from
|
||||
# https://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
|
||||
# to C:/mesa/32 and C:/mesa/64
|
||||
# Ensure the windwos sdk version at least 10.0.18362 or newer is installed, needed for
|
||||
# qt-webengine-14.1
|
||||
|
||||
vm_name 'calibre-windows-build'
|
||||
root 'C:/r'
|
||||
python 'py.exe'
|
||||
perl 'C:/Strawberry/perl/bin/perl.exe'
|
||||
ruby 'C:/Ruby26-x64/bin/ruby.exe'
|
||||
mesa 'C:/mesa'
|
4379
bypy/windows/XUnzip.cpp
Normal file
382
bypy/windows/XUnzip.h
Normal file
@ -0,0 +1,382 @@
|
||||
// XUnzip.h Version 1.3
|
||||
//
|
||||
// Authors: Mark Adler et al. (see below)
|
||||
//
|
||||
// Modified by: Lucian Wischik
|
||||
// lu@wischik.com
|
||||
//
|
||||
// Version 1.0 - Turned C files into just a single CPP file
|
||||
// - Made them compile cleanly as C++ files
|
||||
// - Gave them simpler APIs
|
||||
// - Added the ability to zip/unzip directly in memory without
|
||||
// any intermediate files
|
||||
//
|
||||
// Modified by: Hans Dietrich
|
||||
// hdietrich@gmail.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Lucian Wischik's comments:
|
||||
// --------------------------
|
||||
// THIS FILE is almost entirely based upon code by info-zip.
|
||||
// It has been modified by Lucian Wischik.
|
||||
// The original code may be found at http://www.info-zip.org
|
||||
// The original copyright text follows.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Original authors' comments:
|
||||
// ---------------------------
|
||||
// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The
|
||||
// definitive version of this document should be available at
|
||||
// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
|
||||
//
|
||||
// Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
|
||||
//
|
||||
// For the purposes of this copyright and license, "Info-ZIP" is defined as
|
||||
// the following set of individuals:
|
||||
//
|
||||
// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
|
||||
// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
|
||||
// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
|
||||
// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
|
||||
// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
|
||||
// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler,
|
||||
// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White
|
||||
//
|
||||
// This software is provided "as is", without warranty of any kind, express
|
||||
// or implied. In no event shall Info-ZIP or its contributors be held liable
|
||||
// for any direct, indirect, incidental, special or consequential damages
|
||||
// arising out of the use of or inability to use this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// definition, disclaimer, and this list of conditions.
|
||||
//
|
||||
// 2. Redistributions in binary form (compiled executables) must reproduce
|
||||
// the above copyright notice, definition, disclaimer, and this list of
|
||||
// conditions in documentation and/or other materials provided with the
|
||||
// distribution. The sole exception to this condition is redistribution
|
||||
// of a standard UnZipSFX binary as part of a self-extracting archive;
|
||||
// that is permitted without inclusion of this license, as long as the
|
||||
// normal UnZipSFX banner has not been removed from the binary or disabled.
|
||||
//
|
||||
// 3. Altered versions--including, but not limited to, ports to new
|
||||
// operating systems, existing ports with new graphical interfaces, and
|
||||
// dynamic, shared, or static library versions--must be plainly marked
|
||||
// as such and must not be misrepresented as being the original source.
|
||||
// Such altered versions also must not be misrepresented as being
|
||||
// Info-ZIP releases--including, but not limited to, labeling of the
|
||||
// altered versions with the names "Info-ZIP" (or any variation thereof,
|
||||
// including, but not limited to, different capitalizations),
|
||||
// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of
|
||||
// Info-ZIP. Such altered versions are further prohibited from
|
||||
// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or
|
||||
// of the Info-ZIP URL(s).
|
||||
//
|
||||
// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip",
|
||||
// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its
|
||||
// own source and binary releases.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XUNZIP_H
|
||||
#define XUNZIP_H
|
||||
|
||||
|
||||
#ifndef XZIP_H
|
||||
DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that has been opened
|
||||
#endif
|
||||
|
||||
typedef DWORD ZRESULT;
|
||||
// return codes from any of the zip functions. Listed later.
|
||||
|
||||
#define ZIP_HANDLE 1
|
||||
#define ZIP_FILENAME 2
|
||||
#define ZIP_MEMORY 3
|
||||
|
||||
typedef struct
|
||||
{ int index; // index of this file within the zip
|
||||
char name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
} ZIPENTRY;
|
||||
|
||||
typedef struct
|
||||
{ int index; // index of this file within the zip
|
||||
TCHAR name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
} ZIPENTRYW;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpenZip()
|
||||
//
|
||||
// Purpose: Open an existing zip archive file
|
||||
//
|
||||
// Parameters: z - archive file name if flags is ZIP_FILENAME; for other
|
||||
// uses see below
|
||||
// len - for memory (ZIP_MEMORY) should be the buffer size;
|
||||
// for other uses, should be 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: HZIP - non-zero if zip archive opened ok, otherwise 0
|
||||
//
|
||||
HZIP OpenZip(void *z, unsigned int len, DWORD flags);
|
||||
// OpenZip - opens a zip file and returns a handle with which you can
|
||||
// subsequently examine its contents. You can open a zip file from:
|
||||
// from a pipe: OpenZip(hpipe_read,0, ZIP_HANDLE);
|
||||
// from a file (by handle): OpenZip(hfile,0, ZIP_HANDLE);
|
||||
// from a file (by name): OpenZip("c:\\test.zip",0, ZIP_FILENAME);
|
||||
// from a memory block: OpenZip(bufstart, buflen, ZIP_MEMORY);
|
||||
// If the file is opened through a pipe, then items may only be
|
||||
// accessed in increasing order, and an item may only be unzipped once,
|
||||
// although GetZipItem can be called immediately before and after unzipping
|
||||
// it. If it's opened i n any other way, then full random access is possible.
|
||||
// Note: pipe input is not yet implemented.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetZipItem()
|
||||
//
|
||||
// Purpose: Get information about an item in an open zip archive
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// index - index number (0 based) of item in zip
|
||||
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
|
||||
// (if Unicode)
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define GetZipItem GetZipItemW
|
||||
#else
|
||||
#define GetZipItem GetZipItemA
|
||||
#endif
|
||||
|
||||
ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze);
|
||||
ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *ze);
|
||||
// GetZipItem - call this to get information about an item in the zip.
|
||||
// If index is -1 and the file wasn't opened through a pipe,
|
||||
// then it returns information about the whole zipfile
|
||||
// (and in particular ze.index returns the number of index items).
|
||||
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
// See below for notes on what happens when you unzip such an item.
|
||||
// Note: if you are opening the zip through a pipe, then random access
|
||||
// is not possible and GetZipItem(-1) fails and you can't discover the number
|
||||
// of items except by calling GetZipItem on each one of them in turn,
|
||||
// starting at 0, until eventually the call fails. Also, in the event that
|
||||
// you are opening through a pipe and the zip was itself created into a pipe,
|
||||
// then then comp_size and sometimes unc_size as well may not be known until
|
||||
// after the item has been unzipped.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FindZipItem()
|
||||
//
|
||||
// Purpose: Find item by name and return information about it
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// name - name of file to look for inside zip archive
|
||||
// ic - TRUE = case insensitive
|
||||
// index - pointer to index number returned, or -1
|
||||
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
|
||||
// (if Unicode)
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define FindZipItem FindZipItemW
|
||||
#else
|
||||
#define FindZipItem FindZipItemA
|
||||
#endif
|
||||
|
||||
ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
|
||||
ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *ze);
|
||||
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
||||
// It returns the index of the item, and returns information about it.
|
||||
// If nothing was found, then index is set to -1 and the function returns
|
||||
// an error code.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UnzipItem()
|
||||
//
|
||||
// Purpose: Find item by index and unzip it
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// index - index number of file to unzip
|
||||
// dst - target file name of unzipped file
|
||||
// len - for memory (ZIP_MEMORY. length of buffer;
|
||||
// otherwise 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags);
|
||||
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
||||
// to a pipe: UnzipItem(hz,i, hpipe_write,0,ZIP_HANDLE);
|
||||
// to a file (by handle): UnzipItem(hz,i, hfile,0,ZIP_HANDLE);
|
||||
// to a file (by name): UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
|
||||
// to a memory block: UnzipItem(hz,i, buf,buflen,ZIP_MEMORY);
|
||||
// In the final case, if the buffer isn't large enough to hold it all,
|
||||
// then the return code indicates that more is yet to come. If it was
|
||||
// large enough, and you want to know precisely how big, GetZipItem.
|
||||
// Note: zip files are normally stored with relative pathnames. If you
|
||||
// unzip with ZIP_FILENAME a relative pathname then the item gets created
|
||||
// relative to the current directory - it first ensures that all necessary
|
||||
// subdirectories have been created. Also, the item may itself be a directory.
|
||||
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
||||
// If you unzip it to a handle or a memory block, then nothing gets created
|
||||
// and it emits 0 bytes.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CloseZip()
|
||||
//
|
||||
// Purpose: Close an open zip archive
|
||||
//
|
||||
// Parameters: hz - handle to an open zip archive
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
ZRESULT CloseZip(HZIP hz);
|
||||
// CloseZip - the zip handle must be closed with this function.
|
||||
|
||||
unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len);
|
||||
// FormatZipMessage - given an error code, formats it as a string.
|
||||
// It returns the length of the error message. If buf/len points
|
||||
// to a real buffer, then it also writes as much as possible into there.
|
||||
|
||||
|
||||
// These are the result codes:
|
||||
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
||||
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
||||
// The following come from general system stuff (e.g. files not openable)
|
||||
#define ZR_GENMASK 0x0000FF00
|
||||
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
||||
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
||||
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
||||
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
||||
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
||||
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
||||
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
||||
#define ZR_READ 0x00000800 // a general error reading the file
|
||||
// The following come from mistakes on the part of the caller
|
||||
#define ZR_CALLERMASK 0x00FF0000
|
||||
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
||||
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
||||
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
||||
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
||||
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
||||
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
||||
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
||||
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
||||
// The following come from bugs within the zip library itself
|
||||
#define ZR_BUGMASK 0xFF000000
|
||||
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
||||
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
||||
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
||||
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\stuff");
|
||||
// HZIP hz = OpenZip("c:\\stuff.zip",0,ZIP_FILENAME);
|
||||
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
|
||||
// for (int i=0; i<numitems; i++)
|
||||
// { GetZipItem(hz,i,&ze);
|
||||
// UnzipItem(hz,i,ze.name,0,ZIP_FILENAME);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
//
|
||||
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
|
||||
// HANDLE hglob = LoadResource(hInstance,hrsrc);
|
||||
// void *zipbuf=LockResource(hglob);
|
||||
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
|
||||
// HZIP hz = OpenZip(zipbuf, ziplen, ZIP_MEMORY);
|
||||
// - unzip to a membuffer -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
|
||||
// char *ibuf = new char[ze.unc_size];
|
||||
// UnzipItem(hz,i, ibuf, ze.unc_size,ZIP_MEMORY);
|
||||
// delete[] buf;
|
||||
// - unzip to a fixed membuff -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
|
||||
// char ibuf[1024]; ZIPRESULT zr=ZR_MORE; unsigned long totsize=0;
|
||||
// while (zr==ZR_MORE)
|
||||
// { zr = UnzipItem(hz,i, ibuf,1024,ZIP_MEMORY);
|
||||
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
|
||||
// totsize+=bufsize;
|
||||
// }
|
||||
// - unzip to a pipe -
|
||||
// HANDLE hthread=CreateWavReaderThread(&hread,&hwrite);
|
||||
// FindZipItem(hz,"sound.wav",&i,&ze);
|
||||
// UnzipItem(hz,i, hwrite,0,ZIP_HANDLE);
|
||||
// CloseHandle(hwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hread); CloseHandle(hthread);
|
||||
// - finished -
|
||||
// CloseZip(hz);
|
||||
// // note: no need to free resources obtained through Find/Load/LockResource
|
||||
//
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite);
|
||||
// CreateZipWriterThread(hwrite);
|
||||
// HZIP hz = OpenZip(hread,0,ZIP_HANDLE);
|
||||
// for (int i=0; ; i++)
|
||||
// { ZIPENTRY ze; ZRESULT res = GetZipItem(hz,i,&ze);
|
||||
// if (res!=ZE_OK) break; // no more
|
||||
// UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Now we indulge in a little skullduggery so that the code works whether
|
||||
// the user has included just zip or both zip and unzip.
|
||||
// Idea: if header files for both zip and unzip are present, then presumably
|
||||
// the cpp files for zip and unzip are both present, so we will call
|
||||
// one or the other of them based on a dynamic choice. If the header file
|
||||
// for only one is present, then we will bind to that particular one.
|
||||
HZIP OpenZipU(void *z,unsigned int len,DWORD flags);
|
||||
ZRESULT CloseZipU(HZIP hz);
|
||||
unsigned int FormatZipMessageU(ZRESULT code, char *buf,unsigned int len);
|
||||
bool IsZipHandleU(HZIP hz);
|
||||
#define OpenZip OpenZipU
|
||||
|
||||
#ifdef XZIP_H
|
||||
#undef CloseZip
|
||||
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
|
||||
#else
|
||||
#define CloseZip CloseZipU
|
||||
#define FormatZipMessage FormatZipMessageU
|
||||
#endif
|
||||
|
||||
|
||||
#endif //XUNZIP_H
|
749
bypy/windows/__main__.py
Normal file
@ -0,0 +1,749 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import errno
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import runpy
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
from bypy.constants import (
|
||||
CL, LINK, MT, PREFIX, RC, SIGNTOOL, SRC as CALIBRE_DIR, SW, build_dir, is64bit,
|
||||
python_major_minor_version, worker_env
|
||||
)
|
||||
from bypy.utils import py_compile, run, walk
|
||||
|
||||
iv = globals()['init_env']
|
||||
calibre_constants = iv['calibre_constants']
|
||||
QT_PREFIX = os.path.join(PREFIX, 'qt')
|
||||
QT_DLLS, QT_PLUGINS, PYQT_MODULES = iv['QT_DLLS'], iv['QT_PLUGINS'], iv['PYQT_MODULES']
|
||||
|
||||
APPNAME, VERSION = calibre_constants['appname'], calibre_constants['version']
|
||||
WINVER = VERSION + '.0'
|
||||
machine = 'X64' if is64bit else 'X86'
|
||||
j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename
|
||||
create_installer = runpy.run_path(
|
||||
j(d(a(__file__)), 'wix.py'), {'calibre_constants': calibre_constants}
|
||||
)['create_installer']
|
||||
|
||||
DESCRIPTIONS = {
|
||||
'calibre': 'The main calibre program',
|
||||
'ebook-viewer': 'The calibre e-book viewer',
|
||||
'ebook-edit': 'The calibre e-book editor',
|
||||
'lrfviewer': 'Viewer for LRF files',
|
||||
'ebook-convert': 'Command line interface to the conversion/news download system',
|
||||
'ebook-meta': 'Command line interface for manipulating e-book metadata',
|
||||
'calibredb': 'Command line interface to the calibre database',
|
||||
'calibre-launcher': 'Utility functions common to all executables',
|
||||
'calibre-debug': 'Command line interface for calibre debugging/development',
|
||||
'calibre-customize': 'Command line interface to calibre plugin system',
|
||||
'calibre-server': 'Standalone calibre content server',
|
||||
'calibre-parallel': 'calibre worker process',
|
||||
'calibre-smtp': 'Command line interface for sending books via email',
|
||||
'calibre-eject': 'Helper program for ejecting connected reader devices',
|
||||
'calibre-file-dialog': 'Helper program to show file open/save dialogs',
|
||||
}
|
||||
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx
|
||||
SUPPORTED_OS = {
|
||||
'w7': '{35138b9a-5d96-4fbd-8e2d-a2440225f93a}',
|
||||
'w8': '{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}',
|
||||
'w81': '{1f676c76-80e1-4239-95bb-83d0f6d0da78}',
|
||||
'w10': '{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}',
|
||||
}
|
||||
|
||||
EXE_MANIFEST = '''\
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{w7}"/>
|
||||
<supportedOS Id="{w8}"/>
|
||||
<supportedOS Id="{w81}"/>
|
||||
<supportedOS Id="{w10}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
'''.format(**SUPPORTED_OS)
|
||||
|
||||
|
||||
def printf(*args, **kw):
|
||||
print(*args, **kw)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def run_compiler(env, *cmd):
|
||||
run(*cmd, cwd=env.obj_dir)
|
||||
|
||||
|
||||
class Env(object):
|
||||
|
||||
def __init__(self, build_dir):
|
||||
self.python_base = os.path.join(PREFIX, 'private', 'python')
|
||||
self.portable_uncompressed_size = 0
|
||||
self.src_root = CALIBRE_DIR
|
||||
self.base = j(build_dir, 'winfrozen')
|
||||
self.app_base = j(self.base, 'app')
|
||||
self.rc_template = j(d(a(__file__)), 'template.rc')
|
||||
self.py_ver = '.'.join(map(str, python_major_minor_version()))
|
||||
self.lib_dir = j(self.app_base, 'Lib')
|
||||
self.pylib = j(self.app_base, 'pylib.zip')
|
||||
self.dll_dir = j(self.app_base, 'bin')
|
||||
self.portable_base = j(d(self.base), 'Calibre Portable')
|
||||
self.obj_dir = j(build_dir, 'launcher')
|
||||
self.installer_dir = j(build_dir, 'wix')
|
||||
self.dist = j(SW, 'dist')
|
||||
|
||||
|
||||
def initbase(env):
|
||||
os.makedirs(env.app_base)
|
||||
os.mkdir(env.dll_dir)
|
||||
try:
|
||||
shutil.rmtree(env.dist)
|
||||
except EnvironmentError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
os.mkdir(env.dist)
|
||||
|
||||
|
||||
def add_plugins(env, ext_dir):
|
||||
printf('Adding plugins...')
|
||||
tgt = env.dll_dir
|
||||
for f in glob.glob(j(ext_dir, '*.pyd')):
|
||||
shutil.copy2(f, tgt)
|
||||
|
||||
|
||||
def freeze(env, ext_dir):
|
||||
shutil.copy2(j(env.src_root, 'LICENSE'), env.base)
|
||||
|
||||
printf('Adding resources...')
|
||||
tgt = j(env.app_base, 'resources')
|
||||
if os.path.exists(tgt):
|
||||
shutil.rmtree(tgt)
|
||||
shutil.copytree(j(env.src_root, 'resources'), tgt)
|
||||
|
||||
printf('\tAdding misc binary deps')
|
||||
|
||||
def copybin(x):
|
||||
shutil.copy2(x, env.dll_dir)
|
||||
try:
|
||||
shutil.copy2(x + '.manifest', env.dll_dir)
|
||||
except EnvironmentError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
bindir = os.path.join(PREFIX, 'bin')
|
||||
for x in ('pdftohtml', 'pdfinfo', 'pdftoppm', 'jpegtran-calibre', 'cjpeg-calibre', 'optipng-calibre', 'JXRDecApp-calibre'):
|
||||
copybin(os.path.join(bindir, x + '.exe'))
|
||||
for f in glob.glob(os.path.join(bindir, '*.dll')):
|
||||
if re.search(r'(easylzma|icutest)', f.lower()) is None:
|
||||
copybin(f)
|
||||
|
||||
copybin(os.path.join(env.python_base, 'python%s.dll' % env.py_ver.replace('.', '')))
|
||||
for x in glob.glob(os.path.join(env.python_base, 'DLLs', '*')): # python pyd modules
|
||||
copybin(x)
|
||||
for f in walk(os.path.join(env.python_base, 'Lib')):
|
||||
if f.lower().endswith('.dll') and 'scintilla' not in f.lower():
|
||||
copybin(f)
|
||||
add_plugins(env, ext_dir)
|
||||
|
||||
printf('Adding Qt...')
|
||||
for x in QT_DLLS:
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', 'QtWebEngineProcess.exe'))
|
||||
for x in 'libGLESv2 libEGL'.split():
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
plugdir = j(QT_PREFIX, 'plugins')
|
||||
tdir = j(env.app_base, 'plugins')
|
||||
for d in QT_PLUGINS:
|
||||
imfd = os.path.join(plugdir, d)
|
||||
tg = os.path.join(tdir, d)
|
||||
if os.path.exists(tg):
|
||||
shutil.rmtree(tg)
|
||||
shutil.copytree(imfd, tg)
|
||||
for f in walk(tdir):
|
||||
if not f.lower().endswith('.dll'):
|
||||
os.remove(f)
|
||||
for data_file in os.listdir(j(QT_PREFIX, 'resources')):
|
||||
shutil.copy2(j(QT_PREFIX, 'resources', data_file), j(env.app_base, 'resources'))
|
||||
shutil.copytree(j(QT_PREFIX, 'translations'), j(env.app_base, 'translations'))
|
||||
|
||||
printf('Adding python...')
|
||||
|
||||
def ignore_lib(root, items):
|
||||
ans = []
|
||||
for x in items:
|
||||
ext = os.path.splitext(x)[1].lower()
|
||||
if ext in ('.dll', '.chm', '.htm', '.txt'):
|
||||
ans.append(x)
|
||||
return ans
|
||||
|
||||
shutil.copytree(r'%s\Lib' % env.python_base, env.lib_dir, ignore=ignore_lib)
|
||||
install_site_py(env)
|
||||
|
||||
# Fix win32com
|
||||
sp_dir = j(env.lib_dir, 'site-packages')
|
||||
comext = j(sp_dir, 'win32comext')
|
||||
shutil.copytree(j(comext, 'shell'), j(sp_dir, 'win32com', 'shell'))
|
||||
shutil.rmtree(comext)
|
||||
|
||||
for pat in ('PyQt5\\uic\\port_v3', ):
|
||||
x = glob.glob(j(env.lib_dir, 'site-packages', pat))[0]
|
||||
shutil.rmtree(x)
|
||||
pyqt = j(env.lib_dir, 'site-packages', 'PyQt5')
|
||||
for x in {x for x in os.listdir(pyqt) if x.endswith('.pyd')}:
|
||||
if x.partition('.')[0] not in PYQT_MODULES and x != 'sip.pyd':
|
||||
os.remove(j(pyqt, x))
|
||||
with open(j(pyqt, '__init__.py') , 'r+b') as f:
|
||||
raw = f.read()
|
||||
nraw = raw.replace(b'def find_qt():', b'def find_qt():\n return # disabled for calibre')
|
||||
if nraw == raw:
|
||||
raise Exception('Failed to patch PyQt to disable dll directory manipulation')
|
||||
f.seek(0), f.truncate(), f.write(nraw)
|
||||
|
||||
printf('Adding calibre sources...')
|
||||
for x in glob.glob(j(CALIBRE_DIR, 'src', '*')):
|
||||
if os.path.isdir(x):
|
||||
if os.path.exists(os.path.join(x, '__init__.py')):
|
||||
shutil.copytree(x, j(sp_dir, b(x)), ignore=shutil.ignore_patterns('*.pyc', '*.pyo'))
|
||||
else:
|
||||
shutil.copy(x, j(sp_dir, b(x)))
|
||||
|
||||
for x in (r'calibre\manual', r'calibre\plugins', 'pythonwin'):
|
||||
deld = j(sp_dir, x)
|
||||
if os.path.exists(deld):
|
||||
shutil.rmtree(deld)
|
||||
|
||||
for x in os.walk(j(sp_dir, 'calibre')):
|
||||
for f in x[-1]:
|
||||
if not f.endswith('.py'):
|
||||
os.remove(j(x[0], f))
|
||||
|
||||
extract_pyd_modules(env, sp_dir)
|
||||
|
||||
printf('Byte-compiling all python modules...')
|
||||
for x in ('test', 'lib2to3'):
|
||||
x = j(env.lib_dir, x)
|
||||
if os.path.exists(x):
|
||||
shutil.rmtree(x)
|
||||
py_compile(env.lib_dir.replace(os.sep, '/'))
|
||||
|
||||
|
||||
def embed_manifests(env):
|
||||
printf('Embedding remaining manifests...')
|
||||
for manifest in walk(env.base):
|
||||
dll, ext = os.path.splitext(manifest)
|
||||
if ext != '.manifest':
|
||||
continue
|
||||
res = 2
|
||||
if os.path.splitext(dll)[1] == '.exe':
|
||||
res = 1
|
||||
if os.path.exists(dll) and open(manifest, 'rb').read().strip():
|
||||
run(MT, '-manifest', manifest, '-outputresource:%s;%d' % (dll, res))
|
||||
os.remove(manifest)
|
||||
|
||||
|
||||
def extract_pyd_modules(env, site_packages_dir):
|
||||
printf('\nExtracting .pyd modules from site-packages...')
|
||||
|
||||
def extract_pyd(path, root):
|
||||
fullname = os.path.relpath(path, root).replace(os.sep, '/').replace('/', '.')
|
||||
dest = os.path.join(env.dll_dir, fullname)
|
||||
if os.path.exists(dest):
|
||||
raise ValueError('Cannot extract %s into DLLs as it already exists' % fullname)
|
||||
os.rename(path, dest)
|
||||
bpy = dest[:-1]
|
||||
if os.path.exists(bpy):
|
||||
with open(bpy, 'rb') as f:
|
||||
raw = f.read().strip().decode('utf-8')
|
||||
if (not raw.startswith('def __bootstrap__') or not raw.endswith('__bootstrap__()')):
|
||||
raise ValueError('The file %r has non bootstrap code' % bpy)
|
||||
for ext in ('', 'c', 'o'):
|
||||
try:
|
||||
os.remove(bpy + ext)
|
||||
except EnvironmentError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
def find_pyds(base):
|
||||
for dirpath, dirnames, filenames in os.walk(base):
|
||||
for fname in filenames:
|
||||
if fname.lower().endswith('.pyd'):
|
||||
yield os.path.join(dirpath, fname)
|
||||
|
||||
def process_root(root, base=None):
|
||||
for path in find_pyds(root):
|
||||
extract_pyd(path, base or root)
|
||||
|
||||
def absp(x):
|
||||
return os.path.normcase(os.path.abspath(os.path.join(site_packages_dir, x)))
|
||||
|
||||
roots = set()
|
||||
for pth in glob.glob(os.path.join(site_packages_dir, '*.pth')):
|
||||
for line in open(pth).readlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#') and os.path.exists(os.path.join(site_packages_dir, line)):
|
||||
roots.add(absp(line))
|
||||
|
||||
for x in os.listdir(site_packages_dir):
|
||||
x = absp(x)
|
||||
if x in roots:
|
||||
process_root(x)
|
||||
elif os.path.isdir(x):
|
||||
process_root(x, site_packages_dir)
|
||||
elif x.lower().endswith('.pyd'):
|
||||
extract_pyd(x, site_packages_dir)
|
||||
|
||||
|
||||
def embed_resources(env, module, desc=None, extra_data=None, product_description=None):
|
||||
icon_base = j(env.src_root, 'icons')
|
||||
icon_map = {'calibre': 'library', 'ebook-viewer': 'viewer', 'ebook-edit': 'ebook-edit',
|
||||
'lrfviewer': 'viewer', 'calibre-portable': 'library'}
|
||||
file_type = 'DLL' if module.endswith('.dll') else 'APP'
|
||||
with open(env.rc_template, 'rb') as f:
|
||||
template = f.read().decode('utf-8')
|
||||
bname = b(module)
|
||||
internal_name = os.path.splitext(bname)[0]
|
||||
icon = icon_map.get(internal_name, 'command-prompt')
|
||||
if internal_name.startswith('calibre-portable-'):
|
||||
icon = 'install'
|
||||
icon = j(icon_base, icon + '.ico')
|
||||
if desc is None:
|
||||
defdesc = 'A dynamic link library' if file_type == 'DLL' else \
|
||||
'An executable program'
|
||||
desc = DESCRIPTIONS.get(internal_name, defdesc)
|
||||
license = 'GNU GPL v3.0'
|
||||
|
||||
def e(val):
|
||||
return val.replace('"', r'\"')
|
||||
if product_description is None:
|
||||
product_description = APPNAME + ' - E-book management'
|
||||
rc = template.format(
|
||||
icon=icon.replace('\\', '/'),
|
||||
file_type=e(file_type),
|
||||
file_version=e(WINVER.replace('.', ',')),
|
||||
file_version_str=e(WINVER),
|
||||
file_description=e(desc),
|
||||
internal_name=e(internal_name),
|
||||
original_filename=e(bname),
|
||||
product_version=e(WINVER.replace('.', ',')),
|
||||
product_version_str=e(VERSION),
|
||||
product_name=e(APPNAME),
|
||||
product_description=e(product_description),
|
||||
legal_copyright=e(license),
|
||||
legal_trademarks=e(APPNAME + ' is a registered U.S. trademark number 3,666,525')
|
||||
)
|
||||
if extra_data:
|
||||
rc += '\nextra extra "%s"' % extra_data
|
||||
tdir = env.obj_dir
|
||||
rcf = j(tdir, bname + '.rc')
|
||||
with open(rcf, 'w') as f:
|
||||
f.write(rc)
|
||||
res = j(tdir, bname + '.res')
|
||||
run(RC, '/n', '/fo' + res, rcf)
|
||||
return res
|
||||
|
||||
|
||||
def install_site_py(env):
|
||||
if not os.path.exists(env.lib_dir):
|
||||
os.makedirs(env.lib_dir)
|
||||
shutil.copy2(j(d(__file__), 'site.py'), env.lib_dir)
|
||||
|
||||
|
||||
def build_portable_installer(env):
|
||||
zf = a(j(env.dist, 'calibre-portable-%s.zip.lz' % VERSION)).replace(os.sep, '/')
|
||||
usz = env.portable_uncompressed_size or os.path.getsize(zf)
|
||||
|
||||
def cc(src, obj):
|
||||
cflags = '/c /EHsc /MT /W4 /Ox /nologo /D_UNICODE /DUNICODE /DPSAPI_VERSION=1'.split()
|
||||
cflags.append(r'/I%s\include' % PREFIX)
|
||||
cflags.append('/DUNCOMPRESSED_SIZE=%d' % usz)
|
||||
printf('Compiling', obj)
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
base = d(a(__file__))
|
||||
src = j(base, 'portable-installer.cpp')
|
||||
obj = j(env.obj_dir, b(src) + '.obj')
|
||||
xsrc = j(base, 'XUnzip.cpp')
|
||||
xobj = j(env.obj_dir, b(xsrc) + '.obj')
|
||||
cc(src, obj)
|
||||
cc(xsrc, xobj)
|
||||
|
||||
exe = j(env.dist, 'calibre-portable-installer-%s.exe' % VERSION)
|
||||
printf('Linking', exe)
|
||||
manifest = exe + '.manifest'
|
||||
with open(manifest, 'wb') as f:
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/INCREMENTAL:NO', '/MACHINE:' + machine,
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||
'/LIBPATH:' + (PREFIX + r'\lib'),
|
||||
'/RELEASE', '/MANIFEST:EMBED', '/MANIFESTINPUT:' + manifest,
|
||||
'/ENTRY:wWinMainCRTStartup',
|
||||
'/OUT:' + exe, embed_resources(
|
||||
env, exe, desc='Calibre Portable Installer', extra_data=zf, product_description='Calibre Portable Installer'),
|
||||
xobj, obj, 'User32.lib', 'Shell32.lib', 'easylzma_s.lib',
|
||||
'Ole32.lib', 'Shlwapi.lib', 'Kernel32.lib', 'Psapi.lib']
|
||||
run(*cmd)
|
||||
os.remove(zf)
|
||||
|
||||
|
||||
def build_portable(env):
|
||||
base = env.portable_base
|
||||
if os.path.exists(base):
|
||||
shutil.rmtree(base)
|
||||
os.makedirs(base)
|
||||
root = d(a(__file__))
|
||||
src = j(root, 'portable.c')
|
||||
obj = j(env.obj_dir, b(src) + '.obj')
|
||||
cflags = '/c /EHsc /MT /W3 /Ox /nologo /D_UNICODE /DUNICODE'.split()
|
||||
|
||||
printf('Compiling', obj)
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, '/Tc' + src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
exe = j(base, 'calibre-portable.exe')
|
||||
printf('Linking', exe)
|
||||
cmd = [LINK] + [
|
||||
'/INCREMENTAL:NO', '/MACHINE:' + machine,
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||
'/RELEASE',
|
||||
'/ENTRY:wWinMainCRTStartup',
|
||||
'/OUT:' + exe, embed_resources(env, exe, desc='Calibre Portable', product_description='Calibre Portable'),
|
||||
obj, 'User32.lib']
|
||||
run(*cmd)
|
||||
|
||||
printf('Creating portable installer')
|
||||
shutil.copytree(env.base, j(base, 'Calibre'))
|
||||
os.mkdir(j(base, 'Calibre Library'))
|
||||
os.mkdir(j(base, 'Calibre Settings'))
|
||||
|
||||
name = '%s-portable-%s.zip' % (APPNAME, VERSION)
|
||||
name = j(env.dist, name)
|
||||
with zipfile.ZipFile(name, 'w', zipfile.ZIP_STORED) as zf:
|
||||
add_dir_to_zip(zf, base, 'Calibre Portable')
|
||||
|
||||
env.portable_uncompressed_size = os.path.getsize(name)
|
||||
subprocess.check_call([PREFIX + r'\bin\elzma.exe', '-9', '--lzip', name])
|
||||
|
||||
|
||||
def sign_files(env, files):
|
||||
args = [SIGNTOOL, 'sign', '/a', '/fd', 'sha256', '/td', 'sha256', '/d',
|
||||
'calibre - E-book management', '/du',
|
||||
'https://calibre-ebook.com', '/tr']
|
||||
|
||||
def runcmd(cmd):
|
||||
for timeserver in ('http://sha256timestamp.ws.symantec.com/sha256/timestamp', 'http://timestamp.comodoca.com/rfc3161',):
|
||||
try:
|
||||
subprocess.check_call(cmd + [timeserver] + list(files))
|
||||
break
|
||||
except subprocess.CalledProcessError:
|
||||
print ('Signing failed, retrying with different timestamp server')
|
||||
else:
|
||||
raise SystemExit('Signing failed')
|
||||
|
||||
runcmd(args)
|
||||
|
||||
|
||||
def sign_installers(env):
|
||||
printf('Signing installers...')
|
||||
installers = set()
|
||||
for f in glob.glob(j(env.dist, '*')):
|
||||
if f.rpartition('.')[-1].lower() in {'exe', 'msi'}:
|
||||
installers.add(f)
|
||||
else:
|
||||
os.remove(f)
|
||||
if not installers:
|
||||
raise ValueError('No installers found')
|
||||
sign_files(env, installers)
|
||||
|
||||
|
||||
def add_dir_to_zip(zf, path, prefix=''):
|
||||
'''
|
||||
Add a directory recursively to the zip file with an optional prefix.
|
||||
'''
|
||||
if prefix:
|
||||
zi = zipfile.ZipInfo(prefix + '/')
|
||||
zi.external_attr = 16
|
||||
zf.writestr(zi, '')
|
||||
cwd = os.path.abspath(os.getcwd())
|
||||
try:
|
||||
os.chdir(path)
|
||||
fp = (prefix + ('/' if prefix else '')).replace('//', '/')
|
||||
for f in os.listdir('.'):
|
||||
arcname = fp + f
|
||||
if os.path.isdir(f):
|
||||
add_dir_to_zip(zf, f, prefix=arcname)
|
||||
else:
|
||||
zf.write(f, arcname)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
def build_utils(env):
|
||||
|
||||
def build(src, name, subsys='CONSOLE', libs='setupapi.lib'.split()):
|
||||
printf('Building ' + name)
|
||||
obj = j(env.obj_dir, os.path.basename(src) + '.obj')
|
||||
cflags = '/c /EHsc /MD /W3 /Ox /nologo /D_UNICODE'.split()
|
||||
ftype = '/T' + ('c' if src.endswith('.c') else 'p')
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, ftype + src]
|
||||
run_compiler(env, *cmd)
|
||||
exe = j(env.dll_dir, name)
|
||||
mf = exe + '.manifest'
|
||||
with open(mf, 'wb') as f:
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/MACHINE:' + machine,
|
||||
'/SUBSYSTEM:' + subsys, '/RELEASE', '/MANIFEST:EMBED', '/MANIFESTINPUT:' + mf,
|
||||
'/OUT:' + exe] + [embed_resources(env, exe), obj] + libs
|
||||
run(*cmd)
|
||||
base = d(a(__file__))
|
||||
build(j(base, 'file_dialogs.cpp'), 'calibre-file-dialog.exe', 'WINDOWS', 'Ole32.lib Shell32.lib'.split())
|
||||
build(j(base, 'eject.c'), 'calibre-eject.exe')
|
||||
|
||||
|
||||
def build_launchers(env, debug=False):
|
||||
if not os.path.exists(env.obj_dir):
|
||||
os.makedirs(env.obj_dir)
|
||||
dflags = (['/Zi'] if debug else [])
|
||||
dlflags = (['/DEBUG'] if debug else ['/INCREMENTAL:NO'])
|
||||
base = d(a(__file__))
|
||||
sources = [j(base, x) for x in ['util.c', ]]
|
||||
objects = [j(env.obj_dir, b(x) + '.obj') for x in sources]
|
||||
cflags = '/c /EHsc /W3 /Ox /nologo /D_UNICODE'.split()
|
||||
cflags += ['/DPYDLL="python%s.dll"' % env.py_ver.replace('.', ''), '/I%s/include' % env.python_base]
|
||||
for src, obj in zip(sources, objects):
|
||||
cmd = [CL] + cflags + dflags + ['/MD', '/Fo' + obj, '/Tc' + src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
dll = j(env.obj_dir, 'calibre-launcher.dll')
|
||||
ver = '.'.join(VERSION.split('.')[:2])
|
||||
cmd = [LINK, '/DLL', '/VERSION:' + ver, '/LTCG', '/OUT:' + dll,
|
||||
'/nologo', '/MACHINE:' + machine] + dlflags + objects + \
|
||||
[embed_resources(env, dll),
|
||||
'/LIBPATH:%s/libs' % env.python_base,
|
||||
'delayimp.lib', 'user32.lib', 'shell32.lib',
|
||||
'python%s.lib' % env.py_ver.replace('.', ''),
|
||||
'/delayload:python%s.dll' % env.py_ver.replace('.', '')]
|
||||
printf('Linking calibre-launcher.dll')
|
||||
run(*cmd)
|
||||
|
||||
src = j(base, 'main.c')
|
||||
shutil.copy2(dll, env.dll_dir)
|
||||
basenames, modules, functions = calibre_constants['basenames'], calibre_constants['modules'], calibre_constants['functions']
|
||||
for typ in ('console', 'gui', ):
|
||||
printf('Processing %s launchers' % typ)
|
||||
subsys = 'WINDOWS' if typ == 'gui' else 'CONSOLE'
|
||||
for mod, bname, func in zip(modules[typ], basenames[typ], functions[typ]):
|
||||
cflags = '/c /EHsc /MT /W3 /O1 /nologo /D_UNICODE /DUNICODE /GS-'.split()
|
||||
if typ == 'gui':
|
||||
cflags += ['/DGUI_APP=']
|
||||
|
||||
cflags += ['/DMODULE="%s"' % mod, '/DBASENAME="%s"' % bname,
|
||||
'/DFUNCTION="%s"' % func]
|
||||
dest = j(env.obj_dir, bname + '.obj')
|
||||
printf('Compiling', bname)
|
||||
cmd = [CL] + cflags + dflags + ['/Tc' + src, '/Fo' + dest]
|
||||
run_compiler(env, *cmd)
|
||||
exe = j(env.base, bname + '.exe')
|
||||
lib = dll.replace('.dll', '.lib')
|
||||
u32 = ['user32.lib']
|
||||
printf('Linking', bname)
|
||||
mf = dest + '.manifest'
|
||||
with open(mf, 'wb') as f:
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/MACHINE:' + machine, '/NODEFAULTLIB', '/ENTRY:start_here',
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:' + subsys,
|
||||
'/LIBPATH:%s/libs' % env.python_base, '/RELEASE',
|
||||
'/MANIFEST:EMBED', '/MANIFESTINPUT:' + mf,
|
||||
'user32.lib', 'kernel32.lib',
|
||||
'/OUT:' + exe] + u32 + dlflags + [embed_resources(env, exe), dest, lib]
|
||||
run(*cmd)
|
||||
|
||||
|
||||
def add_to_zipfile(zf, name, base, zf_names):
|
||||
abspath = j(base, name)
|
||||
name = name.replace(os.sep, '/')
|
||||
if name in zf_names:
|
||||
raise ValueError('Already added %r to zipfile [%r]' % (name, abspath))
|
||||
zinfo = zipfile.ZipInfo(filename=name, date_time=(1980, 1, 1, 0, 0, 0))
|
||||
|
||||
if os.path.isdir(abspath):
|
||||
if not os.listdir(abspath):
|
||||
return
|
||||
zinfo.external_attr = 0o700 << 16
|
||||
zf.writestr(zinfo, '')
|
||||
for x in os.listdir(abspath):
|
||||
add_to_zipfile(zf, name + os.sep + x, base, zf_names)
|
||||
else:
|
||||
ext = os.path.splitext(name)[1].lower()
|
||||
if ext in ('.dll',):
|
||||
raise ValueError('Cannot add %r to zipfile' % abspath)
|
||||
zinfo.external_attr = 0o600 << 16
|
||||
if ext in ('.py', '.pyc', '.pyo'):
|
||||
with open(abspath, 'rb') as f:
|
||||
zf.writestr(zinfo, f.read())
|
||||
|
||||
zf_names.add(name)
|
||||
|
||||
|
||||
def archive_lib_dir(env):
|
||||
printf('Putting all python code into a zip file for performance')
|
||||
zf_names = set()
|
||||
with zipfile.ZipFile(env.pylib, 'w', zipfile.ZIP_STORED) as zf:
|
||||
# Add everything in Lib except site-packages to the zip file
|
||||
for x in os.listdir(env.lib_dir):
|
||||
if x == 'site-packages':
|
||||
continue
|
||||
add_to_zipfile(zf, x, env.lib_dir, zf_names)
|
||||
|
||||
sp = j(env.lib_dir, 'site-packages')
|
||||
# Special handling for pywin32
|
||||
handled = {'pywin32.pth', 'win32'}
|
||||
base = j(sp, 'win32', 'lib')
|
||||
for x in os.listdir(base):
|
||||
if os.path.splitext(x)[1] not in ('.exe',):
|
||||
add_to_zipfile(zf, x, base, zf_names)
|
||||
base = os.path.dirname(base)
|
||||
for x in os.listdir(base):
|
||||
if not os.path.isdir(j(base, x)):
|
||||
if os.path.splitext(x)[1] not in ('.exe',):
|
||||
add_to_zipfile(zf, x, base, zf_names)
|
||||
|
||||
# We dont want the site.py (if any) from site-packages
|
||||
handled.add('site.pyo')
|
||||
|
||||
# The rest of site-packages
|
||||
for x in os.listdir(sp):
|
||||
if x in handled or x.endswith('.egg-info'):
|
||||
continue
|
||||
absp = j(sp, x)
|
||||
if os.path.isdir(absp):
|
||||
if not os.listdir(absp):
|
||||
continue
|
||||
add_to_zipfile(zf, x, sp, zf_names)
|
||||
else:
|
||||
add_to_zipfile(zf, x, sp, zf_names)
|
||||
|
||||
shutil.rmtree(env.lib_dir)
|
||||
|
||||
|
||||
def copy_crt_and_d3d(env):
|
||||
printf('Copying CRT and D3D...')
|
||||
plat = ('x64' if is64bit else 'x86')
|
||||
for key, val in worker_env.items():
|
||||
if 'COMNTOOLS' in key.upper():
|
||||
redist_dir = os.path.dirname(os.path.dirname(val.rstrip(os.sep)))
|
||||
redist_dir = os.path.join(redist_dir, 'VC', 'Redist', 'MSVC')
|
||||
vc_path = glob.glob(os.path.join(redist_dir, '*', plat, '*.CRT'))[0]
|
||||
break
|
||||
else:
|
||||
raise SystemExit('Could not find Visual Studio redistributable CRT')
|
||||
|
||||
sdk_path = os.path.join(
|
||||
worker_env['UNIVERSALCRTSDKDIR'], 'Redist', worker_env['WINDOWSSDKVERSION'],
|
||||
'ucrt', 'DLLs', plat)
|
||||
if not os.path.exists(sdk_path):
|
||||
raise SystemExit('Windows 10 Universal CRT redistributable not found at: %r' % sdk_path)
|
||||
d3d_path = os.path.join(
|
||||
worker_env['WINDOWSSDKDIR'], 'Redist', 'D3D', plat)
|
||||
if not os.path.exists(d3d_path):
|
||||
raise SystemExit('Windows 10 D3D redistributable not found at: %r' % d3d_path)
|
||||
mesa_path = os.path.join(os.environ['MESA'], ('64' if is64bit else '32'), 'opengl32sw.dll')
|
||||
if not os.path.exists(mesa_path):
|
||||
raise SystemExit('Mesa DLLs (opengl32sw.dll) not found at: %r' % mesa_path)
|
||||
|
||||
def copy_dll(dll):
|
||||
shutil.copy2(dll, env.dll_dir)
|
||||
os.chmod(os.path.join(env.dll_dir, b(dll)), stat.S_IRWXU)
|
||||
|
||||
for dll in glob.glob(os.path.join(d3d_path, '*.dll')):
|
||||
if os.path.basename(dll).lower().startswith('d3dcompiler_'):
|
||||
copy_dll(dll)
|
||||
copy_dll(mesa_path)
|
||||
for dll in glob.glob(os.path.join(sdk_path, '*.dll')):
|
||||
copy_dll(dll)
|
||||
for dll in glob.glob(os.path.join(vc_path, '*.dll')):
|
||||
bname = os.path.basename(dll)
|
||||
if not bname.startswith('vccorlib') and not bname.startswith('concrt'):
|
||||
# Those two DLLs are not required vccorlib is for the CORE CLR
|
||||
# I think concrt is the concurrency runtime for C++ which I believe
|
||||
# nothing in calibre currently uses
|
||||
copy_dll(dll)
|
||||
|
||||
|
||||
def sign_executables(env):
|
||||
files_to_sign = []
|
||||
for path in walk(env.base):
|
||||
if path.lower().endswith('.exe'):
|
||||
files_to_sign.append(path)
|
||||
printf('Signing {} exe files'.format(len(files_to_sign)))
|
||||
sign_files(env, files_to_sign)
|
||||
|
||||
|
||||
def main():
|
||||
ext_dir = globals()['ext_dir']
|
||||
args = globals()['args']
|
||||
run_tests = iv['run_tests']
|
||||
env = Env(build_dir())
|
||||
initbase(env)
|
||||
build_launchers(env)
|
||||
build_utils(env)
|
||||
freeze(env, ext_dir)
|
||||
embed_manifests(env)
|
||||
copy_crt_and_d3d(env)
|
||||
archive_lib_dir(env)
|
||||
if not args.skip_tests:
|
||||
run_tests(os.path.join(env.base, 'calibre-debug.exe'), env.base)
|
||||
if args.sign_installers:
|
||||
sign_executables(env)
|
||||
create_installer(env)
|
||||
if not is64bit:
|
||||
build_portable(env)
|
||||
build_portable_installer(env)
|
||||
if args.sign_installers:
|
||||
sign_installers(env)
|
||||
|
||||
|
||||
def develop_launcher():
|
||||
import subprocess
|
||||
|
||||
def r(*a):
|
||||
subprocess.check_call(list(a))
|
||||
|
||||
r(
|
||||
'cl.EXE', '/c', '/EHsc', '/MT', '/W3', '/O1', '/nologo', '/D_UNICODE', '/DUNICODE', '/GS-',
|
||||
'/DMODULE="calibre.debug"', '/DBASENAME="calibre-debug"', '/DFUNCTION="main"',
|
||||
r'/TcC:\r\src\bypy\windows\main.c', r'/Fo..\launcher\calibre-debug.obj'
|
||||
)
|
||||
r(
|
||||
'link.EXE', '/MACHINE:X86', '/NODEFAULTLIB', '/ENTRY:start_here',
|
||||
r'/LIBPATH:..\launcher', '/SUBSYSTEM:CONSOLE',
|
||||
r'/LIBPATH:C:\r\sw32\sw\private\python/libs', '/RELEASE',
|
||||
'/MANIFEST:EMBED', r'/MANIFESTINPUT:..\launcher\calibre-debug.obj.manifest',
|
||||
'user32.lib', 'kernel32.lib', r'/OUT:calibre-debug.exe',
|
||||
'user32.lib', '/INCREMENTAL:NO', r'..\launcher\calibre-debug.exe.res',
|
||||
r'..\launcher\calibre-debug.obj', r'..\launcher\calibre-launcher.lib'
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
423
bypy/windows/eject.c
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* eject.c
|
||||
* Copyright (C) 2013 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "Windows.h"
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <winioctl.h>
|
||||
#include <setupapi.h>
|
||||
#include <devguid.h>
|
||||
#include <cfgmgr32.h>
|
||||
|
||||
#define BUFSIZE 4096
|
||||
#define LOCK_TIMEOUT 10000 // 10 Seconds
|
||||
#define LOCK_RETRIES 20
|
||||
|
||||
#define BOOL2STR(x) ((x) ? L"True" : L"False")
|
||||
|
||||
// Error handling {{{
|
||||
|
||||
static void show_error(LPCWSTR msg) {
|
||||
MessageBeep(MB_ICONERROR);
|
||||
MessageBoxW(NULL, msg, L"Error", MB_OK|MB_ICONERROR);
|
||||
}
|
||||
|
||||
static void show_detailed_error(LPCWSTR preamble, LPCWSTR msg, int code) {
|
||||
LPWSTR buf;
|
||||
buf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR)*
|
||||
(wcslen(msg) + wcslen(preamble) + 80));
|
||||
|
||||
_snwprintf_s(buf,
|
||||
LocalSize(buf) / sizeof(WCHAR), _TRUNCATE,
|
||||
L"%s\r\n %s (Error Code: %d)\r\n",
|
||||
preamble, msg, code);
|
||||
|
||||
show_error(buf);
|
||||
LocalFree(buf);
|
||||
}
|
||||
|
||||
static void print_detailed_error(LPCWSTR preamble, LPCWSTR msg, int code) {
|
||||
fwprintf_s(stderr, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void show_last_error_crt(LPCWSTR preamble) {
|
||||
WCHAR buf[BUFSIZE];
|
||||
int err = 0;
|
||||
|
||||
_get_errno(&err);
|
||||
_wcserror_s(buf, BUFSIZE, err);
|
||||
show_detailed_error(preamble, buf, err);
|
||||
}
|
||||
|
||||
static void show_last_error(LPCWSTR preamble) {
|
||||
WCHAR *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR)&msg,
|
||||
0, NULL );
|
||||
|
||||
show_detailed_error(preamble, msg, (int)dw);
|
||||
}
|
||||
|
||||
static void print_last_error(LPCWSTR preamble) {
|
||||
WCHAR *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessageW(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR)&msg,
|
||||
0, NULL );
|
||||
|
||||
print_detailed_error(preamble, msg, (int)dw);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
static void print_help() {
|
||||
fwprintf_s(stderr, L"Usage: calibre-eject.exe drive-letter1 [drive-letter2 drive-letter3 ...]");
|
||||
}
|
||||
|
||||
static LPWSTR root_path = L"X:\\", device_path = L"X:", volume_access_path = L"\\\\.\\X:";
|
||||
static wchar_t dos_device_name[MAX_PATH];
|
||||
static UINT drive_type = 0;
|
||||
static long device_number = -1;
|
||||
static DEVINST dev_inst = 0, dev_inst_parent = 0;
|
||||
|
||||
// Unmount and eject volumes (drives) {{{
|
||||
static HANDLE open_volume(wchar_t drive_letter) {
|
||||
DWORD access_flags;
|
||||
|
||||
switch(drive_type) {
|
||||
case DRIVE_REMOVABLE:
|
||||
access_flags = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
case DRIVE_CDROM:
|
||||
access_flags = GENERIC_READ;
|
||||
break;
|
||||
default:
|
||||
fwprintf_s(stderr, L"Cannot eject %c: Drive type is incorrect.\r\n", drive_letter);
|
||||
fflush(stderr);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return CreateFileW(volume_access_path, access_flags,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
}
|
||||
|
||||
static BOOL lock_volume(HANDLE volume) {
|
||||
DWORD bytes_returned;
|
||||
DWORD sleep_amount = LOCK_TIMEOUT / LOCK_RETRIES;
|
||||
int try_count;
|
||||
|
||||
// Do this in a loop until a timeout period has expired
|
||||
for (try_count = 0; try_count < LOCK_RETRIES; try_count++) {
|
||||
if (DeviceIoControl(volume,
|
||||
FSCTL_LOCK_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&bytes_returned,
|
||||
NULL))
|
||||
return TRUE;
|
||||
|
||||
Sleep(sleep_amount);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL dismount_volume(HANDLE volume) {
|
||||
DWORD bytes_returned;
|
||||
|
||||
return DeviceIoControl( volume,
|
||||
FSCTL_DISMOUNT_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&bytes_returned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static BOOL disable_prevent_removal_of_volume(HANDLE volume) {
|
||||
DWORD bytes_returned;
|
||||
PREVENT_MEDIA_REMOVAL PMRBuffer;
|
||||
|
||||
PMRBuffer.PreventMediaRemoval = FALSE;
|
||||
|
||||
return DeviceIoControl( volume,
|
||||
IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0,
|
||||
&bytes_returned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static BOOL auto_eject_volume(HANDLE volume) {
|
||||
DWORD bytes_returned;
|
||||
|
||||
return DeviceIoControl( volume,
|
||||
IOCTL_STORAGE_EJECT_MEDIA,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&bytes_returned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static BOOL unmount_drive(wchar_t drive_letter, BOOL *remove_safely, BOOL *auto_eject) {
|
||||
// Unmount the drive identified by drive_letter. Code adapted from:
|
||||
// http://support.microsoft.com/kb/165721
|
||||
HANDLE volume;
|
||||
*remove_safely = FALSE; *auto_eject = FALSE;
|
||||
|
||||
volume = open_volume(drive_letter);
|
||||
if (volume == INVALID_HANDLE_VALUE) return FALSE;
|
||||
|
||||
// Lock and dismount the volume.
|
||||
if (lock_volume(volume) && dismount_volume(volume)) {
|
||||
*remove_safely = TRUE;
|
||||
|
||||
// Set prevent removal to false and eject the volume.
|
||||
if (disable_prevent_removal_of_volume(volume) && auto_eject_volume(volume))
|
||||
*auto_eject = TRUE;
|
||||
}
|
||||
CloseHandle(volume);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
// }}}
|
||||
|
||||
// Eject USB device {{{
|
||||
static void get_device_number(wchar_t drive_letter) {
|
||||
HANDLE volume;
|
||||
DWORD bytes_returned = 0;
|
||||
STORAGE_DEVICE_NUMBER sdn;
|
||||
|
||||
volume = CreateFileW(volume_access_path, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (volume == INVALID_HANDLE_VALUE) {
|
||||
print_last_error(L"Failed to open volume while getting device number");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DeviceIoControl(volume,
|
||||
IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||
NULL, 0, &sdn, sizeof(sdn),
|
||||
&bytes_returned, NULL))
|
||||
device_number = sdn.DeviceNumber;
|
||||
CloseHandle(volume);
|
||||
}
|
||||
|
||||
static DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, LPWSTR dos_device_name) {
|
||||
GUID *guid;
|
||||
HDEVINFO dev_info;
|
||||
DWORD index, bytes_returned;
|
||||
BOOL bRet, is_floppy;
|
||||
BYTE Buf[1024];
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd;
|
||||
long res;
|
||||
HANDLE drive;
|
||||
STORAGE_DEVICE_NUMBER sdn;
|
||||
SP_DEVICE_INTERFACE_DATA spdid;
|
||||
SP_DEVINFO_DATA spdd;
|
||||
DWORD size;
|
||||
|
||||
is_floppy = (wcsstr(dos_device_name, L"\\Floppy") != NULL); // is there a better way?
|
||||
|
||||
switch (drive_type) {
|
||||
case DRIVE_REMOVABLE:
|
||||
guid = ( (is_floppy) ? (GUID*)&GUID_DEVINTERFACE_FLOPPY : (GUID*)&GUID_DEVINTERFACE_DISK );
|
||||
break;
|
||||
case DRIVE_FIXED:
|
||||
guid = (GUID*)&GUID_DEVINTERFACE_DISK;
|
||||
break;
|
||||
case DRIVE_CDROM:
|
||||
guid = (GUID*)&GUID_DEVINTERFACE_CDROM;
|
||||
break;
|
||||
default:
|
||||
fwprintf_s(stderr, L"Invalid drive type at line: %d\r\n", __LINE__);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get device interface info set handle
|
||||
// for all devices attached to system
|
||||
dev_info = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
|
||||
if (dev_info == INVALID_HANDLE_VALUE) {
|
||||
fwprintf_s(stderr, L"Failed to setup class devs at line: %d\r\n", __LINE__);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retrieve a context structure for a device interface
|
||||
// of a device information set.
|
||||
index = 0;
|
||||
bRet = FALSE;
|
||||
|
||||
pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
|
||||
spdid.cbSize = sizeof(spdid);
|
||||
|
||||
while ( TRUE ) {
|
||||
bRet = SetupDiEnumDeviceInterfaces(dev_info, NULL,
|
||||
guid, index, &spdid);
|
||||
if ( !bRet ) break;
|
||||
|
||||
size = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(dev_info,
|
||||
&spdid, NULL, 0, &size, NULL);
|
||||
|
||||
if ( size!=0 && size<=sizeof(Buf) ) {
|
||||
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
|
||||
|
||||
ZeroMemory((PVOID)&spdd, sizeof(spdd));
|
||||
spdd.cbSize = sizeof(spdd);
|
||||
|
||||
res = SetupDiGetDeviceInterfaceDetail(dev_info, &spdid, pspdidd, size, &size, &spdd);
|
||||
if ( res ) {
|
||||
drive = CreateFile(pspdidd->DevicePath,0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if ( drive != INVALID_HANDLE_VALUE ) {
|
||||
bytes_returned = 0;
|
||||
res = DeviceIoControl(drive,
|
||||
IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||
NULL, 0, &sdn, sizeof(sdn),
|
||||
&bytes_returned, NULL);
|
||||
if ( res ) {
|
||||
if ( device_number == (long)sdn.DeviceNumber ) {
|
||||
CloseHandle(drive);
|
||||
SetupDiDestroyDeviceInfoList(dev_info);
|
||||
return spdd.DevInst;
|
||||
}
|
||||
}
|
||||
CloseHandle(drive);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(dev_info);
|
||||
fwprintf_s(stderr, L"Invalid device number at line: %d\r\n", __LINE__);
|
||||
fflush(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void get_parent_device(wchar_t drive_letter) {
|
||||
get_device_number(drive_letter);
|
||||
if (device_number == -1) return;
|
||||
if (QueryDosDeviceW(device_path, dos_device_name, MAX_PATH) == 0) {
|
||||
print_last_error(L"Failed to query DOS device name");
|
||||
return;
|
||||
}
|
||||
|
||||
dev_inst = get_dev_inst_by_device_number(device_number,
|
||||
drive_type, dos_device_name);
|
||||
if (dev_inst == 0) {
|
||||
fwprintf_s(stderr, L"Failed to get device by device number");
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
if (CM_Get_Parent(&dev_inst_parent, dev_inst, 0) != CR_SUCCESS) {
|
||||
fwprintf_s(stderr, L"Failed to get device parent from CM");
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int eject_device() {
|
||||
int tries;
|
||||
CONFIGRET res;
|
||||
PNP_VETO_TYPE VetoType;
|
||||
WCHAR VetoNameW[MAX_PATH];
|
||||
BOOL success;
|
||||
|
||||
for ( tries = 0; tries < 3; tries++ ) {
|
||||
VetoNameW[0] = 0;
|
||||
|
||||
res = CM_Request_Device_EjectW(dev_inst_parent,
|
||||
&VetoType, VetoNameW, MAX_PATH, 0);
|
||||
|
||||
success = (res==CR_SUCCESS &&
|
||||
VetoType==PNP_VetoTypeUnknown);
|
||||
if ( success ) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(500); // required to give the next tries a chance!
|
||||
}
|
||||
if (!success) {
|
||||
fwprintf_s(stderr, L"CM_Request_Device_Eject failed after three tries\r\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
return (success) ? 0 : 1;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
int wmain(int argc, wchar_t *argv[ ]) {
|
||||
int i = 0;
|
||||
wchar_t drive_letter;
|
||||
BOOL remove_safely, auto_eject;
|
||||
|
||||
// Validate command line arguments
|
||||
if (argc < 2) { print_help(); return 1; }
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (wcsnlen_s(argv[i], 2) != 1) { print_help(); return 1; }
|
||||
}
|
||||
|
||||
// Unmount all mounted volumes and eject volume media
|
||||
for (i = 1; i < argc; i++) {
|
||||
drive_letter = *argv[i];
|
||||
root_path[0] = drive_letter;
|
||||
device_path[0] = drive_letter;
|
||||
volume_access_path[4] = drive_letter;
|
||||
drive_type = GetDriveTypeW(root_path);
|
||||
if (i == 1 && device_number == -1) {
|
||||
get_parent_device(drive_letter);
|
||||
}
|
||||
if (device_number != -1) {
|
||||
unmount_drive(drive_letter, &remove_safely, &auto_eject);
|
||||
fwprintf_s(stdout, L"Unmounting: %c: Remove safely: %s Media Ejected: %s\r\n",
|
||||
drive_letter, BOOL2STR(remove_safely), BOOL2STR(auto_eject));
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// Eject the parent USB device
|
||||
if (device_number == -1) {
|
||||
fwprintf_s(stderr, L"Cannot eject, failed to get device number\r\n");
|
||||
fflush(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dev_inst_parent == 0) {
|
||||
fwprintf_s(stderr, L"Cannot eject, failed to get device parent\r\n");
|
||||
fflush(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return eject_device();
|
||||
}
|
||||
|
||||
|
9
bypy/windows/en-us.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
|
||||
<String Id="AdvancedWelcomeEulaDlgDescriptionPerUser">Click Advanced to change installation settings.</String>
|
||||
<String Id="ProgressTextFileCost">Computing space requirements, this may take up to five minutes...</String>
|
||||
<String Id="ProgressTextCostInitialize">Computing space requirements, this may take up to five minutes...</String>
|
||||
<String Id="ProgressTextCostFinalize">Computing space requirements, this may take up to five minutes...</String>
|
||||
<String Id="WaitForCostingDlgText">Please wait while the installer finishes determining your disk space requirements, this may take up to five minutes...</String>
|
||||
</WixLocalization>
|
||||
|
355
bypy/windows/file_dialogs.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
* file_dialogs.c
|
||||
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <Shobjidl.h>
|
||||
#include <comdef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define PRINTERR(x) fprintf(stderr, "%s", x); fflush(stderr);
|
||||
#define SECRET_SIZE 32
|
||||
|
||||
void set_dpi_aware() {
|
||||
// Try SetProcessDpiAwareness first
|
||||
HINSTANCE sh_core = LoadLibraryW(L"Shcore.dll");
|
||||
|
||||
if (sh_core) {
|
||||
enum ProcessDpiAwareness
|
||||
{
|
||||
ProcessDpiUnaware = 0,
|
||||
ProcessSystemDpiAware = 1,
|
||||
ProcessPerMonitorDpiAware = 2
|
||||
};
|
||||
|
||||
typedef HRESULT (WINAPI* SetProcessDpiAwarenessFuncType)(ProcessDpiAwareness);
|
||||
SetProcessDpiAwarenessFuncType SetProcessDpiAwarenessFunc = reinterpret_cast<SetProcessDpiAwarenessFuncType>(GetProcAddress(sh_core, "SetProcessDpiAwareness"));
|
||||
|
||||
if (SetProcessDpiAwarenessFunc) {
|
||||
// We only check for E_INVALIDARG because we would get
|
||||
// E_ACCESSDENIED if the DPI was already set previously
|
||||
// and S_OK means the call was successful
|
||||
if (SetProcessDpiAwarenessFunc(ProcessPerMonitorDpiAware) == E_INVALIDARG) {
|
||||
PRINTERR("Failed to set process DPI awareness using SetProcessDpiAwareness");
|
||||
} else {
|
||||
FreeLibrary(sh_core);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(sh_core);
|
||||
}
|
||||
|
||||
// Fall back to SetProcessDPIAware if SetProcessDpiAwareness
|
||||
// is not available on this system
|
||||
HINSTANCE user32 = LoadLibraryW(L"user32.dll");
|
||||
|
||||
if (user32) {
|
||||
typedef BOOL (WINAPI* SetProcessDPIAwareFuncType)(void);
|
||||
SetProcessDPIAwareFuncType SetProcessDPIAwareFunc = reinterpret_cast<SetProcessDPIAwareFuncType>(GetProcAddress(user32, "SetProcessDPIAware"));
|
||||
|
||||
if (SetProcessDPIAwareFunc) {
|
||||
if (!SetProcessDPIAwareFunc()) {
|
||||
PRINTERR("Failed to set process DPI awareness using SetProcessDPIAware");
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(user32);
|
||||
}
|
||||
}
|
||||
|
||||
bool write_bytes(HANDLE pipe, DWORD sz, const char* buf) {
|
||||
DWORD written = 0;
|
||||
if (!WriteFile(pipe, buf, sz, &written, NULL)) {
|
||||
fprintf(stderr, "Failed to write to pipe. GetLastError()=%d\n", GetLastError()); fflush(stderr); return false;
|
||||
}
|
||||
if (written != sz) {
|
||||
fprintf(stderr, "Failed to write to pipe. Incomplete write, leftover bytes: %d", sz - written); fflush(stderr); return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_bytes(size_t sz, char* buf, bool allow_incomplete=false) {
|
||||
char *ptr = buf, *limit = buf + sz;
|
||||
while(limit > ptr && !feof(stdin) && !ferror(stdin)) {
|
||||
ptr += fread(ptr, 1, limit - ptr, stdin);
|
||||
}
|
||||
if (ferror(stdin)) { PRINTERR("Failed to read from stdin!"); return false; }
|
||||
if (ptr - buf != sz) { if (!allow_incomplete) PRINTERR("Truncated input!"); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool from_utf8(size_t sz, const char *src, LPWSTR* ans) {
|
||||
int asz = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, (int)sz, NULL, 0);
|
||||
if (!asz) { PRINTERR("Failed to get size of UTF-8 string"); return false; }
|
||||
*ans = (LPWSTR)calloc(asz+1, sizeof(wchar_t));
|
||||
if(*ans == NULL) { PRINTERR("Out of memory!"); return false; }
|
||||
asz = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, (int)sz, *ans, asz);
|
||||
if (!asz) { PRINTERR("Failed to convert UTF-8 string"); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
char* to_utf8(LPCWSTR src, int *sz) {
|
||||
// Convert to a null-terminated UTF-8 encoded bytearray, allocated on the heap
|
||||
char *ans = NULL;
|
||||
*sz = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
|
||||
if (!*sz) { PRINTERR("Failed to get size of UTF-16 string"); return NULL; }
|
||||
ans = (char*)calloc((*sz) + 1, sizeof(char));
|
||||
if (ans == NULL) { PRINTERR("Out of memory!"); return NULL; }
|
||||
*sz = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, ans, *sz, NULL, NULL);
|
||||
if (!*sz) { PRINTERR("Failed to convert UTF-16 string"); return NULL; }
|
||||
return ans;
|
||||
}
|
||||
|
||||
static char* rsbuf = NULL;
|
||||
|
||||
bool read_string(unsigned short sz, LPWSTR* ans) {
|
||||
memset(rsbuf, 0, 65537);
|
||||
if (!read_bytes(sz, rsbuf)) return false;
|
||||
if (!from_utf8(sz, rsbuf, ans)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
COMDLG_FILTERSPEC *read_file_types(UINT *num_file_types) {
|
||||
char buf[10] = {0};
|
||||
COMDLG_FILTERSPEC *ans = NULL;
|
||||
|
||||
if(!read_bytes(sizeof(unsigned short), buf)) return NULL;
|
||||
*num_file_types = *((unsigned short*)buf);
|
||||
if (*num_file_types < 1 || *num_file_types > 500) { PRINTERR("Invalid number of file types"); return NULL; }
|
||||
ans = (COMDLG_FILTERSPEC*)calloc((*num_file_types) + 1, sizeof(COMDLG_FILTERSPEC));
|
||||
if (ans == NULL) { PRINTERR("Out of memory!"); return NULL; }
|
||||
|
||||
for(unsigned short i = 0; i < *num_file_types; i++) {
|
||||
if(!read_bytes(sizeof(unsigned short), buf)) return NULL;
|
||||
if(!read_string(*((unsigned short*)buf), (LPWSTR*)&(ans[i].pszName))) return NULL;
|
||||
if(!read_bytes(sizeof(unsigned short), buf)) return NULL;
|
||||
if(!read_string(*((unsigned short*)buf), (LPWSTR*)&(ans[i].pszSpec))) return NULL;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
static void print_com_error(HRESULT hr, const char *msg) {
|
||||
_com_error err(hr);
|
||||
LPCWSTR emsg = (LPCWSTR) err.ErrorMessage();
|
||||
int sz = 0;
|
||||
const char *buf = to_utf8(emsg, &sz);
|
||||
if (buf == NULL) { fprintf(stderr, "%s", msg); }
|
||||
else { fprintf(stderr, "%s: (HRESULT=0x%x) %s\n", msg, hr, buf); }
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
#define REPORTERR(hr, x) { print_com_error(hr, x); ret = 1; goto error; }
|
||||
#define CALLCOM(x, err) hr = x; if(FAILED(hr)) REPORTERR(hr, err)
|
||||
|
||||
int show_dialog(HANDLE pipe, char *secret, HWND parent, bool save_dialog, LPWSTR title, LPWSTR folder, LPWSTR filename, LPWSTR save_path, bool multiselect, bool confirm_overwrite, bool only_dirs, bool no_symlinks, COMDLG_FILTERSPEC *file_types, UINT num_file_types, LPWSTR default_extension) {
|
||||
int ret = 0, name_sz = 0;
|
||||
IFileDialog *pfd = NULL;
|
||||
IShellItemArray *items = NULL;
|
||||
IShellItem *item = NULL, *folder_item = NULL, *save_path_item = NULL;
|
||||
char *path = NULL;
|
||||
DWORD options = 0, item_count = 0;
|
||||
LPWSTR name = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
hr = CoInitialize(NULL);
|
||||
if (FAILED(hr)) { PRINTERR("Failed to initialize COM"); return 1; }
|
||||
|
||||
CALLCOM(CoCreateInstance((save_dialog ? CLSID_FileSaveDialog : CLSID_FileOpenDialog),
|
||||
NULL, CLSCTX_INPROC_SERVER, (save_dialog ? IID_IFileSaveDialog : IID_IFileOpenDialog),
|
||||
reinterpret_cast<LPVOID*>(&pfd)),
|
||||
"Failed to create COM object for file dialog")
|
||||
CALLCOM(pfd->GetOptions(&options), "Failed to get options")
|
||||
options |= FOS_PATHMUSTEXIST;
|
||||
if (no_symlinks) options |= FOS_NODEREFERENCELINKS;
|
||||
if (save_dialog) {
|
||||
options |= FOS_NOREADONLYRETURN;
|
||||
if (confirm_overwrite) options |= FOS_OVERWRITEPROMPT;
|
||||
if (save_path != NULL) {
|
||||
hr = SHCreateItemFromParsingName(save_path, NULL, IID_IShellItem, reinterpret_cast<void **>(&save_path_item));
|
||||
// Failure to set initial save path is not critical
|
||||
if (SUCCEEDED(hr)) ((IFileSaveDialog*)pfd)->SetSaveAsItem(save_path_item);
|
||||
}
|
||||
} else {
|
||||
if (multiselect) options |= FOS_ALLOWMULTISELECT;
|
||||
if (only_dirs) options |= FOS_PICKFOLDERS;
|
||||
options |= FOS_FILEMUSTEXIST;
|
||||
}
|
||||
CALLCOM(pfd->SetOptions(options), "Failed to set options")
|
||||
if (title != NULL) { CALLCOM(pfd->SetTitle(title), "Failed to set title") }
|
||||
if (folder != NULL) {
|
||||
hr = SHCreateItemFromParsingName(folder, NULL, IID_IShellItem, reinterpret_cast<void **>(&folder_item));
|
||||
// Failure to set initial folder is not critical
|
||||
if (SUCCEEDED(hr)) pfd->SetFolder(folder_item);
|
||||
}
|
||||
if (filename != NULL) pfd->SetFileName(filename); // Failure is not critical
|
||||
if (!(options & FOS_PICKFOLDERS) && file_types != NULL && num_file_types > 0) {
|
||||
CALLCOM(pfd->SetFileTypes(num_file_types, file_types), "Failed to set file types")
|
||||
CALLCOM(pfd->SetFileTypeIndex(1), "Failed to set file type index")
|
||||
}
|
||||
if (default_extension != NULL) {
|
||||
CALLCOM(pfd->SetDefaultExtension(default_extension), "Failed to set default extension")
|
||||
}
|
||||
hr = pfd->Show(parent);
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) goto error;
|
||||
if (FAILED(hr)) REPORTERR(hr, "Failed to show dialog")
|
||||
|
||||
if (save_dialog) {
|
||||
CALLCOM(pfd->GetResult(&item), "Failed to get save dialog result");
|
||||
CALLCOM(item->GetDisplayName(SIGDN_FILESYSPATH, &name), "Failed to get display name of save dialog result");
|
||||
path = to_utf8(name, &name_sz);
|
||||
CoTaskMemFree(name); name = NULL;
|
||||
if (path == NULL) return 1;
|
||||
if (!write_bytes(pipe, SECRET_SIZE+1, secret)) return 1;
|
||||
if (!write_bytes(pipe, name_sz, path)) return 1;
|
||||
} else {
|
||||
CALLCOM(((IFileOpenDialog*)pfd)->GetResults(&items), "Failed to get dialog results");
|
||||
CALLCOM(items->GetCount(&item_count), "Failed to get count of results");
|
||||
if (item_count > 0) {
|
||||
if (!write_bytes(pipe, SECRET_SIZE+1, secret)) return 1;
|
||||
for (DWORD i = 0; i < item_count; i++) {
|
||||
CALLCOM(items->GetItemAt(i, &item), "Failed to get result item");
|
||||
if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) {
|
||||
path = to_utf8(name, &name_sz);
|
||||
CoTaskMemFree(name); name = NULL;
|
||||
if (path == NULL) return 1;
|
||||
if (!write_bytes(pipe, name_sz, path)) return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
if(pfd) pfd->Release();
|
||||
CoUninitialize();
|
||||
return ret;
|
||||
}
|
||||
#define READ(x, y) if (!read_bytes((x), (y))) return 1;
|
||||
#define CHECK_KEY(x) (key_size == sizeof(x) - 1 && memcmp(buf, x, sizeof(x) - 1) == 0)
|
||||
#define READSTR(x) READ(sizeof(unsigned short), buf); if(!read_string(*((unsigned short*)buf), &x)) return 1;
|
||||
#define SETBINARY(x) if(_setmode(_fileno(x), _O_BINARY) == -1) { PRINTERR("Failed to set binary mode"); return 1; }
|
||||
#define READBOOL(x) READ(1, buf); x = !!buf[0];
|
||||
|
||||
HANDLE open_named_pipe(LPWSTR pipename) {
|
||||
HANDLE ans = INVALID_HANDLE_VALUE;
|
||||
while(true) {
|
||||
ans = CreateFileW(pipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (ans != INVALID_HANDLE_VALUE) break;
|
||||
if (GetLastError() != ERROR_PIPE_BUSY) {
|
||||
fprintf(stderr, "Failed to open pipe. GetLastError()=%d\n", GetLastError()); fflush(stderr); return ans;
|
||||
}
|
||||
if (!WaitNamedPipeW(pipename, 20000)) {
|
||||
fprintf(stderr, "Failed to open pipe. 20 second wait timed out. GetLastError()=%d\n", GetLastError()); fflush(stderr); return ans;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
typedef HRESULT (__stdcall *app_uid_func)(PCWSTR app_uid);
|
||||
|
||||
bool set_app_uid(LPWSTR app_uid) {
|
||||
// Not available on vista so we have to load the function dynamically
|
||||
bool ok = false;
|
||||
HINSTANCE dll = LoadLibraryW(L"Shell32.dll");
|
||||
if (dll != NULL) {
|
||||
app_uid_func f = (app_uid_func)GetProcAddress(dll, "SetCurrentProcessExplicitAppUserModelID");
|
||||
if (f != NULL) ok = f(app_uid) == S_OK;
|
||||
FreeLibrary(dll); dll = NULL;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
|
||||
char buf[257] = {0}, secret[SECRET_SIZE + 1] = {0};
|
||||
size_t key_size = 0;
|
||||
HWND parent = NULL;
|
||||
bool save_dialog = false, multiselect = false, confirm_overwrite = false, only_dirs = false, no_symlinks = false;
|
||||
unsigned short len = 0;
|
||||
LPWSTR title = NULL, folder = NULL, filename = NULL, save_path = NULL, echo = NULL, pipename = NULL, default_extension = NULL, app_uid = NULL;
|
||||
COMDLG_FILTERSPEC *file_types = NULL;
|
||||
UINT num_file_types = 0;
|
||||
HANDLE pipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
SETBINARY(stdout); SETBINARY(stdin); SETBINARY(stderr);
|
||||
// The calibre executables call SetDllDirectory, we unset it here just in
|
||||
// case it interferes with some idiotic shell extension or the other
|
||||
SetDllDirectory(NULL);
|
||||
rsbuf = (char*)calloc(65537, sizeof(char));
|
||||
if(rsbuf == NULL) { PRINTERR("Out of memory!"); return 1; }
|
||||
|
||||
while(!feof(stdin)) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if(!read_bytes(1, buf, true)) { if (feof(stdin)) break; return 1;}
|
||||
key_size = (size_t)buf[0];
|
||||
READ(key_size, buf);
|
||||
if CHECK_KEY("HWND") {
|
||||
READ(sizeof(HWND), buf);
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4312)
|
||||
if (sizeof(HWND) == 8) parent = (HWND)*((__int64*)buf);
|
||||
else if (sizeof(HWND) == 4) parent = (HWND)*((__int32*)buf);
|
||||
else { fprintf(stderr, "Unknown pointer size: %zd", sizeof(HWND)); fflush(stderr); return 1;}
|
||||
#pragma warning( pop )
|
||||
}
|
||||
|
||||
else if CHECK_KEY("PIPENAME") { READSTR(pipename); pipe = open_named_pipe(pipename); if (pipe == INVALID_HANDLE_VALUE) return 1; }
|
||||
|
||||
else if CHECK_KEY("SECRET") { if(!read_bytes(SECRET_SIZE, secret)) return 1; }
|
||||
|
||||
else if CHECK_KEY("APP_UID") { READSTR(app_uid) }
|
||||
|
||||
else if CHECK_KEY("TITLE") { READSTR(title) }
|
||||
|
||||
else if CHECK_KEY("FOLDER") { READSTR(folder) }
|
||||
|
||||
else if CHECK_KEY("FILENAME") { READSTR(filename) }
|
||||
|
||||
else if CHECK_KEY("SAVE_PATH") { READSTR(save_path) }
|
||||
|
||||
else if CHECK_KEY("SAVE_AS") { READBOOL(save_dialog) }
|
||||
|
||||
else if CHECK_KEY("MULTISELECT") { READBOOL(multiselect) }
|
||||
|
||||
else if CHECK_KEY("CONFIRM_OVERWRITE") { READBOOL(confirm_overwrite) }
|
||||
|
||||
else if CHECK_KEY("ONLY_DIRS") { READBOOL(only_dirs) }
|
||||
|
||||
else if CHECK_KEY("NO_SYMLINKS") { READBOOL(no_symlinks) }
|
||||
|
||||
else if CHECK_KEY("FILE_TYPES") { file_types = read_file_types(&num_file_types); if (file_types == NULL) return 1; }
|
||||
|
||||
else if CHECK_KEY("DEFAULT_EXTENSION") { READSTR(default_extension) }
|
||||
|
||||
else if CHECK_KEY("ECHO") { READSTR(echo) }
|
||||
|
||||
else {
|
||||
PRINTERR("Unknown key");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe == INVALID_HANDLE_VALUE) { PRINTERR("No pipename received"); return 1; }
|
||||
if (secret == NULL) { PRINTERR("No secret received"); return 1; }
|
||||
|
||||
if (echo != NULL) {
|
||||
int echo_sz = 0;
|
||||
char *echo_buf = to_utf8(echo, &echo_sz);
|
||||
if (!write_bytes(pipe, SECRET_SIZE+1, secret)) return 1;
|
||||
return write_bytes(pipe, echo_sz, echo_buf) ? 0 : 1;
|
||||
}
|
||||
if (app_uid != NULL) {
|
||||
// dont check return status as failure is not critical
|
||||
set_app_uid(app_uid);
|
||||
}
|
||||
|
||||
set_dpi_aware();
|
||||
return show_dialog(pipe, secret, parent, save_dialog, title, folder, filename, save_path, multiselect, confirm_overwrite, only_dirs, no_symlinks, file_types, num_file_types, default_extension);
|
||||
}
|
128
bypy/windows/main.c
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2009 Kovid Goyal
|
||||
*/
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include<windows.h>
|
||||
#include<strsafe.h>
|
||||
|
||||
static size_t mystrlen(const wchar_t *buf) {
|
||||
size_t ans = 0;
|
||||
if (FAILED(StringCbLengthW(buf, 500, &ans))) return 0;
|
||||
return ans;
|
||||
}
|
||||
|
||||
static int show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
|
||||
wchar_t *buf;
|
||||
buf = (wchar_t*)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)*
|
||||
(mystrlen(msg) + mystrlen(preamble) + 80));
|
||||
if (!buf) {
|
||||
MessageBox(NULL, preamble, NULL, MB_OK|MB_ICONERROR);
|
||||
return code;
|
||||
}
|
||||
|
||||
MessageBeep(MB_ICONERROR);
|
||||
wsprintf(buf, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code);
|
||||
MessageBox(NULL, buf, NULL, MB_OK|MB_ICONERROR);
|
||||
LocalFree(buf);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int show_last_error(wchar_t *preamble) {
|
||||
wchar_t *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
int ret;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR)&msg,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
ret = show_error(preamble, msg, (int)dw);
|
||||
if (msg != NULL) LocalFree(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int (__cdecl *ENTRYPROC)(const char*, const char*, const char*, int);
|
||||
typedef void (__cdecl *SIMPLEPRINT)(const wchar_t*);
|
||||
typedef BOOL (*SETDEFAULTDIRS)(DWORD);
|
||||
static ENTRYPROC entrypoint = NULL;
|
||||
static SIMPLEPRINT simple_print = NULL;
|
||||
static HMODULE dll = 0;
|
||||
|
||||
static void
|
||||
load_launcher_dll() {
|
||||
static wchar_t buf[MAX_PATH]; // Cannot use a zero initializer for the array as it generates an implicit call to memset()
|
||||
wchar_t *dll_point = NULL;
|
||||
int i = 0;
|
||||
DWORD sz = 0;
|
||||
|
||||
if ((sz = GetModuleFileNameW(NULL, buf, MAX_PATH)) >= MAX_PATH - 30) {
|
||||
show_error(L"Installation directory path too long", L"", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (sz > 0) {
|
||||
if (buf[sz] == L'\\' || buf[sz] == L'/') { dll_point = buf + sz + 1; break; }
|
||||
sz--;
|
||||
}
|
||||
if (dll_point == NULL) {
|
||||
show_error(L"Executable path has no path separators", L"", 1);
|
||||
return;
|
||||
}
|
||||
wsprintf(dll_point, L"%s\0\0", L"app\\bin");
|
||||
#if _WIN64
|
||||
// Restrict the directories from which DLLs can be loaded
|
||||
// For some reason I cannot determine, using this in 32bit builds causes
|
||||
// a crash even if no dlls are loaded.
|
||||
SETDEFAULTDIRS SetDefaultDllDirectories = (SETDEFAULTDIRS)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories");
|
||||
if (SetDefaultDllDirectories) SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
#endif
|
||||
if (SetDllDirectoryW(buf) == 0) {
|
||||
show_last_error(L"Failed to set DLL directory");
|
||||
return;
|
||||
}
|
||||
// Have to load ucrtbase manually first, otherwise loading fails on systems where the
|
||||
// Universal CRT is not installed.
|
||||
if (!LoadLibraryW(L"ucrtbase.dll")) {
|
||||
show_last_error(L"Unable to find ucrtbase.dll. You should install all Windows updates on your computer to get this file.");
|
||||
return;
|
||||
}
|
||||
if (!(dll = LoadLibraryW(L"calibre-launcher.dll"))) {
|
||||
show_last_error(L"Failed to load: calibre-launcher.dll");
|
||||
return;
|
||||
}
|
||||
if (!(entrypoint = (ENTRYPROC) GetProcAddress(dll, "execute_python_entrypoint"))) {
|
||||
show_last_error(L"Failed to get the calibre-launcher dll entry point");
|
||||
return;
|
||||
}
|
||||
simple_print = (SIMPLEPRINT) GetProcAddress(dll, "simple_print");
|
||||
}
|
||||
|
||||
int __stdcall start_here() {
|
||||
int ret = 0;
|
||||
load_launcher_dll();
|
||||
if (entrypoint) {
|
||||
#ifdef GUI_APP
|
||||
// This should really be returning the value set in the WM_QUIT message, but I cannot be bothered figuring out how to get that.
|
||||
entrypoint(BASENAME, MODULE, FUNCTION, 1);
|
||||
#else
|
||||
ret = entrypoint(BASENAME, MODULE, FUNCTION, 0);
|
||||
#endif
|
||||
} else ret = 1;
|
||||
if (dll != 0) {
|
||||
FreeLibrary(dll);
|
||||
dll = 0;
|
||||
}
|
||||
ExitProcess(ret);
|
||||
return ret;
|
||||
}
|
607
bypy/windows/portable-installer.cpp
Normal file
@ -0,0 +1,607 @@
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Shlobj.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <Shellapi.h>
|
||||
#include <Psapi.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <easylzma/decompress.h>
|
||||
#include "XUnzip.h"
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
// Error handling {{{
|
||||
|
||||
static void show_error(LPCWSTR msg) {
|
||||
MessageBeep(MB_ICONERROR);
|
||||
MessageBox(NULL, msg, L"Error", MB_OK|MB_ICONERROR);
|
||||
}
|
||||
|
||||
static void show_detailed_error(LPCWSTR preamble, LPCWSTR msg, int code) {
|
||||
LPWSTR buf;
|
||||
buf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR)*
|
||||
(wcslen(msg) + wcslen(preamble) + 80));
|
||||
|
||||
_snwprintf_s(buf,
|
||||
LocalSize(buf) / sizeof(WCHAR), _TRUNCATE,
|
||||
L"%s\r\n %s (Error Code: %d)\r\n",
|
||||
preamble, msg, code);
|
||||
|
||||
show_error(buf);
|
||||
LocalFree(buf);
|
||||
}
|
||||
|
||||
static void show_zip_error(LPCWSTR preamble, LPCWSTR msg, ZRESULT code) {
|
||||
LPWSTR buf;
|
||||
char msgbuf[1024] = {0};
|
||||
|
||||
FormatZipMessage(code, msgbuf, 1024);
|
||||
|
||||
buf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR)*
|
||||
(wcslen(preamble) + wcslen(msg) + 1100));
|
||||
|
||||
_snwprintf_s(buf,
|
||||
LocalSize(buf) / sizeof(WCHAR), _TRUNCATE,
|
||||
L"%s\r\n %s (Error: %S)\r\n",
|
||||
preamble, msg, msgbuf);
|
||||
|
||||
show_error(buf);
|
||||
LocalFree(buf);
|
||||
}
|
||||
|
||||
static void show_last_error(LPCWSTR preamble) {
|
||||
WCHAR *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR)&msg,
|
||||
0, NULL );
|
||||
|
||||
show_detailed_error(preamble, msg, (int)dw);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// Load, decompress and extract data {{{
|
||||
|
||||
static BOOL load_data(LPVOID *data, DWORD *sz) {
|
||||
HRSRC rsrc;
|
||||
HGLOBAL h;
|
||||
|
||||
rsrc = FindResourceW(NULL, L"extra", L"extra");
|
||||
if (rsrc == NULL) { show_last_error(L"Failed to find portable data in exe"); return false; }
|
||||
|
||||
h = LoadResource(NULL, rsrc);
|
||||
if (h == NULL) { show_last_error(L"Failed to load portable data from exe"); return false; }
|
||||
|
||||
*data = LockResource(h);
|
||||
if (*data == NULL) { show_last_error(L"Failed to lock portable data in exe"); return false; }
|
||||
|
||||
*sz = SizeofResource(NULL, rsrc);
|
||||
if (sz == 0) { show_last_error(L"Failed to get size of portable data in exe"); return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOL unzip(HZIP zipf, int nitems, IProgressDialog *pd) {
|
||||
int i = 0;
|
||||
ZRESULT res;
|
||||
ZIPENTRYW ze;
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
res = GetZipItem(zipf, i, &ze);
|
||||
if (res != ZR_OK) { show_zip_error(L"Failed to get zip item", L"", res); return false;}
|
||||
|
||||
res = UnzipItem(zipf, i, ze.name, 0, ZIP_FILENAME);
|
||||
if (res != ZR_OK) { CloseZip(zipf); show_zip_error(L"Failed to extract zip item (is your disk full?):", ze.name, res); return false;}
|
||||
|
||||
pd->SetLine(2, ze.name, true, NULL);
|
||||
pd->SetProgress(i, nitems);
|
||||
}
|
||||
|
||||
CloseZip(zipf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static HANDLE temp_file(LPWSTR name) {
|
||||
UINT res;
|
||||
HANDLE h;
|
||||
|
||||
res = GetTempFileNameW(L".", L"portable_data", 0, name);
|
||||
|
||||
if (res == 0) { show_last_error(L"Failed to create temporary file to decompress portable data"); return INVALID_HANDLE_VALUE; }
|
||||
|
||||
h = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) { show_last_error(L"Failed to open temp file to decompress portable data"); }
|
||||
return h;
|
||||
|
||||
}
|
||||
|
||||
struct DataStream
|
||||
{
|
||||
const unsigned char *in_data;
|
||||
size_t in_len;
|
||||
|
||||
HANDLE out;
|
||||
IProgressDialog *pd;
|
||||
};
|
||||
|
||||
static int
|
||||
input_callback(void *ctx, void *buf, size_t * size)
|
||||
{
|
||||
size_t rd = 0;
|
||||
struct DataStream * ds = (struct DataStream *) ctx;
|
||||
|
||||
rd = (ds->in_len < *size) ? ds->in_len : *size;
|
||||
|
||||
if (rd > 0) {
|
||||
memcpy(buf, (void*) ds->in_data, rd);
|
||||
ds->in_data += rd;
|
||||
ds->in_len -= rd;
|
||||
}
|
||||
|
||||
*size = rd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_error_shown = 0;
|
||||
|
||||
static size_t
|
||||
output_callback(void *ctx, const void *buf, size_t size)
|
||||
{
|
||||
struct DataStream * ds = (struct DataStream *) ctx;
|
||||
DWORD written = 0;
|
||||
|
||||
if (size > 0) {
|
||||
if (!WriteFile(ds->out, buf, size, &written, NULL)) {
|
||||
show_last_error(L"Failed to write uncompressed data to temp file");
|
||||
output_error_shown = 1;
|
||||
return 0;
|
||||
}
|
||||
written = SetFilePointer(ds->out, 0, NULL, FILE_CURRENT);
|
||||
ds->pd->SetProgress(written, UNCOMPRESSED_SIZE);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static BOOL decompress(LPVOID src, DWORD src_sz, HANDLE out, IProgressDialog *pd) {
|
||||
elzma_decompress_handle h;
|
||||
struct DataStream ds;
|
||||
int rc;
|
||||
|
||||
h = elzma_decompress_alloc();
|
||||
|
||||
if (h == NULL) { show_error(L"Out of memory"); return false; }
|
||||
|
||||
ds.in_data = (unsigned char*)src;
|
||||
ds.in_len = src_sz;
|
||||
ds.out = out;
|
||||
ds.pd = pd;
|
||||
|
||||
rc = elzma_decompress_run(h, input_callback, (void *) &ds, output_callback,
|
||||
(void *) &ds, ELZMA_lzip);
|
||||
|
||||
if (rc != ELZMA_E_OK) {
|
||||
if (!output_error_shown) show_detailed_error(L"Failed to decompress portable data", L"", rc);
|
||||
elzma_decompress_free(&h);
|
||||
return false;
|
||||
}
|
||||
|
||||
elzma_decompress_free(&h);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOL extract(LPVOID cdata, DWORD csz) {
|
||||
HANDLE h;
|
||||
WCHAR tempnam[MAX_PATH+1] = {0};
|
||||
BOOL ret = true;
|
||||
HZIP zipf;
|
||||
ZIPENTRYW ze;
|
||||
ZRESULT res;
|
||||
int nitems;
|
||||
HRESULT hr;
|
||||
IProgressDialog *pd = NULL;
|
||||
|
||||
hr = CoCreateInstance(CLSID_ProgressDialog, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pd));
|
||||
|
||||
if (FAILED(hr)) { show_error(L"Failed to create progress dialog"); return false; }
|
||||
pd->SetTitle(L"Extracting Calibre Portable");
|
||||
pd->SetLine(1, L"Decompressing data...", true, NULL);
|
||||
|
||||
h = temp_file(tempnam);
|
||||
if (h == INVALID_HANDLE_VALUE) return false;
|
||||
|
||||
pd->StartProgressDialog(NULL, NULL, PROGDLG_NORMAL | PROGDLG_AUTOTIME | PROGDLG_NOCANCEL, NULL);
|
||||
if (!decompress(cdata, csz, h, pd)) { ret = false; goto end; }
|
||||
SetFilePointer(h, 0, NULL, FILE_BEGIN);
|
||||
zipf = OpenZip(h, 0, ZIP_HANDLE);
|
||||
if (zipf == 0) { show_last_error(L"Failed to open zipped portable data"); ret = false; goto end; }
|
||||
|
||||
res = GetZipItem(zipf, -1, &ze);
|
||||
if (res != ZR_OK) { show_zip_error(L"Failed to get count of items in portable data", L"", res); ret = false; goto end;}
|
||||
nitems = ze.index;
|
||||
|
||||
pd->SetLine(1, L"Copying files...", true, NULL);
|
||||
if (!unzip(zipf, nitems, pd)) { ret = false; goto end; }
|
||||
end:
|
||||
pd->StopProgressDialog();
|
||||
pd->Release();
|
||||
CloseHandle(h);
|
||||
DeleteFile(tempnam);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// Find calibre portable directory and install/upgrade into it {{{
|
||||
|
||||
static BOOL directory_exists( LPCWSTR path )
|
||||
{
|
||||
if( _waccess_s( path, 0 ) == 0 )
|
||||
{
|
||||
struct _stat status;
|
||||
_wstat( path, &status );
|
||||
return (status.st_mode & S_IFDIR) != 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL file_exists( LPCWSTR path )
|
||||
{
|
||||
if( _waccess_s( path, 0 ) == 0 )
|
||||
{
|
||||
struct _stat status;
|
||||
_wstat( path, &status );
|
||||
return (status.st_mode & S_IFREG) != 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static LPWSTR get_directory_from_user() {
|
||||
WCHAR name[MAX_PATH+1] = {0};
|
||||
LPWSTR path = NULL;
|
||||
PIDLIST_ABSOLUTE ret;
|
||||
|
||||
path = (LPWSTR)calloc(2*MAX_PATH, sizeof(WCHAR));
|
||||
if (path == NULL) { show_error(L"Out of memory"); return NULL; }
|
||||
|
||||
int image = 0;
|
||||
BROWSEINFO bi = { NULL, NULL, name,
|
||||
L"Select the folder where you want to install or update Calibre Portable",
|
||||
BIF_RETURNONLYFSDIRS | BIF_DONTGOBELOWDOMAIN | BIF_USENEWUI,
|
||||
NULL, NULL, image };
|
||||
|
||||
ret = SHBrowseForFolder(&bi);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!SHGetPathFromIDList(ret, path)) {
|
||||
show_detailed_error(L"The selected folder is not valid: ", name, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
static bool is_dots(LPCWSTR name) {
|
||||
return wcscmp(name, L".") == 0 || wcscmp(name, L"..") == 0;
|
||||
}
|
||||
|
||||
static bool rmtree(LPCWSTR path) {
|
||||
SHFILEOPSTRUCTW op;
|
||||
WCHAR buf[4*MAX_PATH + 2] = {0};
|
||||
|
||||
if (GetFullPathName(path, 4*MAX_PATH, buf, NULL) == 0) return false;
|
||||
|
||||
op.hwnd = NULL;
|
||||
op.wFunc = FO_DELETE;
|
||||
op.pFrom = buf;
|
||||
op.pTo = NULL;
|
||||
op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMMKDIR;
|
||||
op.fAnyOperationsAborted = false;
|
||||
op.hNameMappings = NULL;
|
||||
op.lpszProgressTitle = NULL;
|
||||
|
||||
return SHFileOperationW(&op) == 0;
|
||||
}
|
||||
|
||||
static BOOL find_portable_dir(LPCWSTR base, LPWSTR *result, BOOL *existing) {
|
||||
WCHAR buf[4*MAX_PATH] = {0};
|
||||
|
||||
_snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE, L"%s\\calibre-portable.exe", base);
|
||||
*existing = true;
|
||||
|
||||
if (file_exists(buf)) {
|
||||
*result = _wcsdup(base);
|
||||
if (*result == NULL) { show_error(L"Out of memory"); return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA fdFile;
|
||||
HANDLE hFind = NULL;
|
||||
_snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE, L"%s\\*", base);
|
||||
|
||||
if((hFind = FindFirstFileEx(buf, FindExInfoStandard, &fdFile, FindExSearchLimitToDirectories, NULL, 0)) != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if(is_dots(fdFile.cFileName)) continue;
|
||||
|
||||
if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
_snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE, L"%s\\%s\\calibre-portable.exe", base, fdFile.cFileName);
|
||||
if (file_exists(buf)) {
|
||||
*result = _wcsdup(buf);
|
||||
if (*result == NULL) { show_error(L"Out of memory"); return false; }
|
||||
PathRemoveFileSpec(*result);
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while(FindNextFile(hFind, &fdFile));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
*existing = false;
|
||||
_snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE, L"%s\\Calibre Portable", base);
|
||||
if (!CreateDirectory(buf, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||
show_last_error(L"Failed to create Calibre Portable folder");
|
||||
return false;
|
||||
}
|
||||
*result = _wcsdup(buf);
|
||||
if (*result == NULL) { show_error(L"Out of memory"); return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static LPWSTR make_unpack_dir() {
|
||||
WCHAR buf[4*MAX_PATH] = {0};
|
||||
LPWSTR ans = NULL;
|
||||
|
||||
if (directory_exists(L"_unpack_calibre_portable"))
|
||||
rmtree(L"_unpack_calibre_portable");
|
||||
|
||||
if (!CreateDirectory(L"_unpack_calibre_portable", NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||
show_last_error(L"Failed to create temporary folder to unpack into");
|
||||
return ans;
|
||||
}
|
||||
|
||||
if (!GetFullPathName(L"_unpack_calibre_portable", 4*MAX_PATH, buf, NULL)) {
|
||||
show_last_error(L"Failed to resolve path");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ans = _wcsdup(buf);
|
||||
if (ans == NULL) show_error(L"Out of memory");
|
||||
return ans;
|
||||
|
||||
}
|
||||
|
||||
static BOOL move_program() {
|
||||
if (MoveFileEx(L"Calibre Portable\\calibre-portable.exe",
|
||||
L"..\\calibre-portable.exe", MOVEFILE_REPLACE_EXISTING) == 0) {
|
||||
show_last_error(L"Failed to move calibre-portable.exe, make sure calibre is not running");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (directory_exists(L"..\\Calibre")) {
|
||||
if (!rmtree(L"..\\Calibre")) {
|
||||
show_error(L"Failed to delete the Calibre program folder. Make sure calibre is not running.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (MoveFileEx(L"Calibre Portable\\Calibre", L"..\\Calibre", 0) == 0) {
|
||||
Sleep(4000); // Sleep and try again
|
||||
if (MoveFileEx(L"Calibre Portable\\Calibre", L"..\\Calibre", 0) == 0) {
|
||||
show_last_error(L"Failed to move calibre program folder. This is usually caused by an antivirus program or a file sync program like DropBox. Turn them off temporarily and try again. Underlying error: ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!directory_exists(L"..\\Calibre Library")) {
|
||||
MoveFileEx(L"Calibre Portable\\Calibre Library", L"..\\Calibre Library", 0);
|
||||
}
|
||||
|
||||
if (!directory_exists(L"..\\Calibre Settings")) {
|
||||
MoveFileEx(L"Calibre Portable\\Calibre Settings", L"..\\Calibre Settings", 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// }}}
|
||||
|
||||
static BOOL ensure_not_running() {
|
||||
DWORD processes[4096], needed, num;
|
||||
unsigned int i;
|
||||
WCHAR name[4*MAX_PATH] = L"<unknown>";
|
||||
HANDLE h;
|
||||
DWORD len;
|
||||
LPWSTR fname = NULL;
|
||||
|
||||
if ( !EnumProcesses( processes, sizeof(processes), &needed ) ) {
|
||||
return true;
|
||||
}
|
||||
num = needed / sizeof(DWORD);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (processes[i] == 0) continue;
|
||||
h = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, processes[i] );
|
||||
if (h != NULL) {
|
||||
len = GetProcessImageFileNameW(h, name, 4*MAX_PATH);
|
||||
CloseHandle(h);
|
||||
if (len != 0) {
|
||||
name[len] = 0;
|
||||
fname = PathFindFileName(name);
|
||||
if (wcscmp(fname, L"calibre.exe") == 0) {
|
||||
show_error(L"Calibre appears to be running on your computer. Please quit it before trying to install Calibre Portable.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void launch_calibre() {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory( &pi, sizeof(pi) );
|
||||
|
||||
|
||||
if (CreateProcess(_wcsdup(L"calibre-portable.exe"), NULL,
|
||||
NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_PROCESS_GROUP,
|
||||
NULL, NULL, &si, &pi)
|
||||
== 0) {
|
||||
show_last_error(L"Failed to launch calibre portable");
|
||||
}
|
||||
|
||||
// Close process and thread handles.
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
|
||||
}
|
||||
|
||||
void makedirs(LPWSTR path) {
|
||||
WCHAR *p = path;
|
||||
while (*p) {
|
||||
if ((*p == L'\\' || *p == L'/') && p != path && *(p-1) != L':') {
|
||||
*p = 0;
|
||||
CreateDirectory(path, NULL);
|
||||
*p = L'\\';
|
||||
}
|
||||
p++;
|
||||
}
|
||||
CreateDirectory(path, NULL);
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
||||
{
|
||||
(void)hPrevInstance; (void)pCmdLine; (void)nCmdShow;
|
||||
LPVOID cdata = NULL;
|
||||
DWORD csz = 0;
|
||||
int ret = 1, argc;
|
||||
HRESULT hr;
|
||||
LPWSTR tgt = NULL, dest = NULL, *argv, unpack_dir = NULL;
|
||||
BOOL existing = false, launch = false, automated = false;
|
||||
WCHAR buf[4*MAX_PATH] = {0}, mb_msg[4*MAX_PATH] = {0}, fdest[4*MAX_PATH] = {0};
|
||||
|
||||
if (!load_data(&cdata, &csz)) return ret;
|
||||
|
||||
hr = CoInitialize(NULL);
|
||||
if (FAILED(hr)) { show_error(L"Failed to initialize COM"); return ret; }
|
||||
|
||||
// Get the target directory for installation
|
||||
argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||
if (argv == NULL) { show_last_error(L"Failed to get command line"); return ret; }
|
||||
if (argc > 1) {
|
||||
tgt = argv[1];
|
||||
automated = true;
|
||||
if (!directory_exists(tgt)) {
|
||||
if (GetFullPathName(tgt, MAX_PATH*4, fdest, NULL) == 0) {
|
||||
show_last_error(L"Failed to resolve target folder");
|
||||
goto end;
|
||||
}
|
||||
makedirs(fdest);
|
||||
}
|
||||
|
||||
} else {
|
||||
tgt = get_directory_from_user();
|
||||
if (tgt == NULL) goto end;
|
||||
}
|
||||
|
||||
if (!directory_exists(tgt)) {
|
||||
show_detailed_error(L"The specified directory does not exist: ",
|
||||
tgt, 1);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Ensure the path to Calibre Portable is not too long
|
||||
do {
|
||||
if (!find_portable_dir(tgt, &dest, &existing)) goto end;
|
||||
|
||||
if (GetFullPathName(dest, MAX_PATH*4, fdest, NULL) == 0) {
|
||||
show_last_error(L"Failed to resolve target folder");
|
||||
goto end;
|
||||
}
|
||||
free(dest); dest = NULL;
|
||||
|
||||
if (wcslen(fdest) > 58) {
|
||||
_snwprintf_s(buf, 4*MAX_PATH, _TRUNCATE,
|
||||
L"Path to Calibre Portable (%s) too long. Must be less than 59 characters.", fdest);
|
||||
if (!existing) RemoveDirectory(fdest);
|
||||
show_error(buf);
|
||||
tgt = get_directory_from_user();
|
||||
if (tgt == NULL) goto end;
|
||||
}
|
||||
} while (wcslen(fdest) > 58);
|
||||
|
||||
// Confirm the user wants to upgrade
|
||||
if (existing && !automated) {
|
||||
_snwprintf_s(mb_msg, 4*MAX_PATH, _TRUNCATE,
|
||||
L"An existing install of Calibre Portable was found at %s. Do you want to upgrade it?",
|
||||
fdest);
|
||||
if (MessageBox(NULL, mb_msg,
|
||||
L"Upgrade Calibre Portable?", MB_ICONEXCLAMATION | MB_YESNO | MB_TOPMOST) != IDYES)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
if (!ensure_not_running()) goto end;
|
||||
}
|
||||
|
||||
// Make a temp dir to unpack into
|
||||
if (!SetCurrentDirectoryW(fdest)) { show_detailed_error(L"Failed to change to unzip directory: ", fdest, 0); goto end; }
|
||||
|
||||
if ( (unpack_dir = make_unpack_dir()) == NULL ) goto end;
|
||||
if (!SetCurrentDirectoryW(unpack_dir)) { show_detailed_error(L"Failed to change to unpack directory: ", fdest, 0); goto end; }
|
||||
|
||||
// Extract files
|
||||
if (!extract(cdata, csz)) goto end;
|
||||
|
||||
// Move files from temp dir to the install dir
|
||||
if (!move_program()) goto end;
|
||||
|
||||
ret = 0;
|
||||
if (!automated) {
|
||||
_snwprintf_s(mb_msg, 4*MAX_PATH, _TRUNCATE,
|
||||
L"Calibre Portable successfully installed to %s. Launch calibre?",
|
||||
fdest);
|
||||
launch = MessageBox(NULL, mb_msg,
|
||||
L"Success", MB_ICONINFORMATION | MB_YESNO | MB_TOPMOST) == IDYES;
|
||||
}
|
||||
|
||||
end:
|
||||
if (unpack_dir != NULL) { SetCurrentDirectoryW(L".."); rmtree(unpack_dir); free(unpack_dir); }
|
||||
CoUninitialize();
|
||||
if (launch) launch_calibre();
|
||||
return ret;
|
||||
}
|
154
bypy/windows/portable.c
Normal file
@ -0,0 +1,154 @@
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
void show_error(LPCTSTR msg) {
|
||||
MessageBeep(MB_ICONERROR);
|
||||
MessageBox(NULL, msg, _T("Error"), MB_OK|MB_ICONERROR);
|
||||
}
|
||||
|
||||
void show_detailed_error(LPCTSTR preamble, LPCTSTR msg, int code) {
|
||||
LPTSTR buf;
|
||||
buf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*
|
||||
(_tcslen(msg) + _tcslen(preamble) + 80));
|
||||
|
||||
_sntprintf_s(buf,
|
||||
LocalSize(buf) / sizeof(TCHAR), _TRUNCATE,
|
||||
_T("%s\r\n %s (Error Code: %d)\r\n"),
|
||||
preamble, msg, code);
|
||||
|
||||
show_error(buf);
|
||||
LocalFree(buf);
|
||||
}
|
||||
|
||||
void show_last_error_crt(LPCTSTR preamble) {
|
||||
TCHAR buf[BUFSIZE];
|
||||
int err = 0;
|
||||
|
||||
_get_errno(&err);
|
||||
_tcserror_s(buf, BUFSIZE, err);
|
||||
show_detailed_error(preamble, buf, err);
|
||||
}
|
||||
|
||||
void show_last_error(LPCTSTR preamble) {
|
||||
TCHAR *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&msg,
|
||||
0, NULL );
|
||||
|
||||
show_detailed_error(preamble, msg, (int)dw);
|
||||
}
|
||||
|
||||
|
||||
LPTSTR get_app_dir() {
|
||||
LPTSTR buf, buf2, buf3;
|
||||
DWORD sz;
|
||||
TCHAR drive[4] = _T("\0\0\0");
|
||||
errno_t err;
|
||||
|
||||
buf = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
|
||||
buf2 = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
|
||||
buf3 = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
|
||||
|
||||
sz = GetModuleFileName(NULL, buf, BUFSIZE);
|
||||
|
||||
if (sz == 0 || sz > BUFSIZE-1) {
|
||||
show_error(_T("Failed to get path to calibre-portable.exe"));
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
err = _tsplitpath_s(buf, drive, 4, buf2, BUFSIZE, NULL, 0, NULL, 0);
|
||||
|
||||
if (err != 0) {
|
||||
show_last_error_crt(_T("Failed to split path to calibre-portable.exe"));
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
_sntprintf_s(buf3, BUFSIZE-1, _TRUNCATE, _T("%s%s"), drive, buf2);
|
||||
free(buf); free(buf2);
|
||||
return buf3;
|
||||
}
|
||||
|
||||
void launch_calibre(LPCTSTR exe, LPCTSTR config_dir) {
|
||||
DWORD dwFlags=0;
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
BOOL fSuccess;
|
||||
|
||||
if (! SetEnvironmentVariable(_T("CALIBRE_CONFIG_DIRECTORY"), config_dir)) {
|
||||
show_last_error(_T("Failed to set environment variables"));
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
if (! SetEnvironmentVariable(_T("CALIBRE_PORTABLE_BUILD"), exe)) {
|
||||
show_last_error(_T("Failed to set environment variables"));
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
dwFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_PROCESS_GROUP;
|
||||
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory( &pi, sizeof(pi) );
|
||||
|
||||
fSuccess = CreateProcess(exe, NULL,
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // Set handle inheritance to FALSE
|
||||
dwFlags, // Creation flags http://msdn.microsoft.com/en-us/library/ms684863(v=vs.85).aspx
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&si, // Pointer to STARTUPINFO structure
|
||||
&pi // Pointer to PROCESS_INFORMATION structure
|
||||
);
|
||||
|
||||
if (fSuccess == 0) {
|
||||
show_last_error(_T("Failed to launch the calibre program"));
|
||||
}
|
||||
|
||||
// Close process and thread handles.
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
|
||||
}
|
||||
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
||||
{
|
||||
LPTSTR app_dir, config_dir, exe;
|
||||
|
||||
app_dir = get_app_dir();
|
||||
config_dir = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
|
||||
exe = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
|
||||
|
||||
_sntprintf_s(config_dir, BUFSIZE, _TRUNCATE, _T("%sCalibre Settings"), app_dir);
|
||||
_sntprintf_s(exe, BUFSIZE, _TRUNCATE, _T("%sCalibre\\calibre.exe"), app_dir);
|
||||
|
||||
launch_calibre(exe, config_dir);
|
||||
|
||||
free(app_dir); free(config_dir); free(exe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
114
bypy/windows/site.py
Normal file
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import imp
|
||||
|
||||
|
||||
class PydImporter(object):
|
||||
|
||||
__slots__ = ('items', 'description')
|
||||
|
||||
def __init__(self):
|
||||
self.items = None
|
||||
self.description = ('.pyd', 'rb', imp.C_EXTENSION)
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
if self.items is None:
|
||||
dlls_dir = os.path.join(sys.app_dir, 'app', 'bin')
|
||||
items = self.items = {}
|
||||
for x in os.listdir(dlls_dir):
|
||||
lx = x.lower()
|
||||
if lx.endswith(b'.pyd'):
|
||||
items[lx[:-4]] = os.path.abspath(os.path.join(dlls_dir, x))
|
||||
return self if fullname.lower() in self.items else None
|
||||
|
||||
def load_module(self, fullname):
|
||||
m = sys.modules.get(fullname)
|
||||
if m is not None:
|
||||
return m
|
||||
try:
|
||||
path = self.items[fullname.lower()]
|
||||
except KeyError:
|
||||
raise ImportError(
|
||||
'The native code module %s seems to have disappeared from self.items'
|
||||
% fullname
|
||||
)
|
||||
package, name = fullname.rpartition(b'.')[::2]
|
||||
m = imp.load_module(
|
||||
fullname, None, path, self.description
|
||||
) # This inserts the module into sys.modules itself
|
||||
m.__loader__ = self
|
||||
m.__package__ = package or None
|
||||
return m
|
||||
|
||||
|
||||
def abs__file__():
|
||||
"""Set all module __file__ attribute to an absolute path"""
|
||||
for m in sys.modules.values():
|
||||
if hasattr(m, '__loader__'):
|
||||
continue # don't mess with a PEP 302-supplied __file__
|
||||
try:
|
||||
m.__file__ = os.path.abspath(m.__file__)
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
|
||||
def aliasmbcs():
|
||||
import locale, codecs
|
||||
enc = locale.getdefaultlocale()[1]
|
||||
if enc.startswith('cp'): # "cp***" ?
|
||||
try:
|
||||
codecs.lookup(enc)
|
||||
except LookupError:
|
||||
import encodings
|
||||
encodings._cache[enc] = encodings._unknown
|
||||
encodings.aliases.aliases[enc] = 'mbcs'
|
||||
|
||||
|
||||
def add_calibre_vars():
|
||||
sys.new_app_layout = 1
|
||||
sys.resources_location = os.path.join(sys.app_dir, 'app', 'resources')
|
||||
sys.extensions_location = os.path.join(sys.app_dir, 'app', 'bin')
|
||||
|
||||
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
||||
if dv and os.path.exists(dv):
|
||||
sys.path.insert(0, os.path.abspath(dv))
|
||||
|
||||
|
||||
def run_entry_point():
|
||||
bname, mod, func = sys.calibre_basename, sys.calibre_module, sys.calibre_function
|
||||
sys.argv[0] = bname + '.exe'
|
||||
pmod = __import__(mod, fromlist=[1], level=0)
|
||||
return getattr(pmod, func)()
|
||||
|
||||
|
||||
def main():
|
||||
sys.frozen = 'windows_exe'
|
||||
sys.setdefaultencoding('utf-8')
|
||||
aliasmbcs()
|
||||
|
||||
sys.meta_path.insert(0, PydImporter())
|
||||
sys.path_importer_cache.clear()
|
||||
|
||||
import linecache
|
||||
|
||||
def fake_getline(filename, lineno, module_globals=None):
|
||||
return ''
|
||||
|
||||
linecache.orig_getline = linecache.getline
|
||||
linecache.getline = fake_getline
|
||||
|
||||
abs__file__()
|
||||
|
||||
add_calibre_vars()
|
||||
|
||||
# Needed to bypass meaningless check in pywintypes.py
|
||||
sys.path.append(os.path.join(sys.app_dir, 'app', 'bin'))
|
||||
|
||||
return run_entry_point()
|
42
bypy/windows/template.rc
Normal file
@ -0,0 +1,42 @@
|
||||
#include <windows.h>
|
||||
|
||||
#define VER_FILEVERSION {file_version}
|
||||
#define VER_FILEVERSION_STR "{file_version_str}"
|
||||
|
||||
#define VER_PRODUCTVERSION {product_version}
|
||||
#define VER_PRODUCTVERSION_STR "{product_version_str}"
|
||||
|
||||
#define VER_DEBUG 0
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS VER_DEBUG
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_{file_type}
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "calibre-ebook.com"
|
||||
VALUE "FileDescription", "{file_description}"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "{internal_name}"
|
||||
VALUE "LegalCopyright", "{legal_copyright}"
|
||||
VALUE "LegalTrademarks", "{legal_trademarks}"
|
||||
VALUE "OriginalFilename", "{original_filename}"
|
||||
VALUE "ProductName", "{product_name}"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
1 ICON "{icon}"
|
409
bypy/windows/util.c
Normal file
@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright 2009 Kovid Goyal
|
||||
*/
|
||||
|
||||
#define UNICODE
|
||||
|
||||
#define _WIN32_WINNT 0x0502
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <Shellapi.h>
|
||||
#include <delayimp.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define arraysz(x) (sizeof((x))/sizeof((x)[0]))
|
||||
|
||||
static int GUI_APP = 0;
|
||||
static char python_dll[] = PYDLL;
|
||||
|
||||
void set_gui_app(int yes) { GUI_APP = yes; }
|
||||
|
||||
int calibre_show_python_error(const wchar_t *preamble, int code);
|
||||
|
||||
static int _show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
|
||||
static wchar_t buf[4096];
|
||||
static char utf8_buf[4096] = {0};
|
||||
int n = WideCharToMultiByte(CP_UTF8, 0, preamble, -1, utf8_buf, sizeof(utf8_buf) - 1, NULL, NULL);
|
||||
if (n > 0) fprintf(stderr, "%s\r\n ", utf8_buf);
|
||||
n = WideCharToMultiByte(CP_UTF8, 0, msg, -1, utf8_buf, sizeof(utf8_buf) - 1, NULL, NULL);
|
||||
if (n > 0) fprintf(stderr, "%s (Error Code: %d)\r\n ", utf8_buf, code);
|
||||
fflush(stderr);
|
||||
|
||||
if (GUI_APP) {
|
||||
_snwprintf_s(buf, arraysz(buf), _TRUNCATE, L"%ls\r\n %ls (Error Code: %d)\r\n", preamble, msg, code);
|
||||
MessageBeep(MB_ICONERROR);
|
||||
MessageBox(NULL, buf, NULL, MB_OK|MB_ICONERROR);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int show_last_error_crt(wchar_t *preamble) {
|
||||
wchar_t buf[1000];
|
||||
int err = 0;
|
||||
|
||||
_get_errno(&err);
|
||||
_wcserror_s(buf, 1000, err);
|
||||
return _show_error(preamble, buf, err);
|
||||
}
|
||||
|
||||
int show_last_error(wchar_t *preamble) {
|
||||
wchar_t *msg = NULL;
|
||||
DWORD dw = GetLastError();
|
||||
int ret;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR)&msg,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
ret = _show_error(preamble, msg, (int)dw);
|
||||
if (msg != NULL) LocalFree(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char app_dir[MAX_PATH] = {0};
|
||||
static wchar_t dll_dir[MAX_PATH] = {0};
|
||||
static wchar_t qt_prefix_dir[MAX_PATH] = {0};
|
||||
static char program_name[MAX_PATH] = {0};
|
||||
static wchar_t w_program_name[MAX_PATH] = {0};
|
||||
static wchar_t w_app_dir[MAX_PATH] = {0};
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
static wchar_t python_path[MAX_PATH] = {0};
|
||||
#else
|
||||
static char python_path[MAX_PATH] = {0};
|
||||
#endif
|
||||
|
||||
static void
|
||||
get_app_dir(void) {
|
||||
char drive[4] = "\0\0\0";
|
||||
DWORD sz; errno_t err;
|
||||
char buf[MAX_PATH] = {0};
|
||||
|
||||
sz = GetModuleFileNameA(NULL, program_name, MAX_PATH);
|
||||
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
||||
err = _splitpath_s(program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0);
|
||||
if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory"));
|
||||
_snprintf_s(app_dir, MAX_PATH, _TRUNCATE, "%s%s", drive, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
get_app_dirw(void) {
|
||||
wchar_t buf[MAX_PATH] = {0};
|
||||
wchar_t drive[4] = L"\0\0\0";
|
||||
DWORD sz; errno_t err;
|
||||
|
||||
sz = GetModuleFileNameW(NULL, w_program_name, MAX_PATH);
|
||||
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
||||
err = _wsplitpath_s(w_program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0);
|
||||
if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory"));
|
||||
_snwprintf_s(w_app_dir, MAX_PATH, _TRUNCATE, L"%ls%ls", drive, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
get_install_locations(void) {
|
||||
get_app_dir();
|
||||
get_app_dirw();
|
||||
_snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%ls\\app", w_app_dir);
|
||||
_wputenv_s(L"CALIBRE_QT_PREFIX", qt_prefix_dir);
|
||||
_snwprintf_s(dll_dir, MAX_PATH-1, _TRUNCATE, L"%ls\\app\\bin", w_app_dir);
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
_snwprintf_s(python_path, MAX_PATH-1, _TRUNCATE, L"%ls\\app\\pylib.zip", w_app_dir);
|
||||
#else
|
||||
_snprintf_s(python_path, MAX_PATH-1, _TRUNCATE, "%s\\app\\pylib.zip", app_dir);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
load_python_dll() {
|
||||
get_install_locations();
|
||||
if (FAILED(__HrLoadAllImportsForDll(python_dll)))
|
||||
ExitProcess(_show_error(L"Failed to delay load the python dll", L"", 1));
|
||||
}
|
||||
|
||||
const static wchar_t out_of_memory[] = L"Out of memory";
|
||||
|
||||
static void
|
||||
setup_stream(const char *name, const char *errors, UINT cp) {
|
||||
PyObject *stream;
|
||||
char buf[128] = {0};
|
||||
|
||||
if (cp == CP_UTF8) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-8");
|
||||
else if (cp == CP_UTF7) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-7");
|
||||
else _snprintf_s(buf, 100, _TRUNCATE, "cp%d", cp);
|
||||
|
||||
stream = PySys_GetObject((char*)name);
|
||||
|
||||
if (!PyFile_SetEncodingAndErrors(stream, buf, (char*)errors))
|
||||
ExitProcess(calibre_show_python_error(L"Failed to set stream encoding", 1));
|
||||
}
|
||||
|
||||
UINT
|
||||
setup_streams() {
|
||||
UINT code_page = GetConsoleOutputCP();
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
_putenv_s("PYTHONIOENCODING", "UTF-8");
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
_setmode(_fileno(stderr), _O_BINARY);
|
||||
if (!GUI_APP) { // Remove buffering
|
||||
setvbuf(stdin, NULL, _IONBF, 2);
|
||||
setvbuf(stdout, NULL, _IONBF, 2);
|
||||
setvbuf(stderr, NULL, _IONBF, 2);
|
||||
}
|
||||
|
||||
//printf("input cp: %d output cp: %d\r\n", GetConsoleCP(), GetConsoleOutputCP());
|
||||
|
||||
setup_stream("stdin", "strict", GetConsoleCP());
|
||||
setup_stream("stdout", "strict", CP_UTF8);
|
||||
setup_stream("stderr", "strict", CP_UTF8);
|
||||
return code_page;
|
||||
}
|
||||
|
||||
UINT
|
||||
initialize_interpreter(const char *basename, const char *module, const char *function) {
|
||||
HMODULE dll;
|
||||
int *flag, i, argc;
|
||||
wchar_t **wargv;
|
||||
PyObject *argv, *v;
|
||||
char *dummy_argv[1] = {""};
|
||||
|
||||
dll = GetModuleHandleA(python_dll);
|
||||
if (!dll) ExitProcess(show_last_error(L"Failed to get python dll handle"));
|
||||
flag = (int*)GetProcAddress(dll, "Py_OptimizeFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get optimize flag", L"", 1));
|
||||
*flag = 2;
|
||||
flag = (int*)GetProcAddress(dll, "Py_NoSiteFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get no_site flag", L"", 1));
|
||||
*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_DontWriteBytecodeFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get no_bytecode flag", L"", 1));
|
||||
*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_IgnoreEnvironmentFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get ignore_environment flag", L"", 1));
|
||||
*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_NoUserSiteDirectory");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get user_site flag", L"", 1));
|
||||
*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_HashRandomizationFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get hash randomization flag", L"", 1));
|
||||
*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_VerboseFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get verbose flag", L"", 1));
|
||||
//*flag = 1;
|
||||
flag = (int*)GetProcAddress(dll, "Py_DebugFlag");
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get debug flag", L"", 1));
|
||||
//*flag = 1;
|
||||
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
Py_SetProgramName(w_program_name);
|
||||
Py_SetPythonHome(w_app_dir);
|
||||
#else
|
||||
Py_SetProgramName(program_name);
|
||||
Py_SetPythonHome(app_dir);
|
||||
#endif
|
||||
|
||||
//printf("Path before Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
Py_Initialize();
|
||||
UINT code_page = setup_streams();
|
||||
|
||||
PySys_SetArgv(1, dummy_argv);
|
||||
//printf("Path after Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
PySys_SetPath(python_path);
|
||||
//printf("Path set by me: %s\r\n\n", path);
|
||||
PySys_SetObject("gui_app", PyBool_FromLong((long)GUI_APP));
|
||||
PySys_SetObject("app_dir", PyUnicode_FromWideChar(w_app_dir, wcslen(w_app_dir)));
|
||||
|
||||
PySys_SetObject("calibre_basename", PyBytes_FromString(basename));
|
||||
PySys_SetObject("calibre_module", PyBytes_FromString(module));
|
||||
PySys_SetObject("calibre_function", PyBytes_FromString(function));
|
||||
|
||||
wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
if (wargv == NULL) ExitProcess(show_last_error(L"Failed to get command line"));
|
||||
argv = PyList_New(argc);
|
||||
if (argv == NULL) ExitProcess(_show_error(out_of_memory, L"", 1));
|
||||
for (i = 0; i < argc; i++) {
|
||||
v = PyUnicode_FromWideChar(wargv[i], wcslen(wargv[i]));
|
||||
if (v == NULL) ExitProcess(_show_error(out_of_memory, L"", 1));
|
||||
PyList_SetItem(argv, i, v);
|
||||
}
|
||||
PySys_SetObject("argv", argv);
|
||||
return code_page;
|
||||
}
|
||||
|
||||
|
||||
static const wchar_t*
|
||||
pyobject_to_wchar(PyObject *o) {
|
||||
PyObject *t = NULL;
|
||||
size_t s;
|
||||
static wchar_t ans[4096];
|
||||
|
||||
if (!PyUnicode_Check(o)) {
|
||||
t = PyUnicode_FromEncodedObject(o, NULL, "replace");
|
||||
if (t == NULL) return NULL;
|
||||
}
|
||||
|
||||
s = PyUnicode_AsWideChar((PyUnicodeObject*)(t ? t : o), ans, arraysz(ans)-1);
|
||||
Py_XDECREF(t);
|
||||
if (s >= 0) ans[s] = 0;
|
||||
else ans[s] = 0;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
int pyobject_to_int(PyObject *res) {
|
||||
int ret; PyObject *tmp;
|
||||
tmp = PyNumber_Int(res);
|
||||
if (tmp == NULL) ret = (PyObject_IsTrue(res)) ? 1 : 0;
|
||||
else ret = (int)PyInt_AS_LONG(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int handle_sysexit(PyObject *e) {
|
||||
PyObject *code;
|
||||
|
||||
code = PyObject_GetAttrString(e, "code");
|
||||
if (!code) return 0;
|
||||
if (!PyInt_Check(code)) {
|
||||
PyObject_Print(code, stderr, Py_PRINT_RAW);
|
||||
fflush(stderr);
|
||||
}
|
||||
return pyobject_to_int(code);
|
||||
}
|
||||
|
||||
int calibre_show_python_error(const wchar_t *preamble, int code) {
|
||||
PyObject *exc, *val, *tb, *str, **system_exit;
|
||||
HMODULE dll;
|
||||
int ret, issysexit = 0; const wchar_t *i;
|
||||
|
||||
if (!PyErr_Occurred()) return code;
|
||||
dll = GetModuleHandleA(python_dll);
|
||||
if (!dll) ExitProcess(show_last_error(L"Failed to get python dll handle"));
|
||||
system_exit = (PyObject**)GetProcAddress(dll, "PyExc_SystemExit");
|
||||
issysexit = PyErr_ExceptionMatches(*system_exit);
|
||||
|
||||
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
|
||||
if (exc != NULL) {
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
|
||||
if (issysexit) {
|
||||
return (val) ? handle_sysexit(val) : 0;
|
||||
}
|
||||
if (val != NULL) {
|
||||
str = PyObject_Unicode(val);
|
||||
if (str == NULL) {
|
||||
PyErr_Clear();
|
||||
str = PyObject_Str(val);
|
||||
}
|
||||
i = pyobject_to_wchar(str);
|
||||
ret = _show_error(preamble, (i==NULL)?out_of_memory:i, code);
|
||||
if (tb != NULL) {
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyErr_Print();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return _show_error(preamble, L"", code);
|
||||
}
|
||||
|
||||
void redirect_out_stream(FILE *stream) {
|
||||
FILE *f = NULL;
|
||||
errno_t err;
|
||||
|
||||
err = freopen_s(&f, "NUL", "wt", stream);
|
||||
if (err != 0) {
|
||||
ExitProcess(show_last_error_crt(L"Failed to redirect stdout/stderr to NUL. This indicates a corrupted Windows install.\r\n You should contact Microsoft for assistance and/or follow the steps described here:\r\n http://bytes.com/topic/net/answers/264804-compile-error-null-device-missing"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
null_invalid_parameter_handler(
|
||||
const wchar_t * expression,
|
||||
const wchar_t * function,
|
||||
const wchar_t * file,
|
||||
unsigned int line,
|
||||
uintptr_t pReserved
|
||||
) {
|
||||
// The python runtime expects various system calls with invalid parameters
|
||||
// to return errors instead of aborting the program. So get the windows CRT
|
||||
// to do that.
|
||||
}
|
||||
__declspec(dllexport) int __cdecl
|
||||
simple_print(const wchar_t *msg) {
|
||||
int n = wprintf(L"%ls", msg); fflush(stdout);
|
||||
return n;
|
||||
}
|
||||
|
||||
__declspec(dllexport) int __cdecl
|
||||
execute_python_entrypoint(const char *basename, const char *module, const char *function, int is_gui_app) {
|
||||
PyObject *site, *main, *res;
|
||||
int ret = 0;
|
||||
// Prevent Windows' idiotic error dialog popups when various win32 api functions fail
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
if (is_gui_app) {
|
||||
// Redirect stdout and stderr to NUL so that python does not fail writing to them
|
||||
redirect_out_stream(stdout);
|
||||
redirect_out_stream(stderr);
|
||||
}
|
||||
set_gui_app(is_gui_app);
|
||||
// Disable the invalid parameter handler
|
||||
_set_invalid_parameter_handler(null_invalid_parameter_handler);
|
||||
|
||||
load_python_dll();
|
||||
UINT code_page = initialize_interpreter(basename, module, function);
|
||||
|
||||
site = PyImport_ImportModule("site");
|
||||
|
||||
if (site == NULL)
|
||||
ret = calibre_show_python_error(L"Failed to import site module", 1);
|
||||
else {
|
||||
Py_INCREF(site);
|
||||
|
||||
main = PyObject_GetAttrString(site, "main");
|
||||
if (main == NULL || !PyCallable_Check(main))
|
||||
ret = calibre_show_python_error(L"site module has no main function", 1);
|
||||
else {
|
||||
Py_INCREF(main);
|
||||
res = PyObject_CallObject(main, NULL);
|
||||
|
||||
if (res == NULL)
|
||||
ret = calibre_show_python_error(L"Python function terminated unexpectedly", 1);
|
||||
else {
|
||||
#if PY_VERSION_MAJOR < 3
|
||||
if (PyInt_Check(res)) {
|
||||
ret = PyInt_AS_LONG(res);
|
||||
}
|
||||
#else
|
||||
if (PyLong_Check(res)) {
|
||||
ret = PyLong_AsLong(res);
|
||||
}
|
||||
#endif
|
||||
Py_DECREF(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
Py_Finalize();
|
||||
if (code_page != CP_UTF8) SetConsoleOutputCP(code_page);
|
||||
/* printf("111111111111 returning: %d\r\n", ret); */
|
||||
|
||||
return ret;
|
||||
}
|
206
bypy/windows/wix-template.xml
Normal file
@ -0,0 +1,206 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
|
||||
>
|
||||
|
||||
<Product Name='{app}{x64}' Id='*' UpgradeCode='{upgrade_code}' Language='1033' Codepage='1252' Version='{version}' Manufacturer='Kovid Goyal'>
|
||||
|
||||
<Package Id='*' Keywords='Installer' Description="{app} Installer"
|
||||
Comments='{app} is a registered trademark of Kovid Goyal' Manufacturer='Kovid Goyal'
|
||||
InstallerVersion='300' Languages='1033' Compressed='yes'
|
||||
SummaryCodepage='1252' />
|
||||
|
||||
<!-- Disable creation of system restore points on calibre installs. Speeds
|
||||
up the install. We dont need system restore since we dont install any
|
||||
system DLLs/components anyway (apart from start menu entries) -->
|
||||
<Property Id="MSIFASTINSTALL" Value="3" />
|
||||
|
||||
<Media Id="1" Cabinet="{app}.cab" CompressionLevel="{compression}" EmbedCab="yes" />
|
||||
<!-- The following line ensures that DLLs are replaced even if
|
||||
their version is the same as before or they dont have versions.
|
||||
Microsoft's brain dead installer will otherwise use file dates to
|
||||
determine whether to install a file or not. Simply not robust. And
|
||||
since we dont install any system files whatsoever, we can never replace
|
||||
a system file with an older version. This way the calibre install
|
||||
should always result in a consistent set of files being present in the
|
||||
installation folder, though of course, with Microsoft there are no
|
||||
guarantees of anything. -->
|
||||
<Property Id='REINSTALLMODE' Value='amus'/>
|
||||
|
||||
<Upgrade Id="{upgrade_code}">
|
||||
<UpgradeVersion Maximum="{version}"
|
||||
IncludeMaximum="yes"
|
||||
OnlyDetect="no"
|
||||
Language="1033"
|
||||
MigrateFeatures="yes"
|
||||
Property="OLDPRODUCTFOUND"/>
|
||||
<UpgradeVersion Minimum="{version}"
|
||||
IncludeMinimum="no"
|
||||
OnlyDetect="yes"
|
||||
Language="1033"
|
||||
Property="NEWPRODUCTFOUND"/>
|
||||
</Upgrade>
|
||||
<CustomAction Id="PreventDowngrading" Error="Newer version of {app} already installed. If you want to downgrade you must uninstall {app} first."/>
|
||||
|
||||
<Property Id="APPLICATIONFOLDER">
|
||||
<RegistrySearch Id='calibreInstDir' Type='raw'
|
||||
Root='HKLM' Key="Software\{app}{x64}\Installer" Name="InstallPath" />
|
||||
</Property>
|
||||
|
||||
<Directory Id='TARGETDIR' Name='SourceDir'>
|
||||
<Directory Id='{ProgramFilesFolder}' Name='PFiles'>
|
||||
<!-- The name must be calibre on 32 bit to ensure
|
||||
that the component guids dont change compared to previous msis.
|
||||
However, on 64 bit it must be Calibre2 otherwise by default it
|
||||
will install to C:\Program Files\calibre -->
|
||||
<Directory Id='APPLICATIONFOLDER' Name="{appfolder}" />
|
||||
</Directory>
|
||||
<Directory Id="ProgramMenuFolder">
|
||||
<Directory Id="ApplicationProgramsFolder" Name="{app}{x64} - E-book Management"/>
|
||||
</Directory>
|
||||
<Directory Id="DesktopFolder" Name="Desktop"/>
|
||||
</Directory>
|
||||
|
||||
<Icon Id="main_icon" SourceFile="{main_icon}"/>
|
||||
<!-- <Icon Id="viewer_icon" SourceFile="{viewer_icon}"/> -->
|
||||
<!-- <Icon Id="editor_icon" SourceFile="{editor_icon}"/> -->
|
||||
|
||||
<DirectoryRef Id="APPLICATIONFOLDER">
|
||||
{app_components}
|
||||
<Component Id="AddToPath" Guid="*">
|
||||
<Environment Id='UpdatePath' Name='PATH' Action='set' System='yes' Part='last' Value='[APPLICATIONFOLDER]' />
|
||||
<RegistryValue Root="HKCU" Key="Software\Microsoft\{app}{x64}" Name="system_path_updated" Type="integer" Value="1" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Id="RememberInstallDir" Guid="*">
|
||||
<RegistryValue Root="HKLM" Key="Software\{app}{x64}\Installer" Name="InstallPath" Type="string" Value="[APPLICATIONFOLDER]" KeyPath="yes"/>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="ApplicationProgramsFolder">
|
||||
<Component Id="StartMenuShortcuts" Guid="*">
|
||||
<Shortcut Id="s1" Name="{app}{x64} - E-book management"
|
||||
Description="Manage your e-book collection and download news"
|
||||
Target="[#{exe_map[calibre]}]"
|
||||
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
|
||||
<Shortcut Id="s2" Name="E-book viewer{x64}"
|
||||
Description="Viewer for all the major e-book formats"
|
||||
Target="[#{exe_map[ebook-viewer]}]"
|
||||
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
|
||||
<Shortcut Id="s4" Name="Edit E-book{x64}"
|
||||
Description="Edit e-books"
|
||||
Target="[#{exe_map[ebook-edit]}]"
|
||||
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
|
||||
<Shortcut Id="s3" Name="LRF viewer{x64}"
|
||||
Description="Viewer for LRF format e-books"
|
||||
Target="[#{exe_map[lrfviewer]}]"
|
||||
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
|
||||
<util:InternetShortcut Id="OnlineDocumentationShortcut"
|
||||
Name="User Manual" Type="url"
|
||||
Target="https://manual.calibre-ebook.com"/>
|
||||
<util:InternetShortcut Id="GetInvolvedS"
|
||||
Name="Get Involved" Type="url"
|
||||
Target="https://calibre-ebook.com/get-involved"/>
|
||||
|
||||
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
|
||||
<RegistryValue Root="HKCU" Key="Software\Microsoft\{app}{x64}" Name="start_menu_shortcuts_installed" Type="integer" Value="1" KeyPath="yes"/>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="DesktopFolder">
|
||||
<Component Id="DesktopShortcut" Guid="*">
|
||||
<Shortcut Id="ds1" Name="{app}{x64} - E-book management"
|
||||
Description="Manage your e-book collection and download news"
|
||||
Target="[#{exe_map[calibre]}]"
|
||||
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
|
||||
<RegistryValue Root="HKCU" Key="Software\Microsoft\{app}{x64}" Name="desktop_shortcut_installed" Type="integer" Value="1" KeyPath="yes"/>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
|
||||
<Feature Id="Complete" Title="{app}" Display="expand" Level="1"
|
||||
ConfigurableDirectory="APPLICATIONFOLDER">
|
||||
|
||||
<Feature Id="MainApplication" Title="Program Files" Level="1"
|
||||
Description="All the files needed to run {app}" Absent="disallow">
|
||||
<ComponentRef Id="RememberInstallDir"/>
|
||||
</Feature>
|
||||
|
||||
<Feature Id="FSMS" Title="Start menu shortcuts" Level="1"
|
||||
Description="Program shortcuts installed in the Start Menu">
|
||||
<ComponentRef Id="StartMenuShortcuts"/>
|
||||
</Feature>
|
||||
|
||||
<Feature Id="DS" Title="Shortcut on desktop" Level="1"
|
||||
Description="Shortcut to {app} on your desktop">
|
||||
<ComponentRef Id="DesktopShortcut"/>
|
||||
</Feature>
|
||||
|
||||
<Feature Id="FAddToPath" Title="Add install directory to path" Level="1"
|
||||
Description="Add installation directory to PATH. Makes using command line tools easier">
|
||||
<ComponentRef Id="AddToPath"/>
|
||||
</Feature>
|
||||
</Feature>
|
||||
|
||||
<!-- Add icon to entry in Add/Remove programs -->
|
||||
<Property Id="ARPPRODUCTICON" Value="main_icon" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://calibre-ebook.com" />
|
||||
<Property Id='ARPHELPLINK' Value="https://calibre-ebook.com/help" />
|
||||
<Property Id='ARPURLUPDATEINFO' Value="https://calibre-ebook.com/download_windows" />
|
||||
<SetProperty Id="ARPINSTALLLOCATION" Value="[APPLICATIONFOLDER]" After="CostFinalize" />
|
||||
|
||||
<Condition
|
||||
Message="This application is only supported on {minverhuman}, or higher.">
|
||||
<![CDATA[Installed OR (VersionNT >= {minver})]]>
|
||||
</Condition>
|
||||
<!-- On 64 bit installers there is a bug in WiX that causes the
|
||||
WixSetDefaultPerMachineFolder action to incorrectly set
|
||||
APPLICATIONFOLDER to the x86 value, so we override it. See
|
||||
http://stackoverflow.com/questions/5479790/wix-how-to-override-c-program-files-x86-on-x64-machine-in-wixui-advanced-s
|
||||
-->
|
||||
<CustomAction
|
||||
Id="OverwriteWixSetDefaultPerMachineFolder"
|
||||
Property="WixPerMachineFolder"
|
||||
Value="[APPLICATIONFOLDER]"
|
||||
Execute="immediate"
|
||||
/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
|
||||
{fix_wix}
|
||||
<RemoveExistingProducts After="InstallFinalize" />
|
||||
</InstallExecuteSequence>
|
||||
<InstallUISequence>
|
||||
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
|
||||
{fix_wix}
|
||||
</InstallUISequence>
|
||||
|
||||
<UI>
|
||||
<UIRef Id="WixUI_Advanced" />
|
||||
<UIRef Id="WixUI_ErrorProgressText" />
|
||||
<Publish Dialog="ExitDialog"
|
||||
Control="Finish"
|
||||
Event="DoAction"
|
||||
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
|
||||
|
||||
</UI>
|
||||
|
||||
<!--
|
||||
Set default folder name and allow only per machine installs.
|
||||
For a per-machine installation, the default installation location
|
||||
will be [ProgramFilesFolder][ApplicationFolderName] and the user
|
||||
will be able to change it in the setup UI. This is no longer necessary
|
||||
(i.e. per user installs should work) but left this way as I
|
||||
dont want to deal with the complications
|
||||
-->
|
||||
<Property Id="ApplicationFolderName" Value="Calibre2" />
|
||||
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
|
||||
<Property Id="ALLUSERS" Value="1" />
|
||||
<WixVariable Id="WixUISupportPerUser" Value="0" />
|
||||
|
||||
<!-- Add option to launch calibre after install -->
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch {app}" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
|
||||
<Property Id="WixShellExecTarget" Value="[#{exe_map[calibre]}]" />
|
||||
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes"/>
|
||||
|
||||
</Product>
|
||||
</Wix>
|
139
bypy/windows/wix.py
Normal file
@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
from itertools import count
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from bypy.constants import is64bit
|
||||
from bypy.utils import run
|
||||
|
||||
WIXP = r'C:\Program Files (x86)\WiX Toolset v3.11'
|
||||
if is64bit:
|
||||
UPGRADE_CODE = '5DD881FF-756B-4097-9D82-8C0F11D521EA'
|
||||
else:
|
||||
UPGRADE_CODE = 'BEB2A80D-E902-4DAD-ADF9-8BD2DA42CFE1'
|
||||
MINVERHUMAN = 'Windows 7'
|
||||
calibre_constants = globals()['calibre_constants']
|
||||
|
||||
CANDLE = WIXP + r'\bin\candle.exe'
|
||||
LIGHT = WIXP + r'\bin\light.exe'
|
||||
j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename
|
||||
|
||||
|
||||
def create_installer(env):
|
||||
if os.path.exists(env.installer_dir):
|
||||
shutil.rmtree(env.installer_dir)
|
||||
os.makedirs(env.installer_dir)
|
||||
|
||||
with open(j(d(__file__), 'wix-template.xml'), 'rb') as f:
|
||||
template = f.read().decode('utf-8')
|
||||
|
||||
components, smap = get_components_from_files(env)
|
||||
wxs = template.format(
|
||||
app=calibre_constants['appname'],
|
||||
appfolder='Calibre2' if is64bit else 'Calibre',
|
||||
version=calibre_constants['version'],
|
||||
upgrade_code=UPGRADE_CODE,
|
||||
ProgramFilesFolder='ProgramFiles64Folder' if is64bit else 'ProgramFilesFolder',
|
||||
x64=' 64bit' if is64bit else '',
|
||||
minverhuman=MINVERHUMAN,
|
||||
minver='601',
|
||||
fix_wix='<Custom Action="OverwriteWixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />' if is64bit else '',
|
||||
compression='high',
|
||||
app_components=components,
|
||||
exe_map=smap,
|
||||
main_icon=j(env.src_root, 'icons', 'library.ico'),
|
||||
viewer_icon=j(env.src_root, 'icons', 'viewer.ico'),
|
||||
editor_icon=j(env.src_root, 'icons', 'ebook-edit.ico'),
|
||||
web_icon=j(env.src_root, 'icons', 'web.ico'),
|
||||
)
|
||||
with open(j(d(__file__), 'en-us.xml'), 'rb') as f:
|
||||
template = f.read().decode('utf-8')
|
||||
enus = template.format(app=calibre_constants['appname'])
|
||||
|
||||
enusf = j(env.installer_dir, 'en-us.wxl')
|
||||
wxsf = j(env.installer_dir, calibre_constants['appname'] + '.wxs')
|
||||
with open(wxsf, 'wb') as f:
|
||||
f.write(wxs.encode('utf-8'))
|
||||
with open(enusf, 'wb') as f:
|
||||
f.write(enus.encode('utf-8'))
|
||||
wixobj = j(env.installer_dir, calibre_constants['appname'] + '.wixobj')
|
||||
arch = 'x64' if is64bit else 'x86'
|
||||
cmd = [CANDLE, '-nologo', '-arch', arch, '-ext', 'WiXUtilExtension', '-o', wixobj, wxsf]
|
||||
run(*cmd)
|
||||
installer = j(env.dist, '%s%s-%s.msi' % (
|
||||
calibre_constants['appname'], ('-64bit' if is64bit else ''), calibre_constants['version']))
|
||||
license = j(env.src_root, 'LICENSE.rtf')
|
||||
banner = j(env.src_root, 'icons', 'wix-banner.bmp')
|
||||
dialog = j(env.src_root, 'icons', 'wix-dialog.bmp')
|
||||
cmd = [LIGHT, '-nologo', '-ext', 'WixUIExtension',
|
||||
'-cultures:en-us', '-loc', enusf, wixobj,
|
||||
'-ext', 'WixUtilExtension',
|
||||
'-o', installer,
|
||||
'-dWixUILicenseRtf=' + license,
|
||||
'-dWixUIBannerBmp=' + banner,
|
||||
'-dWixUIDialogBmp=' + dialog]
|
||||
cmd.extend([
|
||||
'-sice:ICE60', # No language in dlls warning
|
||||
'-sice:ICE61', # Allow upgrading with same version number
|
||||
'-sice:ICE40', # Re-install mode overriden
|
||||
'-sice:ICE69', # Shortcut components are part of a different feature than the files they point to
|
||||
])
|
||||
cmd.append('-sval') # Disable all checks since they fail when running under ssh
|
||||
run(*cmd)
|
||||
|
||||
|
||||
def get_components_from_files(env):
|
||||
|
||||
file_idc = count()
|
||||
file_id_map = {}
|
||||
|
||||
def process_dir(path):
|
||||
components = []
|
||||
for x in os.listdir(path):
|
||||
f = os.path.join(path, x)
|
||||
file_id_map[f] = fid = next(file_idc)
|
||||
|
||||
if os.path.isdir(f):
|
||||
components.append(
|
||||
'<Directory Id="file_%s" FileSource="%s" Name="%s">' %
|
||||
(file_id_map[f], f, x))
|
||||
c = process_dir(f)
|
||||
components.extend(c)
|
||||
components.append('</Directory>')
|
||||
else:
|
||||
checksum = 'Checksum="yes"' if x.endswith('.exe') else ''
|
||||
c = [
|
||||
('<Component Id="component_%s" Feature="MainApplication" '
|
||||
'Guid="*">') % (fid,),
|
||||
('<File Id="file_%s" Source="%s" Name="%s" ReadOnly="yes" '
|
||||
'KeyPath="yes" %s/>') %
|
||||
(fid, f, x, checksum),
|
||||
'</Component>'
|
||||
]
|
||||
if x.endswith('.exe') and not x.startswith('pdf'):
|
||||
# Add the executable to app paths so that users can
|
||||
# launch it from the run dialog even if it is not on
|
||||
# the path. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx
|
||||
c[-1:-1] = [
|
||||
('<RegistryValue Root="HKLM" '
|
||||
r'Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App '
|
||||
r'Paths\%s" Value="[#file_%d]" Type="string" />' % (x, fid)),
|
||||
('<RegistryValue Root="HKLM" '
|
||||
r'Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App '
|
||||
r'Paths\{0}" Name="Path" Value="[APPLICATIONFOLDER]" '
|
||||
'Type="string" />'.format(x)),
|
||||
]
|
||||
components.append('\n'.join(c))
|
||||
return components
|
||||
|
||||
components = process_dir(a(env.base))
|
||||
smap = {}
|
||||
for x in calibre_constants['basenames']['gui']:
|
||||
smap[x] = 'file_%d' % file_id_map[a(j(env.base, x + '.exe'))]
|
||||
|
||||
return '\t\t\t\t' + '\n\t\t\t\t'.join(components), smap
|
@ -61,12 +61,15 @@ content comments
|
||||
|
||||
asin The ISBN 10 for the paper book the pages correspond to
|
||||
pageMap Three value tuple. Looks like: "(N,N,N)"
|
||||
1) Number of bytes after header that starts the page numbering sequence
|
||||
2) unknown
|
||||
3) unknown
|
||||
1) 1 based page list entry number for the first page described by this tuple.
|
||||
2) Page number type, a: Indo-Arabic numeral, r: Roman numeral, c: character.
|
||||
3) Value of page number for the first page of this sequence.
|
||||
|
||||
The third value of the tuple is a decimal number if the type is "a" or "r" and
|
||||
a character string of page labels separated by "|" characters.
|
||||
|
||||
Example:
|
||||
{"asin":"1906694184","pageMap":"(4,a,1)"}
|
||||
{"asin":"1906694184","pageMap":"(4,a,1),(197,c,A-1|A-2|A-3)"}
|
||||
|
||||
|
||||
Page List
|
||||
@ -74,4 +77,9 @@ Page List
|
||||
|
||||
The page list is a sequence of offsets in the uncompressed HTML. Each
|
||||
value is the beginning of a new page. Each entry is a 4 byte big endian
|
||||
int. The list is ordered lowest to highest.
|
||||
int. The list is ordered lowest to highest.
|
||||
|
||||
For more information
|
||||
--------------------
|
||||
|
||||
MobileRead wiki https://wiki.mobileread.com/wiki/APNX
|
||||
|
@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
@ -17,7 +16,7 @@ sources = {'calibre':j(imgsrc, 'calibre.svg'), 'ebook-edit':j(imgsrc, 'tweak.svg
|
||||
if sys.argv[-1] == 'only-logo':
|
||||
sources = {'calibre':sources['calibre']}
|
||||
|
||||
for name, src in sources.iteritems():
|
||||
for name, src in sources.items():
|
||||
iconset = name + '.iconset'
|
||||
if os.path.exists(iconset):
|
||||
shutil.rmtree(iconset)
|
||||
@ -44,4 +43,3 @@ for name, src in sources.iteritems():
|
||||
subprocess.check_call(['optipng', '-o7', '-strip', 'all', name])
|
||||
finally:
|
||||
os.chdir('..')
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=utf-8
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
@ -17,7 +16,7 @@ sources = {'library':j(imgsrc, 'calibre.svg'), 'ebook-edit':j(imgsrc, 'tweak.svg
|
||||
if sys.argv[-1] == 'only-logo':
|
||||
sources = {'library':sources['library']}
|
||||
|
||||
for name, src in sources.iteritems():
|
||||
for name, src in sources.items():
|
||||
os.mkdir('ico_temp')
|
||||
try:
|
||||
names = []
|
||||
|
58
imgsrc/auto-scroll.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1792"
|
||||
height="1792"
|
||||
viewBox="0 0 1792 1792"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="auto-scroll.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.13169643"
|
||||
inkscape:cx="-1025.0847"
|
||||
inkscape:cy="896"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg4" />
|
||||
<path
|
||||
d="m 1395,864 q 0,13 -10,23 l -466,466 q -10,10 -23,10 -13,0 -23,-10 L 407,887 q -10,-10 -10,-23 0,-13 10,-23 l 50,-50 q 10,-10 23,-10 13,0 23,10 l 393,393 393,-393 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 z"
|
||||
id="path823"
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<path
|
||||
d="m 1395,480 q 0,13 -10,23 L 919,969 q -10,10 -23,10 -13,0 -23,-10 L 407,503 q -10,-10 -10,-23 0,-13 10,-23 l 50,-50 q 10,-10 23,-10 13,0 23,10 l 393,393 393,-393 q 10,-10 23,-10 13,0 23,10 l 50,50 q 10,10 10,23 z"
|
||||
id="path2"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
@ -15,19 +15,19 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="bookmark.svg">
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="bookmarks.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#6971cf;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#1c2057;stop-opacity:0.99215686"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -50,16 +50,16 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-20.56769"
|
||||
inkscape:cx="49.43231"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
48
imgsrc/close-for-dark-theme.svg
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="300px"
|
||||
width="300px"
|
||||
fill="#eeeeee"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enable-background="new 0 0 100 100"
|
||||
xml:space="preserve"
|
||||
id="svg4"
|
||||
sodipodi:docname="close-for-light-theme.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"><metadata
|
||||
id="metadata10"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs8" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.78666667"
|
||||
inkscape:cx="-171.61017"
|
||||
inkscape:cy="150"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg4" /><path
|
||||
d="m 29.082441,32.408474 0.675796,-0.664406 c 2.800483,-2.751801 7.338729,-2.751801 10.139212,0 l 8.831365,8.681779 8.83061,-8.682521 c 2.800483,-2.751801 7.341746,-2.751801 10.139212,0 l 0.675796,0.664407 c 2.800483,2.753284 2.800483,7.216525 0,9.969809 l -8.829856,8.682521 8.83061,8.681038 c 2.800484,2.752543 2.800484,7.215784 0,9.969068 l -0.675796,0.664407 c -2.797466,2.752542 -7.338729,2.752542 -10.139212,0 l -8.831364,-8.681038 -8.830611,8.681038 c -2.800483,2.752542 -7.338728,2.752542 -10.139211,0 l -0.675797,-0.664407 c -2.800483,-2.753284 -2.800483,-7.216525 0,-9.969068 l 8.829856,-8.681038 -8.83061,-8.681779 c -2.800483,-2.753284 -2.800483,-7.216526 0,-9.96981 z m 19.646373,55.727119 c -20.827509,0 -37.711865,-16.599788 -37.711865,-37.07553 0,-20.476483 16.884356,-37.077012 37.711865,-37.077012 20.827508,0 37.711864,16.600529 37.711864,37.077012 0,20.475742 -16.884356,37.07553 -37.711864,37.07553 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-width:0.74785435" /></svg>
|
After Width: | Height: | Size: 2.5 KiB |
48
imgsrc/close-for-light-theme.svg
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="300px"
|
||||
width="300px"
|
||||
fill="#000000"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 100 100"
|
||||
enable-background="new 0 0 100 100"
|
||||
xml:space="preserve"
|
||||
id="svg4"
|
||||
sodipodi:docname="close-for-light-theme.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"><metadata
|
||||
id="metadata10"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs8" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.78666667"
|
||||
inkscape:cx="-171.61017"
|
||||
inkscape:cy="150"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg4" /><path
|
||||
d="m 29.082441,32.408474 0.675796,-0.664406 c 2.800483,-2.751801 7.338729,-2.751801 10.139212,0 l 8.831365,8.681779 8.83061,-8.682521 c 2.800483,-2.751801 7.341746,-2.751801 10.139212,0 l 0.675796,0.664407 c 2.800483,2.753284 2.800483,7.216525 0,9.969809 l -8.829856,8.682521 8.83061,8.681038 c 2.800484,2.752543 2.800484,7.215784 0,9.969068 l -0.675796,0.664407 c -2.797466,2.752542 -7.338729,2.752542 -10.139212,0 l -8.831364,-8.681038 -8.830611,8.681038 c -2.800483,2.752542 -7.338728,2.752542 -10.139211,0 l -0.675797,-0.664407 c -2.800483,-2.753284 -2.800483,-7.216525 0,-9.969068 l 8.829856,-8.681038 -8.83061,-8.681779 c -2.800483,-2.753284 -2.800483,-7.216526 0,-9.96981 z m 19.646373,55.727119 c -20.827509,0 -37.711865,-16.599788 -37.711865,-37.07553 0,-20.476483 16.884356,-37.077012 37.711865,-37.077012 20.827508,0 37.711864,16.600529 37.711864,37.077012 0,20.475742 -16.884356,37.07553 -37.711864,37.07553 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-width:0.74785435" /></svg>
|
After Width: | Height: | Size: 2.5 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="code.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:zoom="5.6568542"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -89,6 +89,7 @@
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 41.265039,1017.4603 -3.314134,3.3141 q -0.662836,0.6629 -1.524529,0.6629 -0.861692,0 -1.524481,-0.6629 L 4.0141368,989.88668 Q 3.3513,989.22388 3.3513,988.3622 q 0,-0.86167 0.6628368,-1.52454 L 34.901895,955.94989 q 0.662789,-0.66273 1.524481,-0.66273 0.861693,0 1.524529,0.66273 l 3.314134,3.31417 q 0.662789,0.66281 0.662789,1.52455 0,0.86167 -0.662789,1.52448 l -26.049143,26.04911 26.049143,26.0491 q 0.662789,0.6628 0.662789,1.5245 0,0.8616 -0.662789,1.5245 z m 39.173095,-70.72369 -24.723471,85.57099 q -0.265123,0.8617 -1.02741,1.2926 -0.76224,0.4307 -1.557621,0.1656 l -4.109552,-1.1268 q -0.861648,-0.2651 -1.292492,-1.0273 -0.430844,-0.7623 -0.165722,-1.624 l 24.723471,-85.57098 q 0.265123,-0.86167 1.027363,-1.29251 0.762287,-0.43084 1.557668,-0.1657 l 4.109505,1.12681 q 0.861695,0.26514 1.292539,1.02738 0.430844,0.7623 0.165722,1.62391 z m 43.547726,43.15007 -30.887755,30.88772 q -0.66284,0.6629 -1.524481,0.6629 -0.861695,0 -1.524528,-0.6629 l -3.314137,-3.3141 q -0.662833,-0.6629 -0.662833,-1.5245 0,-0.8617 0.662833,-1.5245 L 112.78411,988.3622 86.734959,962.31309 q -0.662833,-0.66281 -0.662833,-1.52448 0,-0.86174 0.662833,-1.52455 l 3.314137,-3.31417 q 0.662833,-0.66273 1.524528,-0.66273 0.861641,0 1.524481,0.66273 l 30.887755,30.88777 q 0.66284,0.66287 0.66284,1.52454 0,0.86168 -0.66284,1.52448 z"
|
||||
id="path4" />
|
||||
id="path4"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.1 KiB |
@ -5,7 +5,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.0"
|
||||
@ -16,7 +15,7 @@
|
||||
enable-background="new 0 0 76.11 100"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="compress-image.svg"
|
||||
width="256"
|
||||
height="256"
|
||||
@ -24,23 +23,7 @@
|
||||
id="metadata16"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs14"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4136"><stop
|
||||
style="stop-color:#0d57c1;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4138" /><stop
|
||||
style="stop-color:#031125;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4140" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4136"
|
||||
id="linearGradient4142"
|
||||
x1="3.9792354"
|
||||
y1="253.00003"
|
||||
x2="252.39026"
|
||||
y2="6.1779814"
|
||||
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
|
||||
id="defs14" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
@ -49,29 +32,29 @@
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
id="namedview12"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1.888"
|
||||
inkscape:cx="-467.2416"
|
||||
inkscape:cy="37.499"
|
||||
inkscape:zoom="2.6700352"
|
||||
inkscape:cx="22.265054"
|
||||
inkscape:cy="127.38546"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" /><path
|
||||
d="m 222.1275,226.88826 c -3.9632,0 -7.44761,1.92415 -9.44305,4.82059 l -28.9242,0 0,-11.26929 c 0,-0.82683 -0.71958,-1.49543 -1.59414,-1.49543 l -2.40782,0 0,-6.35429 8.80374,0 c 1.31185,0 2.40505,-0.99269 2.40505,-2.21762 l 0,-27.53524 c 0,-1.23002 -1.09597,-2.23803 -2.40505,-2.23803 l -8.80374,0 0,-4.85886 2.89492,0 2.41888,-8.18402 3.48718,0 c 1.31184,0 2.40781,-1.0029 2.40781,-2.23293 l 0,-6.86212 c 0,-1.21727 -1.09597,-2.22272 -2.40781,-2.22272 l -38.53332,0 c -1.32844,0 -2.39674,1.00801 -2.39674,2.22272 l 0,6.86212 c 0,1.23003 1.0683,2.23293 2.39674,2.23293 l 3.48441,0 2.40505,8.18402 3.0499,0 0,4.85886 -63.950964,0 c -3.965973,0 -7.192996,-2.99596 -7.192996,-6.65797 l 0,-123.484967 c 0,-3.672216 3.229791,-6.675829 7.192996,-6.675829 l 52.612094,0 0,5.126812 c 0,1.217267 1.0683,2.21762 2.39675,2.21762 l 38.53331,0 c 1.31184,0 2.40781,-1.002905 2.40781,-2.21762 l 0,-6.864671 c 0,-1.227475 -1.09597,-2.220172 -2.40781,-2.220172 l -4.58038,0 C 144.32193,3.4138771 87.923751,0.48937416 87.923751,0.48937416 86.833316,0.43323187 85.737346,0.40516072 84.644144,0.40516072 50.41722,0.40516072 22.677553,26.138745 22.677553,57.892314 l 0,113.004226 c 0,31.74336 27.739667,51.62539 61.966591,51.62539 1.093202,0 2.189172,-0.0255 3.279607,-0.0689 0,0 28.796889,-1.48521 59.702689,-15.62542 l 0,3.54462 c 0,1.22493 1.0683,2.21762 2.39675,2.21762 l 8.93658,0 0,6.35429 -2.54619,0 c -0.88563,0 -1.59414,0.6686 -1.59414,1.49543 l 0,11.26929 -29.05151,0 c -1.99544,-2.89644 -5.48262,-4.82059 -9.44582,-4.82059 -6.18836,0 -11.19495,4.65981 -11.19495,10.38633 0,5.72651 5.00659,10.37611 11.19495,10.37611 3.9632,0 7.44761,-1.92414 9.44582,-4.82568 l 29.05705,0 0,11.2795 c 0,0.83192 0.7085,1.49032 1.59413,1.49032 l 25.74976,0 c 0.8718,0 1.59414,-0.6584 1.59414,-1.49032 l 0,-11.2795 28.9242,0 c 1.99544,2.90154 5.47985,4.82568 9.44306,4.82568 6.18835,0 11.19218,-4.6496 11.19218,-10.37611 0,-5.72652 -5.00383,-10.38633 -11.19495,-10.38633 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4142);fill-opacity:1" /><path
|
||||
style="fill:#2caf45;fill-opacity:1" /><path
|
||||
d="m 223.19745,54.706661 -123.986485,0 c -4.890824,0 -8.856178,3.643725 -8.856178,8.137856 l 0,81.378573 c 0,4.49413 3.965354,8.13785 8.856178,8.13785 l 123.986485,0 c 4.89083,0 8.85618,-3.64372 8.85618,-8.13785 l 0,-81.378573 c 0,-4.494131 -3.96535,-8.137856 -8.85618,-8.137856 z m 0,89.516429 -123.986485,0 0,-81.378573 123.986485,0 0,81.378573 z"
|
||||
id="path7"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#546e7a" /><path
|
||||
style="fill:#2271d5;fill-opacity:1" /><path
|
||||
d="m 125.7795,79.120231 c 4.89525,0 8.85617,3.639656 8.85617,8.137857 0,4.4982 -3.96092,8.137857 -8.85617,8.137857 -4.89525,0 -8.85618,-3.639657 -8.85618,-8.137857 0,-4.498201 3.96093,-8.137857 8.85618,-8.137857 m 0,-8.137857 c -9.76837,0 -17.71236,7.299658 -17.71236,16.275714 0,8.976056 7.94399,16.275712 17.71236,16.275712 9.76836,0 17.71235,-7.299656 17.71235,-16.275712 0,-8.976056 -7.94399,-16.275714 -17.71235,-16.275714 l 0,0 z"
|
||||
id="path9"
|
||||
inkscape:connector-curvature="0"
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.3 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="connect_share.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,7 +23,7 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4151">
|
||||
<stop
|
||||
style="stop-color:#3d70e4;stop-opacity:1"
|
||||
style="stop-color:#5280e7;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4153" />
|
||||
<stop
|
||||
@ -31,7 +31,7 @@
|
||||
offset="0.53151304"
|
||||
style="stop-color:#123380;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#161c1c;stop-opacity:1"
|
||||
style="stop-color:#405151;stop-opacity:1"
|
||||
offset="0.53151304"
|
||||
id="stop4161" />
|
||||
<stop
|
||||
@ -63,10 +63,10 @@
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.3 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="debug.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="41.906986"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:cy="63.245904"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -111,36 +111,49 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<path
|
||||
d="m 27.985299,942.40335 c 0.58138,0 1.167905,-0.12742 1.720988,-0.39475 l 16.013679,-7.75514 1.880482,4.44472 c 2.1686,-1.32667 4.506983,-2.41599 6.991997,-3.19051 l -3.313352,-7.83009 c -0.01801,-0.0425 -0.04631,-0.0749 -0.06431,-0.11992 -0.02058,-0.0425 -0.03087,-0.0874 -0.05145,-0.12742 -0.03859,-0.075 -0.09004,-0.13742 -0.133769,-0.20487 -0.06688,-0.11243 -0.133769,-0.22237 -0.208371,-0.3248 -0.07717,-0.0999 -0.159493,-0.19238 -0.246958,-0.28482 -0.07975,-0.0899 -0.162066,-0.17739 -0.254675,-0.25984 -0.09775,-0.0874 -0.198081,-0.1649 -0.303552,-0.23985 -0.09261,-0.0675 -0.185219,-0.13741 -0.282973,-0.19488 -0.113189,-0.0675 -0.231523,-0.12742 -0.349857,-0.17988 -0.105472,-0.05 -0.205798,-0.0974 -0.31127,-0.13742 -0.126052,-0.045 -0.252103,-0.0774 -0.375582,-0.11243 -0.113189,-0.03 -0.223806,-0.055 -0.336995,-0.0725 -0.131196,-0.025 -0.25982,-0.035 -0.391016,-0.045 -0.115762,-0.005 -0.231523,-0.015 -0.35243,-0.01 -0.131196,0.003 -0.262393,0.0175 -0.391017,0.035 -0.120906,0.015 -0.241813,0.03 -0.362719,0.055 -0.128624,0.0275 -0.257248,0.0699 -0.380727,0.10993 -0.07975,0.0275 -0.159494,0.04 -0.236668,0.0675 -0.04631,0.02 -0.07975,0.0475 -0.126051,0.0625 -0.04116,0.02 -0.08746,0.03 -0.131197,0.05 L 26.26174,935.2979 c -1.906206,0.92192 -2.683095,3.17301 -1.731278,5.02685 0.676562,1.31917 2.037403,2.07869 3.454839,2.07869 z"
|
||||
id="path4160" />
|
||||
<path
|
||||
d="m 49.082196,942.20598 c -1.77501,1.14928 -3.398244,2.50093 -4.849122,4.00998 -0.07717,0.0824 -0.156921,0.1674 -0.234096,0.25235 -0.640547,0.68707 -1.247652,1.40911 -1.811025,2.15864 -0.06174,0.0824 -0.131196,0.1624 -0.190363,0.24735 -1.216783,1.65896 -2.238056,3.46033 -3.035525,5.36664 -0.06946,0.16989 -0.128624,0.34728 -0.195508,0.51467 -0.29069,0.74953 -0.550511,1.51405 -0.774316,2.29606 -0.07975,0.28233 -0.156921,0.57215 -0.228951,0.86446 -0.177501,0.71206 -0.318987,1.4391 -0.434749,2.17614 -0.0463,0.29231 -0.100326,0.57963 -0.138914,0.87945 -0.123479,1.00936 -0.203225,2.03372 -0.203225,3.07807 l 0,0.005 c 0,2.01624 0.275255,4.00749 0.753736,5.95877 0.262393,-0.25484 0.55051,-0.46971 0.818048,-0.71205 0.691997,-0.62961 1.381421,-1.25921 2.104287,-1.83136 0.501634,-0.40224 1.031564,-0.75702 1.551205,-1.12929 0.545366,-0.39475 1.085586,-0.7995 1.646386,-1.16427 0.553083,-0.35977 1.126746,-0.67957 1.692691,-1.01186 0.558228,-0.3248 1.113883,-0.6496 1.682401,-0.94441 0.58138,-0.29981 1.170478,-0.57214 1.767293,-0.84197 0.59167,-0.26734 1.188485,-0.52717 1.790445,-0.76702 0.589098,-0.22986 1.18334,-0.44722 1.782728,-0.6496 0.653409,-0.21986 1.311964,-0.40974 1.978236,-0.58963 0.57109,-0.1549 1.137035,-0.3123 1.715843,-0.44222 0.779461,-0.17239 1.564067,-0.29731 2.353818,-0.41724 0.483626,-0.0725 0.962107,-0.16989 1.448305,-0.22486 1.291384,-0.14241 2.587914,-0.22736 3.897305,-0.22985 0.0077,0 0.01801,0 0.02315,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 1.322254,0 2.626501,0.0874 3.928171,0.23235 0.47076,0.0525 0.92867,0.14491 1.39686,0.21237 0.80776,0.12242 1.61809,0.25484 2.41555,0.42973 0.5608,0.12742 1.11132,0.27732 1.66183,0.42973 0.68427,0.18488 1.36341,0.38476 2.0374,0.60962 0.58652,0.19487 1.16019,0.40724 1.73385,0.6321 0.61997,0.24485 1.23222,0.50968 1.84447,0.78451 0.58138,0.26483 1.15761,0.52967 1.72613,0.82198 0.58395,0.30231 1.1499,0.63461 1.72099,0.9669 0.55823,0.32729 1.1216,0.64459 1.66439,0.99437 0.56595,0.36977 1.11388,0.77952 1.66182,1.17677 0.51193,0.37226 1.03671,0.72454 1.53577,1.12179 0.69972,0.55716 1.37113,1.16677 2.04512,1.77639 0.28812,0.26234 0.59939,0.49719 0.88494,0.77202 0.4759,-1.95128 0.75116,-3.94753 0.75116,-5.96377 0,-1.03934 -0.0798,-2.05871 -0.20065,-3.07057 -0.0515,-0.40974 -0.13635,-0.8045 -0.20323,-1.20924 -0.0978,-0.57214 -0.20323,-1.14429 -0.33957,-1.70394 -0.0952,-0.40474 -0.20322,-0.80199 -0.31898,-1.19675 -0.18265,-0.6271 -0.39359,-1.24172 -0.62254,-1.84634 -0.10548,-0.27982 -0.19551,-0.56464 -0.31127,-0.83697 -0.36787,-0.87446 -0.77947,-1.72142 -1.23479,-2.54591 -0.1029,-0.18738 -0.22124,-0.36727 -0.33185,-0.55215 -0.40646,-0.68957 -0.83863,-1.36415 -1.3094,-2.01374 -0.12347,-0.17489 -0.24953,-0.34728 -0.37558,-0.51718 -1.22192,-1.61398 -2.61878,-3.09056 -4.1777,-4.39474 -0.054,-0.0475 -0.11319,-0.09 -0.16979,-0.13742 -0.74601,-0.61211 -1.53062,-1.18925 -2.34352,-1.71892 -2.21491,-1.45409 -4.65362,-2.60587 -7.26726,-3.37288 -0.33956,-0.0974 -0.68685,-0.17989 -1.02641,-0.26484 -0.40131,-0.0999 -0.80262,-0.19738 -1.21164,-0.27982 -0.32156,-0.065 -0.64827,-0.12742 -0.97497,-0.17989 -0.47591,-0.0774 -0.95439,-0.14491 -1.44059,-0.19988 -0.27011,-0.03 -0.54279,-0.065 -0.81805,-0.0874 -0.769167,-0.0625 -1.543483,-0.10743 -2.328089,-0.10743 l -0.0051,0 c -0.825766,0 -1.643814,0.05 -2.451572,0.12242 -0.27011,0.0225 -0.537648,0.055 -0.805186,0.0874 -0.542793,0.0625 -1.080441,0.1474 -1.612944,0.23984 -0.298407,0.0525 -0.594242,0.10244 -0.890077,0.1649 -0.609678,0.12742 -1.21421,0.28232 -1.80588,0.44972 -0.120907,0.035 -0.246958,0.0575 -0.367865,0.0974 l 0,-0.005 c -2.505594,0.74703 -4.849122,1.83885 -6.984279,3.21799 l 0.0051,0.0125 z"
|
||||
id="path4158" />
|
||||
<path
|
||||
d="m 82.28518,934.25596 16.01368,7.75514 c 0.55308,0.26733 1.139601,0.39475 1.71841,0.39475 1.41744,0 2.78085,-0.76202 3.45741,-2.0737 0.94925,-1.85384 0.17493,-4.10493 -1.73385,-5.02685 l -19.72576,-9.55401 c -0.0437,-0.02 -0.0849,-0.0275 -0.12863,-0.0475 -0.0437,-0.0175 -0.0797,-0.0475 -0.12605,-0.065 -0.0772,-0.03 -0.15949,-0.0425 -0.23924,-0.0675 -0.12862,-0.0425 -0.25467,-0.0824 -0.38073,-0.10993 -0.1209,-0.0275 -0.23924,-0.0425 -0.36014,-0.055 -0.1312,-0.015 -0.2624,-0.03 -0.39102,-0.035 -0.12091,-0.003 -0.23924,0.005 -0.36015,0.0125 -0.12862,0.007 -0.25467,0.02 -0.38072,0.0425 -0.11834,0.02 -0.2341,0.05 -0.34986,0.0774 -0.12348,0.0325 -0.24181,0.0625 -0.36272,0.10744 -0.11319,0.045 -0.22123,0.0924 -0.32928,0.14491 -0.11319,0.0525 -0.2238,0.10743 -0.33185,0.16989 -0.10547,0.06 -0.20322,0.13492 -0.30098,0.20487 -0.10032,0.0725 -0.19551,0.14741 -0.28812,0.22986 -0.0952,0.0824 -0.1775,0.17239 -0.26496,0.26483 -0.0823,0.0924 -0.16207,0.17989 -0.23924,0.27733 -0.0746,0.10243 -0.14406,0.21486 -0.21094,0.32729 -0.0437,0.0675 -0.0952,0.13242 -0.13377,0.20487 -0.0232,0.04 -0.0309,0.085 -0.0514,0.12742 -0.0206,0.045 -0.0489,0.0775 -0.0643,0.11993 l -3.32107,7.84508 c 2.48501,0.77702 4.84397,1.82636 7.01257,3.15552 l 1.87277,-4.42722 z"
|
||||
id="path4156" />
|
||||
<path
|
||||
d="m 25.639199,989.21152 c 0.848918,-2.44597 1.877909,-4.76701 3.045814,-6.99312 -6.554675,-1.81636 -12.576847,-6.09118 -16.890894,-9.55401 -1.646386,-1.31917 -4.0773782,-1.09431 -5.4330752,0.49719 -1.358268,1.5965 -1.126745,3.95752 0.514496,5.27419 4.7153532,3.79263 11.2443042,8.4622 18.7636592,10.77575 z"
|
||||
id="path4154" />
|
||||
<path
|
||||
d="m 102.35823,989.21652 c 7.52192,-2.31355 14.05345,-6.98812 18.77137,-10.77825 1.64382,-1.31667 1.87277,-3.68269 0.51193,-5.27419 -1.35313,-1.5965 -3.79184,-1.81886 -5.43051,-0.49719 -4.31919,3.47032 -10.34136,7.74514 -16.896039,9.55901 1.165339,2.2236 2.194329,4.54965 3.043249,6.99062 z"
|
||||
id="path4152" />
|
||||
<path
|
||||
d="m 102.35823,1025.0616 c -0.84635,2.441 -1.87534,4.767 -3.045819,6.9931 6.557249,1.8114 12.581989,6.0862 16.896039,9.554 0.71772,0.5796 1.58979,0.8595 2.45672,0.8595 1.11131,0 2.21233,-0.4647 2.97636,-1.3567 1.35569,-1.5965 1.12674,-3.9575 -0.5145,-5.2791 -4.71793,-3.7877 -11.24688,-8.4622 -18.7688,-10.7708 z"
|
||||
id="path4150" />
|
||||
<path
|
||||
d="m 123.14128,1003.3876 -17.93532,0 c 0.0823,1.2442 0.16207,2.4884 0.16207,3.7526 0,1.2642 -0.0797,2.5035 -0.16207,3.7427 l 17.93532,0 c 2.13001,0 3.85872,-1.679 3.85872,-3.7477 0,-2.0687 -1.72871,-3.7476 -3.85872,-3.7476 z"
|
||||
id="path4148" />
|
||||
<path
|
||||
d="m 90.66117,975.97232 c -0.09,-0.10744 -0.1775,-0.21487 -0.27011,-0.3223 -0.76917,-0.90194 -1.56922,-1.7614 -2.4027,-2.58088 -0.10547,-0.10244 -0.21094,-0.20238 -0.31641,-0.30231 -0.84892,-0.81949 -1.72356,-1.599 -2.63165,-2.32855 -0.072,-0.0575 -0.15178,-0.11243 -0.2238,-0.16989 -1.88563,-1.49406 -3.89474,-2.78076 -5.99902,-3.85258 -0.11319,-0.055 -0.22381,-0.11993 -0.337,-0.1749 -0.99812,-0.49469 -2.01939,-0.92941 -3.05868,-1.32417 -0.16463,-0.06 -0.32927,-0.12492 -0.49391,-0.18238 -1.02642,-0.36727 -2.07599,-0.68957 -3.141,-0.9544 -0.17235,-0.045 -0.34986,-0.0824 -0.52478,-0.12243 -1.08302,-0.25484 -2.18147,-0.45971 -3.29535,-0.59462 -0.13377,-0.0175 -0.26754,-0.025 -0.40131,-0.04 -1.17305,-0.13242 -2.361531,-0.21486 -3.568023,-0.21486 -1.250225,0 -2.487587,0.0774 -3.706942,0.21986 -0.509351,0.06 -1.005839,0.17489 -1.512617,0.25984 -0.689425,0.11492 -1.381421,0.21486 -2.060556,0.36976 -0.658554,0.15491 -1.296529,0.36228 -1.939649,0.55715 -0.496488,0.14991 -1.000694,0.27983 -1.486892,0.45472 -0.738302,0.25984 -1.461168,0.57214 -2.181462,0.88445 -0.36272,0.1549 -0.728012,0.30231 -1.088159,0.4697 -0.792323,0.37726 -1.558922,0.7995 -2.322948,1.23673 -0.25982,0.1524 -0.522213,0.28732 -0.779461,0.44472 -0.812903,0.49469 -1.605226,1.02935 -2.382115,1.5915 -0.185218,0.13242 -0.373009,0.25984 -0.553083,0.39475 -0.807758,0.60962 -1.594936,1.25422 -2.361535,1.9263 -0.133769,0.11992 -0.267538,0.23735 -0.401307,0.35727 -0.776888,0.70706 -1.530624,1.44659 -2.256063,2.22111 -0.105472,0.11243 -0.210944,0.22236 -0.313843,0.33729 -0.87207,0.94441 -1.700408,1.94128 -2.497876,2.97813 -0.295835,0.38726 -0.609678,0.76202 -0.895223,1.16427 -0.86178,1.19675 -1.659249,2.45596 -2.410412,3.76015 -4.018212,7.06057 -6.366885,15.56024 -6.366885,24.70945 0,12.21 4.180278,23.263 10.938179,31.2805 0.04116,0.05 0.08232,0.097 0.126051,0.1474 1.59751,1.8738 3.34165,3.5778 5.201552,5.0893 0.172356,0.1424 0.349857,0.2823 0.524786,0.4198 0.884932,0.697 1.787872,1.3516 2.724255,1.9562 0.149203,0.097 0.30098,0.1799 0.450183,0.2724 0.823193,0.5171 1.669539,0.9943 2.528747,1.4391 0.221233,0.1174 0.442466,0.2398 0.668844,0.3472 0.959535,0.4723 1.939649,0.897 2.940343,1.2742 0.236668,0.087 0.478481,0.1649 0.717722,0.2499 0.900367,0.3173 1.813597,0.5996 2.742262,0.8345 0.180073,0.05 0.357574,0.1024 0.537648,0.1474 1.057289,0.2498 2.132585,0.4397 3.220743,0.5796 0.262393,0.035 0.522213,0.062 0.784606,0.092 0.486198,0.05 0.990404,0.052 1.481748,0.087 l 0,-61.07677 c 0,-1.03436 0.864352,-1.87383 1.929359,-1.87383 1.065006,0 1.929363,0.83947 1.929363,1.87383 l 0,61.06927 c 0.49648,-0.04 1.00326,-0.04 1.49461,-0.092 0.24953,-0.025 0.49906,-0.053 0.74859,-0.082 1.10359,-0.1474 2.19432,-0.3373 3.26704,-0.5896 0.14664,-0.035 0.28812,-0.077 0.43218,-0.1174 0.98012,-0.2499 1.94222,-0.5422 2.89147,-0.8795 0.20065,-0.072 0.40645,-0.1374 0.6071,-0.2149 1.02899,-0.3847 2.04255,-0.8244 3.03295,-1.3066 0.17751,-0.088 0.35243,-0.1849 0.52736,-0.2724 0.93381,-0.4822 1.85476,-0.9993 2.74484,-1.5665 0.09,-0.053 0.18264,-0.1074 0.27268,-0.1649 0.97754,-0.6296 1.92421,-1.3117 2.84259,-2.0387 0.12605,-0.097 0.24953,-0.1999 0.37301,-0.2973 9.86545,-7.9875 16.34553,-21.3916 16.34553,-36.5897 0.005,-12.15982 -4.13912,-23.16292 -10.84557,-31.1704 z"
|
||||
id="path4146"
|
||||
style="fill:url(#radialGradient4168);fill-opacity:1" />
|
||||
<path
|
||||
d="m 22.624254,1007.1402 c 0,-1.2642 0.07975,-2.5084 0.164638,-3.7526 l -17.9301752,0 c -2.130012,0 -3.858718,1.6789 -3.858718,3.7476 0,2.0687 1.728706,3.7477 3.858718,3.7477 l 17.9327482,0 c -0.08746,-1.2392 -0.167211,-2.481 -0.167211,-3.7427 z"
|
||||
id="path4144" />
|
||||
<path
|
||||
d="m 6.8729678,1035.8324 c -1.643814,1.3216 -1.875337,3.6851 -0.514496,5.2791 0.761454,0.892 1.867619,1.3567 2.9763584,1.3567 0.8643518,0 1.7364228,-0.2823 2.4567168,-0.8595 4.316619,-3.4703 10.336218,-7.7401 16.890894,-9.554 -1.167905,-2.2261 -2.196897,-4.5521 -3.045815,-6.9931 -7.516782,2.3136 -14.048305,6.9831 -18.7636582,10.7708 z"
|
||||
id="path4" />
|
||||
<g
|
||||
id="g835"
|
||||
style="fill:#dd8808;fill-opacity:1">
|
||||
<path
|
||||
id="path4160"
|
||||
d="m 27.985299,942.40335 c 0.58138,0 1.167905,-0.12742 1.720988,-0.39475 l 16.013679,-7.75514 1.880482,4.44472 c 2.1686,-1.32667 4.506983,-2.41599 6.991997,-3.19051 l -3.313352,-7.83009 c -0.01801,-0.0425 -0.04631,-0.0749 -0.06431,-0.11992 -0.02058,-0.0425 -0.03087,-0.0874 -0.05145,-0.12742 -0.03859,-0.075 -0.09004,-0.13742 -0.133769,-0.20487 -0.06688,-0.11243 -0.133769,-0.22237 -0.208371,-0.3248 -0.07717,-0.0999 -0.159493,-0.19238 -0.246958,-0.28482 -0.07975,-0.0899 -0.162066,-0.17739 -0.254675,-0.25984 -0.09775,-0.0874 -0.198081,-0.1649 -0.303552,-0.23985 -0.09261,-0.0675 -0.185219,-0.13741 -0.282973,-0.19488 -0.113189,-0.0675 -0.231523,-0.12742 -0.349857,-0.17988 -0.105472,-0.05 -0.205798,-0.0974 -0.31127,-0.13742 -0.126052,-0.045 -0.252103,-0.0774 -0.375582,-0.11243 -0.113189,-0.03 -0.223806,-0.055 -0.336995,-0.0725 -0.131196,-0.025 -0.25982,-0.035 -0.391016,-0.045 -0.115762,-0.005 -0.231523,-0.015 -0.35243,-0.01 -0.131196,0.003 -0.262393,0.0175 -0.391017,0.035 -0.120906,0.015 -0.241813,0.03 -0.362719,0.055 -0.128624,0.0275 -0.257248,0.0699 -0.380727,0.10993 -0.07975,0.0275 -0.159494,0.04 -0.236668,0.0675 -0.04631,0.02 -0.07975,0.0475 -0.126051,0.0625 -0.04116,0.02 -0.08746,0.03 -0.131197,0.05 L 26.26174,935.2979 c -1.906206,0.92192 -2.683095,3.17301 -1.731278,5.02685 0.676562,1.31917 2.037403,2.07869 3.454839,2.07869 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4158"
|
||||
d="m 49.082196,942.20598 c -1.77501,1.14928 -3.398244,2.50093 -4.849122,4.00998 -0.07717,0.0824 -0.156921,0.1674 -0.234096,0.25235 -0.640547,0.68707 -1.247652,1.40911 -1.811025,2.15864 -0.06174,0.0824 -0.131196,0.1624 -0.190363,0.24735 -1.216783,1.65896 -2.238056,3.46033 -3.035525,5.36664 -0.06946,0.16989 -0.128624,0.34728 -0.195508,0.51467 -0.29069,0.74953 -0.550511,1.51405 -0.774316,2.29606 -0.07975,0.28233 -0.156921,0.57215 -0.228951,0.86446 -0.177501,0.71206 -0.318987,1.4391 -0.434749,2.17614 -0.0463,0.29231 -0.100326,0.57963 -0.138914,0.87945 -0.123479,1.00936 -0.203225,2.03372 -0.203225,3.07807 l 0,0.005 c 0,2.01624 0.275255,4.00749 0.753736,5.95877 0.262393,-0.25484 0.55051,-0.46971 0.818048,-0.71205 0.691997,-0.62961 1.381421,-1.25921 2.104287,-1.83136 0.501634,-0.40224 1.031564,-0.75702 1.551205,-1.12929 0.545366,-0.39475 1.085586,-0.7995 1.646386,-1.16427 0.553083,-0.35977 1.126746,-0.67957 1.692691,-1.01186 0.558228,-0.3248 1.113883,-0.6496 1.682401,-0.94441 0.58138,-0.29981 1.170478,-0.57214 1.767293,-0.84197 0.59167,-0.26734 1.188485,-0.52717 1.790445,-0.76702 0.589098,-0.22986 1.18334,-0.44722 1.782728,-0.6496 0.653409,-0.21986 1.311964,-0.40974 1.978236,-0.58963 0.57109,-0.1549 1.137035,-0.3123 1.715843,-0.44222 0.779461,-0.17239 1.564067,-0.29731 2.353818,-0.41724 0.483626,-0.0725 0.962107,-0.16989 1.448305,-0.22486 1.291384,-0.14241 2.587914,-0.22736 3.897305,-0.22985 0.0077,0 0.01801,0 0.02315,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 0.0026,0 1.322254,0 2.626501,0.0874 3.928171,0.23235 0.47076,0.0525 0.92867,0.14491 1.39686,0.21237 0.80776,0.12242 1.61809,0.25484 2.41555,0.42973 0.5608,0.12742 1.11132,0.27732 1.66183,0.42973 0.68427,0.18488 1.36341,0.38476 2.0374,0.60962 0.58652,0.19487 1.16019,0.40724 1.73385,0.6321 0.61997,0.24485 1.23222,0.50968 1.84447,0.78451 0.58138,0.26483 1.15761,0.52967 1.72613,0.82198 0.58395,0.30231 1.1499,0.63461 1.72099,0.9669 0.55823,0.32729 1.1216,0.64459 1.66439,0.99437 0.56595,0.36977 1.11388,0.77952 1.66182,1.17677 0.51193,0.37226 1.03671,0.72454 1.53577,1.12179 0.69972,0.55716 1.37113,1.16677 2.04512,1.77639 0.28812,0.26234 0.59939,0.49719 0.88494,0.77202 0.4759,-1.95128 0.75116,-3.94753 0.75116,-5.96377 0,-1.03934 -0.0798,-2.05871 -0.20065,-3.07057 -0.0515,-0.40974 -0.13635,-0.8045 -0.20323,-1.20924 -0.0978,-0.57214 -0.20323,-1.14429 -0.33957,-1.70394 -0.0952,-0.40474 -0.20322,-0.80199 -0.31898,-1.19675 -0.18265,-0.6271 -0.39359,-1.24172 -0.62254,-1.84634 -0.10548,-0.27982 -0.19551,-0.56464 -0.31127,-0.83697 -0.36787,-0.87446 -0.77947,-1.72142 -1.23479,-2.54591 -0.1029,-0.18738 -0.22124,-0.36727 -0.33185,-0.55215 -0.40646,-0.68957 -0.83863,-1.36415 -1.3094,-2.01374 -0.12347,-0.17489 -0.24953,-0.34728 -0.37558,-0.51718 -1.22192,-1.61398 -2.61878,-3.09056 -4.1777,-4.39474 -0.054,-0.0475 -0.11319,-0.09 -0.16979,-0.13742 -0.74601,-0.61211 -1.53062,-1.18925 -2.34352,-1.71892 -2.21491,-1.45409 -4.65362,-2.60587 -7.26726,-3.37288 -0.33956,-0.0974 -0.68685,-0.17989 -1.02641,-0.26484 -0.40131,-0.0999 -0.80262,-0.19738 -1.21164,-0.27982 -0.32156,-0.065 -0.64827,-0.12742 -0.97497,-0.17989 -0.47591,-0.0774 -0.95439,-0.14491 -1.44059,-0.19988 -0.27011,-0.03 -0.54279,-0.065 -0.81805,-0.0874 -0.769167,-0.0625 -1.543483,-0.10743 -2.328089,-0.10743 l -0.0051,0 c -0.825766,0 -1.643814,0.05 -2.451572,0.12242 -0.27011,0.0225 -0.537648,0.055 -0.805186,0.0874 -0.542793,0.0625 -1.080441,0.1474 -1.612944,0.23984 -0.298407,0.0525 -0.594242,0.10244 -0.890077,0.1649 -0.609678,0.12742 -1.21421,0.28232 -1.80588,0.44972 -0.120907,0.035 -0.246958,0.0575 -0.367865,0.0974 l 0,-0.005 c -2.505594,0.74703 -4.849122,1.83885 -6.984279,3.21799 l 0.0051,0.0125 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4156"
|
||||
d="m 82.28518,934.25596 16.01368,7.75514 c 0.55308,0.26733 1.139601,0.39475 1.71841,0.39475 1.41744,0 2.78085,-0.76202 3.45741,-2.0737 0.94925,-1.85384 0.17493,-4.10493 -1.73385,-5.02685 l -19.72576,-9.55401 c -0.0437,-0.02 -0.0849,-0.0275 -0.12863,-0.0475 -0.0437,-0.0175 -0.0797,-0.0475 -0.12605,-0.065 -0.0772,-0.03 -0.15949,-0.0425 -0.23924,-0.0675 -0.12862,-0.0425 -0.25467,-0.0824 -0.38073,-0.10993 -0.1209,-0.0275 -0.23924,-0.0425 -0.36014,-0.055 -0.1312,-0.015 -0.2624,-0.03 -0.39102,-0.035 -0.12091,-0.003 -0.23924,0.005 -0.36015,0.0125 -0.12862,0.007 -0.25467,0.02 -0.38072,0.0425 -0.11834,0.02 -0.2341,0.05 -0.34986,0.0774 -0.12348,0.0325 -0.24181,0.0625 -0.36272,0.10744 -0.11319,0.045 -0.22123,0.0924 -0.32928,0.14491 -0.11319,0.0525 -0.2238,0.10743 -0.33185,0.16989 -0.10547,0.06 -0.20322,0.13492 -0.30098,0.20487 -0.10032,0.0725 -0.19551,0.14741 -0.28812,0.22986 -0.0952,0.0824 -0.1775,0.17239 -0.26496,0.26483 -0.0823,0.0924 -0.16207,0.17989 -0.23924,0.27733 -0.0746,0.10243 -0.14406,0.21486 -0.21094,0.32729 -0.0437,0.0675 -0.0952,0.13242 -0.13377,0.20487 -0.0232,0.04 -0.0309,0.085 -0.0514,0.12742 -0.0206,0.045 -0.0489,0.0775 -0.0643,0.11993 l -3.32107,7.84508 c 2.48501,0.77702 4.84397,1.82636 7.01257,3.15552 l 1.87277,-4.42722 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4154"
|
||||
d="m 25.639199,989.21152 c 0.848918,-2.44597 1.877909,-4.76701 3.045814,-6.99312 -6.554675,-1.81636 -12.576847,-6.09118 -16.890894,-9.55401 -1.646386,-1.31917 -4.0773782,-1.09431 -5.4330752,0.49719 -1.358268,1.5965 -1.126745,3.95752 0.514496,5.27419 4.7153532,3.79263 11.2443042,8.4622 18.7636592,10.77575 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4152"
|
||||
d="m 102.35823,989.21652 c 7.52192,-2.31355 14.05345,-6.98812 18.77137,-10.77825 1.64382,-1.31667 1.87277,-3.68269 0.51193,-5.27419 -1.35313,-1.5965 -3.79184,-1.81886 -5.43051,-0.49719 -4.31919,3.47032 -10.34136,7.74514 -16.896039,9.55901 1.165339,2.2236 2.194329,4.54965 3.043249,6.99062 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4150"
|
||||
d="m 102.35823,1025.0616 c -0.84635,2.441 -1.87534,4.767 -3.045819,6.9931 6.557249,1.8114 12.581989,6.0862 16.896039,9.554 0.71772,0.5796 1.58979,0.8595 2.45672,0.8595 1.11131,0 2.21233,-0.4647 2.97636,-1.3567 1.35569,-1.5965 1.12674,-3.9575 -0.5145,-5.2791 -4.71793,-3.7877 -11.24688,-8.4622 -18.7688,-10.7708 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4148"
|
||||
d="m 123.14128,1003.3876 -17.93532,0 c 0.0823,1.2442 0.16207,2.4884 0.16207,3.7526 0,1.2642 -0.0797,2.5035 -0.16207,3.7427 l 17.93532,0 c 2.13001,0 3.85872,-1.679 3.85872,-3.7477 0,-2.0687 -1.72871,-3.7476 -3.85872,-3.7476 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4144"
|
||||
d="m 22.624254,1007.1402 c 0,-1.2642 0.07975,-2.5084 0.164638,-3.7526 l -17.9301752,0 c -2.130012,0 -3.858718,1.6789 -3.858718,3.7476 0,2.0687 1.728706,3.7477 3.858718,3.7477 l 17.9327482,0 c -0.08746,-1.2392 -0.167211,-2.481 -0.167211,-3.7427 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path4"
|
||||
d="m 6.8729678,1035.8324 c -1.643814,1.3216 -1.875337,3.6851 -0.514496,5.2791 0.761454,0.892 1.867619,1.3567 2.9763584,1.3567 0.8643518,0 1.7364228,-0.2823 2.4567168,-0.8595 4.316619,-3.4703 10.336218,-7.7401 16.890894,-9.554 -1.167905,-2.2261 -2.196897,-4.5521 -3.045815,-6.9931 -7.516782,2.3136 -14.048305,6.9831 -18.7636582,10.7708 z"
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,41 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="diff.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4136">
|
||||
<stop
|
||||
style="stop-color:#34ae3d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4138" />
|
||||
<stop
|
||||
style="stop-color:#27812d;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4140" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4136"
|
||||
id="linearGradient4142"
|
||||
x1="18.439"
|
||||
y1="46.9435"
|
||||
x2="46.291"
|
||||
y2="46.9435"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4136"
|
||||
id="linearGradient4150"
|
||||
x1="18.438999"
|
||||
y1="46.943501"
|
||||
x2="46.291"
|
||||
y2="46.943501"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -57,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="-10.424833"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -122,14 +90,14 @@
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 97.75685,950.20353 -29.611681,0 -23.709931,-24.84123 -23.747868,0 c -10.8726981,0 -19.6873739,8.81466 -19.6873739,19.68737 l 0,61.78533 c 0,10.8728 8.8146758,19.6875 19.6873739,19.6875 l 33.305003,0 c 0.111101,0 0.218131,-0.015 0.327874,-0.018 l 0,5.1701 c 0,10.8714 8.814675,19.6874 19.687373,19.6874 l 33.30501,0 c 10.87269,0 19.68737,-8.816 19.68737,-19.6874 l 0,-50.83407 -29.24315,-30.63734 z m -76.576314,66.70757 c -5.435672,0 -9.844363,-4.4073 -9.844363,-9.8444 l 0,-61.85172 c 0,-5.43703 4.407337,-9.84437 9.844363,-9.84437 l 18.210583,0 c 2.717835,0 4.922182,2.20299 4.922182,4.92219 l 0,9.31731 c 0,2.71784 2.202991,4.92218 4.922181,4.92218 l 9.844365,0 c 2.717835,0 4.922181,2.20299 4.922181,4.92218 l 0,35.40507 0,12.20856 c 0,5.437 -4.407337,9.8444 -9.844364,9.8444 l -32.977128,0 z m 96.140394,14.9969 c 0,5.4384 -4.40734,9.8444 -9.84437,9.8444 l -32.975775,0 c -5.437026,0 -9.844364,-4.406 -9.844364,-9.8444 l 0,-8.5383 c 5.423479,-3.5077 9.021969,-9.5951 9.021969,-16.5333 l 0,-46.57986 c 0.270971,-0.023 0.543297,-0.0447 0.821041,-0.0447 l 18.209228,0 c 2.719191,0 4.922181,2.20299 4.922181,4.92218 l 0,9.31868 c 0,2.71784 2.204354,4.92218 4.92218,4.92218 l 9.84438,0 c 2.71918,0 4.92217,2.20304 4.92217,4.92223 l 0,47.61089 z"
|
||||
id="path8"
|
||||
style="fill:#3027dd;fill-opacity:1" />
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<polygon
|
||||
transform="matrix(1.3284504,0,0,1.4015682,2.5047034,916.06764)"
|
||||
points="29.216,60.143 46.291,46.943 29.216,33.744 29.216,43.31 18.439,43.31 18.439,50.333 29.216,50.333 "
|
||||
id="polygon4"
|
||||
style="fill:url(#linearGradient4142);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<polygon
|
||||
style="fill:url(#linearGradient4150);fill-opacity:1.0"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
id="polygon4153"
|
||||
points="18.439,43.31 18.439,50.333 29.216,50.333 29.216,60.143 46.291,46.943 29.216,33.744 29.216,43.31 "
|
||||
transform="matrix(-1.3284504,0,0,1.4015682,134.4953,948.06764)" />
|
||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 4.5 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="document-encrypt.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="38.332091"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -114,11 +114,11 @@
|
||||
<g
|
||||
transform="matrix(1.3939367,0,0,1.3695651,-5.6968353,-384.43812)"
|
||||
id="g4"
|
||||
style="fill:#3027dd;fill-opacity:1">
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 20.000054,956.3622 c -1.94862,0.01 -3.01295,1.69 -3,3 l 0,86 c 1.6e-4,1.5708 1.42925,2.9998 3,3 l 60,0 c 1.57075,-2e-4 2.99984,-1.4292 3,-3 l 0,-70 c 0.002,-0.7861 -0.32012,-1.5681 -0.875,-2.125 l -16,-16 c -0.55685,-0.5549 -1.33889,-0.8769 -2.125,-0.875 l -44,0 z m 3,6 38,0 0,13 a 3.0003,3.0003 0 0 0 3,3 l 13,0 0,64 -54,0 0,-80 z m 44,4.2188 5.78125,5.7812 -5.78125,0 0,-5.7812 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,33 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="document-import.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4145"
|
||||
x1="25.760529"
|
||||
y1="988.36218"
|
||||
x2="102.23947"
|
||||
y2="988.36218"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.62762378,0,0,0.6386548,23.832078,368.13994)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#557022;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#95c43c;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -49,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="19.1967"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -113,11 +89,11 @@
|
||||
<g
|
||||
transform="matrix(1.3939367,0,0,1.3695651,-5.6968353,-384.43812)"
|
||||
id="g4"
|
||||
style="fill:#3027dd;fill-opacity:1">
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 20.000054,956.3622 c -1.94862,0.01 -3.01295,1.69 -3,3 l 0,86 c 1.6e-4,1.5708 1.42925,2.9998 3,3 l 60,0 c 1.57075,-2e-4 2.99984,-1.4292 3,-3 l 0,-70 c 0.002,-0.7861 -0.32012,-1.5681 -0.875,-2.125 l -16,-16 c -0.55685,-0.5549 -1.33889,-0.8769 -2.125,-0.875 l -44,0 z m 3,6 38,0 0,13 a 3.0003,3.0003 0 0 0 3,3 l 13,0 0,64 -54,0 0,-80 z m 44,4.2188 5.78125,5.7812 -5.78125,0 0,-5.7812 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
@ -127,6 +103,6 @@
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 87.119695,974.32745 -24.602319,25.03473 24.602319,25.03472 Q 88,1025.2927 88,1026.5185 q 0,1.2258 -0.880305,2.1217 l -7.691123,7.8262 q -0.880309,0.8958 -2.084942,0.8958 -1.204633,0 -2.084943,-0.8958 L 40.880312,1001.4838 Q 40,1000.588 40,999.36218 q 0,-1.2258 0.880312,-2.12159 l 34.378375,-34.98261 q 0.88031,-0.89578 2.084943,-0.89578 1.204633,0 2.084942,0.89578 l 7.691123,7.82631 Q 88,970.98006 88,972.20587 q 0,1.2258 -0.880305,2.12158 z"
|
||||
id="path4"
|
||||
style="fill:url(#linearGradient4145);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.2 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,34 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="document-new.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4142">
|
||||
<stop
|
||||
style="stop-color:#34ae3d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4144" />
|
||||
<stop
|
||||
style="stop-color:#26822e;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4146" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4142"
|
||||
id="radialGradient4148"
|
||||
cx="64"
|
||||
cy="999.36214"
|
||||
fx="64"
|
||||
fy="999.36214"
|
||||
r="29"
|
||||
gradientTransform="matrix(1,0,0,1.0000021,0,-0.00206765)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -57,10 +32,10 @@
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -114,11 +89,11 @@
|
||||
<g
|
||||
transform="matrix(1.3939367,0,0,1.3695651,-5.6968353,-384.43812)"
|
||||
id="g4"
|
||||
style="fill:#3027dd;fill-opacity:1">
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 20.000054,956.3622 c -1.94862,0.01 -3.01295,1.69 -3,3 l 0,86 c 1.6e-4,1.5708 1.42925,2.9998 3,3 l 60,0 c 1.57075,-2e-4 2.99984,-1.4292 3,-3 l 0,-70 c 0.002,-0.7861 -0.32012,-1.5681 -0.875,-2.125 l -16,-16 c -0.55685,-0.5549 -1.33889,-0.8769 -2.125,-0.875 l -44,0 z m 3,6 38,0 0,13 a 3.0003,3.0003 0 0 0 3,3 l 13,0 0,64 -54,0 0,-80 z m 44,4.2188 5.78125,5.7812 -5.78125,0 0,-5.7812 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
@ -128,6 +103,6 @@
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 93,995.40757 0,7.90913 q 0,1.6479 -1.153415,2.801 -1.1534,1.1535 -2.801125,1.1535 l -17.13637,0 0,17.1366 q 0,1.6475 -1.153401,2.8009 -1.153414,1.1535 -2.801139,1.1535 l -7.90909,0 q -1.647735,0 -2.801139,-1.1535 -1.153411,-1.1534 -1.153411,-2.8009 l 0,-17.1366 -17.13636,0 q -1.647725,0 -2.801135,-1.1535 Q 35,1004.9646 35,1003.3167 l 0,-7.90913 q 0,-1.6477 1.153415,-2.8011 1.15341,-1.1535 2.801135,-1.1535 l 17.13636,0 0,-17.13635 q 0,-1.64771 1.153411,-2.80112 1.153404,-1.15342 2.801139,-1.15342 l 7.90909,0 q 1.647725,0 2.801139,1.15342 1.153401,1.15341 1.153401,2.80112 l 0,17.13635 17.13637,0 q 1.647725,0 2.801125,1.1535 Q 93,993.75987 93,995.40757 Z"
|
||||
id="path4"
|
||||
style="fill:url(#radialGradient4148);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.4 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,43 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="document-split.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4141"
|
||||
id="linearGradient4147"
|
||||
x1="64.402176"
|
||||
y1="1023.1872"
|
||||
x2="63.597828"
|
||||
y2="953.27203"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.3265309,0,0,-0.3265309,43.102023,1283.843)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4141">
|
||||
<stop
|
||||
style="stop-color:#016324;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4143" />
|
||||
<stop
|
||||
style="stop-color:#16fb67;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4145" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4141"
|
||||
id="linearGradient4157"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.3265309,0,0,0.3265309,43.102023,691.95274)"
|
||||
x1="64.402176"
|
||||
y1="1023.1872"
|
||||
x2="63.597828"
|
||||
y2="953.27203" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -66,10 +32,10 @@
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -125,7 +91,7 @@
|
||||
overflow="visible"
|
||||
display="inline"
|
||||
visibility="visible"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
d="m 22.181976,924.64788 c -2.716253,0.0137 -4.199861,2.31457 -4.18181,4.1087 l 0,53.22899 c 2.23e-4,2.1513 1.992284,4.1085 4.18181,4.1087 l 83.636194,0 c 2.18953,-2e-4 4.18159,-1.9574 4.18181,-4.1087 l 0,-31.31595 c 0.003,-1.07662 -0.44623,-2.14762 -1.21969,-2.91033 L 86.477307,925.84625 c -0.77621,-0.75997 -1.86633,-1.20097 -2.96212,-1.19837 z m 4.18181,8.21739 52.969595,0 0,17.80435 c 2.34e-4,2.26907 1.872355,4.10846 4.181806,4.10869 l 18.121173,0 0,23.09856 -75.272574,0 z m 61.333211,5.77792 8.0587,7.91773 -8.0587,0 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccc" />
|
||||
@ -133,7 +99,7 @@
|
||||
sodipodi:nodetypes="cccccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 22.18198,990.27288 c -2.716253,0.0137 -4.199861,2.31457 -4.18181,4.1087 l 0,53.22902 c 2.23e-4,2.1513 1.992284,4.1085 4.18181,4.1087 l 83.6362,0 c 2.18953,-2e-4 4.18159,-1.9574 4.18181,-4.1087 l -0.21907,-53.19292 c -0.005,-1.88755 -0.90332,-4.04296 -3.14069,-4.05551 z m 4.18181,8.21739 74.66602,0 0.60656,45.01163 -75.27258,0 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
@ -142,9 +108,9 @@
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 84.244916,970.00105 q 0,-1.03174 -0.751276,-1.7857 L 65.779338,950.43753 Q 65.028063,949.68357 64,949.68357 q -1.028062,0 -1.779338,0.75396 L 44.50636,968.21535 q -0.751276,0.75396 -0.751276,1.7857 0,1.03177 0.751276,1.7857 0.751277,0.75399 1.779339,0.75399 l 35.428602,0 q 1.028063,0 1.779339,-0.75399 0.751275,-0.75393 0.751275,-1.7857 z"
|
||||
id="path4"
|
||||
style="fill:url(#linearGradient4147);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4157);fill-opacity:1"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
id="path4155"
|
||||
d="m 84.244916,1005.7947 q 0,1.0317 -0.751276,1.7857 l -17.714302,17.7778 q -0.751275,0.754 -1.779338,0.754 -1.028062,0 -1.779338,-0.754 L 44.50636,1007.5804 q -0.751276,-0.754 -0.751276,-1.7857 0,-1.0318 0.751276,-1.7857 0.751277,-0.754 1.779339,-0.754 l 35.428602,0 q 1.028063,0 1.779339,0.754 0.751275,0.7539 0.751275,1.7857 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="document_open.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="8.0642339"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -86,19 +86,15 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
id="g4152"
|
||||
transform="translate(95.31562,26.03569)">
|
||||
<path
|
||||
style="fill:#3027dd;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 29.929313,974.80653 c -1.587443,-2.02757 -4.087204,-3.04531 -6.685793,-3.04531 l -92.131013,0 c -4.627058,0 -8.133024,2.79574 -9.368384,7.20513 0,0 0,-0.16617 0,-0.16556 l -12.79591,46.52571 107.224081,0 c 2.205125,0 4.135382,-1.6265 4.694385,-3.7283 L 31.41175,981.98368 c 0.659685,-2.4768 0.105624,-5.14959 -1.482437,-7.17715 z"
|
||||
id="path6-6" />
|
||||
<path
|
||||
style="fill:#1c168e;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -68.887493,967.50035 16.838636,0 3.520788,0 2.391666,0 0,-60.52687 c 0,-2.32704 3.251479,-2.16878 3.657297,-2.16878 l 42.3242049,0 c 1.229805,0.6087 1.580031,0.36096 1.580031,1.59235 l 0,8.90765 c 0,2.83531 2.821573,6.54348 5.737033,6.54348 l 7.4387471,0 c 1.361372,0 2.266276,-0.39322 2.266276,1.14922 l 0,44.50295 4.941458,0 0,-47.44478 c 0,-1.92165 -0.195187,-4.36922 -2.031557,-6.2513 L 7.6871929,901.62609 c -1.597326,-1.63739 -3.665944,-2.29965 -6.366451,-2.29965 l -43.7998479,0 c -4.601733,0 -9.216437,2.75861 -9.216437,7.64704 l 0,31.42757 c -4.323776,-0.5387 -8.42951,-1.9107 -10.14852,-6.02791 -1.030294,-2.46887 -3.200211,-4.438 -5.909366,-4.438 l -21.052468,0 c -2.92163,0 -5.509723,2.26861 -5.509723,5.14774 l 0,7.03104 0,1.13583 0,76.97325 10.921863,-40.15873 c 1.71777,-6.44122 7.748202,-10.56392 14.506264,-10.56392 z"
|
||||
id="path8" />
|
||||
</g>
|
||||
<path
|
||||
id="path6-6"
|
||||
d="m 125.24493,1000.8422 c -1.58744,-2.02755 -4.0872,-3.04529 -6.68579,-3.04529 H 26.428127 c -4.627058,0 -8.133024,2.79579 -9.368384,7.20509 0,0 0,-0.1661 0,-0.1655 l -12.79591,46.5257 H 111.48791 c 2.20513,0 4.13539,-1.6265 4.69439,-3.7283 l 10.54507,-39.6145 c 0.65969,-2.4768 0.10562,-5.1496 -1.48244,-7.1772 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#3027dd;fill-opacity:1" />
|
||||
<path
|
||||
id="path8"
|
||||
d="m 26.428127,993.53604 h 16.838636 3.520788 2.391666 v -60.52687 c 0,-2.32704 3.251479,-2.16878 3.657297,-2.16878 h 42.324205 c 1.229805,0.6087 1.580031,0.36096 1.580031,1.59235 v 8.90765 c 0,2.83531 2.821573,6.54348 5.73703,6.54348 h 7.43875 c 1.36137,0 2.26628,-0.39322 2.26628,1.14922 v 44.50295 h 4.94145 v -47.44478 c 0,-1.92165 -0.19518,-4.36922 -2.03155,-6.2513 l -12.0899,-12.17818 c -1.59732,-1.63739 -3.665941,-2.29965 -6.366448,-2.29965 H 52.836514 c -4.601733,0 -9.216437,2.75861 -9.216437,7.64704 v 31.42757 c -4.323776,-0.5387 -8.42951,-1.9107 -10.14852,-6.02791 -1.030294,-2.46887 -3.200211,-4.438 -5.909366,-4.438 H 6.509723 C 3.588093,953.97083 1,956.23944 1,959.11857 v 7.03104 1.13583 76.97326 L 11.921863,1004.1 c 1.71777,-6.44126 7.748202,-10.56396 14.506264,-10.56396 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.0 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="edit-clear.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -71,17 +71,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="30.132813"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -144,7 +144,7 @@
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssscc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:4.02708244;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#2271d5;stroke-width:4.02708244;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 9.6415558,1036.8579 83.8879072,0"
|
||||
id="path4223"
|
||||
inkscape:connector-curvature="0" />
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="edit-cut.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="-38.266034"
|
||||
inkscape:zoom="5.656854"
|
||||
inkscape:cx="102.11588"
|
||||
inkscape:cy="95.08399"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -94,7 +94,7 @@
|
||||
d="m 68.495532,983.86336 q 1.82763,0 3.1632,1.3356 1.33557,1.3356 1.33557,3.1632 0,1.8276 -1.33557,3.1632 -1.33557,1.3356 -3.1632,1.3356 -1.82763,0 -3.1632,-1.3356 -1.33557,-1.3356 -1.33557,-3.1632 0,-1.8276 1.33557,-3.1632 1.33557,-1.3356 3.1632,-1.3356 z m 21.088,4.4988 35.638728,27.97674 q 1.96821,1.4059 1.75733,3.9365 -0.35146,2.4602 -2.46026,3.5849 l -8.99755,4.4988 q -0.91382,0.4921 -2.03851,0.4921 -1.19499,0 -2.17909,-0.5624 l -48.502408,-27.2035 -7.73227,4.6393 q -0.56234,0.2812 -0.84352,0.3515 0.98411,3.4444 0.70294,6.8185 -0.49206,5.4126 -3.93643,10.3682 -3.44438,4.9557 -9.27872,8.6813 -9.27873,5.9046 -19.47126,5.9046 -9.5599,0 -15.6051202,-5.4829 -6.32639997,-5.9046 -5.55318,-14.5507 0.49206,-5.3423 3.93643,-10.3331 3.44437,-4.9909 9.2084302,-8.71644 9.27872,-5.9046 19.54155,-5.9046 5.83435,0 10.61429,2.1791 0.63264,-0.9139 1.54646,-1.5465 l 8.57579,-5.1314 -8.57579,-5.1314 q -0.91382,-0.6327 -1.54646,-1.5465 -4.77994,2.1791 -10.61429,2.1791 -10.26283,0 -19.54155,-5.9046 -5.7640602,-3.7256 -9.2084302,-8.7164 -3.44437,-4.9908 -3.93643,-10.3331 -0.35145997,-4.1473 1.08955,-7.9432 1.44101,-3.7958 4.46363,-6.5373 5.9749302,-5.5531 15.6051202,-5.5531 10.19253,0 19.47126,5.9046 5.83434,3.6553 9.27872,8.6461 3.44437,4.9908 3.93643,10.4034 0.28117,3.3741 -0.70294,6.8185 0.28118,0.07 0.84352,0.3514 l 7.73227,4.6394 48.502408,-27.2035 q 0.9841,-0.5624 2.17909,-0.5624 1.12469,0 2.03851,0.4921 l 8.99755,4.4987 q 2.1088,1.1247 2.46026,3.585 0.21088,2.5306 -1.75733,3.9364 z m -47.86976,-18.2763 q 3.23349,-2.9523 1.47616,-7.5917 -1.75734,-4.6393 -7.4511,-8.2243 -6.46699,-4.1473 -13.49632,-4.1473 -5.20171,0 -7.94315,2.5306 -3.23349,2.9523 -1.47616,7.5916 1.75734,4.6394 7.4511,8.2244 6.46698,4.1473 13.49632,4.1473 5.20171,0 7.94315,-2.5306 z m -5.97494,52.36864 q 5.69376,-3.585 7.4511,-8.2244 1.75733,-4.6393 -1.47616,-7.5916 -2.74144,-2.5306 -7.94315,-2.5306 -7.02934,0 -13.49632,4.1473 -5.69376,3.585 -7.4511,8.2243 -1.75733,4.6394 1.47616,7.5917 2.74144,2.5306 7.94315,2.5306 7.02933,0 13.49632,-4.1473 z m 12.51222,-43.08994 6.74816,4.0771 0,-0.7733 q 0,-2.5305 2.31968,-3.9364 l 0.98411,-0.5623 -5.55318,-3.3038 -1.82763,1.8276 q -0.21088,0.2109 -0.70293,0.7732 -0.49205,0.5624 -0.84352,0.8435 -0.14059,0.1406 -0.28117,0.2461 -0.14059,0.1054 -0.21088,0.1757 z m 15.74571,15.7457 6.74816,2.2494 51.735898,-40.4889 -8.99755,-4.4988 -53.985288,30.2964 0,7.9432 -11.24693,6.7481 0.63264,0.5624 q 0.14058,0.1406 0.49205,0.4217 0.28117,0.2812 0.77323,0.8436 0.49205,0.5623 0.77322,0.84354 l 1.82763,1.8276 z m 49.486508,29.24214 8.99755,-4.4988 -36.552538,-28.67974 -12.44192,9.70054 q -0.14059,0.2109 -0.91382,0.4921 z"
|
||||
id="path4-3"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#160a02;fill-opacity:1" />
|
||||
style="fill:#888888;fill-opacity:1" />
|
||||
<path
|
||||
style="fill:#ea8404;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="edit-paste.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -69,17 +69,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -135,7 +135,7 @@
|
||||
d="m 55,1897.4872 63,0 0,-45 -29.25,0 q -2.8125,0 -4.78125,-1.9687 Q 82,1848.5497 82,1845.7372 l 0,-29.25 -27,0 0,81 z m 18,-101.25 0,-4.5 q 0,-0.9141 -0.66797,-1.582 -0.66797,-0.668 -1.58203,-0.668 l -49.5,0 q -0.91406,0 -1.58203,0.668 Q 19,1790.8231 19,1791.7372 l 0,4.5 q 0,0.9141 0.66797,1.582 0.66797,0.668 1.58203,0.668 l 49.5,0 q 0.91406,0 1.58203,-0.668 Q 73,1797.1513 73,1796.2372 Z m 18,47.25 21.02344,0 L 91,1822.4638 l 0,21.0234 z m 36,9 0,47.25 q 0,2.8125 -1.96875,4.7813 -1.96875,1.9687 -4.78125,1.9687 l -67.5,0 q -2.8125,0 -4.78125,-1.9687 Q 46,1902.5497 46,1899.7372 l 0,-11.25 -38.25,0 q -2.8125,0 -4.78125,-1.9687 Q 1,1884.5497 1,1881.7372 l 0,-94.5 q 0,-2.8125 1.96875,-4.7813 1.96875,-1.9687 4.78125,-1.9687 l 76.5,0 q 2.8125,0 4.78125,1.9687 Q 91,1784.4247 91,1787.2372 l 0,23.0625 q 1.47656,0.9141 2.53125,1.9687 l 28.6875,28.6875 q 1.96875,1.9688 3.375,5.3438 1.40625,3.375 1.40625,6.1875 z"
|
||||
id="path4" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3c3c3c;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 35.477134,925.36215 -4.081555,12.29269 34.477134,0 -4.081555,-12.29269 -26.314024,0 z"
|
||||
id="path4162" />
|
||||
<path
|
||||
@ -147,7 +147,7 @@
|
||||
d="m 53.243902,968.38655 0,82.97565 67.609758,0 0,-55.31712 -24.585367,0 a 3.0734781,3.0734781 0 0 1 -3.07317,-3.07317 l 0,-24.58536 -39.951221,0 z"
|
||||
id="path4158" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3c3c3c;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#686868;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 99.341464,968.38655 0,21.51219 21.512196,0 -21.512196,-21.51219 z"
|
||||
id="path6" />
|
||||
</g>
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.9 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="edit-select-all.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4142">
|
||||
<stop
|
||||
style="stop-color:#545ada;stop-opacity:1;"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4144" />
|
||||
<stop
|
||||
style="stop-color:#23289f;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4146" />
|
||||
</linearGradient>
|
||||
@ -48,17 +48,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -115,7 +115,7 @@
|
||||
id="path4"
|
||||
style="fill:url(#linearGradient4148);fill-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#30a82d;stroke-width:3.94074321;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.94074312, 11.82222935;stroke-dashoffset:0;stroke-opacity:1"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#2caf45;stroke-width:3.94074321;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:3.94074312, 11.82222935000000064;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 2.970371,927.33253 122.059259,0 0,122.05927 -122.059259,0 z"
|
||||
id="rect4139"
|
||||
inkscape:connector-curvature="0" />
|
||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="edit_input.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="-10.424833"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -105,29 +105,28 @@
|
||||
transform="matrix(1.4835039,0,0,1.4904899,-11.62087,914.96969)"
|
||||
style="fill-opacity:1;fill:#ea8404" />
|
||||
</g>
|
||||
<path
|
||||
id="path12"
|
||||
d="m 112.20127,973.84851 v 64.10449 c 0,4.9186 -4.00546,8.9429 -8.90103,8.9429 H 14.356767 c -4.8955631,0 -8.9010236,-4.0243 -8.9010236,-8.9429 v -88.94052 c 0,-4.91862 4.0054605,-8.94294 8.9010236,-8.94294 h 64.643682"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;fill-opacity:1;stroke:#2271d5;stroke-width:8.92195702;stroke-opacity:1" />
|
||||
<g
|
||||
transform="matrix(1.4835039,0,0,1.4904899,-11.62087,914.96969)"
|
||||
id="g10"
|
||||
style="fill:none;fill-opacity:1;stroke:#3244c4;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:none;stroke:#3244c4;stroke-width:6;fill-opacity:1;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 83.466,39.503 0,43.009 c 0,3.3 -2.7,6 -6,6 l -59.955,0 c -3.3,0 -6,-2.7 -6,-6 l 0,-59.672 c 0,-3.3 2.7,-6 6,-6 l 43.575,0"
|
||||
id="path12" />
|
||||
id="g823"
|
||||
style="stroke:#2caf45;stroke-opacity:1">
|
||||
<line
|
||||
id="line14"
|
||||
y2="1018.5588"
|
||||
x2="92.966148"
|
||||
y1="1018.5588"
|
||||
x1="24.724976"
|
||||
style="fill:none;stroke:#2caf45;stroke-width:4.46097851;stroke-opacity:1" />
|
||||
<line
|
||||
id="line16"
|
||||
y2="1030.4828"
|
||||
x2="92.966148"
|
||||
y1="1030.4828"
|
||||
x1="24.724976"
|
||||
style="fill:none;stroke:#2caf45;stroke-width:4.46097851;stroke-opacity:1" />
|
||||
</g>
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:4.46097851"
|
||||
x1="24.724976"
|
||||
y1="1018.5588"
|
||||
x2="92.966148"
|
||||
y2="1018.5588"
|
||||
id="line14" />
|
||||
<line
|
||||
style="fill:none;stroke:#000000;stroke-width:4.46097851"
|
||||
x1="24.724976"
|
||||
y1="1030.4828"
|
||||
x2="92.966148"
|
||||
y2="1030.4828"
|
||||
id="line16" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.3 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,45 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="embed-fonts.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4142">
|
||||
<stop
|
||||
style="stop-color:#34ae3d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4144" />
|
||||
<stop
|
||||
style="stop-color:#26822e;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4146" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4142"
|
||||
id="radialGradient4153"
|
||||
cx="-66.893486"
|
||||
cy="971.11334"
|
||||
fx="-66.893486"
|
||||
fy="971.11334"
|
||||
r="3.9624026"
|
||||
gradientTransform="matrix(1,0,0,1.2615541,0,-253.99865)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4142"
|
||||
id="radialGradient4155"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.2615541,0,-253.99865)"
|
||||
cx="-66.893486"
|
||||
cy="971.11334"
|
||||
fx="-66.893486"
|
||||
fy="971.11334"
|
||||
r="3.9624026" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -61,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="6.1653019"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -125,25 +89,25 @@
|
||||
<g
|
||||
transform="matrix(1.3939367,0,0,1.3695651,-5.6968353,-384.43812)"
|
||||
id="g4"
|
||||
style="fill:#3027dd;fill-opacity:1">
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 20.000054,956.3622 c -1.94862,0.01 -3.01295,1.69 -3,3 l 0,86 c 1.6e-4,1.5708 1.42925,2.9998 3,3 l 60,0 c 1.57075,-2e-4 2.99984,-1.4292 3,-3 l 0,-70 c 0.002,-0.7861 -0.32012,-1.5681 -0.875,-2.125 l -16,-16 c -0.55685,-0.5549 -1.33889,-0.8769 -2.125,-0.875 l -44,0 z m 3,6 38,0 0,13 a 3.0003,3.0003 0 0 0 3,3 l 13,0 0,64 -54,0 0,-80 z m 44,4.2188 5.78125,5.7812 -5.78125,0 0,-5.7812 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
id="path6" />
|
||||
</g>
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Cambria;-inkscape-font-specification:Cambria;letter-spacing:0px;word-spacing:0px;fill:url(#radialGradient4153);fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Cambria;-inkscape-font-specification:Cambria;letter-spacing:0px;word-spacing:0px;fill:#2caf45;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4140"
|
||||
transform="matrix(5.8045592,0,0,5.6013611,452.2872,-4439.1944)">
|
||||
<path
|
||||
d="m -70.855888,966.11462 7.924804,0 0,2.54883 -0.717773,0 q -0.161133,-0.62988 -0.322266,-0.99609 -0.153808,-0.36621 -0.32959,-0.55664 -0.175781,-0.19043 -0.380859,-0.271 -0.197754,-0.0806 -0.600586,-0.0806 l -0.930176,0 0,7.5 q 0,0.43212 0.04395,0.68847 0.05127,0.25635 0.146484,0.41016 0.102539,0.14648 0.270996,0.23437 0.168457,0.0806 0.527344,0.16114 l 0,0.35888 -3.347168,0 0,-0.35888 q 0.219726,-0.0513 0.388183,-0.10987 0.168458,-0.0586 0.270997,-0.13916 0.109863,-0.0879 0.175781,-0.21972 0.07324,-0.13184 0.109863,-0.35889 0.04394,-0.22705 0.04394,-0.6665 l 0,-7.5 -0.922851,0 q -0.344238,0 -0.571289,0.0659 -0.219727,0.0659 -0.410156,0.27832 -0.19043,0.20508 -0.351563,0.59327 -0.153809,0.38085 -0.292969,0.96679 l -0.725097,0 0,-2.54883 z"
|
||||
id="path4145"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#radialGradient4155);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 4.9 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="folder_saved_search.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="68.276786"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -95,11 +95,11 @@
|
||||
id="path8"
|
||||
d="m 26.428127,993.53604 16.838636,0 3.520788,0 2.391666,0 0,-60.52687 c 0,-2.32704 3.251479,-2.16878 3.657297,-2.16878 l 42.324205,0 c 1.229805,0.6087 1.580031,0.36096 1.580031,1.59235 l 0,8.90765 c 0,2.83531 2.821573,6.54348 5.73703,6.54348 l 7.43875,0 c 1.36137,0 2.26628,-0.39322 2.26628,1.14922 l 0,44.50295 4.94145,0 0,-47.44478 c 0,-1.92165 -0.19518,-4.36922 -2.03155,-6.2513 l -12.0899,-12.17818 c -1.59732,-1.63739 -3.665941,-2.29965 -6.366448,-2.29965 l -43.799848,0 c -4.601733,0 -9.216437,2.75861 -9.216437,7.64704 l 0,31.42757 c -4.323776,-0.5387 -8.42951,-1.9107 -10.14852,-6.02791 -1.030294,-2.46887 -3.200211,-4.438 -5.909366,-4.438 l -21.052468,0 C 3.588093,953.97083 1,956.23944 1,959.11857 l 0,7.03104 0,1.13583 0,76.97326 10.921863,-40.1587 c 1.71777,-6.44126 7.748202,-10.56396 14.506264,-10.56396 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#1c168e;fill-opacity:1" />
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 95.489615,975.4847 -11.935263,-9.67724 c -0.430099,-0.32257 -0.645149,-0.96772 -0.322574,-1.50535 2.365547,-5.05367 1.505348,-11.18259 -2.688123,-15.37606 -5.591294,-5.59129 -15.053484,-5.26872 -20.214679,1.18278 -3.870896,4.83862 -3.870896,11.82773 -0.107524,16.77388 4.085945,5.16119 10.967538,6.45149 16.451307,3.8709 0.537625,-0.21505 1.075249,-0.10753 1.505349,0.32257 l 9.67724,11.93524 c 1.505348,1.82792 4.193471,1.93545 5.806344,0.32258 l 2.258023,-2.25803 c 1.505348,-1.3978 1.397823,-4.08592 -0.4301,-5.59127 z m -17.311507,-9.56971 c -3.978421,3.97842 -10.537439,3.97842 -14.623385,0 -3.978421,-3.97843 -3.978421,-10.53744 0,-14.62339 3.978421,-4.08594 10.537439,-3.97842 14.623385,0 4.085946,4.08595 4.085946,10.64496 0,14.62339 z"
|
||||
id="path6"
|
||||
style="fill:#261fb5;fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
@ -15,8 +15,9 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="font.svg">
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="font.svg"
|
||||
enable-background="new">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
@ -72,6 +73,16 @@
|
||||
result="composite2"
|
||||
id="feComposite4298" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter1038">
|
||||
<feBlend
|
||||
inkscape:collect="always"
|
||||
mode="overlay"
|
||||
in2="BackgroundImage"
|
||||
id="feBlend1040" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@ -80,17 +91,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="-12.10305"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -163,22 +174,22 @@
|
||||
id="polyline14" />
|
||||
<g
|
||||
id="g4167"
|
||||
style="fill:#6d0b0b;fill-opacity:1;filter:url(#filter4288)">
|
||||
style="fill:#dd8808;fill-opacity:1;filter:url(#filter1038)">
|
||||
<path
|
||||
id="path4"
|
||||
d="m 17.470144,999.2509 -7.005639,0 0,-4.98468 20.050489,0 0,4.98468 -7.12241,0 0,21.2627 -5.92244,0 0,-21.2627 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#6d0b0b;fill-opacity:1" />
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path6"
|
||||
d="m 58.629806,994.26622 15.947361,0 0,4.86785 -10.024922,0 0,5.99723 9.367518,0 0,4.8276 -9.367518,0 0,10.5541 -5.922439,0 0,-26.24678 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#6d0b0b;fill-opacity:1" />
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
<path
|
||||
id="path16"
|
||||
d="m 41.341832,999.2509 -7.005639,0 0,-4.98468 20.050488,0 0,4.98468 -7.12241,0 0,21.2627 -5.922439,0 0,-21.2627 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#6d0b0b;fill-opacity:1" />
|
||||
style="fill:#dd8808;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.5 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="font_size_larger.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -113,17 +113,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="47.159598"
|
||||
inkscape:cy="72.481885"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -174,30 +174,34 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#261fb5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
id="text4133"
|
||||
transform="matrix(1.4074832,0,0,1.4146743,-44.275876,-351.59006)">
|
||||
<path
|
||||
d="m 121.33301,973.61005 q 0.35156,0.96679 0.35156,1.58203 0.044,0.57129 -0.30762,0.8789 -0.35156,0.30762 -1.18652,0.39551 -0.79102,0.0879 -2.15332,0.0879 -1.36231,0 -2.19727,-0.0879 -0.79101,-0.0439 -1.23046,-0.17578 -0.39551,-0.17578 -0.61524,-0.43945 -0.17578,-0.26367 -0.35156,-0.65918 l -4.87793,-13.84278 -23.64258,0 -4.658203,13.667 q -0.131836,0.3955 -0.351562,0.70312 -0.219727,0.26367 -0.65918,0.4834 -0.395508,0.17578 -1.186523,0.26367 -0.747071,0.0879 -1.97754,0.0879 -1.274414,0 -2.109375,-0.13183 -0.791015,-0.0879 -1.142578,-0.39551 -0.307617,-0.30762 -0.307617,-0.87891 0.04395,-0.61523 0.395508,-1.58203 l 19.072266,-52.82226 q 0.175781,-0.4834 0.439453,-0.79102 0.307617,-0.30762 0.834961,-0.4834 0.571289,-0.17578 1.40625,-0.21973 0.878906,-0.0879 2.197265,-0.0879 1.40625,0 2.329102,0.0879 0.922853,0.0439 1.494143,0.21973 0.57129,0.17578 0.8789,0.52735 0.30762,0.30761 0.4834,0.79101 l 19.07227,52.82227 z m -24.477541,-46.62598 -0.04395,0 -9.799804,28.34473 19.775395,0 -9.931645,-28.34473 z"
|
||||
id="path4140"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#261fb5;fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
d="M 2.3203367,970.6888 32.772366,939.97452 C 33.614358,939.11738 34.737013,938.6888 36,938.6888 c 1.262988,0 2.385643,0.42858 3.227635,1.28572 l 30.452029,30.71428 c 1.262987,1.28572 1.683983,3.28572 0.982323,5.14286 -0.70166,1.71428 -2.385643,2.85714 -4.209958,2.85714 l -60.9040579,0 c -1.8243151,0 -3.5082982,-1.14286 -4.2099579,-2.85714 -0.70165963,-1.71429 -0.2806639,-3.71429 0.9823235,-5.14286 z"
|
||||
id="path4145"
|
||||
style="fill:url(#linearGradient4149);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#261fb5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
id="text4151"
|
||||
transform="matrix(4.0418484,0,0,4.0418484,-38.501788,-3022.6663)">
|
||||
<path
|
||||
d="m 22.196219,1002.0939 q 0.05859,0.1612 0.05859,0.2637 0.0073,0.095 -0.05127,0.1465 -0.05859,0.051 -0.197754,0.066 -0.131836,0.015 -0.358887,0.015 -0.227051,0 -0.366211,-0.015 -0.131836,-0.01 -0.205078,-0.029 -0.06592,-0.029 -0.102539,-0.073 -0.0293,-0.044 -0.05859,-0.1099 l -0.812988,-2.3071 -3.94043,0 -0.776367,2.2778 q -0.02197,0.066 -0.05859,0.1172 -0.03662,0.044 -0.109863,0.081 -0.06592,0.029 -0.197754,0.044 -0.124512,0.015 -0.32959,0.015 -0.212402,0 -0.351562,-0.022 -0.131836,-0.015 -0.19043,-0.066 -0.05127,-0.051 -0.05127,-0.1465 0.0073,-0.1026 0.06592,-0.2637 l 3.178711,-8.8037 q 0.0293,-0.0806 0.07324,-0.13184 0.05127,-0.0513 0.13916,-0.0806 0.09521,-0.0293 0.234375,-0.0366 0.146484,-0.0146 0.366211,-0.0146 0.234375,0 0.388183,0.0146 0.153809,0.007 0.249024,0.0366 0.09521,0.0293 0.146484,0.0879 0.05127,0.0513 0.08057,0.13183 l 3.17871,8.80371 z m -4.079589,-7.77096 -0.0073,0 -1.6333,4.72412 3.295898,0 -1.655273,-4.72412 z"
|
||||
id="path4156"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#261fb5;fill-opacity:1" />
|
||||
id="g837"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<g
|
||||
transform="matrix(1.4074832,0,0,1.4146743,-44.275876,-351.59006)"
|
||||
id="text4133"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#2271d5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4140"
|
||||
d="m 121.33301,973.61005 q 0.35156,0.96679 0.35156,1.58203 0.044,0.57129 -0.30762,0.8789 -0.35156,0.30762 -1.18652,0.39551 -0.79102,0.0879 -2.15332,0.0879 -1.36231,0 -2.19727,-0.0879 -0.79101,-0.0439 -1.23046,-0.17578 -0.39551,-0.17578 -0.61524,-0.43945 -0.17578,-0.26367 -0.35156,-0.65918 l -4.87793,-13.84278 -23.64258,0 -4.658203,13.667 q -0.131836,0.3955 -0.351562,0.70312 -0.219727,0.26367 -0.65918,0.4834 -0.395508,0.17578 -1.186523,0.26367 -0.747071,0.0879 -1.97754,0.0879 -1.274414,0 -2.109375,-0.13183 -0.791015,-0.0879 -1.142578,-0.39551 -0.307617,-0.30762 -0.307617,-0.87891 0.04395,-0.61523 0.395508,-1.58203 l 19.072266,-52.82226 q 0.175781,-0.4834 0.439453,-0.79102 0.307617,-0.30762 0.834961,-0.4834 0.571289,-0.17578 1.40625,-0.21973 0.878906,-0.0879 2.197265,-0.0879 1.40625,0 2.329102,0.0879 0.922853,0.0439 1.494143,0.21973 0.57129,0.17578 0.8789,0.52735 0.30762,0.30761 0.4834,0.79101 l 19.07227,52.82227 z m -24.477541,-46.62598 -0.04395,0 -9.799804,28.34473 19.775395,0 -9.931645,-28.34473 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(4.0418484,0,0,4.0418484,-38.501788,-3022.6663)"
|
||||
id="text4151"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#2271d5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4156"
|
||||
d="m 22.196219,1002.0939 q 0.05859,0.1612 0.05859,0.2637 0.0073,0.095 -0.05127,0.1465 -0.05859,0.051 -0.197754,0.066 -0.131836,0.015 -0.358887,0.015 -0.227051,0 -0.366211,-0.015 -0.131836,-0.01 -0.205078,-0.029 -0.06592,-0.029 -0.102539,-0.073 -0.0293,-0.044 -0.05859,-0.1099 l -0.812988,-2.3071 -3.94043,0 -0.776367,2.2778 q -0.02197,0.066 -0.05859,0.1172 -0.03662,0.044 -0.109863,0.081 -0.06592,0.029 -0.197754,0.044 -0.124512,0.015 -0.32959,0.015 -0.212402,0 -0.351562,-0.022 -0.131836,-0.015 -0.19043,-0.066 -0.05127,-0.051 -0.05127,-0.1465 0.0073,-0.1026 0.06592,-0.2637 l 3.178711,-8.8037 q 0.0293,-0.0806 0.07324,-0.13184 0.05127,-0.0513 0.13916,-0.0806 0.09521,-0.0293 0.234375,-0.0366 0.146484,-0.0146 0.366211,-0.0146 0.234375,0 0.388183,0.0146 0.153809,0.007 0.249024,0.0366 0.09521,0.0293 0.146484,0.0879 0.05127,0.0513 0.08057,0.13183 l 3.17871,8.80371 z m -4.079589,-7.77096 -0.0073,0 -1.6333,4.72412 3.295898,0 -1.655273,-4.72412 z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.7 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="font_size_smaller.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -113,17 +113,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="16.891741"
|
||||
inkscape:cy="72.481885"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -177,27 +177,31 @@
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#261fb5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
id="text4133"
|
||||
transform="matrix(1.4074832,0,0,1.4146743,-44.275876,-351.59006)">
|
||||
<path
|
||||
d="m 121.33301,973.61005 q 0.35156,0.96679 0.35156,1.58203 0.044,0.57129 -0.30762,0.8789 -0.35156,0.30762 -1.18652,0.39551 -0.79102,0.0879 -2.15332,0.0879 -1.36231,0 -2.19727,-0.0879 -0.79101,-0.0439 -1.23046,-0.17578 -0.39551,-0.17578 -0.61524,-0.43945 -0.17578,-0.26367 -0.35156,-0.65918 l -4.87793,-13.84278 -23.64258,0 -4.658203,13.667 q -0.131836,0.3955 -0.351562,0.70312 -0.219727,0.26367 -0.65918,0.4834 -0.395508,0.17578 -1.186523,0.26367 -0.747071,0.0879 -1.97754,0.0879 -1.274414,0 -2.109375,-0.13183 -0.791015,-0.0879 -1.142578,-0.39551 -0.307617,-0.30762 -0.307617,-0.87891 0.04395,-0.61523 0.395508,-1.58203 l 19.072266,-52.82226 q 0.175781,-0.4834 0.439453,-0.79102 0.307617,-0.30762 0.834961,-0.4834 0.571289,-0.17578 1.40625,-0.21973 0.878906,-0.0879 2.197265,-0.0879 1.40625,0 2.329102,0.0879 0.922853,0.0439 1.494143,0.21973 0.57129,0.17578 0.8789,0.52735 0.30762,0.30761 0.4834,0.79101 l 19.07227,52.82227 z m -24.477541,-46.62598 -0.04395,0 -9.799804,28.34473 19.775395,0 -9.931645,-28.34473 z"
|
||||
id="path4140"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#261fb5;fill-opacity:1" />
|
||||
</g>
|
||||
transform="matrix(1.4074832,0,0,1.4146743,-44.275876,-351.59006)" />
|
||||
<path
|
||||
d="m 2.3203367,946.6888 30.4520293,30.71428 c 0.841992,0.85714 1.964647,1.28572 3.227634,1.28572 1.262988,0 2.385643,-0.42858 3.227635,-1.28572 L 69.679664,946.6888 c 1.262987,-1.28572 1.683983,-3.28572 0.982323,-5.14286 -0.70166,-1.71428 -2.385643,-2.85714 -4.209958,-2.85714 l -60.9040579,0 c -1.8243151,0 -3.5082982,1.14286 -4.2099579,2.85714 -0.70165963,1.71429 -0.2806639,3.71429 0.9823235,5.14286 z"
|
||||
id="path4145"
|
||||
style="fill:url(#linearGradient4149);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#261fb5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
id="text4151"
|
||||
transform="matrix(4.0418484,0,0,4.0418484,-38.501788,-3022.6663)">
|
||||
id="g837"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
d="m 22.196219,1002.0939 q 0.05859,0.1612 0.05859,0.2637 0.0073,0.095 -0.05127,0.1465 -0.05859,0.051 -0.197754,0.066 -0.131836,0.015 -0.358887,0.015 -0.227051,0 -0.366211,-0.015 -0.131836,-0.01 -0.205078,-0.029 -0.06592,-0.029 -0.102539,-0.073 -0.0293,-0.044 -0.05859,-0.1099 l -0.812988,-2.3071 -3.94043,0 -0.776367,2.2778 q -0.02197,0.066 -0.05859,0.1172 -0.03662,0.044 -0.109863,0.081 -0.06592,0.029 -0.197754,0.044 -0.124512,0.015 -0.32959,0.015 -0.212402,0 -0.351562,-0.022 -0.131836,-0.015 -0.19043,-0.066 -0.05127,-0.051 -0.05127,-0.1465 0.0073,-0.1026 0.06592,-0.2637 l 3.178711,-8.8037 q 0.0293,-0.0806 0.07324,-0.13184 0.05127,-0.0513 0.13916,-0.0806 0.09521,-0.0293 0.234375,-0.0366 0.146484,-0.0146 0.366211,-0.0146 0.234375,0 0.388183,0.0146 0.153809,0.007 0.249024,0.0366 0.09521,0.0293 0.146484,0.0879 0.05127,0.0513 0.08057,0.13183 l 3.17871,8.80371 z m -4.079589,-7.77096 -0.0073,0 -1.6333,4.72412 3.295898,0 -1.655273,-4.72412 z"
|
||||
id="path4156"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#2271d5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#261fb5;fill-opacity:1" />
|
||||
id="path4140"
|
||||
d="m 121.33301,973.61005 q 0.35156,0.96679 0.35156,1.58203 0.044,0.57129 -0.30762,0.8789 -0.35156,0.30762 -1.18652,0.39551 -0.79102,0.0879 -2.15332,0.0879 -1.36231,0 -2.19727,-0.0879 -0.79101,-0.0439 -1.23046,-0.17578 -0.39551,-0.17578 -0.61524,-0.43945 -0.17578,-0.26367 -0.35156,-0.65918 l -4.87793,-13.84278 -23.64258,0 -4.658203,13.667 q -0.131836,0.3955 -0.351562,0.70312 -0.219727,0.26367 -0.65918,0.4834 -0.395508,0.17578 -1.186523,0.26367 -0.747071,0.0879 -1.97754,0.0879 -1.274414,0 -2.109375,-0.13183 -0.791015,-0.0879 -1.142578,-0.39551 -0.307617,-0.30762 -0.307617,-0.87891 0.04395,-0.61523 0.395508,-1.58203 l 19.072266,-52.82226 q 0.175781,-0.4834 0.439453,-0.79102 0.307617,-0.30762 0.834961,-0.4834 0.571289,-0.17578 1.40625,-0.21973 0.878906,-0.0879 2.197265,-0.0879 1.40625,0 2.329102,0.0879 0.922853,0.0439 1.494143,0.21973 0.57129,0.17578 0.8789,0.52735 0.30762,0.30761 0.4834,0.79101 l 19.07227,52.82227 z m -24.477541,-46.62598 -0.04395,0 -9.799804,28.34473 19.775395,0 -9.931645,-28.34473 z"
|
||||
transform="matrix(1.4074832,0,0,1.4146743,-44.275876,-351.59004)" />
|
||||
<g
|
||||
transform="matrix(4.0418484,0,0,4.0418484,-38.501788,-3022.6663)"
|
||||
id="text4151"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Calibri;-inkscape-font-specification:Calibri;letter-spacing:0px;word-spacing:0px;fill:#2271d5;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4156"
|
||||
d="m 22.196219,1002.0939 q 0.05859,0.1612 0.05859,0.2637 0.0073,0.095 -0.05127,0.1465 -0.05859,0.051 -0.197754,0.066 -0.131836,0.015 -0.358887,0.015 -0.227051,0 -0.366211,-0.015 -0.131836,-0.01 -0.205078,-0.029 -0.06592,-0.029 -0.102539,-0.073 -0.0293,-0.044 -0.05859,-0.1099 l -0.812988,-2.3071 -3.94043,0 -0.776367,2.2778 q -0.02197,0.066 -0.05859,0.1172 -0.03662,0.044 -0.109863,0.081 -0.06592,0.029 -0.197754,0.044 -0.124512,0.015 -0.32959,0.015 -0.212402,0 -0.351562,-0.022 -0.131836,-0.015 -0.19043,-0.066 -0.05127,-0.051 -0.05127,-0.1465 0.0073,-0.1026 0.06592,-0.2637 l 3.178711,-8.8037 q 0.0293,-0.0806 0.07324,-0.13184 0.05127,-0.0513 0.13916,-0.0806 0.09521,-0.0293 0.234375,-0.0366 0.146484,-0.0146 0.366211,-0.0146 0.234375,0 0.388183,0.0146 0.153809,0.007 0.249024,0.0366 0.09521,0.0293 0.146484,0.0879 0.05127,0.0513 0.08057,0.13183 l 3.17871,8.80371 z m -4.079589,-7.77096 -0.0073,0 -1.6333,4.72412 3.295898,0 -1.655273,-4.72412 z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 9.0 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-fill-color.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -86,51 +86,47 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
transform="translate(0.00260059,0.00376367)"
|
||||
id="g4140">
|
||||
<path
|
||||
id="path4"
|
||||
d="m 40.013479,999.06915 c 6.359757,4.67475 20.124993,-3.15171 30.748644,-17.46631 l 33.295197,33.61766 c -10.626597,14.3161 -20.771572,17.651 -27.134275,12.9792"
|
||||
stroke-miterlimit="10"
|
||||
style="fill:#bc3e4c;fill-opacity:1;stroke:#000000;stroke-width:4.40812302;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0" />
|
||||
<ellipse
|
||||
id="ellipse6"
|
||||
ry="32.282364"
|
||||
rx="14.290408"
|
||||
cy="-748.86212"
|
||||
cx="-616.16022"
|
||||
stroke-miterlimit="10"
|
||||
transform="matrix(-0.8058623,-0.592103,0.59573364,-0.80318206,0,0)"
|
||||
style="fill:none;stroke:#000000;stroke-width:4.40800762;stroke-miterlimit:10" />
|
||||
<path
|
||||
id="path8"
|
||||
d="m 85.46409,977.45432 c 3.178405,-2.48472 6.266967,-5.64375 9.022665,-9.36276 0.785028,-1.05546 1.517033,-2.1285 2.198962,-3.20448 7.602843,-12.04097 8.679493,-24.85155 2.075243,-29.70811 -5.9886,-4.40066 -16.413416,-0.87222 -25.244612,7.869"
|
||||
stroke-miterlimit="10"
|
||||
style="fill:none;stroke:#000000;stroke-width:5.8774972;stroke-linecap:round;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path10"
|
||||
d="m 31.182284,992.23215 56.121393,44.06525 c 5.727905,4.2086 18.116023,-2.8366 27.674813,-15.719 9.55141,-12.8912 12.66501,-26.74548 6.94153,-30.94971 L 69.644231,940.36975"
|
||||
stroke-miterlimit="10"
|
||||
style="fill:none;stroke:#000000;stroke-width:4.40812302;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#37b63b;fill-opacity:1"
|
||||
id="path12"
|
||||
d="m 64.359653,971.28577 c -12.75928,-0.0748 -27.904574,4.3303 -33.175896,7.31929 -5.26985,2.98899 -12.095026,8.47882 -15.822804,14.98012 -3.729251,6.50422 -5.051868,17.33732 -0.29457,24.86472 0,0 6.227201,9.4258 7.65439,19.0671 0.768827,3.1928 -1.322617,7.4981 5.275741,8.7647 6.596886,1.2695 4.73226,-12.8912 4.73226,-12.8912 0,0 -0.631851,-3.8085 -1.543544,-7.9101 -1.624551,-9.263 4.813266,-29.4706 4.813266,-29.4706 0,0 1.857261,-2.08159 6.938586,-4.3347 2.947169,-1.27241 8.386396,-5.52794 8.386396,-5.52794 l 5.857515,-5.61883 4.755826,-5.76395 c -0.0044,0 1.281377,-1.66674 2.422834,-3.47861 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#3a37b6;fill-opacity:1"
|
||||
id="path14"
|
||||
d="m 24.801907,980.76288 c 0,0 -21.867371,-2.08306 -20.6728915,6.1231 1.1959525,8.20616 7.2611395,3.59148 10.3364455,-1.19032 3.073834,-4.78326 10.336446,-4.93278 10.336446,-4.93278 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#3a37b6;fill-opacity:1"
|
||||
id="path16"
|
||||
d="m 15.670251,989.86324 c 0,0 -19.2648493,10.50616 -13.6415164,16.62636 5.6233329,6.1187 8.0343844,-1.0877 7.87679,-6.76666 -0.1575947,-5.676 5.7647264,-9.8597 5.7647264,-9.8597 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#bc3e4c;fill-opacity:1;stroke:#000000;stroke-width:4.40812302;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:10"
|
||||
stroke-miterlimit="10"
|
||||
d="m 40.01608,999.07291 c 6.359757,4.67479 20.124993,-3.15171 30.748644,-17.46631 l 33.295196,33.6177 c -10.626596,14.3161 -20.771571,17.651 -27.134274,12.9792"
|
||||
id="path4" />
|
||||
<ellipse
|
||||
style="fill:none;stroke:#dba50a;stroke-width:4.40800762;stroke-miterlimit:10;stroke-opacity:1"
|
||||
transform="matrix(-0.8058623,-0.592103,0.59573364,-0.80318206,0,0)"
|
||||
stroke-miterlimit="10"
|
||||
cx="-616.16455"
|
||||
cy="-748.86359"
|
||||
rx="14.290408"
|
||||
ry="32.282364"
|
||||
id="ellipse6" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#dba50a;stroke-width:5.8774972;stroke-linecap:round;stroke-miterlimit:10;fill-opacity:1;stroke-opacity:1"
|
||||
stroke-miterlimit="10"
|
||||
d="m 85.466691,977.45808 c 3.178405,-2.48472 6.266967,-5.64375 9.022665,-9.36276 0.785028,-1.05546 1.517033,-2.1285 2.198962,-3.20448 7.602842,-12.04097 8.679492,-24.85155 2.075243,-29.70811 -5.9886,-4.40066 -16.413416,-0.87222 -25.244612,7.869"
|
||||
id="path8" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#dba50a;stroke-width:4.40812302;stroke-miterlimit:10;stroke-opacity:1"
|
||||
stroke-miterlimit="10"
|
||||
d="m 31.184885,992.23591 56.121393,44.06529 c 5.727905,4.2086 18.116022,-2.8366 27.674812,-15.719 9.55141,-12.8912 12.66501,-26.74552 6.94153,-30.94975 L 69.646832,940.37351"
|
||||
id="path10" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 64.362254,971.28953 c -12.75928,-0.0748 -27.904574,4.3303 -33.175896,7.31929 -5.26985,2.98899 -12.095026,8.47882 -15.822804,14.98012 -3.729251,6.50426 -5.051868,17.33736 -0.29457,24.86476 0,0 6.227201,9.4258 7.65439,19.0671 0.768827,3.1928 -1.322617,7.4981 5.275741,8.7647 6.596886,1.2695 4.73226,-12.8912 4.73226,-12.8912 0,0 -0.631851,-3.8085 -1.543544,-7.9101 -1.624551,-9.263 4.813266,-29.47064 4.813266,-29.47064 0,0 1.857261,-2.08159 6.938586,-4.3347 2.947169,-1.27241 8.386396,-5.52794 8.386396,-5.52794 l 5.857515,-5.61883 4.755826,-5.76395 c -0.0044,0 1.281377,-1.66674 2.422834,-3.47861 z"
|
||||
id="path12"
|
||||
style="fill:#37b63b;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 24.804508,980.76664 c 0,0 -21.8673714,-2.08306 -20.6728919,6.1231 1.1959525,8.20616 7.2611399,3.59148 10.3364459,-1.19032 3.073834,-4.78326 10.336446,-4.93278 10.336446,-4.93278 z"
|
||||
id="path14"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 15.672852,989.867 c 0,0 -19.2648497,10.5062 -13.6415168,16.6264 5.6233329,6.1187 8.0343848,-1.0877 7.87679,-6.7667 -0.1575947,-5.676 5.7647268,-9.8597 5.7647268,-9.8597 z"
|
||||
id="path16"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.6 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,51 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-indent-less.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4178">
|
||||
<stop
|
||||
style="stop-color:#0a4da3;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4180" />
|
||||
<stop
|
||||
style="stop-color:#041f42;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4182" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4205"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="matrix(1.2741702,0,0,1.3174597,91.323232,-313.85451)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4207"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4209"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -67,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="57.130788"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -131,22 +89,23 @@
|
||||
<path
|
||||
d="m 127,1022.1122 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -121.5,0 q -0.91406,0 -1.58203,-0.668 Q 1,1036.5263 1,1035.6122 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 121.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
id="path4145"
|
||||
style="fill:#041f42;fill-opacity:1" />
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 127,961.59431 0,53.35729 q 0,1.2042 -0.85111,2.0841 -0.85111,0.8801 -2.01577,0.8801 -1.25426,0 -2.06057,-0.8337 L 96.270594,990.40347 q -0.806308,-0.8337 -0.806308,-2.13061 0,-1.2969 0.806308,-2.13059 l 25.801956,-26.67856 q 0.80631,-0.83369 2.06057,-0.83369 1.16466,0 2.01577,0.88007 Q 127,960.39002 127,961.59431 Z"
|
||||
id="path4147"
|
||||
style="fill:url(#linearGradient4205);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<g
|
||||
id="g4144"
|
||||
transform="translate(-45,0)">
|
||||
transform="translate(-45,0)"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
style="fill:url(#linearGradient4207);fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
id="path4143"
|
||||
d="m 127,995.11216 0,13.50004 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -76.5,0 q -0.91406,0 -1.58203,-0.668 Q 46,1009.5263 46,1008.6122 l 0,-13.50004 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 76.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4209);fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
id="path4141"
|
||||
d="m 127,968.11216 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -76.5,0 q -0.91406,0 -1.58203,-0.668 Q 46,982.52626 46,981.61216 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 76.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
@ -154,6 +113,6 @@
|
||||
<path
|
||||
d="m 127,941.11216 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -121.5,0 q -0.91406,0 -1.58203,-0.668 Q 1,955.52626 1,954.61216 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 121.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
id="path4"
|
||||
style="fill-opacity:1;fill:#041f42" />
|
||||
style="fill-opacity:1;fill:#2271d5" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.8 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,51 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-indent-more.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4178">
|
||||
<stop
|
||||
style="stop-color:#0a4da3;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4180" />
|
||||
<stop
|
||||
style="stop-color:#041f42;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4182" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4205"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="matrix(-1.2741702,0,0,1.3174597,36.676768,-313.85451)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4207"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4178"
|
||||
id="linearGradient4209"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3.25"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -67,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="26.862931"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -131,21 +89,22 @@
|
||||
<path
|
||||
d="m 127,1022.1122 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -121.5,0 q -0.91406,0 -1.58203,-0.668 Q 1,1036.5263 1,1035.6122 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 121.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
id="path4145"
|
||||
style="fill:#041f42;fill-opacity:1" />
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 1,961.59431 0,53.35729 q 0,1.2042 0.85111,2.0841 0.85111,0.8801 2.01577,0.8801 1.25426,0 2.06057,-0.8337 l 25.801956,-26.67863 q 0.806308,-0.8337 0.806308,-2.13061 0,-1.2969 -0.806308,-2.13059 L 5.92745,959.46371 q -0.80631,-0.83369 -2.06057,-0.83369 -1.16466,0 -2.01577,0.88007 Q 1,960.39002 1,961.59431 Z"
|
||||
id="path4147"
|
||||
style="fill:url(#linearGradient4205);fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<g
|
||||
id="g4144">
|
||||
id="g4144"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
style="fill:url(#linearGradient4207);fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
id="path4143"
|
||||
d="m 127,995.11216 0,13.50004 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -76.5,0 q -0.91406,0 -1.58203,-0.668 Q 46,1009.5263 46,1008.6122 l 0,-13.50004 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 76.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4209);fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
id="path4141"
|
||||
d="m 127,968.11216 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -76.5,0 q -0.91406,0 -1.58203,-0.668 Q 46,982.52626 46,981.61216 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 76.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
@ -153,6 +112,6 @@
|
||||
<path
|
||||
d="m 127,941.11216 0,13.5 q 0,0.9141 -0.66797,1.582 -0.66797,0.668 -1.58203,0.668 l -121.5,0 q -0.91406,0 -1.58203,-0.668 Q 1,955.52626 1,954.61216 l 0,-13.5 q 0,-0.9141 0.66797,-1.582 0.66797,-0.668 1.58203,-0.668 l 121.5,0 q 0.91406,0 1.58203,0.668 0.66797,0.6679 0.66797,1.582 z"
|
||||
id="path4"
|
||||
style="fill-opacity:1;fill:#041f42" />
|
||||
style="fill-opacity:1;fill:#2271d5" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.7 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-justify-center.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,15 +23,15 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#08387a;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
id="stop4147"
|
||||
offset="0.50773352"
|
||||
style="stop-color:#0d5cc6;stop-opacity:1" />
|
||||
style="stop-color:#b2cffa;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#08397a;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -52,17 +52,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="15.309153"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-justify-fill.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,15 +23,15 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
id="stop4147"
|
||||
offset="0.51573128"
|
||||
style="stop-color:#08397a;stop-opacity:1" />
|
||||
style="stop-color:#0b59bd;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -52,17 +52,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="49.38296"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-justify-left.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#083a7c;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -48,17 +48,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="23.828721"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-justify-right.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#08397a;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -48,17 +48,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="-10.424833"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@ -15,19 +15,19 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="chapters.svg">
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-list-ordered.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4165">
|
||||
<stop
|
||||
style="stop-color:#116def;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4167" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4169" />
|
||||
</linearGradient>
|
||||
@ -48,17 +48,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="19.843024"
|
||||
inkscape:zoom="5.656854"
|
||||
inkscape:cx="-24.881482"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -111,19 +111,19 @@
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
id="g4155"
|
||||
style="fill:#116def;fill-opacity:1">
|
||||
style="fill:#2caf45;fill-opacity:1">
|
||||
<path
|
||||
id="path4149"
|
||||
d="m 28.258393,1037.5797 q 0,5.4724 -3.728101,8.619 -3.728102,3.1466 -9.26888,3.1466 -7.2509858,0 -11.7656771,-4.5147 l 3.899039,-6.0196 q 3.3518541,3.0782 7.2509851,3.0782 1.983707,0 3.454417,-0.9919 1.47071,-0.9919 1.47071,-2.9072 0,-4.3779 -7.182518,-3.8307 l -1.77849,-3.8307 q 0.547185,-0.6841 2.223112,-2.9756 1.675927,-2.2916 2.907232,-3.6939 1.231304,-1.4023 2.530984,-2.6336 l 0,-0.068 q -1.094462,0 -3.317667,0.068 -2.223112,0.068 -3.317666,0.068 l 0,3.6254 -7.2508934,0 0,-10.3976 22.7788594,0 0,6.0197 -6.498491,7.8665 q 3.488696,0.8209 5.540871,3.3519 2.052174,2.531 2.052174,6.0197 z"
|
||||
style="fill:#116def;fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<path
|
||||
id="path4147"
|
||||
d="m 28.395143,994.68968 0,10.87642 -24.7626581,0 q -0.4104349,-2.4626 -0.4104349,-3.6939 0,-3.48869 1.607552,-6.36165 1.6075521,-2.87304 3.8648515,-4.65153 2.2573915,-1.77858 4.5147835,-3.24929 2.257392,-1.47071 3.864852,-2.97561 1.607552,-1.50489 1.607552,-3.07826 0,-1.71011 -0.9919,-2.63355 -0.991807,-0.92352 -2.702014,-0.92352 -3.146637,0 -5.5407787,3.96751 l -5.8144634,-4.03589 q 1.6417395,-3.48869 4.8910311,-5.43821 3.249199,-1.94952 7.216706,-1.94952 4.993593,0 8.413822,2.83876 3.420229,2.83886 3.420229,7.69561 0,3.42023 -2.325766,6.25909 -2.325767,2.83876 -5.130344,4.41213 -2.804669,1.57327 -5.164624,3.45441 -2.359954,1.88115 -2.428329,3.59126 l 8.687415,0 0,-4.10426 7.182518,0 z"
|
||||
style="fill:#116def;fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
<path
|
||||
id="path4143"
|
||||
d="m 28.463611,955.01471 0,6.77209 -22.9157941,0 0,-6.77209 7.3193601,0 q 0,-2.80457 0.03419,-8.34545 0.03419,-5.54077 0.03419,-8.27698 l 0,-0.82087 -0.136842,0 q -0.547277,1.16284 -3.4202291,3.69392 l -4.8567512,-5.19881 9.3030673,-8.68751 7.250893,0 0,27.6357 7.387828,0 z"
|
||||
style="fill:#116def;fill-opacity:1" />
|
||||
style="fill:#2caf45;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g4160"
|
||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
@ -15,67 +15,31 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-list-unordered.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4165">
|
||||
id="linearGradient848">
|
||||
<stop
|
||||
style="stop-color:#116def;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4167" />
|
||||
id="stop844" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4169" />
|
||||
id="stop846" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4165"
|
||||
id="linearGradient4158"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="77.170937"
|
||||
y1="944.39056"
|
||||
x2="77.170937"
|
||||
y2="1032.3369" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4165"
|
||||
id="linearGradient4160"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="77.170937"
|
||||
y1="944.39056"
|
||||
x2="77.170937"
|
||||
y2="1032.3369" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4165"
|
||||
id="linearGradient4162"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="77.170937"
|
||||
y1="944.39056"
|
||||
x2="77.170937"
|
||||
y2="1032.3369" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4165"
|
||||
id="linearGradient4164"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="77.170937"
|
||||
y1="944.39056"
|
||||
x2="77.170937"
|
||||
y2="1032.3369" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4165"
|
||||
id="linearGradient4166"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="77.170937"
|
||||
y1="944.39056"
|
||||
x2="77.170937"
|
||||
y2="1032.3369" />
|
||||
xlink:href="#linearGradient848"
|
||||
id="linearGradient850"
|
||||
x1="82.474236"
|
||||
y1="944.56732"
|
||||
x2="82.705093"
|
||||
y2="1032.0718"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@ -84,17 +48,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="70.163491"
|
||||
inkscape:zoom="5.656854"
|
||||
inkscape:cx="25.438985"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -145,48 +109,56 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4158);fill-opacity:1"
|
||||
d="m 124.77795,1016.5109 0,13.1337 q 0,0.8893 -0.64984,1.5392 -0.64984,0.6499 -1.53908,0.6499 l -83.180612,0 q -0.889337,0 -1.539177,-0.6499 -0.64984,-0.6499 -0.64984,-1.5392 l 0,-13.1337 q 0,-0.9577 0.615652,-1.5734 0.615653,-0.6156 1.573365,-0.6156 l 83.180612,0 q 0.88924,0 1.53908,0.6498 0.64984,0.6499 0.64984,1.5392 z"
|
||||
id="path4145" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4160);fill-opacity:1"
|
||||
d="m 124.77795,981.48749 0,13.13382 q 0,0.88924 -0.64984,1.53908 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53908 l 0,-13.13382 q 0,-0.95772 0.615652,-1.57337 0.615653,-0.61556 1.573365,-0.61556 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
id="path4141" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4162);fill-opacity:1"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
id="path4" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4150"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
style="fill:url(#linearGradient4164);fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4166);fill-opacity:1"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
id="path4154" />
|
||||
<circle
|
||||
style="fill:#116def;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4148"
|
||||
cx="16.484426"
|
||||
cy="953.03094"
|
||||
r="11.092738" />
|
||||
<circle
|
||||
r="11.092738"
|
||||
cy="988.05438"
|
||||
cx="16.484426"
|
||||
id="circle4152"
|
||||
style="fill:#116def;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<circle
|
||||
style="fill:#116def;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle4156"
|
||||
cx="16.484426"
|
||||
cy="1023.0778"
|
||||
r="11.092738" />
|
||||
<g
|
||||
id="g842"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)">
|
||||
<path
|
||||
id="path4145"
|
||||
d="m 124.77795,1016.5109 0,13.1337 q 0,0.8893 -0.64984,1.5392 -0.64984,0.6499 -1.53908,0.6499 l -83.180612,0 q -0.889337,0 -1.539177,-0.6499 -0.64984,-0.6499 -0.64984,-1.5392 l 0,-13.1337 q 0,-0.9577 0.615652,-1.5734 0.615653,-0.6156 1.573365,-0.6156 l 83.180612,0 q 0.88924,0 1.53908,0.6498 0.64984,0.6499 0.64984,1.5392 z"
|
||||
style="fill:url(#linearGradient850);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path4141"
|
||||
d="m 124.77795,981.48749 0,13.13382 q 0,0.88924 -0.64984,1.53908 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53908 l 0,-13.13382 q 0,-0.95772 0.615652,-1.57337 0.615653,-0.61556 1.573365,-0.61556 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
style="fill:url(#linearGradient850);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path4"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
style="fill:url(#linearGradient850);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient850);fill-opacity:1"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
id="path4150"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path4154"
|
||||
d="m 124.77795,946.46405 0,13.13382 q 0,0.88925 -0.64984,1.53909 -0.64984,0.64984 -1.53908,0.64984 l -83.180612,0 q -0.889337,0 -1.539177,-0.64984 -0.64984,-0.64984 -0.64984,-1.53909 l 0,-13.13382 q 0,-0.88925 0.64984,-1.53909 0.64984,-0.64984 1.539177,-0.64984 l 83.180612,0 q 0.88924,0 1.53908,0.64984 0.64984,0.64984 0.64984,1.53909 z"
|
||||
style="fill:url(#linearGradient850);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g831"
|
||||
style="fill:#2caf45;fill-opacity:1">
|
||||
<circle
|
||||
r="11.092738"
|
||||
cy="953.03094"
|
||||
cx="16.484426"
|
||||
id="path4148"
|
||||
style="fill:#2caf45;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<circle
|
||||
style="fill:#2caf45;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle4152"
|
||||
cx="16.484426"
|
||||
cy="988.05438"
|
||||
r="11.092738" />
|
||||
<circle
|
||||
r="11.092738"
|
||||
cy="1023.0778"
|
||||
cx="16.484426"
|
||||
id="circle4156"
|
||||
style="fill:#2caf45;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.7 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-bold.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4235">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1;"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4237" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4239" />
|
||||
</linearGradient>
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.999999"
|
||||
inkscape:zoom="5.6568539"
|
||||
inkscape:cx="29.797726"
|
||||
inkscape:cy="52.767291"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
showguides="false" />
|
||||
<metadata
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-color.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="53.188911"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -93,7 +93,7 @@
|
||||
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
|
||||
y="732.13635"
|
||||
x="-634.40143"
|
||||
style="fill:#0a50a9;fill-opacity:1" />
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<polygon
|
||||
id="polygon8"
|
||||
points="19.092,13.435 18.385,12.728 13.435,7.778 12.727,7.071 10.605,9.192 16.971,15.557 "
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-heading.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="61.892855"
|
||||
inkscape:cy="54.756941"
|
||||
inkscape:cy="82.536136"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.1 r"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-hr.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -26,16 +26,16 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:cx="50.735407"
|
||||
inkscape:cx="34.76237"
|
||||
inkscape:cy="62.616635"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -89,7 +89,7 @@
|
||||
<path
|
||||
d="m 127,990.98716 v -5.25 q 0,-1.1484 -0.73828,-1.8867 -0.73828,-0.7383 -1.88672,-0.7383 H 3.6250002 q -1.14844,0 -1.88672,0.7383 -0.7382799,0.7383 -0.7382799,1.8867 v 5.25 q 0,1.1484 0.7382799,1.8867 0.73828,0.7383 1.88672,0.7383 H 124.375 q 1.14844,0 1.88672,-0.7383 Q 127,992.13556 127,990.98716 Z"
|
||||
id="path4"
|
||||
style="fill:#0d5cc6;fill-opacity:1"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-italic.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="43.191939"
|
||||
inkscape:cy="49.735915"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,56 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-strikethrough.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4149">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4151" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4153" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4149"
|
||||
id="radialGradient4155"
|
||||
cx="64"
|
||||
cy="988.36218"
|
||||
fx="64"
|
||||
fy="988.36218"
|
||||
r="36"
|
||||
gradientTransform="matrix(1,0,0,1.5000006,0,-494.18164)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4149"
|
||||
id="radialGradient4152"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.5000006,0,-494.18164)"
|
||||
cx="64"
|
||||
cy="988.36218"
|
||||
fx="64"
|
||||
fy="988.36218"
|
||||
r="36" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4149"
|
||||
id="radialGradient4154"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.5000006,0,-494.18164)"
|
||||
cx="64"
|
||||
cy="988.36218"
|
||||
fx="64"
|
||||
fy="988.36218"
|
||||
r="36" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -72,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="52.937487"
|
||||
inkscape:cy="73.610886"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -133,28 +86,20 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
id="g4145"
|
||||
transform="matrix(1,0,0,1.0251369,0,-31.378774)">
|
||||
<path
|
||||
style="fill:#0d5cc6;fill-opacity:1"
|
||||
id="path4143"
|
||||
d="m 124.75,988.36216 q 0.98438,0 1.61719,0.6328 0.63281,0.6328 0.63281,1.6172 l 0,4.5 q 0,0.9844 -0.63281,1.6172 -0.63281,0.6328 -1.61719,0.6328 l -121.5,0 q -0.98437,0 -1.61719,-0.6328 Q 1,996.09656 1,995.11216 l 0,-4.5 q 0,-0.9844 0.63281,-1.6172 0.63282,-0.6328 1.61719,-0.6328 l 121.5,0 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
style="fill:url(#radialGradient4155);fill-opacity:1"
|
||||
id="g4148">
|
||||
<path
|
||||
style="fill:url(#radialGradient4152);fill-opacity:1"
|
||||
d="m 34.96094,983.86216 q -1.96875,-2.4609 -3.58594,-5.625 Q 28,971.41686 28,965.01846 q 0,-12.7266 9.42188,-21.7266 9.35156,-8.9297 27.63281,-8.9297 3.51562,0 11.74219,1.3359 4.64062,0.8438 12.44531,3.375 0.70312,2.6719 1.47656,8.2969 0.98438,8.6485 0.98438,12.8672 0,1.2656 -0.35157,3.1641 l -0.84375,0.2109 -5.90625,-0.4219 -0.98437,-0.1406 q -3.51563,-10.4766 -7.24219,-14.4141 -6.1875,-6.3984 -14.76562,-6.3984 -8.01563,0 -12.79688,4.1484 -4.71094,4.0782 -4.71094,10.2657 0,5.1328 4.64063,9.8437 4.64062,4.711 19.61719,9.0703 4.85156,1.4063 12.16406,4.6407 4.07812,1.9687 6.67969,3.6562 l -52.24219,0 z"
|
||||
id="path4141"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#radialGradient4154);fill-opacity:1"
|
||||
d="m 70.60938,1001.8622 28.89843,0 Q 100,1004.6044 100,1008.331 q 0,7.8046 -2.88281,14.9062 -1.61719,3.8672 -4.99219,7.3125 -2.60156,2.4609 -7.66406,5.6953 -5.625,3.375 -10.75781,4.6406 -5.625,1.4766 -14.27344,1.4766 -8.01563,0 -13.71094,-1.6172 l -9.84375,-2.8125 q -4.00781,-1.125 -5.0625,-1.9687 -0.5625,-0.5625 -0.5625,-1.5469 l 0,-0.9141 q 0,-7.5937 -0.14062,-10.9687 -0.0703,-2.1094 0,-4.7813 l 0.14062,-2.6015 0,-3.0938 7.17188,-0.1406 q 1.05468,2.3906 2.10937,4.9922 1.05469,2.6015 1.58203,3.9375 0.52735,1.3359 0.87891,1.8984 2.46094,4.0078 5.625,6.6094 3.02344,2.5312 7.38281,4.0078 4.14844,1.5469 9.28125,1.5469 4.5,0 9.77344,-1.8985 5.41406,-1.8281 8.57812,-6.0468 3.30469,-4.2891 3.30469,-9.0703 0,-5.9063 -5.69531,-11.0391 -2.39063,-2.0391 -9.63281,-4.9922 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 124.75,981.82775 q 0.98438,0 1.61719,0.6487 Q 127,983.12516 127,984.1343 v 4.61312 q 0,1.00915 -0.63281,1.65785 -0.63281,0.64871 -1.61719,0.64871 H 3.25 q -0.98437,0 -1.61719,-0.64871 Q 1,989.75657 1,988.74742 v -4.61312 q 0,-1.00914 0.63281,-1.65785 0.63282,-0.6487 1.61719,-0.6487 z"
|
||||
id="path4143"
|
||||
style="fill:#2caf45;fill-opacity:1;stroke-width:1.01249039" />
|
||||
<path
|
||||
style="fill:#2271d5;fill-opacity:1;stroke-width:1.01249039"
|
||||
d="M 34.96094,977.21463 Q 32.99219,974.69187 31.375,971.44824 28,964.45649 28,957.89726 q 0,-13.04651 9.42188,-22.27274 9.35156,-9.15417 27.63281,-9.15417 3.51562,0 11.74219,1.36948 4.64062,0.86502 12.44531,3.45984 0.70312,2.73906 1.47656,8.50546 0.98438,8.8659 0.98438,13.19064 0,1.29741 -0.35157,3.24364 l -0.84375,0.2162 -5.90625,-0.43251 -0.98437,-0.14413 q -3.51563,-10.73995 -7.24219,-14.77643 -6.1875,-6.55923 -14.76562,-6.55923 -8.01563,0 -12.79688,4.25268 -4.71094,4.18071 -4.71094,10.52374 0,5.26183 4.64063,10.09114 4.64062,4.82942 19.61719,9.2983 4.85156,1.44165 12.16406,4.75736 4.07812,2.01818 6.67969,3.7481 z"
|
||||
id="path4141"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#2271d5;fill-opacity:1;stroke-width:1.01249039"
|
||||
d="M 70.60938,995.66714 H 99.50781 Q 100,998.47827 100,1002.2985 q 0,8.0008 -2.88281,15.2809 -1.61719,3.9644 -4.99219,7.4964 -2.60156,2.5227 -7.66406,5.8384 -5.625,3.4598 -10.75781,4.7573 -5.625,1.5137 -14.27344,1.5137 -8.01563,0 -13.71094,-1.6579 l -9.84375,-2.8832 q -4.00781,-1.1532 -5.0625,-2.0182 -0.5625,-0.5766 -0.5625,-1.5857 v -0.9371 q 0,-7.7846 -0.14062,-11.2444 -0.0703,-2.1625 0,-4.9015 l 0.14062,-2.6669 v -3.1716 l 7.17188,-0.1441 q 1.05468,2.4507 2.10937,5.1177 1.05469,2.6669 1.58203,4.0364 0.52735,1.3695 0.87891,1.9462 2.46094,4.1085 5.625,6.7755 3.02344,2.5948 7.38281,4.1085 4.14844,1.5858 9.28125,1.5858 4.5,0 9.77344,-1.9462 5.41406,-1.874 8.57812,-6.1988 3.30469,-4.3969 3.30469,-9.2983 0,-6.0548 -5.69531,-11.3166 -2.39063,-2.09033 -9.63281,-5.11766 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 4.8 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-subscript.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="61.234372"
|
||||
inkscape:cy="36.681475"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -89,12 +89,12 @@
|
||||
<path
|
||||
d="m 76.984807,1022.7464 0,13.7439 -20.41019,0 -13.08556,-20.7394 -1.97518,-3.4565 q -0.65839,-0.7407 -0.90529,-1.7283 l -0.2469,0 -0.74069,1.7283 q -0.82299,1.646 -2.05748,3.621 l -12.75637,20.5749 -21.2331803,0 0,-13.7439 10.5342903,0 16.21293,-23.94897 -15.22534,-22.3855 -11.2749803,0 0,-13.82615 22.7145603,0 11.43959,18.76415 q 0.16459,0.3292 1.89288,3.4566 0.65839,0.7406 0.90529,1.7282 l 0.24689,0 q 0.2469,-0.7407 0.90529,-1.7282 l 2.05748,-3.4566 11.52188,-18.76415 21.15089,0 0,13.82615 -10.2874,0 -15.14304,21.9739 16.78903,24.36057 8.9706,0 z"
|
||||
id="path4141"
|
||||
style="fill:#05244e;fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 126.43179,1035.247 0,16.9536 -42.301761,0 -0.3292,-2.2221 q -0.2469,-3.7034 -0.2469,-3.7857 0,-5.2672 2.13978,-9.629 2.13978,-4.3619 5.34945,-7.1189 3.20966,-2.757 6.91312,-5.3495 3.703471,-2.5924 6.913131,-4.4853 3.20967,-1.8928 5.34945,-4.4441 2.13978,-2.5513 2.13978,-5.2672 0,-3.1273 -2.42783,-5.1437 -2.42782,-2.0163 -5.80209,-2.0163 -4.197261,0 -7.983021,3.2097 -1.15219,0.9053 -2.96277,3.1273 l -8.64141,-7.5715 q 2.13978,-3.045 5.18485,-5.4317 6.58393,-5.3495 15.472241,-5.3495 9.05291,0 14.64925,4.8968 5.59634,4.8968 5.59634,13.0444 0,5.4318 -2.83932,9.7525 -2.83932,4.3207 -6.91313,7.0777 -4.07381,2.757 -8.18876,5.1437 -4.11496,2.3867 -7.16003,5.1849 -3.045071,2.7981 -3.374271,6.0078 l 19.093411,0 0,-6.5839 10.36969,0 z"
|
||||
id="path4"
|
||||
style="fill:#0d5cc6;fill-opacity:1"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -89,12 +89,12 @@
|
||||
<path
|
||||
d="m 75.420992,1023.2866 0,13.7439 -20.41019,0 -13.08556,-20.7394 -1.97518,-3.4565 q -0.65839,-0.7407 -0.90529,-1.7283 l -0.2469,0 -0.74069,1.7283 q -0.82299,1.646 -2.05748,3.6211 l -12.75637,20.5748 -21.2331795,0 0,-13.7439 10.5342895,0 16.21293,-23.94913 -15.22534,-22.38539 -11.2749795,0 0,-13.8262 22.7145595,0 11.43959,18.7642 q 0.16459,0.3292 1.89288,3.4566 0.65839,0.7406 0.90529,1.7282 l 0.24689,0 q 0.2469,-0.7407 0.90529,-1.7282 l 2.05748,-3.4566 11.52188,-18.7642 21.15089,0 0,13.8262 -10.2874,0 -15.14304,21.97389 16.78903,24.36063 8.9706,0 z"
|
||||
id="path4141"
|
||||
style="fill:#05244e;fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 126.68433,971.96849 0,16.9536 -42.301763,0 -0.3292,-2.2221 q -0.2469,-3.7034 -0.2469,-3.7857 0,-5.2672 2.13978,-9.629 2.13978,-4.3619 5.34945,-7.1189 3.20966,-2.757 6.91312,-5.3495 3.703473,-2.5924 6.913133,-4.4853 3.20967,-1.8928 5.34945,-4.44414 2.13978,-2.5513 2.13978,-5.2672 0,-3.1273 -2.42783,-5.1437 -2.42782,-2.0163 -5.80209,-2.0163 -4.19726,0 -7.983023,3.2097 -1.15219,0.9053 -2.96277,3.1273 l -8.64141,-7.5715 q 2.13978,-3.045 5.18485,-5.4317 6.58393,-5.3495 15.472243,-5.3495 9.05291,0 14.64925,4.8968 5.59634,4.8968 5.59634,13.0444 0,5.4318 -2.83932,9.75254 -2.83932,4.3207 -6.91313,7.0777 -4.07381,2.757 -8.18876,5.1437 -4.11496,2.3867 -7.16003,5.1849 -3.045073,2.7981 -3.374273,6.0078 l 19.093413,0 0,-6.5839 10.36969,0 z"
|
||||
id="path4"
|
||||
style="fill:#0d5cc6;fill-opacity:1"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -14,7 +14,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="format-text-underline.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -25,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="15.839192"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="50.735407"
|
||||
inkscape:cy="44.938966"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -89,12 +89,12 @@
|
||||
<path
|
||||
d="m 4.9375164,939.15294 q -3.03516,-0.1641 -3.69141,-0.3282 l -0.24609,-7.2187 q 1.06641,-0.082 3.28125,-0.082 4.92188,0 9.1875006,0.3281 10.82813,0.5742 13.61719,0.5742 7.05469,0 13.78125,-0.2461 9.51562,-0.3281 11.97656,-0.4102 4.59375,0 7.05469,-0.164 l -0.082,1.1484 0.16406,5.25 0,0.7383 q -4.92188,0.7383 -10.17188,0.7383 -4.92187,0 -6.48046,2.0508 -1.06641,1.1484 -1.06641,10.8281 0,1.0664 0.041,2.666 0.041,1.5996 0.041,2.0918 l 0.082,18.7852 1.14844,22.9687 q 0.49219,10.17196 4.18359,16.57036 2.8711,4.8399 7.875,7.5469 7.21875,3.8555 14.51953,3.8555 8.53125,0 15.66797,-2.2969 4.59375,-1.4766 8.1211,-4.1836 3.9375,-2.9531 5.33203,-5.25 2.953113,-4.5937 4.347643,-9.3517 1.72266,-5.98816 1.72266,-18.78506 0,-6.4805 -0.28711,-10.5 -0.28711,-4.0195 -0.90234,-10.0488 -0.61524,-6.0293 -1.10742,-13.084 l -0.32813,-4.8399 q -0.41016,-5.4961 -1.96875,-7.2187 -2.789053,-2.8711 -6.316403,-2.7891 l -8.20312,0.1641 -1.14844,-0.2461 0.16406,-7.0547 6.89063,0 16.816403,0.8203 q 6.23437,0.2461 16.07812,-0.8203 l 1.47656,0.1641 q 0.49219,3.1171 0.49219,4.1835 0,0.5743 -0.32812,2.543 -3.69141,0.9844 -6.89063,1.0664 -5.98828,0.9024 -6.48047,1.3946 -1.23047,1.2304 -1.23047,3.3632 0,0.5743 0.12305,2.2149 0.12305,1.6406 0.12305,2.543 0.65625,1.5585 1.80468,32.4843 0.49219,15.9961 -1.23046,24.93756 -1.23047,6.2344 -3.36329,10.0078 -3.11718,5.3321 -9.18749,10.0899 -6.152343,4.6758 -14.929683,7.3008 -8.94141,2.707 -20.91797,2.707 -13.69922,0 -23.29688,-3.7734 -9.76172,-3.8555 -14.68359,-10.0078 -5.00391,-6.2344 -6.80859,-15.9961 -1.3125,-6.5626 -1.3125,-19.44156 l 0,-27.3164 q 0,-15.4218 -1.39454,-17.4726 -2.05078,-2.9531 -12.0585906,-3.1992 z"
|
||||
id="path4141"
|
||||
style="fill:#052147;fill-opacity:1"
|
||||
style="fill:#2271d5;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 127,1049.5579 0,-5.25 q 0,-1.1484 -0.73828,-1.8867 -0.73828,-0.7383 -1.88672,-0.7383 l -120.7499996,0 q -1.14844,0 -1.88672,0.7383 -0.7382799,0.7383 -0.7382799,1.8867 l 0,5.25 q 0,1.1484 0.7382799,1.8867 0.73828,0.7383 1.88672,0.7383 l 120.7499996,0 q 1.14844,0 1.88672,-0.7383 Q 127,1050.7063 127,1049.5579 Z"
|
||||
id="path4"
|
||||
style="fill:#0d5cc6;fill-opacity:1"
|
||||
style="fill:#2caf45;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.9 KiB |
@ -2,9 +2,8 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
import os, glob, subprocess, argparse
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import os, glob, subprocess, argparse, json, hashlib
|
||||
|
||||
duplicates = {
|
||||
'character-set': ['languages'],
|
||||
@ -27,6 +26,13 @@ skip = {'calibre'}
|
||||
j = os.path.join
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
output_base = j(os.path.dirname(base), 'resources', 'images')
|
||||
hash_path = j(os.path.dirname(base), '.build-cache', 'imgsrc-gen.json')
|
||||
if os.path.exists(hash_path):
|
||||
with open(hash_path, 'rb') as f:
|
||||
hashes = json.load(f)
|
||||
else:
|
||||
hashes = {}
|
||||
src_hashes = {}
|
||||
|
||||
|
||||
def iterfiles(only=()):
|
||||
@ -34,6 +40,9 @@ def iterfiles(only=()):
|
||||
name = os.path.relpath(src, base).rpartition('.')[0]
|
||||
if only and name not in only:
|
||||
continue
|
||||
src_hashes[name] = h = hashlib.sha1(open(src, 'rb').read()).hexdigest()
|
||||
if not only and h == hashes.get(name):
|
||||
continue
|
||||
output_names = [n for n in [name] + duplicates.get(name, []) if n not in skip]
|
||||
output_files = [j(output_base, n) + '.png' for n in output_names]
|
||||
if output_files:
|
||||
@ -54,6 +63,8 @@ def render(src, output_files):
|
||||
size = sizes.get(oname, '128')
|
||||
print('Rendering', oname, 'at size:', size)
|
||||
rsvg(src, size, dest)
|
||||
name = os.path.relpath(src, base).rpartition('.')[0]
|
||||
hashes[name] = src_hashes[name]
|
||||
|
||||
|
||||
def main():
|
||||
@ -62,6 +73,8 @@ def main():
|
||||
args = p.parse_args()
|
||||
for src, ofiles in iterfiles(args.only):
|
||||
render(src, ofiles)
|
||||
with open(hash_path, 'w') as f:
|
||||
json.dump(hashes, f, indent=2, sort_keys=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
111
imgsrc/generic-library.svg
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
fill="#000000"
|
||||
viewBox="0 0 17 17"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
id="svg18"
|
||||
sodipodi:docname="generic-library.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14">
|
||||
<metadata
|
||||
id="metadata24">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs22">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient848">
|
||||
<stop
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop844" />
|
||||
<stop
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop846" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient848"
|
||||
id="linearGradient850"
|
||||
x1="8.8487625"
|
||||
y1="17.227978"
|
||||
x2="8.4970684"
|
||||
y2="-0.060158744"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
id="namedview20"
|
||||
showgrid="false"
|
||||
inkscape:zoom="55.529412"
|
||||
inkscape:cx="6.6271186"
|
||||
inkscape:cy="8.5"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg18" />
|
||||
<g
|
||||
id="g842"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)">
|
||||
<path
|
||||
id="path2"
|
||||
d="M1.7866,6.5 L15.9196,6.5 C16.8236,6.5 17.1906,5.336 16.4496,4.818 L11.5146,1.363 C9.9166,0.244 7.7896,0.244 6.1916,1.363 L1.2566,4.818 C0.5156,5.336 0.8826,6.5 1.7866,6.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon4"
|
||||
points="1.853 12.5 3.853 12.5 3.853 7.5 1.853 7.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon6"
|
||||
points="4.853 12.5 6.853 12.5 6.853 7.5 4.853 7.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon8"
|
||||
points="7.853 12.5 9.853 12.5 9.853 7.5 7.853 7.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon10"
|
||||
points="10.853 12.5 12.853 12.5 12.853 7.5 10.853 7.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon12"
|
||||
points="13.853 12.5 15.853 12.5 15.853 7.5 13.853 7.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon14"
|
||||
points="0.853 16.5 16.853 16.5 16.853 15.5 0.853 15.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
<polygon
|
||||
id="polygon16"
|
||||
points="1.853 14.5 15.853 14.5 15.853 13.5 1.853 13.5"
|
||||
style="fill-opacity:1;fill:url(#linearGradient850)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="grid.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -23,11 +23,11 @@
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4134">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
style="stop-color:#b2cffa;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4136" />
|
||||
<stop
|
||||
style="stop-color:#020e1e;stop-opacity:1"
|
||||
style="stop-color:#0b59bd;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4138" />
|
||||
</linearGradient>
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="49.38296"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.9 KiB |
113
imgsrc/h-ellipsis.svg
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="h-ellipsis.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.656854"
|
||||
inkscape:cx="4.4025571"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Kovid Goyal</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
id="g831"
|
||||
style="fill:#7d7d7d;fill-opacity:1"
|
||||
transform="rotate(90,22.052892,1030.5691)">
|
||||
<circle
|
||||
r="11.092738"
|
||||
cy="953.03094"
|
||||
cx="16.484426"
|
||||
id="path4148"
|
||||
style="fill:#7d7d7d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<circle
|
||||
style="fill:#7d7d7d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle4152"
|
||||
cx="16.484426"
|
||||
cy="988.05438"
|
||||
r="11.092738" />
|
||||
<circle
|
||||
r="11.092738"
|
||||
cy="1023.0778"
|
||||
cx="16.484426"
|
||||
id="circle4156"
|
||||
style="fill:#7d7d7d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="heuristics.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -50,17 +50,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="33.653639"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -120,11 +120,11 @@
|
||||
<g
|
||||
transform="matrix(1.3939367,0,0,1.3695651,-5.6968353,-384.43812)"
|
||||
id="g4"
|
||||
style="fill:#3027dd;fill-opacity:1">
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 20.000054,956.3622 c -1.94862,0.01 -3.01295,1.69 -3,3 l 0,86 c 1.6e-4,1.5708 1.42925,2.9998 3,3 l 60,0 c 1.57075,-2e-4 2.99984,-1.4292 3,-3 l 0,-70 c 0.002,-0.7861 -0.32012,-1.5681 -0.875,-2.125 l -16,-16 c -0.55685,-0.5549 -1.33889,-0.8769 -2.125,-0.875 l -44,0 z m 3,6 38,0 0,13 a 3.0003,3.0003 0 0 0 3,3 l 13,0 0,64 -54,0 0,-80 z m 44,4.2188 5.78125,5.7812 -5.78125,0 0,-5.7812 z"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#3027dd;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
style="color:#000000;text-indent:0;text-transform:none;direction:ltr;block-progression:tb;baseline-shift:baseline;display:inline;overflow:visible;visibility:visible;fill:#2271d5;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate"
|
||||
visibility="visible"
|
||||
display="inline"
|
||||
overflow="visible"
|
||||
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,57 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="highlight_only_off.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
id="stop4147"
|
||||
offset="0.51573128"
|
||||
style="stop-color:#062a5a;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4145"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,-2.1428647)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4149"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="translate(0,12.946445)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4151"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="translate(-6.85e-7,28.035712)" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -73,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="38.236962"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -134,21 +86,25 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<path
|
||||
style="fill:url(#linearGradient4151);fill-opacity:1"
|
||||
d="m 127,1025.3979 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117.0000007,0 q -1.82812,0 -3.16406,-1.3359 -1.33594003,-1.336 -1.33594003,-3.1641 l 0,-9 q 0,-1.8281 1.33594003,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117.0000007,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
id="path4143"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4149);fill-opacity:1"
|
||||
d="m 127,983.3086 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,994.1367 1,992.3086 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 Q 127,981.4805 127,983.3086 Z"
|
||||
id="path4141"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4145);fill-opacity:1"
|
||||
d="m 127,941.21929 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,952.04739 1,950.21929 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g826"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4143"
|
||||
d="m 127,1025.3979 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117.0000007,0 q -1.82812,0 -3.16406,-1.3359 -1.33594003,-1.336 -1.33594003,-3.1641 l 0,-9 q 0,-1.8281 1.33594003,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117.0000007,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4141"
|
||||
d="m 127,983.3086 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,994.1367 1,992.3086 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 Q 127,981.4805 127,983.3086 Z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 127,941.21929 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,952.04739 1,950.21929 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:#b60c09;fill-opacity:1"
|
||||
d="m 125.33871,1041.5223 -8.17848,8.1786 q -1.66126,1.6613 -4.08931,1.6613 -2.42794,0 -4.08921,-1.6613 L 2.6612865,943.38045 q -1.6612525,-1.66124 -1.6612882,-4.08921 5.41e-5,-2.42804 1.6612882,-4.08929 l 8.1784945,-8.17849 q 1.661234,-1.66123 4.089285,-1.66129 2.427958,4e-5 4.089209,1.66129 L 125.33871,1033.3439 q 1.66126,1.6613 1.66129,4.0893 -6e-5,2.428 -1.66129,4.0891 z"
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.5 KiB |
@ -7,7 +7,6 @@
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
@ -15,57 +14,10 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="highlight_only_on.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4139">
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4141" />
|
||||
<stop
|
||||
id="stop4147"
|
||||
offset="0.51573128"
|
||||
style="stop-color:#062a5a;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#0d5cc6;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4143" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4145"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,-2.1428647)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4149"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="translate(0,12.946445)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4139"
|
||||
id="linearGradient4151"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1"
|
||||
y1="988.36218"
|
||||
x2="127"
|
||||
y2="988.36218"
|
||||
gradientTransform="translate(-6.85e-7,28.035712)" />
|
||||
</defs>
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@ -73,17 +25,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="7.9691049"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -134,20 +86,24 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<path
|
||||
style="fill:url(#linearGradient4151);fill-opacity:1"
|
||||
d="m 127,1025.3979 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117.0000007,0 q -1.82812,0 -3.16406,-1.3359 -1.33594003,-1.336 -1.33594003,-3.1641 l 0,-9 q 0,-1.8281 1.33594003,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117.0000007,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
id="path4143"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4149);fill-opacity:1"
|
||||
d="m 127,983.3086 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,994.1367 1,992.3086 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 Q 127,981.4805 127,983.3086 Z"
|
||||
id="path4141"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4145);fill-opacity:1"
|
||||
d="m 127,941.21929 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,952.04739 1,950.21929 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g828"
|
||||
style="fill:#2271d5;fill-opacity:1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4143"
|
||||
d="m 127,1025.3979 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117.0000007,0 q -1.82812,0 -3.16406,-1.3359 -1.33594003,-1.336 -1.33594003,-3.1641 l 0,-9 q 0,-1.8281 1.33594003,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117.0000007,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4141"
|
||||
d="m 127,983.3086 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,994.1367 1,992.3086 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 Q 127,981.4805 127,983.3086 Z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4"
|
||||
d="m 127,941.21929 0,9 q 0,1.8281 -1.33594,3.1641 -1.33593,1.3359 -3.16406,1.3359 l -117,0 q -1.82812,0 -3.16406,-1.3359 Q 1,952.04739 1,950.21929 l 0,-9 q 0,-1.8281 1.33594,-3.1641 1.33594,-1.3359 3.16406,-1.3359 l 117,0 q 1.82813,0 3.16406,1.3359 1.33594,1.336 1.33594,3.1641 z"
|
||||
style="fill:#2271d5;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.0 KiB |
@ -15,8 +15,9 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="html-fix.svg">
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="html-fix.svg"
|
||||
enable-background="new">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
@ -104,6 +105,16 @@
|
||||
result="composite2"
|
||||
id="feComposite4467" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter871">
|
||||
<feBlend
|
||||
inkscape:collect="always"
|
||||
mode="overlay"
|
||||
in2="BackgroundImage"
|
||||
id="feBlend873" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@ -112,17 +123,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="-10.424833"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -195,15 +206,15 @@
|
||||
id="polyline14" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:45px;line-height:125%;font-family:Consolas;-inkscape-font-specification:Consolas;letter-spacing:0px;word-spacing:0px;fill:#6d0b0b;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4457)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:Consolas;-inkscape-font-specification:Consolas;letter-spacing:0px;word-spacing:0px;fill:#dd8808;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter871);"
|
||||
x="7.5610352"
|
||||
y="1020.3086"
|
||||
id="text4151"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4151"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4153"
|
||||
x="7.5610352"
|
||||
y="1020.3086">HTML</tspan></text>
|
||||
y="1020.3086"
|
||||
style="font-size:45px;line-height:1.25;fill:#dd8808;fill-opacity:1;">HTML</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 62.500001,944.14932 q 0,1.11152 -0.778059,1.88963 l -20.11853,20.11853 -3.779167,3.7791 q -0.778072,0.77811 -1.889584,0.77811 -1.111526,0 -1.889598,-0.77811 l -3.779168,-3.7791 -10.059265,-10.05934 q -0.778058,-0.77797 -0.778058,-1.88948 0,-1.11152 0.778058,-1.88963 l 3.779182,-3.77911 q 0.778058,-0.77812 1.889584,-0.77812 1.111512,0 1.889584,0.77812 l 8.169681,8.19743 18.228932,-18.25677 q 0.778072,-0.77811 1.889584,-0.77811 1.111525,0 1.889584,0.77811 l 3.779181,3.77925 q 0.778059,0.77798 0.778059,1.88949 z"
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.7 KiB |
@ -15,7 +15,7 @@
|
||||
viewBox="0 0 128 128"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="icon_choose.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
@ -26,17 +26,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.2"
|
||||
inkscape:zoom="7.919596"
|
||||
inkscape:cx="53.868545"
|
||||
inkscape:cy="69.707741"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2128"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1400"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-y="40"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
@ -87,32 +87,28 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-924.36216)">
|
||||
<g
|
||||
id="g4149"
|
||||
transform="matrix(0.88920982,0,0,0.90113892,-35.480349,84.31281)">
|
||||
<path
|
||||
style="overflow:visible;fill:#546e7a"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path7"
|
||||
d="m 173.86824,934.4279 -123.986482,0 c -4.890824,0 -8.856178,3.64373 -8.856178,8.13786 l 0,81.37854 c 0,4.4941 3.965354,8.1378 8.856178,8.1378 l 123.986482,0 c 4.89083,0 8.85618,-3.6437 8.85618,-8.1378 l 0,-81.37854 c 0,-4.49413 -3.96535,-8.13786 -8.85618,-8.13786 z m 0,89.5164 -123.986482,0 0,-81.37854 123.986482,0 0,81.37854 z" />
|
||||
<path
|
||||
style="overflow:visible;fill:#ffa000"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9"
|
||||
d="m 76.450293,958.84147 c 4.89525,0 8.85617,3.63966 8.85617,8.13786 0,4.4982 -3.96092,8.13785 -8.85617,8.13785 -4.89525,0 -8.85618,-3.63965 -8.85618,-8.13785 0,-4.4982 3.96093,-8.13786 8.85618,-8.13786 m 0,-8.13786 c -9.76837,0 -17.71236,7.29966 -17.71236,16.27572 0,8.97605 7.94399,16.27571 17.71236,16.27571 9.76836,0 17.71235,-7.29966 17.71235,-16.27571 0,-8.97606 -7.94399,-16.27572 -17.71235,-16.27572 l 0,0 z" />
|
||||
<path
|
||||
style="overflow:visible;fill:#b0bec5"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path11"
|
||||
d="m 72.022203,1015.8064 c -1.13249,0 -2.26608,-0.3977 -3.13066,-1.1922 -1.73028,-1.5899 -1.73028,-4.1645 0,-5.7534 l 26.56853,-24.41356 c 1.35832,-1.24001 3.41627,-1.5462 5.111117,-0.76293 l 14.40901,6.62015 24.35006,-29.83338 c 0.85572,-1.05691 2.27493,-1.67335 3.66313,-1.62961 1.44024,0.0397 2.76756,0.71105 3.56351,1.81169 l 17.71235,24.41357 c 1.35832,1.87171 0.80813,4.39444 -1.22769,5.64259 -2.04135,1.23594 -4.79119,0.73953 -6.14065,-1.12811 l -14.24073,-19.62953 -22.81573,27.94947 c -1.27972,1.57773 -3.60668,2.08227 -5.52183,1.20033 l -14.858447,-6.82664 -24.31131,22.33936 c -0.86459,0.7945 -1.99818,1.1922 -3.13066,1.1922 z" />
|
||||
</g>
|
||||
<path
|
||||
d="M 119.125,926.36216 H 8.8750001 c -4.3489688,0 -7.87500049,3.28351 -7.87500049,7.33334 v 73.3334 c 0,4.0498 3.52603169,7.3333 7.87500049,7.3333 H 119.125 c 4.34897,0 7.875,-3.2835 7.875,-7.3333 v -73.3334 c 0,-4.04983 -3.52603,-7.33334 -7.875,-7.33334 z m 0,80.66674 H 8.8750001 V 933.6955 H 119.125 Z"
|
||||
id="path7"
|
||||
inkscape:connector-curvature="0"
|
||||
style="overflow:visible;fill:#2271d5;stroke-width:0.89515448;fill-opacity:1" />
|
||||
<path
|
||||
d="m 32.500002,948.36218 c 4.352905,0 7.874994,3.27984 7.874994,7.33334 0,4.0535 -3.522089,7.33333 -7.874994,7.33333 -4.352904,0 -7.875002,-3.27983 -7.875002,-7.33333 0,-4.0535 3.522098,-7.33334 7.875002,-7.33334 m 0,-7.33335 c -8.68613,0 -15.750004,6.57801 -15.750004,14.66669 0,8.08867 7.063874,14.66667 15.750004,14.66667 8.686122,0 15.749996,-6.578 15.749996,-14.66667 0,-8.08868 -7.063874,-14.66669 -15.749996,-14.66669 z"
|
||||
id="path9"
|
||||
inkscape:connector-curvature="0"
|
||||
style="overflow:visible;fill:#ffa000;stroke-width:0.89515448" />
|
||||
<path
|
||||
d="m 28.562501,999.69549 c -1.007021,0 -2.01502,-0.35838 -2.783813,-1.07434 -1.538582,-1.43272 -1.538582,-3.75279 0,-5.18461 l 23.624997,-22.00001 c 1.207832,-1.11742 3.037781,-1.39334 4.544856,-0.6875 l 12.812633,5.96567 21.652312,-26.88402 c 0.760915,-0.95242 2.022891,-1.50792 3.257292,-1.4685 1.280675,0.0358 2.460941,0.64075 3.168708,1.63258 l 15.749994,22.00002 c 1.20783,1.68667 0.7186,3.96 -1.09167,5.08476 -1.81519,1.11375 -4.26038,0.66642 -5.46033,-1.01659 L 91.374484,958.37402 71.086513,983.56037 c -1.13794,1.42176 -3.207095,1.87642 -4.910066,1.08167 L 52.96417,978.49029 31.346315,998.62115 c -0.768802,0.71596 -1.776801,1.07434 -2.783814,1.07434 z"
|
||||
id="path11"
|
||||
inkscape:connector-curvature="0"
|
||||
style="overflow:visible;fill:#b0bec5;stroke-width:0.89515448" />
|
||||
</g>
|
||||
<image
|
||||
sodipodi:absref="/home/kovid/work/calibre/imgsrc/new/config.svg"
|
||||
sodipodi:absref="/home/kovid/work/calibre/imgsrc/config.svg"
|
||||
xlink:href="config.svg"
|
||||
y="57.85714"
|
||||
x="56.964283"
|
||||
id="image7"
|
||||
width="70.321426"
|
||||
height="69.428574"
|
||||
width="70.321426" />
|
||||
id="image7"
|
||||
x="56.964283"
|
||||
y="57.85714" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.7 KiB |