text:
from nose.tools import *  # flake8: noqa

from tests.base import ApiTestCase
from osf_tests.factories import (
    AuthUserFactory,
    InstitutionFactory,
    RegistrationFactory,
    WithdrawnRegistrationFactory
)

from framework.auth import Auth
from api.base.settings.defaults import API_BASE
from api_tests.registrations.filters.test_filters import RegistrationListFilteringMixin
from osf.models import Node

class TestInstitutionRegistrationList(ApiTestCase):
    def setUp(self):
        super(TestInstitutionRegistrationList, self).setUp()
        self.institution = InstitutionFactory()
        self.registration1 = RegistrationFactory(is_public=True)
        self.registration1.affiliated_institutions.add(self.institution)
        self.registration1.save()
        self.user1 = AuthUserFactory()
        self.user2 = AuthUserFactory()
        self.registration2 = RegistrationFactory(
            creator=self.user1, is_public=False)
        self.registration2.affiliated_institutions.add(self.institution)
        self.registration2.add_contributor(self.user2, auth=Auth(self.user1))
        self.registration2.save()
        self.registration3 = RegistrationFactory(
            creator=self.user2, is_public=False)
        self.registration3.affiliated_institutions.add(self.institution)
        self.registration3.save()

        self.institution_node_url = '/{0}institutions/{1}/registrations/'.format(
            API_BASE, self.institution._id)

    def test_return_all_public_nodes(self):
        res = self.app.get(self.institution_node_url)

        assert_equal(res.status_code, 200)
        ids = [each['id'] for each in res.json['data']]

        assert_in(self.registration1._id, ids)
        assert_not_in(self.registration2._id, ids)
        assert_not_in(self.registration3._id, ids)

    def test_does_not_return_private_nodes_with_auth(self):
        res = self.app.get(self.institution_node_url, auth=self.user1.auth)

        assert_equal(res.status_code, 200)
        ids = [each['id'] for each in res.json['data']]

        assert_in(self.registration1._id, ids)
        assert_not_in(self.registration2._id, ids)
        assert_not_in(self.registration3._id, ids)

    def test_doesnt_return_retractions_without_auth(self):
        self.registration2.is_public = True
        self.registration2.save()
        retraction = WithdrawnRegistrationFactory(
            registration=self.registration2, user=self.user1)
        assert_true(self.registration2.is_retracted)

        res = self.app.get(self.institution_node_url)

        assert_equal(res.status_code, 200)
        ids = [each['id'] for each in res.json['data']]

        assert_not_in(self.registration2._id, ids)

    def test_doesnt_return_retractions_with_auth(self):
        retraction = WithdrawnRegistrationFactory(
            registration=self.registration2, user=self.user1)

        assert_true(self.registration2.is_retracted)

        res = self.app.get(self.institution_node_url, auth=self.user1.auth)

        assert_equal(res.status_code, 200)
        ids = [each['id'] for each in res.json['data']]

        assert_not_in(self.registration2._id, ids)

    def test_total_biographic_contributor_in_institution_registration(self):
        user3 = AuthUserFactory()
        registration3 = RegistrationFactory(is_public=True, creator=self.user1)
        registration3.affiliated_institutions.add(self.institution)
        registration3.add_contributor(self.user2, auth=Auth(self.user1))
        registration3.add_contributor(
            user3, auth=Auth(self.user1), visible=False)
        registration3.save()
        registration3_url = '/{0}registrations/{1}/?embed=contributors'.format(
            API_BASE, registration3._id)

        res = self.app.get(registration3_url)
        assert_true(
            res.json['data']['embeds']['contributors']['links']['meta']['total_bibliographic']
        )
        assert_equal(
            res.json['data']['embeds']['contributors']['links']['meta']['total_bibliographic'],
            2
        )

class TestRegistrationListFiltering(
        RegistrationListFilteringMixin,
        ApiTestCase):

    def setUp(self):
        self.institution = InstitutionFactory()
        self.url = '/{}institutions/{}/registrations/?version=2.2&'.format(
            API_BASE, self.institution._id)

        super(TestRegistrationListFiltering, self).setUp()

        A_children = [
            child for child in Node.objects.get_children(
                self.node_A
            )
        ]
        B2_children = [
            child for child in Node.objects.get_children(
                self.node_B2
            )
        ]

        for child in (A_children + B2_children):
            child.affiliated_institutions.add(self.institution)
            child.is_public = True
            child.save()

        self.node_A.is_public = True
        self.node_B2.is_public = True
        self.node_A.affiliated_institutions.add(self.institution)
        self.node_B2.affiliated_institutions.add(self.institution)

        self.node_A.save()
        self.node_B2.save()


text:
package in.twizmwaz.cardinal.module.channel.channels;

import in.twizmwaz.cardinal.module.channel.AbstractChannel;
import lombok.Getter;
import org.bukkit.entity.Player;

@Getter
public class PlayerChannel extends AbstractChannel {

  public PlayerChannel(Player player) {
    addPlayer(player);
  }

}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace Maestroprog\Saw\Thread;

/**
 * Интерфейс поддержки мультиплексирования.
 * Thread-ы его должны имплементировать.
 */
interface MultiplexingInterface
{
    /**
     * Назначает операционный размер шага для мультиплексируемого потока.
     *
     * @param int $stepSize
     * @return mixed
     */
    public function setOperationStepSize(int $stepSize);

    /**
     * Назначает общий операционный размер потока.
     *
     * @param int $size
     * @return mixed
     */
    public function setOperationSize(int $size);

    /**
     * Возвращает приоритет потока при мультиплексировании,
     * по отношению к другим потокам, в процентах от 0 до 100.
     *
     * @return int
     */
    public function getMuxPriority(): int;

    /**
     * Ставит поток в состояние паузы, то есть этот метод
     * вызывается, когда система временно переключается с данного
     * потока на другой поток.
     *
     * @return mixed
     */
    public function switchOff();

    /**
     * Назначает коллбек, который выполнится при переключении с потока.
     * Это что-то вроде события, и оно может пригодится в некоторых случаях,
     * например - когда требуется освободить память.
     *
     * @param callable $callback
     * @return mixed
     */
    public function onSwitchOff(callable $callback);

    /**
     * Аналогично методу @see switchOff, только наоборот, этот метод
     * вызывается при переключении на данный поток.
     *
     * @return mixed
     */
    public function switchOn();

    /**
     * Назначает коллбек, который выполнится при переключении на поток.
     * Аналогично методу @see onSwitchOff.
     *
     * @param callable $callback
     * @return mixed
     */
    public function onSwitch(callable $callback);
}


text:
package com.adamroughton.concentus.canonicalstate.direct;

import java.util.ArrayList;

import com.adamroughton.concentus.data.model.kryo.CandidateValue;

final class ComputeStateEvent {

	public long time;
	public final ArrayList<CandidateValue> candidateValues = new ArrayList<>();

}


text:
package com.moosemorals.configparser.types;

import com.moosemorals.configparser.SourceFile.Location;
import com.moosemorals.configparser.XML;
import java.util.LinkedList;
import java.util.List;
import javax.xml.stream.XMLStreamException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Osric Wilkinson (osric@fluffypeople.com)
 */
public class Menu extends Entry {

    private final Logger log = LoggerFactory.getLogger(Menu.class);

    private final List<Entry> entries;
    private Condition visibleIf;

    public Menu(Location location, String symbol) {
        super(location, symbol);
        this.entries = new LinkedList<>();
    }

    public void addEntry(Entry e) {
        entries.add(e);
    }

    public void setVisibleIf(Condition visibleIf) {
        this.visibleIf = visibleIf;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();

        result.append("[menu: ").append(prompt);

        result.append(entries.size()).append(entries.size() == 1 ? " entry" : " entries");

        result.append("]");
        return result.toString();
    }

    @Override
    public void toXML(XML xml) throws XMLStreamException {
        super.toXML(xml, "menu", x -> {
            xml.add("visibleIf", visibleIf);
            xml.add("entries", entries);
        });
    }

}


text:
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;

namespace OpenSim.Data.SQLite
{
    /// <summary>
    /// A SQL Interface for user grid data
    /// </summary>
    public class SQLiteGridUserData : SQLiteGenericTableHandler<GridUserData>, IGridUserData
    {
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public SQLiteGridUserData(string connectionString, string realm)
            : base(connectionString, realm, "GridUserStore") {}

        public new GridUserData Get(string userID)
        {
            GridUserData[] ret = Get("UserID", userID);

            if (ret.Length == 0)
                return null;

            return ret[0];
        }

        public GridUserData[] GetAll(string userID)
        {
            return base.Get(String.Format("UserID LIKE '{0}%'", userID));
        }

    }
}


text:
from math import ceil, log2

from scipy.stats import geom

from gwydion.base import np, Base, ProbDist, DiscreteProbDist
from gwydion.exceptions import GwydionError

class Geometric(DiscreteProbDist):
    """
    Geometric function. Returned function is

        y = p*(1 - p)**(x-1)

    Parameters
    ----------

    N : Integer.
        Length of arrays to be returned via the data method. Defaults to 100.
    p : Float, integer, or None.
        Probability of each trial succeeding. If none, defaults to a random value between 0 and 30.
    xlim : Tuple of floats or integers, or None.
        (Min, Max) values for the x-data. If None, defaults to (mu - 5*sigma, mu + 5*sigma).
    rand : Float or integer.
        The amplitude of random numbers added to the y-data. If None, no random data added. Defaults to 0.02.
    seed : Integer or None.
        Used to seed the RNG if repeatable results are required. Defaults to None (and thus no seeding).

    NOTE
    ----

    The Geometric distribution is a discrete probability distribution, meaning that x can take only integer values.

    If you try to return N values between x0 and x1, but x1-x0 > N, then you will, by definition, have some duplicate x values.

    Gwydion will prevent this by reducing the number N to the maximum possible. This is by design to ensure that all x values are unique.

    Examples
    --------

    >>>> Geometric()  # Default params, returns a random geom distribution.
    >>>> Geometric(N=1000)  # Increase the number of data points.
    >>>> Geometric(p=10)  # Setting the number of events expected in an interval to 10.
    >>>> Geometric(rand=None)  # Turn off randomness.
    >>>> Geometric(seed=1234)  # Seeded RNG.
    """

    def __init__(self, N=100, p=None, xlim=None, rand=0.01, seed=None, allow_negative_y=True):
        super().__init__(N=N,
                         xlim=xlim,
                         rand=rand,
                         seed=seed,
                         allow_negative_y=allow_negative_y)

        self.set_variables(p)

    def set_variables(self, p):

        for var in [p]:
            if var is not None and not isinstance(var, (float, int)):
                raise GwydionError('Variables must be either float, int, or None.')

        defaults = {'p': self.random.uniform(0.1,0.9)}

        for key, val in defaults.items():
            if locals()[key] is None:
                setattr(self, key, val)
            else:
                setattr(self, key, locals()[key])

        if self.xlim is None:
            self.xlim = (0, ceil(5/self.p))
        if self.N > (self.xlim[1]-self.xlim[0]):
            self.N = 1 + self.xlim[1] - self.xlim[0]

    def func(self, x):
        p = self.p
        return geom(p).pmf(x)

    def sample(self, N=None):
        p = self.p
        return geom(p).rvs(size=N, random_state=self.random)

    @property
    def mean(self):
        return 1/self.p

    @property
    def median(self):
        return ceil((-1 / (log2(1 - self.p))))

    @property
    def mode(self):
        return 1

    @property
    def variance(self):
        return (1 - self.p) / self.p**2

    @property
    def skewness(self):
        return (2 - self.p) / (1 - self.p)**0.5


text:
package com.chariotsolutions.jshepard.lang;

import java.util.Objects;
import java.util.stream.IntStream;

public class SafeString {
  private final String data;
  private final int length;

  private SafeString(String source) {
    data = Objects.requireNonNull(source).intern();
    length = data.codePointCount(0, data.length());
  }

  public String get() {
    return data;
  }

  public int length() {
    return length;
  }

  public int characterAt(int index) {
    return data.codePointAt(getRealIndex(index));
  }

  public IntStream characters() {
    return data.codePoints();
  }

  public SafeString substring(int startIndex, int endIndex) {
    int codePointStartIndex = getRealIndex(startIndex);
    int codePointEndIndex = getRealIndex(endIndex);
    String newData = data.substring(codePointStartIndex, codePointEndIndex);
    return new SafeString(newData);
  }

  private int getRealIndex(int index) {
    return data.offsetByCodePoints(0, index);
  }

  public static SafeString of(String source) {
    return new SafeString(source);
  }

  @Override
  public boolean equals(Object object) {
    if (object == null) {
      return false;
    }
    if (!(object instanceof SafeString)) {
      return false;
    }
    SafeString other = (SafeString) object;
    return data == other.data;
  }

  @Override
  public int hashCode() {
    return data.hashCode();
  }

  @Override
  public String toString() {
    return data;
  }
}


text:
id: version-24.0-puppeteer
title: Using with puppeteer
original_id: puppeteer
---

With the [Global Setup/Teardown](Configuration.md#globalsetup-string) and [Async Test Environment](Configuration.md#testenvironment-string) APIs, Jest can work smoothly with [puppeteer](https://github.com/GoogleChrome/puppeteer).

> Generating code coverage for test files using Puppeteer is currently not possible if your test uses `page.$eval`, `page.$$eval` or `page.evaluate` as the passed function is executed outside of Jest's scope. Check out [issue #7962](https://github.com/facebook/jest/issues/7962#issuecomment-495272339) on GitHub for a workaround.

## Use jest-puppeteer Preset

[Jest Puppeteer](https://github.com/smooth-code/jest-puppeteer) provides all required configuration to run your tests using Puppeteer.

1.  First install `jest-puppeteer`

```
yarn add --dev jest-puppeteer
```

2.  Specify preset in your Jest configuration:

```json
{
  "preset": "jest-puppeteer"
}
```

3.  Write your test

```js
describe('Google', () => {
  beforeAll(async () => {
    await page.goto('https://google.com');
  });

  it('should be titled "Google"', async () => {
    await expect(page.title()).resolves.toMatch('Google');
  });
});
```

There's no need to load any dependencies. Puppeteer's `page` and `browser` classes will automatically be exposed

See [documentation](https://github.com/smooth-code/jest-puppeteer).

## Custom example without jest-puppeteer preset

You can also hook up puppeteer from scratch. The basic idea is to:

1.  launch & file the websocket endpoint of puppeteer with Global Setup
2.  connect to puppeteer from each Test Environment
3.  close puppeteer with Global Teardown

Here's an example of the GlobalSetup script

```js
// setup.js
const puppeteer = require('puppeteer');
const mkdirp = require('mkdirp');
const path = require('path');
const fs = require('fs');
const os = require('os');

const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');

module.exports = async function() {
  const browser = await puppeteer.launch();
  // store the browser instance so we can teardown it later
  // this global is only available in the teardown but not in TestEnvironments
  global.__BROWSER_GLOBAL__ = browser;

  // use the file system to expose the wsEndpoint for TestEnvironments
  mkdirp.sync(DIR);
  fs.writeFileSync(path.join(DIR, 'wsEndpoint'), browser.wsEndpoint());
};
```

Then we need a custom Test Environment for puppeteer

```js
// puppeteer_environment.js
const NodeEnvironment = require('jest-environment-node');
const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer');
const os = require('os');

const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');

class PuppeteerEnvironment extends NodeEnvironment {
  constructor(config) {
    super(config);
  }

  async setup() {
    await super.setup();
    // get the wsEndpoint
    const wsEndpoint = fs.readFileSync(path.join(DIR, 'wsEndpoint'), 'utf8');
    if (!wsEndpoint) {
      throw new Error('wsEndpoint not found');
    }

    // connect to puppeteer
    this.global.__BROWSER__ = await puppeteer.connect({
      browserWSEndpoint: wsEndpoint,
    });
  }

  async teardown() {
    await super.teardown();
  }

  runScript(script) {
    return super.runScript(script);
  }
}

module.exports = PuppeteerEnvironment;
```

Finally we can close the puppeteer instance and clean-up the file

```js
// teardown.js
const os = require('os');
const rimraf = require('rimraf');
const path = require('path');

const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup');
module.exports = async function() {
  // close the browser instance
  await global.__BROWSER_GLOBAL__.close();

  // clean-up the wsEndpoint file
  rimraf.sync(DIR);
};
```

With all the things set up, we can now write our tests like this:

```js
// test.js
const timeout = 5000;

describe(
  '/ (Home Page)',
  () => {
    let page;
    beforeAll(async () => {
      page = await global.__BROWSER__.newPage();
      await page.goto('https://google.com');
    }, timeout);

    it('should load without error', async () => {
      const text = await page.evaluate(() => document.body.textContent);
      expect(text).toContain('google');
    });
  },
  timeout,
);
```

Finally, set `jest.config.js` to read from these files. (The `jest-puppeteer` preset does something like this under the hood.)

```js
module.exports = {
  globalSetup: './setup.js',
  globalTeardown: './teardown.js',
  testEnvironment: './puppeteer_environment.js',
};
```

Here's the code of [full working example](https://github.com/xfumihiro/jest-puppeteer-example).


text:
package ru.job4j.threads.notify;

import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.IntStream;

import static org.hamcrest.Matchers.is;

/**
 * Класс, реализующий тест для класса SimpleBlockingQueue.
 *
 * @author - b.savelev (mailto: justmustdie@yandex.ru)
 * @version - 1.0
 * @since 0.1
 */
public class SimpleBlockingQueueTest {

    /**
     * Проверяем работу блокирующей очереди в двух потоках.
     * Если очередь полна, то продюсер ждет освобождения места в очереди.
     * Если очередь пуста, то консьюмер ждет появления места в очереди.
     *
     * @throws InterruptedException в случае прерывания программы, когда один из потоков ждет
     *                              появления места или элементов в очереди.
     */
    @Test
    public void whenQueueOverloadedThenProducerWaits() throws InterruptedException {
        SimpleBlockingQueue<Integer> queue = new SimpleBlockingQueue<>();
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    queue.put(i);
                    System.out.println(String.format("Queue put: %d", i));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread consumer1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Assert.assertThat(queue.poll(), is(i));
                    System.out.println(String.format("Queue poll: %d", i));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();
        consumer1.start();
        producer.join();
        consumer1.join();
    }

    /**
     * Проверка того, что все данные, отправленные в очередь, из нее получаются.
     *
     * @throws InterruptedException в случае, если поток ждал, но был прерван.
     */
    @Test
    public void whenProducerGivesElementsThenComsumerGetsItAll() throws InterruptedException {
        final CopyOnWriteArrayList<Integer> buffer = new CopyOnWriteArrayList<>();
        final SimpleBlockingQueue<Integer> queue = new SimpleBlockingQueue<>();
        Thread producer = new Thread(
                () -> IntStream.range(0, 5).forEach(
                        (i) -> {
                            try {
                                queue.put(i);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                )
        );
        producer.start();
        Thread consumer = new Thread(
                () -> {
                    while (!queue.isEmpty() || !Thread.currentThread().isInterrupted()) {
                        try {
                            buffer.add(queue.poll());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            Thread.currentThread().interrupt();
                        }
                    }
                }
        );
        consumer.start();
        producer.join();
        consumer.interrupt();
        consumer.join();
        Assert.assertThat(buffer, is(Arrays.asList(0, 1, 2, 3, 4)));
    }
}


text:
<meta charset="UTF-8">
<title>Month - biomedicus-core</title>
<link rel="stylesheet" href="../../../style.css">

biomedicus-core / edu.umn.biomedicus.time / Month

Month

data class Month : Label

A month in text, e.g. "Jan", "February", "Sept."

Constructors

<init>

Month(<span class="identifier" id="edu.umn.biomedicus.time.Month$<init>(edu.umn.nlpengine.TextRange)/textRange">textRange: TextRange)Month(<span class="identifier" id="edu.umn.biomedicus.time.Month$<init>(kotlin.Int, kotlin.Int)/startIndex">startIndex: Int, <span class="identifier" id="edu.umn.biomedicus.time.Month$<init>(kotlin.Int, kotlin.Int)/endIndex">endIndex: Int)

A month in text, e.g. "Jan", "February", "Sept."

Properties

endIndex

val endIndex: Int

startIndex

val startIndex: Int


text:
<?php namespace Auth;

use Cartalyst\Sentry\Groups\Eloquent\Group as SentryGroup;

/**
* Group
*/
class Group extends SentryGroup
{

}


text:
# Client.Conference Property

Access to Conference Api

**Namespace:** Bandwidth.Net
**Assembly:** Bandwidth.Net (in Bandwidth.Net.dll) Version: 3.0.3

## Syntax

**C#**

``` C#
public IConference Conference { get; }
```

#### Property Value
Type: IConference

## See Also

#### Reference
Client Class
Bandwidth.Net Namespace


text:
/**
 * Operators and utilities used for style expressions
 * @module ol/style/expressions
 */

import PaletteTexture from '../webgl/PaletteTexture.js';
import {Uniforms} from '../renderer/webgl/TileLayer.js';
import {asArray, fromString, isStringColor} from '../color.js';

/**
 * Base type used for literal style parameters; can be a number literal or the output of an operator,
 * which in turns takes {@link import("./expressions.js").ExpressionValue} arguments.
 *
 * The following operators can be used:
 *
 * * Reading operators:
 *   * `['band', bandIndex, xOffset, yOffset]` For tile layers only. Fetches pixel values from band
 *     `bandIndex` of the source's data. The first `bandIndex` of the source data is `1`. Fetched values
 *     are in the 0..1 range. {@link import("../source/TileImage.js").default} sources have 4 bands: red,
 *     green, blue and alpha. {@link import("../source/DataTile.js").default} sources can have any number
 *     of bands, depending on the underlying data source and
 *     {@link import("../source/GeoTIFF.js").Options configuration}. `xOffset` and `yOffset` are optional
 *     and allow specifying pixel offsets for x and y. This is used for sampling data from neighboring pixels.
 *   * `['get', 'attributeName']` fetches a feature attribute (it will be prefixed by `a_` in the shader)
 *     Note: those will be taken from the attributes provided to the renderer
 *   * `['resolution']` returns the current resolution
 *   * `['time']` returns the time in seconds since the creation of the layer
 *   * `['var', 'varName']` fetches a value from the style variables, or 0 if undefined
 *   * `['zoom']` returns the current zoom level
 *
 * * Math operators:
 *   * `['*', value1, value2]` multiplies `value1` by `value2`
 *   * `['/', value1, value2]` divides `value1` by `value2`
 *   * `['+', value1, value2]` adds `value1` and `value2`
 *   * `['-', value1, value2]` subtracts `value2` from `value1`
 *   * `['clamp', value, low, high]` clamps `value` between `low` and `high`
 *   * `['%', value1, value2]` returns the result of `value1 % value2` (modulo)
 *   * `['^', value1, value2]` returns the value of `value1` raised to the `value2` power
 *   * `['abs', value1]` returns the absolute value of `value1`
 *   * `['floor', value1]` returns the nearest integer less than or equal to `value1`
 *   * `['round', value1]` returns the nearest integer to `value1`
 *   * `['ceil', value1]` returns the nearest integer greater than or equal to `value1`
 *   * `['sin', value1]` returns the sine of `value1`
 *   * `['cos', value1]` returns the cosine of `value1`
 *   * `['atan', value1, value2]` returns `atan2(value1, value2)`. If `value2` is not provided, returns `atan(value1)`
 *
 * * Transform operators:
 *   * `['case', condition1, output1, ...conditionN, outputN, fallback]` selects the first output whose corresponding
 *     condition evaluates to `true`. If no match is found, returns the `fallback` value.
 *     All conditions should be `boolean`, output and fallback can be any kind.
 *   * `['match', input, match1, output1, ...matchN, outputN, fallback]` compares the `input` value against all
 *     provided `matchX` values, returning the output associated with the first valid match. If no match is found,
 *     returns the `fallback` value.
 *     `input` and `matchX` values must all be of the same type, and can be `number` or `string`. `outputX` and
 *     `fallback` values must be of the same type, and can be of any kind.
 *   * `['interpolate', interpolation, input, stop1, output1, ...stopN, outputN]` returns a value by interpolating between
 *     pairs of inputs and outputs; `interpolation` can either be `['linear']` or `['exponential', base]` where `base` is
 *     the rate of increase from stop A to stop B (i.e. power to which the interpolation ratio is raised); a value
 *     of 1 is equivalent to `['linear']`.
 *     `input` and `stopX` values must all be of type `number`. `outputX` values can be `number` or `color` values.
 *     Note: `input` will be clamped between `stop1` and `stopN`, meaning that all output values will be comprised
 *     between `output1` and `outputN`.
 *
 * * Logical operators:
 *   * `['<', value1, value2]` returns `true` if `value1` is strictly lower than `value2`, or `false` otherwise.
 *   * `['<=', value1, value2]` returns `true` if `value1` is lower than or equals `value2`, or `false` otherwise.
 *   * `['>', value1, value2]` returns `true` if `value1` is strictly greater than `value2`, or `false` otherwise.
 *   * `['>=', value1, value2]` returns `true` if `value1` is greater than or equals `value2`, or `false` otherwise.
 *   * `['==', value1, value2]` returns `true` if `value1` equals `value2`, or `false` otherwise.
 *   * `['!=', value1, value2]` returns `true` if `value1` does not equal `value2`, or `false` otherwise.
 *   * `['!', value1]` returns `false` if `value1` is `true` or greater than `0`, or `true` otherwise.
 *   * `['all', value1, value2, ...]` returns `true` if all the inputs are `true`, `false` otherwise.
 *   * `['any', value1, value2, ...]` returns `true` if any of the inputs are `true`, `false` otherwise.
 *   * `['between', value1, value2, value3]` returns `true` if `value1` is contained between `value2` and `value3`
 *     (inclusively), or `false` otherwise.
 *
 * * Conversion operators:
 *   * `['array', value1, ...valueN]` creates a numerical array from `number` values; please note that the amount of
 *     values can currently only be 2, 3 or 4.
 *   * `['color', red, green, blue, alpha]` creates a `color` value from `number` values; the `alpha` parameter is
 *     optional; if not specified, it will be set to 1.
 *     Note: `red`, `green` and `blue` components must be values between 0 and 255; `alpha` between 0 and 1.
 *   * `['palette', index, colors]` picks a `color` value from an array of colors using the given index; the `index`
 *     expression must evaluate to a number; the items in the `colors` array must be strings with hex colors
 *     (e.g. `'#86A136'`), colors using the rgba[a] functional notation (e.g. `'rgb(134, 161, 54)'` or `'rgba(134, 161, 54, 1)'`),
 *     named colors (e.g. `'red'`), or array literals with 3 ([r, g, b]) or 4 ([r, g, b, a]) values (with r, g, and b
 *     in the 0-255 range and a in the 0-1 range).
 *
 * Values can either be literals or another operator, as they will be evaluated recursively.
 * Literal values can be of the following types:
 * * `boolean`
 * * `number`
 * * `string`
 * * {@link module:ol/color~Color}
 *
 * @typedef {Array<*>|import("../color.js").Color|string|number|boolean} ExpressionValue
 * @api
 */

/**
 * Possible inferred types from a given value or expression.
 * Note: these are binary flags.
 * @enum {number}
 */
export const ValueTypes = {
  NUMBER: 0b00001,
  STRING: 0b00010,
  COLOR: 0b00100,
  BOOLEAN: 0b01000,
  NUMBER_ARRAY: 0b10000,
  ANY: 0b11111,
  NONE: 0,
};

/**
 * An operator declaration must contain two methods: `getReturnType` which returns a type based on
 * the operator arguments, and `toGlsl` which returns a GLSL-compatible string.
 * Note: both methods can process arguments recursively.
 * @typedef {Object} Operator
 * @property {function(Array<ExpressionValue>): ValueTypes|number} getReturnType Returns one or several types
 * @property {function(ParsingContext, Array<ExpressionValue>, ValueTypes=): string} toGlsl Returns a GLSL-compatible string
 * Note: takes in an optional type hint as 3rd parameter
 */

/**
 * Operator declarations
 * @type {Object<string, Operator>}
 */
export const Operators = {};

/**
 * Returns the possible types for a given value (each type being a binary flag)
 * To test a value use e.g. `getValueType(v) & ValueTypes.BOOLEAN`
 * @param {ExpressionValue} value Value
 * @return {ValueTypes|number} Type or types inferred from the value
 */
export function getValueType(value) {
  if (typeof value === 'number') {
    return ValueTypes.NUMBER;
  }
  if (typeof value === 'boolean') {
    return ValueTypes.BOOLEAN;
  }
  if (typeof value === 'string') {
    if (isStringColor(value)) {
      return ValueTypes.COLOR | ValueTypes.STRING;
    }
    return ValueTypes.STRING;
  }
  if (!Array.isArray(value)) {
    throw new Error(`Unhandled value type: ${JSON.stringify(value)}`);
  }
  const valueArr = /** @type {Array<*>} */ (value);
  const onlyNumbers = valueArr.every(function (v) {
    return typeof v === 'number';
  });
  if (onlyNumbers) {
    if (valueArr.length === 3 || valueArr.length === 4) {
      return ValueTypes.COLOR | ValueTypes.NUMBER_ARRAY;
    }
    return ValueTypes.NUMBER_ARRAY;
  }
  if (typeof valueArr[0] !== 'string') {
    throw new Error(
      `Expected an expression operator but received: ${JSON.stringify(
        valueArr
      )}`
    );
  }
  const operator = Operators[valueArr[0]];
  if (operator === undefined) {
    throw new Error(
      `Unrecognized expression operator: ${JSON.stringify(valueArr)}`
    );
  }
  return operator.getReturnType(valueArr.slice(1));
}

/**
 * Checks if only one value type is enabled in the input number.
 * @param {ValueTypes|number} valueType Number containing value type binary flags
 * @return {boolean} True if only one type flag is enabled, false if zero or multiple
 */
export function isTypeUnique(valueType) {
  return Math.log2(valueType) % 1 === 0;
}

/**
 * Context available during the parsing of an expression.
 * @typedef {Object} ParsingContext
 * @property {boolean} [inFragmentShader] If false, means the expression output should be made for a vertex shader
 * @property {Array<string>} variables List of variables used in the expression; contains **unprefixed names**
 * @property {Array<string>} attributes List of attributes used in the expression; contains **unprefixed names**
 * @property {Object<string, number>} stringLiteralsMap This object maps all encountered string values to a number
 * @property {Object<string, string>} functions Lookup of functions used by the style.
 * @property {number} [bandCount] Number of bands per pixel.
 * @property {Array<PaletteTexture>} [paletteTextures] List of palettes used by the style.
 */

/**
 * Will return the number as a float with a dot separator, which is required by GLSL.
 * @param {number} v Numerical value.
 * @return {string} The value as string.
 */
export function numberToGlsl(v) {
  const s = v.toString();
  return s.includes('.') ? s : s + '.0';
}

/**
 * Will return the number array as a float with a dot separator, concatenated with ', '.
 * @param {Array<number>} array Numerical values array.
 * @return {string} The array as a vector, e. g.: `vec3(1.0, 2.0, 3.0)`.
 */
export function arrayToGlsl(array) {
  if (array.length < 2 || array.length > 4) {
    throw new Error(
      '`formatArray` can only output `vec2`, `vec3` or `vec4` arrays.'
    );
  }
  return `vec${array.length}(${array.map(numberToGlsl).join(', ')})`;
}

/**
 * Will normalize and converts to string a `vec4` color array compatible with GLSL.
 * @param {string|import("../color.js").Color} color Color either in string format or [r, g, b, a] array format,
 * with RGB components in the 0..255 range and the alpha component in the 0..1 range.
 * Note that the final array will always have 4 components.
 * @return {string} The color expressed in the `vec4(1.0, 1.0, 1.0, 1.0)` form.
 */
export function colorToGlsl(color) {
  const array = asArray(color).slice();
  if (array.length < 4) {
    array.push(1);
  }
  return arrayToGlsl(
    array.map(function (c, i) {
      return i < 3 ? c / 255 : c;
    })
  );
}

/**
 * Returns a stable equivalent number for the string literal.
 * @param {ParsingContext} context Parsing context
 * @param {string} string String literal value
 * @return {number} Number equivalent
 */
export function getStringNumberEquivalent(context, string) {
  if (context.stringLiteralsMap[string] === undefined) {
    context.stringLiteralsMap[string] = Object.keys(
      context.stringLiteralsMap
    ).length;
  }
  return context.stringLiteralsMap[string];
}

/**
 * Returns a stable equivalent number for the string literal, for use in shaders. This number is then
 * converted to be a GLSL-compatible string.
 * @param {ParsingContext} context Parsing context
 * @param {string} string String literal value
 * @return {string} GLSL-compatible string containing a number
 */
export function stringToGlsl(context, string) {
  return numberToGlsl(getStringNumberEquivalent(context, string));
}

/**
 * Recursively parses a style expression and outputs a GLSL-compatible string. Takes in a parsing context that
 * will be read and modified during the parsing operation.
 * @param {ParsingContext} context Parsing context
 * @param {ExpressionValue} value Value
 * @param {ValueTypes|number} [typeHint] Hint for the expected final type (can be several types combined)
 * @return {string} GLSL-compatible output
 */
export function expressionToGlsl(context, value, typeHint) {
  // operator
  if (Array.isArray(value) && typeof value[0] === 'string') {
    const operator = Operators[value[0]];
    if (operator === undefined) {
      throw new Error(
        `Unrecognized expression operator: ${JSON.stringify(value)}`
      );
    }
    return operator.toGlsl(context, value.slice(1), typeHint);
  }

  const valueType = getValueType(value);
  if ((valueType & ValueTypes.NUMBER) > 0) {
    return numberToGlsl(/** @type {number} */ (value));
  }

  if ((valueType & ValueTypes.BOOLEAN) > 0) {
    return value.toString();
  }

  if (
    (valueType & ValueTypes.STRING) > 0 &&
    (typeHint === undefined || typeHint == ValueTypes.STRING)
  ) {
    return stringToGlsl(context, value.toString());
  }

  if (
    (valueType & ValueTypes.COLOR) > 0 &&
    (typeHint === undefined || typeHint == ValueTypes.COLOR)
  ) {
    return colorToGlsl(/** @type {Array<number> | string} */ (value));
  }

  if ((valueType & ValueTypes.NUMBER_ARRAY) > 0) {
    return arrayToGlsl(/** @type {Array<number>} */ (value));
  }

  throw new Error(`Unexpected expression ${value} (expected type ${typeHint})`);
}

function assertNumber(value) {
  if (!(getValueType(value) & ValueTypes.NUMBER)) {
    throw new Error(
      `A numeric value was expected, got ${JSON.stringify(value)} instead`
    );
  }
}
function assertNumbers(values) {
  for (let i = 0; i < values.length; i++) {
    assertNumber(values[i]);
  }
}
function assertString(value) {
  if (!(getValueType(value) & ValueTypes.STRING)) {
    throw new Error(
      `A string value was expected, got ${JSON.stringify(value)} instead`
    );
  }
}
function assertBoolean(value) {
  if (!(getValueType(value) & ValueTypes.BOOLEAN)) {
    throw new Error(
      `A boolean value was expected, got ${JSON.stringify(value)} instead`
    );
  }
}
function assertArgsCount(args, count) {
  if (args.length !== count) {
    throw new Error(
      `Exactly ${count} arguments were expected, got ${args.length} instead`
    );
  }
}
function assertArgsMinCount(args, count) {
  if (args.length < count) {
    throw new Error(
      `At least ${count} arguments were expected, got ${args.length} instead`
    );
  }
}
function assertArgsMaxCount(args, count) {
  if (args.length > count) {
    throw new Error(
      `At most ${count} arguments were expected, got ${args.length} instead`
    );
  }
}
function assertArgsEven(args) {
  if (args.length % 2 !== 0) {
    throw new Error(
      `An even amount of arguments was expected, got ${args} instead`
    );
  }
}
function assertArgsOdd(args) {
  if (args.length % 2 === 0) {
    throw new Error(
      `An odd amount of arguments was expected, got ${args} instead`
    );
  }
}
function assertUniqueInferredType(args, types) {
  if (!isTypeUnique(types)) {
    throw new Error(
      `Could not infer only one type from the following expression: ${JSON.stringify(
        args
      )}`
    );
  }
}

Operators['get'] = {
  getReturnType: function (args) {
    return ValueTypes.ANY;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertString(args[0]);
    const value = args[0].toString();
    if (!context.attributes.includes(value)) {
      context.attributes.push(value);
    }
    const prefix = context.inFragmentShader ? 'v_' : 'a_';
    return prefix + value;
  },
};

/**
 * Get the uniform name given a variable name.
 * @param {string} variableName The variable name.
 * @return {string} The uniform name.
 */
export function uniformNameForVariable(variableName) {
  return 'u_var_' + variableName;
}

Operators['var'] = {
  getReturnType: function (args) {
    return ValueTypes.ANY;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertString(args[0]);
    const value = args[0].toString();
    if (!context.variables.includes(value)) {
      context.variables.push(value);
    }
    return uniformNameForVariable(value);
  },
};

export const PALETTE_TEXTURE_ARRAY = 'u_paletteTextures';

// ['palette', index, colors]
Operators['palette'] = {
  getReturnType: function (args) {
    return ValueTypes.COLOR;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumber(args[0]);
    const index = expressionToGlsl(context, args[0]);
    const colors = args[1];
    if (!Array.isArray(colors)) {
      throw new Error('The second argument of palette must be an array');
    }
    const numColors = colors.length;
    const palette = new Uint8Array(numColors * 4);
    for (let i = 0; i < numColors; i++) {
      const candidate = colors[i];
      /**
       * @type {import('../color.js').Color}
       */
      let color;
      if (typeof candidate === 'string') {
        color = fromString(candidate);
      } else {
        if (!Array.isArray(candidate)) {
          throw new Error(
            'The second argument of palette must be an array of strings or colors'
          );
        }
        const length = candidate.length;
        if (length === 4) {
          color = candidate;
        } else {
          if (length !== 3) {
            throw new Error(
              `Expected palette color to have 3 or 4 values, got ${length}`
            );
          }
          color = [candidate[0], candidate[1], candidate[2], 1];
        }
      }
      const offset = i * 4;
      palette[offset] = color[0];
      palette[offset + 1] = color[1];
      palette[offset + 2] = color[2];
      palette[offset + 3] = color[3] * 255;
    }
    if (!context.paletteTextures) {
      context.paletteTextures = [];
    }
    const paletteName = `${PALETTE_TEXTURE_ARRAY}[${context.paletteTextures.length}]`;
    const paletteTexture = new PaletteTexture(paletteName, palette);
    context.paletteTextures.push(paletteTexture);
    return `texture2D(${paletteName}, vec2((${index} + 0.5) / ${numColors}.0, 0.5))`;
  },
};

const GET_BAND_VALUE_FUNC = 'getBandValue';

Operators['band'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsMinCount(args, 1);
    assertArgsMaxCount(args, 3);
    const band = args[0];

    if (!(GET_BAND_VALUE_FUNC in context.functions)) {
      let ifBlocks = '';
      const bandCount = context.bandCount || 1;
      for (let i = 0; i < bandCount; i++) {
        const colorIndex = Math.floor(i / 4);
        let bandIndex = i % 4;
        if (i === bandCount - 1 && bandIndex === 1) {
          // LUMINANCE_ALPHA - band 1 assigned to rgb and band 2 assigned to alpha
          bandIndex = 3;
        }
        const textureName = `${Uniforms.TILE_TEXTURE_ARRAY}[${colorIndex}]`;
        ifBlocks += `
          if (band == ${i + 1}.0) {
            return texture2D(${textureName}, v_textureCoord + vec2(dx, dy))[${bandIndex}];
          }
        `;
      }

      context.functions[GET_BAND_VALUE_FUNC] = `
        float getBandValue(float band, float xOffset, float yOffset) {
          float dx = xOffset / ${Uniforms.TEXTURE_PIXEL_WIDTH};
          float dy = yOffset / ${Uniforms.TEXTURE_PIXEL_HEIGHT};
          ${ifBlocks}
        }
      `;
    }

    const bandExpression = expressionToGlsl(context, band);
    const xOffsetExpression = expressionToGlsl(context, args[1] || 0);
    const yOffsetExpression = expressionToGlsl(context, args[2] || 0);
    return `${GET_BAND_VALUE_FUNC}(${bandExpression}, ${xOffsetExpression}, ${yOffsetExpression})`;
  },
};

Operators['time'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 0);
    return 'u_time';
  },
};

Operators['zoom'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 0);
    return 'u_zoom';
  },
};

Operators['resolution'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 0);
    return 'u_resolution';
  },
};

Operators['*'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} * ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['/'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} / ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['+'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} + ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['-'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} - ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['clamp'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 3);
    assertNumbers(args);
    const min = expressionToGlsl(context, args[1]);
    const max = expressionToGlsl(context, args[2]);
    return `clamp(${expressionToGlsl(context, args[0])}, ${min}, ${max})`;
  },
};

Operators['%'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `mod(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['^'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `pow(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['abs'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `abs(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['floor'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `floor(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['round'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `floor(${expressionToGlsl(context, args[0])} + 0.5)`;
  },
};

Operators['ceil'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `ceil(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['sin'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `sin(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['cos'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertNumbers(args);
    return `cos(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['atan'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER;
  },
  toGlsl: function (context, args) {
    assertArgsMinCount(args, 1);
    assertArgsMaxCount(args, 2);
    assertNumbers(args);
    return args.length === 2
      ? `atan(${expressionToGlsl(context, args[0])}, ${expressionToGlsl(
          context,
          args[1]
        )})`
      : `atan(${expressionToGlsl(context, args[0])})`;
  },
};

Operators['>'] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} > ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['>='] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} >= ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['<'] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} < ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

Operators['<='] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 2);
    assertNumbers(args);
    return `(${expressionToGlsl(context, args[0])} <= ${expressionToGlsl(
      context,
      args[1]
    )})`;
  },
};

function getEqualOperator(operator) {
  return {
    getReturnType: function (args) {
      return ValueTypes.BOOLEAN;
    },
    toGlsl: function (context, args) {
      assertArgsCount(args, 2);

      // find common type
      let type = ValueTypes.ANY;
      for (let i = 0; i < args.length; i++) {
        type &= getValueType(args[i]);
      }
      if (type === ValueTypes.NONE) {
        throw new Error(
          `All arguments should be of compatible type, got ${JSON.stringify(
            args
          )} instead`
        );
      }

      // Since it's not possible to have color types here, we can leave it out
      // This fixes issues in case the value type is ambiguously detected as a color (e.g. the string 'red')
      type &= ~ValueTypes.COLOR;

      return `(${expressionToGlsl(
        context,
        args[0],
        type
      )} ${operator} ${expressionToGlsl(context, args[1], type)})`;
    },
  };
}

Operators['=='] = getEqualOperator('==');

Operators['!='] = getEqualOperator('!=');

Operators['!'] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 1);
    assertBoolean(args[0]);
    return `(!${expressionToGlsl(context, args[0])})`;
  },
};

function getDecisionOperator(operator) {
  return {
    getReturnType: function (args) {
      return ValueTypes.BOOLEAN;
    },
    toGlsl: function (context, args) {
      assertArgsMinCount(args, 2);
      for (let i = 0; i < args.length; i++) {
        assertBoolean(args[i]);
      }
      let result = '';
      result = args
        .map((arg) => expressionToGlsl(context, arg))
        .join(` ${operator} `);
      result = `(${result})`;
      return result;
    },
  };
}

Operators['all'] = getDecisionOperator('&&');

Operators['any'] = getDecisionOperator('||');

Operators['between'] = {
  getReturnType: function (args) {
    return ValueTypes.BOOLEAN;
  },
  toGlsl: function (context, args) {
    assertArgsCount(args, 3);
    assertNumbers(args);
    const min = expressionToGlsl(context, args[1]);
    const max = expressionToGlsl(context, args[2]);
    const value = expressionToGlsl(context, args[0]);
    return `(${value} >= ${min} && ${value} <= ${max})`;
  },
};

Operators['array'] = {
  getReturnType: function (args) {
    return ValueTypes.NUMBER_ARRAY;
  },
  toGlsl: function (context, args) {
    assertArgsMinCount(args, 2);
    assertArgsMaxCount(args, 4);
    assertNumbers(args);
    const parsedArgs = args.map(function (val) {
      return expressionToGlsl(context, val, ValueTypes.NUMBER);
    });
    return `vec${args.length}(${parsedArgs.join(', ')})`;
  },
};

Operators['color'] = {
  getReturnType: function (args) {
    return ValueTypes.COLOR;
  },
  toGlsl: function (context, args) {
    assertArgsMinCount(args, 3);
    assertArgsMaxCount(args, 4);
    assertNumbers(args);
    const array = /** @type {Array<number>} */ (args);
    if (args.length === 3) {
      array.push(1);
    }
    const parsedArgs = args.map(function (val, i) {
      return (
        expressionToGlsl(context, val, ValueTypes.NUMBER) +
        (i < 3 ? ' / 255.0' : '')
      );
    });
    return `vec${args.length}(${parsedArgs.join(', ')})`;
  },
};

Operators['interpolate'] = {
  getReturnType: function (args) {
    let type = ValueTypes.COLOR | ValueTypes.NUMBER;
    for (let i = 3; i < args.length; i += 2) {
      type = type & getValueType(args[i]);
    }
    return type;
  },
  toGlsl: function (context, args, typeHint) {
    assertArgsEven(args);
    assertArgsMinCount(args, 6);

    // validate interpolation type
    const type = args[0];
    let interpolation;
    switch (type[0]) {
      case 'linear':
        interpolation = 1;
        break;
      case 'exponential':
        interpolation = type[1];
        break;
      default:
        interpolation = null;
    }
    if (!interpolation) {
      throw new Error(
        `Invalid interpolation type for "interpolate" operator, received: ${JSON.stringify(
          type
        )}`
      );
    }

    // compute input/output types
    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
    const outputType = Operators['interpolate'].getReturnType(args) & typeHint;
    assertUniqueInferredType(args, outputType);

    const input = expressionToGlsl(context, args[1]);
    const exponent = numberToGlsl(interpolation);

    let result = '';
    for (let i = 2; i < args.length - 2; i += 2) {
      const stop1 = expressionToGlsl(context, args[i]);
      const output1 =
        result || expressionToGlsl(context, args[i + 1], outputType);
      const stop2 = expressionToGlsl(context, args[i + 2]);
      const output2 = expressionToGlsl(context, args[i + 3], outputType);
      result = `mix(${output1}, ${output2}, pow(clamp((${input} - ${stop1}) / (${stop2} - ${stop1}), 0.0, 1.0), ${exponent}))`;
    }
    return result;
  },
};

Operators['match'] = {
  getReturnType: function (args) {
    let type = ValueTypes.ANY;
    for (let i = 2; i < args.length; i += 2) {
      type = type & getValueType(args[i]);
    }
    type = type & getValueType(args[args.length - 1]);
    return type;
  },
  toGlsl: function (context, args, typeHint) {
    assertArgsEven(args);
    assertArgsMinCount(args, 4);

    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
    const outputType = Operators['match'].getReturnType(args) & typeHint;
    assertUniqueInferredType(args, outputType);

    const input = expressionToGlsl(context, args[0]);
    const fallback = expressionToGlsl(
      context,
      args[args.length - 1],
      outputType
    );
    let result = null;
    for (let i = args.length - 3; i >= 1; i -= 2) {
      const match = expressionToGlsl(context, args[i]);
      const output = expressionToGlsl(context, args[i + 1], outputType);
      result = `(${input} == ${match} ? ${output} : ${result || fallback})`;
    }
    return result;
  },
};

Operators['case'] = {
  getReturnType: function (args) {
    let type = ValueTypes.ANY;
    for (let i = 1; i < args.length; i += 2) {
      type = type & getValueType(args[i]);
    }
    type = type & getValueType(args[args.length - 1]);
    return type;
  },
  toGlsl: function (context, args, typeHint) {
    assertArgsOdd(args);
    assertArgsMinCount(args, 3);

    typeHint = typeHint !== undefined ? typeHint : ValueTypes.ANY;
    const outputType = Operators['case'].getReturnType(args) & typeHint;
    assertUniqueInferredType(args, outputType);
    for (let i = 0; i < args.length - 1; i += 2) {
      assertBoolean(args[i]);
    }

    const fallback = expressionToGlsl(
      context,
      args[args.length - 1],
      outputType
    );
    let result = null;
    for (let i = args.length - 3; i >= 0; i -= 2) {
      const condition = expressionToGlsl(context, args[i]);
      const output = expressionToGlsl(context, args[i + 1], outputType);
      result = `(${condition} ? ${output} : ${result || fallback})`;
    }
    return result;
  },
};


text:
import os
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'static')
MEDIA_URL = '/static/'
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'testdb.sqlite'
SITE_ID = 1
DEBUG = True

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.request',
)

ROOT_URLCONF = 'urls'

TEMPLATE_DIRS = (
    PROJECT_PATH + '/templates',
)

FIXTURE_DIRS = ['fixtures']

ADMIN_TOOLS_INDEX_DASHBOARD = 'test_proj.dashboard.CustomIndexDashboard'
ADMIN_TOOLS_MENU = 'test_proj.menu.CustomMenu'

INSTALLED_APPS = [
    'admin_tools',
    'admin_tools.theming',
    'admin_tools.menu',
    'admin_tools.dashboard',

    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',

    'test_app',
]

try:
    import django_coverage
    TEST_RUNNER = 'django_coverage.coverage_runner.run_tests'
    COVERAGE_REPORT_HTML_OUTPUT_DIR = os.path.join(PROJECT_PATH, '_coverage')
except ImportError:
    pass


text:
package org.apache.wicket.validation.validator;

import java.util.Locale;

import org.apache.wicket.Component;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.ValidationError;

/**
 * Validator for checking if length of a string falls within [min,max] range.
 *
 * If either min or max are {@code null} they are not checked.
 *
 *

 * If the component is attached to an {@code input} tag, a {@code maxlen} attribute will be added if
 * the maximum is set.
 *
 * *
 *

 * Resource keys:
 *

 *
{@code StringValidator.exact} if min==max ({@link #exactLength(int)})

 *
{@code StringValidator.range} if both min and max are not {@code null}

 *
{@code StringValidator.minimum} if max is {@code null} ({@link #minimumLength(int)})

 *
{@code StringValidator.maximum} if min is {@code null} ({@link #maximumLength(int)})

 *

 *

 *
 *

 * Error Message Variables:
 *

 *
{@code name}: the id of {@code Component} that failed

 *
{@code label}: the label of the {@code Component} (either comes from
 * {@code FormComponent.labelModel} or resource key {@code <form-id>.<form-component-id>}

 *
{@code input}: the input value

 *
{@code length}: the length of the entered

 *
{@code minimum}: the minimum alloed length

 *
{@code maximum}: the maximum allowed length

 *

 *

 *
 * @author igor
 */
public class StringValidator extends AbstractRangeValidator<Integer, String>
{
	private static final long serialVersionUID = 1L;

	/**
	 * Constructor that sets the minimum and maximum length values.
	 *
	 * @param minimum
	 *            the minimum lenghh
	 * @param maximum
	 *            the maximum length
	 */
	public StringValidator(Integer minimum, Integer maximum)
	{
		setRange(minimum, maximum);
	}

	/**
	 * Constructor used for subclasses who want to set the range using
	 * {@link #setRange(Comparable, Comparable)}
	 */
	protected StringValidator()
	{
	}

	@Override
	protected Integer getValue(IValidatable<String> validatable)
	{
		return validatable.getValue().length();
	}

	@Override
	protected ValidationError decorate(ValidationError error, IValidatable<String> validatable)
	{
		error = super.decorate(error, validatable);
		error.setVariable("length", validatable.getValue().length());
		return error;
	}

	@Override
	public void onComponentTag(Component component, ComponentTag tag)
	{
		super.onComponentTag(component, tag);

		String tagName = tag.getName().toLowerCase(Locale.ENGLISH);
		boolean hasLengthAttribute = hasLengthAttribute(tagName);

		Integer maximum = getMaximum();
		if (maximum != null && hasLengthAttribute)
		{
			tag.put("maxlength", maximum);
		}

		Integer minimum = getMinimum();
		if (minimum != null && hasLengthAttribute)
		{
			tag.put("minlength", minimum);
		}
	}

	private boolean hasLengthAttribute(String tagName)
	{
		return "input".equalsIgnoreCase(tagName) || "textarea".equalsIgnoreCase(tagName);
	}

	/**
	 * @param length
	 * @return a {@link StringValidator} that generates an error if a string is not of an exact
	 *         length
	 */
	public static StringValidator exactLength(int length)
	{
		return new StringValidator(length, length);
	}

	/**
	 * @param length
	 * @return a {@link StringValidator} that generates an error if a string exceeds a maximum
	 *         length
	 */
	public static StringValidator maximumLength(int length)
	{
		return new StringValidator(null, length);
	}

	/**
	 * @param length
	 * @return a {@link StringValidator} that generates an error if a string is not of a minimum
	 *         length
	 */
	public static StringValidator minimumLength(int length)
	{
		return new StringValidator(length, null);
	}

	/**
	 * @param minimum
	 * @param maximum
	 * @return a {@link StringValidator} that generates an error if the length of a string is not
	 *         between (inclusive) minimum and maximum
	 */
	public static StringValidator lengthBetween(int minimum, int maximum)
	{
		return new StringValidator(minimum, maximum);
	}

}


text:
package de.tudarmstadt.ukp.clarin.webanno.support.lambda;

import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.cycle.IRequestCycleListener;
import org.apache.wicket.request.cycle.RequestCycle;
import org.danekja.java.util.function.serializable.SerializableSupplier;

@Deprecated
public class LambdaModel<T>
    extends LoadableDetachableModel<T>
{
    private static final long serialVersionUID = -1455152622735082623L;

    private final SerializableSupplier<T> supplier;
    private boolean autoDetach;

    public LambdaModel(SerializableSupplier<T> aSupplier)
    {
        supplier = aSupplier;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected T load()
    {
        Object value = supplier.get();
        if (value instanceof IModel) {
            return ((IModel<T>) value).getObject();
        }
        else {
            return (T) value;
        }
    }

    public LambdaModel<T> autoDetaching()
    {
        autoDetach = true;
        return this;
    }

    @Override
    protected void onAttach()
    {
        if (autoDetach) {
            RequestCycle.get().getListeners().add(new IRequestCycleListener()
            {
                @Override
                public void onDetach(RequestCycle aCycle)
                {
                    LambdaModel.this.detach();
                }
            });
        }
    }
}


text:
using System;
using System.Runtime.InteropServices;

namespace DbgEng
{
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct _DEBUG_STACK_FRAME_EX
	{
		public ulong InstructionOffset;

		public ulong ReturnOffset;

		public ulong FrameOffset;

		public ulong StackOffset;

		public ulong FuncTableEntry;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
		public ulong[] Params;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
		public ulong[] Reserved;

		public int Virtual;

		public uint FrameNumber;

		public uint InlineFrameContext;

		public uint Reserved1;
	}
}


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>edu.javacourse</groupId>
        <artifactId>examples</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../</relativePath>
    </parent>

    <groupId>edu.javacourse.zk</groupId>
    <artifactId>ZKExample04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>ZK ZKExample04</name>

    <dependencies>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zk</artifactId>
        </dependency>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.zkoss.zk</groupId>
            <artifactId>zkplus</artifactId>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
        </dependency>
    </dependencies>

</project>


text:
// +k8s:deepcopy-gen=package
// +k8s:protobuf-gen=package
// +k8s:openapi-gen=true
// +groupName=admissionregistration.k8s.io

// Package v1alpha1 is the v1alpha1 version of the API.
package v1alpha1 // import "k8s.io/api/admissionregistration/v1alpha1"