# -*- coding: utf-8 -*-

__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'

'''
Transform OEB content into FB2 markup
'''

import re, textwrap, uuid
from datetime import datetime

from lxml import etree

from calibre import prepare_string_for_xml
from calibre.constants import __appname__, __version__
from calibre.utils.localization import lang_as_iso639_1
from calibre.utils.xml_parse import safe_xml_fromstring
from calibre.utils.img import save_cover_data_to
from calibre.ebooks.oeb.base import urlnormalize
from polyglot.builtins import unicode_type, string_or_bytes, range, filter
from polyglot.binary import as_base64_unicode
from polyglot.urllib import urlparse

class FB2MLizer(object):
    '''
    Todo: * Include more FB2 specific tags in the conversion.
          * Handle notes and anchor links.
    '''

    def __init__(self, log):
        self.log = log
        self.reset_state()

    def reset_state(self):
        # Used to ensure text and tags are always within
 and

        self.in_p = False
        # Mapping of image names. OEB allows for images to have the same name but be stored
        # in different directories. FB2 images are all in a flat layout so we rename all images
        # into a sequential numbering system to ensure there are no collisions between image names.
        self.image_hrefs = {}
        # Mapping of toc items and their
        self.toc = {}
        # Used to see whether a new
 needs to be opened
        self.section_level = 0

    def extract_content(self, oeb_book, opts):
        self.log.info('Converting XHTML to FB2 markup...')
        self.oeb_book = oeb_book
        self.opts = opts
        self.reset_state()

        # Used for adding
s and <title>s to allow readers
        # to generate toc from the document.
        if self.opts.sectionize == 'toc':
            self.create_flat_toc(self.oeb_book.toc, 1)

        return self.fb2mlize_spine()

    def fb2mlize_spine(self):
        output = (
            self.fb2_header(),
            self.get_text(),
            self.fb2mlize_images(),
            self.fb2_footer(),
        )
        output = self.clean_text('\n'.join(output))

        if self.opts.pretty_print:
            output = etree.tostring(safe_xml_fromstring(output), encoding='unicode', pretty_print=True)

        return '<?xml version="1.0" encoding="UTF-8"?>\n' + output

    def clean_text(self, text):
        # Remove pointless tags, but keep their contents.
        text = re.sub(r'(?mu)<(strong|emphasis|strikethrough|sub|sup)>(\s*)</\1>', r'\2', text)

        # Clean up paragraphs endings.
        text = re.sub(r'(?mu)\s+
', '
', text)
        # Condense empty paragraphs into a line break.
        text = re.sub(r'(?mu)(?:

\s*){3,}', '<empty-line/>', text)
        # Remove empty paragraphs.
        text = re.sub(r'(?mu)

\s*', '', text)
        # Put the paragraph following a paragraph on a separate line.
        text = re.sub(r'(?mu)
\s*
', '
\n
', text)

        if self.opts.insert_blank_line:
            text = re.sub(r'(?mu)
', '
<empty-line/>', text)

        # Clean up title endings.
        text = re.sub(r'(?mu)\s+</title>', '</title>', text)
        # Remove empty title elements.
        text = re.sub(r'(?mu)<title></title>\s*', '', text)
        # Put the paragraph following a title on a separate line.
        text = re.sub(r'(?mu)</title>\s*
', '</title>\n
', text)

        # Put line breaks between paragraphs on a separate line.
        text = re.sub(r'(?mu)</(p|title)>\s*<empty-line/>', r'</\1>\n<empty-line/>', text)
        text = re.sub(r'(?mu)<empty-line/>\s*
', '<empty-line/>\n
', text)

        # Remove empty sections.
        text = re.sub(r'(?mu)
\s*
', '', text)
        # Clean up sections starts and ends.
        text = re.sub(r'(?mu)\s*
', '\n
', text)
        text = re.sub(r'(?mu)
\s*', '
\n', text)
        text = re.sub(r'(?mu)\s*
', '\n
', text)
        text = re.sub(r'(?mu)
\s*', '
\n', text)

        return text

    def fb2_header(self):
        from calibre.ebooks.oeb.base import OPF
        metadata = {}
        metadata['title'] = self.oeb_book.metadata.title[0].value
        metadata['appname'] = __appname__
        metadata['version'] = __version__
        metadata['date'] = '%i.%i.%i' % (datetime.now().day, datetime.now().month, datetime.now().year)
        if self.oeb_book.metadata.language:
            lc = lang_as_iso639_1(self.oeb_book.metadata.language[0].value)
            if not lc:
                lc = self.oeb_book.metadata.language[0].value
            metadata['lang'] = lc or 'en'
        else:
            metadata['lang'] = u'en'
        metadata['id'] = None
        metadata['cover'] = self.get_cover()
        metadata['genre'] = self.opts.fb2_genre

        metadata['author'] = ''
        for auth in self.oeb_book.metadata.creator:
            author_first = ''
            author_middle = ''
            author_last = ''
            author_parts = auth.value.split(' ')
            if len(author_parts) == 1:
                author_last = author_parts[0]
            elif len(author_parts) == 2:
                author_first = author_parts[0]
                author_last = author_parts[1]
            else:
                author_first = author_parts[0]
                author_middle = ' '.join(author_parts[1:-1])
                author_last = author_parts[-1]
            metadata['author'] += '<author>'
            metadata['author'] += '<first-name>%s</first-name>' % prepare_string_for_xml(author_first)
            if author_middle:
                metadata['author'] += '<middle-name>%s</middle-name>' % prepare_string_for_xml(author_middle)
            metadata['author'] += '<last-name>%s</last-name>' % prepare_string_for_xml(author_last)
            metadata['author'] += '</author>'
        if not metadata['author']:
            metadata['author'] = '<author><first-name></first-name><last-name></last-name></author>'

        metadata['keywords'] = ''
        tags = list(map(unicode_type, self.oeb_book.metadata.subject))
        if tags:
            tags = ', '.join(prepare_string_for_xml(x) for x in tags)
            metadata['keywords'] = '<keywords>%s</keywords>'%tags

        metadata['sequence'] = ''
        if self.oeb_book.metadata.series:
            index = '1'
            if self.oeb_book.metadata.series_index:
                index = self.oeb_book.metadata.series_index[0]
            metadata['sequence'] = '<sequence name="%s" number="%s"/>' % (prepare_string_for_xml('%s' % self.oeb_book.metadata.series[0]), index)

        year = publisher = isbn = ''
        identifiers = self.oeb_book.metadata['identifier']
        for x in identifiers:
            if x.get(OPF('scheme'), None).lower() == 'uuid' or unicode_type(x).startswith('urn:uuid:'):
                metadata['id'] = unicode_type(x).split(':')[-1]
                break
        if metadata['id'] is None:
            self.log.warn('No UUID identifier found')
            metadata['id'] = unicode_type(uuid.uuid4())

        try:
            date = self.oeb_book.metadata['date'][0]
        except IndexError:
            pass
        else:
            year = '<year>%s</year>' % prepare_string_for_xml(date.value.partition('-')[0])

        try:
            publisher = self.oeb_book.metadata['publisher'][0]
        except IndexError:
            pass
        else:
            publisher = '<publisher>%s</publisher>' % prepare_string_for_xml(publisher.value)

        for x in identifiers:
            if x.get(OPF('scheme'), None).lower() == 'isbn':
                isbn = '<isbn>%s</isbn>' % prepare_string_for_xml(x.value)

        metadata['year'], metadata['isbn'], metadata['publisher'] = year, isbn, publisher
        for key, value in metadata.items():
            if key not in ('author', 'cover', 'sequence', 'keywords', 'year', 'publisher', 'isbn'):
                metadata[key] = prepare_string_for_xml(value)

        try:
            comments = self.oeb_book.metadata['description'][0]
        except Exception:
            metadata['comments'] = ''
        else:
            from calibre.utils.html2text import html2text
            metadata['comments'] = '<annotation>
{}
</annotation>'.format(prepare_string_for_xml(html2text(comments.value).strip()))

        # Keep the indentation level of the description the same as the body.
        header = textwrap.dedent('''\
            <FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
            <description>
                <title-info>
                    <genre>%(genre)s</genre>
                    %(author)s
                    <book-title>%(title)s</book-title>
                    %(cover)s
                    <lang>%(lang)s</lang>
                    %(keywords)s
                    %(sequence)s
                    %(comments)s
                </title-info>
                <document-info>
                    %(author)s
                    <program-used>%(appname)s %(version)s</program-used>
                    <date>%(date)s</date>
                    <id>%(id)s</id>
                    <version>1.0</version>
                </document-info>
                <publish-info>
                    %(publisher)s
                    %(year)s
                    %(isbn)s
                </publish-info>
            </description>''') % metadata

        # Remove empty lines.
        return '\n'.join(filter(unicode_type.strip, header.splitlines()))

    def fb2_footer(self):
        return '</FictionBook>'

    def get_cover(self):
        from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES

        cover_href = None

        # Get the raster cover if it's available.
        if self.oeb_book.metadata.cover and unicode_type(self.oeb_book.metadata.cover[0]) in self.oeb_book.manifest.ids:
            id = unicode_type(self.oeb_book.metadata.cover[0])
            cover_item = self.oeb_book.manifest.ids[id]
            if cover_item.media_type in OEB_RASTER_IMAGES:
                cover_href = cover_item.href
        else:
            # Figure out if we have a title page or a cover page
            page_name = ''
            if 'titlepage' in self.oeb_book.guide:
                page_name = 'titlepage'
            elif 'cover' in self.oeb_book.guide:
                page_name = 'cover'

            if page_name:
                cover_item = self.oeb_book.manifest.hrefs[self.oeb_book.guide[page_name].href]
                # Get the first image in the page
                for img in cover_item.xpath('//img'):
                    cover_href = cover_item.abshref(img.get('src'))
                    break

        if cover_href:
            # Only write the image tag if it is in the manifest.
            if cover_href in self.oeb_book.manifest.hrefs and cover_href not in self.image_hrefs:
                self.image_hrefs[cover_href] = 'img_%s' % len(self.image_hrefs)
            return '<coverpage><image l:href="#%s"/></coverpage>' % self.image_hrefs[cover_href]

        return ''

    def get_text(self):
        from calibre.ebooks.oeb.base import XHTML
        from calibre.ebooks.oeb.stylizer import Stylizer
        text = ['']

        # Create main section if there are no others to create
        if self.opts.sectionize == 'nothing':
            text.append('
')
            self.section_level += 1

        for item in self.oeb_book.spine:
            self.log.debug('Converting %s to FictionBook2 XML' % item.href)
            stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)

            # Start a
 if we must sectionize each file or if the TOC references this page
            page_section_open = False
            if self.opts.sectionize == 'files' or None in self.toc.get(item.href, ()):
                text.append('
')
                page_section_open = True
                self.section_level += 1

            text += self.dump_text(item.data.find(XHTML('body')), stylizer, item)

            if page_section_open:
                text.append('
')
                self.section_level -= 1

        # Close any open sections
        while self.section_level > 0:
            text.append('
')
            self.section_level -= 1

        text.append('')
        return ''.join(text)

    def fb2mlize_images(self):
        '''
        This function uses the self.image_hrefs dictionary mapping. It is populated by the dump_text function.
        '''
        from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES

        images = []
        for item in self.oeb_book.manifest:
            # Don't write the image if it's not referenced in the document's text.
            if item.href not in self.image_hrefs:
                continue
            if item.media_type in OEB_RASTER_IMAGES:
                try:
                    if item.media_type not in ('image/jpeg', 'image/png'):
                        imdata = save_cover_data_to(item.data, compression_quality=70)
                        raw_data = as_base64_unicode(imdata)
                        content_type = 'image/jpeg'
                    else:
                        raw_data = as_base64_unicode(item.data)
                        content_type = item.media_type
                    # Don't put the encoded image on a single line.
                    step = 72
                    data = '\n'.join(raw_data[i:i+step] for i in range(0, len(raw_data), step))
                    images.append('<binary id="%s" content-type="%s">%s</binary>' % (self.image_hrefs[item.href], content_type, data))
                except Exception as e:
                    self.log.error('Error: Could not include file %s because '
                        '%s.' % (item.href, e))
        return '\n'.join(images)

    def create_flat_toc(self, nodes, level):
        for item in nodes:
            href, mid, id = item.href.partition('#')
            if not id:
                self.toc[href] = {None: 'page'}
            else:
                if not self.toc.get(href, None):
                    self.toc[href] = {}
                self.toc[href][id] = level
                self.create_flat_toc(item.nodes, level + 1)

    def ensure_p(self):
        if self.in_p:
            return [], []
        else:
            self.in_p = True
            return ['
'], ['p']

    def close_open_p(self, tags):
        text = ['']
        added_p = False

        if self.in_p:
            # Close all up to p. Close p. Reopen all closed tags including p.
            closed_tags = []
            tags.reverse()
            for t in tags:
                text.append('</%s>' % t)
                closed_tags.append(t)
                if t == 'p':
                    break
            closed_tags.reverse()
            for t in closed_tags:
                text.append('<%s>' % t)
        else:
            text.append('
')
            added_p = True
            self.in_p = True

        return text, added_p

    def handle_simple_tag(self, tag, tags):
        s_out = []
        s_tags = []
        if tag not in tags:
            p_out, p_tags = self.ensure_p()
            s_out += p_out
            s_tags += p_tags
            s_out.append('<%s>' % tag)
            s_tags.append(tag)
        return s_out, s_tags

    def dump_text(self, elem_tree, stylizer, page, tag_stack=[]):
        '''
        This function is intended to be used in a recursive manner. dump_text will
        run though all elements in the elem_tree and call itself on each element.

        self.image_hrefs will be populated by calling this function.

        @param elem_tree: etree representation of XHTML content to be transformed.
        @param stylizer: Used to track the style of elements within the tree.
        @param page: OEB page used to determine absolute urls.
        @param tag_stack: List of open FB2 tags to take into account.

        @return: List of string representing the XHTML converted to FB2 markup.
        '''
        from calibre.ebooks.oeb.base import XHTML_NS, barename, namespace
        elem = elem_tree

        # Ensure what we are converting is not a string and that the fist tag is part of the XHTML namespace.
        if not isinstance(elem_tree.tag, string_or_bytes) or namespace(elem_tree.tag) != XHTML_NS:
            p = elem.getparent()
            if p is not None and isinstance(p.tag, string_or_bytes) and namespace(p.tag) == XHTML_NS \
                    and elem.tail:
                return [elem.tail]
            return []

        style = stylizer.style(elem_tree)
        if style['display'] in ('none', 'oeb-page-head', 'oeb-page-foot') \
           or style['visibility'] == 'hidden':
            if hasattr(elem, 'tail') and elem.tail:
                return [elem.tail]
            return []

        # FB2 generated output.
        fb2_out = []
        # FB2 tags in the order they are opened. This will be used to close the tags.
        tags = []
        # First tag in tree
        tag = barename(elem_tree.tag)
        # Number of blank lines above tag
        try:
            ems = int(round((float(style.marginTop) / style.fontSize) - 1))
            if ems < 0:
                ems = 0
        except:
            ems = 0

        # Convert TOC entries to <title>s and add
s
        if self.opts.sectionize == 'toc':
            # A section cannot be a child of any other element than another section,
            # so leave the tag alone if there are parents
            if not tag_stack:
                # There are two reasons to start a new section here: the TOC pointed to
                # this page (then we use the first non- on the page as a <title>), or
                # the TOC pointed to a specific element
                newlevel = 0
                toc_entry = self.toc.get(page.href, None)
                if toc_entry is not None:
                    if None in toc_entry:
                        if tag != 'body' and hasattr(elem_tree, 'text') and elem_tree.text:
                            newlevel = 1
                            self.toc[page.href] = None
                    if not newlevel and elem_tree.attrib.get('id', None) is not None:
                        newlevel = toc_entry.get(elem_tree.attrib.get('id', None), None)

                # Start a new section if necessary
                if newlevel:
                    while newlevel <= self.section_level:
                        fb2_out.append('
')
                        self.section_level -= 1
                    fb2_out.append('
')
                    self.section_level += 1
                    fb2_out.append('<title>')
                    tags.append('title')
            if self.section_level == 0:
                # If none of the prior processing made a section, make one now to be FB2 spec compliant
                fb2_out.append('
')
                self.section_level += 1

        # Process the XHTML tag and styles. Converted to an FB2 tag.
        # Use individual if statement not if else. There can be
        # only one XHTML tag but it can have multiple styles.
        if tag == 'img' and elem_tree.attrib.get('src', None):
            # Only write the image tag if it is in the manifest.
            ihref = urlnormalize(page.abshref(elem_tree.attrib['src']))
            if ihref in self.oeb_book.manifest.hrefs:
                if ihref not in self.image_hrefs:
                    self.image_hrefs[ihref] = 'img_%s' % len(self.image_hrefs)
                p_txt, p_tag = self.ensure_p()
                fb2_out += p_txt
                tags += p_tag
                fb2_out.append('<image l:href="#%s"/>' % self.image_hrefs[ihref])
            else:
                self.log.warn(u'Ignoring image not in manifest: %s' % ihref)
        if tag in ('br', 'hr') or ems >= 1:
            if ems < 1:
                multiplier = 1
            else:
                multiplier = ems
            if self.in_p:
                closed_tags = []
                open_tags = tag_stack+tags
                open_tags.reverse()
                for t in open_tags:
                    fb2_out.append('</%s>' % t)
                    closed_tags.append(t)
                    if t == 'p':
                        break
                fb2_out.append('<empty-line/>' * multiplier)
                closed_tags.reverse()
                for t in closed_tags:
                    fb2_out.append('<%s>' % t)
            else:
                fb2_out.append('<empty-line/>' * multiplier)
        if tag in ('div', 'li', 'p'):
            p_text, added_p = self.close_open_p(tag_stack+tags)
            fb2_out += p_text
            if added_p:
                tags.append('p')
        if tag == 'a' and elem_tree.attrib.get('href', None):
            # Handle only external links for now
            if urlparse(elem_tree.attrib['href']).netloc:
                p_txt, p_tag = self.ensure_p()
                fb2_out += p_txt
                tags += p_tag
                fb2_out.append('' % urlnormalize(elem_tree.attrib['href']))
                tags.append('a')
        if tag == 'b' or style['font-weight'] in ('bold', 'bolder'):
            s_out, s_tags = self.handle_simple_tag('strong', tag_stack+tags)
            fb2_out += s_out
            tags += s_tags
        if tag == 'i' or style['font-style'] == 'italic':
            s_out, s_tags = self.handle_simple_tag('emphasis', tag_stack+tags)
            fb2_out += s_out
            tags += s_tags
        if tag in ('del', 'strike') or style['text-decoration'] == 'line-through':
            s_out, s_tags = self.handle_simple_tag('strikethrough', tag_stack+tags)
            fb2_out += s_out
            tags += s_tags
        if tag == 'sub':
            s_out, s_tags = self.handle_simple_tag('sub', tag_stack+tags)
            fb2_out += s_out
            tags += s_tags
        if tag == 'sup':
            s_out, s_tags = self.handle_simple_tag('sup', tag_stack+tags)
            fb2_out += s_out
            tags += s_tags

        # Process element text.
        if hasattr(elem_tree, 'text') and elem_tree.text:
            if not self.in_p:
                fb2_out.append('
')
            fb2_out.append(prepare_string_for_xml(elem_tree.text))
            if not self.in_p:
                fb2_out.append('
')

        # Process sub-elements.
        for item in elem_tree:
            fb2_out += self.dump_text(item, stylizer, page, tag_stack+tags)

        # Close open FB2 tags.
        tags.reverse()
        fb2_out += self.close_tags(tags)

        # Process element text that comes after the close of the XHTML tag but before the next XHTML tag.
        if hasattr(elem_tree, 'tail') and elem_tree.tail:
            if not self.in_p:
                fb2_out.append('
')
            fb2_out.append(prepare_string_for_xml(elem_tree.tail))
            if not self.in_p:
                fb2_out.append('
')

        return fb2_out

    def close_tags(self, tags):
        text = []
        for tag in tags:
            text.append('</%s>' % tag)
            if tag == 'p':
                self.in_p = False

        return text

{'repo_name': 'kovidgoyal/calibre', 'stars': '8012', 'repo_language': 'Python', 'file_name': 'sfin.recipe', 'mime_type': 'text/x-python', 'hash': -5969348341244345895, 'source_dataset': 'data'}


'use strict';
angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
function getDecimals(n) {
  n = n + '';
  var i = n.indexOf('.');
  return (i == -1) ? 0 : n.length - i - 1;
}

function getVF(n, opt_precision) {
  var v = opt_precision;

  if (undefined === v) {
    v = Math.min(getDecimals(n), 3);
  }

  var base = Math.pow(10, v);
  var f = ((n * base) | 0) % base;
  return {v: v, f: f};
}

$provide.value("$locale", {
  "DATETIME_FORMATS": {
    "AMPMS": [
      "a.m.",
      "p.m."
    ],
    "DAY": [
      "dy Sul",
      "dy Lun",
      "dy Meurth",
      "dy Merher",
      "dy Yow",
      "dy Gwener",
      "dy Sadorn"
    ],
    "ERANAMES": [
      "RC",
      "AD"
    ],
    "ERAS": [
      "RC",
      "AD"
    ],
    "FIRSTDAYOFWEEK": 0,
    "MONTH": [
      "mis Genver",
      "mis Hwevrer",
      "mis Meurth",
      "mis Ebrel",
      "mis Me",
      "mis Metheven",
      "mis Gortheren",
      "mis Est",
      "mis Gwynngala",
      "mis Hedra",
      "mis Du",
      "mis Kevardhu"
    ],
    "SHORTDAY": [
      "Sul",
      "Lun",
      "Mth",
      "Mhr",
      "Yow",
      "Gwe",
      "Sad"
    ],
    "SHORTMONTH": [
      "Gen",
      "Hwe",
      "Meu",
      "Ebr",
      "Me",
      "Met",
      "Gor",
      "Est",
      "Gwn",
      "Hed",
      "Du",
      "Kev"
    ],
    "STANDALONEMONTH": [
      "mis Genver",
      "mis Hwevrer",
      "mis Meurth",
      "mis Ebrel",
      "mis Me",
      "mis Metheven",
      "mis Gortheren",
      "mis Est",
      "mis Gwynngala",
      "mis Hedra",
      "mis Du",
      "mis Kevardhu"
    ],
    "WEEKENDRANGE": [
      5,
      6
    ],
    "fullDate": "y MMMM d, EEEE",
    "longDate": "y MMMM d",
    "medium": "y MMM d HH:mm:ss",
    "mediumDate": "y MMM d",
    "mediumTime": "HH:mm:ss",
    "short": "y-MM-dd HH:mm",
    "shortDate": "y-MM-dd",
    "shortTime": "HH:mm"
  },
  "NUMBER_FORMATS": {
    "CURRENCY_SYM": "\u00a3",
    "DECIMAL_SEP": ".",
    "GROUP_SEP": ",",
    "PATTERNS": [
      {
        "gSize": 3,
        "lgSize": 3,
        "maxFrac": 3,
        "minFrac": 0,
        "minInt": 1,
        "negPre": "-",
        "negSuf": "",
        "posPre": "",
        "posSuf": ""
      },
      {
        "gSize": 3,
        "lgSize": 3,
        "maxFrac": 2,
        "minFrac": 2,
        "minInt": 1,
        "negPre": "-\u00a4",
        "negSuf": "",
        "posPre": "\u00a4",
        "posSuf": ""
      }
    ]
  },
  "id": "kw-gb",
  "localeID": "kw_GB",
  "pluralCat": function(n, opt_precision) {  var i = n | 0;  var vf = getVF(n, opt_precision);  if (i == 1 && vf.v == 0) {    return PLURAL_CATEGORY.ONE;  }  return PLURAL_CATEGORY.OTHER;}
});
}]);

{'repo_name': 'pikock/bootstrap-magic', 'stars': '1700', 'repo_language': 'HTML', 'file_name': 'popovers.less', 'mime_type': 'text/plain', 'hash': 913670072868579478, 'source_dataset': 'data'}


# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.proguard.annotations.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.proguard.annotations.DoNotStrip *;
}

-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
  void set*(***);
  *** get*();
}

{'repo_name': 'ctripcorp/CRN', 'stars': '1241', 'repo_language': 'JavaScript', 'file_name': 'ReactAndroid-0.59.0-01-20190327.110133-2.pom', 'mime_type': 'text/xml', 'hash': -7324428333504241918, 'source_dataset': 'data'}


/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1995, 1996, 2003 by Ralf Baechle
 * Copyright (C) 1995, 1996 Andreas Busse
 * Copyright (C) 1995, 1996 Stoned Elipot
 * Copyright (C) 1995, 1996 Paul M. Antoine.
 * Copyright (C) 2009       Zhang Le
 */
#ifndef _ASM_BOOTINFO_H
#define _ASM_BOOTINFO_H

#include <linux/types.h>
#include <asm/setup.h>

/*
 * The MACH_ IDs are sort of equivalent to PCI product IDs.  As such the
 * numbers do not necessarily reflect technical relations or similarities
 * between systems.
 */

/*
 * Valid machtype values for group unknown
 */
#define  MACH_UNKNOWN		0	/* whatever...			*/

/*
 * Valid machtype for group DEC
 */
#define  MACH_DSUNKNOWN		0
#define  MACH_DS23100		1	/* DECstation 2100 or 3100	*/
#define  MACH_DS5100		2	/* DECsystem 5100		*/
#define  MACH_DS5000_200	3	/* DECstation 5000/200		*/
#define  MACH_DS5000_1XX	4	/* DECstation 5000/120, 125, 133, 150 */
#define  MACH_DS5000_XX		5	/* DECstation 5000/20, 25, 33, 50 */
#define  MACH_DS5000_2X0	6	/* DECstation 5000/240, 260	*/
#define  MACH_DS5400		7	/* DECsystem 5400		*/
#define  MACH_DS5500		8	/* DECsystem 5500		*/
#define  MACH_DS5800		9	/* DECsystem 5800		*/
#define  MACH_DS5900		10	/* DECsystem 5900		*/

/*
 * Valid machtype for group PMC-MSP
 */
#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation */
#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo */
#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation */
#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation */
#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential GW */
#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation */
#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */

/*
 * Valid machtype for group Mikrotik
 */
#define	MACH_MIKROTIK_RB532	0	/* Mikrotik RouterBoard 532 	*/
#define MACH_MIKROTIK_RB532A	1	/* Mikrotik RouterBoard 532A 	*/

/*
 * Valid machtype for Loongson family
 */
#define MACH_LOONGSON_UNKNOWN  0
#define MACH_LEMOTE_FL2E       1
#define MACH_LEMOTE_FL2F       2
#define MACH_LEMOTE_ML2F7      3
#define MACH_LEMOTE_YL2F89     4
#define MACH_DEXXON_GDIUM2F10  5
#define MACH_LEMOTE_NAS        6
#define MACH_LEMOTE_LL2F       7
#define MACH_LOONGSON_END      8

/*
 * Valid machtype for group INGENIC
 */
#define  MACH_INGENIC_JZ4730	0	/* JZ4730 SOC		*/
#define  MACH_INGENIC_JZ4740	1	/* JZ4740 SOC		*/

extern char *system_type;
const char *get_system_type(void);

extern unsigned long mips_machtype;

#define BOOT_MEM_MAP_MAX	32
#define BOOT_MEM_RAM		1
#define BOOT_MEM_ROM_DATA	2
#define BOOT_MEM_RESERVED	3
#define BOOT_MEM_INIT_RAM	4

/*
 * A memory map that's built upon what was determined
 * or specified on the command line.
 */
struct boot_mem_map {
	int nr_map;
	struct boot_mem_map_entry {
		phys_t addr;	/* start of memory segment */
		phys_t size;	/* size of memory segment */
		long type;		/* type of memory segment */
	} map[BOOT_MEM_MAP_MAX];
};

extern struct boot_mem_map boot_mem_map;

extern void add_memory_region(phys_t start, phys_t size, long type);

extern void prom_init(void);
extern void prom_free_prom_memory(void);

extern void free_init_pages(const char *what,
			    unsigned long begin, unsigned long end);

/*
 * Initial kernel command line, usually setup by prom_init()
 */
extern char arcs_cmdline[COMMAND_LINE_SIZE];

/*
 * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware
 */
extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;

/*
 * Platform memory detection hook called by setup_arch
 */
extern void plat_mem_setup(void);

#ifdef CONFIG_SWIOTLB
/*
 * Optional platform hook to call swiotlb_setup().
 */
extern void plat_swiotlb_setup(void);

#else

static inline void plat_swiotlb_setup(void) {}

#endif /* CONFIG_SWIOTLB */

#endif /* _ASM_BOOTINFO_H */

{'repo_name': 'tangsilian/android-vuln', 'stars': '315', 'repo_language': 'C', 'file_name': 'bamboo_defconfig', 'mime_type': 'text/plain', 'hash': -9220282227623901496, 'source_dataset': 'data'}


Subject: attraction

want succeed date , need little spark = relationship marriage ? here answer ! sensation = ae , compact disc prove subliminal = technique increase chance sexual success opposite sex . . simply = play watch work ! ! ! ! want winner ? = 20 yes http : / / 207 . 134 . 166 . 10 / user / subliminal / subliminal . htm

{'repo_name': 'savanpatel/machine-learning-101', 'stars': '128', 'repo_language': 'Python', 'file_name': 'spmsgc134.txt', 'mime_type': 'text/plain', 'hash': -4601093991368569118, 'source_dataset': 'data'}


/*
 Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.md or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang("uicolor","et",{title:"Värvivalija kasutajaliides",preview:"Automaatne eelvaade",config:"Aseta see sõne oma config.js faili.",predefined:"Eelmääratud värvikomplektid"});

{'repo_name': 'summerblue/laravel-blog', 'stars': '192', 'repo_language': 'JavaScript', 'file_name': 'jquery.ui.datepicker-tj.js', 'mime_type': 'text/plain', 'hash': -5943198236343126477, 'source_dataset': 'data'}


{% extends 'kingadmin/index.html' %}
{% load admin_tags %}
{% block page-title-text %}Password Reset{% endblock %}

{% block extra_head_resources %}

{% endblock %}

{% block breadcrumb %}

重置密码

 {{ user_obj.name  }}

 {% endblock %}

{% block page-content %}

{% include 'kingadmin/filter_search_box.html' %}

重置密码： "{{ user_obj}}"

    <form method="post" onsubmit="return CheckSelectedOptions()" class=" form-horizontal form-padding">{% csrf_token %}

            {% for field in form %}

                    {%if field.field.required%}

                            {{field.label}}

                    {% else %}

                           {{field.label}}

                    {% endif %}

                        {{ field }}

            {% endfor %}

            {{ form.errors }}

                    <button class="btn btn-info pull-right "  type="submit">Save</button>

    </form>

{% endblock %}

{'repo_name': 'triaquae/PerfectCRM', 'stars': '125', 'repo_language': 'JavaScript', 'file_name': '0011_auto_20161221_0759.py', 'mime_type': 'text/x-python', 'hash': -6037138916154146936, 'source_dataset': 'data'}


#ifndef GREGORIAN_HPP__
#define GREGORIAN_HPP__

/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
 * Use, modification and distribution is subject to the
 * Boost Software License, Version 1.0. (See accompanying
 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 * Author: Jeff Garland, Bart Garst
 * $Date$
 */

/*! @file gregorian.hpp
  Single file header that provides overall include for all elements of
  the gregorian date-time system.  This includes the various types
  defined, but also other functions for formatting and parsing.
*/

#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/gregorian/conversion.hpp"
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/gregorian/formatters_limited.hpp"
#else
#include "boost/date_time/gregorian/formatters.hpp"
#endif

#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/gregorian/greg_facet.hpp"
#else
#include "boost/date_time/gregorian/gregorian_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO

#include "boost/date_time/gregorian/parsers.hpp"

#endif

{'repo_name': 'nginnever/zogminer', 'stars': '148', 'repo_language': 'C++', 'file_name': 'run-bitcoin-cli', 'mime_type': 'text/x-shellscript', 'hash': -7013734833724267454, 'source_dataset': 'data'}


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true">

    <ImageView
        android:id="@+id/emoji"
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:layout_marginTop="24dp"
        android:importantForAccessibility="no"
        app:srcCompat="@drawable/emoji_hugging_face"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>

    <TextView
        android:id="@+id/supportText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/support_title"
        android:layout_marginTop="24dp"
        android:textStyle="bold"
        android:textSize="18sp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/emoji"/>

    <TextView
        android:id="@+id/supportDescription"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/support_description"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:gravity="center"
        android:textSize="16sp"
        android:paddingBottom="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/supportText"/>

</androidx.constraintlayout.widget.ConstraintLayout>

{'repo_name': 'lucasnlm/antimine-android', 'stars': '167', 'repo_language': 'Kotlin', 'file_name': 'MainApplication.kt', 'mime_type': 'text/plain', 'hash': 5172697556421367580, 'source_dataset': 'data'}


package protocolsupport.protocol.packet.middleimpl.clientbound.play.v_9r1_9r2_10_11_12r1_12r2;

import protocolsupport.api.utils.Any;
import protocolsupport.protocol.packet.PacketType;
import protocolsupport.protocol.packet.middleimpl.ClientBoundPacketData;
import protocolsupport.protocol.packet.middleimpl.clientbound.play.v_4_5_6_7_8_9r1_9r2_10_11_12r1_12r2.AbstractScoreboardTeam;
import protocolsupport.protocol.serializer.ArraySerializer;
import protocolsupport.protocol.serializer.MiscSerializer;
import protocolsupport.protocol.serializer.StringSerializer;
import protocolsupport.protocol.typeremapper.legacy.LegacyChat;

public class ScoreboardTeam extends AbstractScoreboardTeam {

	public ScoreboardTeam(MiddlePacketInit init) {
		super(init);
	}

	@Override
	protected void writeToClient() {
		ClientBoundPacketData scoreboardteam = ClientBoundPacketData.create(PacketType.CLIENTBOUND_PLAY_SCOREBOARD_TEAM);
		StringSerializer.writeVarIntUTF8String(scoreboardteam, name);
		MiscSerializer.writeByteEnum(scoreboardteam, mode);
		if ((mode == Mode.CREATE) || (mode == Mode.UPDATE)) {
			StringSerializer.writeVarIntUTF8String(scoreboardteam, LegacyChat.clampLegacyText(displayName.toLegacyText(clientCache.getLocale()), 32));
			Any<String, String> nfix = formatPrefixSuffix();
			StringSerializer.writeVarIntUTF8String(scoreboardteam, nfix.getObj1());
			StringSerializer.writeVarIntUTF8String(scoreboardteam, nfix.getObj2());
			scoreboardteam.writeByte(friendlyFire);
			StringSerializer.writeVarIntUTF8String(scoreboardteam, nameTagVisibility);
			StringSerializer.writeVarIntUTF8String(scoreboardteam, collisionRule);
			scoreboardteam.writeByte(format.isColor() ? format.ordinal() : -1);
		}
		if ((mode == Mode.CREATE) || (mode == Mode.PLAYERS_ADD) || (mode == Mode.PLAYERS_REMOVE)) {
			ArraySerializer.writeVarIntVarIntUTF8StringArray(scoreboardteam, players);
		}
		codec.write(scoreboardteam);
	}

}

{'repo_name': 'ProtocolSupport/ProtocolSupport', 'stars': '397', 'repo_language': 'Java', 'file_name': 'ProtocolVersionTests.java', 'mime_type': 'text/plain', 'hash': -7661203912283375171, 'source_dataset': 'data'}


# -*- coding: utf-8 -*-

# =============================================================================
#  @article{zhang2017beyond,
#    title={Beyond a {Gaussian} denoiser: Residual learning of deep {CNN} for image denoising},
#    author={Zhang, Kai and Zuo, Wangmeng and Chen, Yunjin and Meng, Deyu and Zhang, Lei},
#    journal={IEEE Transactions on Image Processing},
#    year={2017},
#    volume={26},
#    number={7},
#    pages={3142-3155},
#  }
# by Kai Zhang (08/2018)
# cskaizhang@gmail.com
# https://github.com/cszn
# modified on the code from https://github.com/husqin/DnCNN-keras
# =============================================================================

# run this to test the model

import argparse
import os, time, datetime
#import PIL.Image as Image
import numpy as np
from keras.models import load_model, model_from_json
from skimage.measure import compare_psnr, compare_ssim
from skimage.io import imread, imsave

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--set_dir', default='data/Test', type=str, help='directory of test dataset')
    parser.add_argument('--set_names', default=['Set68','Set12'], type=list, help='name of test dataset')
    parser.add_argument('--sigma', default=25, type=int, help='noise level')
    parser.add_argument('--model_dir', default=os.path.join('models','DnCNN_sigma25'), type=str, help='directory of the model')
    parser.add_argument('--model_name', default='model_001.hdf5', type=str, help='the model name')
    parser.add_argument('--result_dir', default='results', type=str, help='directory of results')
    parser.add_argument('--save_result', default=0, type=int, help='save the denoised image, 1 or 0')
    return parser.parse_args()

def to_tensor(img):
    if img.ndim == 2:
        return img[np.newaxis,...,np.newaxis]
    elif img.ndim == 3:
        return np.moveaxis(img,2,0)[...,np.newaxis]

def from_tensor(img):
    return np.squeeze(np.moveaxis(img[...,0],0,-1))

def log(*args,**kwargs):
     print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S:"),*args,**kwargs)

def save_result(result,path):
    path = path if path.find('.') != -1 else path+'.png'
    ext = os.path.splitext(path)[-1]
    if ext in ('.txt','.dlm'):
        np.savetxt(path,result,fmt='%2.4f')
    else:
        imsave(path,np.clip(result,0,1))

def show(x,title=None,cbar=False,figsize=None):
    import matplotlib.pyplot as plt
    plt.figure(figsize=figsize)
    plt.imshow(x,interpolation='nearest',cmap='gray')
    if title:
        plt.title(title)
    if cbar:
        plt.colorbar()
    plt.show()

if __name__ == '__main__':

    args = parse_args()

    # =============================================================================
    #     # serialize model to JSON
    #     model_json = model.to_json()
    #     with open("model.json", "w") as json_file:
    #         json_file.write(model_json)
    #     # serialize weights to HDF5
    #     model.save_weights("model.h5")
    #     print("Saved model")
    # =============================================================================

    if not os.path.exists(os.path.join(args.model_dir, args.model_name)):
        # load json and create model
        json_file = open(os.path.join(args.model_dir,'model.json'), 'r')
        loaded_model_json = json_file.read()
        json_file.close()
        model = model_from_json(loaded_model_json)
        # load weights into new model
        model.load_weights(os.path.join(args.model_dir,'model.h5'))
        log('load trained model on Train400 dataset by kai')
    else:
        model = load_model(os.path.join(args.model_dir, args.model_name),compile=False)
        log('load trained model')

    if not os.path.exists(args.result_dir):
        os.mkdir(args.result_dir)

    for set_cur in args.set_names:

        if not os.path.exists(os.path.join(args.result_dir,set_cur)):
            os.mkdir(os.path.join(args.result_dir,set_cur))
        psnrs = []
        ssims = []

        for im in os.listdir(os.path.join(args.set_dir,set_cur)):
            if im.endswith(".jpg") or im.endswith(".bmp") or im.endswith(".png"):
                #x = np.array(Image.open(os.path.join(args.set_dir,set_cur,im)), dtype='float32') / 255.0
                x = np.array(imread(os.path.join(args.set_dir,set_cur,im)), dtype=np.float32) / 255.0
                np.random.seed(seed=0) # for reproducibility
                y = x + np.random.normal(0, args.sigma/255.0, x.shape) # Add Gaussian noise without clipping
                y = y.astype(np.float32)
                y_  = to_tensor(y)
                start_time = time.time()
                x_ = model.predict(y_) # inference
                elapsed_time = time.time() - start_time
                print('%10s : %10s : %2.4f second'%(set_cur,im,elapsed_time))
                x_=from_tensor(x_)
                psnr_x_ = compare_psnr(x, x_)
                ssim_x_ = compare_ssim(x, x_)
                if args.save_result:
                    name, ext = os.path.splitext(im)
                    show(np.hstack((y,x_))) # show the image
                    save_result(x_,path=os.path.join(args.result_dir,set_cur,name+'_dncnn'+ext)) # save the denoised image
                psnrs.append(psnr_x_)
                ssims.append(ssim_x_)

        psnr_avg = np.mean(psnrs)
        ssim_avg = np.mean(ssims)
        psnrs.append(psnr_avg)
        ssims.append(ssim_avg)

        if args.save_result:
            save_result(np.hstack((psnrs,ssims)),path=os.path.join(args.result_dir,set_cur,'results.txt'))

        log('Datset: {0:10s} \n  PSNR = {1:2.2f}dB, SSIM = {2:1.4f}'.format(set_cur, psnr_avg, ssim_avg))

{'repo_name': 'cszn/DnCNN', 'stars': '775', 'repo_language': 'MATLAB', 'file_name': 'shave.m', 'mime_type': 'text/plain', 'hash': 4719103809226821547, 'source_dataset': 'data'}


#!/usr/bin/env python
# extract test case IDs from json-formatted list (`sp_testdrv.py -l` or `idp_testdrv.py -l`)
# usage:
#  sp_testdrv.py -l | filter_testcase_ids.py
__author__ = 'rhoerbe'

import json, sys
jdata = json.load(sys.stdin)
for k in jdata:
    print(k["id"])

{'repo_name': 'IdentityPython/pysaml2', 'stars': '333', 'repo_language': 'Python', 'file_name': 'run_oper.sh', 'mime_type': 'text/x-shellscript', 'hash': 7492142273457886846, 'source_dataset': 'data'}


{'repo_name': 'gyjzh/LLWeChat', 'stars': '1219', 'repo_language': 'Objective-C', 'file_name': 'IEMCallManager.h', 'mime_type': 'text/x-objective-c', 'hash': 7230265600665145548, 'source_dataset': 'data'}


/*
 * Copyright (C) 2013 Dr. John Lindsay <jlindsay@uoguelph.ca>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package plugins;

import java.util.Date;
import whitebox.geospatialfiles.WhiteboxRaster;
import whitebox.interfaces.WhiteboxPlugin;
import whitebox.interfaces.WhiteboxPluginHost;

/**
 * This tool can be used to calculate the downslope index described by Hjerdt et al (2004).
 *
 * @author Dr. John Lindsay email: jlindsay@uoguelph.ca
 */
public class DownslopeIndex implements WhiteboxPlugin {

    private WhiteboxPluginHost myHost = null;
    private String[] args;
    // Constants
    private static final double LnOf2 = 0.693147180559945;

    /**
     * Used to retrieve the plugin tool's name. This is a short, unique name
     * containing no spaces.
     *
     * @return String containing plugin name.
     */
    @Override
    public String getName() {
        return "DownslopeIndex";
    }

    /**
     * Used to retrieve the plugin tool's descriptive name. This can be a longer
     * name (containing spaces) and is used in the interface to list the tool.
     *
     * @return String containing the plugin descriptive name.
     */
    @Override
    public String getDescriptiveName() {
        return "Downslope Index";
    }

    /**
     * Used to retrieve a short description of what the plugin tool does.
     *
     * @return String containing the plugin's description.
     */
    @Override
    public String getToolDescription() {
        return "Calculates the downslope index of Hjerdt et al. (WRR 2004)";
    }

    /**
     * Used to identify which toolboxes this plugin tool should be listed in.
     *
     * @return Array of Strings.
     */
    @Override
    public String[] getToolbox() {
        String[] ret = {"FlowpathTAs", "HydroTools"};
        return ret;
    }

    /**
     * Sets the WhiteboxPluginHost to which the plugin tool is tied. This is the
     * class that the plugin will send all feedback messages, progress updates,
     * and return objects.
     *
     * @param host The WhiteboxPluginHost that called the plugin tool.
     */
    @Override
    public void setPluginHost(WhiteboxPluginHost host) {
        myHost = host;
    }

    /**
     * Used to communicate feedback pop-up messages between a plugin tool and
     * the main Whitebox user-interface.
     *
     * @param feedback String containing the text to display.
     */
    private void showFeedback(String message) {
        if (myHost != null) {
            myHost.showFeedback(message);
        } else {
            System.out.println(message);
        }
    }

    /**
     * Used to communicate a return object from a plugin tool to the main
     * Whitebox user-interface.
     *
     * @return Object, such as an output WhiteboxRaster.
     */
    private void returnData(Object ret) {
        if (myHost != null) {
            myHost.returnData(ret);
        }
    }
    private int previousProgress = 0;
    private String previousProgressLabel = "";

    /**
     * Used to communicate a progress update between a plugin tool and the main
     * Whitebox user interface.
     *
     * @param progressLabel A String to use for the progress label.
     * @param progress Float containing the progress value (between 0 and 100).
     */
    private void updateProgress(String progressLabel, int progress) {
        if (myHost != null && ((progress != previousProgress)
                || (!progressLabel.equals(previousProgressLabel)))) {
            myHost.updateProgress(progressLabel, progress);
        }
        previousProgress = progress;
        previousProgressLabel = progressLabel;
    }

    /**
     * Used to communicate a progress update between a plugin tool and the main
     * Whitebox user interface.
     *
     * @param progress Float containing the progress value (between 0 and 100).
     */
    private void updateProgress(int progress) {
        if (myHost != null && progress != previousProgress) {
            myHost.updateProgress(progress);
        }
        previousProgress = progress;
    }

    /**
     * Sets the arguments (parameters) used by the plugin.
     *
     * @param args An array of string arguments.
     */
    @Override
    public void setArgs(String[] args) {
        this.args = args.clone();
    }
    private boolean cancelOp = false;

    /**
     * Used to communicate a cancel operation from the Whitebox GUI.
     *
     * @param cancel Set to true if the plugin should be canceled.
     */
    @Override
    public void setCancelOp(boolean cancel) {
        cancelOp = cancel;
    }

    private void cancelOperation() {
        showFeedback("Operation cancelled.");
        updateProgress("Progress: ", 0);
    }
    private boolean amIActive = false;

    /**
     * Used by the Whitebox GUI to tell if this plugin is still running.
     *
     * @return a boolean describing whether or not the plugin is actively being
     * used.
     */
    @Override
    public boolean isActive() {
        return amIActive;
    }

    /**
     * Used to execute this plugin tool.
     */
    @Override
    public void run() {
        amIActive = true;

        String pointerHeader, DEMHeader, outputHeader;
        int row, col, x, y;
        int progress;
        int c;
        int[] dX = new int[]{1, 1, 1, 0, -1, -1, -1, 0};
        int[] dY = new int[]{-1, 0, 1, 1, 1, 0, -1, -1};
        boolean flag;
        double flowDir, flowLength, flowLengthThroughCell;
        double zSt, zCurrent, zLastCell;
        double rad2Deg = 180.0 / Math.PI;

        if (args.length <= 0) {
            showFeedback("Plugin parameters have not been set.");
            return;
        }

        pointerHeader = args[0];
        DEMHeader = args[1];
        outputHeader = args[2];
        double d = Double.parseDouble(args[3]);
        if (d <= 0) {
            showFeedback("The vertical drop parameter must be set to a positive numerical value.");
            return;
        }
        String outputType = args[4].toLowerCase().trim();

        // check to see that the inputHeader and outputHeader are not null.
        if (pointerHeader.isEmpty() || DEMHeader.isEmpty() || outputHeader.isEmpty()) {
            showFeedback("One or more of the input parameters have not been set properly.");
            return;
        }

        try {
            WhiteboxRaster pointer = new WhiteboxRaster(pointerHeader, "r");
            int rows = pointer.getNumberRows();
            int cols = pointer.getNumberColumns();
            double noData = pointer.getNoDataValue();

            double gridResX = pointer.getCellSizeX();
            double gridResY = pointer.getCellSizeY();
            double diagGridRes = Math.sqrt(gridResX * gridResX + gridResY * gridResY);
            double[] gridLengths = new double[]{diagGridRes, gridResX, diagGridRes, gridResY, diagGridRes, gridResX, diagGridRes, gridResY};

            WhiteboxRaster dem = new WhiteboxRaster(DEMHeader, "r");
            if (dem.getNumberColumns() != cols || dem.getNumberRows() != rows) {
                showFeedback("Each of the input images must have the same dimensions (i.e. rows and columns).");
                return;
            }
            double demNoData = dem.getNoDataValue();

            if (pointer.getXYUnits().toLowerCase().contains("deg") ||
                    dem.getXYUnits().toLowerCase().contains("deg")) {

                    double p1 = 111412.84;		// longitude calculation term 1
                    double p2 = -93.5;			// longitude calculation term 2
                    double p3 = 0.118;			// longitude calculation term 3
                    double lat = Math.toRadians((pointer.getNorth() - pointer.getSouth()) / 2.0);
                    double longlen = (p1 * Math.cos(lat)) + (p2 * Math.cos(3 * lat)) +
                                                (p3 * Math.cos(5 * lat));
                    for (int i = 0;i < 8; i++) {
                        gridLengths[i] = gridLengths[i] * longlen;
                    }
            }

            WhiteboxRaster output = new WhiteboxRaster(outputHeader, "rw",
                    pointerHeader, WhiteboxRaster.DataType.FLOAT, noData);
            output.setPreferredPalette("spectrum.pal");
            output.setDataScale(WhiteboxRaster.DataScale.CONTINUOUS);

            switch (outputType) {
                case "tangent":
                    for (row = 0; row < rows; row++) {
                        for (col = 0; col < cols; col++) {
                            if (pointer.getValue(row, col) != noData && dem.getValue(row, col) != demNoData) {
                                zSt = dem.getValue(row, col);
                                flag = false;
                                x = col;
                                y = row;
                                flowLength = 0;
                                do {
                                    zLastCell = dem.getValue(row, col);
                                    // find it's downslope neighbour
                                    flowDir = pointer.getValue(y, x);
                                    if (flowDir > 0) {

                                        // what's the flow direction as an int?
                                        c = (int) (Math.log(flowDir) / LnOf2);

                                        //move x and y accordingly
                                        x += dX[c];
                                        y += dY[c];
                                        zCurrent = dem.getValue(y, x);
                                        if (zCurrent != demNoData) {
                                            if ((zSt - zCurrent) < d) {
                                                flowLength += gridLengths[c];
                                            } else {
                                                //interpolate the distance
                                                flowLengthThroughCell = gridLengths[c] * (zLastCell - (zSt - d)) / (zLastCell - zCurrent);
                                                flowLength += flowLengthThroughCell;
                                                output.setValue(row, col, d / flowLength);
                                                flag = true;
                                            }
                                        } else {
                                            if (flowLength > 0) {
                                                output.setValue(row, col, (zSt - zLastCell) / flowLength);
                                            } else {
                                                output.setValue(row, col, noData);
                                            }
                                            flag = true;
                                        }

                                    } else {  // you've hit the edge or a pit cell.
                                        if (flowLength > 0) {
                                            output.setValue(row, col, (zSt - zLastCell) / flowLength);
                                        } else {
                                            output.setValue(row, col, noData);
                                        }
                                        flag = true;
                                    }
                                } while (!flag);
                            }
                        }
                        if (cancelOp) {
                            cancelOperation();
                            return;
                        }
                        progress = (int) (100f * row / (rows - 1));
                        updateProgress(progress);
                    }
                    break;

                case "degrees":
                    for (row = 0; row < rows; row++) {
                        for (col = 0; col < cols; col++) {
                            if (pointer.getValue(row, col) != noData && dem.getValue(row, col) != demNoData) {
                                zSt = dem.getValue(row, col);
                                flag = false;
                                x = col;
                                y = row;
                                flowLength = 0;
                                do {
                                    zLastCell = dem.getValue(row, col);
                                    // find it's downslope neighbour
                                    flowDir = pointer.getValue(y, x);
                                    if (flowDir > 0) {

                                        // what's the flow direction as an int?
                                        c = (int) (Math.log(flowDir) / LnOf2);

                                        //move x and y accordingly
                                        x += dX[c];
                                        y += dY[c];
                                        zCurrent = dem.getValue(y, x);
                                        if (zCurrent != demNoData) {
                                            if ((zSt - zCurrent) < d) {
                                                flowLength += gridLengths[c];
                                            } else {
                                                //interpolate the distance
                                                flowLengthThroughCell = gridLengths[c] * (zLastCell - (zSt - d)) / (zLastCell - zCurrent);
                                                flowLength += flowLengthThroughCell;
                                                output.setValue(row, col, Math.atan(d / flowLength) * rad2Deg);
                                                flag = true;
                                            }
                                        } else {
                                            if (flowLength > 0) {
                                                output.setValue(row, col, Math.atan((zSt - zLastCell) / flowLength) * rad2Deg);
                                            } else {
                                                output.setValue(row, col, noData);
                                            }
                                            flag = true;
                                        }

                                    } else {  // you've hit the edge or a pit cell.
                                        if (flowLength > 0) {
                                            output.setValue(row, col, Math.atan((zSt - zLastCell) / flowLength) * rad2Deg);
                                        } else {
                                            output.setValue(row, col, noData);
                                        }
                                        flag = true;
                                    }
                                } while (!flag);
                            }
                        }
                        if (cancelOp) {
                            cancelOperation();
                            return;
                        }
                        progress = (int) (100f * row / (rows - 1));
                        updateProgress(progress);
                    }
                    break;

                case "radians":
                    for (row = 0; row < rows; row++) {
                        for (col = 0; col < cols; col++) {
                            if (pointer.getValue(row, col) != noData && dem.getValue(row, col) != demNoData) {
                                zSt = dem.getValue(row, col);
                                flag = false;
                                x = col;
                                y = row;
                                flowLength = 0;
                                do {
                                    zLastCell = dem.getValue(row, col);
                                    // find it's downslope neighbour
                                    flowDir = pointer.getValue(y, x);
                                    if (flowDir > 0) {

                                        // what's the flow direction as an int?
                                        c = (int) (Math.log(flowDir) / LnOf2);

                                        //move x and y accordingly
                                        x += dX[c];
                                        y += dY[c];
                                        zCurrent = dem.getValue(y, x);
                                        if (zCurrent != demNoData) {
                                            if ((zSt - zCurrent) < d) {
                                                flowLength += gridLengths[c];
                                            } else {
                                                //interpolate the distance
                                                flowLengthThroughCell = gridLengths[c] * (zLastCell - (zSt - d)) / (zLastCell - zCurrent);
                                                flowLength += flowLengthThroughCell;
                                                output.setValue(row, col, Math.atan(d / flowLength));
                                                flag = true;
                                            }
                                        } else {
                                            if (flowLength > 0) {
                                                output.setValue(row, col, Math.atan((zSt - zLastCell) / flowLength));
                                            } else {
                                                output.setValue(row, col, noData);
                                            }
                                            flag = true;
                                        }

                                    } else {  // you've hit the edge or a pit cell.
                                        if (flowLength > 0) {
                                            output.setValue(row, col, Math.atan((zSt - zLastCell) / flowLength));
                                        } else {
                                            output.setValue(row, col, noData);
                                        }
                                        flag = true;
                                    }
                                } while (!flag);
                            }
                        }
                        if (cancelOp) {
                            cancelOperation();
                            return;
                        }
                        progress = (int) (100f * row / (rows - 1));
                        updateProgress(progress);
                    }
                    break;

                case "distance":
                    for (row = 0; row < rows; row++) {
                        for (col = 0; col < cols; col++) {
                            if (pointer.getValue(row, col) != noData && dem.getValue(row, col) != demNoData) {
                                zSt = dem.getValue(row, col);
                                flag = false;
                                x = col;
                                y = row;
                                flowLength = 0;
                                do {
                                    zLastCell = dem.getValue(row, col);
                                    // find it's downslope neighbour
                                    flowDir = pointer.getValue(y, x);
                                    if (flowDir > 0) {

                                        // what's the flow direction as an int?
                                        c = (int) (Math.log(flowDir) / LnOf2);

                                        //move x and y accordingly
                                        x += dX[c];
                                        y += dY[c];
                                        zCurrent = dem.getValue(y, x);
                                        if (zCurrent != demNoData) {
                                            if ((zSt - zCurrent) < d) {
                                                flowLength += gridLengths[c];
                                            } else {
                                                //interpolate the distance
                                                flowLengthThroughCell = gridLengths[c] * (zLastCell - (zSt - d)) / (zLastCell - zCurrent);
                                                flowLength += flowLengthThroughCell;
                                                output.setValue(row, col, flowLength);
                                                flag = true;
                                            }
                                        } else {
                                            if (flowLength > 0) {
                                                output.setValue(row, col, flowLength);
                                            } else {
                                                output.setValue(row, col, noData);
                                            }
                                            flag = true;
                                        }

                                    } else {  // you've hit the edge or a pit cell.
                                        if (flowLength > 0) {
                                            output.setValue(row, col, flowLength);
                                        } else {
                                            output.setValue(row, col, noData);
                                        }
                                        flag = true;
                                    }
                                } while (!flag);
                            }
                        }
                        if (cancelOp) {
                            cancelOperation();
                            return;
                        }
                        progress = (int) (100f * row / (rows - 1));
                        updateProgress(progress);
                    }
                    break;
            }

            output.addMetadataEntry("Created by the "
                    + getDescriptiveName() + " tool.");
            output.addMetadataEntry("Created on " + new Date());

            pointer.close();
            dem.close();
            output.close();

            // returning a header file string displays the image.
            returnData(outputHeader);

        } catch (OutOfMemoryError oe) {
            myHost.showFeedback("An out-of-memory error has occurred during operation.");
        } catch (Exception e) {
            myHost.showFeedback("An error has occurred during operation. See log file for details.");
            myHost.logException("Error in " + getDescriptiveName(), e);
        } finally {
            updateProgress("Progress: ", 0);
            // tells the main application that this process is completed.
            amIActive = false;
            myHost.pluginComplete();
        }
    }

//    /**
//     * This method is only used during testing.
//    */
//    // this is only used for testing the tool
//    public static void main(String[] args) {
//        args = new String[5];
//        args[0] = "/Users/johnlindsay/Documents/Data/SouthernOnt/tmp10.dep";
//        args[1] = "/Users/johnlindsay/Documents/Data/SouthernOnt/tmp4.dep";
//        args[2] = "/Users/johnlindsay/Documents/Data/SouthernOnt/tmp11.dep";
//        args[3] = "5";
//        args[4] = "distance";
//
//        DownslopeIndex di = new DownslopeIndex();
//        di.setArgs(args);
//        di.run();
//
//    }
}

{'repo_name': 'jblindsay/whitebox-geospatial-analysis-tools', 'stars': '152', 'repo_language': 'Java', 'file_name': 'ToolDialog.java', 'mime_type': 'text/x-java', 'hash': -2758767191113003317, 'source_dataset': 'data'}