text:
package okuki.sample.common.network;

import android.util.Range;

import com.jakewharton.rxrelay.PublishRelay;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import okuki.sample.common.rx.Errors;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public abstract class DataManager<T> {

    private static final int DEFAULT_PAGE_SIZE = 20;

    private final List<T> results = new ArrayList<>();
    private final AtomicBoolean loading = new AtomicBoolean(false);
    private final PublishRelay<Boolean> loadingStatus = PublishRelay.create();
    private final PublishRelay<Range<Integer>> rangeInserted = PublishRelay.create();
    private final PublishRelay<Void> listUpdated = PublishRelay.create();
    private int pageSize = DEFAULT_PAGE_SIZE;

    public Observable<Boolean> onLoadingStatus() {
        return loadingStatus;
    }

    public Observable<Range<Integer>> onRangeInserted() {
        return rangeInserted;
    }

    public Observable<Void> onListUpdated() {
        return listUpdated;
    }

    public void load() {
        if (!loading.get()) {
            results.clear();
            loadMore();
        }
    }

    public void loadMore() {
        if (!loading.get()) {
            setLoading(true);
            loadData(pageSize, results.size())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnError(error -> setLoading(false))
                    .subscribe(
                            list -> {
                                if (!list.isEmpty()) {
                                    int start = results.size();
                                    int end = start + list.size();
                                    results.addAll(list);
                                    if (start > 0) {
                                        rangeInserted.call(new Range<>(start, end));
                                    } else {
                                        listUpdated.call(null);
                                    }
                                }
                                setLoading(false);
                            },
                            Errors.log());
        }
    }

    private void setLoading(boolean isLoading) {
        loading.set(isLoading);
        loadingStatus.call(isLoading);
    }

    protected abstract Observable<List<T>> loadData(int limit, int offset);

    public int getNumResults() {
        return results.size();
    }

    public T getResult(int index) {
        return results.get(index);
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageSize() {
        return pageSize;
    }

    protected List<T> getResults() {
        return results;
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticles extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');

            $table->string('category')->index();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body')->nullable();

            $table->date('date')->index();
            $table->boolean('featured')->index()->nullable();
            $table->integer('position');
            $table->boolean('public');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('articles');
    }
}


text: <!DOCTYPE html>


text:
<?xml version="1.0" encoding="utf-8"?>
<library isWhitelist="true">
  <extension id="blackberry.app">
    <entryClass>blackberry.app.AppExtension</entryClass>
  </extension>

  <platforms>
    <platform value="JAVA">
      <target version="default" config="JAVA_XHR" />
      <target version="5.0" config="JAVA_XHR_BlackBerry" />
    </platform>
  </platforms>

  <configurations>
    <configuration name="JAVA_XHR" version="1.0" comment="For XHR architecture for Java implementation">
      <src type="text/java" path="blackberry" comment="API implementation in JavaScript" />
    </configuration>
    <configuration name="JAVA_XHR_BlackBerry" version="1.0" comment="For XHR architecture for Java implementation for OS 5.0">
      <src type="text/java" path="blackberry" comment="API implementation in JavaScript" />
    </configuration>
  </configurations>

  <features>
    <feature id="blackberry.app" version="1.0.0">The Application object provides functions and properties for the currently running application.</feature>
    <feature id="blackberry.app.event" version="1.0.0">The Application Event object allows you to access events triggered by the application.</feature>
  </features>

  <object name="blackberry.app" shortName="Application" introduced="1.0.0" comment="The Application object provides functions and properties for the currently running application.">
    <example><![CDATA[<script type="text/javascript">
  function newData(isNewData) {
    if (isNewData && !blackberry.app.isForeground) {
      blackberry.app.setHomeScreenName("New data");
    }
    else {
      alert("New data has arrived");
    }
  }
</script>]]></example>

    <functions>
      <func name="exit" static="true" returns="void" comment="This function will cause the application to exit."/>
      <func name="setHomeScreenName" static="true" returns="void" comment="This method will set the text for the icon that appears in the Home Screen of the device.">
        <param name="text" type="String" comment="Text to appear on the home screen icon."/>
        <details>
          Returns true if successful, false otherwise. Changes made using this API are NOT persisted across resets.
        </details>
      </func>
      <func name="setHomeScreenIcon" static="true" returns="void" comment="This method will set the icon that appears in the Home Screen of the device.">
        <param name="uri" type="String" comment="Location of the image to use for the icon.  The path to the image resource must be fully qualified.  An example of a fully qualified path is local:///resourceFolder/icons/icon.png.  The path to the resource must also be included in the whitelist.  For example, accessing an image on the file system requires 'file:///' to be whitelisted"/>
        <param name="hover" type="Boolean" optional="true" comment="optional parameter.  If set to true then the hover icon for the application is changed.  By default this is false, so the icon that is changed is the default main icon for the application."/>
        <details>
          Returns true if successful, false otherwise. The hover icon can only be set when the application icon has been set first. Changes made using this API are NOT persisted across device resets.
        </details>
      </func>
      <func name="requestForeground" static="true" returns="void" comment="This function will move the application to the foreground application.">
      </func>
      <func name="requestBackground" static="true" returns="void" comment="This function will move the application to the background.">
      </func>
    </functions>

    <properties>
      <property name="id" static="true" type="String" readonly="true" comment="A property representing the ID of the widget that is specified in the config.xml file."/>
      <property name="name" static="true" type="String" readonly="true" comment="A property representing the name of the widget that is specified in the config.xml file."/>
      <property name="description" static="true" type="String" readonly="true" comment="A property representing the description of the widget that is specified in the config.xml file."/>
      <property name="author" static="true" type="String" readonly="true" comment="A property representing the ID of the author's name that is specified in the config.xml file."/>
      <property name="authorEmail" static="true" type="String" readonly="true" comment="A property representing the author's email of the widget that is specified in the config.xml file."/>
      <property name="authorURL" static="true" type="String" readonly="true" comment="A property representing the author's URL of the widget that is specified in the config.xml file."/>
      <property name="version" static="true" type="String" readonly="true" comment="A property representing the version of the widget that is specified in the config.xml file."/>
      <property name="license" static="true" type="String" readonly="true" comment="A property representing the license of the widget that is specified in the config.xml file."/>
      <property name="copyright" static="true" type="String" readonly="true" comment="A property representing the copyright information of the widget that is specified in the config.xml file."/>
      <property name="isForeground" static="true" type="Boolean" readonly="true" comment="A property that will return true if the widget is in the foreground."/>
      <property name="licenseURL" static="true" type="String" readonly="true" comment="A property representing the license URL of the widget that is specified in the config.xml file."/>
    </properties>

  </object>
</library>


text:
package com.diandi.demo.widget.dialog;

import android.content.Context;
import android.widget.ArrayAdapter;

import com.diandi.demo.R;

import java.util.ArrayList;
import java.util.List;

public class ImgListDialog extends ListDialog {
    public ImgListDialog(Context context) {
        super(context);
    }

    public ImgListDialog(Context context, int theme) {
        super(context, theme);
    }

    public ImgListDialog(Context context, String title, ArrayList<String> list) {
        super(context, title, list);
    }

    @Override
    public void setListText(ArrayList<String> lists) {
        mListText.setAdapter(new ArrayAdapter<String>(mContext, R.layout.item_list_dialog, lists));
    }

    public class ImgListDialogAdapter extends ArrayAdapter<ActionItem> {
        public ImgListDialogAdapter(Context context, int resource, List<ActionItem> objects) {
            super(context, resource, objects);
        }
    }

}


text:
package com.n2hsu.launcher;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

public class PreloadReceiver extends BroadcastReceiver {
	private static final String TAG = "Launcher.PreloadReceiver";
	private static final boolean LOGD = false;

	public static final String EXTRA_WORKSPACE_NAME = "com.n2hsu.launcher.action.EXTRA_WORKSPACE_NAME";

	@Override
	public void onReceive(Context context, Intent intent) {
		final LauncherProvider provider = LauncherAppState.getLauncherProvider();
		if (provider != null) {
			String name = intent.getStringExtra(EXTRA_WORKSPACE_NAME);
			final int workspaceResId = !TextUtils.isEmpty(name) ? context.getResources().getIdentifier(name,
					"xml", "com.n2hsu.launcher") : 0;
			if (LOGD) {
				Log.d(TAG, "workspace name: " + name + " id: " + workspaceResId);
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					provider.loadDefaultFavoritesIfNecessary(workspaceResId);
				}
			}).start();
		}
	}
}


text:
import datetime

from jsonpath_rw_ext import parser
from oslo_log import log
from oslo_utils import timeutils
import yaml

from ceilometer import sample as sample_util

LOG = log.getLogger(__name__)

class UnableToLoadMappings(Exception):
    pass

class NoMappingsFound(Exception):
    pass

class CeiloscaMappingDefinitionException(Exception):
    def __init__(self, message, definition_cfg):
        super(CeiloscaMappingDefinitionException, self).__init__(message)
        self.message = message
        self.definition_cfg = definition_cfg

    def __str__(self):
        return '%s %s: %s' % (self.__class__.__name__,
                              self.definition_cfg, self.message)

class MonascaDataFilter(object):
    JSONPATH_RW_PARSER = parser.ExtentedJsonPathParser()

    def __init__(self, conf):
        self.conf = conf
        self._mapping = {}
        self._mapping = self._get_mapping()

    def _get_mapping(self):
        with open(self.conf.monasca.monasca_mappings, 'r') as f:
            try:
                return yaml.safe_load(f)
            except yaml.YAMLError as err:
                if hasattr(err, 'problem_mark'):
                    mark = err.problem_mark
                    errmsg = ("Invalid YAML syntax in Monasca Data "
                              "Filter file %(file)s at line: "
                              "%(line)s, column: %(column)s."
                              % dict(file=self.conf.monasca.monasca_mappings,
                                     line=mark.line + 1,
                                     column=mark.column + 1))
                else:
                    errmsg = ("YAML error reading Monasca Data Filter "
                              "file %(file)s" %
                              dict(file=self.conf.monasca.monasca_mappings))
                LOG.error(errmsg)
                raise UnableToLoadMappings(err.message)

    def _convert_timestamp(self, timestamp):
        if isinstance(timestamp, datetime.datetime):
            ts = timestamp
        else:
            ts = timeutils.parse_isotime(timestamp)
        tdelta = (ts - datetime.datetime(1970, 1, 1, tzinfo=ts.tzinfo))
        # convert timestamp to milli seconds as Monasca expects
        return int(tdelta.total_seconds() * 1000)

    def _convert_to_sample(self, s):
        return sample_util.Sample(
            name=s['counter_name'],
            type=s['counter_type'],
            unit=s['counter_unit'],
            volume=s['counter_volume'],
            user_id=s['user_id'],
            project_id=s['project_id'],
            resource_id=s['resource_id'],
            timestamp=s['timestamp'],
            resource_metadata=s['resource_metadata'],
            source=s.get('source')).as_dict()

    def get_value_for_nested_dictionary(self, lst, dct):
        val = dct
        for element in lst:
            if isinstance(val, dict) and element in val:
                val = val.get(element)
            else:
                return
        return val

    def parse_jsonpath(self, field):
        try:
            parts = self.JSONPATH_RW_PARSER.parse(field)
        except Exception as e:
            raise CeiloscaMappingDefinitionException(
                "Parse error in JSONPath specification "
                "'%(jsonpath)s': %(err)s"
                % dict(jsonpath=field, err=e))
        return parts

    def _get_value_metadata_for_key(self, sample_meta, meta_key):
        """Get the data for the given key, supporting JSONPath"""
        if isinstance(meta_key, dict):
            # extract key and jsonpath
            # If following convention, dict will have one and only one
            # element of the form <monasca key>: <json path>
            if len(meta_key.keys()) == 1:
                mon_key = list(meta_key.keys())[0]
            else:
                # If no keys or more keys than one
                raise CeiloscaMappingDefinitionException(
                    "Field definition format mismatch, should "
                    "have only one key:value pair. %(meta_key)s" %
                    {'meta_key': meta_key}, meta_key)
            json_path = meta_key[mon_key]
            parts = self.parse_jsonpath(json_path)
            val_matches = parts.find(sample_meta)
            if len(val_matches) > 0:
                # resolve the find to the first match and get value
                val = val_matches[0].value
                if not isinstance(val, (str, str)) \
                   and not isinstance(val, int):
                    # Don't support lists or dicts or ...
                    raise CeiloscaMappingDefinitionException(
                        "Metadata format mismatch, value "
                        "should be a simple string. %(valuev)s" %
                        {'valuev': val}, meta_key)
            else:
                val = 'None'
            return mon_key, val
        else:
            # simple string
            val = sample_meta.get(meta_key, None)
            if val is not None:
                return meta_key, val
            else:
                # one more attempt using a dotted notation
                # TODO(joadavis) Deprecate this . notation code
                # in favor of jsonpath
                if len(meta_key.split('.')) > 1:
                    val = self.get_value_for_nested_dictionary(
                        meta_key.split('.'), sample_meta)
                    if val is not None:
                        return meta_key, val
                    else:
                        return meta_key, 'None'
                else:
                    return meta_key, 'None'

    def process_sample_for_monasca(self, sample_obj):
        if not self._mapping:
            raise NoMappingsFound("Unable to process the sample")

        dimensions = {}
        dimensions['datasource'] = 'ceilometer'
        # control_plane, cluster and cloud_name can be None, but we use
        # literal 'None' for such case
        dimensions['control_plane'] = self.conf.monasca.control_plane or 'None'
        dimensions['cluster'] = self.conf.monasca.cluster or 'None'
        dimensions['cloud_name'] = self.conf.monasca.cloud_name or 'None'
        if isinstance(sample_obj, sample_util.Sample):
            sample = sample_obj.as_dict()
        elif isinstance(sample_obj, dict):
            if 'counter_name' in sample_obj:
                sample = self._convert_to_sample(sample_obj)
            else:
                sample = sample_obj

        for dim in self._mapping['dimensions']:
            val = sample.get(dim, None)
            if val:
                dimensions[dim] = val
            else:
                dimensions[dim] = 'None'

        sample_meta = sample.get('resource_metadata', None)
        value_meta = {}

        meter_name = sample.get('name') or sample.get('counter_name')
        if sample_meta:
            for meta_key in self._mapping['metadata']['common']:
                monasca_key, val = self._get_value_metadata_for_key(
                    sample_meta, meta_key)
                value_meta[monasca_key] = val

            if meter_name in self._mapping['metadata'].keys():
                for meta_key in self._mapping['metadata'][meter_name]:
                    monasca_key, val = self._get_value_metadata_for_key(
                        sample_meta, meta_key)
                    value_meta[monasca_key] = val

        meter_value = sample.get('volume') or sample.get('counter_volume')
        if meter_value is None:
            meter_value = 0

        metric = dict(
            name=meter_name,
            timestamp=self._convert_timestamp(sample['timestamp']),
            value=meter_value,
            dimensions=dimensions,
            value_meta=value_meta,
        )

        LOG.debug("Generated metric with name %(name)s,"
                  " timestamp %(timestamp)s, value %(value)s,"
                  " dimensions %(dimensions)s" %
                  {'name': metric['name'],
                   'timestamp': metric['timestamp'],
                   'value': metric['value'],
                   'dimensions': metric['dimensions']})

        return metric


text:
package org.apache.tinkerpop.gremlin.process.traversal.step.map;

import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;

import java.util.Collections;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public final class EdgeVertexStep extends FlatMapStep<Edge, Vertex> {

    private Direction direction;

    public EdgeVertexStep(final Traversal.Admin traversal, final Direction direction) {
        super(traversal);
        this.direction = direction;
    }

    @Override
    protected Iterator<Vertex> flatMap(final Traverser.Admin<Edge> traverser) {
        return traverser.get().vertices(this.direction);
    }

    @Override
    public String toString() {
        return StringFactory.stepString(this, this.direction);
    }

    @Override
    public int hashCode() {
        return super.hashCode() ^ this.direction.hashCode();
    }

    public Direction getDirection() {
        return this.direction;
    }

    public void reverseDirection() {
        this.direction = this.direction.opposite();
    }

    @Override
    public Set<TraverserRequirement> getRequirements() {
        return Collections.singleton(TraverserRequirement.OBJECT);
    }
}


text:
var arrLang = {

	'es' : {
		'contact' : 'Contactanos',
		'themes' : 'Variacion de Temas',
		'funds' : 'Fondos',
		'colors' : 'Colores',
		'persistent' : 'Esta seleccion no es persistente',
		'camr' : 'CENTRO DE ARTES MODERNAS RHYTHM',
		'areasegura' : 'Area Segura',
		'paginas' : 'Paginas',
		'acciones' : 'Acciones',
		'info' : 'Informacion Rhythm',
		'calendario' : 'Calendario',
		'galeria' : 'Galeria',
		'tiposdanza' : 'Tipos de danza',
		'bailes' : 'Bailes',
		'evento' : 'Eventos Especiales',
		'academia' : 'Centro de Artes Modernas Rhythm',
		'vida' : 'Le damos ritmo a tu vida.',
		'ladanza' : 'La danza es como una comunicación entre cuerpo y alma para expresar lo que esta demasiado profundo para encontrar palabras.',
		'pies' : 'Bailar es como soñar con tus pies!',
		'empezar' : 'Si no has comenzado a bailar aún, te recomiendo empezar ya. Para la salud mental es excelente. Por una parte el ejercicio físico es bueno para nuestra salud física y mental (disminuye estrés, depresión y ansiedad) y por otra parte, socializarás con otras personas, algo fundamental para la felicidad.',
		'pz' : 'Somos un Centro de Baile ubicada en San Isidro de Peréz Zeledón, San José Costa Rica. Impartimos lecciones de de baile popular,ballet, baile Coreográfico, danza Contemporanea, Ballroom, y mas.',
		'clases' : 'Algunas de nuestras clases',
		'bailar' : 'Para bailar no importa la edad, el sexo, la raza, la cultura, la religión, el idioma. No importa la profesión, ni los gustos intelectuales. No importa la ciudad, ni siquiera el momento histórico. Sólo importa una cosa: la conexión entre el bailador o los bailadores y su música.',
		'ballet' : 'Técnica de danza occidental que se originó en la época del Renacimiento.',
		'hiphop' : 'Derivación del funk y que se caracteriza por su base electrónica.',
		'latino' : 'Incluye danzas originarias de América Latina y del Caribe con sus ritmos.',
		'percucion' : 'Los bailarines tratan de mostrar una interacción física y emocional.',
		'lirica' : 'Forma de danza moderna que fusiona la danza contemporánea, jazz y balle.',
		'moderna' : 'Expresión corporal que nace de la interpretación y visión del coreógrafo.',
		'dancehall' : 'Tradicional género jamaiquina que se originó hacia finales de los años 1970.',
		'break' : 'Baile urbano que forma parte del movimiento de la cultura HIP HOP.',
		'coro' : 'Movimientos del cuerpo que coordinan con la melodía y el ritmo de una pieza musical.',
		'servicios' : 'Nuestros Principales Servicios',
		'grupo' : 'Clases por grupos / Diversos Ritmos',
		'grupos' : 'Contamos con clases por grupos de los diversos tipos de danzas en el Centro de Artes Modernas Rhythm en sus diferentes niveles y especialidades, todos con instuctores altamente calificados.',
		'personalizadas' : 'Clases personalizadas / Parejas o Individuales',
		'individual' : 'Se imparten clases personalizadas, para sus direffentes fines sociales o personales, nos ajustamos a su agenda y contamos con talentosos instructores para que sea una experiencia unica y de crecimiento personal.',
		'eventos' : 'Eventos Especiales / Bodas, Festejos, Quinceaños y mas',
		'bodas' : 'En Centro de Artes Modernas Rhythm ofrecemos preparacion para eventos principales, contamos con todo lo necesario para que su evento sea un acontecimineto unico y especial.',
		'animate' : '! Animate a Bailar con Centro de Artes Modernas Rhythm !',
		'admi' : 'Administrador',
		'pasion' : 'La pasion por la danza y el baile, es un sentimiento unico que quiero compartir con el resto del mundo !',
		'esperamos' : 'Te esperamos en Centro de Arte Modernas Rhythm',
		'enviar' : 'Enviar Mensaje',
                'quienes' : 'nuestra principal preocupacion es el bienestar fisico y mental de todos nuetros clientes y que lo vivas en su maxima expresion',
                'somos' : 'QUIENES SOMOS ..?',
                'parte' : 'HAZ QUE BAILAR SEA PARTE DE TI',
                'valores' : 'NUESTROS VALORES',
                'mision' : 'es arte, pasión, crecimiento, movimiento y vida. Promovemos y buscamos desarrollar en las personas su estado físico, psicológico y dancístico por medio de la interpretación y expresión musical. Brindamos un espacio recreativo sano que promueve valores y conocimientos históricos de los diversos géneros de la danza. Estamos enfocados en llegar a toda persona interesada en aprender sin importar su edad y género para que convivan en un espacio donde se pueda apreciar, bailar y compartir los diversos géneros de danza en armonía, convivencia y amistad.',
                'vision' : 'busca colocarse como el mejor centro de artes de Costa Rica, Centroamérica y el mundo. Deseamos formar nuevas generaciones de grupos y parejas de baile profesionales que puedan destacar a nivel nacional e internacional representando algun tipo de baile en Costa Rica como una de las mejores del mundo. Así mismo deseamos promover y educar a la gente sobre la cultura del baile para que muchas generaciones más puedan seguir el legado del baile.'
	},

	'en' : {
		'contact': 'Contact Us',
		'themes': 'Theme Variation',
		'funds': 'Funds',
		'colors': 'Colors',
		'persistent': 'This selection is not persistent',
		'camr' : 'MODERN ARTS CENTER RHYTHM',
		'areasegura' : 'Login',
		'paginas' : 'Pages',
		'acciones' : 'Actions',
		'info' : 'Rhythm Information',
		'calendario' : 'Calendar',
		'galeria' : 'Gallery',
		'tiposdanza' : 'Types of dance',
		'bailes' : 'Dances',
		'evento' : 'Special Events',
		'academia' : 'Academy of Modern Arts',
		'vida' : 'The rhythm we give to your life',
		'ladanza' : 'Dance is like a communication between body and soul to express what is too deep to find words.',
		'pies' : 'Dancing is like dreaming of your feet!',
		'empezar' : 'If you have not started a dance yet, I recommend you start now. For mental health is excellent. On the one hand, physical exercise is good for our physical and mental health (decreases stress, depression and anxiety) and on the other hand, socialize with other people, something fundamental to happiness.',
		'pz' : 'We are a dance academy located in San Isidro de Peréz Zeledón, San José Costa Rica. We teach lessons in popular dance, ballet, choreographic dance, contemporary dance, ballroom, and more.',
		'clases' : 'Some of our classes',
		'bailar' : 'For dancing no matter the age, sex, race, culture, religion, language. It does not matter the profession, nor the intellectual tastes. No matter the city, not even the historical moment. Only one thing matters: the connection between the dancers and the dancers and the music.',
		'ballet' : 'Western dance technique that originated in the Renaissance period',
		'hiphop' : 'Derivation of funk and characterized by its electronic base.',
		'latino' : 'It includes dances originating from Latin America and the Caribbean with their rhythms.',
		'percucion' : 'The dancers try to show a physical and emotional interaction.',
		'lirica' : 'Modern dance form that fuses contemporary dance, jazz and balle.',
		'moderna' : 'Body expression that is born of the choreographer is interpretation and vision.',
		'dancehall' : 'Traditional Jamaican genre that originated towards the end of the 1970s.',
		'break' : 'Urban dance that is part of the HIP HOP culture movement.',
		'coro' : 'Body movements that coordinate with the melody and rhythm of a piece of music.',
		'servicios' : 'Our Main Services',
		'grupo' : 'Classes by groups / Various rhythms',
		'grupos' : 'We have classes by groups of the various types of dances of the Academy of Modern Art, All rhythms in their different levels and specialties, all with highly qualified instuctores',
		'personalizadas' : 'Custom Classes / Couples or Individuals',
		'individual' : 'We offer personalized classes, for your direct social or personal fines, our adjustments to your agenda and we have talents instructors to make a unique experience and personal growth.',
		'eventos' : 'Special Events / Weddings, Celebrations, Quinceasia and more',
		'bodas' : 'The Academy of Modern Arts Rhythm of the preparations for the main events, we have everything you need to make your event a unique and special event.',
		'animate' : 'Animate to Dance with Academy of Modern Arts Rhythm',
		'admi' : 'Administrator',
		'pasion' : 'The passion for dance and dancing is a unique feeling that I want to share with the rest of the world!',
		'esperamos' : 'Well be waiting for you at Rhythm Modern Art Academy',
		'enviar' : 'Send Message',
                'quienes' : 'our main concern is the physical and mental well-being of all our clients and that they live it at their maximum expression',
                'somos' : 'ABOUT US ..?',
                'parte' : 'MAKE DANCE A PART OF YOU',
                'valores' : 'OUR VALUES',
                'mision' : 'It is art, passion, growth, movement and life. We promote and seek to develop in people their physical, psychological and dance through the interpretation and musical expression. We offer a healthy recreational space that promotes values and historical knowledge of the different genres of dance. We are focused on reaching all people interested in learning regardless of their age and gender so that they can live in a space where they can appreciate, dance and share the different dance genres in harmony, coexistence and friendship.',
                'vision' : 'seeks to position itself as the best academy in Costa Rica, Central America and the world. We want to form new generations of professional dance groups and couples that can stand out nationally and internationally representing some kind of dance in Costa Rica as one of the best in the world. We also want to promote and educate people about the dance culture so that many more generations can follow the dance legacy.'

	}

};

var select = "off";
var lang;
$(function(){
	$('#toggle').click(function(){
		//var lang = $(this).attr('id');
		if(select == "off"){
			$("#toggle").html(' English');
			select = "on";  lang = "en";
		}
		else{
			$("#toggle").html(' English');
			select = "off";  lang = "es";
		}

		$('.lang').each(function(index, element){
			$(this).text(arrLang[lang][$(this).attr('key')]);
		});
	});
});


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
null

#### Original name
Eurotium vitis Novobr., 1972

### Remarks
null


text:
/**
 * @author Boom.Lee <boom11235.gg@gmail.com>
 * Idea from: http://www.2ality.com/2015/03/no-promises.html
 */

/**
 * Check if a generator object
 *
 * @param {Object} obj
 * @returns {Boolean}
 */
function _isGenerator (obj) {
  return typeof obj.next === 'function' && typeof obj.throw === 'function'
}

/**
 * Run generator object to make up async control-flow
 * Get result via the callbacks
 *
 * @param {Generator} gen
 * @param {Object} callbacks
 * @param {Function} callbacks.success Handle async success.
 * @param {Function} callbacks.fail
 * @returns
 */
function runGenObj(gen, callbacks) {
  handleNext()

  /**
   * Handle the generator.next, mainly check if done or error.
   *
   * @param {Mixed} prev Last iteration's result.
   */
  function handleNext(prev) {
    try {
      var yielded = gen.next(prev)

      if (yielded.done) {
        if (yielded.value !== undefined) {
          callbacks.success(yielded.value)
        }
      } else {
        runYielded(yielded.value)
      }
    } catch (err) {
      if (callbacks) {
        callbacks.fail(err)
      } else {
        throw err
      }
    }
  }

  /**
   * Handle yielded value.
   * To return noraml, handle array in parallel, or call `runGenObj` to handle generator.
   *
   * @param {Mixed} value From last `next()`.
   */
  function runYielded(value) {
    if (value === undefined) {
      handleNext(callbacks)
    } else if (Array.isArray(value)) {
      runInParallel(value)
    } else if (_isGenerator(value)){
      runGenObj(value, {
        success: function (re) {
          handleNext(re)
        },
        fail: function (err) {
          gen.throw(err)
        }
      })
    } else {
      handleNext(value)
    }
  }

  /**
   * Handle array in parallel.
   * Diff generator and normal value. Count to call `handleNext`
   *
   * @param {Array} array
   */
  function runInParallel(array) {
    var len = array.length
    var count = len
    var results = new Array(len)

    // Make function out of loop.
    function _runGen(index) {
      var value = array[index]
      if (_isGenerator(value)) {
        runGenObj(value, {
          success: function (result) {
            results[index] = result
            count--
            if (count <= 0) {
              handleNext(results)
            }
          },
          fail: function (err) {
            gen.throw(err)
          }
        })
      } else {
        results[index] = value
        count--
        if (count <= 0) {
          handleNext(results)
        }
      }
    }

    for (var i = 0; i < len; i++) {
      _runGen(i)
    }
  }
}

/**
 * Just exports like co/Q.spawn, to run the generatorFunction.
 *
 * @param {GeneratorFunction} genFunc
 * @param {Object}
 * @param {Function} callbacks.success
 * @param {Function} callbacks.fail
 */
function run(genFunc, callbacks) {
  runGenObj(genFunc(), callbacks)
}

var context = this

/**
 * Wrap generator function to pass arguments.
 *
 * @param {GeneratorFunction} genFunc
 * @param {Object}
 * @param {Function} callbacks.success
 * @param {Function} callbacks.fail
 * @returns {Function} Used to pass arguments.
 */
run.wrap = function wrap(genFunc, callbacks) {
  return function () {
    runGenObj(genFunc.call(context, arguments), callbacks)
  }
}

/**
 * Transform async function to yieldable generator function.
 * Just for callback(error, data ...), others may throw error.
 *
 * @param {Function} func
 * @returns {GeneratorFunction}
 */
run.yield = function (func, ctx) {
  return function *() {
    var args = [].slice.call(arguments, 0)
    var caller = yield undefined

    args.push(function (error) {
      if (error) {
        caller.fail(error)
      } else {
        caller.success.apply(caller, [].slice.call(arguments, 1))
      }
    })

    func.apply(ctx || context, args)
  }
}

module.exports = run


text:
<?php declare(strict_types=1);

namespace Rollbar\Payload;

use Rollbar\LevelFactory;
use Rollbar\SerializerInterface;

class Level implements SerializerInterface
{
    /**
     * Those are PSR-3 compatible loggin levels. They are mapped to Rollbar
     * service supported levels in Level::init()
     */
    const EMERGENCY = 'emergency';
    const ALERT = 'alert';
    const CRITICAL = 'critical';
    const ERROR = 'error';
    const WARNING = 'warning';
    const NOTICE = 'notice';
    const INFO = 'info';
    const DEBUG = 'debug';

    /**
     * @deprecated 1.2.0
     */
    const IGNORED = 'ignored';
    /**
     * @deprecated 1.2.0
     */
    const IGNORE = 'ignore';

    /**
     * @deprecated 1.2.0
     *
     * Usage of Level::error(), Level::warning(), Level::info(), Level::notice(),
     * Level::debug() is no longer supported. It has been replaced with matching
     * class constants, i.e.: Level::ERROR
     */
    public static function __callStatic($name, $args)
    {
        $factory = new LevelFactory();
        $level = $factory->fromName($name);

        if (!$level) {
            throw new \Exception("Level '$level' doesn't exist.");
        }

        return $level;
    }

    public function __construct(
        private string $level,
        private int $val
    ) {
    }

    public function __toString()
    {
        return $this->level;
    }

    public function toInt(): int
    {
        return $this->val;
    }

    public function serialize()
    {
        return $this->level;
    }
}


text:
<?php

namespace Gitcolab\Bundle\AppBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Gitcolab\Bundle\AppBundle\Model\Organization;

class LoadOrganizationData
{
    /**
     * {@inheritdoc}
     */
    public function load(ObjectManager $manager)
    {
        $organization = (new Organization())
            ->setName('Foo')
            ->getEmail('foo@foo.io');

        $manager->persist($organization);

        $organization = (new Organization())
            ->setName('Bar')
            ->getEmail('bar@bar.io');

        $organization = (new Organization())
            ->setName('FooBar')
            ->getEmail('foobar@foobar.io');

        $manager->flush();
    }

    /**
     * {@inheritDoc}
     */
    public function getOrder()
    {
        return 30;
    }
}


text:
{// 引入标签库 }
<tagLib name="html" />
<include file="Public:header" />

{$main_title}

	<input type="button" class="button" value="{%ADD}" onclick="add();" />
	<input type="button" class="button" value="{%FOREVERDEL}" onclick="foreverdel();" />

{$page}

<include file="Public:footer" />


text:
package org.eshow.demo.model;

import android.support.annotation.NonNull;

/**
 * Created by Administrator on 2018-6-8 0008.
 */

public class DirModel implements Comparable<DirModel> {

    public String name;
    public String path;

    @Override
    public int compareTo(@NonNull DirModel o) {
        return name.compareToIgnoreCase(o.name);
    }
}


text:
from babel import Locale, UnknownLocaleError

__LOCALE_SEP_SCRIPT__ = '-'
__LOCALE_SEP_REGION__ = '_'

_cached_locale_ = {}

def get_locale(locale_code):
    locale = None

    try:
        locale = Locale.parse(locale_code)
    except (UnknownLocaleError, ValueError) as e:
        try:
            locale = Locale.parse(locale_code, sep='-')
        except (UnknownLocaleError, ValueError) as e:
            pass

    if locale_code in _cached_locale_:
        locale = _cached_locale_[locale_code]

    if locale:
        _cached_locale_[locale_code] = locale

    return locale

def lang(locale_code):
    l = get_locale(locale_code)
    return l.language if l else None

def is_equal_lang(locale1, locale2):
    l1, l2 = lang(locale1), lang(locale2)
    return (l1 and l2) and l1 == l2

def region(locale_code):
    l = get_locale(locale_code)
    return l.territory if l else None

def is_equal_region(locale1, locale2):
    r1, r2 = region(locale1), region(locale2)
    return (r1 and r2) and r1 == r2

def script(locale_code):
    l = get_locale(locale_code)
    return l.script if l else None

def is_equal_script(locale1, locale2):
    s1, s2 = script(locale1), script(locale2)
    return (s1 and s2) and s1 == s2

def is_equal_lang_and_script(locale1, locale2):
    return is_equal_lang(locale1, locale2) and is_equal_script(locale1, locale2)

def matched_locale_code(code, for_codes):

    if code in for_codes:
        return code
    else:
        lang_matched_codes = filter(lambda l: is_equal_lang(code, l), for_codes)

        # fallback by only lang code
        if not lang_matched_codes:
            if __LOCALE_SEP_SCRIPT__ in code:
                return matched_locale_code(code.split(__LOCALE_SEP_SCRIPT__)[0], for_codes)
            elif __LOCALE_SEP_REGION__ in code:
                return matched_locale_code(code.split(__LOCALE_SEP_REGION__)[0], for_codes)
        # found unique one
        elif len(lang_matched_codes) == 1:
            return lang_matched_codes[0]
        # found several aliases
        elif len(lang_matched_codes) > 1:
            script_matched_codes = filter(lambda l: is_equal_script(code, l), lang_matched_codes)
            region_matched_codes = filter(lambda l: is_equal_region(code, l), lang_matched_codes)

            primary_matched_codes = script_matched_codes or region_matched_codes
            intersacted_codes = list(set(script_matched_codes) & set(region_matched_codes))

            # phase 1 - intersacted
            if intersacted_codes:
                return intersacted_codes[0]
            # phase 2 - match by primary matched
            elif primary_matched_codes:
                return primary_matched_codes[0]
            # phase 3 - forcefully return with first lang
            else:
                return lang_matched_codes[0]

    return None

def intersacted_locale_codes(codes, for_codes):
    alt_matched_codes = []
    for c in list(set(codes) - set(for_codes)):
        matched_code = matched_locale_code(c, for_codes)
        if matched_code:
            alt_matched_codes.append(matched_locale_code(c, for_codes))
    return list((set(for_codes) - set(codes)) | set(alt_matched_codes))

def map_locale_codes(matching_codes, for_codes):
    mapped = {}
    for c in matching_codes:
        m = matched_locale_code(c, for_codes)
        if m:
            mapped[c] = m
    return mapped

# Language Support for the Neural Machine Translation Model: https://cloud.google.com/translate/docs/languages
def default_supporting_xcode_lang_codes():
    return [
        'ko',
        'el',
        'vi',
        'ca',
        'it',
        'zh-HK',
        'ar',
        'cs',
        'id',
        'es',
        'ru',
        'nl',
        'pt',
        'nb',
        'tr',
        'th',
        'ro',
        'pl',
        'fr',
        'uk',
        'hr',
        'de',
        'hu',
        'hi',
        'fi',
        'da',
        'ja',
        'he',
        'zh-Hans',
        'zh-Hant',
        'sv',
        'sk',
        'ms'
    ]

def secondary_supporting_xcode_lang_codes():
    return [
        'hy', 'az', 'gu', 'co', 'af', 'sw', 'is', 'am', 'eo', 'ne', 'st', 'cy', 'gd', 'km', 'ga', 'zu', 'eu',
        'et', 'xh',
        'gl', 'ig', 'ps', 'sr', 'lb', 'lo', 'tl', 'lv', 'ny', 'lt', 'pa', 'tg', 'te', 'ta', 'yi', 'bg', 'sm', 'yo',
        'sl', 'fy', 'bn', 'jw', 'ka', 'ht', 'fa', 'bs', 'ha', 'mg', 'uz', 'kk', 'ml', 'sq', 'mn', 'mi', 'kn', 'mk',
        'ur', 'mt', 'si', 'so', 'sn', 'ku', 'mr', 'sd'
    ]


text:
#include <QDebug>

#include <QGraphicsSceneMouseEvent>

#include <MLabel>

#include <MLayout>
#include <MLinearLayoutPolicy>

#include "seasidelabel.h"

class SeasideLabelPriv
{
public:
    MLabel *label;
    bool mouseEnabled;
};

SeasideLabel::SeasideLabel(const QString &text, QGraphicsItem *parent):
    MStylableWidget(parent)
{
    priv = new SeasideLabelPriv;
    priv->mouseEnabled = false;

    MLayout *layout = new MLayout(this);
    MLinearLayoutPolicy *policy = new MLinearLayoutPolicy(layout, Qt::Horizontal);

    priv->label = new MLabel(text);
    priv->label->setTextElide(true);
    policy->addItem(priv->label, Qt::AlignLeft);
}

SeasideLabel::~SeasideLabel()
{
    delete priv;
}

void SeasideLabel::setMouseEnabled(bool enable)
{
    priv->mouseEnabled = enable;
}

bool SeasideLabel::isMouseEnabled()
{
    return priv->mouseEnabled;
}

void SeasideLabel::setText(const QString &text)
{
    if(priv->label)
     priv->label->setText(text);
}

void SeasideLabel::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
    if (!priv->mouseEnabled)
        MStylableWidget::mousePressEvent(event);
    else
        priv->label->setColor(style()->pressedColor());
}

void SeasideLabel::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);
    if (!priv->mouseEnabled)
        MStylableWidget::mousePressEvent(event);
    else {
        priv->label->setColor(style()->color());
        if (sceneBoundingRect().contains(event->scenePos()))
            emit clicked(this);
    }
}

void SeasideLabel::cancelEvent(MCancelEvent *event)
{
    if (!priv->mouseEnabled)
        MStylableWidget::cancelEvent(event);
    else
        priv->label->setColor(style()->color());
}

static int getFontWeight(const QString& weight)
{
    int rval = QFont::Normal;
    if (weight == "bold")
        rval = QFont::Bold;
    else if (weight == "bolder")
        rval = QFont::Black;
    else if (weight == "lighter")
        rval = QFont::Light;
    return rval;
}

static Qt::Alignment getAlignment(const QString& textAlign, const QString& vertAlign)
{
    Qt::Alignment align = 0;
    if (textAlign == "left")
        align |= Qt::AlignLeft;
    else if (textAlign == "right")
        align |= Qt::AlignRight;
    else if (textAlign == "center")
        align |= Qt::AlignCenter;
    else if (textAlign == "justify")
        align |= Qt::AlignJustify;
    if (vertAlign == "top")
        align |= Qt::AlignTop;
    else if (vertAlign == "middle" || vertAlign == "center")
        align |= Qt::AlignVCenter;
    else if (vertAlign == "bottom")
        align |= Qt::AlignBottom;
    return align;
}

void SeasideLabel::applyStyle()
{
    priv->label->setColor(style()->color());

    QFont font = style()->font();
    font.setWeight(getFontWeight(style()->fontWeight()));
    priv->label->setFont(font);

    priv->label->setAlignment(getAlignment(style()->textAlign(), style()->verticalAlign()));
}


text:
/**
 * @ngdoc service
 * @name Customisation.Action-driven
 * @description

 # Action-driven framework
 */


text:
using System.IO;
using Codestellation.Galaxy.WebEnd.TagBuilder.Attributes;

namespace Codestellation.Galaxy.WebEnd.TagBuilder
{
    public class OptionTag : Tag
    {
        private bool _isSelected;

        public OptionTag()
            : base("option")
	    {
	    }

        public OptionTag Selected(bool isSelected)
        {
            _isSelected = isSelected;
            return this;
        }

        protected override void WriteAttributes(TextWriter writer)
        {
            if (_isSelected)
            {
                SetAttribute(HtmlAttribute.Selected);
            }

            base.WriteAttributes(writer);
        }

        public OptionTag Disabled()
        {
            SetAttribute(HtmlAttribute.Disabled);
            return this;
        }
    }
}


text:
JARS.internal('Strategies/Resolution/Absolute', function(getInternal) {
    'use strict';

    var VersionResolutionStrategy = getInternal('Strategies/Resolution/Version'),
        RelativeResolver = getInternal('Resolvers/Relative'),
        MSG_ABSOLUTE_RESOLUTION_ERROR = 'a module can not be resolved beyond the root';

    /**
     * @memberof JARS~internals.Strategies.Resolution
     *
     * @param {JARS~internals.Subjects.Module} baseModule
     * @param {string} moduleName
     *
     * @return {string}
     */
    function Absolute(baseModule, moduleName) {
        return (baseModule.isRoot || RelativeResolver(moduleName)) ? {
            error: MSG_ABSOLUTE_RESOLUTION_ERROR
        } : VersionResolutionStrategy(baseModule, moduleName);
    }

    return Absolute;
});


text: package sandbox


text:
package phone

import (
	"fmt"
	"regexp"
	"strings"
)

const (
	PLUS_SIGN_REGEX       = `(?i)^\+`
	NON_DIGIT_CHAR        = `(?i)\D`
	ZERO_DIGIT_CHARS      = `^0+`
	EIGHT_DIGIT_CHARS     = `^8+`
	RUS_START_DIGIT_CHARS = `^89`
)

var (
	NON_LEADING_ZERO_COUNTRIES = []string{"GAB", "CIV", "COG"}

	ErrNotFound  = fmt.Errorf("No valid format found.")
	ErrPhoneMiss = fmt.Errorf("Unable to locate data from phone number.")
)

func Normalise(p, c string) (*PhoneResult, error) {
	var (
		phone   string
		country string
		err     error
	)

	hasPlusSign := containsPlusSign(p)

	phone, err = normalisePhoneNumber(p)
	if err != nil {
		return nil, err
	}

	country, err = normaliseCountry(c)
	if err != nil {
		return nil, err
	}

	// if no country, default is USA
	var iso3166 *PhoneData
	if country != "" {
		iso3166 = GetISO3166(country)
	}

	var result *Result
	if iso3166 != nil {
		result, err = normaliseWithCountry(phone, iso3166, hasPlusSign)
	} else {
		result, err = normaliseWithoutCountry(phone, hasPlusSign)
	}

	if err != nil {
		return nil, err
	}

	if result.PhoneData == nil {
		return nil, ErrPhoneMiss
	}

	if IsValidPhoneISO3166(result.PhoneNumber, result.PhoneData) {
		return result.WithPlusSign().AsPhoneResult(), nil
	}

	return result.AsPhoneResult(), ErrNotFound
}

func normalisePhoneNumber(phone string) (string, error) {
	reg, err := regexp.Compile(NON_DIGIT_CHAR)
	if err != nil {
		return "", err
	}
	return reg.ReplaceAllString(strings.TrimSpace(phone), ""), nil
}

func normaliseCountry(country string) (string, error) {
	return strings.ToUpper(strings.TrimSpace(country)), nil
}

func containsPlusSign(phone string) bool {
	if matched, err := regexp.MatchString(PLUS_SIGN_REGEX, phone); err == nil {
		return matched
	}
	return false
}

func containsString(haystack []string, needle string) bool {
	for _, v := range haystack {
		if v == needle {
			return true
		}
	}
	return false
}

func containsInt(haystack []int, needle int) bool {
	for _, v := range haystack {
		if v == needle {
			return true
		}
	}
	return false
}

func removeZeros(phone string) (string, error) {
	reg, err := regexp.Compile(ZERO_DIGIT_CHARS)
	if err != nil {
		return "", err
	}
	return reg.ReplaceAllString(phone, ""), nil
}

func isRussianPhoneNum(phone, country string) bool {
	if country == "RUS" && len(phone) == 11 {
		if matched, err := regexp.MatchString(RUS_START_DIGIT_CHARS, phone); err == nil {
			return matched
		}
		return false
	}
	return false
}

func cleanRussianPhoneNum(phone string) (string, error) {
	reg, err := regexp.Compile(EIGHT_DIGIT_CHARS)
	if err != nil {
		return "", err
	}
	return reg.ReplaceAllString(phone, ""), nil
}

func normaliseWithCountry(phone string, data *PhoneData, hasPlusSign bool) (*Result, error) {
	var err error
	if !containsString(NON_LEADING_ZERO_COUNTRIES, data.CountryData.Alpha3) {
		if phone, err = removeZeros(phone); err != nil {
			return nil, err
		}
	}

	if isRussianPhoneNum(phone, data.CountryData.Alpha3) {
		if phone, err = cleanRussianPhoneNum(phone); err != nil {
			return nil, err
		}
	}

	if !hasPlusSign {
		lenOfPhoneNum := len(phone)
		if containsInt(data.PhoneNumberLengths, lenOfPhoneNum) {
			phone = fmt.Sprintf("%s%s", data.CountryData.CountryCode, phone)
		}
	}

	return NewResult(phone, data), nil
}

func normaliseWithoutCountry(phone string, hasPlusSign bool) (*Result, error) {
	// Let's try and brute force it anyway
	if possible, err := GetISO3166ByPhone(phone); err == nil && possible != nil {
		return NewResult(phone, possible), nil
	}

	if hasPlusSign {
		return nil, ErrPhoneMiss
	}

	// We really have no idea what this phone number is!
	var (
		data          = GetDefaultISO3166()
		lenOfPhoneNum = len(phone)
	)
	if containsInt(data.PhoneNumberLengths, lenOfPhoneNum) {
		phone = fmt.Sprintf("1%s", phone)
	}

	return NewResult(phone, data), nil
}


text:
package com.giyeok.jparser.metalang3a.codegen

import com.giyeok.jparser.Inputs.CharsGrouping
import com.giyeok.jparser.NGrammar.{NNonterminal, NStart}
import com.giyeok.jparser.metalang3a.MetaLanguage3.{ProcessedGrammar, check}
import com.giyeok.jparser.metalang3a.codegen.ScalaCodeGen.{CodeBlob, ExprBlob, Options}
import com.giyeok.jparser.metalang3a.{ClassHierarchyItem, ClassRelationCollector, Type, ValuefyExpr}
import com.giyeok.jparser.proto.GrammarProtobufConverter
import com.giyeok.jparser.utils.JavaCodeGenUtil.javaChar
import com.giyeok.jparser.{NGrammar, Symbols}

import java.util.Base64
import scala.annotation.tailrec

object ScalaCodeGen {

  /**
   *
   * @param useNull                 (미구현) true이면 Option 대신 그냥 값+null을 사용한다.
   * @param looseSuperType          TODO 기본 false
   * @param assertBindTypes         Unbind할 때 unbind된 심볼의 타입을 체크한다. 기본 true
   * @param symbolComments          human readable한 심볼 설명 코멘트를 추가한다. 기본 true
   * @param withParseNodesInClasses 모든 클래스를 WithParseNode trait를 상속받게 하고 모든 클래스를 생성할 때 parseNode를 설정한다. 기본 true
   */
  case class Options(useNull: Boolean = false,
                     looseSuperType: Boolean = false,
                     assertBindTypes: Boolean = true,
                     symbolComments: Boolean = true,
                     withParseNodesInClasses: Boolean = true,
                     grammarDefType: GrammarDefType = InlineSourceDef)

  sealed trait GrammarDefType

  object InlineSourceDef extends GrammarDefType

  object InlineProtoDef extends GrammarDefType

  case class FileProtoDef(filePath: String) extends GrammarDefType

  case class CodeBlob(code: String, required: Set[String]) {
    def indent(width: Int = 2): CodeBlob =
      copy(code.linesIterator.toList.map(line => (" " * width) + line).mkString("\n"))

    def +(other: CodeBlob): CodeBlob = CodeBlob(code + "\n" + other.code, required ++ other.required)

    def wrap(pre: CodeBlob, post: CodeBlob, requiredImports: Set[String]): CodeBlob =
      CodeBlob(pre.code + "\n" + indent().code + "\n" + post.code,
        requiredImports ++ pre.required ++ post.required)

    def wrap(pre: String, post: String): CodeBlob = copy(pre + "\n" + indent().code + "\n" + post)

    def wrapBrace(): CodeBlob = wrap(CodeBlob("{", Set()), CodeBlob("}", Set()), Set())
  }

  case class ExprBlob(prepares: List[String], result: String, required: Set[String]) {
    def withBraceIfNeeded: String =
      if (prepares.isEmpty) result else "{\n" + prepares.map("  " + _).mkString("\n") + "\n}"
  }

  object ExprBlob {
    def code(code: String) = ExprBlob(List(), code, Set())
  }

}

class ScalaCodeGen(val analysis: ProcessedGrammar, val options: Options = Options()) {
  def escapeString(str: String): String = "\"" + str.toCharArray.map(javaChar).mkString("") + "\""

  def escapeChar(c: Char): String = s"'${javaChar(c)}'"

  def ngrammarDef(ngrammar: NGrammar): CodeBlob = {
    def symbolString(symbol: Symbols.Symbol): String = symbol match {
      case Symbols.Nonterminal(name) => s"Symbols.Nonterminal(${escapeString(name)})"
      case Symbols.OneOf(syms) => s"Symbols.OneOf(ListSet(${syms map symbolString mkString ","}))"
      case Symbols.Repeat(sym, lower) => s"Symbols.Repeat(${symbolString(sym)}, $lower)"
      case Symbols.Except(sym, except) => s"Symbols.Except(${symbolString(sym)}, ${symbolString(except)})"
      case Symbols.LookaheadIs(sym) => s"Symbols.LookaheadIs(${symbolString(sym)})"
      case Symbols.LookaheadExcept(sym) => s"Symbols.LookaheadExcept(${symbolString(sym)})"
      case Symbols.Proxy(sym) => s"Symbols.Proxy(${symbolString(sym)})"
      case Symbols.Join(sym, join) => s"Symbols.Join(${symbolString(sym)}, ${symbolString(join)})"
      case Symbols.Longest(sym) => s"Symbols.Longest(${symbolString(sym)})"
      case Symbols.ExactChar(c) => s"Symbols.ExactChar(${escapeChar(c)})"
      case Symbols.Any => "Symbols.Any"
      case Symbols.AnyChar => "Symbols.AnyChar"
      case Symbols.Chars(chars) =>
        val groups = chars.groups
        val (singles, doubles) = groups partition { g => g._1 == g._2 }
        val singlesString = if (singles.isEmpty) None else {
          Some(s"Set(${singles map (_._1) map escapeChar mkString ","})")
        }
        val doublesString = if (doubles.isEmpty) None else {
          val g = doubles map { g => s"(${escapeChar(g._1)} to ${escapeChar(g._2)}).toSet" }
          Some(g mkString " ++ ")
        }
        s"Symbols.Chars(${List(singlesString, doublesString).flatten mkString " ++ "})"
      case Symbols.Sequence(seq) => s"Symbols.Sequence(Seq(${seq map symbolString mkString ","}))"
    }

    def intSetString(s: Set[Int]) = s"Set(${s mkString ","})"

    def intSeqString(s: Seq[Int]) = s"Seq(${s mkString ","})"

    def nAtomicSymbolString(nsymbol: NGrammar.NAtomicSymbol): String = nsymbol match {
      case NGrammar.NTerminal(id, symbol) =>
        s"NGrammar.NTerminal($id, ${symbolString(symbol)})"
      case NGrammar.NStart(id, produce) =>
        s"NGrammar.NStart($id, $produce)"
      case NGrammar.NNonterminal(id, symbol, produces) =>
        s"NGrammar.NNonterminal($id, ${symbolString(symbol)}, ${intSetString(produces)})"
      case NGrammar.NOneOf(id, symbol, produces) =>
        s"NGrammar.NOneOf($id, ${symbolString(symbol)}, ${intSetString(produces)})"
      case NGrammar.NProxy(id, symbol, produce) =>
        s"NGrammar.NProxy($id, ${symbolString(symbol)}, $produce)"
      case NGrammar.NRepeat(id, symbol, baseSeq, repeatSeq) =>
        s"NGrammar.NRepeat($id, ${symbolString(symbol)}, $baseSeq, $repeatSeq)"
      case NGrammar.NExcept(id, symbol, body, except) =>
        s"NGrammar.NExcept($id, ${symbolString(symbol)}, $body, $except)"
      case NGrammar.NJoin(id, symbol, body, join) =>
        s"NGrammar.NJoin($id, ${symbolString(symbol)}, $body, $join)"
      case NGrammar.NLongest(id, symbol, body) =>
        s"NGrammar.NLongest($id, ${symbolString(symbol)}, $body)"
      case NGrammar.NLookaheadIs(id, symbol, emptySeqId, lookahead) =>
        s"NGrammar.NLookaheadIs($id, ${symbolString(symbol)}, $emptySeqId, $lookahead)"
      case NGrammar.NLookaheadExcept(id, symbol, emptySeqId, lookahead) =>
        s"NGrammar.NLookaheadExcept($id, ${symbolString(symbol)}, $emptySeqId, $lookahead)"
    }

    def nSequenceString(nseq: NGrammar.NSequence): String =
      s"NGrammar.NSequence(${nseq.id}, ${symbolString(nseq.symbol)}, ${intSeqString(nseq.sequence)})"

    val nsymbolsString = ngrammar.nsymbols.toList.sortBy(_._1) flatMap { s =>
      List( // s"// ${s._2.symbol.toShortString}",
        s"${s._1} -> ${nAtomicSymbolString(s._2)}")
    }
    val nseqsString = ngrammar.nsequences.toList.sortBy(_._1) flatMap { s =>
      List( // s"// ${s._2.symbol.toShortString}",
        s"${s._1} -> ${nSequenceString(s._2)}")
    }
    CodeBlob(
      s"""new NGrammar(
         |  Map(${nsymbolsString mkString ",\n"}),
         |  Map(${nseqsString mkString ",\n"}),
         |  ${ngrammar.startSymbol})""".stripMargin,
      Set("scala.collection.immutable.ListSet",
        "com.giyeok.jparser.NGrammar",
        "com.giyeok.jparser.Symbols",
        "com.giyeok.jparser.ParsingErrors",
        "com.giyeok.jparser.nparser.Parser",
        "com.giyeok.jparser.nparser.NaiveParser"))
  }

  def classDefs(classRelation: ClassRelationCollector): CodeBlob = {
    val classHierarchy = classRelation.toHierarchy
    val baseCodeBlob = if (!options.withParseNodesInClasses) CodeBlob("", Set())
    else CodeBlob("sealed trait WithParseNode { val parseNode: Node }", Set())
    if (classHierarchy.allTypes.isEmpty) baseCodeBlob else {
      def classDefinitionCode(cls: ClassHierarchyItem): CodeBlob = {
        val supers = if (cls.superclasses.isEmpty) {
          if (options.withParseNodesInClasses) " extends WithParseNode" else ""
        } else {
          val superclasses = if (options.withParseNodesInClasses) cls.superclasses.toList.sorted :+ "WithParseNode"
          else cls.superclasses.toList.sorted
          s" extends ${superclasses.mkString(" with ")}"
        }
        if (cls.subclasses.isEmpty) {
          // concrete type
          val params = analysis.classParamTypes.getOrElse(cls.className, List()).map { param =>
            val paramType = typeDescStringOf(param._2, context = Some(s"parameter type of ${cls.className}.${param._1}"))
            CodeBlob(s"${param._1}: ${paramType.code}", paramType.required)
          }
          val parseNodeVal = if (options.withParseNodesInClasses) "(override val parseNode: Node)" else ""
          CodeBlob(s"case class ${cls.className}(${params.map(_.code).mkString(", ")})$parseNodeVal$supers",
            params.flatMap(_.required).toSet)
        } else {
          // abstract type
          CodeBlob(s"sealed trait ${cls.className}$supers", Set())
        }
      }

      (baseCodeBlob +: classHierarchy.allTypes.values.toList.sorted.map(classDefinitionCode)).reduce(_ + _)
    }
  }

  def typeDescStringOf(typ: Type, context: Option[String] = None): CodeBlob = typ match {
    case Type.NodeType => CodeBlob("Node", Set("com.giyeok.jparser.ParseResultTree.Node"))
    case Type.ClassType(name) => CodeBlob(name, Set())
    case Type.OptionalOf(typ) =>
      val elemType = typeDescStringOf(typ, context)
      CodeBlob(s"Option[${elemType.code}]", elemType.required)
    case Type.ArrayOf(typ) =>
      val elemType = typeDescStringOf(typ, context)
      CodeBlob(s"List[${elemType.code}]", elemType.required)
    case unionType: Type.UnionOf =>
      analysis.reduceUnionType(unionType) match {
        case reducedType: Type.UnionOf =>
          val unionTypeNames = reducedType.types.map(Type.readableNameOf)
          val contextText = context.map(ctx => s" around $ctx").getOrElse("")
          throw new Exception(s"Union type of {${unionTypeNames.mkString(", ")}} is not supported$contextText")
        case reducedType => typeDescStringOf(reducedType)
      }
    case Type.EnumType(enumName) => CodeBlob(s"$enumName.Value", Set())
    case Type.UnspecifiedEnumType(uniqueId) => CodeBlob(s"${analysis.shortenedEnumTypesMap(uniqueId)}.Value", Set())
    case Type.NullType => CodeBlob("Option[Nothing]", Set())
    case Type.AnyType => CodeBlob("Any", Set())
    case Type.BoolType => CodeBlob("Boolean", Set())
    case Type.CharType => CodeBlob("Char", Set())
    case Type.StringType => CodeBlob("String", Set())
    case Type.NothingType => CodeBlob("Nothing", Set())
  }

  def enumDefs(enumValuesMap: Map[String, Set[String]]): CodeBlob = {
    if (enumValuesMap.isEmpty) CodeBlob("", Set()) else enumValuesMap.keySet.toList.sorted.map { enumName =>
      val members = enumValuesMap(enumName).toList.sorted
      CodeBlob(s"object $enumName extends Enumeration { val ${members.mkString(", ")} = Value }", Set())
    }.reduce(_ + _)
  }

  def matchStartFunc(): CodeBlob = {
    val startSymbol = analysis.ngrammar.symbolOf(analysis.ngrammar.nsymbols(analysis.ngrammar.startSymbol).asInstanceOf[NStart].produce).asInstanceOf[NNonterminal]
    val returnType = typeDescStringOf(analysis.nonterminalTypes(analysis.startNonterminalName), context = Some(s"return type of ${analysis.startNonterminalName}"))
    CodeBlob(
      s"""def matchStart(node: Node): ${returnType.code} = {
         |  val BindNode(start, BindNode(_, body)) = node
         |  assert(start.id == ${analysis.ngrammar.startSymbol})
         |  ${nonterminalMatchFuncName(startSymbol.symbol.name)}(body)
         |}""".stripMargin,
      returnType.required ++ Set(
        "com.giyeok.jparser.ParseResultTree.Node",
        "com.giyeok.jparser.ParseResultTree.BindNode"))
  }

  def nonterminalMatchFunc(nonterminal: String): CodeBlob = {
    val valuefyExpr = analysis.nonterminalValuefyExprs(nonterminal)
    val body = unrollChoicesExpr(valuefyExpr.choices, "node", analysis.nonterminalTypes(nonterminal), useOriginalInput = false)
    val returnType = typeDescStringOf(analysis.nonterminalTypes(nonterminal), Some(s"return type of nonterminal $nonterminal"))
    val bodyCode = if (body.prepares.isEmpty) {
      CodeBlob(body.result, body.required)
    } else {
      CodeBlob(body.prepares.mkString("\n") + "\n" + body.result, body.required).wrapBrace()
    }
    CodeBlob(s"def ${nonterminalMatchFuncName(nonterminal)}(node: Node): ${returnType.code} = " + bodyCode.code,
      body.required ++ returnType.required ++ bodyCode.required + "com.giyeok.jparser.ParseResultTree.Node")
  }

  private def unrollChoicesExpr(choices: Map[Symbols.Symbol, ValuefyExpr], inputName: String, requiredType: Type, useOriginalInput: Boolean): ExprBlob = {
    val bindedVar = newVar()
    val bodyVar = newVar()
    val casesExpr = choices.map { choice =>
      val choiceId = analysis.ngrammar.idOf(choice._1)
      /**
       * UnrollChoices가 사용되는 경우는 1. Nonterminal match function 2. Optional이나 InPlaceChoices에서 사용되는 경우
       * 이 때,
       * * 1의 경우는 가장 바깥의 Nonterminal symbol에 대한(즉 LHS에 대한) bind가 벗겨진 채로 오고,
       * * 2의 경우는 가장 바깥 symbol에 대한 bind가 그대로 들어온다.
       * 그래서 1의 경우 useOriginalInput=false, 2의 경우 useOriginalInput=true이다.
       * 여기서, unroll choice를 하기 위해 기본적으로 Bind를 한 번 풀어야 하기 때문에 2에서 가장 첫번째 valuefy expr이 Unbind인 경우
       * original input은 사용하지 않고 unbind된 body를 사용함
       */
      val bodyCode = if (useOriginalInput) {
        choice._2 match {
          case ValuefyExpr.Unbind(symbol, unbindExpr) =>
            assert(symbol == choice._1)
            valuefyExprToCodeWithCoercion(unbindExpr, bodyVar, requiredType)
          case _ => valuefyExprToCodeWithCoercion(choice._2, inputName, requiredType)
        }
      } else valuefyExprToCodeWithCoercion(choice._2, bodyVar, requiredType)
      val caseBody =
        if (bodyCode.prepares.isEmpty) bodyCode.result
        else (bodyCode.prepares :+ bodyCode.result).map("  " + _) mkString ("\n")
      CodeBlob(s"case $choiceId =>\n$caseBody", bodyCode.required)
    }.toList.reduce(_ + _)
    val unrolledVar = newVar()
    ExprBlob(List(
      s"val BindNode($bindedVar, $bodyVar) = $inputName",
      s"val $unrolledVar = " + casesExpr.wrap(s"$bindedVar.id match {", "}").code
    ), unrolledVar, casesExpr.required)
  }

  private def nonterminalMatchFuncName(nonterminal: String) =
    s"match${nonterminal.substring(0, 1).toUpperCase}${nonterminal.substring(1)}"

  private var counter = 0

  private def newVar(): String = {
    counter += 1
    s"v$counter"
  }

  private def typeOf(expr: ValuefyExpr): Type = analysis.typeInferer.typeOfValuefyExpr(expr).get

  private def addCoercion(expr: String, requiredType: Type, actualType: Type): String =
    (requiredType, actualType) match {
      case (requiredType, actualType) if requiredType == actualType => expr
      case (Type.OptionalOf(optType), actual) if optType == actual => s"Some($expr)"
      case _ => expr // TODO
    }

  private def addCoercion(expr: ExprBlob, requiredType: Type, actualType: Type): ExprBlob =
    expr.copy(result = addCoercion(expr.result, requiredType, actualType))

  private def valuefyExprToCodeWithCoercion(valuefyExpr: ValuefyExpr, inputName: String, requiredType: Type): ExprBlob =
    addCoercion(valuefyExprToCode(valuefyExpr, inputName), requiredType, typeOf(valuefyExpr))

  def funcCallToCode(funcCall: ValuefyExpr.FuncCall, inputName: String): ExprBlob = {
    val ValuefyExpr.FuncCall(funcType, params) = funcCall
    // TODO coercion
    funcType match {
      case com.giyeok.jparser.metalang3a.ValuefyExpr.FuncType.IsPresent =>
        check(params.size == 1, "ispresent function only can have exactly one parameter")
        val param = valuefyExprToCode(params.head, inputName)

        @tailrec def isPresentCode(paramType: Type): String = paramType match {
          case Type.NodeType => s"${param.result}.sourceText.nonEmpty"
          case Type.ArrayOf(_) => s"${param.result}.nonEmpty"
          case Type.OptionalOf(_) => s"${param.result}.isDefined"
          case Type.StringType => s"${param.result}.nonEmpty"
          case unionType: Type.UnionOf =>
            val reducedType = analysis.reduceUnionType(unionType)
            check(!reducedType.isInstanceOf[Type.UnionOf], "union type not supported in ispresent function")
            isPresentCode(reducedType)
          // 그 외 타입은 지원하지 않음
        }

        ExprBlob(param.prepares, isPresentCode(typeOf(params.head)), param.required)
      case com.giyeok.jparser.metalang3a.ValuefyExpr.FuncType.IsEmpty =>
        check(params.size == 1, "isempty function only can have exactly one parameter")
        val param = valuefyExprToCode(params.head, inputName)

        @tailrec def isEmptyCode(paramType: Type): String = paramType match {
          case Type.NodeType => s"${param.result}.sourceText.isEmpty"
          case Type.ArrayOf(_) => s"${param.result}.isEmpty"
          case Type.OptionalOf(_) => s"${param.result}.isEmpty"
          case Type.StringType => s"${param.result}.isEmpty"
          case unionType: Type.UnionOf =>
            val reducedType = analysis.reduceUnionType(unionType)
            check(!reducedType.isInstanceOf[Type.UnionOf], "union type not supported in isempty function")
            isEmptyCode(reducedType)
          // 그 외 타입은 지원하지 않음
        }

        ExprBlob(param.prepares, isEmptyCode(typeOf(params.head)), param.required)
      case com.giyeok.jparser.metalang3a.ValuefyExpr.FuncType.Chr =>
        check(params.size == 1, "chr function only can have exactly one parameter")
        val paramCode = valuefyExprToCode(params.head, inputName)
        val result = typeOf(params.head) match {
          case Type.NodeType => s"${paramCode.result}.sourceText.charAt(0)"
          case Type.CharType => paramCode.result
        }
        ExprBlob(paramCode.prepares, result, paramCode.required)
      case com.giyeok.jparser.metalang3a.ValuefyExpr.FuncType.Str =>
        val paramCodes = params.map(valuefyExprToCode(_, inputName))

        def toStringCode(input: String, inputType: Type): String = inputType match {
          case Type.NodeType => s"$input.sourceText"
          case Type.ArrayOf(elemType) => s"""$input.map(x => ${toStringCode("x", elemType)}).mkString("")"""
          case Type.OptionalOf(valueType) =>
            s"""$input.map(x => ${toStringCode("x", valueType)}).getOrElse("")"""
          case Type.BoolType => s"$input.toString"
          case Type.CharType => s"$input.toString"
          case Type.StringType => input
          case unionType: Type.UnionOf =>
            val reducedType = analysis.reduceUnionType(unionType)
            check(!reducedType.isInstanceOf[Type.UnionOf], "union type not supported in str function")
            toStringCode(input, reducedType)
        }

        ExprBlob(paramCodes.flatMap(_.prepares),
          paramCodes.zip(params).map { case (paramCode, param) =>
            val paramType = typeOf(param)
            toStringCode(paramCode.result, paramType)
          }.mkString(" + "),
          paramCodes.flatMap(_.required).toSet)
    }
  }

  def valuefyExprToCode(valuefyExpr: ValuefyExpr, inputName: String): ExprBlob = valuefyExpr match {
    case ValuefyExpr.InputNode => ExprBlob(List(), inputName, Set())
    case ValuefyExpr.MatchNonterminal(nonterminalName) =>
      ExprBlob(List(), s"${nonterminalMatchFuncName(nonterminalName)}($inputName)", Set())
    case ValuefyExpr.Unbind(symbol, expr) =>
      val bindedVar = newVar()
      val bodyVar = newVar()
      val exprCode = valuefyExprToCode(expr, bodyVar)
      ExprBlob(List(
        s"val BindNode($bindedVar, $bodyVar) = $inputName",
        s"assert($bindedVar.id == ${analysis.ngrammar.idOf(symbol)})"
      ) ++ exprCode.prepares, exprCode.result, exprCode.required)
    case ValuefyExpr.JoinBody(bodyProcessor) =>
      val bodyVar = newVar()
      val bodyProcessorCode = valuefyExprToCode(bodyProcessor, bodyVar)
      ExprBlob(s"val JoinNode(_, $bodyVar, _) = $inputName" +: bodyProcessorCode.prepares,
        bodyProcessorCode.result,
        bodyProcessorCode.required + "com.giyeok.jparser.ParseResultTree.JoinNode")
    case ValuefyExpr.JoinCond(condProcessor) =>
      val condVar = newVar()
      val bodyProcessorCode = valuefyExprToCode(condProcessor, condVar)
      ExprBlob(s"val JoinNode(_, _, $condVar) = $inputName" +: bodyProcessorCode.prepares,
        bodyProcessorCode.result,
        bodyProcessorCode.required + "com.giyeok.jparser.ParseResultTree.JoinNode")
    case ValuefyExpr.SeqElemAt(index, expr) =>
      val elemVar = newVar()
      val exprCode = valuefyExprToCode(expr, elemVar)
      val indexer = if (index == 0) ".head" else s"($index)"
      ExprBlob(
        s"val $elemVar = $inputName.asInstanceOf[SequenceNode].children$indexer" +: exprCode.prepares,
        exprCode.result,
        exprCode.required + "com.giyeok.jparser.ParseResultTree.SequenceNode")
    case ValuefyExpr.UnrollRepeatFromZero(elemProcessor) =>
      val unrolledVar = newVar()
      val elemProcessorCode = valuefyExprToCode(elemProcessor, "elem")
      ExprBlob(
        List(s"val $unrolledVar = unrollRepeat0($inputName).map { elem =>") ++
          elemProcessorCode.prepares :+
          addCoercion(elemProcessorCode.result, typeOf(valuefyExpr).asInstanceOf[Type.ArrayOf].elemType, typeOf(elemProcessor)) :+
          "}",
        unrolledVar,
        elemProcessorCode.required + "com.giyeok.jparser.nparser.ParseTreeUtil.unrollRepeat0")
    case ValuefyExpr.UnrollRepeatFromOne(elemProcessor) =>
      val unrolledVar = newVar()
      val elemProcessorCode = valuefyExprToCode(elemProcessor, "elem")
      ExprBlob(
        List(s"val $unrolledVar = unrollRepeat1($inputName).map { elem =>") ++
          elemProcessorCode.prepares :+
          addCoercion(elemProcessorCode.result, typeOf(valuefyExpr).asInstanceOf[Type.ArrayOf].elemType, typeOf(elemProcessor)) :+
          "}",
        unrolledVar,
        elemProcessorCode.required + "com.giyeok.jparser.nparser.ParseTreeUtil.unrollRepeat1")
    case ValuefyExpr.UnrollChoices(choices) =>
      unrollChoicesExpr(choices, inputName, typeOf(valuefyExpr), useOriginalInput = true)
    case ValuefyExpr.ConstructCall(className, params) =>
      val paramCodes = params.zipWithIndex.map { case (param, index) =>
        valuefyExprToCodeWithCoercion(param, inputName, analysis.classParamTypes(className)(index)._2)
      }
      val constructorExpr = s"$className(${paramCodes.map(_.result).mkString(", ")})" + (if (options.withParseNodesInClasses) s"($inputName)" else "")
      ExprBlob(paramCodes.flatMap(_.prepares), constructorExpr, paramCodes.flatMap(_.required).toSet)
    case funcCall: ValuefyExpr.FuncCall =>
      funcCallToCode(funcCall, inputName)
    case ValuefyExpr.ArrayExpr(elems) =>
      val elemType = typeOf(valuefyExpr).asInstanceOf[Type.ArrayOf].elemType
      val elemCodes = elems.map(valuefyExprToCodeWithCoercion(_, inputName, elemType))
      ExprBlob(elemCodes.flatMap(_.prepares),
        s"List(${elemCodes.map(_.result).mkString(", ")})",
        elemCodes.flatMap(_.required).toSet)
    case ValuefyExpr.BinOp(op, lhs, rhs) =>
      val lhsCode = valuefyExprToCode(lhs, inputName)
      val rhsCode = valuefyExprToCode(rhs, inputName)
      val opExpr = op match {
        case com.giyeok.jparser.metalang3a.ValuefyExpr.BinOpType.ADD =>
          (typeOf(lhs), typeOf(rhs)) match {
            case (Type.StringType, Type.StringType) => s"${lhsCode.result} + ${rhsCode.result}"
            case (Type.ArrayOf(_), Type.ArrayOf(_)) => s"${lhsCode.result} ++ ${rhsCode.result}"
          }
        case com.giyeok.jparser.metalang3a.ValuefyExpr.BinOpType.EQ =>
          check(typeOf(lhs) == typeOf(rhs), "lhs and rhs of == must be same type")
          s"${lhsCode.result} == ${rhsCode.result}"
        case com.giyeok.jparser.metalang3a.ValuefyExpr.BinOpType.NE =>
          check(typeOf(lhs) == typeOf(rhs), "lhs and rhs of == must be same type")
          s"${lhsCode.result} != ${rhsCode.result}"
        case com.giyeok.jparser.metalang3a.ValuefyExpr.BinOpType.BOOL_AND =>
          (typeOf(lhs), typeOf(rhs)) match {
            case (Type.BoolType, Type.BoolType) => s"${lhsCode.result} && ${rhsCode.result}"
          }
        case com.giyeok.jparser.metalang3a.ValuefyExpr.BinOpType.BOOL_OR =>
          (typeOf(lhs), typeOf(rhs)) match {
            case (Type.BoolType, Type.BoolType) => s"${lhsCode.result} || ${rhsCode.result}"
          }
      }
      ExprBlob(lhsCode.prepares ++ rhsCode.prepares, opExpr, lhsCode.required ++ rhsCode.required)
    case ValuefyExpr.PreOp(op, expr) =>
      op match {
        case com.giyeok.jparser.metalang3a.ValuefyExpr.PreOpType.NOT =>
          check(typeOf(expr) == Type.BoolType, "not can be applied only to boolean expression")
          val exprCode = valuefyExprToCodeWithCoercion(expr, inputName, Type.BoolType)
          val resultVar = newVar()
          ExprBlob(exprCode.prepares :+ s"val $resultVar = !${exprCode.result}", resultVar, exprCode.required)
      }
    case ValuefyExpr.ElvisOp(expr, ifNull) =>
      val exprVar = newVar()
      val requiredType = typeOf(valuefyExpr)
      val exprCode = valuefyExprToCodeWithCoercion(expr, inputName, requiredType)
      val ifNullCode = valuefyExprToCodeWithCoercion(ifNull, inputName, requiredType)
      ExprBlob(
        exprCode.prepares :+ s"val $exprVar = ${exprCode.result}",
        s"if ($exprVar.isDefined) $exprVar.get else ${ifNullCode.withBraceIfNeeded}",
        exprCode.required ++ ifNullCode.required)
    case ValuefyExpr.TernaryOp(condition, ifTrue, ifFalse) =>
      val conditionCode = valuefyExprToCode(condition, inputName)
      val resultType = typeOf(valuefyExpr)
      val thenCode = valuefyExprToCodeWithCoercion(ifTrue, inputName, resultType)
      val elseCode = valuefyExprToCodeWithCoercion(ifFalse, inputName, resultType)
      val resultVar = newVar()
      ExprBlob(conditionCode.prepares ++
        List(s"val $resultVar = if (${conditionCode.result}) {") ++
        thenCode.prepares ++
        List(thenCode.result, "} else {") ++
        elseCode.prepares ++ List(elseCode.result, "}"),
        resultVar,
        conditionCode.required ++ thenCode.required ++ elseCode.required)
    case literal: ValuefyExpr.Literal =>
      literal match {
        case ValuefyExpr.NullLiteral => ExprBlob.code("None")
        case ValuefyExpr.BoolLiteral(value) => ExprBlob.code(s"$value")
        case ValuefyExpr.CharLiteral(value) => ExprBlob.code(s"'${javaChar(value)}'") // TODO escape
        case ValuefyExpr.CharFromTerminalLiteral =>
          ExprBlob(List(),
            s"$inputName.asInstanceOf[TerminalNode].input.asInstanceOf[Inputs.Character].char",
            Set("com.giyeok.jparser.ParseResultTree.TerminalNode",
              "com.giyeok.jparser.Inputs"))
        case ValuefyExpr.StringLiteral(value) => ExprBlob.code("\"" + value + "\"") // TODO escape
      }
    case enumValue: ValuefyExpr.EnumValue =>
      enumValue match {
        case ValuefyExpr.CanonicalEnumValue(enumName, enumValue) => ExprBlob.code(s"$enumName.$enumValue")
        case ValuefyExpr.ShortenedEnumValue(unspecifiedEnumTypeId, enumValue) =>
          val enumName = analysis.shortenedEnumTypesMap(unspecifiedEnumTypeId)
          ExprBlob.code(s"$enumName.$enumValue")
      }
  }

  def reachableNonterminalMatchFuncs(valuefyExpr: ValuefyExpr, cc: Set[String]): Set[String] = valuefyExpr match {
    case ValuefyExpr.MatchNonterminal(nonterminalName) =>
      if (cc contains nonterminalName) cc
      else reachableNonterminalMatchFuncs(analysis.nonterminalValuefyExprs(nonterminalName), cc + nonterminalName)
    case ValuefyExpr.Unbind(_, expr) => reachableNonterminalMatchFuncs(expr, cc)
    case ValuefyExpr.JoinBody(bodyProcessor) => reachableNonterminalMatchFuncs(bodyProcessor, cc)
    case ValuefyExpr.JoinCond(condProcessor) => reachableNonterminalMatchFuncs(condProcessor, cc)
    case ValuefyExpr.SeqElemAt(_, expr) => reachableNonterminalMatchFuncs(expr, cc)
    case ValuefyExpr.UnrollRepeatFromZero(elemProcessor) => reachableNonterminalMatchFuncs(elemProcessor, cc)
    case ValuefyExpr.UnrollRepeatFromOne(elemProcessor) => reachableNonterminalMatchFuncs(elemProcessor, cc)
    case ValuefyExpr.UnrollChoices(choices) =>
      choices.values.foldLeft(cc) { (m, choiceExpr) => reachableNonterminalMatchFuncs(choiceExpr, m) }
    case ValuefyExpr.ConstructCall(_, params) =>
      params.foldLeft(cc) { (m, paramExpr) => reachableNonterminalMatchFuncs(paramExpr, m) }
    case ValuefyExpr.FuncCall(_, params) =>
      params.foldLeft(cc) { (m, paramExpr) => reachableNonterminalMatchFuncs(paramExpr, m) }
    case ValuefyExpr.ArrayExpr(elems) =>
      elems.foldLeft(cc) { (m, elemExpr) => reachableNonterminalMatchFuncs(elemExpr, m) }
    case ValuefyExpr.BinOp(_, lhs, rhs) =>
      reachableNonterminalMatchFuncs(lhs, reachableNonterminalMatchFuncs(rhs, cc))
    case ValuefyExpr.PreOp(_, expr) =>
      reachableNonterminalMatchFuncs(expr, cc)
    case ValuefyExpr.ElvisOp(expr, ifNull) =>
      reachableNonterminalMatchFuncs(expr, reachableNonterminalMatchFuncs(ifNull, cc))
    case ValuefyExpr.TernaryOp(condition, ifTrue, ifFalse) =>
      reachableNonterminalMatchFuncs(condition,
        reachableNonterminalMatchFuncs(ifTrue,
          reachableNonterminalMatchFuncs(ifFalse, cc)))
    case ValuefyExpr.InputNode | _: ValuefyExpr.Literal | _: ValuefyExpr.EnumValue => cc
  }

  def generateParser(className: String, ngrammarDefCode: CodeBlob, parserDef: CodeBlob, mainFunc: Option[CodeBlob]): String = {
    val classDefsCode = classDefs(analysis.classRelations)
    val enumDefsCode = enumDefs(analysis.enumValuesMap)
    val reachableNonterms = reachableNonterminalMatchFuncs(
      analysis.nonterminalValuefyExprs(analysis.startNonterminalName), Set(analysis.startNonterminalName))
    val nontermMatchCodes = reachableNonterms.toList.sorted.map(nonterminalMatchFunc)
    val startMatchCode = matchStartFunc()
    val startType = typeDescStringOf(analysis.nonterminalTypes(analysis.startNonterminalName), context = Some(s"nonterminal type of ${analysis.startNonterminalName}"))

    val allImports = (ngrammarDefCode.required ++
      classDefsCode.required ++
      enumDefsCode.required ++
      nontermMatchCodes.flatMap(_.required) ++
      startMatchCode.required ++
      startType.required ++
      parserDef.required ++
      mainFunc.map(_.required).getOrElse(Set()) +
      "com.giyeok.jparser.nparser.ParseTreeUtil" +
      "com.giyeok.jparser.NGrammar").toList.sorted
    s"""${allImports.map(pkg => s"import $pkg").mkString("\n")}
       |
       |object $className {
       |  val ngrammar: NGrammar = ${ngrammarDefCode.indent().code}
       |
       |${classDefsCode.indent().code}
       |${enumDefsCode.indent().code}
       |
       |${nontermMatchCodes.map(_.indent().code).mkString("\n\n")}
       |
       |${startMatchCode.indent().code}
       |
       |${parserDef.indent().code}
       |${mainFunc.map(_.indent().code).getOrElse("")}
       |}
       |""".stripMargin
  }

  def generateParser(className: String, mainFuncExamples: Option[List[String]] = None): String = {
    val grammarDef = options.grammarDefType match {
      case ScalaCodeGen.InlineSourceDef => ngrammarDef(analysis.ngrammar)
      case ScalaCodeGen.InlineProtoDef => inlinedProtoNGrammar()
      case ScalaCodeGen.FileProtoDef(filePath) => fileProtoGrammar(filePath)
    }
    generateParser(className, grammarDef, naiveParserDef(), mainFuncExamples.map(mainFuncBlob))
  }

  def inlinedProtoNGrammar(): CodeBlob = {
    val grammarProto = GrammarProtobufConverter.convertNGrammarToProto(analysis.ngrammar)
    val grammarProtoBase64 = Base64.getEncoder.encodeToString(grammarProto.toByteArray)

    CodeBlob(
      s"""GrammarProtobufConverter.convertProtoToNGrammar(GrammarProto.NGrammar.parseFrom(Base64.getDecoder.decode(
         |  \"$grammarProtoBase64\")))""".stripMargin,
      Set("com.giyeok.jparser.proto.GrammarProto",
        "com.giyeok.jparser.proto.GrammarProtobufConverter",
        "java.util.Base64"))
  }

  def fileProtoGrammar(filePath: String): CodeBlob = CodeBlob(
    s"""Using(new FileInputStream(s"${escapeString(filePath)}")) { inputStream =>
       |  GrammarProtobufConverter.convertProtoToNGrammar(GrammarProto.NGrammar.parseFrom(inputStream))
       |}.get""".stripMargin,
    Set("java.io.FileInputStream", "scala.util.Using",
      "com.giyeok.jparser.proto.GrammarProto",
      "com.giyeok.jparser.proto.GrammarProtobufConverter"))

  def naiveParserDef(): CodeBlob = {
    val startType = typeDescStringOf(analysis.nonterminalTypes(analysis.startNonterminalName), context = Some(s"nonterminal type of ${analysis.startNonterminalName}"))

    CodeBlob(
      s"""val naiveParser = new NaiveParser(ngrammar)
         |
         |def parse(text: String): Either[Parser.NaiveContext, ParsingErrors.ParsingError] =
         |  naiveParser.parse(text)
         |
         |def parseAst(text: String): Either[${startType.code}, ParsingErrors.ParsingError] =
         |  ParseTreeUtil.parseAst(naiveParser, text, matchStart)
         |""".stripMargin,
      Set("com.giyeok.jparser.nparser.ParseTreeUtil",
        "com.giyeok.jparser.nparser.NaiveParser",
        "com.giyeok.jparser.nparser.Parser",
        "com.giyeok.jparser.ParsingErrors")
    )
  }

  def mainFuncBlob(examples: List[String]): CodeBlob = CodeBlob(
    s"""def main(args: Array[String]): Unit = {
       |  ${examples.map(example => "    println(parseAst(" + escapeString(example) + "))").mkString("\n")}
       |}""",
    Set()
  )
}


text:
package com.bmj.greader.ui.module.user.view;

import com.bmj.greader.data.model.GithubComment;
import com.bmj.mvp.lce.LceView;

import java.util.ArrayList;

/**
 * Created by Administrator on 2016/12/21 0021.
 */
public interface CommentView extends LceView<ArrayList<GithubComment>> {
    void addCommentResult(boolean isSuccess,GithubComment comment);
    void deleteCommentResult(boolean isSuccess,int position);
    void loadMore(ArrayList<GithubComment> data);
}


text:
require File.expand_path('../../../../spec_helper', __FILE__)

describe GamesRadarApi::Client::Franchises do

  before do
    @client = get_client
  end

  describe 'Franchises list' do
    let(:response) { @client.franchises }
    it 'should have at least one result' do
      response.size.must_be :>, 0
    end

    it 'should return valid franchises' do
      response.first.name.us.must_equal '.hack'
    end
  end

end


text:
<manifest package="com.hackplan.androidarcmenu">
    <application />
</manifest>


text:
import os

import GafferSceneTest

class OSLTestCase( GafferSceneTest.SceneTestCase ) :

	def setUp( self ) :

		self.__compiledShaders = set()

	def compileShader( self, sourceFileName ) :

		outputFileName = "/tmp/" + os.path.splitext( os.path.basename( sourceFileName ) )[0] + ".oso"
		os.system( "oslc -q -o %s %s" % ( outputFileName, sourceFileName ) )

		return os.path.splitext( outputFileName )[0]

	def tearDown( self ) :

		for f in self.__compiledShaders :
			if os.path.exists( f ) :
				os.remove( f )


text:
<?php
if ( ! function_exists( 'add_filter' ) ) {
	exit;
}
function hocwp_comment_wp_insert_comment( $comment_id, $comment_object ) {

}

add_action( 'wp_insert_comment', 'hocwp_comment_wp_insert_comment', 10, 2 );

function hocwp_comment_transition_comment_status( $new_status, $old_status, $comment ) {
	if ( $old_status != $new_status ) {
		if ( 'approved' === $new_status ) {
			do_action( 'hocwp_comment_approved', $comment );
			$notify_me = get_comment_meta( $comment->comment_ID, 'notify_me', true );
			if ( ! empty( $notify_me ) ) {

			}
		}
		hocwp_delete_transient( 'hocwp_top_commenters' );
		do_action( 'hocwp_comment_status_changed', $comment );
	}
}

add_action( 'transition_comment_status', 'hocwp_comment_transition_comment_status', 10, 3 );

function hocwp_comment_form_default_fields( $fields ) {
	$commenter     = wp_get_current_commenter();
	$user          = wp_get_current_user();
	$user_identity = $user->exists() ? $user->display_name : '';
	$format        = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml';
	$format        = apply_filters( 'hocwp_comment_form_format', $format );
	$req           = get_option( 'require_name_email' );
	$aria_req      = ( $req ? "aria-required='true'" : '' );
	$html_req      = ( $req ? "required='required'" : '' );
	$required_html = '';
	hocwp_add_string_with_space_before( $required_html, $aria_req );
	hocwp_add_string_with_space_before( $required_html, $html_req );
	$html5  = 'html5' === $format;
	$fields = array(
		'author' => '
' . '' . __( 'Name', 'hocwp-theme' ) . ( $req ? ' *' : '' ) . ' ' .
		            '<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30" ' . $required_html . ' />
',
		'email'  => '
' . __( 'Email', 'hocwp-theme' ) . ( $req ? ' *' : '' ) . ' ' .
		            '<input id="email" name="email" ' . ( $html5 ? 'type="email"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30" aria-describedby="email-notes" ' . $required_html . ' />
',
		'url'    => '
' . __( 'Website', 'hocwp-theme' ) . ' ' .
		            '<input id="url" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" />
',
	);

	return $fields;
}

add_filter( 'comment_form_default_fields', 'hocwp_comment_form_default_fields' );

function hocwp_comment_form_defaults( $defaults ) {
	$commenter     = wp_get_current_commenter();
	$user          = wp_get_current_user();
	$user_identity = $user->exists() ? $user->display_name : '';
	$format        = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml';
	$format        = apply_filters( 'hocwp_comment_form_format', $format );
	$req           = get_option( 'require_name_email' );
	$aria_req      = ( $req ? " aria-required='true'" : '' );
	$html_req      = ( $req ? " required='required'" : '' );
	$required_text = sprintf( ' ' . __( 'Required fields are marked %s', 'hocwp-theme' ), '*' );
	$html5         = 'html5' === $format;
	$defaults      = array(
		'comment_field'        => '
' . _x( 'Comment', 'comment field label', 'hocwp-theme' ) . ' <textarea id="comment" name="comment" cols="45" rows="8"  aria-required="true" required="required"></textarea>
',
		'must_log_in'          => '
' . sprintf( __( 'You must be logged in to post a comment.', 'hocwp-theme' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( get_the_ID() ) ) ) ) . '
',
		'logged_in_as'         => '
' . sprintf( __( 'Logged in as %2$s. Log out?', 'hocwp-theme' ), get_edit_user_link(), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( get_the_ID() ) ) ) ) . '
',
		'comment_notes_before' => '
' . __( 'Your email address will not be published.', 'hocwp-theme' ) . '' . ( $req ? $required_text : '' ) . '
',
		'comment_notes_after'  => '',
		'id_form'              => 'commentform',
		'id_submit'            => 'submit',
		'class_submit'         => 'submit',
		'name_submit'          => 'submit',
		'title_reply'          => '' . __( 'Leave a Reply', 'hocwp-theme' ) . '',
		'title_reply_to'       => __( 'Leave a Reply to %s', 'hocwp-theme' ),
		'cancel_reply_link'    => __( 'Click here to cancel reply.', 'hocwp-theme' ),
		'label_submit'         => __( 'Post Comment', 'hocwp-theme' ),
		'submit_button'        => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />',
		'submit_field'         => '
%1$s %2$s
',
		'format'               => 'html5'
	);

	return $defaults;
}

add_filter( 'comment_form_defaults', 'hocwp_comment_form_defaults' );

function hocwp_wp_list_comments_args( $args ) {
	$args['reply_text'] = '' . __( 'Reply', 'hocwp-theme' ) . '';

	return $args;
}

add_filter( 'wp_list_comments_args', 'hocwp_wp_list_comments_args', 10 );

function hocwp_get_comment_likes( $comment_id ) {
	$result = get_comment_meta( $comment_id, 'likes', true );
	$result = absint( $result );

	return $result;
}

function hocwp_facebook_comment( $args = array() ) {
	$args        = apply_filters( 'hocwp_facebook_comment_args', $args );
	$colorscheme = isset( $args['colorscheme'] ) ? $args['colorscheme'] : 'light';
	$colorscheme = apply_filters( 'hocwp_facebook_comment_colorscheme', $colorscheme, $args );
	$href        = isset( $args['href'] ) ? $args['href'] : '';
	if ( empty( $href ) ) {
		if ( is_single() || is_page() || is_singular() ) {
			$href = get_the_permalink();
		}
	}
	if ( empty( $href ) ) {
		$href = $this->get_current_url();
	}
	$href         = apply_filters( 'hocwp_facebook_comment_href', $href, $args );
	$mobile       = isset( $args['mobile'] ) ? $args['mobile'] : '';
	$num_posts    = isset( $args['num_posts'] ) ? $args['num_posts'] : 10;
	$num_posts    = apply_filters( 'hocwp_facebook_comment_num_posts', $num_posts, $args );
	$order_by     = isset( $args['order_by'] ) ? $args['order_by'] : 'social';
	$width        = isset( $args['width'] ) ? $args['width'] : '100%';
	$width        = apply_filters( 'hocwp_facebook_comment_width', $width, $args );
	$loading_text = hocwp_get_value_by_key( $args, 'loading_text', __( 'Loading...', 'hocwp-theme' ) );
	$div          = new HOCWP_HTML( 'div' );
	$div->set_class( 'fb-comments' );
	$atts = array(
		'data-colorscheme' => $colorscheme,
		'data-href'        => $href,
		'data-mobile'      => $mobile,
		'data-numposts'    => $num_posts,
		'data-order-by'    => $order_by,
		'data-width'       => $width
	);
	$atts = apply_filters( 'hocwp_facebook_comment_attributes', $atts, $args );
	$div->set_attribute_array( $atts );
	$div->set_text( $loading_text );
	$div->output();
}

function hocwp_google_comment() {
	?>

<?php _e( 'Loading...', 'hocwp-theme' ); ?>

	<?php
}

function hocwp_disqus_comment() {
	?>

<?php _e( 'Loading...', 'hocwp-theme' ); ?>

	Please enable JavaScript to view the comments powered by
			Disqus.
	<?php
}

function hocwp_get_top_commenters( $number = 5, $time = 'all', $condition = '' ) {
	$transient_name = hocwp_build_transient_name( 'hocwp_top_commenters_%s', $number );
	if ( false === ( $results = get_transient( $transient_name ) ) ) {
		global $wpdb;
		$sql     = 'SELECT COUNT(comment_author_email) AS comments_count, comment_author_email, comment_author, comment_author_url, user_id FROM ' . $wpdb->comments . '
                    WHERE comment_author_email != "" AND comment_type = "" AND comment_approved = 1';
		$expires = HOUR_IN_SECONDS;
		switch ( $time ) {
			case 'today':
				$sql .= ' AND DAY(comment_date) = DAY(CURDATE()) AND MONTH(comment_date) = MONTH(CURDATE()) AND YEAR(comment_date) = YEAR(CURDATE())';
				break;
			case 'week':
			case 'this_week':
				$sql .= ' AND YEARWEEK(comment_date) = YEARWEEK(NOW())';
				$expires = 12 * HOUR_IN_SECONDS;
				break;
			case 'month':
			case 'this_month':
				$sql .= ' AND MONTH(comment_date) = MONTH(CURDATE()) AND YEAR(comment_date) = YEAR(CURDATE())';
				$expires = DAY_IN_SECONDS;
				break;
			case 'year':
			case 'this_year':
				$sql .= ' AND YEAR(comment_date) = YEAR(CURDATE())';
				$expires = 2 * DAY_IN_SECONDS;
				break;
		}
		$condition = trim( $condition );
		if ( ! empty( $condition ) ) {
			$sql .= ' ' . $condition;
		}
		$sql .= ' GROUP BY comment_author_email ORDER BY comments_count DESC, comment_author ASC LIMIT ' . $number;
		$results = $wpdb->get_results( $sql );
		set_transient( $transient_name, $results, $expires );
	}

	return $results;
}

function hocwp_comment_inserted_hook( $id, $comment ) {
	hocwp_delete_transient( 'hocwp_top_commenters' );
}

add_action( 'wp_insert_comment', 'hocwp_comment_inserted_hook', 10, 2 );