Repository: Pythonity/icon-font-to-png Branch: master Commit: 4851fe15c077 Files: 26 Total size: 86.3 KB Directory structure: gitextract_vzb55rlz/ ├── .gitignore ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── README.md ├── _config.yml ├── bin/ │ ├── font-awesome-to-png │ └── icon-font-to-png ├── icon_font_to_png/ │ ├── __init__.py │ ├── command_line.py │ ├── icon_font.py │ ├── icon_font_downloader.py │ └── test/ │ ├── files/ │ │ ├── font-awesome.css │ │ ├── octicons.css │ │ ├── test-foo.css │ │ └── test.css │ ├── test_command_line.py │ ├── test_font_awesome.py │ ├── test_icon_font.py │ ├── test_icon_font_downloader.py │ └── test_octicons.py ├── requirements/ │ ├── common.txt │ └── dev.txt ├── requirements.txt ├── setup.py └── tox.ini ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Created by https://www.gitignore.io/api/python,pycharm,osx ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # dotenv .env # virtualenv .venv/ venv/ ENV/ # Spyder project settings .spyderproject # Rope project settings .ropeproject ### PyCharm ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/workspace.xml .idea/tasks.xml # Sensitive or high-churn files: .idea/dataSources/ .idea/dataSources.ids .idea/dataSources.xml .idea/dataSources.local.xml .idea/sqlDataSources.xml .idea/dynamic.xml .idea/uiDesigner.xml # Gradle: .idea/gradle.xml .idea/libraries # Mongo Explorer plugin: .idea/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # IntelliJ /out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties ### PyCharm Patch ### # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 # *.iml # modules.xml # .idea/misc.xml # *.ipr ### OSX ### *.DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk # End of https://www.gitignore.io/api/python,pycharm,osx ================================================ FILE: .travis.yml ================================================ language: python python: - "2.7" - "3.4" - "3.5" - "3.6" install: - pip install -r requirements/dev.txt - pip install tox-travis script: - tox - coverage run --source icon_font_to_png -m py.test - coverage report -m after_success: - coveralls ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016-2017 Pythonity Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ include *.md include *.txt include *.yml include LICENSE include tox.ini recursive-include icon_font_to_png *.css recursive-include icon_font_to_png *.png recursive-include icon_font_to_png *.py recursive-include icon_font_to_png *.ttf recursive-include requirements *.txt ================================================ FILE: README.md ================================================ # Icon Font to PNG [![Build status](https://img.shields.io/travis/Pythonity/icon-font-to-png.svg)][travis] [![Test coverage](https://img.shields.io/coveralls/Pythonity/icon-font-to-png.svg)][coveralls] [![PyPI version](https://img.shields.io/pypi/v/icon_font_to_png.svg)][pypi] [![Python versions](https://img.shields.io/pypi/pyversions/icon_font_to_png.svg)][pypi] [![License](https://img.shields.io/github/license/Pythonity/icon-font-to-png.svg)][license] Python script (and library) for easy and simple export of icons from web icon fonts (e.g. Font Awesome, Octicons) as PNG images. The best part is the provided shell script, but you can also use it's functionality directly in your (*probably awesome*) Python project. There's also `font-awesome-to-png` script for backwards compatibility with the [first][odyniec fa2p] iteration of the concept. ## Installation Make sure you have required packages for [Pillow installation][pillow]. From PyPI (recommended): ``` $ pip install icon_font_to_png ``` With `git clone`: ```shell $ git clone https://github.com/Pythonity/icon-font-to-png $ pip install -r icon-font-to-png/requirements.txt $ cd icon-font-to-png/bin ``` ### OS X As reported [here][if2p osx bug], to install it on OS X: ``` $ pip install icon_font_to_png --ignore-installed six ``` ## Usage ``` usage: icon-font-to-png [-h] [--list] [--download {font-awesome,octicons}] [--ttf TTF-FILE] [--css CSS-FILE] [--size SIZE] [--scale SCALE] [--color COLOR] [--filename FILENAME] [--keep_prefix] [icons [icons ...]] Exports font icons as PNG images. optional arguments: -h, --help show this help message and exit --list list all available icon names and exit --download {font-awesome,octicons} download latest icon font and exit required arguments: --ttf TTF-FILE path to TTF file --css CSS-FILE path to CSS file exporting icons: icons names of the icons to export (or 'ALL' for all icons) --size SIZE icon size in pixels (default: 16) --scale SCALE scaling factor between 0 and 1, or 'auto' for automatic scaling (default: auto); be careful, as setting it may lead to icons being cropped --color COLOR color name or hex value (default: black) --filename FILENAME name of the output file (without '.png' extension); it's used as a prefix if multiple icons are exported --keep_prefix do not remove common icon prefix (i.e. 'fa-arrow- right' instead of 'arrow-right') ``` ## Examples Download latest Font Awesome: ``` $ icon-font-to-png --download font-awesome ``` List all available icons: ``` $ icon-font-to-png --css font-awesome.css --ttf fontawesome-webfont.ttf --list ``` Export 'play' and 'stop' icons, size 64x64: ``` $ icon-font-to-png --css font-awesome.css --ttf fontawesome-webfont.ttf --size 64 play stop ``` Export all icons in blue: ``` $ icon-font-to-png --css font-awesome.css --ttf fontawesome-webfont.ttf --color blue ALL ``` Export all icons in blue, but using it's hex value: ``` $ icon-font-to-png --css font-awesome.css --ttf fontawesome-webfont.ttf --color '#0000ff' ALL ``` Or you can use `font-awesome-to-png`, without css and ttf arguments: ``` $ font-awesome-to-png ALL ``` ## API You can use `IconFont` (and `IconFontDownloader` for that matter) directly inside your Python project. There's no proper documentation as of now, but the code is commented and *should* be pretty straightforward to use. That said - feel free to ask me via [email](mailto:pawel.ad@gmail.com) or [GitHub issues][github add issue] if anything is unclear. ## Tests Package was tested with the help of `py.test` and `tox` on Python 2.7, 3.4, 3.5 and 3.6 (see `tox.ini`). Code coverage is available at [Coveralls][coveralls]. To run tests yourself you need to run `tox` inside the repository: ```shell $ pip install -r requirements/dev.txt $ tox ``` ## Contributions Package source code is available at [GitHub][github]. Feel free to use, ask, fork, star, report bugs, fix them, suggest enhancements, add functionality and point out any mistakes. Thanks! ## Authors Developed and maintained by [Pythonity][pythonity], a group of Python enthusiasts who love open source, have a neat [blog][pythonity blog] and are available [for hire][pythonity]. Original version by [Michał Wojciechowski][odyniec], refactored by [Paweł Adamczak][pawelad]. [coveralls]: https://coveralls.io/github/Pythonity/icon-font-to-png [github]: https://github.com/Pythonity/icon-font-to-png [github add issue]: https://github.com/Pythonity/icon-font-to-png/issues/new [if2p osx bug]: https://github.com/Pythonity/icon-font-to-png/issues/2#issuecomment-197068427 [license]: https://github.com/Pythonity/icon-font-to-png/blob/master/LICENSE [odyniec]: https://github.com/odyniec [odyniec fa2p]: https://github.com/odyniec/font-awesome-to-png [pawelad]: https://github.com/pawelad [pillow]: https://pillow.readthedocs.org/en/latest/installation.html [pypi]: https://pypi.python.org/pypi/icon_font_to_png [pythonity]: https://pythonity.com/ [pythonity blog]: http://blog.pythonity.com/ [travis]: https://travis-ci.org/Pythonity/icon-font-to-png ================================================ FILE: _config.yml ================================================ theme: jekyll-theme-leap-day gems: - jekyll-default-layout - jekyll-optional-front-matter - jekyll-readme-index - jekyll-titles-from-headings ================================================ FILE: bin/font-awesome-to-png ================================================ #!/usr/bin/env python import os import sys try: # Installed system wide from icon_font_to_png import command_line except ImportError: # Locally sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from icon_font_to_png import command_line if __name__ == '__main__': # TODO: Download only once, and load after? # Download Font Awesome to temp directory font_awesome = command_line.download_icon_font('font-awesome', directory=None) # Append paths to Font Awesome files args = sys.argv[1:] args.append('--css') args.append(font_awesome.css_path) args.append('--ttf') args.append(font_awesome.ttf_path) # Execute original script command_line.run(args) ================================================ FILE: bin/icon-font-to-png ================================================ #!/usr/bin/env python import os import sys try: # Installed system wide from icon_font_to_png import command_line except ImportError: # Locally sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from icon_font_to_png import command_line if __name__ == '__main__': command_line.run(sys.argv[1:]) ================================================ FILE: icon_font_to_png/__init__.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals from icon_font_to_png.icon_font import IconFont # noqa from icon_font_to_png.icon_font_downloader import ( # noqa FontAwesomeDownloader, OcticonsDownloader, AVAILABLE_ICON_FONTS ) __version__ = '0.4.1' ================================================ FILE: icon_font_to_png/command_line.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals, print_function import os import argparse from icon_font_to_png import IconFont, AVAILABLE_ICON_FONTS def run(arguments): """Main function for command line usage""" parser = argparse.ArgumentParser( description="Exports font icons as PNG images." ) parser.add_argument( '--list', action='store_true', help="list all available icon names and exit" ) parser.add_argument( '--download', choices=[x for x in AVAILABLE_ICON_FONTS.keys()], help="download latest icon font and exit" ) required_group = parser.add_argument_group("required arguments") required_group.add_argument( '--ttf', metavar='TTF-FILE', type=open, help='path to TTF file' ) required_group.add_argument( '--css', metavar='CSS-FILE', type=open, help="path to CSS file" ) exp_group = parser.add_argument_group("exporting icons") exp_group.add_argument( 'icons', type=str, nargs='*', help="names of the icons to export (or 'ALL' for all icons)" ) exp_group.add_argument( '--size', type=int, default=16, help="icon size in pixels (default: 16)" ) exp_group.add_argument( '--scale', type=str, default='auto', help="scaling factor between 0 and 1, or 'auto' for automatic scaling " "(default: auto); be careful, as setting it may lead to icons " "being cropped" ) exp_group.add_argument( '--color', type=str, default='black', help="color name or hex value (default: black)" ) exp_group.add_argument( '--filename', type=str, help="name of the output file (without '.png' extension); " "it's used as a prefix if multiple icons are exported" ) exp_group.add_argument( '--keep_prefix', default=False, action='store_true', help="do not remove common icon prefix " "(i.e. 'fa-arrow-right' instead of 'arrow-right')" ) args = parser.parse_args(arguments) # Parse '--download' argument first if args.download: downloader = download_icon_font(args.download, os.getcwd()) downloader.download_files() print("Icon font '{name}' successfully downloaded".format( name=args.download) ) parser.exit() # If not '--download', then css and tff files are required if not args.css or not args.ttf: parser.error("You have to provide CSS and TTF files") icon_font = IconFont(css_file=args.css.name, ttf_file=args.ttf.name, keep_prefix=args.keep_prefix) args.css.close() args.ttf.close() # Then '--list' if args.list: for icon in icon_font.css_icons.keys(): print(icon) parser.exit() # If not '--list' or '--download', parse passed icons selected_icons = list() if not args.icons: parser.error("You have to pass at least one icon name") elif args.icons == ['ALL']: selected_icons = icon_font.css_icons.keys() else: for icon in args.icons: if (args.keep_prefix and not icon.startswith(icon_font.common_prefix)): # Prepend icon name with prefix icon = icon_font.common_prefix + icon elif (not args.keep_prefix and icon.startswith(icon_font.common_prefix)): # Remove prefix from icon name icon = icon[len(icon_font.common_prefix):] # Check if given icon names exist if icon in icon_font.css_icons: selected_icons.append(icon) else: parser.error("Unknown icon name '{icon}'".format(icon=icon)) # Parse filename and remove the extension if necessary given_filename = args.filename or '' if given_filename.lower().endswith('.png'): given_filename = given_filename[:-4] # Some fonts have empty values # (prefix only - which we remove - for common styles) selected_icons = list(filter(None, selected_icons)) # Commence exporting for icon in selected_icons: if len(selected_icons) > 1: # Multiple icons - treat the filename option as name prefix filename = '{prefix}{icon}.png'.format( prefix=given_filename, icon=icon, ) else: if given_filename: # Use the specified filename filename = given_filename + '.png' else: # Use icon name as filename filename = str(icon) + '.png' print("Exporting icon '{icon}' as '{filename}'" "({size}x{size} pixels)".format(icon=icon, filename=filename, size=args.size)) icon_font.export_icon(icon=icon, filename=filename, size=args.size, color=args.color, scale=args.scale) print() print("All done") # Isolated for use in wrapper scripts def download_icon_font(icon_font, directory): """Download given (implemented) icon font into passed directory""" try: downloader = AVAILABLE_ICON_FONTS[icon_font]['downloader'](directory) downloader.download_files() return downloader except KeyError: # pragma: no cover raise Exception("We don't support downloading font '{name}'".format( name=icon_font) ) ================================================ FILE: icon_font_to_png/icon_font.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import re from collections import OrderedDict import tinycss from PIL import Image, ImageFont, ImageDraw from six import unichr class IconFont(object): """Base class that represents web icon font""" def __init__(self, css_file, ttf_file, keep_prefix=False): """ :param css_file: path to icon font CSS file :param ttf_file: path to icon font TTF file :param keep_prefix: whether to keep common icon prefix """ self.css_file = css_file self.ttf_file = ttf_file self.keep_prefix = keep_prefix self.css_icons, self.common_prefix = self.load_css() def load_css(self): """ Creates a dict of all icons available in CSS file, and finds out what's their common prefix. :returns sorted icons dict, common icon prefix """ icons = dict() common_prefix = None parser = tinycss.make_parser('page3') stylesheet = parser.parse_stylesheet_file(self.css_file) is_icon = re.compile("\.(.*):before,?") for rule in stylesheet.rules: selector = rule.selector.as_css() # Skip CSS classes that are not icons if not is_icon.match(selector): continue # Find out what the common prefix is if common_prefix is None: common_prefix = selector[1:] else: common_prefix = os.path.commonprefix((common_prefix, selector[1:])) for match in is_icon.finditer(selector): name = match.groups()[0] for declaration in rule.declarations: if declaration.name == "content": val = declaration.value.as_css() # Strip quotation marks if re.match("^['\"].*['\"]$", val): val = val[1:-1] icons[name] = unichr(int(val[1:], 16)) common_prefix = common_prefix or '' # Remove common prefix if not self.keep_prefix and len(common_prefix) > 0: non_prefixed_icons = {} for name in icons.keys(): non_prefixed_icons[name[len(common_prefix):]] = icons[name] icons = non_prefixed_icons sorted_icons = OrderedDict(sorted(icons.items(), key=lambda t: t[0])) return sorted_icons, common_prefix def export_icon(self, icon, size, color='black', scale='auto', filename=None, export_dir='exported'): """ Exports given icon with provided parameters. If the desired icon size is less than 150x150 pixels, we will first create a 150x150 pixels image and then scale it down, so that it's much less likely that the edges of the icon end up cropped. :param icon: valid icon name :param filename: name of the output file :param size: icon size in pixels :param color: color name or hex value :param scale: scaling factor between 0 and 1, or 'auto' for automatic scaling :param export_dir: path to export directory """ org_size = size size = max(150, size) image = Image.new("RGBA", (size, size), color=(0, 0, 0, 0)) draw = ImageDraw.Draw(image) if scale == 'auto': scale_factor = 1 else: scale_factor = float(scale) font = ImageFont.truetype(self.ttf_file, int(size * scale_factor)) width, height = draw.textsize(self.css_icons[icon], font=font) # If auto-scaling is enabled, we need to make sure the resulting # graphic fits inside the boundary. The values are rounded and may be # off by a pixel or two, so we may need to do a few iterations. # The use of a decrementing multiplication factor protects us from # getting into an infinite loop. if scale == 'auto': iteration = 0 factor = 1 while True: width, height = draw.textsize(self.css_icons[icon], font=font) # Check if the image fits dim = max(width, height) if dim > size: font = ImageFont.truetype(self.ttf_file, int(size * size/dim * factor)) else: break # Adjust the factor every two iterations iteration += 1 if iteration % 2 == 0: factor *= 0.99 draw.text((float(size - width) / 2, float(size - height) / 2), self.css_icons[icon], font=font, fill=color) # Get bounding box bbox = image.getbbox() # Create an alpha mask image_mask = Image.new("L", (size, size), 0) draw_mask = ImageDraw.Draw(image_mask) # Draw the icon on the mask draw_mask.text((float(size - width) / 2, float(size - height) / 2), self.css_icons[icon], font=font, fill=255) # Create a solid color image and apply the mask icon_image = Image.new("RGBA", (size, size), color) icon_image.putalpha(image_mask) if bbox: icon_image = icon_image.crop(bbox) border_w = int((size - (bbox[2] - bbox[0])) / 2) border_h = int((size - (bbox[3] - bbox[1])) / 2) # Create output image out_image = Image.new("RGBA", (size, size), (0, 0, 0, 0)) out_image.paste(icon_image, (border_w, border_h)) # If necessary, scale the image to the target size if org_size != size: out_image = out_image.resize((org_size, org_size), Image.ANTIALIAS) # Make sure export directory exists if not os.path.exists(export_dir): os.makedirs(export_dir) # Default filename if not filename: filename = icon + '.png' # Save file out_image.save(os.path.join(export_dir, filename)) ================================================ FILE: icon_font_to_png/icon_font_downloader.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os from abc import ABCMeta, abstractmethod import requests import six from six.moves.urllib.request import urlretrieve @six.add_metaclass(ABCMeta) class IconFontDownloader(object): """Abstract class for downloading icon font CSS and TTF files""" css_path = None ttf_path = None @property def css_url(self): """Icon font CSS file URL""" raise NotImplementedError @property def ttf_url(self): """Icon font TTF file URL""" raise NotImplementedError def __init__(self, directory=None): """ :param directory: path to download directory; temporary dir if None """ self.directory = directory @staticmethod def _download_file_from_url(url, directory=None): """ Download file from given URL and save it in given directory :param url: URL of file :param directory: path to download directory :return: path to downloaded file """ # Files are saved in temporary folder if `directory` isn't specified if not directory: return urlretrieve(url)[0] else: # Get the filename from URL css_filename = os.path.join(directory, url.split('/')[-1]) return urlretrieve(url, filename=css_filename)[0] @staticmethod def _get_latest_tag_from_github(repo_api_url): """Get latest icon font tag via GitHub API""" url = '/'.join([repo_api_url, 'tags']) r = requests.get(url) latest = r.json()[0] return latest['name'] @abstractmethod def get_latest_version_number(self): """Get latest icon font version number""" return def download_css(self, directory): """Downloads icon font CSS file and returns its path""" return self._download_file_from_url(self.css_url, directory) def download_ttf(self, directory): """Downloads icon font TTF file and returns its path""" return self._download_file_from_url(self.ttf_url, directory) def download_files(self): """Download CSS and TTF files""" self.css_path = self.download_css(self.directory) self.ttf_path = self.download_ttf(self.directory) class FontAwesomeDownloader(IconFontDownloader): """ Font Awesome icon font downloader. Project page: https://fortawesome.github.io/Font-Awesome/ """ css_url = ( 'https://cdn.rawgit.com/FortAwesome/Font-Awesome/' 'master/css/font-awesome.css' ) ttf_url = ( 'https://cdn.rawgit.com/FortAwesome/Font-Awesome/' 'master/fonts/fontawesome-webfont.ttf' ) def get_latest_version_number(self): return self._get_latest_tag_from_github( 'https://api.github.com/repos/FortAwesome/Font-Awesome' ) class OcticonsDownloader(IconFontDownloader): """ Octicons icon font downloader. They unfortunately deleted compiled files from their GitHub repo, so let's get them via CDN fow now. Project page: https://octicons.github.com/ """ css_url = ( 'https://cdnjs.cloudflare.com/ajax/libs/' 'octicons/4.4.0/font/octicons.css' ) ttf_url = ( 'https://cdnjs.cloudflare.com/ajax/libs/' 'octicons/4.4.0/font/octicons.ttf' ) def get_latest_version_number(self): return self._get_latest_tag_from_github( 'https://api.github.com/repos/github/octicons' ) # List of implemented icon font downloader classes AVAILABLE_ICON_FONTS = { 'font-awesome': { 'name': 'Font Awesome', 'downloader': FontAwesomeDownloader, }, 'octicons': { 'name': 'Octicons', 'downloader': OcticonsDownloader, }, } ================================================ FILE: icon_font_to_png/test/files/font-awesome.css ================================================ /*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ @font-face { font-family: 'FontAwesome'; src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } .fa { display: inline-block; font: normal normal normal 14px/1 FontAwesome; font-size: inherit; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* makes the font 33% larger relative to the icon container */ .fa-lg { font-size: 1.33333333em; line-height: 0.75em; vertical-align: -15%; } .fa-2x { font-size: 2em; } .fa-3x { font-size: 3em; } .fa-4x { font-size: 4em; } .fa-5x { font-size: 5em; } .fa-fw { width: 1.28571429em; text-align: center; } .fa-ul { padding-left: 0; margin-left: 2.14285714em; list-style-type: none; } .fa-ul > li { position: relative; } .fa-li { position: absolute; left: -2.14285714em; width: 2.14285714em; top: 0.14285714em; text-align: center; } .fa-li.fa-lg { left: -1.85714286em; } .fa-border { padding: .2em .25em .15em; border: solid 0.08em #eeeeee; border-radius: .1em; } .fa-pull-left { float: left; } .fa-pull-right { float: right; } .fa.fa-pull-left { margin-right: .3em; } .fa.fa-pull-right { margin-left: .3em; } /* Deprecated as of 4.4.0 */ .pull-right { float: right; } .pull-left { float: left; } .fa.pull-left { margin-right: .3em; } .fa.pull-right { margin-left: .3em; } .fa-spin { -webkit-animation: fa-spin 2s infinite linear; animation: fa-spin 2s infinite linear; } .fa-pulse { -webkit-animation: fa-spin 1s infinite steps(8); animation: fa-spin 1s infinite steps(8); } @-webkit-keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); transform: rotate(359deg); } } @keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); transform: rotate(359deg); } } .fa-rotate-90 { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .fa-rotate-180 { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } .fa-rotate-270 { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); } .fa-flip-horizontal { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; -webkit-transform: scale(-1, 1); -ms-transform: scale(-1, 1); transform: scale(-1, 1); } .fa-flip-vertical { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; -webkit-transform: scale(1, -1); -ms-transform: scale(1, -1); transform: scale(1, -1); } :root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270, :root .fa-flip-horizontal, :root .fa-flip-vertical { filter: none; } .fa-stack { position: relative; display: inline-block; width: 2em; height: 2em; line-height: 2em; vertical-align: middle; } .fa-stack-1x, .fa-stack-2x { position: absolute; left: 0; width: 100%; text-align: center; } .fa-stack-1x { line-height: inherit; } .fa-stack-2x { font-size: 2em; } .fa-inverse { color: #ffffff; } /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .fa-glass:before { content: "\f000"; } .fa-music:before { content: "\f001"; } .fa-search:before { content: "\f002"; } .fa-envelope-o:before { content: "\f003"; } .fa-heart:before { content: "\f004"; } .fa-star:before { content: "\f005"; } .fa-star-o:before { content: "\f006"; } .fa-user:before { content: "\f007"; } .fa-film:before { content: "\f008"; } .fa-th-large:before { content: "\f009"; } .fa-th:before { content: "\f00a"; } .fa-th-list:before { content: "\f00b"; } .fa-check:before { content: "\f00c"; } .fa-remove:before, .fa-close:before, .fa-times:before { content: "\f00d"; } .fa-search-plus:before { content: "\f00e"; } .fa-search-minus:before { content: "\f010"; } .fa-power-off:before { content: "\f011"; } .fa-signal:before { content: "\f012"; } .fa-gear:before, .fa-cog:before { content: "\f013"; } .fa-trash-o:before { content: "\f014"; } .fa-home:before { content: "\f015"; } .fa-file-o:before { content: "\f016"; } .fa-clock-o:before { content: "\f017"; } .fa-road:before { content: "\f018"; } .fa-download:before { content: "\f019"; } .fa-arrow-circle-o-down:before { content: "\f01a"; } .fa-arrow-circle-o-up:before { content: "\f01b"; } .fa-inbox:before { content: "\f01c"; } .fa-play-circle-o:before { content: "\f01d"; } .fa-rotate-right:before, .fa-repeat:before { content: "\f01e"; } .fa-refresh:before { content: "\f021"; } .fa-list-alt:before { content: "\f022"; } .fa-lock:before { content: "\f023"; } .fa-flag:before { content: "\f024"; } .fa-headphones:before { content: "\f025"; } .fa-volume-off:before { content: "\f026"; } .fa-volume-down:before { content: "\f027"; } .fa-volume-up:before { content: "\f028"; } .fa-qrcode:before { content: "\f029"; } .fa-barcode:before { content: "\f02a"; } .fa-tag:before { content: "\f02b"; } .fa-tags:before { content: "\f02c"; } .fa-book:before { content: "\f02d"; } .fa-bookmark:before { content: "\f02e"; } .fa-print:before { content: "\f02f"; } .fa-camera:before { content: "\f030"; } .fa-font:before { content: "\f031"; } .fa-bold:before { content: "\f032"; } .fa-italic:before { content: "\f033"; } .fa-text-height:before { content: "\f034"; } .fa-text-width:before { content: "\f035"; } .fa-align-left:before { content: "\f036"; } .fa-align-center:before { content: "\f037"; } .fa-align-right:before { content: "\f038"; } .fa-align-justify:before { content: "\f039"; } .fa-list:before { content: "\f03a"; } .fa-dedent:before, .fa-outdent:before { content: "\f03b"; } .fa-indent:before { content: "\f03c"; } .fa-video-camera:before { content: "\f03d"; } .fa-photo:before, .fa-image:before, .fa-picture-o:before { content: "\f03e"; } .fa-pencil:before { content: "\f040"; } .fa-map-marker:before { content: "\f041"; } .fa-adjust:before { content: "\f042"; } .fa-tint:before { content: "\f043"; } .fa-edit:before, .fa-pencil-square-o:before { content: "\f044"; } .fa-share-square-o:before { content: "\f045"; } .fa-check-square-o:before { content: "\f046"; } .fa-arrows:before { content: "\f047"; } .fa-step-backward:before { content: "\f048"; } .fa-fast-backward:before { content: "\f049"; } .fa-backward:before { content: "\f04a"; } .fa-play:before { content: "\f04b"; } .fa-pause:before { content: "\f04c"; } .fa-stop:before { content: "\f04d"; } .fa-forward:before { content: "\f04e"; } .fa-fast-forward:before { content: "\f050"; } .fa-step-forward:before { content: "\f051"; } .fa-eject:before { content: "\f052"; } .fa-chevron-left:before { content: "\f053"; } .fa-chevron-right:before { content: "\f054"; } .fa-plus-circle:before { content: "\f055"; } .fa-minus-circle:before { content: "\f056"; } .fa-times-circle:before { content: "\f057"; } .fa-check-circle:before { content: "\f058"; } .fa-question-circle:before { content: "\f059"; } .fa-info-circle:before { content: "\f05a"; } .fa-crosshairs:before { content: "\f05b"; } .fa-times-circle-o:before { content: "\f05c"; } .fa-check-circle-o:before { content: "\f05d"; } .fa-ban:before { content: "\f05e"; } .fa-arrow-left:before { content: "\f060"; } .fa-arrow-right:before { content: "\f061"; } .fa-arrow-up:before { content: "\f062"; } .fa-arrow-down:before { content: "\f063"; } .fa-mail-forward:before, .fa-share:before { content: "\f064"; } .fa-expand:before { content: "\f065"; } .fa-compress:before { content: "\f066"; } .fa-plus:before { content: "\f067"; } .fa-minus:before { content: "\f068"; } .fa-asterisk:before { content: "\f069"; } .fa-exclamation-circle:before { content: "\f06a"; } .fa-gift:before { content: "\f06b"; } .fa-leaf:before { content: "\f06c"; } .fa-fire:before { content: "\f06d"; } .fa-eye:before { content: "\f06e"; } .fa-eye-slash:before { content: "\f070"; } .fa-warning:before, .fa-exclamation-triangle:before { content: "\f071"; } .fa-plane:before { content: "\f072"; } .fa-calendar:before { content: "\f073"; } .fa-random:before { content: "\f074"; } .fa-comment:before { content: "\f075"; } .fa-magnet:before { content: "\f076"; } .fa-chevron-up:before { content: "\f077"; } .fa-chevron-down:before { content: "\f078"; } .fa-retweet:before { content: "\f079"; } .fa-shopping-cart:before { content: "\f07a"; } .fa-folder:before { content: "\f07b"; } .fa-folder-open:before { content: "\f07c"; } .fa-arrows-v:before { content: "\f07d"; } .fa-arrows-h:before { content: "\f07e"; } .fa-bar-chart-o:before, .fa-bar-chart:before { content: "\f080"; } .fa-twitter-square:before { content: "\f081"; } .fa-facebook-square:before { content: "\f082"; } .fa-camera-retro:before { content: "\f083"; } .fa-key:before { content: "\f084"; } .fa-gears:before, .fa-cogs:before { content: "\f085"; } .fa-comments:before { content: "\f086"; } .fa-thumbs-o-up:before { content: "\f087"; } .fa-thumbs-o-down:before { content: "\f088"; } .fa-star-half:before { content: "\f089"; } .fa-heart-o:before { content: "\f08a"; } .fa-sign-out:before { content: "\f08b"; } .fa-linkedin-square:before { content: "\f08c"; } .fa-thumb-tack:before { content: "\f08d"; } .fa-external-link:before { content: "\f08e"; } .fa-sign-in:before { content: "\f090"; } .fa-trophy:before { content: "\f091"; } .fa-github-square:before { content: "\f092"; } .fa-upload:before { content: "\f093"; } .fa-lemon-o:before { content: "\f094"; } .fa-phone:before { content: "\f095"; } .fa-square-o:before { content: "\f096"; } .fa-bookmark-o:before { content: "\f097"; } .fa-phone-square:before { content: "\f098"; } .fa-twitter:before { content: "\f099"; } .fa-facebook-f:before, .fa-facebook:before { content: "\f09a"; } .fa-github:before { content: "\f09b"; } .fa-unlock:before { content: "\f09c"; } .fa-credit-card:before { content: "\f09d"; } .fa-feed:before, .fa-rss:before { content: "\f09e"; } .fa-hdd-o:before { content: "\f0a0"; } .fa-bullhorn:before { content: "\f0a1"; } .fa-bell:before { content: "\f0f3"; } .fa-certificate:before { content: "\f0a3"; } .fa-hand-o-right:before { content: "\f0a4"; } .fa-hand-o-left:before { content: "\f0a5"; } .fa-hand-o-up:before { content: "\f0a6"; } .fa-hand-o-down:before { content: "\f0a7"; } .fa-arrow-circle-left:before { content: "\f0a8"; } .fa-arrow-circle-right:before { content: "\f0a9"; } .fa-arrow-circle-up:before { content: "\f0aa"; } .fa-arrow-circle-down:before { content: "\f0ab"; } .fa-globe:before { content: "\f0ac"; } .fa-wrench:before { content: "\f0ad"; } .fa-tasks:before { content: "\f0ae"; } .fa-filter:before { content: "\f0b0"; } .fa-briefcase:before { content: "\f0b1"; } .fa-arrows-alt:before { content: "\f0b2"; } .fa-group:before, .fa-users:before { content: "\f0c0"; } .fa-chain:before, .fa-link:before { content: "\f0c1"; } .fa-cloud:before { content: "\f0c2"; } .fa-flask:before { content: "\f0c3"; } .fa-cut:before, .fa-scissors:before { content: "\f0c4"; } .fa-copy:before, .fa-files-o:before { content: "\f0c5"; } .fa-paperclip:before { content: "\f0c6"; } .fa-save:before, .fa-floppy-o:before { content: "\f0c7"; } .fa-square:before { content: "\f0c8"; } .fa-navicon:before, .fa-reorder:before, .fa-bars:before { content: "\f0c9"; } .fa-list-ul:before { content: "\f0ca"; } .fa-list-ol:before { content: "\f0cb"; } .fa-strikethrough:before { content: "\f0cc"; } .fa-underline:before { content: "\f0cd"; } .fa-table:before { content: "\f0ce"; } .fa-magic:before { content: "\f0d0"; } .fa-truck:before { content: "\f0d1"; } .fa-pinterest:before { content: "\f0d2"; } .fa-pinterest-square:before { content: "\f0d3"; } .fa-google-plus-square:before { content: "\f0d4"; } .fa-google-plus:before { content: "\f0d5"; } .fa-money:before { content: "\f0d6"; } .fa-caret-down:before { content: "\f0d7"; } .fa-caret-up:before { content: "\f0d8"; } .fa-caret-left:before { content: "\f0d9"; } .fa-caret-right:before { content: "\f0da"; } .fa-columns:before { content: "\f0db"; } .fa-unsorted:before, .fa-sort:before { content: "\f0dc"; } .fa-sort-down:before, .fa-sort-desc:before { content: "\f0dd"; } .fa-sort-up:before, .fa-sort-asc:before { content: "\f0de"; } .fa-envelope:before { content: "\f0e0"; } .fa-linkedin:before { content: "\f0e1"; } .fa-rotate-left:before, .fa-undo:before { content: "\f0e2"; } .fa-legal:before, .fa-gavel:before { content: "\f0e3"; } .fa-dashboard:before, .fa-tachometer:before { content: "\f0e4"; } .fa-comment-o:before { content: "\f0e5"; } .fa-comments-o:before { content: "\f0e6"; } .fa-flash:before, .fa-bolt:before { content: "\f0e7"; } .fa-sitemap:before { content: "\f0e8"; } .fa-umbrella:before { content: "\f0e9"; } .fa-paste:before, .fa-clipboard:before { content: "\f0ea"; } .fa-lightbulb-o:before { content: "\f0eb"; } .fa-exchange:before { content: "\f0ec"; } .fa-cloud-download:before { content: "\f0ed"; } .fa-cloud-upload:before { content: "\f0ee"; } .fa-user-md:before { content: "\f0f0"; } .fa-stethoscope:before { content: "\f0f1"; } .fa-suitcase:before { content: "\f0f2"; } .fa-bell-o:before { content: "\f0a2"; } .fa-coffee:before { content: "\f0f4"; } .fa-cutlery:before { content: "\f0f5"; } .fa-file-text-o:before { content: "\f0f6"; } .fa-building-o:before { content: "\f0f7"; } .fa-hospital-o:before { content: "\f0f8"; } .fa-ambulance:before { content: "\f0f9"; } .fa-medkit:before { content: "\f0fa"; } .fa-fighter-jet:before { content: "\f0fb"; } .fa-beer:before { content: "\f0fc"; } .fa-h-square:before { content: "\f0fd"; } .fa-plus-square:before { content: "\f0fe"; } .fa-angle-double-left:before { content: "\f100"; } .fa-angle-double-right:before { content: "\f101"; } .fa-angle-double-up:before { content: "\f102"; } .fa-angle-double-down:before { content: "\f103"; } .fa-angle-left:before { content: "\f104"; } .fa-angle-right:before { content: "\f105"; } .fa-angle-up:before { content: "\f106"; } .fa-angle-down:before { content: "\f107"; } .fa-desktop:before { content: "\f108"; } .fa-laptop:before { content: "\f109"; } .fa-tablet:before { content: "\f10a"; } .fa-mobile-phone:before, .fa-mobile:before { content: "\f10b"; } .fa-circle-o:before { content: "\f10c"; } .fa-quote-left:before { content: "\f10d"; } .fa-quote-right:before { content: "\f10e"; } .fa-spinner:before { content: "\f110"; } .fa-circle:before { content: "\f111"; } .fa-mail-reply:before, .fa-reply:before { content: "\f112"; } .fa-github-alt:before { content: "\f113"; } .fa-folder-o:before { content: "\f114"; } .fa-folder-open-o:before { content: "\f115"; } .fa-smile-o:before { content: "\f118"; } .fa-frown-o:before { content: "\f119"; } .fa-meh-o:before { content: "\f11a"; } .fa-gamepad:before { content: "\f11b"; } .fa-keyboard-o:before { content: "\f11c"; } .fa-flag-o:before { content: "\f11d"; } .fa-flag-checkered:before { content: "\f11e"; } .fa-terminal:before { content: "\f120"; } .fa-code:before { content: "\f121"; } .fa-mail-reply-all:before, .fa-reply-all:before { content: "\f122"; } .fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before { content: "\f123"; } .fa-location-arrow:before { content: "\f124"; } .fa-crop:before { content: "\f125"; } .fa-code-fork:before { content: "\f126"; } .fa-unlink:before, .fa-chain-broken:before { content: "\f127"; } .fa-question:before { content: "\f128"; } .fa-info:before { content: "\f129"; } .fa-exclamation:before { content: "\f12a"; } .fa-superscript:before { content: "\f12b"; } .fa-subscript:before { content: "\f12c"; } .fa-eraser:before { content: "\f12d"; } .fa-puzzle-piece:before { content: "\f12e"; } .fa-microphone:before { content: "\f130"; } .fa-microphone-slash:before { content: "\f131"; } .fa-shield:before { content: "\f132"; } .fa-calendar-o:before { content: "\f133"; } .fa-fire-extinguisher:before { content: "\f134"; } .fa-rocket:before { content: "\f135"; } .fa-maxcdn:before { content: "\f136"; } .fa-chevron-circle-left:before { content: "\f137"; } .fa-chevron-circle-right:before { content: "\f138"; } .fa-chevron-circle-up:before { content: "\f139"; } .fa-chevron-circle-down:before { content: "\f13a"; } .fa-html5:before { content: "\f13b"; } .fa-css3:before { content: "\f13c"; } .fa-anchor:before { content: "\f13d"; } .fa-unlock-alt:before { content: "\f13e"; } .fa-bullseye:before { content: "\f140"; } .fa-ellipsis-h:before { content: "\f141"; } .fa-ellipsis-v:before { content: "\f142"; } .fa-rss-square:before { content: "\f143"; } .fa-play-circle:before { content: "\f144"; } .fa-ticket:before { content: "\f145"; } .fa-minus-square:before { content: "\f146"; } .fa-minus-square-o:before { content: "\f147"; } .fa-level-up:before { content: "\f148"; } .fa-level-down:before { content: "\f149"; } .fa-check-square:before { content: "\f14a"; } .fa-pencil-square:before { content: "\f14b"; } .fa-external-link-square:before { content: "\f14c"; } .fa-share-square:before { content: "\f14d"; } .fa-compass:before { content: "\f14e"; } .fa-toggle-down:before, .fa-caret-square-o-down:before { content: "\f150"; } .fa-toggle-up:before, .fa-caret-square-o-up:before { content: "\f151"; } .fa-toggle-right:before, .fa-caret-square-o-right:before { content: "\f152"; } .fa-euro:before, .fa-eur:before { content: "\f153"; } .fa-gbp:before { content: "\f154"; } .fa-dollar:before, .fa-usd:before { content: "\f155"; } .fa-rupee:before, .fa-inr:before { content: "\f156"; } .fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before { content: "\f157"; } .fa-ruble:before, .fa-rouble:before, .fa-rub:before { content: "\f158"; } .fa-won:before, .fa-krw:before { content: "\f159"; } .fa-bitcoin:before, .fa-btc:before { content: "\f15a"; } .fa-file:before { content: "\f15b"; } .fa-file-text:before { content: "\f15c"; } .fa-sort-alpha-asc:before { content: "\f15d"; } .fa-sort-alpha-desc:before { content: "\f15e"; } .fa-sort-amount-asc:before { content: "\f160"; } .fa-sort-amount-desc:before { content: "\f161"; } .fa-sort-numeric-asc:before { content: "\f162"; } .fa-sort-numeric-desc:before { content: "\f163"; } .fa-thumbs-up:before { content: "\f164"; } .fa-thumbs-down:before { content: "\f165"; } .fa-youtube-square:before { content: "\f166"; } .fa-youtube:before { content: "\f167"; } .fa-xing:before { content: "\f168"; } .fa-xing-square:before { content: "\f169"; } .fa-youtube-play:before { content: "\f16a"; } .fa-dropbox:before { content: "\f16b"; } .fa-stack-overflow:before { content: "\f16c"; } .fa-instagram:before { content: "\f16d"; } .fa-flickr:before { content: "\f16e"; } .fa-adn:before { content: "\f170"; } .fa-bitbucket:before { content: "\f171"; } .fa-bitbucket-square:before { content: "\f172"; } .fa-tumblr:before { content: "\f173"; } .fa-tumblr-square:before { content: "\f174"; } .fa-long-arrow-down:before { content: "\f175"; } .fa-long-arrow-up:before { content: "\f176"; } .fa-long-arrow-left:before { content: "\f177"; } .fa-long-arrow-right:before { content: "\f178"; } .fa-apple:before { content: "\f179"; } .fa-windows:before { content: "\f17a"; } .fa-android:before { content: "\f17b"; } .fa-linux:before { content: "\f17c"; } .fa-dribbble:before { content: "\f17d"; } .fa-skype:before { content: "\f17e"; } .fa-foursquare:before { content: "\f180"; } .fa-trello:before { content: "\f181"; } .fa-female:before { content: "\f182"; } .fa-male:before { content: "\f183"; } .fa-gittip:before, .fa-gratipay:before { content: "\f184"; } .fa-sun-o:before { content: "\f185"; } .fa-moon-o:before { content: "\f186"; } .fa-archive:before { content: "\f187"; } .fa-bug:before { content: "\f188"; } .fa-vk:before { content: "\f189"; } .fa-weibo:before { content: "\f18a"; } .fa-renren:before { content: "\f18b"; } .fa-pagelines:before { content: "\f18c"; } .fa-stack-exchange:before { content: "\f18d"; } .fa-arrow-circle-o-right:before { content: "\f18e"; } .fa-arrow-circle-o-left:before { content: "\f190"; } .fa-toggle-left:before, .fa-caret-square-o-left:before { content: "\f191"; } .fa-dot-circle-o:before { content: "\f192"; } .fa-wheelchair:before { content: "\f193"; } .fa-vimeo-square:before { content: "\f194"; } .fa-turkish-lira:before, .fa-try:before { content: "\f195"; } .fa-plus-square-o:before { content: "\f196"; } .fa-space-shuttle:before { content: "\f197"; } .fa-slack:before { content: "\f198"; } .fa-envelope-square:before { content: "\f199"; } .fa-wordpress:before { content: "\f19a"; } .fa-openid:before { content: "\f19b"; } .fa-institution:before, .fa-bank:before, .fa-university:before { content: "\f19c"; } .fa-mortar-board:before, .fa-graduation-cap:before { content: "\f19d"; } .fa-yahoo:before { content: "\f19e"; } .fa-google:before { content: "\f1a0"; } .fa-reddit:before { content: "\f1a1"; } .fa-reddit-square:before { content: "\f1a2"; } .fa-stumbleupon-circle:before { content: "\f1a3"; } .fa-stumbleupon:before { content: "\f1a4"; } .fa-delicious:before { content: "\f1a5"; } .fa-digg:before { content: "\f1a6"; } .fa-pied-piper-pp:before { content: "\f1a7"; } .fa-pied-piper-alt:before { content: "\f1a8"; } .fa-drupal:before { content: "\f1a9"; } .fa-joomla:before { content: "\f1aa"; } .fa-language:before { content: "\f1ab"; } .fa-fax:before { content: "\f1ac"; } .fa-building:before { content: "\f1ad"; } .fa-child:before { content: "\f1ae"; } .fa-paw:before { content: "\f1b0"; } .fa-spoon:before { content: "\f1b1"; } .fa-cube:before { content: "\f1b2"; } .fa-cubes:before { content: "\f1b3"; } .fa-behance:before { content: "\f1b4"; } .fa-behance-square:before { content: "\f1b5"; } .fa-steam:before { content: "\f1b6"; } .fa-steam-square:before { content: "\f1b7"; } .fa-recycle:before { content: "\f1b8"; } .fa-automobile:before, .fa-car:before { content: "\f1b9"; } .fa-cab:before, .fa-taxi:before { content: "\f1ba"; } .fa-tree:before { content: "\f1bb"; } .fa-spotify:before { content: "\f1bc"; } .fa-deviantart:before { content: "\f1bd"; } .fa-soundcloud:before { content: "\f1be"; } .fa-database:before { content: "\f1c0"; } .fa-file-pdf-o:before { content: "\f1c1"; } .fa-file-word-o:before { content: "\f1c2"; } .fa-file-excel-o:before { content: "\f1c3"; } .fa-file-powerpoint-o:before { content: "\f1c4"; } .fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before { content: "\f1c5"; } .fa-file-zip-o:before, .fa-file-archive-o:before { content: "\f1c6"; } .fa-file-sound-o:before, .fa-file-audio-o:before { content: "\f1c7"; } .fa-file-movie-o:before, .fa-file-video-o:before { content: "\f1c8"; } .fa-file-code-o:before { content: "\f1c9"; } .fa-vine:before { content: "\f1ca"; } .fa-codepen:before { content: "\f1cb"; } .fa-jsfiddle:before { content: "\f1cc"; } .fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before { content: "\f1cd"; } .fa-circle-o-notch:before { content: "\f1ce"; } .fa-ra:before, .fa-resistance:before, .fa-rebel:before { content: "\f1d0"; } .fa-ge:before, .fa-empire:before { content: "\f1d1"; } .fa-git-square:before { content: "\f1d2"; } .fa-git:before { content: "\f1d3"; } .fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before { content: "\f1d4"; } .fa-tencent-weibo:before { content: "\f1d5"; } .fa-qq:before { content: "\f1d6"; } .fa-wechat:before, .fa-weixin:before { content: "\f1d7"; } .fa-send:before, .fa-paper-plane:before { content: "\f1d8"; } .fa-send-o:before, .fa-paper-plane-o:before { content: "\f1d9"; } .fa-history:before { content: "\f1da"; } .fa-circle-thin:before { content: "\f1db"; } .fa-header:before { content: "\f1dc"; } .fa-paragraph:before { content: "\f1dd"; } .fa-sliders:before { content: "\f1de"; } .fa-share-alt:before { content: "\f1e0"; } .fa-share-alt-square:before { content: "\f1e1"; } .fa-bomb:before { content: "\f1e2"; } .fa-soccer-ball-o:before, .fa-futbol-o:before { content: "\f1e3"; } .fa-tty:before { content: "\f1e4"; } .fa-binoculars:before { content: "\f1e5"; } .fa-plug:before { content: "\f1e6"; } .fa-slideshare:before { content: "\f1e7"; } .fa-twitch:before { content: "\f1e8"; } .fa-yelp:before { content: "\f1e9"; } .fa-newspaper-o:before { content: "\f1ea"; } .fa-wifi:before { content: "\f1eb"; } .fa-calculator:before { content: "\f1ec"; } .fa-paypal:before { content: "\f1ed"; } .fa-google-wallet:before { content: "\f1ee"; } .fa-cc-visa:before { content: "\f1f0"; } .fa-cc-mastercard:before { content: "\f1f1"; } .fa-cc-discover:before { content: "\f1f2"; } .fa-cc-amex:before { content: "\f1f3"; } .fa-cc-paypal:before { content: "\f1f4"; } .fa-cc-stripe:before { content: "\f1f5"; } .fa-bell-slash:before { content: "\f1f6"; } .fa-bell-slash-o:before { content: "\f1f7"; } .fa-trash:before { content: "\f1f8"; } .fa-copyright:before { content: "\f1f9"; } .fa-at:before { content: "\f1fa"; } .fa-eyedropper:before { content: "\f1fb"; } .fa-paint-brush:before { content: "\f1fc"; } .fa-birthday-cake:before { content: "\f1fd"; } .fa-area-chart:before { content: "\f1fe"; } .fa-pie-chart:before { content: "\f200"; } .fa-line-chart:before { content: "\f201"; } .fa-lastfm:before { content: "\f202"; } .fa-lastfm-square:before { content: "\f203"; } .fa-toggle-off:before { content: "\f204"; } .fa-toggle-on:before { content: "\f205"; } .fa-bicycle:before { content: "\f206"; } .fa-bus:before { content: "\f207"; } .fa-ioxhost:before { content: "\f208"; } .fa-angellist:before { content: "\f209"; } .fa-cc:before { content: "\f20a"; } .fa-shekel:before, .fa-sheqel:before, .fa-ils:before { content: "\f20b"; } .fa-meanpath:before { content: "\f20c"; } .fa-buysellads:before { content: "\f20d"; } .fa-connectdevelop:before { content: "\f20e"; } .fa-dashcube:before { content: "\f210"; } .fa-forumbee:before { content: "\f211"; } .fa-leanpub:before { content: "\f212"; } .fa-sellsy:before { content: "\f213"; } .fa-shirtsinbulk:before { content: "\f214"; } .fa-simplybuilt:before { content: "\f215"; } .fa-skyatlas:before { content: "\f216"; } .fa-cart-plus:before { content: "\f217"; } .fa-cart-arrow-down:before { content: "\f218"; } .fa-diamond:before { content: "\f219"; } .fa-ship:before { content: "\f21a"; } .fa-user-secret:before { content: "\f21b"; } .fa-motorcycle:before { content: "\f21c"; } .fa-street-view:before { content: "\f21d"; } .fa-heartbeat:before { content: "\f21e"; } .fa-venus:before { content: "\f221"; } .fa-mars:before { content: "\f222"; } .fa-mercury:before { content: "\f223"; } .fa-intersex:before, .fa-transgender:before { content: "\f224"; } .fa-transgender-alt:before { content: "\f225"; } .fa-venus-double:before { content: "\f226"; } .fa-mars-double:before { content: "\f227"; } .fa-venus-mars:before { content: "\f228"; } .fa-mars-stroke:before { content: "\f229"; } .fa-mars-stroke-v:before { content: "\f22a"; } .fa-mars-stroke-h:before { content: "\f22b"; } .fa-neuter:before { content: "\f22c"; } .fa-genderless:before { content: "\f22d"; } .fa-facebook-official:before { content: "\f230"; } .fa-pinterest-p:before { content: "\f231"; } .fa-whatsapp:before { content: "\f232"; } .fa-server:before { content: "\f233"; } .fa-user-plus:before { content: "\f234"; } .fa-user-times:before { content: "\f235"; } .fa-hotel:before, .fa-bed:before { content: "\f236"; } .fa-viacoin:before { content: "\f237"; } .fa-train:before { content: "\f238"; } .fa-subway:before { content: "\f239"; } .fa-medium:before { content: "\f23a"; } .fa-yc:before, .fa-y-combinator:before { content: "\f23b"; } .fa-optin-monster:before { content: "\f23c"; } .fa-opencart:before { content: "\f23d"; } .fa-expeditedssl:before { content: "\f23e"; } .fa-battery-4:before, .fa-battery:before, .fa-battery-full:before { content: "\f240"; } .fa-battery-3:before, .fa-battery-three-quarters:before { content: "\f241"; } .fa-battery-2:before, .fa-battery-half:before { content: "\f242"; } .fa-battery-1:before, .fa-battery-quarter:before { content: "\f243"; } .fa-battery-0:before, .fa-battery-empty:before { content: "\f244"; } .fa-mouse-pointer:before { content: "\f245"; } .fa-i-cursor:before { content: "\f246"; } .fa-object-group:before { content: "\f247"; } .fa-object-ungroup:before { content: "\f248"; } .fa-sticky-note:before { content: "\f249"; } .fa-sticky-note-o:before { content: "\f24a"; } .fa-cc-jcb:before { content: "\f24b"; } .fa-cc-diners-club:before { content: "\f24c"; } .fa-clone:before { content: "\f24d"; } .fa-balance-scale:before { content: "\f24e"; } .fa-hourglass-o:before { content: "\f250"; } .fa-hourglass-1:before, .fa-hourglass-start:before { content: "\f251"; } .fa-hourglass-2:before, .fa-hourglass-half:before { content: "\f252"; } .fa-hourglass-3:before, .fa-hourglass-end:before { content: "\f253"; } .fa-hourglass:before { content: "\f254"; } .fa-hand-grab-o:before, .fa-hand-rock-o:before { content: "\f255"; } .fa-hand-stop-o:before, .fa-hand-paper-o:before { content: "\f256"; } .fa-hand-scissors-o:before { content: "\f257"; } .fa-hand-lizard-o:before { content: "\f258"; } .fa-hand-spock-o:before { content: "\f259"; } .fa-hand-pointer-o:before { content: "\f25a"; } .fa-hand-peace-o:before { content: "\f25b"; } .fa-trademark:before { content: "\f25c"; } .fa-registered:before { content: "\f25d"; } .fa-creative-commons:before { content: "\f25e"; } .fa-gg:before { content: "\f260"; } .fa-gg-circle:before { content: "\f261"; } .fa-tripadvisor:before { content: "\f262"; } .fa-odnoklassniki:before { content: "\f263"; } .fa-odnoklassniki-square:before { content: "\f264"; } .fa-get-pocket:before { content: "\f265"; } .fa-wikipedia-w:before { content: "\f266"; } .fa-safari:before { content: "\f267"; } .fa-chrome:before { content: "\f268"; } .fa-firefox:before { content: "\f269"; } .fa-opera:before { content: "\f26a"; } .fa-internet-explorer:before { content: "\f26b"; } .fa-tv:before, .fa-television:before { content: "\f26c"; } .fa-contao:before { content: "\f26d"; } .fa-500px:before { content: "\f26e"; } .fa-amazon:before { content: "\f270"; } .fa-calendar-plus-o:before { content: "\f271"; } .fa-calendar-minus-o:before { content: "\f272"; } .fa-calendar-times-o:before { content: "\f273"; } .fa-calendar-check-o:before { content: "\f274"; } .fa-industry:before { content: "\f275"; } .fa-map-pin:before { content: "\f276"; } .fa-map-signs:before { content: "\f277"; } .fa-map-o:before { content: "\f278"; } .fa-map:before { content: "\f279"; } .fa-commenting:before { content: "\f27a"; } .fa-commenting-o:before { content: "\f27b"; } .fa-houzz:before { content: "\f27c"; } .fa-vimeo:before { content: "\f27d"; } .fa-black-tie:before { content: "\f27e"; } .fa-fonticons:before { content: "\f280"; } .fa-reddit-alien:before { content: "\f281"; } .fa-edge:before { content: "\f282"; } .fa-credit-card-alt:before { content: "\f283"; } .fa-codiepie:before { content: "\f284"; } .fa-modx:before { content: "\f285"; } .fa-fort-awesome:before { content: "\f286"; } .fa-usb:before { content: "\f287"; } .fa-product-hunt:before { content: "\f288"; } .fa-mixcloud:before { content: "\f289"; } .fa-scribd:before { content: "\f28a"; } .fa-pause-circle:before { content: "\f28b"; } .fa-pause-circle-o:before { content: "\f28c"; } .fa-stop-circle:before { content: "\f28d"; } .fa-stop-circle-o:before { content: "\f28e"; } .fa-shopping-bag:before { content: "\f290"; } .fa-shopping-basket:before { content: "\f291"; } .fa-hashtag:before { content: "\f292"; } .fa-bluetooth:before { content: "\f293"; } .fa-bluetooth-b:before { content: "\f294"; } .fa-percent:before { content: "\f295"; } .fa-gitlab:before { content: "\f296"; } .fa-wpbeginner:before { content: "\f297"; } .fa-wpforms:before { content: "\f298"; } .fa-envira:before { content: "\f299"; } .fa-universal-access:before { content: "\f29a"; } .fa-wheelchair-alt:before { content: "\f29b"; } .fa-question-circle-o:before { content: "\f29c"; } .fa-blind:before { content: "\f29d"; } .fa-audio-description:before { content: "\f29e"; } .fa-volume-control-phone:before { content: "\f2a0"; } .fa-braille:before { content: "\f2a1"; } .fa-assistive-listening-systems:before { content: "\f2a2"; } .fa-asl-interpreting:before, .fa-american-sign-language-interpreting:before { content: "\f2a3"; } .fa-deafness:before, .fa-hard-of-hearing:before, .fa-deaf:before { content: "\f2a4"; } .fa-glide:before { content: "\f2a5"; } .fa-glide-g:before { content: "\f2a6"; } .fa-signing:before, .fa-sign-language:before { content: "\f2a7"; } .fa-low-vision:before { content: "\f2a8"; } .fa-viadeo:before { content: "\f2a9"; } .fa-viadeo-square:before { content: "\f2aa"; } .fa-snapchat:before { content: "\f2ab"; } .fa-snapchat-ghost:before { content: "\f2ac"; } .fa-snapchat-square:before { content: "\f2ad"; } .fa-pied-piper:before { content: "\f2ae"; } .fa-first-order:before { content: "\f2b0"; } .fa-yoast:before { content: "\f2b1"; } .fa-themeisle:before { content: "\f2b2"; } .fa-google-plus-circle:before, .fa-google-plus-official:before { content: "\f2b3"; } .fa-fa:before, .fa-font-awesome:before { content: "\f2b4"; } .fa-handshake-o:before { content: "\f2b5"; } .fa-envelope-open:before { content: "\f2b6"; } .fa-envelope-open-o:before { content: "\f2b7"; } .fa-linode:before { content: "\f2b8"; } .fa-address-book:before { content: "\f2b9"; } .fa-address-book-o:before { content: "\f2ba"; } .fa-vcard:before, .fa-address-card:before { content: "\f2bb"; } .fa-vcard-o:before, .fa-address-card-o:before { content: "\f2bc"; } .fa-user-circle:before { content: "\f2bd"; } .fa-user-circle-o:before { content: "\f2be"; } .fa-user-o:before { content: "\f2c0"; } .fa-id-badge:before { content: "\f2c1"; } .fa-drivers-license:before, .fa-id-card:before { content: "\f2c2"; } .fa-drivers-license-o:before, .fa-id-card-o:before { content: "\f2c3"; } .fa-quora:before { content: "\f2c4"; } .fa-free-code-camp:before { content: "\f2c5"; } .fa-telegram:before { content: "\f2c6"; } .fa-thermometer-4:before, .fa-thermometer:before, .fa-thermometer-full:before { content: "\f2c7"; } .fa-thermometer-3:before, .fa-thermometer-three-quarters:before { content: "\f2c8"; } .fa-thermometer-2:before, .fa-thermometer-half:before { content: "\f2c9"; } .fa-thermometer-1:before, .fa-thermometer-quarter:before { content: "\f2ca"; } .fa-thermometer-0:before, .fa-thermometer-empty:before { content: "\f2cb"; } .fa-shower:before { content: "\f2cc"; } .fa-bathtub:before, .fa-s15:before, .fa-bath:before { content: "\f2cd"; } .fa-podcast:before { content: "\f2ce"; } .fa-window-maximize:before { content: "\f2d0"; } .fa-window-minimize:before { content: "\f2d1"; } .fa-window-restore:before { content: "\f2d2"; } .fa-times-rectangle:before, .fa-window-close:before { content: "\f2d3"; } .fa-times-rectangle-o:before, .fa-window-close-o:before { content: "\f2d4"; } .fa-bandcamp:before { content: "\f2d5"; } .fa-grav:before { content: "\f2d6"; } .fa-etsy:before { content: "\f2d7"; } .fa-imdb:before { content: "\f2d8"; } .fa-ravelry:before { content: "\f2d9"; } .fa-eercast:before { content: "\f2da"; } .fa-microchip:before { content: "\f2db"; } .fa-snowflake-o:before { content: "\f2dc"; } .fa-superpowers:before { content: "\f2dd"; } .fa-wpexplorer:before { content: "\f2de"; } .fa-meetup:before { content: "\f2e0"; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; } ================================================ FILE: icon_font_to_png/test/files/octicons.css ================================================ @font-face { font-family:"Octicons"; src:url("octicons.eot?ef21c39f0ca9b1b5116e5eb7ac5eabe6"); src:url("octicons.eot?#iefix") format("embedded-opentype"), url("octicons.woff2?ef21c39f0ca9b1b5116e5eb7ac5eabe6") format("woff2"), url("octicons.woff?ef21c39f0ca9b1b5116e5eb7ac5eabe6") format("woff"), url("octicons.ttf?ef21c39f0ca9b1b5116e5eb7ac5eabe6") format("truetype"), url("octicons.svg?ef21c39f0ca9b1b5116e5eb7ac5eabe6#octicons") format("svg"); font-weight:normal; font-style:normal; } /* .octicon is optimized for 16px. .mega-octicon is optimized for 32px but can be used larger. */ .octicon, .mega-octicon { font: normal normal normal 16px/1 Octicons; display: inline-block; text-decoration: none; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-user-select: none; -ms-user-select: none; user-select: none; speak: none; } .mega-octicon { font-size: 32px; } .octicon-alert:before { content:"\f02d"; } .octicon-arrow-down:before { content:"\f03f"; } .octicon-arrow-left:before { content:"\f040"; } .octicon-arrow-right:before { content:"\f03e"; } .octicon-arrow-small-down:before { content:"\f0a0"; } .octicon-arrow-small-left:before { content:"\f0a1"; } .octicon-arrow-small-right:before { content:"\f071"; } .octicon-arrow-small-up:before { content:"\f09f"; } .octicon-arrow-up:before { content:"\f03d"; } .octicon-beaker:before { content:"\f0dd"; } .octicon-bell:before { content:"\f0de"; } .octicon-bold:before { content:"\f0e2"; } .octicon-book:before { content:"\f007"; } .octicon-bookmark:before { content:"\f07b"; } .octicon-briefcase:before { content:"\f0d3"; } .octicon-broadcast:before { content:"\f048"; } .octicon-browser:before { content:"\f0c5"; } .octicon-bug:before { content:"\f091"; } .octicon-calendar:before { content:"\f068"; } .octicon-check:before { content:"\f03a"; } .octicon-checklist:before { content:"\f076"; } .octicon-chevron-down:before { content:"\f0a3"; } .octicon-chevron-left:before { content:"\f0a4"; } .octicon-chevron-right:before { content:"\f078"; } .octicon-chevron-up:before { content:"\f0a2"; } .octicon-circle-slash:before { content:"\f084"; } .octicon-circuit-board:before { content:"\f0d6"; } .octicon-clippy:before { content:"\f035"; } .octicon-clock:before { content:"\f046"; } .octicon-cloud-download:before { content:"\f00b"; } .octicon-cloud-upload:before { content:"\f00c"; } .octicon-code:before { content:"\f05f"; } .octicon-comment-discussion:before { content:"\f04f"; } .octicon-comment:before { content:"\f02b"; } .octicon-credit-card:before { content:"\f045"; } .octicon-dash:before { content:"\f0ca"; } .octicon-dashboard:before { content:"\f07d"; } .octicon-database:before { content:"\f096"; } .octicon-desktop-download:before { content:"\f0dc"; } .octicon-device-camera-video:before { content:"\f057"; } .octicon-device-camera:before { content:"\f056"; } .octicon-device-desktop:before { content:"\f27c"; } .octicon-device-mobile:before { content:"\f038"; } .octicon-diff-added:before { content:"\f06b"; } .octicon-diff-ignored:before { content:"\f099"; } .octicon-diff-modified:before { content:"\f06d"; } .octicon-diff-removed:before { content:"\f06c"; } .octicon-diff-renamed:before { content:"\f06e"; } .octicon-diff:before { content:"\f04d"; } .octicon-ellipses:before { content:"\f101"; } .octicon-ellipsis:before { content:"\f09a"; } .octicon-eye:before { content:"\f04e"; } .octicon-file-binary:before { content:"\f094"; } .octicon-file-code:before { content:"\f010"; } .octicon-file-directory:before { content:"\f016"; } .octicon-file-media:before { content:"\f012"; } .octicon-file-pdf:before { content:"\f014"; } .octicon-file-submodule:before { content:"\f017"; } .octicon-file-symlink-directory:before { content:"\f0b1"; } .octicon-file-symlink-file:before { content:"\f0b0"; } .octicon-file-text:before { content:"\f011"; } .octicon-file-zip:before { content:"\f013"; } .octicon-file:before { content:"\f102"; } .octicon-flame:before { content:"\f0d2"; } .octicon-fold:before { content:"\f0cc"; } .octicon-gear:before { content:"\f02f"; } .octicon-gift:before { content:"\f042"; } .octicon-gist-secret:before { content:"\f08c"; } .octicon-gist:before { content:"\f00e"; } .octicon-git-branch:before { content:"\f020"; } .octicon-git-commit:before { content:"\f01f"; } .octicon-git-compare:before { content:"\f0ac"; } .octicon-git-merge:before { content:"\f023"; } .octicon-git-pull-request:before { content:"\f009"; } .octicon-globe:before { content:"\f0b6"; } .octicon-grabber:before { content:"\f103"; } .octicon-graph:before { content:"\f043"; } .octicon-heart:before { content:"\2665"; } .octicon-history:before { content:"\f07e"; } .octicon-home:before { content:"\f08d"; } .octicon-horizontal-rule:before { content:"\f070"; } .octicon-hubot:before { content:"\f09d"; } .octicon-inbox:before { content:"\f0cf"; } .octicon-info:before { content:"\f059"; } .octicon-issue-closed:before { content:"\f028"; } .octicon-issue-opened:before { content:"\f026"; } .octicon-issue-reopened:before { content:"\f027"; } .octicon-italic:before { content:"\f0e4"; } .octicon-jersey:before { content:"\f019"; } .octicon-key:before { content:"\f049"; } .octicon-keyboard:before { content:"\f00d"; } .octicon-law:before { content:"\f0d8"; } .octicon-light-bulb:before { content:"\f000"; } .octicon-link-external:before { content:"\f07f"; } .octicon-link:before { content:"\f05c"; } .octicon-list-ordered:before { content:"\f062"; } .octicon-list-unordered:before { content:"\f061"; } .octicon-location:before { content:"\f060"; } .octicon-lock:before { content:"\f06a"; } .octicon-logo-gist:before { content:"\f0ad"; } .octicon-logo-github:before { content:"\f092"; } .octicon-mail-read:before { content:"\f03c"; } .octicon-mail-reply:before { content:"\f051"; } .octicon-mail:before { content:"\f03b"; } .octicon-mark-github:before { content:"\f00a"; } .octicon-markdown:before { content:"\f0c9"; } .octicon-megaphone:before { content:"\f077"; } .octicon-mention:before { content:"\f0be"; } .octicon-milestone:before { content:"\f075"; } .octicon-mirror:before { content:"\f024"; } .octicon-mortar-board:before { content:"\f0d7"; } .octicon-mute:before { content:"\f080"; } .octicon-no-newline:before { content:"\f09c"; } .octicon-octoface:before { content:"\f008"; } .octicon-organization:before { content:"\f037"; } .octicon-package:before { content:"\f0c4"; } .octicon-paintcan:before { content:"\f0d1"; } .octicon-pencil:before { content:"\f058"; } .octicon-person:before { content:"\f018"; } .octicon-pin:before { content:"\f041"; } .octicon-plug:before { content:"\f0d4"; } .octicon-plus-small:before { content:"\f104"; } .octicon-plus:before { content:"\f05d"; } .octicon-primitive-dot:before { content:"\f052"; } .octicon-primitive-square:before { content:"\f053"; } .octicon-pulse:before { content:"\f085"; } .octicon-question:before { content:"\f02c"; } .octicon-quote:before { content:"\f063"; } .octicon-radio-tower:before { content:"\f030"; } .octicon-reply:before { content:"\f105"; } .octicon-repo-clone:before { content:"\f04c"; } .octicon-repo-force-push:before { content:"\f04a"; } .octicon-repo-forked:before { content:"\f002"; } .octicon-repo-pull:before { content:"\f006"; } .octicon-repo-push:before { content:"\f005"; } .octicon-repo:before { content:"\f001"; } .octicon-rocket:before { content:"\f033"; } .octicon-rss:before { content:"\f034"; } .octicon-ruby:before { content:"\f047"; } .octicon-search:before { content:"\f02e"; } .octicon-server:before { content:"\f097"; } .octicon-settings:before { content:"\f07c"; } .octicon-shield:before { content:"\f0e1"; } .octicon-sign-in:before { content:"\f036"; } .octicon-sign-out:before { content:"\f032"; } .octicon-smiley:before { content:"\f0e7"; } .octicon-squirrel:before { content:"\f0b2"; } .octicon-star:before { content:"\f02a"; } .octicon-stop:before { content:"\f08f"; } .octicon-sync:before { content:"\f087"; } .octicon-tag:before { content:"\f015"; } .octicon-tasklist:before { content:"\f0e5"; } .octicon-telescope:before { content:"\f088"; } .octicon-terminal:before { content:"\f0c8"; } .octicon-text-size:before { content:"\f0e3"; } .octicon-three-bars:before { content:"\f05e"; } .octicon-thumbsdown:before { content:"\f0db"; } .octicon-thumbsup:before { content:"\f0da"; } .octicon-tools:before { content:"\f031"; } .octicon-trashcan:before { content:"\f0d0"; } .octicon-triangle-down:before { content:"\f05b"; } .octicon-triangle-left:before { content:"\f044"; } .octicon-triangle-right:before { content:"\f05a"; } .octicon-triangle-up:before { content:"\f0aa"; } .octicon-unfold:before { content:"\f039"; } .octicon-unmute:before { content:"\f0ba"; } .octicon-unverified:before { content:"\f0e8"; } .octicon-verified:before { content:"\f0e6"; } .octicon-versions:before { content:"\f064"; } .octicon-watch:before { content:"\f0e0"; } .octicon-x:before { content:"\f081"; } .octicon-zap:before { content:"\26a1"; } ================================================ FILE: icon_font_to_png/test/files/test-foo.css ================================================ .foo-bar:before { content: '\f001' } .foo-test:before { content: '\f002' } ================================================ FILE: icon_font_to_png/test/files/test.css ================================================ .foo:before { content: '\f001' } .bar:before { content: '\f002' } ================================================ FILE: icon_font_to_png/test/test_command_line.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import shutil import pytest from icon_font_to_png import command_line BASE_DIR = os.path.dirname(os.path.realpath(__file__)) # Tests def test_list_option(capfd): """Test listing CSS icons""" css_file = os.path.join(BASE_DIR, 'files', 'test-foo.css') ttf_file = os.path.join(BASE_DIR, 'files', 'test.ttf') # Required argument # No CSS and TTF files with pytest.raises(SystemExit): command_line.run( '--list'.split() ) out, err = capfd.readouterr() assert out == '' # Lists correctly with pytest.raises(SystemExit): command_line.run( '--css {css_file} --ttf {ttf_file} --list'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() assert out == 'bar\ntest\n' # Lists correctly, with the prefix with pytest.raises(SystemExit): command_line.run( '--css {css_file} --ttf {ttf_file} --keep_prefix --list'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() assert out == 'foo-bar\nfoo-test\n' def test_icon_export(capfd): """Test exporting icons (on Font Awesome files)""" css_file = os.path.join(BASE_DIR, 'files', 'font-awesome.css') ttf_file = os.path.join(BASE_DIR, 'files', 'fontawesome-webfont.ttf') # Export none icons with pytest.raises(SystemExit): command_line.run( '--css {css_file} --ttf {ttf_file}'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout # Export one icon command_line.run( '--css {css_file} --ttf {ttf_file} github'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout assert os.path.isfile(os.path.join('exported', 'github.png')) # Export two icons command_line.run( '--css {css_file} --ttf {ttf_file} github star'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout assert os.path.isfile(os.path.join('exported', 'github.png')) assert os.path.isfile(os.path.join('exported', 'star.png')) # Export all icons command_line.run( '--css {css_file} --ttf {ttf_file} ALL'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout def test_filename_option(capfd): """Test filename option""" css_file = os.path.join(BASE_DIR, 'files', 'font-awesome.css') ttf_file = os.path.join(BASE_DIR, 'files', 'fontawesome-webfont.ttf') # Export one icon command_line.run( '--css {css_file} --ttf {ttf_file} ' '--filename foo github'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout assert os.path.isfile(os.path.join('exported', 'foo.png')) # Export multiple icons command_line.run( '--css {css_file} --ttf {ttf_file} ' '--filename foo- github star'.format( css_file=css_file, ttf_file=ttf_file ).split() ) out, err = capfd.readouterr() # For skipping stdout assert os.path.isfile(os.path.join('exported', 'foo-github.png')) assert os.path.isfile(os.path.join('exported', 'foo-star.png')) def test_download_option(capfd): """Test icon font download option""" with pytest.raises(SystemExit): command_line.run( '--download {font_name}'.format(font_name='font-awesome').split() ) out, err = capfd.readouterr() # For skipping stdout assert out == "Icon font 'font-awesome' successfully downloaded\n" assert os.path.isfile('font-awesome.css') assert os.path.isfile('fontawesome-webfont.ttf') # Teardown def teardown_module(): """Delete exported icons directory and downloaded FontAwesome files""" if os.path.isdir('exported'): shutil.rmtree('exported') if os.path.isfile('font-awesome.css'): os.remove('font-awesome.css') if os.path.isfile('fontawesome-webfont.ttf'): os.remove('fontawesome-webfont.ttf') ================================================ FILE: icon_font_to_png/test/test_font_awesome.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import random import pytest from icon_font_to_png import icon_font BASE_DIR = os.path.dirname(os.path.realpath(__file__)) # Fixtures @pytest.fixture(scope='module') def font_awesome(): """Create a IconFont instance from Font Awesome files""" css_file = os.path.join(BASE_DIR, 'files', 'font-awesome.css') ttf_file = os.path.join(BASE_DIR, 'files', 'fontawesome-webfont.ttf') return icon_font.IconFont(css_file=css_file, ttf_file=ttf_file) # Tests def test_font_awesome_load_icons(font_awesome): """Test Font Awesome icon loading""" assert len(font_awesome.css_icons) > 0 def test_font_awesome_prefix(font_awesome): """Test Font Awesome common prefix""" assert font_awesome.common_prefix == 'fa-' def test_font_awesome_export_icon(font_awesome): """Test Font Awesome random icon exporting""" icon = random.choice(list(font_awesome.css_icons.keys())) font_awesome.export_icon(icon, size=128, export_dir='/tmp') font_awesome.export_icon(icon, size=128, color='blue', export_dir='/tmp') font_awesome.export_icon(icon, size=256, export_dir='/tmp') font_awesome.export_icon(icon, size=256, color='blue', export_dir='/tmp') ================================================ FILE: icon_font_to_png/test/test_icon_font.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import shutil import tempfile import uuid import pytest from PIL import Image, ImageChops from icon_font_to_png import icon_font BASE_DIR = os.path.dirname(os.path.realpath(__file__)) # Fixtures @pytest.fixture(scope='module') def font_awesome(): """Create a IconFont instance from Font Awesome files""" css_file = os.path.join(BASE_DIR, 'files', 'font-awesome.css') ttf_file = os.path.join(BASE_DIR, 'files', 'fontawesome-webfont.ttf') return icon_font.IconFont(css_file=css_file, ttf_file=ttf_file) # Tests def test_init(): """Test initializing""" # No arguments with pytest.raises(TypeError): icon_font.IconFont() # Non-existent files with pytest.raises(IOError): icon_font.IconFont(css_file=str(uuid.uuid4()), ttf_file=str(uuid.uuid4())) obj = icon_font.IconFont(css_file=tempfile.mkstemp()[1], ttf_file=tempfile.mkstemp()[1]) assert len(obj.css_icons) == 0 def test_common_prefix(): """Test finding out what the common prefix is""" css_file = os.path.join(BASE_DIR, 'files', 'test-foo.css') obj = icon_font.IconFont(css_file=css_file, ttf_file=None, keep_prefix=True) assert obj.common_prefix == 'foo-' css_file = os.path.join(BASE_DIR, 'files', 'test.css') obj = icon_font.IconFont(css_file=css_file, ttf_file=None, keep_prefix=True) assert obj.common_prefix == '' @pytest.mark.parametrize("image,size", [ ("rocket_16.png", 16), ("rocket_100.png", 100), ("rocket_256.png", 256), ]) def test_size(font_awesome, image, size): """Test size option""" original_file = os.path.join(BASE_DIR, 'files', image) font_awesome.export_icon(icon='rocket', size=size) exported_file = os.path.join('exported', 'rocket.png') img1 = Image.open(original_file) img2 = Image.open(exported_file) # Check dimensions assert img1.size == (size, size) assert img2.size == (size, size) # Check if the images are equal assert ImageChops.difference(img1, img2).getbbox() is None @pytest.mark.parametrize("image,color", [ ("rocket_blue.png", 'blue'), ("rocket_cyan.png", 'cyan'), ("rocket_123123.png", '#123123'), ]) def test_color(font_awesome, image, color): """Test color option""" original_file = os.path.join(BASE_DIR, 'files', image) font_awesome.export_icon(icon='rocket', size=16, color=color) exported_file = os.path.join('exported', 'rocket.png') img1 = Image.open(original_file) img2 = Image.open(exported_file) # Check if the images are equal assert ImageChops.difference(img1, img2).getbbox() is None @pytest.mark.parametrize("image,scale", [ ("rocket_x1.png", 1), ("rocket_x05.png", 0.5), ("rocket_auto.png", 'auto'), ]) def test_scale(font_awesome, image, scale): """Test scale option""" original_file = os.path.join(BASE_DIR, 'files', image) font_awesome.export_icon(icon='rocket', size=16, scale=scale) exported_file = os.path.join('exported', 'rocket.png') img1 = Image.open(original_file) img2 = Image.open(exported_file) # Check if the images are equal assert ImageChops.difference(img1, img2).getbbox() is None # Teardown def teardown_module(): """Delete exported icons directory""" if os.path.isdir('exported'): shutil.rmtree('exported') ================================================ FILE: icon_font_to_png/test/test_icon_font_downloader.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import tempfile import pytest from flaky import flaky from icon_font_to_png.icon_font_downloader import ( FontAwesomeDownloader, OcticonsDownloader ) # Tests @flaky @pytest.mark.parametrize("downloader", [ FontAwesomeDownloader, OcticonsDownloader, ]) def test_icon_font_downloader(downloader): """Test initializing Font Awesome Downloader""" # With directory obj = downloader(tempfile.mkdtemp()) obj.download_files() assert os.path.isfile(obj.css_path) assert os.path.isfile(obj.ttf_path) # Without directory obj = downloader() obj.download_files() assert os.path.isfile(obj.css_path) assert os.path.isfile(obj.ttf_path) @pytest.mark.parametrize("downloader", [ FontAwesomeDownloader, OcticonsDownloader, ]) def test_font_awesome_latest_version_number(downloader): """Test that getting latest version number""" obj = downloader(tempfile.mkdtemp()) assert obj.get_latest_version_number() ================================================ FILE: icon_font_to_png/test/test_octicons.py ================================================ # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import os import random import pytest from icon_font_to_png import icon_font BASE_DIR = os.path.dirname(os.path.realpath(__file__)) # Fixtures @pytest.fixture(scope='module') def octicons(): """Create a IconFont instance from Octicons files""" css_file = os.path.join(BASE_DIR, 'files', 'octicons.css') ttf_file = os.path.join(BASE_DIR, 'files', 'octicons.ttf') return icon_font.IconFont(css_file=css_file, ttf_file=ttf_file) # Tests def test_octicons_load_icons(octicons): """Test Octicons icon loading""" assert len(octicons.css_icons) > 0 def test_octicons_prefix(octicons): """Test Octicons common prefix""" assert octicons.common_prefix == 'octicon-' def test_octicons_export_icon(octicons): """Test Octicons random icon exporting""" icon = random.choice(list(octicons.css_icons.keys())) octicons.export_icon(icon=icon, size=128, export_dir='/tmp') octicons.export_icon(icon=icon, size=128, color='blue', export_dir='/tmp') octicons.export_icon(icon=icon, size=256, export_dir='/tmp') octicons.export_icon(icon=icon, size=256, color='blue', export_dir='/tmp') ================================================ FILE: requirements/common.txt ================================================ Pillow>=4.0.0 requests>=2.13.0 six>=1.10.0 tinycss>=0.4 ================================================ FILE: requirements/dev.txt ================================================ -r common.txt check-manifest>=0.35 coverage>=4.3.4 coveralls>=1.1 flake8>=3.2.1 flaky>=3.3.0 pypandoc>=1.3.3 pytest>=3.0.6 tox>=2.6.0 twine>=1.8.1 ================================================ FILE: requirements.txt ================================================ -r requirements/common.txt ================================================ FILE: setup.py ================================================ # -*- coding: utf-8 -*- from __future__ import unicode_literals import io import os import re from setuptools import setup, find_packages # Convert description from markdown to reStructuredText try: import pypandoc description = pypandoc.convert('README.md', 'rst', 'markdown') except (OSError, ImportError): description = '' # Get package version number # Source: https://packaging.python.org/single_source_version/ def read(*names, **kwargs): with io.open( os.path.join(os.path.dirname(__file__), *names), encoding=kwargs.get('encoding', 'utf8') ) as fp: return fp.read() def find_version(*file_paths): version_file = read(*file_paths) version_match = re.search( r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M ) if version_match: return version_match.group(1) raise RuntimeError("Unable to find version string.") setup( name='icon_font_to_png', url='https://github.com/Pythonity/icon-font-to-png', download_url='https://github.com/Pythonity/icon-font-to-png/releases/' 'latest', bugtrack_url='https://github.com/Pythonity/icon-font-to-png/issues', version=find_version('icon_font_to_png', '__init__.py'), license='MIT License', author='Pythonity', author_email='pythonity@pythonity.com', maintainer='Paweł Adamczak', maintainer_email='pawel.adamczak@sidnet.info', description="Python script (and library) for exporting icons from " "icon fonts (e.g. Font Awesome, Octicons) as PNG images.", long_description=description, packages=find_packages(), include_package_data=True, install_requires=[ 'Pillow>=4.0.0', 'requests>=2.12.5', 'six>=1.10.0', 'tinycss>=0.4', ], extras_require={ 'testing': ['pytest'], }, scripts=['bin/font-awesome-to-png', 'bin/icon-font-to-png'], keywords='icon font export font awesome octicons', classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console', 'Intended Audience :: End Users/Desktop', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Topic :: Utilities', ], ) ================================================ FILE: tox.ini ================================================ [tox] envlist = py27,py34,py35,py36,py36-flake8 [testenv] commands = py.test -v deps = -r{toxinidir}/requirements/dev.txt passenv = TRAVIS* [testenv:flake8] commands = flake8 . deps = flake8 [pytest] addopts = --ignore=setup.py python_files = *.py python_functions = test_ [flake8] exclude = .git, .tox, build, dist