text:
\hypertarget{classCassandraConnectionFailedException}{
\section{CassandraConnectionFailedException Class Reference}
\label{classCassandraConnectionFailedException}\index{CassandraConnectionFailedException@{CassandraConnectionFailedException}}
}

\subsection{Detailed Description}
Thrown if no \hyperlink{classCassandra}{Cassandra} connection could be opened.

Definition at line 3638 of file Cassandra.php.

The documentation for this class was generated from the following file:\begin{DoxyCompactItemize}
\item
Cassandra.php\end{DoxyCompactItemize}


text:
#ifndef AERON_DRIVER_AGENT_H
#define AERON_DRIVER_AGENT_H

#include "aeron_driver_conductor.h"
#include "command/aeron_control_protocol.h"

#define AERON_EVENT_LOG_ENV_VAR "AERON_EVENT_LOG"
#define AERON_EVENT_LOG_DISABLE_ENV_VAR "AERON_EVENT_LOG_DISABLE"
#define AERON_EVENT_LOG_FILENAME_ENV_VAR "AERON_EVENT_LOG_FILENAME"
#define AERON_EVENT_RB_LENGTH (8 * 1024 * 1024)
#define AERON_MAX_CMD_LENGTH (512)
#define AERON_MAX_FRAME_LENGTH (1408)

#define AERON_DRIVER_AGENT_LOG_CONTEXT "DRIVER"
#define AERON_DRIVER_AGENT_ALL_EVENTS "all"
#define AERON_DRIVER_AGENT_ADMIN_EVENTS "admin"
#define AERON_DRIVER_AGENT_EVENT_UNKNOWN_NAME "unknown"

typedef enum aeron_driver_agent_event_enum
{
    AERON_DRIVER_EVENT_FRAME_IN = 1,
    AERON_DRIVER_EVENT_FRAME_OUT = 2,
    AERON_DRIVER_EVENT_CMD_IN_ADD_PUBLICATION = 3,
    AERON_DRIVER_EVENT_CMD_IN_REMOVE_PUBLICATION = 4,
    AERON_DRIVER_EVENT_CMD_IN_ADD_SUBSCRIPTION = 5,
    AERON_DRIVER_EVENT_CMD_IN_REMOVE_SUBSCRIPTION = 6,
    AERON_DRIVER_EVENT_CMD_OUT_PUBLICATION_READY = 7,
    AERON_DRIVER_EVENT_CMD_OUT_AVAILABLE_IMAGE = 8,
    AERON_DRIVER_EVENT_CMD_OUT_ON_OPERATION_SUCCESS = 12,
    AERON_DRIVER_EVENT_CMD_IN_KEEPALIVE_CLIENT = 13,
    AERON_DRIVER_EVENT_REMOVE_PUBLICATION_CLEANUP = 14,
    AERON_DRIVER_EVENT_REMOVE_SUBSCRIPTION_CLEANUP = 15,
    AERON_DRIVER_EVENT_REMOVE_IMAGE_CLEANUP = 16,
    AERON_DRIVER_EVENT_CMD_OUT_ON_UNAVAILABLE_IMAGE = 17,
    AERON_DRIVER_EVENT_SEND_CHANNEL_CREATION = 23,
    AERON_DRIVER_EVENT_RECEIVE_CHANNEL_CREATION = 24,
    AERON_DRIVER_EVENT_SEND_CHANNEL_CLOSE = 25,
    AERON_DRIVER_EVENT_RECEIVE_CHANNEL_CLOSE = 26,
    AERON_DRIVER_EVENT_CMD_IN_ADD_DESTINATION = 30,
    AERON_DRIVER_EVENT_CMD_IN_REMOVE_DESTINATION = 31,
    AERON_DRIVER_EVENT_CMD_IN_ADD_EXCLUSIVE_PUBLICATION = 32,
    AERON_DRIVER_EVENT_CMD_OUT_EXCLUSIVE_PUBLICATION_READY = 33,
    AERON_DRIVER_EVENT_CMD_OUT_ERROR = 34,
    AERON_DRIVER_EVENT_CMD_IN_ADD_COUNTER = 35,
    AERON_DRIVER_EVENT_CMD_IN_REMOVE_COUNTER = 36,
    AERON_DRIVER_EVENT_CMD_OUT_SUBSCRIPTION_READY = 37,
    AERON_DRIVER_EVENT_CMD_OUT_COUNTER_READY = 38,
    AERON_DRIVER_EVENT_CMD_OUT_ON_UNAVAILABLE_COUNTER = 39,
    AERON_DRIVER_EVENT_CMD_IN_CLIENT_CLOSE = 40,
    AERON_DRIVER_EVENT_CMD_IN_ADD_RCV_DESTINATION = 41,
    AERON_DRIVER_EVENT_CMD_IN_REMOVE_RCV_DESTINATION = 42,
    AERON_DRIVER_EVENT_CMD_OUT_ON_CLIENT_TIMEOUT = 43,
    AERON_DRIVER_EVENT_CMD_IN_TERMINATE_DRIVER = 44,
    AERON_DRIVER_EVENT_UNTETHERED_SUBSCRIPTION_STATE_CHANGE = 45,
    AERON_DRIVER_EVENT_NAME_RESOLUTION_NEIGHBOR_ADDED = 46,
    AERON_DRIVER_EVENT_NAME_RESOLUTION_NEIGHBOR_REMOVED = 47,
    AERON_DRIVER_EVENT_FLOW_CONTROL_RECEIVER_ADDED = 48,
    AERON_DRIVER_EVENT_FLOW_CONTROL_RECEIVER_REMOVED = 49,
    AERON_DRIVER_EVENT_NAME_RESOLUTION_RESOLVE = 50,

    // C-specific events. Note: event IDs are dynamic to avoid gaps in the sparse arrays.
    AERON_DRIVER_EVENT_ADD_DYNAMIC_DISSECTOR,
    AERON_DRIVER_EVENT_DYNAMIC_DISSECTOR_EVENT,

    AERON_DRIVER_EVENT_NUM_ELEMENTS, // number of elements in this enum (including gaps)
    AERON_DRIVER_EVENT_UNKNOWN_EVENT = -1
}
aeron_driver_agent_event_t;

typedef struct aeron_driver_agent_log_header_stct
{
    int64_t time_ns;
}
aeron_driver_agent_log_header_t;

typedef struct aeron_driver_agent_cmd_log_header_stct
{
    int64_t time_ns;
    int64_t cmd_id;
}
aeron_driver_agent_cmd_log_header_t;

typedef struct aeron_driver_agent_frame_log_header_stct
{
    int64_t time_ns;
    int32_t result;
    int32_t sockaddr_len;
    int32_t message_len;
}
aeron_driver_agent_frame_log_header_t;

typedef struct aeron_driver_agent_untethered_subscription_state_change_log_header_stct
{
    int64_t time_ns;
    int64_t subscription_id;
    int32_t stream_id;
    int32_t session_id;
    aeron_subscription_tether_state_t old_state;
    aeron_subscription_tether_state_t new_state;
}
aeron_driver_agent_untethered_subscription_state_change_log_header_t;

typedef struct aeron_driver_agent_remove_resource_cleanup_stct
{
    int64_t time_ns;
    int64_t id;
    int32_t stream_id;
    int32_t session_id;
    int32_t channel_length;
}
aeron_driver_agent_remove_resource_cleanup_t;

typedef struct aeron_driver_agent_on_endpoint_change_stct
{
    int64_t time_ns;
    struct sockaddr_storage local_data;
    struct sockaddr_storage remote_data;
    uint8_t multicast_ttl;
}
aeron_driver_agent_on_endpoint_change_t;

typedef void (*aeron_driver_agent_generic_dissector_func_t)(
    FILE *fpout, const char *log_header_str, const void *message, size_t len);

typedef struct aeron_driver_agent_add_dissector_header_stct
{
    int64_t time_ns;
    int64_t index;
    aeron_driver_agent_generic_dissector_func_t dissector_func;
}
aeron_driver_agent_add_dissector_header_t;

typedef struct aeron_driver_agent_dynamic_event_header_stct
{
    int64_t time_ns;
    int64_t index;
}
aeron_driver_agent_dynamic_event_header_t;

typedef struct aeron_driver_agent_flow_control_receiver_change_log_header_stct
{
    int64_t time_ns;
    int64_t receiver_id;
    int32_t session_id;
    int32_t stream_id;
    int32_t channel_length;
    int32_t receiver_count;
}
aeron_driver_agent_flow_control_receiver_change_log_header_t;

typedef struct aeron_driver_agent_name_resolver_resolve_log_header_stct
{
    int64_t time_ns;
    int32_t resolver_name_length;
    int32_t hostname_length;
    int32_t address_length;
}
aeron_driver_agent_name_resolver_resolve_log_header_t;

aeron_mpsc_rb_t *aeron_driver_agent_mpsc_rb(void);

typedef int (*aeron_driver_context_init_t)(aeron_driver_context_t **);

int aeron_driver_agent_context_init(aeron_driver_context_t *context);

const char *aeron_driver_agent_dissect_log_header(
    int64_t time_ns,
    aeron_driver_agent_event_t event_id,
    size_t capture_length,
    size_t message_length);

const char *aeron_driver_agent_dissect_log_start(int64_t time_ns, int64_t time_ms);

void aeron_driver_agent_log_dissector(int32_t msg_type_id, const void *message, size_t length, void *clientd);

int aeron_driver_agent_init_logging_events_interceptors(aeron_driver_context_t *context);

void aeron_driver_agent_logging_ring_buffer_init(void);

void aeron_driver_agent_logging_ring_buffer_free(void);

bool aeron_driver_agent_logging_events_init(const char *event_log, const char *event_log_disable);

void aeron_driver_agent_logging_events_free(void);

bool aeron_driver_agent_is_event_enabled(aeron_driver_agent_event_t id);

const char *aeron_driver_agent_event_name(aeron_driver_agent_event_t id);

void aeron_driver_agent_untethered_subscription_state_change_interceptor(
    aeron_tetherable_position_t *tetherable_position,
    int64_t now_ns,
    aeron_subscription_tether_state_t new_state,
    int32_t stream_id,
    int32_t session_id);

void aeron_driver_agent_name_resolution_on_neighbor_added(const struct sockaddr_storage *addr);

void aeron_driver_agent_name_resolution_on_neighbor_removed(const struct sockaddr_storage *addr);

void aeron_driver_agent_remove_publication_cleanup(
    int32_t session_id, int32_t stream_id, size_t channel_length, const char *channel);

void aeron_driver_agent_remove_subscription_cleanup(
    int64_t id, int32_t stream_id, size_t channel_length, const char *channel);

void aeron_driver_agent_remove_image_cleanup(
    int64_t id, int32_t session_id, int32_t stream_id, size_t channel_length, const char *channel);

void aeron_driver_agent_conductor_to_driver_interceptor(
    int32_t msg_type_id, const void *message, size_t length, void *clientd);

void aeron_driver_agent_conductor_to_client_interceptor(
    aeron_driver_conductor_t *conductor, int32_t msg_type_id, const void *message, size_t length);

void aeron_driver_agent_log_frame(
    int32_t msg_type_id, const struct msghdr *msghdr, int result, int32_t message_len);

void aeron_driver_agent_sender_proxy_on_add_endpoint(const void *channel);

void aeron_driver_agent_sender_proxy_on_remove_endpoint(const void *channel);

void aeron_driver_agent_receiver_proxy_on_add_endpoint(const void *channel);

void aeron_driver_agent_receiver_proxy_on_remove_endpoint(const void *channel);

int64_t aeron_driver_agent_add_dynamic_dissector(aeron_driver_agent_generic_dissector_func_t func);

void aeron_driver_agent_log_dynamic_event(int64_t index, const void *message, size_t length);

void aeron_driver_agent_flow_control_on_receiver_added(
    int64_t receiver_id,
    int32_t session_id,
    int32_t stream_id,
    size_t channel_length,
    const char *channel,
    size_t receiver_count);

void aeron_driver_agent_flow_control_on_receiver_removed(
    int64_t receiver_id,
    int32_t session_id,
    int32_t stream_id,
    size_t channel_length,
    const char *channel,
    size_t receiver_count);

#endif //AERON_DRIVER_AGENT_H

redpajama_set_name: RedPajamaGithub


text:
app.controller('TurnosController', TurnosController);

TurnosController.$inject = [
	'$stateParams',
	'$scope',
	'$timeout',
	'apiService'
];

/* -------------------------- */

function TurnosController($stateParams, $scope, $timeout, apiService) {

	$scope.turno = $stateParams.turno ? $stateParams.turno : null;

	$scope.Servicios = [
		'Internación',
		'Laboratorio Central',
		'Medio interno y guardia',
		'Microbiología',
		'Virología'
	];

	/* -------------- */

	$scope.guardar = function() {

		var cleanScope = function() {
			$scope.Persona = null;
			$scope.HistoriaClinica = null;
			$scope.ObraSoc = null;
			$scope.NroAfil = null;
			$scope.Servicio = null;
			$scope.FechaTurno = null;
		}

		$scope.submitted = true;

		var dataToSend = {
			Persona: $scope.Persona,
			HistoriaClinica: $scope.HistoriaClinica,
			ObraSoc: $scope.ObraSoc,
			NroAfil: $scope.NroAfil,
			Servicio: $scope.Servicio,
			FechaTurno: $scope.FechaTurno
		};

		apiService.request('turnos', 'create', null, dataToSend, null)
		.then(function(response) {
			$scope.submitted = false;
			$scope.turno = response.data;
			cleanScope();
		}, function(response) {
			$scope.submitted = false;
		});

	};

	/* -------------- */

	$scope.listarTurnos = function() {

		var parameters = {
			filtros: 'Servicio=%' + $scope.Servicio + '%',
		};

		apiService.request('turnos', 'search', null, null, parameters)
		.then(function(response) {
			if (!response || response.msj.http != 200) {
				return;
			} else {
				$scope.turnos = response.data;
				return;
			}
		}, function(error) {
			return;
		});

	};

	/* -------------- */

	$scope.eliminarTurno = function() {
		if (!$scope.turno || !$scope.turno.IDTurno) return;
		apiService.request('turnos', 'delete', $scope.turno.IDTurno, null, null)
		.then(function(response) {
			$scope.turno = {};
			return;
		},
		function(error) {
			return;
		});
	};

	/* -------------- */

	$scope.actualizarTurno = function() {
		if (!$scope.turno || !$scope.turno.IDTurno) return;
		var dataToSend = {};
		if ($scope.turno.Persona) dataToSend.Persona = $scope.turno.Persona;
		if ($scope.turno.ObraSoc) dataToSend.ObraSoc = $scope.turno.ObraSoc;
		if ($scope.turno.HistoriaClinica) dataToSend.HistoriaClinica = $scope.turno.HistoriaClinica;
		if ($scope.turno.NroAfil) dataToSend.NroAfil = $scope.turno.NroAfil;
		if ($scope.turno.Servicio) dataToSend.Servicio = $scope.turno.Servicio;
		if ($scope.turno.FechaTurno) dataToSend.FechaTurno = $scope.turno.FechaTurno;
		apiService.request('turnos', 'update', $scope.turno.IDTurno, dataToSend, null)
		.then(function(response) {
			return;
		},
		function(error) {
			return;
		});
	}
}


text:
<?php

require('../../config.php');

require_once($CFG->libdir.'/adminlib.php');
require_login();
$context = context_system::instance();
$PAGE->set_context($context);
$adminroot = admin_get_root(false, false);  // settings not required - only pages

if ($section = optional_param('section', '', PARAM_SAFEDIR) and confirm_sesskey()) {

    if (get_user_preferences('admin_bookmarks')) {
        $bookmarks = explode(',', get_user_preferences('admin_bookmarks'));

        if (in_array($section, $bookmarks)) {
            print_error('bookmarkalreadyexists','admin');
            die;
        }

    } else {
        $bookmarks = array();
    }

    $temp = $adminroot->locate($section);

    if ($temp instanceof admin_settingpage || $temp instanceof admin_externalpage) {
        $bookmarks[] = $section;
        $bookmarks = implode(',', $bookmarks);
        set_user_preference('admin_bookmarks', $bookmarks);

    } else {
        print_error('invalidsection','admin');
        die;
    }

    if ($temp instanceof admin_settingpage) {
        redirect($CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=' . $section);

    } elseif ($temp instanceof admin_externalpage) {
        redirect($temp->url);
    }

} else {
    print_error('invalidsection','admin');
    die;
}


text:
from __future__ import absolute_import

from sentry.utils.compat.mock import patch

from datetime import timedelta
from django.utils import timezone
from time import time

from sentry.models import Group, GroupStatus
from sentry.tasks.auto_resolve_issues import schedule_auto_resolution
from sentry.testutils import TestCase

class ScheduleAutoResolutionTest(TestCase):
    def test_task_persistent_name(self):
        assert schedule_auto_resolution.name == "sentry.tasks.schedule_auto_resolution"

    @patch("sentry.tasks.auto_resolve_issues.kick_off_status_syncs")
    def test_simple(self, mock_kick_off_status_syncs):
        project = self.create_project()
        project2 = self.create_project()
        project3 = self.create_project()
        project4 = self.create_project()

        current_ts = int(time()) - 1

        project.update_option("sentry:resolve_age", 1)
        project3.update_option("sentry:resolve_age", 1)
        project3.update_option("sentry:_last_auto_resolve", current_ts)
        project4.update_option("sentry:_last_auto_resolve", current_ts)

        group1 = self.create_group(
            project=project,
            status=GroupStatus.UNRESOLVED,
            last_seen=timezone.now() - timedelta(days=1),
        )

        group2 = self.create_group(
            project=project, status=GroupStatus.UNRESOLVED, last_seen=timezone.now()
        )

        group3 = self.create_group(
            project=project3,
            status=GroupStatus.UNRESOLVED,
            last_seen=timezone.now() - timedelta(days=1),
        )

        with self.tasks():
            schedule_auto_resolution()

        assert Group.objects.get(id=group1.id).status == GroupStatus.RESOLVED

        assert Group.objects.get(id=group2.id).status == GroupStatus.UNRESOLVED

        assert Group.objects.get(id=group3.id).status == GroupStatus.UNRESOLVED

        mock_kick_off_status_syncs.apply_async.assert_called_once_with(
            kwargs={"project_id": group1.project_id, "group_id": group1.id}
        )

        assert project.get_option("sentry:_last_auto_resolve") > current_ts
        assert not project2.get_option("sentry:_last_auto_resolve")
        assert project3.get_option("sentry:_last_auto_resolve") == current_ts
        # this should get cleaned up since it had no resolve age set
        assert not project4.get_option("sentry:_last_auto_resolve")


text:
const path = require('path');

// package.json as JS object
module.exports.pkg = require(path.join(__dirname, '../package.json'));

// note: for all paths, the base dir is ../
module.exports.PATHS = {
  srcDir: 'src',
  tsSrcFiles: 'src/**/*.ts',
  tsTestFiles: [
    'test/**/*.ts',
    'typings/main.d.ts',
  ],
  releaseAssets: ['assets/release/**/*', 'package.json', 'LICENSE'],
  jsFiles: ['gulpfile.js', 'gulp/*.js'],
  tsConfig: path.join(__dirname, '../tsconfig.json'),
  dist: {
    base: 'dist/',
    cjs: 'dist/',
    es6: 'dist/es6/',
    ts: 'dist/ts/',
    bundles: 'dist/bundles/',
  },
  testBuilt: 'test-built/',
};


text:
using System;
using System.Collections.Generic;

using FlintSharp.Behaviours;
using FlintSharp.Activities;
using FlintSharp.Counters;
using FlintSharp.Easing;
using FlintSharp.Emitters;
using FlintSharp.EnergyEasing;
using FlintSharp.Initializers;
using FlintSharp.Particles;
using FlintSharp.Zones;

namespace FlintSharp.Behaviours
{
    /// <summary>
    /// The ApproachNeighbours action applies an acceleration to the particle to draw it
    /// towards other nearby particles.
    /// </summary>
    public class ApproachNeighbours : Behaviour
    {
        private double m_max;
        private double m_acc;
        private double m_maxSq;

        public ApproachNeighbours()
            : this(10.0, 1.0)
        {
        }

        /// <summary>
        /// The constructor creates a ApproachNeighbours action for use by
        /// an emitter. To add a ApproachNeighbours to all particles created by an emitter, use the
        /// emitter's addAction method.
        ///
        /// @see org.flintparticles.emitters.Emitter#addAction()
        /// </summary>
        /// <param name="maxDistance">The maximum distance, in pixels, over which this action operates.
        /// The particle will approach other particles that are this close or closer to it.</param>
        /// <param name="acceleration">The acceleration force applied to approach the other particles.</param>
        public ApproachNeighbours(double maxDistance, double acceleration)
        {
            m_max = maxDistance;
            m_maxSq = maxDistance * maxDistance;
            m_acc = acceleration;
        }

        /// <summary>
        /// The maximum distance, in pixels, over which this action operates.
        /// The particle will approach other particles that are this close or closer to it.
        /// </summary>
        public double MaxDistance
        {
            get { return m_max; }
            set { m_max = value; m_maxSq = value * value; }
        }

        /// <summary>
        /// The acceleration force applied to approach the other particles.
        /// </summary>
        public double Acceleration
        {
            get { return m_acc; }
            set { m_acc = value; }
        }

        /// <summary>
        /// The getDefaultPriority method is used to order the execution of actions.
        /// It is called within the emitter's addAction method when the user doesn't
        /// manually set a priority. It need not be called directly by the user.
        ///
        /// @see org.flintparticles.common.actions.Action#getDefaultPriority()
        /// </summary>
        /// <returns>The priority value</returns>
        public override int GetDefaultPriority()
        {
            return 10;
        }

        /// <summary>
        /// The addedToEmitter method is called by the emitter when the Action is added to it
        /// It is called within the emitter's addAction method and need not
        /// be called by the user.
        /// </summary>
        /// <param name="emitter">The Emitter that the Action was added to.</param>
        public override void AddedToEmitter(Emitter emitter)
        {
            if (emitter == null)
            {
                return;
            }

            emitter.SpaceSort = true;
        }

        /// <summary>
        /// The update method is used by the emitter to apply the action
        /// to every particle. It is called within the emitter's update
        /// loop and need not be called by the user.
        /// </summary>
        /// <param name="emitter">The Emitter that created the particle.</param>
        /// <param name="particle">The particle to be updated.</param>
        /// <param name="elapsedTime">The duration of the frame - used for time based updates.</param>
        public override void Update(Emitter emitter, Particle particle, double elapsedTime)
        {
            if (emitter == null)
            {
                return;
            }

            if (particle == null)
            {
                return;
            }

            List<Particle> particles = emitter.Particles;
            Particle other = null;
            int i = 0;
            int len = particles.Count;
            double distanceInv = 0;
            double distanceSq = 0;
            double dx = 0;
            double dy = 0;
            double moveX = 0;
            double moveY = 0;
            double factor = 0;

            for (i = particles.IndexOf(particle) - 1; i >= 0; i--)
            {
                other = particles[i];
                if ((dx = particle.X - other.X) > m_max)
                    break;
                dy = other.Y - particle.Y;
                if (dy > m_max || dy < -m_max)
                    continue;
                distanceSq = dy * dy + dx * dx;
                if (distanceSq <= m_maxSq && distanceSq > 0)
                {
                    distanceInv = (1 / Math.Sqrt(distanceSq));
                    moveX += -dx * distanceInv;
                    moveY += dy * distanceInv;
                }
            }
            for (i = particles.IndexOf(particle) + 1; i < len; i++)
            {
                other = particles[i];
                if ((dx = other.X - particle.X) > m_max)
                    break;
                dy = other.Y - particle.Y;
                if (dy > m_max || dy < -m_max)
                    continue;
                distanceSq = dy * dy + dx * dx;
                if (distanceSq <= m_maxSq && distanceSq > 0)
                {
                    distanceInv = (1 / Math.Sqrt(distanceSq));
                    moveX += dx * distanceInv;
                    moveY += dy * distanceInv;
                }
            }
            if (moveX != 0 || moveY != 0)
            {
                factor = (elapsedTime * m_acc / Math.Sqrt(moveX * moveX + moveY * moveY));
                particle.VelocityX += factor * moveX;
                particle.VelocityY += factor * moveY;
            }
        }
    }
}


text:
Michelangelo
============

Contributors
------------
Jonatan H Sundqvist

TODO
----


text:
GNUstep Objective-C Runtime
===========================

[![Build Status](https://travis-ci.org/gnustep/libobjc2.svg?branch=master)](https://travis-ci.org/gnustep/libobjc2)

The GNUstep Objective-C runtime is designed as a drop-in replacement for the
GCC runtime.  It supports both a legacy and a modern ABI, allowing code
compiled with old versions of GCC to be supported without requiring
recompilation.  The modern ABI adds the following features:

- Non-fragile instance variables.
- Protocol uniquing.
- Object planes support.
- Declared property introspection.

Both ABIs support the following feature above and beyond the GCC runtime:

- The modern Objective-C runtime APIs, introduced with OS X 10.5.
- Blocks (closures).
- Low memory profile for platforms where memory usage is more important than
  speed.
- Synthesised property accessors.
- Efficient support for @synchronized()
- Type-dependent dispatch, eliminating stack corruption from mismatched
  selectors.
- Support for the associated reference APIs introduced with Mac OS X 10.6.
- Support for the automatic reference counting APIs introduced with Mac OS X
  10.7

History
-------

Early work on the GNUstep runtime combined code from the GCC Objective-C
runtime, the Étoilé Objective-C runtime, Remy Demarest's blocks runtime for OS
X 10.5, and the Étoilé Objective-C 2 API compatibility framework.  All of these
aside from the GCC runtime were MIT licensed, although the GPL'd code present
in the GCC runtime meant that the combined work had to remain under the GPL.

Since then, all of the GCC code has been removed, leaving the remaining files
all MIT licensed, and allowing the entire work to be MIT licensed.

The exception handling code uses a header file implementing the generic parts
of the Itanium EH ABI.  This file comes from PathScale's libcxxrt.  PathScale
kindly allowed it to be MIT licensed for inclusion here.

Non-Fragile Instance Variables
------------------------------

When a class is compiled to support non-fragile instance variables, the
`instance_size` field in the class is set to 0 - the size of the instance
variables declared on that class (excluding those inherited.  For example, an
NSObject subclass declaring an int ivar would have its `instance_size` set to
`0 - sizeof(int))`.  The offsets of each instance variable in the class's
`ivar_list` field are then set to the offset from the start of the superclass's
ivars.

When the class is loaded, the runtime library uses the size of the superclass
to calculate the correct size for this new class and the correct offsets.  Each
instance variable should have two other variables exported as global symbols.
Consider the following class:

	@interface NewClass : SuperClass {
		int anIvar;
	}
	@end

This would have its `instance_size` initialized to `0-sizeof(int)`, and
`anIvar`'s offset initialized to 0.  It should also export the following two
symbols:

	int __objc_ivar_offset_value_NewClass.anIvar;
	int *__objc_ivar_offset_NewClass.anIvar;

The latter should point to the former or to the `ivar_offset` field in the ivar
metadata.  The former should be pointed to by the only element in the
`ivar_offsets` array in the class structure.

In other compilation units referring to this ivar, the latter symbol should be
exported as a weak symbol pointing to an internal symbol containing the
compiler's guess at the ivar offset.  The ivar will then work as a fragile ivar
when `NewClass` is compiled with the old ABI.  If `NewClass` is compiled with
the new ABI, then the linker will replace the weak symbol with the version in
the class's compilation unit and references which use this offset will function
correctly.

If the compiler can guarantee that `NewClass` is compiled with the new ABI, for
example if it is declared in the same compilation unit, by finding the symbol
during a link-time optimization phase, or as a result of a command-line
argument, then it may use the `__objc_ivar_offset_value_NewClass.anIvar` symbol
as the ivar offset.  This eliminates the need for one load for every ivar
access.

Protocols
---------

The runtime now provides a `__ObjC_Protocol_Holder_Ugly_Hack` class.  All
protocols that are referenced but not defined should be registered as
categories on this class.  This ensures that every protocol is registered with
the runtime.

In the near future, the runtime will ensure that protocols can be looked up by
name at run time and that empty protocol definitions have their fields updated
to match the defined version.

Protocols have been extended to provide space for introspection on properties
and optional methods.  These fields only exist on protocols compiled with a
compiler that supports Objective-C 2.  To differentiate the two, the `isa`
pointer for new protocols will be set to the `Protocol2` class.

Blocks
------

The GNUstep runtime provides the run time support required for Apple's blocks
(closures) extension to C.  This follows the same ABI as OS X 10.6.

Fast Proxies and Cacheable Lookups
----------------------------------

The new runtime provides two mechanisms for faster lookup.  The older
`objc_msg_lookup()` function, which returns an IMP, is still supported, however
it is no longer recommended.  The new lookup functions is:

	Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender)

The receiver is passed by pointer, and so may be modified during the lookup
process.  The runtime itself will never modify the receiver.  The following
hook is provided to allow fast proxy support:

	id (*objc_proxy_lookup)(id receiver, SEL op);

This function takes an object and selector as arguments and returns a new
objects.  The lookup will then be re-run and the final message should be sent to
the new object.

The returned `Slot_t` from the new lookup function is a pointer to a structure
which contains both an IMP and a version (among other things).  The version is
incremented every time the method is overridden, allowing this to be cached by
the caller.  User code wishing to perform IMP caching may use the old mechanism
if it can guarantee that the IMP will not change between calls, or the newer
mechanism.  Note that a modern compiler should insert caching automatically,
ideally with the aid of run-time profiling results.  To support this, a new hook
has been added:

	Slot_t objc_msg_forward3(id receiver, SEL op);

This is identical to `objc_msg_forward2()`, but returns a pointer to a slot,
instead of an IMP.  The slot should have its version set to 0, to prevent
caching.

Object Planes
-------------

Object planes provide interception points for messages between groups of
related objects.  They can be thought of as similar to processes, with mediated
inter-plane communication.  A typical use-case for an object plane is to
automatically queue messages sent to a thread, or to record every message sent
to model objects.  Planes can dramatically reduce the number of proxy objects
required for this kind of activity.

The GNUstep runtime adds a flag to class objects indicating that their
instances are present in the global plane.  All constant strings, protocols,
and classes are in the global plane, and may therefore be sent and may receive
messages bypassing the normal plane interception mechanism.

The runtime library does not provide direct support for planes, it merely
provides the core components required to implement support for planes in
another framework.  Two objects are regarded as being in the same plane when
they words immediately before their isa pointers are the same.  In this case,
the runtime's usual dispatch mechanisms will be used.  In all other cases, the
runtime will delegate message lookup to another library via the following hook:

	Slot_t (*objc_plane_lookup)(id *receiver, SEL op, id sender);

From the perspective of the runtime, the plane identifier is opaque.  In
GNUstep, it is a pointer to an `NSZone` structure.

Threading
---------

The threading APIs from GCC libobjc are not present in this runtime.  They were
buggy, badly supported, inadequately tested, and irrelevant now that there are
well tested thread abstraction layers, such as the POSIX thread APIs and the
C1x thread functions.  The library always runs in thread-safe mode.  The same
functions for locking the runtime mutex are still supported, but their use any
mutex not exported by the runtime library is explicitly not supported.  The
(private) lock.h header is used to abstract the details of different threading
systems sufficiently for the runtime.  This provides mechanisms for locking,
unlocking, creating, and destroying mutex objects.

Type-Dependent Dispatch
-----------------------

Traditionally, Objective-C method lookup is done entirely on the name of the
method.  This is problematic when the sender and receiver of the method
disagree on the types of a method.

For example, consider a trivial case where you have two methods with the same
name, one taking an integer, the other taking a floating point value.  Both
will pass their argument in a register on most platforms, but not the same
register.  If the sender thinks it is calling one, but is really calling the
other, then the receiver will look in the wrong register and use a nonsense
value.  The compiler will often not warn about this.

This is a relatively benign example, but if the mismatch is between methods
taking or returning a structure and those only using scalar arguments and
return then the call frame layout will be so different that the result will be
stack corruption, possibly leading to security holes.

If you compile the GNUstep runtime with type-dependent dispatch enabled, then
sending a message with a typed selector will only ever invoke a method with the
same types.  Sending a message with an untyped selector will invoke any method
with a matching name, although the slot returned from the lookup function will
contain the types, allowing the caller to check them and construct a valid call
frame, if required.

If a lookup with a typed selector matches a method with the wrong types, the
runtime will call a handler.  This handler, by default, prints a helpful
message and exits.  LanguageKit provides an alternative version which
dynamically generates a new method performing the required boxing and calling
the original.

Exception ABI Changes
---------------------

The non-fragile ABI makes a small change to the exception structure.  The old
GCC ABI was very poorly designed.  It attempted to do things in a clever way,
avoiding the need to call functions on entering and exiting catch blocks, but
in doing so completely broke support for throwing foreign (e.g. C++) exceptions
through Objective-C stack frames containing an @finally or @catch(id) block.
It also could not differentiate between @catch(id) (catch any object type) and
@catch(...) (catch any exception and discard it).

The new ABI makes a small number of changes.  Most importantly, `@catch(id)` is
now indicated by using the string `"@id"` as the type ID, in the same way that
`"Foo"` is used for `@catch(Foo*)`.  Catchalls remain identified by a NULL
pointer in this field, as with the GCC ABI.  The runtime will still deliver the
exception object to catchalls, for interoperability with old code and with the
old ABI, but this comes with all of the same problems that the old ABI had
(i.e. code using this ABI will break in exciting and spectacular ways when
mixed with C++).

The runtime provides a hook, `_objc_class_for_boxing_foreign_exception()`, which
takes an exception class (64-bit integer value) as an argument, and returns a
class for boxing exceptions using this ABI.  The returned class must implement
a `+exceptionWithForeignException:` method, taking a pointer to the ABI-defined
generic exception structure as the argument.  It should also implement a
`-rethrow` method, used for rethrowing the exception.  If this is omitted, then
the boxed version of the exception, rather than the original, will propagate
out from @finally blocks.

If a catch block exists that handles this class, then it will box foreign
exceptions and allow them to propagate through any @finally directives.  Boxed
exceptions will only match explicit catch statements.  To fully understand the
semantics, we'll take a look at some examples.  These all use GNUstep's
`CXXException` class, which boxes C++ exceptions, and this simple C++ function:

	extern "C" void throwcxx()
	{
		throw 1;
	}

This exception will be caught, boxed, and then silently discarded by a catchall:

	@try
	{
		throwcxx();
	}
	@catch(...)
	{
		// This will be reached, then the exception propagation stops.
	}

If an id catch block is encountered, it will be ignored, but @finally blocks
will still be called:

	@try
	{
		throwcxx();
	}
	@catch(id anyObject)
	{
		// Code here is not reached.
	}
	@finally
	{
		// This will be reached, then the exception propagation continues.
	}

The `CXXException` class is a subclass of `NSObject`, but catch statements for
the superclass will not be hit:

	@try
	{
		throwcxx();
	}
	@catch(NSObject *anyObject)
	{
		// Code here is not reached.
	}
	@catch(CXXException *boxedForeign)
	{
		// Code here is reached.
	}

As of version 1.3, the runtime also provides a unified exception model for
Objective-C++.  This allows C++ `catch` statements and Objective-C `@catch`
statements to catch Objective-C objects thrown with `@throw` or `throw`.

This required some small changes to the ABI.  Both `@try` and `try` must use
the same personality function in Objective-C++ code, because otherwise things
like nested blocks are not possible.  The unwind library must be able to map
from any instruction pointer value to a single personality function, and
without a unified personality function, it would not be able to in code like
this:

	@try
	{
		try
		{
			// What personality function should be used when unwinding from
			// here?
			objc_exception_throw(@"foo");
		}
		catch (int i) {}
	}
	catch (id foo) {}

If there is a single personality function, there must be a single format for
language-specific data.  The current C++ format is more expressive than the
Objective-C format, so we used it directly, with one extension.  C++ landing
pads are identified by a `std::type_info` subclass in the type info tables for
exception unwinding.  We provide two subclasses of this:

	gnustep::libobjc::__objc_id_type_info;
	gnustep::libobjc::__objc_class_type_info;

The first is used for identifying `id`-typed throws and catches.  The second is
for identifying Objective-C classes.  All `id` throws use the singleton
instance of the first class, exported as `__objc_id_type_info` (with C
linkage).  Type info for classes should generate an instance of the second
class, with the name `__objc_eh_typeinfo_Foo` where `Foo` is the name of the
class (e.g. `NSObject` should generate `__objc_eh_typeinfo_NSObject`).  The
name field should be set to the name of the class, via a global variable named
`__objc_eh_typename_Foo`.  Both should have link-once ODR linkage, so that the
linker will ensure that they are unique and pointer comparison can be used to
test for equality (required by the C++ personality function).

In Objective-C++ code, the personality function is:

	__gnustep_objcxx_personality_v0()

This is a very thin wrapper around the C++ personality function.  If it is
called with an exception coming from Objective-C code, then it wraps it in a
`__cxa_exception` structure (defined by the C++ ABI spec).  For any other
exception type (including C++ exceptions), it passes it directly to the C++
personality function.

The Objective-C personality function was also modified slightly so that any
incoming C++ exception that was has type info indicating that it's an
Objective-C type is treated as an Objective-C object, for the purpose of
exception delivery.

Low Memory Profile
------------------

The dispatch tables for each class, in spite of using a more space-efficient
sparse array implementation than GCC libobjc, can still use quite a lot of
memory.  The NeXT runtime avoided this problem by not providing dispatch tables
at all.  Instead, it did a linear search of the method lists, caching a few
results.  Although this is O(n), it performed reasonably well.  Most message
sends are to a small number of methods.  For example, an NSMutableDictionary is
most often sent `-objectForKey:` and `-setObject:forKey:`.  If these two methods
are in the cache, then the O(n) algorithm is almost never used.

The GNUstep runtime's low memory profile stores the slots in a sorted array.
This means that the worst case performance is O(log(n)) in terms of the number
of methods, as the uncached lookup proceeds using a binary search.

If you compile the GNUstep runtime with the low memory profile, it uses a
similar strategy.  The caches use the same slot-caching mechanism described
above and can be combined with caching at the call site.  The runtime will not
create dispatch tables, which can save a few MB of RAM in projects with a lot
of classes, but can make message sending a lot slower in the worst case.

To enable the low memory profile, add `low_memory=yes` to your make command
line.

Objective-C 2 Features
----------------------

The runtime now provides implementations of the functions required for the
@synchronized directive, for property accessors, and for fast enumeration.  The
public runtime function interfaces now match those of OS X.

Garbage Collection
------------------

As of version 1.5, the runtime support Apple-compatible garbage collection
semantics.  The `objc/objc-auto.h` header describes the interfaces to garbage
collection.  This contains some extensions to Apple's API, required to
implement parts of Cocoa that rely on private interfaces between Cocoa, Apple
libobjc, and Autozone.

Garbage collection is implemented using the Boehm-Demers-Weiser garbage
collector.  If built with `boehm_gc=no`, this support will not be compiled into
the runtime.  When built with GC support, the runtime will use garbage
collection for its internal tables, irrespective of whether linked Objective-C
code is using it.

Zeroing weak references are implemented by storing the bit-flipped version of
the value (making it invisible to the collector) at the designated address.
The read barrier reads the value while holding the collector lock.  This
ensures that reads of weak variables never point to finalised objects.

The runtime uses the `objc_assign_global()` write barrier to add static roots.
Currently, GNUstep crashes if the collector relies on every write of a pointer
to a static location being through this write barrier, so this requirement is
relaxed.  It will be enabled at some point in the future.

Several environment variables can be used for debugging programs

- `LIBOBJC_DUMP_GC_STATUS_ON_EXIT`.  I this is set, then the program will dump
  information about the garbage collector when it exits.
- `LIBOBJC_DUMP_GC_STATUS_ON_SIGNAL`.  This should be set to a signal number.
  The program will dump GC statistics when it receives the corresponding signal
  (`SIGUSR2` if this environment variable is set to something that is not a
  number).
- `LIBOBJC_LOG_ALLOCATIONS`.  This may be set to the name of a file.  The
  runtime will dump a stack trace on every allocation and finalisation to the
  named file.  This can be used to implement tools like Apple's
  `malloc_history()`.  Note: Enabling this causes a significant speed decrease.
- `LIBOBJC_CANARIES`.  If this environment variable is set, then every
  allocation of garbage-collected memory will have a canary value appended to
  it.  On finalisation, the runtime will check that this value has not been
  modified, and abort if it has.  This can help to catch heap buffer overflows.
  It is most useful when debugging.

Automatic Reference Counting
----------------------------

As of version 1.5, the runtime provides support for automatic reference
counting (ARC).  This uses the same runtime interface as documented by the ABI
supplement here:

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime

The runtime implements the following optimisations:

- Classes that have ARC-compliant retain, release, and autorelease methods will
  never see them called from ARC code.  Instead, equivalent code will be run
  directly.
- If an object is autoreleased, returned, and retained, it is just stored in
  thread-local storage temporarily, not actually autoreleased.
- Moving weak references skips the retain / release step.

ARC requires the ability to interoperate perfectly with manual retain / release
code, including the ability for non-ARC code to implement custom reference
counting behaviour.  If an object implements `-_ARCCompliantRetainRelease`, then
it is advertising that its `-retain`, `-release`, and `-autorelease`
implementations are ARC-compatible.  These methods may be called explicitly in
non-ARC code, but will not be called from ARC.

ARC moves autorelease pools into the runtime.  If `NSAutoreleasePool` exists
and does not implement a `-_ARCCompatibleAutoreleasePool` method, then it will
be used directly.  If it does not exist, ARC will implement its own
`-autorelease` pools.  If it exists and does implement
`-_ARCCompatibleAutoreleasePool` then it must call `objc_autoreleasePoolPush()`
and `objc_autoreleasePoolPop()` to manage autoreleased object storage and call
`objc_autorelease()` in its `-addObject:` method.


text:
package gocrawl

import (
	"net/http"
	"os"
	"path"
	"strings"
)

const (
	FileFetcherBasePath = "./testdata/"
)

// The file fetcher, that loads URLs from files in the testdata/ directory.
type fileFetcherExtender struct {
	*DefaultExtender
}

// FileFetcher constructor, creates the internal default implementation
func newFileFetcher() *fileFetcherExtender {
	return &fileFetcherExtender{new(DefaultExtender)}
}

// FileFetcher's Fetch() implementation
func (this *fileFetcherExtender) Fetch(ctx *URLContext, userAgent string, headRequest bool) (*http.Response, error) {
	var res *http.Response = new(http.Response)
	var req *http.Request
	var e error

	if req, e = http.NewRequest("GET", ctx.url.String(), nil); e != nil {
		panic(e)
	}

	// Prepare the pseudo-request
	req.Header.Add("User-Agent", userAgent)

	// Open the file specified as path in u, relative to testdata/[host]/
	host := ctx.url.Host
	if strings.HasPrefix(host, "www.") {
		host = host[4:]
	}
	f, e := os.Open(path.Join(FileFetcherBasePath, host, ctx.url.Path))
	if e != nil {
		// Treat errors as 404s - file not found
		res.Status = "404 Not Found"
		res.StatusCode = 404
	} else {
		res.Status = "200 OK"
		res.StatusCode = 200
		res.Body = f
	}
	res.Request = req

	return res, e
}


text:
import initTailRecursiveFunction from './modules/initTailRecursiveFunction.js';
import call from './modules/call.js';
import continuation from './modules/continuation.js';
import construct from './modules/construct.js';

$traceurRuntime.initTailRecursiveFunction = initTailRecursiveFunction;
$traceurRuntime.call = call;
$traceurRuntime.continuation = continuation;
$traceurRuntime.construct = construct;


text:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="DeliveryIntervention" name="DeliveryIntervention"
		class="org.socraticgrid.hl7.services.eps.clients.psdeliveryintervention.PSDeliveryInterventionService">
	</bean>
</beans>


text:
using namespace irr;
using namespace irr::asset;
using namespace irr::video;
using namespace irr::scene;

const std::string raygenShaderExtensions = R"======(
#version 430 core
)======";

const std::string lightStruct = R"======(
#define SLight_ET_ELLIPSOID	0u
#define SLight_ET_TRIANGLE	1u
#define SLight_ET_COUNT		2u
struct SLight
{
	vec3 factor;
	uint data0;
	mat4x3 transform; // needs row_major qualifier
	mat3 transformCofactors;
};
uint SLight_extractType(in SLight light)
{
	return bitfieldExtract(light.data0,0,findMSB(SLight_ET_COUNT)+1);
}
)======";

const std::string raygenShader = R"======(
#define WORK_GROUP_DIM 16u
layout(local_size_x = WORK_GROUP_DIM, local_size_y = WORK_GROUP_DIM) in;
#define WORK_GROUP_SIZE (WORK_GROUP_DIM*WORK_GROUP_DIM)

// uniforms
layout(location = 0) uniform vec3 uCameraPos;
layout(location = 1) uniform float uDepthLinearizationConstant;
layout(location = 2) uniform mat4 uFrustumCorners;
layout(location = 3) uniform uvec2 uImageSize;
layout(location = 4) uniform uvec2 uSamples_ImageWidthSamples;
layout(location = 5) uniform uint uSamplesComputed;
layout(location = 6) uniform vec4 uImageSize2Rcp;

// image views
layout(binding = 0) uniform sampler2D depthbuf;
layout(binding = 1) uniform sampler2D normalbuf;
layout(binding = 2) uniform sampler2D albedobuf;
layout(binding = 3) uniform usamplerBuffer sampleSequence;
layout(binding = 4) uniform usampler2D scramblebuf;

// SSBOs
layout(binding = 0, std430) restrict writeonly buffer Rays
{
	RadeonRays_ray rays[];
};

layout(binding = 1, std430) restrict readonly buffer CumulativeLightPDF
{
	uint lightCDF[];
};

layout(binding = 2, std430, row_major) restrict readonly buffer Lights
{
	SLight light[];
};

#define kPI 3.14159265358979323846

vec3 decode(in vec2 enc)
{
	float ang = enc.x*kPI;
    return vec3(vec2(cos(ang),sin(ang))*sqrt(1.0-enc.y*enc.y), enc.y);
}

#define FLT_MIN -1.17549449e-38
#define FLT_MAX 3.402823466e+38

float linearizeZBufferVal(in float nonLinearZBufferVal)
{
	// 1-(Ax+B)/(Cx) = y
	// (Ax+B)/(Cx) = 1-y
	// x = B/(C(1-y)-A)
	// x = B/(C-A-Cy)
	// get back original Z: `row[2][3]/(row[3][2]-row[2][2]-y*row[3][2]) = x`
	// max Z: `B/(C-A)`
	// positive [0,1] Z: `B/(C-A-Cy)/(B/(C-A))`
	// positive [0,1] Z: `(C-A)/(C-A-Cy)`
	// positive [0,1] Z: `D/(D-Cy)`
    return 1.0/(uDepthLinearizationConstant*nonLinearZBufferVal+1.0);
}

float maxAbs1(in float val)
{
	return abs(val);
}
float maxAbs2(in vec2 val)
{
	vec2 v = abs(val);
	return max(v.x,v.y);
}
float maxAbs3(in vec3 val)
{
	vec3 v = abs(val);
	return max(max(v.x,v.y),v.z);
}

float ULP1(in float val, in uint accuracy)
{
	return uintBitsToFloat(floatBitsToUint(abs(val)) + accuracy)-val;
}
float ULP2(in vec2 val, in uint accuracy)
{
	float x = maxAbs2(val);
	return uintBitsToFloat(floatBitsToUint(x) + accuracy)-x;
}
float ULP3(in vec3 val, in uint accuracy)
{
	float x = maxAbs3(val);
	return uintBitsToFloat(floatBitsToUint(x) + accuracy)-x;
}

uint ugen_uniform_sample1(in uint dimension, in uint sampleIx, in uint scramble);
uvec2 ugen_uniform_sample2(in uint dimension, in uint sampleIx, in uint scramble);

vec2 gen_uniform_sample2(in uint dimension, in uint sampleIx, in uint scramble);

uint ugen_uniform_sample1(in uint dimension, in uint sampleIx, in uint scramble)
{
	return ugen_uniform_sample2(dimension,sampleIx,scramble).x;
}
uvec2 ugen_uniform_sample2(in uint dimension, in uint sampleIx, in uint scramble)
{
	uint address = (dimension>>1u)*MAX_SAMPLES+(sampleIx&(MAX_SAMPLES-1u));
	return texelFetch(sampleSequence,int(address)).xy^uvec2(scramble);
}

vec2 gen_uniform_sample2(in uint dimension, in uint sampleIx, in uint scramble)
{
	return vec2(ugen_uniform_sample2(dimension,sampleIx,scramble))/vec2(~0u);
}

// https://orbit.dtu.dk/files/126824972/onb_frisvad_jgt2012_v2.pdf
mat2x3 frisvad(in vec3 n)
{
	const float a = 1.0/(1.0 + n.z);
	const float b = -n.x*n.y*a;
	return (n.z<-0.9999999) ? mat2x3(vec3(0.0,-1.0,0.0),vec3(-1.0,0.0,0.0)):mat2x3(vec3(1.0-n.x*n.x*a, b, -n.x),vec3(b, 1.0-n.y*n.y*a, -n.y));
}

uint lower_bound(in uint key, uint size)
{
    uint low = 0u;

#define ITERATION \
	{\
        uint _half = size >> 1u; \
        uint other_half = size - _half; \
        uint probe = low + _half; \
        uint other_low = low + other_half; \
        uint v = lightCDF[probe]; \
        size = _half; \
        low = v<key ? other_low:low; \
	}

    while (size >= 8u)
	{
		ITERATION
		ITERATION
		ITERATION
    }

    while (size > 0u)
		ITERATION

#undef ITERATION

	return low;
}

uint upper_bound(in uint key, uint size)
{
    uint low = 0u;

#define ITERATION \
	{\
        uint _half = size >> 1u; \
        uint other_half = size - _half; \
        uint probe = low + _half; \
        uint other_low = low + other_half; \
        uint v = lightCDF[probe]; \
        size = _half; \
        low = v<=key ? other_low:low; \
	}

    while (size >= 8u)
	{
		ITERATION
		ITERATION
		ITERATION
    }

    while (size > 0u)
		ITERATION

#undef ITERATION

	return low;
}

vec3 light_sample(out vec3 incoming, in uint sampleIx, in uint scramble, inout float maxT, inout bool alive, in vec3 position, in vec3 normal)
{
	uint lightIDSample = ugen_uniform_sample1(0u,sampleIx,scramble);
	vec2 lightSurfaceSample = gen_uniform_sample2(2u,sampleIx,scramble);

	uint lightID = upper_bound(lightIDSample,uint(lightCDF.length()-1));

	SLight light = light[lightID];

#define SHADOW_RAY_LEN 0.93
	float factor; // 1.0/light_probability already baked into the light factor
	switch (SLight_extractType(light))
	{
		case SLight_ET_ELLIPSOID:
			lightSurfaceSample.x = lightSurfaceSample.x*2.0-1.0;
			{
				mat4x3 tform = light.transform;
				float equator = lightSurfaceSample.y*2.0*kPI;
				vec3 pointOnSurface = vec3(vec2(cos(equator),sin(equator))*sqrt(1.0-lightSurfaceSample.x*lightSurfaceSample.x),lightSurfaceSample.x);

				incoming = mat3(tform)*pointOnSurface+(tform[3]-position);
				float incomingInvLen = inversesqrt(dot(incoming,incoming));
				incoming *= incomingInvLen;

				maxT = SHADOW_RAY_LEN/incomingInvLen;

				factor = 4.0*kPI; // compensate for the domain of integration
				// don't normalize, length of the normal times determinant is very handy for differential area after a 3x3 matrix transform
				vec3 negLightNormal = light.transformCofactors*pointOnSurface;

				factor *= max(dot(negLightNormal,incoming),0.0)*incomingInvLen*incomingInvLen;
			}
			break;
		default: // SLight_ET_TRIANGLE:
			{
				vec3 pointOnSurface = transpose(light.transformCofactors)[0];
				vec3 shortEdge = transpose(light.transformCofactors)[1];
				vec3 longEdge = transpose(light.transformCofactors)[2];

				lightSurfaceSample.x = sqrt(lightSurfaceSample.x);

				pointOnSurface += (shortEdge*(1.0-lightSurfaceSample.y)+longEdge*lightSurfaceSample.y)*lightSurfaceSample.x;

				vec3 negLightNormal = cross(shortEdge,longEdge);

				incoming = pointOnSurface-position;
				float incomingInvLen = inversesqrt(dot(incoming,incoming));
				incoming *= incomingInvLen;

				maxT = SHADOW_RAY_LEN/incomingInvLen;

				factor = 0.5*max(dot(negLightNormal,incoming),0.0)*incomingInvLen*incomingInvLen;
			}
			break;
	}

	if (factor<0.0) // TODO: FLT_MIN
		alive = false;

	return light.factor*factor;
}

void main()
{
	uvec2 outputLocation = gl_GlobalInvocationID.xy;
	bool alive = all(lessThan(outputLocation,uImageSize));
	if (alive)
	{
		// TODO: accelerate texture fetching
		ivec2 uv = ivec2(outputLocation);
		float revdepth = texelFetch(depthbuf,uv,0).r;

		uint outputID = uSamples_ImageWidthSamples.x*outputLocation.x+uSamples_ImageWidthSamples.y*outputLocation.y;

		// unproject
		vec3 viewDir;
		vec3 position;
		{
			vec2 NDC = vec2(outputLocation)*uImageSize2Rcp.xy+uImageSize2Rcp.zw;
			viewDir = mix(uFrustumCorners[0]*NDC.x+uFrustumCorners[1],uFrustumCorners[2]*NDC.x+uFrustumCorners[3],NDC.yyyy).xyz;
			position = viewDir*linearizeZBufferVal(revdepth)+uCameraPos;
		}

		alive = revdepth>0.0;
		vec2 encNormal;
		if (alive)
			encNormal = texelFetch(normalbuf,uv,0).rg;

		uint scramble = texelFetch(scramblebuf,uv,0).r;

		RadeonRays_ray newray;
		newray.time = 0.0;
		newray.mask = alive ? -1:0;
		vec3 normal;
		if (alive)
			normal = decode(encNormal);
		for (uint i=0u; i<uSamples_ImageWidthSamples.x; i++)
		{
			vec4 bsdf = vec4(0.0,0.0,0.0,-1.0);
			float error = ULP1(uDepthLinearizationConstant,8u);

			newray.maxT = FLT_MAX;
			if (alive)
				bsdf.rgb = light_sample(newray.direction,uSamplesComputed+i,scramble,newray.maxT,alive,position,normal);
			if (alive)
				bsdf.rgb *= texelFetch(albedobuf,uv,0).rgb*max(dot(normal,newray.direction),0.0)/kPI;

			newray.origin = position+newray.direction*error/maxAbs3(newray.direction);
			newray._active = alive ? 1:0;
			newray.backfaceCulling = int(packHalf2x16(bsdf.ab));
			newray.useless_padding = int(packHalf2x16(bsdf.gr));

			// TODO: repack rays for coalescing
			rays[outputID+i] = newray;
		}
	}
}

)======";

const std::string compostShaderExtensions = R"======(
#version 430 core
)======";

const std::string compostShader = R"======(
#define WORK_GROUP_DIM 16u
layout(local_size_x = WORK_GROUP_DIM, local_size_y = WORK_GROUP_DIM) in;
#define WORK_GROUP_SIZE (WORK_GROUP_DIM*WORK_GROUP_DIM)

// uniforms
layout(location = 0) uniform uvec2 uImageSize;
layout(location = 1) uniform uvec2 uSamples_ImageWidthSamples;
layout(location = 2) uniform float uRcpFramesDone;

// image views
layout(binding = 0) uniform usampler2D lightIndex;
layout(binding = 0, rgba32f) restrict uniform image2D framebuffer;

// SSBOs
layout(binding = 0, std430) restrict readonly buffer Rays
{
	RadeonRays_ray rays[];
};
layout(binding = 1, std430) restrict buffer Queries
{
	int hit[];
};

layout(binding = 2, std430, row_major) restrict readonly buffer LightRadiances
{
	vec3 lightRadiance[]; // Watts / steriadian / steradian
};

void main()
{
	uvec2 outputLocation = gl_GlobalInvocationID.xy;
	bool alive = all(lessThan(outputLocation,uImageSize));
	if (alive)
	{
		ivec2 uv = ivec2(outputLocation);
		vec4 acc = vec4(0.0);
		if (uRcpFramesDone<1.0)
			acc = imageLoad(framebuffer,uv);

		uint baseID = uSamples_ImageWidthSamples.x*outputLocation.x+uSamples_ImageWidthSamples.y*outputLocation.y;
		vec3 color = vec3(0.0);
		for (uint i=0u; i<uSamples_ImageWidthSamples.x; i++)
		{
			uint rayID = baseID+i;
			if (hit[rayID]<0)
				color += vec4(unpackHalf2x16(rays[rayID].useless_padding),unpackHalf2x16(rays[rayID].backfaceCulling)).gra;//b;
			// hit buffer needs clearing
			hit[rayID] = -1;
		}
		// TODO: move the `div` to tonemapping shader (or ray gen actually, for fractional sampling)
		color *= 1.0/float(uSamples_ImageWidthSamples.x);

		// TODO: move this to tonemapping
		uint lightID = texelFetch(lightIndex,uv,0)[0];
		if (lightID!=0xdeadbeefu)
			color += lightRadiance[lightID];

		// TODO: optimize the color storage (RGB9E5/RGB19E7 anyone?)
		acc.rgb += (color-acc.rgb)*uRcpFramesDone;
		imageStore(framebuffer,uv,acc);
	}
}

)======";

inline GLuint createComputeShader(const std::string& source)
{
    GLuint program = COpenGLExtensionHandler::extGlCreateProgram();
	GLuint cs = COpenGLExtensionHandler::extGlCreateShader(GL_COMPUTE_SHADER);

	const char* tmp = source.c_str();
	COpenGLExtensionHandler::extGlShaderSource(cs, 1, const_cast<const char**>(&tmp), NULL);
	COpenGLExtensionHandler::extGlCompileShader(cs);

	// check for compilation errors
    GLint success;
    GLchar infoLog[0x200];
    COpenGLExtensionHandler::extGlGetShaderiv(cs, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        COpenGLExtensionHandler::extGlGetShaderInfoLog(cs, sizeof(infoLog), nullptr, infoLog);
        os::Printer::log("CS COMPILATION ERROR:\n", infoLog,ELL_ERROR);
        COpenGLExtensionHandler::extGlDeleteShader(cs);
        COpenGLExtensionHandler::extGlDeleteProgram(program);
        return 0;
	}

	COpenGLExtensionHandler::extGlAttachShader(program, cs);
	COpenGLExtensionHandler::extGlLinkProgram(program);

	//check linking errors
	success = 0;
    COpenGLExtensionHandler::extGlGetProgramiv(program, GL_LINK_STATUS, &success);
    if (success == GL_FALSE)
    {
        COpenGLExtensionHandler::extGlGetProgramInfoLog(program, sizeof(infoLog), nullptr, infoLog);
        os::Printer::log("CS LINK ERROR:\n", infoLog,ELL_ERROR);
        COpenGLExtensionHandler::extGlDeleteShader(cs);
        COpenGLExtensionHandler::extGlDeleteProgram(program);
        return 0;
    }

	return program;
}

class SimpleCallBack : public video::IShaderConstantSetCallBack
{
		Renderer* renderer;
		video::E_MATERIAL_TYPE currentMat;

		int32_t mvpUniformLocation[video::EMT_COUNT+2];
		int32_t nUniformLocation[video::EMT_COUNT+2];
		int32_t flipFacesUniformLocation[video::EMT_COUNT+2];
		int32_t colorUniformLocation[video::EMT_COUNT+2];
		int32_t nastyUniformLocation[video::EMT_COUNT+2];
		int32_t lightIDUniformLocation[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE mvpUniformType[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE nUniformType[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE flipFacesUniformType[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE colorUniformType[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE nastyUniformType[video::EMT_COUNT+2];
		video::E_SHADER_CONSTANT_TYPE lightIDUniformType[video::EMT_COUNT+2];
	public:
		SimpleCallBack(Renderer* _renderer) : renderer(_renderer), currentMat(video::EMT_SOLID)
		{
			std::fill(mvpUniformLocation, reinterpret_cast<int32_t*>(mvpUniformType), -1);
		}

		virtual void PostLink(video::IMaterialRendererServices* services, const video::E_MATERIAL_TYPE& materialType, const core::vector<video::SConstantLocationNamePair>& constants)
		{
			for (size_t i=0; i<constants.size(); i++)
			{
				if (constants[i].name == "MVP")
				{
					mvpUniformLocation[materialType] = constants[i].location;
					mvpUniformType[materialType] = constants[i].type;
				}
				else if (constants[i].name == "NormalMatrix")
				{
					nUniformLocation[materialType] = constants[i].location;
					nUniformType[materialType] = constants[i].type;
				}
				else if (constants[i].name == "flipFaces")
				{
					flipFacesUniformLocation[materialType] = constants[i].location;
					flipFacesUniformType[materialType] = constants[i].type;
				}
				else if (constants[i].name == "color")
				{
					colorUniformLocation[materialType] = constants[i].location;
					colorUniformType[materialType] = constants[i].type;
				}
				else if (constants[i].name == "nasty")
				{
					nastyUniformLocation[materialType] = constants[i].location;
					nastyUniformType[materialType] = constants[i].type;
				}
				else if (constants[i].name == "lightID")
				{
					lightIDUniformLocation[materialType] = constants[i].location;
					lightIDUniformType[materialType] = constants[i].type;
				}
			}
		}

		virtual void OnSetMaterial(video::IMaterialRendererServices* services, const video::SGPUMaterial& material, const video::SGPUMaterial& lastMaterial)
		{
			currentMat = material.MaterialType;
			services->setShaderConstant(&material.AmbientColor, colorUniformLocation[currentMat], colorUniformType[currentMat], 1);
			services->setShaderConstant(&material.MaterialTypeParam, nastyUniformLocation[currentMat], nastyUniformType[currentMat], 1);
			services->setShaderConstant(&material.userData, lightIDUniformLocation[currentMat], lightIDUniformType[currentMat], 1);
		}

		virtual void OnSetConstants(video::IMaterialRendererServices* services, int32_t userData)
		{
			auto world = services->getVideoDriver()->getTransform(video::E4X3TS_WORLD);
			if (flipFacesUniformLocation[currentMat]>=0)
			{
				auto tmp = world.getPseudoDeterminant();
				if (renderer->isRightHanded())
					tmp = -tmp;
				services->setShaderConstant(tmp.pointer, flipFacesUniformLocation[currentMat], flipFacesUniformType[currentMat], 1);
			}
			if (nUniformLocation[currentMat]>=0)
			{
				float tmp[9];
				world.getSub3x3InverseTransposePacked(tmp);
				services->setShaderConstant(tmp, nUniformLocation[currentMat], nUniformType[currentMat], 1);
			}
			if (mvpUniformLocation[currentMat]>=0)
				services->setShaderConstant(services->getVideoDriver()->getTransform(video::EPTS_PROJ_VIEW_WORLD).pointer(), mvpUniformLocation[currentMat], mvpUniformType[currentMat], 1);
		}

		virtual void OnUnsetMaterial() {}
};

constexpr uint32_t UNFLEXIBLE_MAX_SAMPLES_TODO_REMOVE = 1024u*1024u;

Renderer::Renderer(IVideoDriver* _driver, IAssetManager* _assetManager, ISceneManager* _smgr) :
		m_driver(_driver), m_smgr(_smgr), m_assetManager(_assetManager),
		nonInstanced(static_cast<E_MATERIAL_TYPE>(-1)), m_raygenProgram(0u), m_compostProgram(0u),
		m_rrManager(ext::RadeonRays::Manager::create(m_driver)), m_rightHanded(false),
		m_depth(), m_albedo(), m_normals(), m_lightIndex(), m_accumulation(), m_tonemapOutput(),
		m_colorBuffer(nullptr), m_gbuffer(nullptr), tmpTonemapBuffer(nullptr),
		m_maxSamples(0u), m_workGroupCount{0u,0u}, m_samplesPerDispatch(0u), m_samplesComputed(0u), m_rayCount(0u), m_framesDone(0u),
		m_rayBuffer(), m_intersectionBuffer(), m_rayCountBuffer(),
		m_rayBufferAsRR(nullptr,nullptr), m_intersectionBufferAsRR(nullptr,nullptr), m_rayCountBufferAsRR(nullptr,nullptr),
		nodes(), sceneBound(FLT_MAX,FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX), rrInstances(),
		m_lightCount(0u)
{
	SimpleCallBack* cb = new SimpleCallBack(this);
	nonInstanced = (E_MATERIAL_TYPE)m_driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("../mesh.vert",
		"", "", "", //! No Geometry or Tessellation Shaders
		"../mesh.frag",
		3, EMT_SOLID, //! 3 vertices per primitive (this is tessellation shader relevant only
		cb, //! Our Shader Callback
		0); //! No custom user data
	cb->drop();

	auto includes = m_rrManager->getRadeonRaysGLSLIncludes();
	m_raygenProgram = createComputeShader(
		raygenShaderExtensions+"#define MAX_SAMPLES "+std::to_string(UNFLEXIBLE_MAX_SAMPLES_TODO_REMOVE)+"\n"+
		//"irr/builtin/glsl/ext/RadeonRays/"
		includes->getBuiltinInclude("ray.glsl")+
		lightStruct+
		raygenShader
	);
	m_compostProgram = createComputeShader(
		compostShaderExtensions+
		//"irr/builtin/glsl/ext/RadeonRays/"
		includes->getBuiltinInclude("ray.glsl") +
		lightStruct+
		compostShader
	);

	// TODO: Upgrade to Icosphere!
	{
		auto tmpSphereMesh = m_assetManager->getGeometryCreator()->createSphereMesh(1.f, 16u, 16u);
		auto mb = tmpSphereMesh->getMeshBuffer(0u);

		uint32_t triangleCount = 0u;
		asset::IMeshManipulator::getPolyCount(triangleCount, mb);
		m_precomputedGeodesic.resize(triangleCount);
		for (auto triID=0u; triID<triangleCount; triID++)
		{
			auto triangle = asset::IMeshManipulator::getTriangleIndices(mb,triID);
			std::swap(triangle[1], triangle[2]); // make the sphere face inwards
			for (auto k=0u; k<3u; k++)
				m_precomputedGeodesic[triID][k] = mb->getPosition(triangle[k]);
		}
	}
}

Renderer::~Renderer()
{
	if (m_raygenProgram)
		COpenGLExtensionHandler::extGlDeleteProgram(m_raygenProgram);
	if (m_compostProgram)
		COpenGLExtensionHandler::extGlDeleteProgram(m_compostProgram);
}

void Renderer::init(const SAssetBundle& meshes,
					bool isCameraRightHanded,
					core::smart_refctd_ptr<ICPUBuffer>&& sampleSequence,
					uint32_t rayBufferSize)
{
	deinit();

	m_rightHanded = isCameraRightHanded;

	core::vector<SLight> lights;
	core::vector<uint32_t> lightCDF;
	core::vector<core::vectorSIMDf> lightRadiances;
	auto& lightPDF = reinterpret_cast<core::vector<float>&>(lightCDF); // save on memory

	const ext::MitsubaLoader::CGlobalMitsubaMetadata* globalMeta = nullptr;
	{
		auto contents = meshes.getContents();
		for (auto cpuit = contents.first; cpuit!=contents.second; cpuit++)
		{
			auto cpumesh = static_cast<asset::ICPUMesh*>(cpuit->get());

			auto* meta = cpumesh->getMetadata();

			assert(meta && core::strcmpi(meta->getLoaderName(), ext::MitsubaLoader::IMitsubaMetadata::LoaderName) == 0);
			const auto* meshmeta = static_cast<const ext::MitsubaLoader::IMeshMetadata*>(meta);
			globalMeta = meshmeta->globalMetadata.get();

			//! TODO: fix
			const auto shapeType = meshmeta->getShapeType()==ext::MitsubaLoader::CElementShape::Type::INSTANCE ? ext::MitsubaLoader::CElementShape::Type::SERIALIZED:meshmeta->getShapeType();

			const auto& instances = meshmeta->getInstances();

			auto meshBufferCount = cpumesh->getMeshBufferCount();
			for (auto i=0u; i<meshBufferCount; i++)
			{
				// TODO: get rid of `getMeshBuffer` and `getMeshBufferCount`, just return a range as `getMeshBuffers`
				auto cpumb = cpumesh->getMeshBuffer(i);
				m_rrManager->makeRRShapes(rrShapeCache, &cpumb, (&cpumb)+1);
			}

			for (auto instance : instances)
			{
				auto cpumesh = static_cast<ICPUMesh*>(cpuit->get());
				if (instance.emitter.type != ext::MitsubaLoader::CElementEmitter::Type::INVALID)
				{
					assert(instance.emitter.type==ext::MitsubaLoader::CElementEmitter::Type::AREA);

					uint32_t totalTriangleCount = 0u;
					asset::IMeshManipulator::getPolyCount(totalTriangleCount, cpumesh);

					SLight light;
					light.setFactor(instance.emitter.area.radiance);
					light.analytical = SLight::CachedTransform(instance.tform);

					bool bail = false;
					switch (shapeType)
					{
						case ext::MitsubaLoader::CElementShape::Type::SPHERE:
							light.type = SLight::ET_ELLIPSOID;
							light.analytical.transformCofactors = -light.analytical.transformCofactors;
							break;
						case ext::MitsubaLoader::CElementShape::Type::CYLINDER:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::DISK:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::RECTANGLE:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::CUBE:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::OBJ:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::PLY:
							_IRR_FALLTHROUGH;
						case ext::MitsubaLoader::CElementShape::Type::SERIALIZED:
							light.type = SLight::ET_TRIANGLE;
							if (!totalTriangleCount)
								bail = true;
							break;
						default:
						#ifdef _DEBUG
							assert(false);
						#endif
							bail = true;
							break;
					}
					if (bail)
						continue;

					auto addLight = [&instance,&cpumesh,&lightPDF,&lights,&lightRadiances](auto& newLight,float approxArea) -> void
					{
						float weight = newLight.computeFlux(approxArea) * instance.emitter.area.samplingWeight;
						if (weight <= FLT_MIN)
							return;

						lightPDF.push_back(weight);
						lights.push_back(newLight);
						lightRadiances.push_back(newLight.strengthFactor);
					};
					auto areaFromTriangulationAndMakeMeshLight = [&]() -> float
					{
						double totalSurfaceArea = 0.0;

						uint32_t runningTriangleCount = 0u;
						for (auto i=0u; i<meshBufferCount; i++)
						{
							auto cpumb = cpumesh->getMeshBuffer(i);
							reinterpret_cast<uint32_t&>(cpumb->getMaterial().userData) = lights.size();

							uint32_t triangleCount = 0u;
							asset::IMeshManipulator::getPolyCount(triangleCount,cpumb);
							for (auto triID=0u; triID<triangleCount; triID++)
							{
								auto triangle = asset::IMeshManipulator::getTriangleIndices(cpumb,triID);

								core::vectorSIMDf v[3];
								for (auto k=0u; k<3u; k++)
									v[k] = cpumb->getPosition(triangle[k]);

								float triangleArea = NAN;
								auto triLight = SLight::createFromTriangle(instance.emitter.area.radiance, light.analytical, v, &triangleArea);
								if (light.type==SLight::ET_TRIANGLE)
									addLight(triLight,triangleArea);
								else
									totalSurfaceArea += triangleArea;
							}
						}
						return totalSurfaceArea;
					};

					auto totalArea = areaFromTriangulationAndMakeMeshLight();
					if (light.type!=SLight::ET_TRIANGLE)
						addLight(light,totalArea);
				}
				else // no emissive
				{
					for (auto i=0u; i<meshBufferCount; i++)
					{
						auto cpumb = cpumesh->getMeshBuffer(i);
						reinterpret_cast<uint32_t&>(cpumb->getMaterial().userData) = 0xdeadbeefu;
					}
				}
			}
		}

		auto gpumeshes = m_driver->getGPUObjectsFromAssets<ICPUMesh>(contents.first, contents.second);
		auto cpuit = contents.first;
		for (auto gpuit = gpumeshes->begin(); gpuit!=gpumeshes->end(); gpuit++,cpuit++)
		{
			auto* meta = cpuit->get()->getMetadata();

			assert(meta && core::strcmpi(meta->getLoaderName(),ext::MitsubaLoader::IMitsubaMetadata::LoaderName) == 0);
			const auto* meshmeta = static_cast<const ext::MitsubaLoader::IMeshMetadata*>(meta);

			const auto& instances = meshmeta->getInstances();

			const auto& gpumesh = *gpuit;
			for (auto i=0u; i<gpumesh->getMeshBufferCount(); i++)
				gpumesh->getMeshBuffer(i)->getMaterial().MaterialType = nonInstanced;

			for (auto instance : instances)
			{
				auto node = core::smart_refctd_ptr<IMeshSceneNode>(m_smgr->addMeshSceneNode(core::smart_refctd_ptr(gpumesh)));
				node->setRelativeTransformationMatrix(instance.tform.getAsRetardedIrrlichtMatrix());
				node->updateAbsolutePosition();
				sceneBound.addInternalBox(node->getTransformedBoundingBox());

				nodes.push_back(std::move(node));
			}
		}
		core::vector<int32_t> ids(nodes.size());
		std::iota(ids.begin(), ids.end(), 0);
		auto nodesBegin = &nodes.data()->get();
		m_rrManager->makeRRInstances(rrInstances, rrShapeCache, m_assetManager, nodesBegin, nodesBegin+nodes.size(), ids.data());
		m_rrManager->attachInstances(rrInstances.begin(), rrInstances.end());
	}

	auto renderSize = m_driver->getScreenSize();
	if (globalMeta)
	{
		constantClearColor.set(0.f, 0.f, 0.f, 1.f);
		float constantCombinedWeight = 0.f;
		for (auto emitter : globalMeta->emitters)
		{
			SLight light;

			float weight = 0.f;
			switch (emitter.type)
			{
				case ext::MitsubaLoader::CElementEmitter::Type::CONSTANT:
					constantClearColor += emitter.constant.radiance;
					constantCombinedWeight += emitter.constant.samplingWeight;
					break;
				case ext::MitsubaLoader::CElementEmitter::Type::INVALID:
					break;
				default:
				#ifdef _DEBUG
					assert(false);
				#endif
					//weight = emitter..samplingWeight;
					//light.type = SLight::ET_;
					//light.setFactor(emitter..radiance);
					break;
			}
			if (weight==0.f)
				continue;

			weight *= light.computeFlux(NAN);
			if (weight <= FLT_MIN)
				continue;

			lightPDF.push_back(weight);
			lights.push_back(light);
		}
		// add constant light
		if (constantCombinedWeight>FLT_MIN)
		{
			core::matrix3x4SIMD tform;
			tform.setScale(core::vectorSIMDf().set(sceneBound.getExtent())*core::sqrt(3.f/4.f));
			tform.setTranslation(core::vectorSIMDf().set(sceneBound.getCenter()));
			SLight::CachedTransform cachedT(tform);

			const float areaOfSphere = 4.f * core::PI<float>();

			auto startIx = lights.size();
			float triangulationArea = 0.f;
			for (const auto& tri : m_precomputedGeodesic)
			{
				// make light, correct radiance parameter for domain of integration
				float area = NAN;
				auto triLight = SLight::createFromTriangle(constantClearColor,cachedT,&tri[0],&area);
				// compute flux, abuse of notation on area parameter, we've got the wrong units on strength factor so need to cancel
				float flux = triLight.computeFlux(1.f);
				// add to light list
				float weight = constantCombinedWeight*flux;
				if (weight>FLT_MIN)
				{
					// needs to be weighted be contribution to sphere area
					lightPDF.push_back(weight*area);
					lights.push_back(triLight);
					lightRadiances.push_back(constantClearColor);
				}
				triangulationArea += area;
			}

			for (auto i=startIx; i<lights.size(); i++)
				lightPDF[i] *= areaOfSphere/triangulationArea;
		}

		if (globalMeta->sensors.size())
		{
			const auto& sensor = globalMeta->sensors.front();
			const auto& film = sensor.film;
			renderSize.set(film.cropWidth,film.cropHeight);
		}
	}

	//! TODO: move out into a function `finalizeLights`
	if (lights.size())
	{
		double weightSum = 0.0;
		for (auto i=0u; i<lightPDF.size(); i++)
			weightSum += lightPDF[i];
		assert(weightSum>FLT_MIN);

		constexpr double UINT_MAX_DOUBLE = double(0x1ull<<32ull);

		double weightSumRcp = UINT_MAX_DOUBLE/weightSum;
		double partialSum = 0.0;
		for (auto i=0u; i<lightCDF.size(); i++)
		{
			uint32_t prevCDF = i ? lightCDF[i-1u]:0u;

			double pdf = lightPDF[i];
			partialSum += pdf;

			double inv_prob = NAN;
			double exactCDF = partialSum*weightSumRcp+double(FLT_MIN);
			if (exactCDF<UINT_MAX_DOUBLE)
			{
				lightCDF[i] = static_cast<uint32_t>(exactCDF);
				inv_prob = UINT_MAX_DOUBLE/(lightCDF[i]-prevCDF);
			}
			else
			{
				assert(exactCDF<UINT_MAX_DOUBLE+1.0);
				lightCDF[i] = 0xdeadbeefu;
				inv_prob = 1.0/(1.0-double(prevCDF)/UINT_MAX_DOUBLE);
			}
			lights[i].setFactor(core::vectorSIMDf(lights[i].strengthFactor)*inv_prob);
		}
		lightCDF.back() = 0xdeadbeefu;

		m_lightCount = lights.size();
		m_lightCDFBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createFilledDeviceLocalGPUBufferOnDedMem(lightCDF.size()*sizeof(uint32_t),lightCDF.data()),core::dont_grab);
		m_lightBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createFilledDeviceLocalGPUBufferOnDedMem(lights.size()*sizeof(SLight),lights.data()),core::dont_grab);
		m_lightRadianceBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createFilledDeviceLocalGPUBufferOnDedMem(lightRadiances.size()*sizeof(core::vectorSIMDf),lightRadiances.data()),core::dont_grab);
	}

	//! set up GPU sampler
	{
		m_maxSamples = sampleSequence->getSize()/(sizeof(uint32_t)*MaxDimensions);
		assert(m_maxSamples==UNFLEXIBLE_MAX_SAMPLES_TODO_REMOVE);

		// upload sequence to GPU
		auto gpubuf = m_driver->createFilledDeviceLocalGPUBufferOnDedMem(sampleSequence->getSize(), sampleSequence->getPointer());
		m_sampleSequence = core::smart_refctd_ptr<ITextureBufferObject>(m_driver->addTextureBufferObject(gpubuf, ITextureBufferObject::ETBOF_RG32UI), core::dont_grab);
		gpubuf->drop();

		// create scramble texture
		uint32_t res[3] = {renderSize.Width,renderSize.Height,1u};
		m_scrambleTexture = m_driver->createGPUTexture(ITexture::ETT_2D, &res[0], 1u, EF_R32_UINT);
		{
			core::vector<uint32_t> random(res[0]*res[1]);
			// generate
			{
				core::RandomSampler rng(0xbadc0ffeu);
				for (auto& pixel : random)
					pixel = rng.nextSample();
			}
			// upload
			uint32_t _min[3] = {0u,0u,0u};
			m_scrambleTexture->updateSubRegion(EF_R32_UINT, random.data(), &_min[0], &res[0]);
		}
	}

	m_depth = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_D32_SFLOAT);
	m_albedo = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_R8G8B8_SRGB);
	m_normals = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_R16G16_SNORM);
	m_lightIndex = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_R32_UINT);

	m_accumulation = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_R32G32B32A32_SFLOAT);
	m_tonemapOutput = m_driver->createGPUTexture(ITexture::ETT_2D, &renderSize.Width, 1, EF_R8G8B8_SRGB);

	m_colorBuffer = m_driver->addFrameBuffer();
	m_colorBuffer->attach(EFAP_COLOR_ATTACHMENT0, m_tonemapOutput.get());

	tmpTonemapBuffer = m_driver->addFrameBuffer();
	tmpTonemapBuffer->attach(EFAP_COLOR_ATTACHMENT0, m_accumulation.get());

	m_gbuffer = m_driver->addFrameBuffer();
	m_gbuffer->attach(EFAP_DEPTH_ATTACHMENT, m_depth.get());
	m_gbuffer->attach(EFAP_COLOR_ATTACHMENT0, m_albedo.get());
	m_gbuffer->attach(EFAP_COLOR_ATTACHMENT1, m_normals.get());
	m_gbuffer->attach(EFAP_COLOR_ATTACHMENT2, m_lightIndex.get());

	//
#define WORK_GROUP_DIM 16u
	m_workGroupCount[0] = (renderSize.Width+WORK_GROUP_DIM-1)/WORK_GROUP_DIM;
	m_workGroupCount[1] = (renderSize.Height+WORK_GROUP_DIM-1)/WORK_GROUP_DIM;
	uint32_t pixelCount = renderSize.Width*renderSize.Height;

	auto raygenBufferSize = static_cast<size_t>(pixelCount)*sizeof(::RadeonRays::ray);
	assert(raygenBufferSize<=rayBufferSize);
	auto shadowBufferSize = static_cast<size_t>(pixelCount)*sizeof(int32_t);
	assert(shadowBufferSize<=rayBufferSize);
	m_samplesPerDispatch = rayBufferSize/(raygenBufferSize+shadowBufferSize);
	assert(m_samplesPerDispatch >= 1u);
	printf("Using %d samples\n", m_samplesPerDispatch);

	raygenBufferSize *= m_samplesPerDispatch;
	m_rayBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createDeviceLocalGPUBufferOnDedMem(raygenBufferSize), core::dont_grab);

	shadowBufferSize *= m_samplesPerDispatch;
	m_intersectionBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createDeviceLocalGPUBufferOnDedMem(shadowBufferSize),core::dont_grab);

	m_rayCount = m_samplesPerDispatch*pixelCount;
	m_rayCountBuffer = core::smart_refctd_ptr<IGPUBuffer>(m_driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(uint32_t),&m_rayCount), core::dont_grab);

	m_rayBufferAsRR = m_rrManager->linkBuffer(m_rayBuffer.get(), CL_MEM_READ_WRITE);
	// TODO: clear hit buffer to -1 before usage
	m_intersectionBufferAsRR = m_rrManager->linkBuffer(m_intersectionBuffer.get(), CL_MEM_READ_WRITE);
	m_rayCountBufferAsRR = m_rrManager->linkBuffer(m_rayCountBuffer.get(), CL_MEM_READ_ONLY);

	const cl_mem clObjects[] = { m_rayCountBufferAsRR.second };
	auto objCount = sizeof(clObjects)/sizeof(cl_mem);
	clEnqueueAcquireGLObjects(m_rrManager->getCLCommandQueue(), objCount, clObjects, 0u, nullptr, nullptr);
}

void Renderer::deinit()
{
	auto commandQueue = m_rrManager->getCLCommandQueue();
	clFinish(commandQueue);

	glFinish();

	// create a screenshot
	if (m_tonemapOutput)
		ext::ScreenShot::dirtyCPUStallingScreenshot(m_driver, m_assetManager, "screenshot.png", m_tonemapOutput.get());

	// release OpenCL objects and wait for OpenCL to finish
	const cl_mem clObjects[] = { m_rayCountBufferAsRR.second };
	auto objCount = sizeof(clObjects) / sizeof(cl_mem);
	clEnqueueReleaseGLObjects(commandQueue, objCount, clObjects, 1u, nullptr, nullptr);
	clFlush(commandQueue);
	clFinish(commandQueue);

	if (m_colorBuffer)
	{
		m_driver->removeFrameBuffer(m_colorBuffer);
		m_colorBuffer = nullptr;
	}
	if (m_gbuffer)
	{
		m_driver->removeFrameBuffer(m_gbuffer);
		m_gbuffer = nullptr;
	}
	if (tmpTonemapBuffer)
	{
		m_driver->removeFrameBuffer(tmpTonemapBuffer);
		tmpTonemapBuffer = nullptr;
	}

	m_depth = m_albedo = m_normals = m_lightIndex = m_accumulation = m_tonemapOutput = nullptr;

	if (m_rayBufferAsRR.first)
	{
		m_rrManager->deleteRRBuffer(m_rayBufferAsRR.first);
		m_rayBufferAsRR = {nullptr,nullptr};
	}
	if (m_intersectionBufferAsRR.first)
	{
		m_rrManager->deleteRRBuffer(m_intersectionBufferAsRR.first);
		m_intersectionBufferAsRR = {nullptr,nullptr};
	}
	if (m_rayCountBufferAsRR.first)
	{
		m_rrManager->deleteRRBuffer(m_rayCountBufferAsRR.first);
		m_rayCountBufferAsRR = {nullptr,nullptr};
	}
	m_rayBuffer = m_intersectionBuffer = m_rayCountBuffer = nullptr;
	m_samplesPerDispatch = 0u;
	m_samplesComputed = 0u;
	m_rayCount = 0u;
	m_framesDone = 0u;
	m_workGroupCount[0] = m_workGroupCount[1] = 0u;
	m_maxSamples = 0u;

	for (auto& node : nodes)
		node->remove();
	nodes.clear();
	sceneBound = core::aabbox3df(FLT_MAX,FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX);
	m_rrManager->deleteShapes(rrShapeCache.begin(),rrShapeCache.end());
	rrShapeCache.clear();
	m_rrManager->detachInstances(rrInstances.begin(),rrInstances.end());
	m_rrManager->deleteInstances(rrInstances.begin(),rrInstances.end());
	rrInstances.clear();

	constantClearColor.set(0.f,0.f,0.f,1.f);
	m_lightCount = 0u;
	m_lightCDFBuffer = m_lightBuffer = m_lightRadianceBuffer = nullptr;

	// start deleting objects
	m_sampleSequence = nullptr;
	m_scrambleTexture = nullptr;

	m_rightHanded = false;
}

void Renderer::render()
{
	m_driver->setRenderTarget(m_gbuffer);
	{ // clear
		m_driver->clearZBuffer();
		float zero[4] = { 0.f,0.f,0.f,0.f };
		m_driver->clearColorBuffer(EFAP_COLOR_ATTACHMENT0, zero);
		m_driver->clearColorBuffer(EFAP_COLOR_ATTACHMENT1, zero);
		uint32_t clearLightID[4] = {((constantClearColor>core::vectorSIMDf(0.f))&core::vectorSIMDu32(~0u,~0u,~0u,0u)).any() ? (m_lightCount-1u):0xdeadbeefu,0,0,0};
		m_driver->clearColorBuffer(EFAP_COLOR_ATTACHMENT2, clearLightID);
	}

	auto camera = m_smgr->getActiveCamera();
	auto prevViewProj = camera->getConcatenatedMatrix();

	//! This animates (moves) the camera and sets the transforms
	//! Also draws the meshbuffer
	m_smgr->drawAll();

	auto currentViewProj = camera->getConcatenatedMatrix();
	if (!core::equals(prevViewProj,currentViewProj,core::ROUNDING_ERROR<core::matrix4SIMD>()*100.0))
	{
		m_samplesComputed = 0u;
		m_framesDone = 0u;
	}

	auto rSize = m_depth->getSize();

	// generate rays
	{
		GLint prevProgram;
		glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);

		STextureSamplingParams params;
		params.MaxFilter = ETFT_NEAREST_NEARESTMIP;
		params.MinFilter = ETFT_NEAREST_NEARESTMIP;
		params.UseMipmaps = 0;

		const COpenGLDriver::SAuxContext* foundConst = static_cast<COpenGLDriver*>(m_driver)->getThreadContext();
		COpenGLDriver::SAuxContext* found = const_cast<COpenGLDriver::SAuxContext*>(foundConst);
		found->setActiveTexture(0, core::smart_refctd_ptr(m_depth), params);
		found->setActiveTexture(1, core::smart_refctd_ptr(m_normals), params);
		found->setActiveTexture(2, core::smart_refctd_ptr(m_albedo), params);
		found->setActiveTexture(3, core::smart_refctd_ptr(m_sampleSequence), params);
		found->setActiveTexture(4, core::smart_refctd_ptr(m_scrambleTexture), params);

		COpenGLExtensionHandler::extGlUseProgram(m_raygenProgram);

		const COpenGLBuffer* buffers[] = { static_cast<const COpenGLBuffer*>(m_rayBuffer.get()),static_cast<const COpenGLBuffer*>(m_lightCDFBuffer.get()),static_cast<const COpenGLBuffer*>(m_lightBuffer.get()) };
		ptrdiff_t offsets[] = { 0,0,0 };
		ptrdiff_t sizes[] = { m_rayBuffer->getSize(),m_lightCDFBuffer->getSize(),m_lightBuffer->getSize() };
		found->setActiveSSBO(0, sizeof(offsets)/sizeof(ptrdiff_t), buffers, offsets, sizes);

		{
			auto camPos = core::vectorSIMDf().set(camera->getAbsolutePosition());
			COpenGLExtensionHandler::pGlProgramUniform3fv(m_raygenProgram, 0, 1, camPos.pointer);

			float uDepthLinearizationConstant;
			{
				auto projMat = camera->getProjectionMatrix();
				auto* row = projMat.rows;
				uDepthLinearizationConstant = -row[3][2]/(row[3][2]-row[2][2]);
			}
			COpenGLExtensionHandler::pGlProgramUniform1fv(m_raygenProgram, 1, 1, &uDepthLinearizationConstant);

			auto frustum = camera->getViewFrustum();
			core::matrix4SIMD uFrustumCorners;
			uFrustumCorners.rows[1] = frustum->getFarLeftDown();
			uFrustumCorners.rows[0] = frustum->getFarRightDown()-uFrustumCorners.rows[1];
			uFrustumCorners.rows[1] -= camPos;
			uFrustumCorners.rows[3] = frustum->getFarLeftUp();
			uFrustumCorners.rows[2] = frustum->getFarRightUp()-uFrustumCorners.rows[3];
			uFrustumCorners.rows[3] -= camPos;
			COpenGLExtensionHandler::pGlProgramUniformMatrix4fv(m_raygenProgram, 2, 1, false, uFrustumCorners.pointer()); // important to say no to transpose

			COpenGLExtensionHandler::pGlProgramUniform2uiv(m_raygenProgram, 3, 1, rSize);

			uint32_t uSamples_ImageWidthSamples[2] = {m_samplesPerDispatch,rSize[0]*m_samplesPerDispatch};
			COpenGLExtensionHandler::pGlProgramUniform2uiv(m_raygenProgram, 4, 1, uSamples_ImageWidthSamples);

			COpenGLExtensionHandler::pGlProgramUniform1uiv(m_raygenProgram, 5, 1, &m_samplesComputed);
			m_samplesComputed += m_samplesPerDispatch;

			float uImageSize2Rcp[4] = {1.f/static_cast<float>(rSize[0]),1.f/static_cast<float>(rSize[1]),0.5f/static_cast<float>(rSize[0]),0.5f/static_cast<float>(rSize[1])};
			COpenGLExtensionHandler::pGlProgramUniform4fv(m_raygenProgram, 6, 1, uImageSize2Rcp);
		}

		COpenGLExtensionHandler::pGlDispatchCompute(m_workGroupCount[0], m_workGroupCount[1], 1);

		COpenGLExtensionHandler::extGlUseProgram(prevProgram);

		// probably wise to flush all caches
		COpenGLExtensionHandler::pGlMemoryBarrier(GL_ALL_BARRIER_BITS);
	}

	// do radeon rays
	m_rrManager->update(rrInstances);
	if (m_rrManager->hasImplicitCL2GLSync())
		glFlush();
	else
		glFinish();

	auto commandQueue = m_rrManager->getCLCommandQueue();
	{
		const cl_mem clObjects[] = {m_rayBufferAsRR.second,m_intersectionBufferAsRR.second};
		auto objCount = sizeof(clObjects)/sizeof(cl_mem);

		cl_event acquired = nullptr;
		clEnqueueAcquireGLObjects(commandQueue,objCount,clObjects,0u,nullptr,&acquired);

		clEnqueueWaitForEvents(commandQueue,1u,&acquired);
		m_rrManager->getRadeonRaysAPI()->QueryOcclusion(m_rayBufferAsRR.first,m_rayCountBufferAsRR.first,m_rayCount,m_intersectionBufferAsRR.first,nullptr,nullptr);
		cl_event raycastDone = nullptr;
		clEnqueueMarker(commandQueue,&raycastDone);

		if (m_rrManager->hasImplicitCL2GLSync())
		{
			clEnqueueReleaseGLObjects(commandQueue, objCount, clObjects, 1u, &raycastDone, nullptr);
			clFlush(commandQueue);
		}
		else
		{
			cl_event released;
			clEnqueueReleaseGLObjects(commandQueue, objCount, clObjects, 1u, &raycastDone, &released);
			clFlush(commandQueue);
			clWaitForEvents(1u, &released);
		}
	}

	// use raycast results
	{
		GLint prevProgram;
		glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);

		STextureSamplingParams params;
		params.MaxFilter = ETFT_NEAREST_NEARESTMIP;
		params.MinFilter = ETFT_NEAREST_NEARESTMIP;
		params.UseMipmaps = 0;

		const COpenGLDriver::SAuxContext* foundConst = static_cast<COpenGLDriver*>(m_driver)->getThreadContext();
		COpenGLDriver::SAuxContext* found = const_cast<COpenGLDriver::SAuxContext*>(foundConst);
		found->setActiveTexture(0, core::smart_refctd_ptr(m_lightIndex), params);

		COpenGLExtensionHandler::extGlBindImageTexture(0u,static_cast<COpenGLFilterableTexture*>(m_accumulation.get())->getOpenGLName(),0,false,0,GL_READ_WRITE,GL_RGBA32F);

		COpenGLExtensionHandler::extGlUseProgram(m_compostProgram);

		const COpenGLBuffer* buffers[] ={	static_cast<const COpenGLBuffer*>(m_rayBuffer.get()),
											static_cast<const COpenGLBuffer*>(m_intersectionBuffer.get()),
											static_cast<const COpenGLBuffer*>(m_lightRadianceBuffer.get())
										};
		ptrdiff_t offsets[] = { 0,0,0 };
		ptrdiff_t sizes[] = { m_rayBuffer->getSize(),m_intersectionBuffer->getSize(),m_lightRadianceBuffer->getSize() };
		found->setActiveSSBO(0, 3, buffers, offsets, sizes);

		{
			COpenGLExtensionHandler::pGlProgramUniform2uiv(m_compostProgram, 0, 1, rSize);

			uint32_t uSamples_ImageWidthSamples[2] = {m_samplesPerDispatch,rSize[0]*m_samplesPerDispatch};
			COpenGLExtensionHandler::pGlProgramUniform2uiv(m_compostProgram, 1, 1, uSamples_ImageWidthSamples);

			m_framesDone++;
			float uRcpFramesDone = 1.0/double(m_framesDone);
			COpenGLExtensionHandler::pGlProgramUniform1fv(m_compostProgram, 2, 1, &uRcpFramesDone);
		}

		COpenGLExtensionHandler::pGlDispatchCompute(m_workGroupCount[0], m_workGroupCount[1], 1);

		COpenGLExtensionHandler::extGlBindImageTexture(0u, 0u, 0, false, 0, GL_INVALID_ENUM, GL_INVALID_ENUM);

		COpenGLExtensionHandler::extGlUseProgram(prevProgram);

		COpenGLExtensionHandler::pGlMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT);
	}

	// TODO: tonemap properly
	{
		auto oldVP = m_driver->getViewPort();
		m_driver->blitRenderTargets(tmpTonemapBuffer, m_colorBuffer, false, false, {}, {}, true);
		m_driver->setViewPort(oldVP);
	}
}
#endif


text:
try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

readme = open('README.rst').read()
history = open('HISTORY.rst').read().replace('.. :changelog:', '')

requirements = [
    # TODO: put package requirements here
]

test_requirements = [
    # TODO: put package test requirements here
]

setup(
    name='manutils',
    version='0.0.1',
    description='manutils is a collection of utils and libraries to help package maintainers easily create and maintain man pages for Python projects.',
    long_description=readme + '\n\n' + history,
    author='Oz N Tiram',
    author_email='oz.tiram@gmail.com',
    url='https://github.com/oz123/man-utils',
    packages=[
        'manutils',
    ],
    package_dir={'manutils':
                 'manutils'},
    include_package_data=True,
    install_requires=requirements,
    license="BSD",
    zip_safe=False,
    keywords='man-utils, man pages',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
    ],
    test_suite='tests',
    tests_require=test_requirements
)


text:
/**
 * @fileoverview This file is generated by the Angular 2 template compiler.
 * Do not edit.
 * @suppress {suspiciousCode,uselessCode,missingProperties}
 */
 /* tslint:disable */

import * as import0 from '@angular/material/tabs/tab-label';
import * as import1 from '@angular/core/src/linker/view';
export class Wrapper_MdTabLabel {
  /*private*/ _eventHandler:Function;
  context:import0.MdTabLabel;
  /*private*/ _changed:boolean;
  constructor(p0:any,p1:any) {
    this._changed = false;
    this.context = new import0.MdTabLabel(p0,p1);
  }
  ngOnDetach(view:import1.AppView<any>,componentView:import1.AppView<any>,el:any):void {
  }
  ngOnDestroy():void {
  }
  ngDoCheck(view:import1.AppView<any>,el:any,throwOnChange:boolean):boolean {
    var changed:any = this._changed;
    this._changed = false;
    return changed;
  }
  checkHost(view:import1.AppView<any>,componentView:import1.AppView<any>,el:any,throwOnChange:boolean):void {
  }
  handleEvent(eventName:string,$event:any):boolean {
    var result:boolean = true;
    return result;
  }
  subscribe(view:import1.AppView<any>,_eventHandler:any):void {
    this._eventHandler = _eventHandler;
  }
}


text:
module Chartmogul
  class Configuration
    attr_accessor :api_host, :response_type
    attr_accessor :account_token, :secret_key

    def initialize
      @api_host ||= "https://api.chartmogul.com/v1"
      @response_type ||= :object
    end

    def response_klass
      response_object || Hash
    end

    private

    def response_object
      if response_as_object?
        ResponseObject
      end
    end

    def response_as_object?
      response_type.to_s.casecmp("object") == 0
    end
  end

  def self.configure
    yield configuration
  end

  def self.configuration
    @configuration ||= Configuration.new
  end

  def self.configuration=(config)
    @configuration = config
  end
end