text:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
*
*/
class Berita extends MY_Controller
{

	public function __construct()
	{
		$this->_accessable = TRUE;
		parent::__construct();

		$this->load->helper(array('dump', 'form', 'potong_teks', 'cek_file'));
		$this->load->library(array('form_validation', 'slug'));
		$this->load->model(array('berita_m'));

		$this->slug_config($this->berita_m->table, 'judul');

		$q = $this->berita_m->where('status','1')->where('tanggal_publish <=', date('Y-m-d'))->update(array('status' => '0'));
	}

    public function index($page = NULL)
    {
        if(!$page){
            $this->go('berita/page/1');
        }
        // Get Filter and Order By from Session
        $filter = $this->session->userdata('fp');
        $order_by = $this->session->userdata('obp');
        $order_type = $this->session->userdata('otp');
        // Setting up Pagination
        $this->load->library('pagination');
        $total_data = $this->berita_m->where($filter, 'like', '%')->count_rows();

        $data['beritas'] = $this->berita_m
            ->where('status',array('0', '1'))
            ->where('id_organisasi', $this->ion_auth->get_current_id_org())
            ->order_by($order_by, $order_type)
            ->order_by('tanggal_publish','asc')
            ->limit(5)
            ->fields('judul, isi, slug, gambar, tanggal_publish, status')
            ->with_akun('fields:username')
            ->paginate(10, $total_data, $page);
        $data['pagination'] = $this->berita_m->all_pages;
        $this->render('berita/berita', $data);
	}

    /**
     * Use to make URI looks good
     *
     * @param int $page
     */
    public function page($page = 1)
    {
        $this->index($page);
    }

    /**
     * Order the data
     *
     * @param $order_by
     * @param string $order_type
     */
    public function urut($order_by, $order_type = 'asc')
    {
        $this->session->unset_userdata(array('obpbe', 'otpbe'));
        $this->session->set_userdata('obpbe', $order_by);
        $this->session->set_userdata('otpbe', $order_type);
        $this->go('berita');
    }

    /**
     * Call when user want to search specific data
     * Store filter in Session
     */
    public function search()
    {
        $this->session->unset_userdata('fpbe');
        $this->session->set_userdata('fpbe', $this->input->post());
        $this->go('berita');
    }

    /**
     * Reset any filter made while user search specific data
     */
    public function refresh()
    {
        $this->session->unset_userdata(array('fpbe', 'obpbe', 'otpbe'));
        $this->go('berita');
    }

    /**
     * View for Add New Penduduk
     */
    public function tambah()
    {
        $current_id_org = $this->ion_auth->get_current_id_org();
        $data['kelurahan'] = $this->organisasi->get(array('id' => $current_id_org))->nama;
        $data['pekerjaan'] = $this->pekerjaan->get_all();
        $this->render('kependudukan/create', $data);
    }

	public function draf()
	{
		$data['beritas'] = $this->berita_m
		->where('status', '2')
		->where('id_organisasi', $this->ion_auth->get_current_id_org())
		->order_by('tanggal_publish','asc')
		->limit(5)
		->fields('judul, isi, slug, gambar, tanggal_publish, status')
		->with_akun('fields:username')
		->get_all();

		$this->render('berita/draf', $data);
	}

	public function arsip()
	{
		$data['beritas'] = $this->berita_m
		->where('id_organisasi', $this->ion_auth->get_current_id_org())
		->order_by('tanggal_publish','asc')
		->limit(5)
		->fields('judul, isi, slug, gambar, tanggal_publish, status')
		->with_akun('fields:username')
		->only_trashed()
		->get_all();

		$this->render('berita/arsip', $data);
	}

	public function selengkapnya($slug = NULL)
	{
		if (!is_null($slug) && !empty($slug)) {
			$query = $this->berita_m
			->fields('judul, isi, slug, gambar, tanggal_publish, status, deleted_at')
			->with_akun('fields:username')
			->get(array(
				'slug' => $slug,
				'id_organisasi' => $this->ion_auth->get_current_id_org()
				));

			if ($query === FALSE) {
				$this->message('Berita tidak ditemukan', 'warning');
				$this->go('berita');
			}else{
				$data['berita'] = $query;
				$this->render('berita/detail', $data);
			}
		}else{
			$this->message('Berita tidak ditemukan', 'warning');
			$this->go('berita');
		}
	}

	public function tulis($optionalData = NULL, $optStatus = FALSE)
	{
		$this->generateCsrf();

		if ($optStatus) {
			$data['berita'] = $optionalData['prev_input'];
			$this->message($optionalData['msg'], $optionalData['msg_type']);
			$this->render('berita/tulis', $data);
		}else{
			$this->render('berita/tulis');
		}
	}

	public function sunting($slug = NULL, $optionalData = NULL, $optStatus = FALSE)
	{
		if (!is_null($slug) && !empty($slug)) {
			$this->generateCsrf();

			if ($optStatus) {
				$data['berita'] = $optionalData['prev_input'];
				$this->message($optionalData['msg'], $optionalData['msg_type']);
				$this->render('berita/sunting', $data);
			}else{
				$query = $this->berita_m
				->fields('judul, isi, slug, gambar, tanggal_publish, status, deleted_at')
				->as_array()
				->get(array(
					'slug' => $slug,
					'id_organisasi' => $this->ion_auth->get_current_id_org()
					));

				if ($query === FALSE) {
					$this->message('Berita tidak ditemukan', 'warning');
					$this->go('berita');
				}else{
					$data['berita'] = $query;
					$this->render('berita/sunting', $data);
				}
			}
		}else{
			$this->message('Berita tidak ditemukan', 'warning');
			$this->go('berita');
		}
	}

	public function simpan()
	{
		$today = date('Y-m-d');
		$data = $this->input->post();

		if(empty($data['status'])){
			if (!(empty($data['tanggal_publish'])) && $data['tanggal_publish'] > $today) {
				$data['status'] = '1';
			}elseif (!(empty($data['tanggal_publish'])) && $data['tanggal_publish'] == $today) {
				$data['status'] = '0';
			}
			else{
				$data['msg'] = 'Pilih tanggal sama atau lebih dari tanggal sekarang';
				$data['msg_type'] = 'warning';
				$data['prev_input'] = $data;
				$this->tulis($data, TRUE);
			}
		}

		$data['slug'] = $this->slug->create_uri($data);

		if (!empty($_FILES['gambar']['name'])) {
			$data['gambar']= $this->do_upload('gambar');
		} else {
			$data['gambar'] = 'default.png';
		}

		$data['id_organisasi'] = $this->ion_auth->get_current_id_org();

		$query = $this->berita_m->from_form(NULL, array(
			'id_organisasi' => $data['id_organisasi'],
			'isi' => $data['isi'],
			'slug' => $data['slug'],
			'gambar' => $data['gambar'],
			'status' => $data['status'],
			'tanggal_publish' => $data['tanggal_publish']
			))->insert();

		if ($query === FALSE) {
			$data['msg'] = 'Terjadi kesalahan dalam membuat berita';
			$data['msg_type'] = 'warning';
			$data['prev_input'] = $data;
			$this->tulis($data, TRUE);
		}else{
			if ($data['status'] == '2') {
				$this->message('Berhasil Berita Disimpan di Draft', 'success');
				$this->go('berita/draf');
			}else{
				$this->message('Berhasil membuat Berita Baru', 'success');
				$this->go('berita');
			}
		}
	}

	public function ubah($slug = NULL)
	{
		//AMBIL DATA YG DIPERLUKAN
		$query = $this->berita_m
		->fields('gambar, status, deleted_at')
		->get(array(
			'slug' => $slug,
			'id_organisasi' => $this->ion_auth->get_current_id_org()
			));

		if ($query === FALSE) {
			$this->message('Terjadi kesalahan pada sistem', 'danger');
			$this->go('berita/sunting/'.$slug);
		}else{
			$data = $this->input->post();
			$data['status'] = $query->status;
			$data['deleted_at'] = $query->deleted_at;

			$today = date('Y-m-d');

			if($data['status'] != '2' || is_null($data['deleted_at'])){
				if (!(empty($data['tanggal_publish'])) && $data['tanggal_publish'] > $today) {
					$data['status'] = '1';
				}elseif (!(empty($data['tanggal_publish'])) && $data['tanggal_publish'] == $today) {
					$data['status'] = '0';
				}
				else{
					$data['msg'] = 'Pilih tanggal sama atau lebih dari tanggal sekarang';
					$data['msg_type'] = 'warning';
					$data['prev_input'] = $data;
					$this->sunting($slug, $data, TRUE);
				}
			}

			$data['slug'] = $this->slug->create_uri($data);

			if (!empty($_FILES['gambar']['name'])) {
				if ($this->delete_files($query->gambar)) {
					$data['gambar']= $this->do_upload('gambar');
				}else{
					$data['msg'] = 'Coba lagi nanti. Terjadi kesalahan pada saat mengunggah gambar.';
					$data['msg_type'] = 'warning';
					$data['prev_input'] = $data;
					$this->sunting($slug, $data, TRUE);
				}
			} else {
				$data['gambar'] = 'default.png';
			}

			$query = $this->berita_m->from_form(NULL, array(
				'isi' => $data['isi'],
				'slug' => $data['slug'],
				'gambar' => $data['gambar'],
				'status' => $data['status'],
				'tanggal_publish' => $data['tanggal_publish']
				), array('slug' => $slug))->update();

			if ($query === FALSE) {
				$data['msg'] = 'Terjadi kesalahan saat mengubah berita';
				$data['msg_type'] = 'warning';
				$data['prev_input'] = $data;
				$this->sunting($slug, $data, TRUE);
			}else{
				if ($data['status'] == '2') {
					$this->message('Berhasil Berita Disimpan di Draft', 'success');
					$this->go('berita/draf');
				}else{
					$this->message('Berhasil mengubah Berita', 'success');
					$this->go('berita');
				}
			}
		}
	}

	public function arsipkan($slug = NULL)
	{
		if (is_null($slug) || empty($slug)) {
			$this->message('Berita tidak ditemukan', 'danger');
			$this->go('berita');
		}else{
			//ambil status berita sesuai slug
			$q_status = $this->berita_m->fields('status')->as_array()->get(array('slug' => $slug));
			if ($q_status === FALSE) {
				$this->message('Berita tidak ditemukan', 'danger');
				$this->go('berita');
			}else{
				//arsipkan
				$query = $this->berita_m->delete(array('slug' => $slug));
				if ($query === FALSE) {
					$this->message('Terjadi kesalahan sistem saat mengarsipkan berita! Coba lagi nanti.', 'danger');
				}else{
					$this->message('Berita berhasil diarsipkan', 'success');
				}
				$this->redirectBerita($q_status);
			}
		}
	}

	public function publikasikan($slug = NULL)
	{
		if (is_null($slug) || empty($slug)) {
			$this->message('Draf tidak ditemukan', 'danger');
		}else{
			//publikasikan
			$query = $this->berita_m
			->where('slug', $slug)
			->update(array(
				'tanggal_publish' => date('Y-m-d'),
				'status' => '0'
				));
			if ($query === FALSE) {
				$this->message('Terjadi kesalahan pada sistem saat mempublikasikan draf! Coba lagi nanti.', 'danger');
			}else{
				$this->message('Draf berhasil dipublikasikan', 'success');
			}
		}
		$this->go('berita/draf');
	}

	public function kembalikan($slug = NULL)
	{
		if (is_null($slug) || empty($slug)) {
			$this->message('Arsip tidak ditemukan', 'danger');
		}else{
			//kembalikan
			$query = $this->berita_m->restore(array('slug' => $slug));
			if ($query === FALSE) {
				$this->message('Terjadi kesalahan pada sistem saat mengembalikan arsip! Coba lagi nanti.', 'danger');
			}else{
				$this->message('Arsip berhasil dikembalikan', 'success');
			}
		}
		$this->go('berita/arsip');
	}

	public function hapus($slug = NULL)
	{
		if (is_null($slug) || empty($slug)) {
			$this->message('Berita tidak ditemukan', 'danger');
			$this->go('berita');
		}else{
			//ambil atribut berita yg diperlukan sesuai slug
			$q = $this->berita_m->fields('status, deleted_at')->as_array()->get(array('slug' => $slug));
			if ($q === FALSE) {
				$this->message('Berita tidak ditemukan', 'danger');
				$this->go('berita');
			}else{
				//hapus
				$query = $this->berita_m->force_delete(array('slug' => $slug));
				if ($query === FALSE) {
					$this->message('Terjadi kesalahan sistem saat menghapus berita! Coba lagi nanti.', 'danger');
				}else{
					$this->message('Berita berhasil dihapus', 'success');
				}
				$this->redirectBerita($q);
			}
		}
	}

	private function redirectBerita($data)
	{
		if (!is_null($data['deleted_at'])) {
			$this->go('berita/arsip');
		}else{
			if ($data['status'] == '2') {
				$this->go("berita/draf");
			}else{
				$this->go('berita');
			}
		}
	}

	private function do_upload($input_name)
	{
		$this->load->helper('prefix_unik');
		$config['file_name'] = prefix_unik(1). '.' .pathinfo($_FILES[$input_name]['name'], PATHINFO_EXTENSION);
		$config['upload_path'] = './assets/images/berita/';
		$config['allowed_types'] = 'jpg|jpeg|png';
		$config['max_size'] = 10000;

		$this->load->library('upload', $config);

		if (!$this->upload->do_upload($input_name)) {
			$this->message($this->upload->display_errors(), 'danger');
			$this->redirectBerita($input_name);
		}else{
			$file_date = $this->upload->data();
			$link = $file_date['file_name'];
			return $link;
		}
	}

	private function delete_files($filename){
		$path = $_SERVER['DOCUMENT_ROOT'].'assets/images/berita/';
		$get_file = $path.$filename;
		if(file_exists($get_file)){
			unlink($get_file);
			return TRUE;
		}
		return FALSE;
	}
}


text:
export const index = (req, res, next) => {
  res.send(
    "You must use the lastest version of Chrome, Safari, Firefox, or Internet Explorer to use Artsy Writer."
  )
}

redpajama_set_name: RedPajamaGithub


text:
var $ = require('jquery')
var d3 = require('d3')
var merge = require('merge')
var Handlebars = require('handlebars')
var fs = require('fs')
var path = require('path')
var cycle = require('cycle')
var david = require('../david')
var transformData = require('./transform-data')
var graph = require('./graph')

require('../vendor/stackable')
require('../vendor/jquery.fancybox.js')
require('../vendor/jquery.ba-bbq.js')
require('../vendor/jquery.ba-hashchange.js')

var embedTmpl = Handlebars.compile(fs.readFileSync(path.join(__dirname, '..', '..', '..', 'dist', 'inc', 'embed-badge.html'), {encoding: 'utf8'}))
var embedTmplType = Handlebars.compile(fs.readFileSync(path.join(__dirname, '..', '..', '..', 'dist', 'inc', 'embed-badge-type.html'), {encoding: 'utf8'}))

$('#status-page').each(function () {
  var state = {
    info: $.bbq.getState('info', true) || 'dependencies',
    view: $.bbq.getState('view', true) || 'table'
  }

  var query = $.deparam($.param.querystring())
  // Normalized pathname for use with XHR requests
  var pathname = window.location.pathname

  if (pathname[pathname.length - 1] !== '/') {
    pathname += '/'
  }

  function initInfo (container, depsType) {
    var graphJsonUrl = (depsType ? depsType + '-' : '') + 'graph.json' + (query.path ? '?path=' + encodeURIComponent(query.path) : '')

    $('.dep-table table', container).stacktable()

    // Load the graph data and render when change view
    var graphLoaded = false
    var graphContainer = $('.dep-graph', container)
    var tableContainer = $('.dep-table', container)

    graphContainer.hide()

    function initGraph () {
      var loading = david.createLoadingEl()
      graphContainer.prepend(loading)

      d3.json(pathname + graphJsonUrl, function (err, json) {
        if (err) {
          console.error('Failed to load graph data', err)
          return loading.empty().text('Error occurred retrieving graph data')
        }

        transformData(cycle.retrocycle(json), function (er, root) {
          var vis = graph.create(container)
          // Initialize the display to show a few nodes.
          root.children.forEach(graph.toggleChildren)
          graph.update(vis, root)
          loading.remove()
        })
      })
    }

    var viewSwitchers = $('.switch a', container)

    viewSwitchers.click(function (e) {
      e.preventDefault()
      merge(state, $.deparam.fragment($(this).attr('href')))
      $.bbq.pushState(state)
    })

    function onHashChange () {
      merge(state, $.bbq.getState())

      viewSwitchers.removeClass('selected')

      if (state.view !== 'tree') {
        graphContainer.hide()
        tableContainer.fadeIn()
        viewSwitchers.first().addClass('selected')
      } else {
        tableContainer.hide()
        graphContainer.fadeIn()
        viewSwitchers.last().addClass('selected')

        if (!graphLoaded) {
          graphLoaded = true
          initGraph()
        }
      }
    }

    /* Init changes links */

    $('.changes-icon', container).click(function (e) {
      e.preventDefault()

      var row = $(this).closest('tr')
      var container = $('<div class="changes-popup"/>').append(david.createLoadingEl())
      var name, from, to

      if (row.closest('table').is('.stacktable')) {
        name = $('a:first-child', row).text()
        from = $('.st-val', row.next()).text()
        to = $('.st-val', row.next().next()).text()
      } else {
        name = $('.dep > a:first-child', row).text()
        from = $('.required', row).text()
        to = $('.stable', row).text()
      }

      $.fancybox.open(container)

      $.ajax({
        url: '/package/' + name + '/changes.json',
        dataType: 'json',
        data: {from: from, to: to},
        success: function (data) {
          data.from = from
          data.to = to

          var tpl = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'dist', 'inc', 'changes.html'), {encoding: 'utf8'})
          container.html(Handlebars.compile(tpl)(data))
          $.fancybox.update()
        },
        error: function () {
          container.html(fs.readFileSync(path.join(__dirname, '..', '..', '..', 'dist', 'inc', 'changelog-er.html'), {encoding: 'utf8'}))
          $.fancybox.update()
        }
      })
    })

    $(window).bind('hashchange', onHashChange)

    onHashChange()
  }

  var badges = $('.badge')
  var depInfoLoaded = {}
  var depInfos = $('.dep-info')
  var depSwitchers = $('#dep-switch a')
  var repo = $('#repo')

  badges.click(function () {
    if (!$($(this).attr('href')).size()) {
      var data = {type: $(this).data('type'), user: repo.data('user'), repo: repo.data('repo'), path: repo.data('path'), ref: repo.data('ref')}
      var ct = $(data.type ? embedTmplType(data) : embedTmpl(data))

      $('input', ct).each(function () {
        var clicked = false
        var embedCode = $(this)

        embedCode.click(function () {
          if (!clicked) {
            embedCode.select()
            clicked = true
          }
        })
      })

      $('select', ct).change(function () {
        $('.theme', ct).hide()
        $('.theme-' + $(this).val(), ct).show()
      })

      $('.theme', ct).not('.theme-svg').hide()

      repo.append(ct)
    }
  })

  badges.fancybox()

  depSwitchers.click(function (e) {
    e.preventDefault()
    merge(state, $.deparam.fragment($(this).attr('href')))
    $.bbq.pushState(state)
  })

  // Hash change for info switch
  function onHashChange () {
    merge(state, $.bbq.getState())
    depSwitchers.removeClass('selected')

    var badge, depInfo

    if (!state.info || state.info === 'dependencies') {
      badge = badges.first()
      depInfo = depInfos.first()
      depSwitchers.filter("[href='#info=dependencies']").addClass('selected')
    } else {
      var type = state.info.replace('Dependencies', '')

      badge = $('#' + type + '-status')
      depInfo = $('#' + type + '-dep-info')
      depSwitchers.filter("[href='#info=" + type + "Dependencies']").addClass('selected')

      if (!depInfoLoaded[type]) {
        depInfoLoaded[type] = true

        var loading = david.createLoadingEl()

        depInfo.prepend(loading)

        var infoUrl = pathname + type + '-info.json' + (query.path ? '?path=' + encodeURIComponent(query.path) : '')

        $.getJSON(infoUrl, function (data) {
          var tpl = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'dist', 'inc', 'info.html'), {encoding: 'utf8'})
          loading.remove()
          depInfo.html(Handlebars.compile(tpl)({ info: data }))
          initInfo(depInfo, type)
        })
      }
    }

    depInfos.not(depInfo).hide()
    depInfo.fadeIn()

    badges.not(badge).hide()
    badge.show()
  }

  $(window).bind('hashchange', onHashChange)

  onHashChange()
  initInfo(depInfos.first())
})


text:
package walk

import (
	"sort"
)

import (
	"github.com/Skarm/win"
)

type Orientation byte

const (
	Horizontal Orientation = iota
	Vertical
)

type BoxLayout struct {
	container          Container
	margins            Margins
	spacing            int
	orientation        Orientation
	hwnd2StretchFactor map[win.HWND]int
	resetNeeded        bool
}

func newBoxLayout(orientation Orientation) *BoxLayout {
	return &BoxLayout{
		orientation:        orientation,
		hwnd2StretchFactor: make(map[win.HWND]int),
	}
}

func NewHBoxLayout() *BoxLayout {
	return newBoxLayout(Horizontal)
}

func NewVBoxLayout() *BoxLayout {
	return newBoxLayout(Vertical)
}

func (l *BoxLayout) Container() Container {
	return l.container
}

func (l *BoxLayout) SetContainer(value Container) {
	if value != l.container {
		if l.container != nil {
			l.container.SetLayout(nil)
		}

		l.container = value

		if value != nil && value.Layout() != Layout(l) {
			value.SetLayout(l)

			l.Update(true)
		}
	}
}

func (l *BoxLayout) Margins() Margins {
	return l.margins
}

func (l *BoxLayout) SetMargins(value Margins) error {
	if value.HNear < 0 || value.VNear < 0 || value.HFar < 0 || value.VFar < 0 {
		return newError("margins must be positive")
	}

	l.margins = value

	l.Update(false)

	return nil
}

func (l *BoxLayout) Orientation() Orientation {
	return l.orientation
}

func (l *BoxLayout) SetOrientation(value Orientation) error {
	if value != l.orientation {
		switch value {
		case Horizontal, Vertical:

		default:
			return newError("invalid Orientation value")
		}

		l.orientation = value

		l.Update(false)
	}

	return nil
}

func (l *BoxLayout) Spacing() int {
	return l.spacing
}

func (l *BoxLayout) SetSpacing(value int) error {
	if value != l.spacing {
		if value < 0 {
			return newError("spacing cannot be negative")
		}

		l.spacing = value

		l.Update(false)
	}

	return nil
}

func (l *BoxLayout) StretchFactor(widget Widget) int {
	if factor, ok := l.hwnd2StretchFactor[widget.Handle()]; ok {
		return factor
	}

	return 1
}

func (l *BoxLayout) SetStretchFactor(widget Widget, factor int) error {
	if factor != l.StretchFactor(widget) {
		if l.container == nil {
			return newError("container required")
		}

		handle := widget.Handle()

		if !l.container.Children().containsHandle(handle) {
			return newError("unknown widget")
		}
		if factor < 1 {
			return newError("factor must be >= 1")
		}

		l.hwnd2StretchFactor[handle] = factor

		l.Update(false)
	}

	return nil
}

func (l *BoxLayout) cleanupStretchFactors() {
	widgets := l.container.Children()

	for handle, _ := range l.hwnd2StretchFactor {
		if !widgets.containsHandle(handle) {
			delete(l.hwnd2StretchFactor, handle)
		}
	}
}

type widgetInfo struct {
	index   int
	minSize int
	maxSize int
	stretch int
	greedy  bool
	widget  Widget
}

type widgetInfoList []widgetInfo

func (l widgetInfoList) Len() int {
	return len(l)
}

func (l widgetInfoList) Less(i, j int) bool {
	_, iIsSpacer := l[i].widget.(*Spacer)
	_, jIsSpacer := l[j].widget.(*Spacer)

	if l[i].greedy == l[j].greedy {
		if iIsSpacer == jIsSpacer {
			minDiff := l[i].minSize - l[j].minSize

			if minDiff == 0 {
				return l[i].maxSize/l[i].stretch < l[j].maxSize/l[j].stretch
			}

			return minDiff > 0
		}

		return jIsSpacer
	}

	return l[i].greedy
}

func (l widgetInfoList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

func (l *BoxLayout) widgets() []Widget {
	children := l.container.Children()
	widgets := make([]Widget, 0, children.Len())

	for i := 0; i < cap(widgets); i++ {
		widget := children.At(i)

		if !shouldLayoutWidget(widget) {
			continue
		}

		ps := widget.SizeHint()
		if ps.Width == 0 && ps.Height == 0 && widget.LayoutFlags() == 0 {
			continue
		}

		widgets = append(widgets, widget)
	}

	return widgets
}

func (l *BoxLayout) LayoutFlags() LayoutFlags {
	if l.container == nil {
		return 0
	}

	var flags LayoutFlags
	var hasNonShrinkableHorz bool
	var hasNonShrinkableVert bool

	children := l.container.Children()
	count := children.Len()
	if count == 0 {
		return ShrinkableHorz | ShrinkableVert | GrowableHorz | GrowableVert
	} else {
		for i := 0; i < count; i++ {
			widget := children.At(i)

			if !shouldLayoutWidget(widget) {
				continue
			}

			f := widget.LayoutFlags()
			flags |= f
			if f&ShrinkableHorz == 0 {
				hasNonShrinkableHorz = true
			}
			if f&ShrinkableVert == 0 {
				hasNonShrinkableVert = true
			}
		}
	}

	if l.orientation == Horizontal {
		flags |= GrowableHorz

		if hasNonShrinkableVert {
			flags &^= ShrinkableVert
		}
	} else {
		flags |= GrowableVert

		if hasNonShrinkableHorz {
			flags &^= ShrinkableHorz
		}
	}

	return flags
}

func (l *BoxLayout) MinSize() Size {
	if l.container == nil {
		return Size{}
	}

	widgets := l.widgets()
	var s Size

	for _, widget := range widgets {
		min := minSizeEffective(widget)

		if l.orientation == Horizontal {
			s.Width += min.Width
			s.Height = maxi(s.Height, min.Height)
		} else {
			s.Height += min.Height
			s.Width = maxi(s.Width, min.Width)
		}
	}

	if l.orientation == Horizontal {
		s.Width += l.spacing * (len(widgets) - 1)
		s.Width += l.margins.HNear + l.margins.HFar
		s.Height += l.margins.VNear + l.margins.VFar
	} else {
		s.Height += l.spacing * (len(widgets) - 1)
		s.Height += l.margins.VNear + l.margins.VFar
		s.Width += l.margins.HNear + l.margins.HFar
	}

	return s
}

func (l *BoxLayout) MaxSize() Size {
	if l.container == nil {
		return Size{}
	}

	widgets := l.widgets()
	var s Size

	for _, widget := range widgets {
		max := maxSizeEffective(widget)

		if l.orientation == Horizontal {
			s.Width += max.Width
			s.Height = maxi(s.Height, max.Height)
		} else {
			s.Height += max.Height
			s.Width = maxi(s.Width, max.Width)
		}
	}

	if l.orientation == Horizontal {
		s.Width += l.spacing * (len(widgets) - 1)
		s.Width += l.margins.HNear + l.margins.HFar
		s.Height += l.margins.VNear + l.margins.VFar
	} else {
		s.Height += l.spacing * (len(widgets) - 1)
		s.Height += l.margins.VNear + l.margins.VFar
		s.Width += l.margins.HNear + l.margins.HFar
	}

	return s
}

func (l *BoxLayout) Update(reset bool) error {
	if l.container == nil {
		return nil
	}

	if reset {
		l.resetNeeded = true
	}

	if l.container.Suspended() {
		return nil
	}

	if l.resetNeeded {
		l.resetNeeded = false

		// Make GC happy.
		l.cleanupStretchFactors()
	}

	// Begin by finding out which widgets we care about.
	widgets := l.widgets()

	// Prepare some useful data.
	var greedyNonSpacerCount int
	var greedySpacerCount int
	var stretchFactorsTotal [3]int
	stretchFactors := make([]int, len(widgets))
	var minSizesRemaining int
	minSizes := make([]int, len(widgets))
	maxSizes := make([]int, len(widgets))
	sizes := make([]int, len(widgets))
	prefSizes2 := make([]int, len(widgets))
	growable2 := make([]bool, len(widgets))
	sortedWidgetInfo := widgetInfoList(make([]widgetInfo, len(widgets)))

	for i, widget := range widgets {
		sf := l.hwnd2StretchFactor[widget.Handle()]
		if sf == 0 {
			sf = 1
		}
		stretchFactors[i] = sf

		flags := widget.LayoutFlags()

		min := widget.MinSize()
		max := widget.MaxSize()
		minHint := widget.MinSizeHint()
		pref := widget.SizeHint()

		if l.orientation == Horizontal {
			growable2[i] = flags&GrowableVert > 0

			minSizes[i] = maxi(min.Width, minHint.Width)

			if max.Width > 0 {
				maxSizes[i] = max.Width
			} else if pref.Width > 0 && flags&GrowableHorz == 0 {
				maxSizes[i] = pref.Width
			} else {
				maxSizes[i] = 32768
			}

			prefSizes2[i] = pref.Height

			sortedWidgetInfo[i].greedy = flags&GreedyHorz > 0
		} else {
			growable2[i] = flags&GrowableHorz > 0

			minSizes[i] = maxi(min.Height, minHint.Height)

			if max.Height > 0 {
				maxSizes[i] = max.Height
			} else if pref.Height > 0 && flags&GrowableVert == 0 {
				maxSizes[i] = pref.Height
			} else {
				maxSizes[i] = 32768
			}

			prefSizes2[i] = pref.Width

			sortedWidgetInfo[i].greedy = flags&GreedyVert > 0
		}

		sortedWidgetInfo[i].index = i
		sortedWidgetInfo[i].minSize = minSizes[i]
		sortedWidgetInfo[i].maxSize = maxSizes[i]
		sortedWidgetInfo[i].stretch = sf
		sortedWidgetInfo[i].widget = widget

		minSizesRemaining += minSizes[i]

		if sortedWidgetInfo[i].greedy {
			if _, isSpacer := widget.(*Spacer); !isSpacer {
				greedyNonSpacerCount++
				stretchFactorsTotal[0] += sf
			} else {
				greedySpacerCount++
				stretchFactorsTotal[1] += sf
			}
		} else {
			stretchFactorsTotal[2] += sf
		}
	}

	sort.Sort(sortedWidgetInfo)

	cb := l.container.ClientBounds()
	var start1, start2, space1, space2 int
	if l.orientation == Horizontal {
		start1 = cb.X + l.margins.HNear
		start2 = cb.Y + l.margins.VNear
		space1 = cb.Width - l.margins.HNear - l.margins.HFar
		space2 = cb.Height - l.margins.VNear - l.margins.VFar
	} else {
		start1 = cb.Y + l.margins.VNear
		start2 = cb.X + l.margins.HNear
		space1 = cb.Height - l.margins.VNear - l.margins.VFar
		space2 = cb.Width - l.margins.HNear - l.margins.HFar
	}

	// Now calculate widget primary axis sizes.
	spacingRemaining := l.spacing * (len(widgets) - 1)

	offsets := [3]int{0, greedyNonSpacerCount, greedyNonSpacerCount + greedySpacerCount}
	counts := [3]int{greedyNonSpacerCount, greedySpacerCount, len(widgets) - greedyNonSpacerCount - greedySpacerCount}

	for i := 0; i < 3; i++ {
		stretchFactorsRemaining := stretchFactorsTotal[i]

		for j := 0; j < counts[i]; j++ {
			info := sortedWidgetInfo[offsets[i]+j]
			k := info.index

			stretch := stretchFactors[k]
			min := info.minSize
			max := info.maxSize
			size := min

			if min < max {
				excessSpace := float64(space1 - minSizesRemaining - spacingRemaining)
				size += int(excessSpace * float64(stretch) / float64(stretchFactorsRemaining))
				if size < min {
					size = min
				} else if size > max {
					size = max
				}
			}

			sizes[k] = size

			minSizesRemaining -= min
			stretchFactorsRemaining -= stretch
			space1 -= (size + l.spacing)
			spacingRemaining -= l.spacing
		}
	}

	// Finally position widgets.
	hdwp := win.BeginDeferWindowPos(int32(len(widgets)))
	if hdwp == 0 {
		return lastError("BeginDeferWindowPos")
	}

	excessTotal := space1 - minSizesRemaining - spacingRemaining
	excessShare := excessTotal / (len(widgets) + 1)
	p1 := start1
	for i, widget := range widgets {
		p1 += excessShare
		s1 := sizes[i]

		var s2 int
		if growable2[i] {
			s2 = space2
		} else {
			s2 = prefSizes2[i]
		}

		p2 := start2 + (space2-s2)/2

		var x, y, w, h int
		if l.orientation == Horizontal {
			x, y, w, h = p1, p2, s1, s2
		} else {
			x, y, w, h = p2, p1, s2, s1
		}

		if hdwp = win.DeferWindowPos(
			hdwp,
			widget.Handle(),
			0,
			int32(x),
			int32(y),
			int32(w),
			int32(h),
			win.SWP_NOACTIVATE|win.SWP_NOOWNERZORDER|win.SWP_NOZORDER); hdwp == 0 {

			return lastError("DeferWindowPos")
		}

		p1 += s1 + l.spacing
	}

	if !win.EndDeferWindowPos(hdwp) {
		return lastError("EndDeferWindowPos")
	}

	return nil
}


text:
/* export default buildUpgrade = ({key, type, name, description, short, tier, price}) => ({
  key,
  type,
  name,
  description,
  price,
  unlocked
}) */

import MonkeyUpgrades from "./monkey"
import KeyboardUpgrades from "./keyboard"

export default { ...MonkeyUpgrades, ...KeyboardUpgrades }


text:
"""Module for testing the update_building_preference command"""

import unittest

if __name__ == "__main__":
    import utils
    utils.import_depends()

from brokertest import TestBrokerCommand

class TestUpdateBuildingPreference(TestBrokerCommand):

    def test_000_justification(self):
        command = ["update_building_preference", "--building_pair", "utb1,utb2",
                   "--archetype", "hacluster", "--prefer", "utb1"]
        self.justificationmissingtest(command, auth=True, msgcheck=False)

    def test_100_update_utb12(self):
        command = ["update_building_preference", "--building_pair", "utb1,utb2",
                   "--archetype", "hacluster", "--prefer", "utb1"] + self.valid_just_tcm
        out = self.statustest(command)
        self.matchoutput(out, "Flushed 4/8 templates.", command)

    def test_105_show_utb12(self):
        command = ["show_building_preference", "--building_pair", "utb1,utb2",
                   "--archetype", "hacluster"]
        out = self.commandtest(command)
        self.output_equals(out, """
            Building Pair: utb1,utb2  Archetype: hacluster  Prefer: utb1
            """, command)

    def test_105_show_utb12_proto(self):
        # Different pair order
        command = ["show_building_preference", "--building_pair", "utb2,utb1",
                   "--archetype", "hacluster", "--format", "proto"]
        pref = self.protobuftest(command, expect=1)[0]
        self.assertEqual(len(pref.location), 2)
        self.assertEqual(pref.location[0].location_type, "building")
        self.assertEqual(pref.location[0].name, "utb1")
        self.assertEqual(pref.location[1].location_type, "building")
        self.assertEqual(pref.location[1].name, "utb2")
        self.assertEqual(pref.prefer.location_type, "building")
        self.assertEqual(pref.prefer.name, "utb1")
        # TODO
        #self.assertEqual(pref.archetype.name, "hacluster")

    def test_105_cat_utbvcs2a(self):
        command = ["cat", "--cluster", "utbvcs2a", "--data"]
        out = self.commandtest(command)
        self.matchoutput(out,
                         '"system/cluster/preferred_location/building" = "utb1";',
                         command)

    def test_106_show_building_preference_utbvcs2a(self):
        command = ["show_building_preference", "--cluster", "utbvcs2a"]
        out = self.commandtest(command)
        self.matchoutput(out,
                         'Building Pair: utb1,utb2  Archetype: hacluster  Prefer: utb1',
                         command)

    def test_108_make_utbvcs2a(self):
        self.statustest(["make_cluster", "--cluster", "utbvcs2a"])

    def test_200_single_building(self):
        command = ["update_building_preference", "--building_pair", "ut",
                   "--archetype", "hacluster", "--prefer", "ut"] + self.valid_just_tcm
        out = self.badrequesttest(command)
        self.matchoutput(out, "should be two building codes", command)

    def test_201_three_buildings(self):
        command = ["update_building_preference", "--building_pair", "ut,utb1,utb2",
                   "--archetype", "hacluster", "--prefer", "ut"] + self.valid_just_tcm
        out = self.badrequesttest(command)
        self.matchoutput(out, "should be two building codes", command)

    def test_202_repeated_building(self):
        command = ["update_building_preference", "--building_pair", "ut,ut",
                   "--archetype", "hacluster", "--prefer", "ut"] + self.valid_just_tcm
        out = self.badrequesttest(command)
        self.matchoutput(out, "two different building codes", command)

    def test_203_preferred_outside(self):
        command = ["update_building_preference", "--building_pair", "utb1,utb2",
                   "--archetype", "hacluster", "--prefer", "ut"] + self.valid_just_tcm
        out = self.badrequesttest(command)
        self.matchoutput(out, "Preferred building ut must be one of "
                         "utb1 and utb2.", command)

    def test_210_update_missing_pair(self):
        command = ["update_building_preference", "--building_pair", "utb1,utb3",
                   "--archetype", "hacluster", "--prefer", "utb3"] + self.valid_just_tcm
        out = self.notfoundtest(command)
        self.matchoutput(out, "Building pair utb1,utb3 does not have a "
                         "preference for archetype hacluster.", command)

    def test_210_update_missing_archetype(self):
        command = ["update_building_preference", "--building_pair", "utb1,utb2",
                   "--archetype", "esx_cluster", "--prefer", "utb2"] + self.valid_just_tcm
        out = self.notfoundtest(command)
        self.matchoutput(out, "Building pair utb1,utb2 does not have a "
                         "preference for archetype esx_cluster.", command)

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestUpdateBuildingPreference)
    unittest.TextTestRunner(verbosity=2).run(suite)


text:
<!doctype html>

		<meta charset="utf-8"/>
		<title>Page title here</title>
		<link href="styles/styles.css" rel="stylesheet" type="text/css"/>

Module 1: Library 101

Internet Guidelines

 Navigation

Library 101

Use of Library

Get a card

Library Etiquette

Internet Guidelines

Materials

Materials Activity

Video

References

Module 1 Assessment

Certificate

Audio

						<audio controls="controls" autoplay="autoplay">
					<source src="audio/5-guidelines.mp3" type="audio/mpeg"/>
					</audio>

Captions

				The library has internet access, free Wi-Fi and printing services available at all 30 locations. Internet access time is up to 3 hours.

				Wi-Fi access is available 24/7 and no password is needed. You'll just need to agree to the User Agreement once you click in a browser.

				The only service the library charges for is printing. It is only twenty cents per page for black and white copies and $1 per page for color copies.

The library has internet access, free Wi-Fi and printing services available at all locations.

				Internet access time is up to 3 hours.

				Wi-Fi access is available 24/7 and no password is needed. You'll just need to agree to the User Agreement once you click in a browser.

Printing is the only service that the library does charge for.

				Printing Costs: .20 cents per page

        	    $1.00 for color per page


text:
// namespace:
this.createjs = this.createjs||{};

(function() {

/**
 * The EventDispatcher provides methods for managing prioritized queues of event listeners and dispatching events. All
 * {{#crossLink "DisplayObject"}}{{/crossLink}} classes dispatch events, as well as some of the utilities like {{#crossLink "Ticker"}}{{/crossLink}}.
 *
 * You can either extend this class or mix its methods into an existing prototype or instance by using the
 * EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method.
 *
 *
Example

 * Add EventDispatcher capabilities to the "MyClass" class.
 *
 *      EventDispatcher.initialize(MyClass.prototype);
 *
 * Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}).
 *
 *      instance.addEventListener("eventName", handlerMethod);
 *      function handlerMethod(event) {
 *          console.log(event.target + " Was Clicked");
 *      }
 *
 * Maintaining proper scope

 * When using EventDispatcher in a class, you may need to use Function.bind or another approach to
 * maintain you method scope. Note that Function.bind is not supported in some older browsers.
 *
 *      instance.addEventListener("click", handleClick.bind(this));
 *      function handleClick(event) {
 *          console.log("Method called in scope: " + this);
 *      }
 *
 * Please note that currently, EventDispatcher does not support event priority or bubbling. Future versions may add
 * support for one or both of these features.
 *
 * @class EventDispatcher
 * @constructor
 **/
var EventDispatcher = function() {
  this.initialize();
};
var p = EventDispatcher.prototype;

	/**
	 * Static initializer to mix in EventDispatcher methods.
	 * @method initialize
	 * @static
	 * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a
	 * prototype.
	 **/
	EventDispatcher.initialize = function(target) {
		target.addEventListener = p.addEventListener;
		target.removeEventListener = p.removeEventListener;
		target.removeAllEventListeners = p.removeAllEventListeners;
		target.hasEventListener = p.hasEventListener;
		target.dispatchEvent = p.dispatchEvent;
	};

// private properties:
	/**
	 * @protected
	 * @property _listeners
	 * @type Object
	 **/
	p._listeners = null;

// constructor:
	/**
	 * Initialization method.
	 * @method initialize
	 * @protected
	 **/
	p.initialize = function() {};

// public methods:
	/**
	 * Adds the specified event listener. Note that adding multiple listeners to the same function will result in
	 * multiple callbacks getting fired.
	 *
	 *
Example

	 *
	 *      displayObject.addEventListener("click", handleClick);
	 *      function handleClick(event) {
	 *         // Click happened.
	 *      }
	 *
	 * @method addEventListener
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
	 * the event is dispatched.
	 * @return {Function | Object} Returns the listener for chaining or assignment.
	 **/
	p.addEventListener = function(type, listener) {
		var listeners = this._listeners;
		if (!listeners) { listeners = this._listeners = {}; }
		else { this.removeEventListener(type, listener); }
		var arr = listeners[type];
		if (!arr) { arr = listeners[type] = []; }
		arr.push(listener);
		return listener;
	};

	/**
	 * Removes the specified event listener.
	 *
	 * Important Note: that you must pass the exact function reference used when the event was added. If a proxy
	 * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or
	 * closure will not work.
	 *
	 *
Example

	 *
	 *      displayObject.removeEventListener("click", handleClick);
	 *
	 * @method removeEventListener
	 * @param {String} type The string type of the event.
	 * @param {Function | Object} listener The listener function or object.
	 **/
	p.removeEventListener = function(type, listener) {
		var listeners = this._listeners;
		if (!listeners) { return; }
		var arr = listeners[type];
		if (!arr) { return; }
		for (var i=0,l=arr.length; i<l; i++) {
			if (arr[i] == listener) {
				if (l==1) { delete(listeners[type]); } // allows for faster checks.
				else { arr.splice(i,1); }
				break;
			}
		}
	};

	/**
	 * Removes all listeners for the specified type, or all listeners of all types.
	 *
	 *
Example

	 *
	 *      // Remove all listeners
	 *      displayObject.removeAllEvenListeners();
	 *
	 *      // Remove all click listeners
	 *      displayObject.removeAllEventListeners("click");
	 *
	 * @method removeAllEventListeners
	 * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed.
	 **/
	p.removeAllEventListeners = function(type) {
		if (!type) { this._listeners = null; }
		else if (this._listeners) { delete(this._listeners[type]); }
	};

	/**
	 * Dispatches the specified event to all listeners.
	 *
	 *
Example

	 *
	 *      // Use a string event
	 *      this.dispatchEvent("complete");
	 *
	 *      // Use an object
	 *      var event = {
	 *          type: "complete",
	 *          foo: "bar"
	 *      };
	 *      this.dispatchEvent(event);
	 *
	 * @method dispatchEvent
	 * @param {Object | String} eventObj An object with a "type" property, or a string type. If a string is used,
	 * dispatchEvent will construct a generic event object with the specified type.
	 * @param {Object} [target] The object to use as the target property of the event object. This will default to the
	 * dispatching object.
	 * @return {Boolean} Returns true if any listener returned true.
	 **/
	p.dispatchEvent = function(eventObj, target) {
		var ret=false, listeners = this._listeners;
		if (eventObj && listeners) {
			if (typeof eventObj == "string") { eventObj = {type:eventObj}; }
			var arr = listeners[eventObj.type];
			if (!arr) { return ret; }
			eventObj.target = target||this;
			arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch
			for (var i=0,l=arr.length; i<l; i++) {
				var o = arr[i];
				if (o.handleEvent) { ret = ret||o.handleEvent(eventObj); }
				else { ret = ret||o(eventObj); }
			}
		}
		return !!ret;
	};

	/**
	 * Indicates whether there is at least one listener for the specified event type.
	 * @method hasEventListener
	 * @param {String} type The string type of the event.
	 * @return {Boolean} Returns true if there is at least one listener for the specified event.
	 **/
	p.hasEventListener = function(type) {
		var listeners = this._listeners;
		return !!(listeners && listeners[type]);
	};

	/**
	 * @method toString
	 * @return {String} a string representation of the instance.
	 **/
	p.toString = function() {
		return "[EventDispatcher]";
	};

createjs.EventDispatcher = EventDispatcher;
}());


text:
using System.Configuration;

namespace Configurations
{
	public class Loggers : ConfigurationElementCollection
	{
		protected override ConfigurationElement CreateNewElement()
		{
			return new Logger();
		}

		/// <summary>
		/// Represents the child-chollection of the loggers section.
		/// </summary>
		protected override object GetElementKey(ConfigurationElement element)
		{
			return element;
		}
	}
}


text:
package com.google.common.collect;

import com.google.common.annotations.Beta;

import java.util.NoSuchElementException;
import java.util.Set;

import javax.annotation.Nullable;

/**
 * A set comprising zero or more {@linkplain Range#isEmpty nonempty},
 * {@linkplain Range#isConnected(Range) disconnected} ranges of type {@code C}.
 *
 *
Implementations that choose to support the {@link #add(Range)} operation are required to
 * ignore empty ranges and coalesce connected ranges.  For example:
   {@code
 *
 *   RangeSet<Integer> rangeSet = TreeRangeSet.create();
 *   rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
 *   rangeSet.add(Range.closedOpen(11, 15)); // disconnected range; {[1, 10], [11, 15)}
 *   rangeSet.add(Range.closedOpen(15, 20)); // connected range; {[1, 10], [11, 20)}
 *   rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}
 *   rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}}

 *
 *
Note that the behavior of {@link Range#isEmpty()} and {@link Range#isConnected(Range)} may
 * not be as expected on discrete ranges.  See the Javadoc of those methods for details.
 *
 *
For a {@link Set} whose contents are specified by a {@link Range}, see {@link ContiguousSet}.
 *
 * @author Kevin Bourrillion
 * @author Louis Wasserman
 * @since 14.0
 */
@Beta
public interface RangeSet<C extends Comparable> {

  // Query methods

  /**
   * Determines whether any of this range set's member ranges contains {@code value}.
   */
  boolean contains(C value);

  /**
   * Returns the unique range from this range set that {@linkplain Range#contains contains}
   * {@code value}, or {@code null} if this range set does not contain {@code value}.
   */
  Range<C> rangeContaining(C value);

  /**
   * Returns {@code true} if there exists a member range in this range set which
   * {@linkplain Range#encloses encloses} the specified range.
   */
  boolean encloses(Range<C> otherRange);

  /**
   * Returns {@code true} if for each member range in {@code other} there exists a member range in
   * this range set which {@linkplain Range#encloses encloses} it. It follows that
   * {@code this.contains(value)} whenever {@code other.contains(value)}. Returns {@code true} if
   * {@code other} is empty.
   *
   *
This is equivalent to checking if this range set {@link #encloses} each of the ranges in
   * {@code other}.
   */
  boolean enclosesAll(RangeSet<C> other);

  /**
   * Returns {@code true} if this range set contains no ranges.
   */
  boolean isEmpty();

  /**
   * Returns the minimal range which {@linkplain Range#encloses(Range) encloses} all ranges
   * in this range set.
   *
   * @throws NoSuchElementException if this range set is {@linkplain #isEmpty() empty}
   */
  Range<C> span();

  // Views

  /**
   * Returns a view of the {@linkplain Range#isConnected disconnected} ranges that make up this
   * range set.  The returned set may be empty. The iterators returned by its
   * {@link Iterable#iterator} method return the ranges in increasing order of lower bound
   * (equivalently, of upper bound).
   */
  Set<Range<C>> asRanges();

  /**
   * Returns a descending view of the {@linkplain Range#isConnected disconnected} ranges that
   * make up this range set. The returned set may be empty. The iterators returned by its
   * {@link Iterable#iterator} method return the ranges in decreasing order of lower bound
   * (equivalently, of upper bound).
   */
  Set<Range<C>> asDescendingSetOfRanges();

  /**
   * Returns a view of the complement of this {@code RangeSet}.
   *
   *
The returned view supports the {@link #add} operation if this {@code RangeSet} supports
   * {@link #remove}, and vice versa.
   */
  RangeSet<C> complement();

  /**
   * Returns a view of the intersection of this {@code RangeSet} with the specified range.
   *
   *
The returned view supports all optional operations supported by this {@code RangeSet}, with
   * the caveat that an {@link IllegalArgumentException} is thrown on an attempt to
   * {@linkplain #add(Range) add} any range not {@linkplain Range#encloses(Range) enclosed} by
   * {@code view}.
   */
  RangeSet<C> subRangeSet(Range<C> view);

  // Modification

  /**
   * Adds the specified range to this {@code RangeSet} (optional operation). That is, for equal
   * range sets a and b, the result of {@code a.add(range)} is that {@code a} will be the minimal
   * range set for which both {@code a.enclosesAll(b)} and {@code a.encloses(range)}.
   *
   *
Note that {@code range} will be {@linkplain Range#span(Range) coalesced} with any ranges in
   * the range set that are {@linkplain Range#isConnected(Range) connected} with it.  Moreover,
   * if {@code range} is empty, this is a no-op.
   *
   * @throws UnsupportedOperationException if this range set does not support the {@code add}
   *         operation
   */
  void add(Range<C> range);

  /**
   * Removes the specified range from this {@code RangeSet} (optional operation). After this
   * operation, if {@code range.contains(c)}, {@code this.contains(c)} will return {@code false}.
   *
   *
If {@code range} is empty, this is a no-op.
   *
   * @throws UnsupportedOperationException if this range set does not support the {@code remove}
   *         operation
   */
  void remove(Range<C> range);

  /**
   * Removes all ranges from this {@code RangeSet} (optional operation).  After this operation,
   * {@code this.contains(c)} will return false for all {@code c}.
   *
   *
This is equivalent to {@code remove(Range.all())}.
   *
   * @throws UnsupportedOperationException if this range set does not support the {@code clear}
   *         operation
   */
  void clear();

  /**
   * Adds all of the ranges from the specified range set to this range set (optional operation).
   * After this operation, this range set is the minimal range set that
   * {@linkplain #enclosesAll(RangeSet) encloses} both the original range set and {@code other}.
   *
   *
This is equivalent to calling {@link #add} on each of the ranges in {@code other} in turn.
   *
   * @throws UnsupportedOperationException if this range set does not support the {@code addAll}
   *         operation
   */
  void addAll(RangeSet<C> other);

  /**
   * Removes all of the ranges from the specified range set from this range set (optional
   * operation). After this operation, if {@code other.contains(c)}, {@code this.contains(c)} will
   * return {@code false}.
   *
   *
This is equivalent to calling {@link #remove} on each of the ranges in {@code other} in
   * turn.
   *
   * @throws UnsupportedOperationException if this range set does not support the {@code removeAll}
   *         operation
   */
  void removeAll(RangeSet<C> other);

  // Object methods

  /**
   * Returns {@code true} if {@code obj} is another {@code RangeSet} that contains the same ranges
   * according to {@link Range#equals(Object)}.
   */
  @Override
  boolean equals(@Nullable Object obj);

  /**
   * Returns {@code asRanges().hashCode()}.
   */
  @Override
  int hashCode();

  /**
   * Returns a readable string representation of this range set. For example, if this
   * {@code RangeSet} consisted of {@code Range.closed(1, 3)} and {@code Range.greaterThan(4)},
   * this might return {@code " [1‥3](4‥+∞)}"}.
   */
  @Override
  String toString();
}


text:
/** @file */	// Doxygen marker

#import "CC3Texture.h"
#import "CCProtocols.h"
#import "CC3NodeVisitor.h"

/** Default material color under ambient lighting. */
static const ccColor4F kCC3DefaultMaterialColorAmbient = { 0.2, 0.2, 0.2, 1.0 };

/** Default material color under diffuse lighting. */
static const ccColor4F kCC3DefaultMaterialColorDiffuse = { 0.8, 0.8, 0.8, 1.0 };

/** Default material color under specular lighting. */
static const ccColor4F kCC3DefaultMaterialColorSpecular = { 0.0, 0.0, 0.0, 1.0 };

/** Default emissive material color. */
static const ccColor4F kCC3DefaultMaterialColorEmission = { 0.0, 0.0, 0.0, 1.0 };

/** Default material shininess. */
static const GLfloat kCC3DefaultMaterialShininess = 0.0;

/** Maximum material shininess allowed by OGLES. */
static const GLfloat kCC3MaximumMaterialShininess = 128.0;

#pragma mark -
#pragma mark CC3Material

/**
 * CC3Material manages information about a material that is used to cover one or more meshes.
 * This includes:
 *   - color
 *   - texture
 *   - interaction with lighting
 *   - opacity, translucency, and blending with background objects
 *
 * CC3Material supports two levels of control for blending and translucency:
 *   - To achieve the highest level of detail, accuracy and realism, you can individually
 *     set the explicit ambientColor, diffuseColor, specularColor, emissiveColor, shininess,
 *     sourceBlend, and destinationBlend properties. This suite of properties gives you the
 *     most complete control over the appearance of the material and its interaction with
 *     lighting conditions and the colors of the objects behind it, allowing you to generate
 *     rich visual effects. In addition, the isOpaque property sets the most commonly used
 *     blending combinations, and can be used to simplify your management of blending opaque
 *     or transparent materials, while still providing fine control of the ambient, diffuse
 *     and specular coloring.
 *   - At a simpler level, CC3Material also supports the cocos2d <CCRGBAProtocol> protocol.
 *     You can use the color and opacity properties of this protocol to set the most commonly
 *     used coloring and blending characteristics simply and easily. Setting the color property
 *     changes both the ambient and diffuse colors of the material in tandem. Setting the
 *     opacity property also automatically sets the source and destination blend functions to
 *     appropriate values for the opacity level. By using the color and opacity properties,
 *     you will not be able to achieve the complexity and realism that you can by using the
 *     more detailed properties, but you can achieve good effect with much less effort.
 *     And by supporting the <CCRGBAProtocol> protocol, the coloring and translucency of nodes
 *     with materials can be changed using standard cocos2d CCTint and CCFade actions, making
 *     it easier for you to add dynamic coloring effects to your nodes.
 *
 * CC3Material also supports alpha testing, where the alpha value of each pixel can be
 * tested to determine whether or not it should be drawn. By default, alpha testing is
 * disabled, but alpha testing can sometimes be useful when drawing overlapping objects
 * each contain transparency and it is not possible to rely only on drawing order and
 * depth testing to mediate whether a pixel should be drawn.
 *
 * Textures are optional. In some cases, if simple solid coloring is to be used, the material
 * may hold no texture at all. This solid coloring will still interact with lighting, creating
 * a realistic surface.
 *
 * More commonly, a material will hold a single instance of CC3Texture in the texture
 * property to provide a simple single-texture surface. This is the most common application
 * of textures to a material.
 *
 * For more sophisticated surfaces, materials also support multi-texturing, where more than
 * one instance of CC3Texture is added to the material using the addTexture: method. Using
 * multi-texturing, these textures can be combined in flexible, customized fashion,
 * permitting sophisticated surface effects.
 *
 * With OpenGL, multi-texturing is processed by a chain of texture units. The material's
 * first texture is processed by the first texture unit (texture unit zero), and subsequent
 * textures held in the material are processed by subsequent texture units, in the order in
 * which the textures were added to the material.
 *
 * Each texture unit combines its texture with the output of the previous texture unit
 * in the chain. Combining textures is quite flexible under OpenGL, and there are many
 * ways that each texture can be combined with the output of the previous texture unit.
 * The way that a particular texture combines with the previous textures is defined by
 * an instance of CC3TextureUnit, held in the textureUnit property of each texture that
 * was added to the material.
 *
 * For example, to configure a material for bump-mapping, add a texture that contains a
 * normal vector at each pixel instead of a color, and set the textureUnit property of
 * the texture to a CC3BumpMapTextureUnit. You can then combine the output of this
 * bump-mapping with an additional texture that contains the image that will be visible,
 * to provide a detailed 3D bump-mapped surface. To do so, add that second texture to
 * the material, with a texture unit that defines how that addtional texture is to be
 * combined with the output of the bump-mapped texture.
 *
 * The maximum number of texture units is platform dependent, and can be read from
 * [CC3OpenGLES11Engine engine].platform.maxTextureUnits.value. This effectively defines
 * how many textures you can add to a material.
 *
 * You'll notice that there are two ways to assign textures to a material: through the
 * texture propety, and through the addTexture: method. The texture property exists for
 * the common case where only one texture is attached to a material. The addTexture:
 * method is used when more than one texture is to be added to the material. However,
 * for the first texture, the two mechanisms are synonomous. The texture property
 * corresponds to the first texture added using the addTexture: method, and for that
 * first texture, you can use either the texture property or the addTexture: method.
 * When multi-texturing, for consistency and simplicity, you would likely just use the
 * addTexture: method for all textures added to the material, including the first texture.
 *
 * Each CC3MeshNode instance references an instance of CC3Material. Many CC3MeshNode
 * instances may reference the same instance of CC3Material, allowing many objects to
 * be covered by the same material.
 *
 * When being drawn, the CC3MeshNode invokes the draw method on the CC3Material
 * instance prior to drawing the associated mesh.
 *
 * When drawing the material to the GL engine, this class remembers which material was
 * last drawn, and only binds the material data to the GL engine when a different material
 * is drawn. This allows the application to organize the CC3MeshNodes within the CC3World
 * so that nodes using the same material are drawn together, before moving on to other
 * materials. This strategy can minimize the number of mesh switches in the GL engine,
 * which improves performance.
 */
@interface CC3Material : CC3Identifiable <CCRGBAProtocol, CCBlendProtocol> {
	CC3Texture* texture;
	CCArray* textureOverlays;
	ccColor4F ambientColor;
	ccColor4F diffuseColor;
	ccColor4F specularColor;
	ccColor4F emissionColor;
	GLfloat shininess;
	GLenum alphaTestFunction;
	GLfloat alphaTestReference;
	ccBlendFunc blendFunc;
	BOOL shouldUseLighting;
	BOOL isOpaque;
}

/**
 * If this value is set to YES, current lighting conditions will be taken into consideration
 * when drawing colors and textures, and the ambientColor, diffuseColor, specularColor,
 * emissionColor, and shininess properties will interact with lighting settings.
 *
 * If this value is set to NO, lighting conditions will be ignored when drawing colors and
 * textures, and the emissionColor will be applied to the mesh surface without regard to
 * lighting. Blending will still occur, but the other material aspects, including ambientColor,
 * diffuseColor, specularColor, and shininess will be ignored. This is useful for a cartoon
 * effect, where you want a pure color, or the natural colors of the texture, to be included
 * in blending calculations, without having to arrange lighting, or if you want those colors
 * to be displayed in their natural values despite current lighting conditions.
 *
 * The initial value of this property is YES.
 */
@property(nonatomic, assign) BOOL shouldUseLighting;

/**
 * The color of this material under ambient lighting.
 * Initially set to kCC3DefaultMaterialColorAmbient.
 *
 * The value of this property is also affected by changes to the color and opacity
 * properties. See the notes for those properties for more information.
 */
@property(nonatomic, assign) ccColor4F ambientColor;

/**
 * The color of this material under ambient lighting.
 * Initially set to kCC3DefaultMaterialColorDiffuse.
 *
 * The value of this property is also affected by changes to the color and opacity
 * properties. See the notes for those properties for more information.
 */
@property(nonatomic, assign) ccColor4F diffuseColor;

/**
 * The color of this material under ambient lighting.
 * Initially set to kCC3DefaultMaterialColorSpecular.
 *
 * The value of this property is also affected by changes to the opacity property.
 * See the notes for the opacity property for more information.
 */
@property(nonatomic, assign) ccColor4F specularColor;

/**
 * The emission color of this material.
 * Initially set to kCC3DefaultMaterialColorEmission.
 *
 * The value of this property is also affected by changes to the opacity property.
 * See the notes for the opacity property for more information.
 */
@property(nonatomic, assign) ccColor4F emissionColor;

/**
 * The shininess of this material.
 *
 * This value is clamped to between zero and kCC3MaximumMaterialShininess.
 * Initially set to kCC3DefaultMaterialShininess.
 */
@property(nonatomic, assign) GLfloat shininess;

/**
 * The blending function for the source material (this material). This property must
 * be set to one of the valid GL blending functions.
 *
 * The value in this property combines with the value in the destinationBlend property
 * to determine the way that materials are combined when one (the source) is drawn over
 * another (the destination). Features such as transparency can cause the two to blend
 * together in various ways.
 *
 * If you want the source to completely cover the destination, set sourceBlend to GL_ONE.
 *
 * If you want to have the destination show through the source, either by setting
 * the diffuse alpha below one, or by covering this material with a texture that contains
 * an alpha channel set the sourceBlend to GL_ONE_MINUS_SRC_ALPHA.
 *
 * However, watch out for textures with a pre-multiplied alpha channel. If this material
 * has a texture with a pre-multiplied alpha channel AND you are NOT trying to make this
 * material translucent by setting diffuse alpha below one, set sourceBlend to GL_ONE,
 * so that the pre-multiplied alpha of the source will blend with the destination correctly.
 *
 * Opaque materials can be managed slightly more efficiently than translucent materials.
 * If a material really does not allow other materials to be seen behind it, you should
 * ensure that the sourceBlend and destinationBlend properties are set to GL_ONE and
 * GL_ZERO, respectively, to optimize rendering performance. The performance improvement
 * is small, but can add up if a large number of opaque objects are rendered as if they
 * were translucent.
 *
 * The initial value is determined by the value of the class-side property
 * defaultBlendFunc, which can be modified by the setDefaultBlendFunc: method.
 *
 * The value of this property is also affected by changes to the isOpaque and opacity
 * properties. See the notes for those properties for more information.
 */
@property(nonatomic, assign) GLenum sourceBlend;

/**
 * The blending function for the destination material. This property must be set to one
 * of the valid GL blending functions.
 *
 * The value in this property combines with the value in the sourceBlend property
 * to determine the way that materials are combined when one (the source) is drawn over
 * another (the destination). Features such as transparency can cause the two to blend
 * together in various ways.
 *
 * If you want the source to completely cover the destination, set destinationBlend to GL_ZERO.
 *
 * If you want to have the destination show through the source, either by setting the diffuse
 * alpha below one, or by covering this material with a texture that contains an alpha channel
 ( (including pre-multiplied alpha channel), set the destinationBlend to GL_ONE_MINUS_SRC_ALPHA.
 *
 * Opaque materials can be managed slightly more efficiently than translucent materials.
 * If a material really does not allow other materials to be seen behind it, you should
 * ensure that the sourceBlend and destinationBlend properties are set to GL_ONE and
 * GL_ZERO, respectively, to optimize rendering performance. The performance improvement
 * is small, but can add up if a large number of opaque objects are rendered as if they
 * were translucent.
 *
 * The initial value is determined by the value of the class-side property
 * defaultBlendFunc, which can be modified by the setDefaultBlendFunc: method.
 *
 * The value of this property is also affected by changes to the isOpaque and opacity
 * properties. See the notes for those properties for more information.
 */
@property(nonatomic, assign) GLenum destinationBlend;

/**
 * Indicates whether this material is opaque.
 *
 * This method returns YES if the values of the sourceBlend and destinationBlend
 * properties are GL_ONE and GL_ZERO, respectively, otherwise this method returns NO.
 *
 * Setting this property to YES sets the value of the sourceBlend property to GL_ONE
 * and the value of the destinationBlend to GL_ZERO. Setting this property to YES is
 * a convenient way to force the source to completely cover the destination, even if
 * the diffuse alpha value is less than one, and even if the texture contains alpha.
 *
 * Setting this property to NO sets the value of the destinationBlend property to
 * GL_ONE_MINUS_SRC_ALPHA, and sets the sourceBlend property to GL_SRC_ALPHA, unless
 * the diffuse alpha value is equal to one AND this material has a texture that
 * contains pre-multiplied alpha, in which case sourceBlend is set to GL_ONE.
 *
 * Setting the value of this property does not change the alpha values of any
 * of the material colors.
 *
 * The state of this property is also affected by setting the opacity property.
 * As a convenience, changing the opacity property to less than 255 will automatically
 * cause the isOpaque property to be set to NO, which in turn will change the sourceBlend
 * and destinationBlend properties, so that the translucency will be blended correctly.
 *
 * However, changing the opacity property to 255 will NOT automatically cause the
 * isOpaque property to be set to YES, Even if the opacity of the material is full,
 * the texture may contain translucency, which would be ignored if the isOpaque property
 * were to be set to YES.
 *
 * Setting this property should be thought of as a convenient way to switch between
 * the two most common types of blending combinations. For finer control of blending,
 * set the sourceBlend and destinationBlend properties and the alpha values of the
 * individual material colors directly, and avoid making changes to this property.
 *
 * Opaque materials can be managed slightly more efficiently than translucent materials.
 * If a material really does not allow other materials to be seen behind it, you should
 * ensure that this property is set to YES. The performance improvement is small, but
 * can add up if a large number of opaque objects are rendered as if they were translucent.
 */
@property(nonatomic, assign) BOOL isOpaque;

/**
 * Indicates the alpha test function that is used to determine if a pixel should be
 * drawn, based on the value of its alpha component.
 *
 * The value of this property must be one of the following values:
 *   - GL_ALWAYS: The pixel is always drawn, regardless of its alpha value.
 *   - GL_GREATER - The pixel is drawn only if its alpha value is greater than the
 *     value in the reference property.
 *   - GL_GEQUAL - The pixel is drawn only if its alpha value is greater than or equal
 *     to the value in the reference property.
 *   - GL_LESS - The pixel is drawn only if its alpha value is less than the value
 *     in the reference property.
 *   - GL_LEQUAL - The pixel is drawn only if its alpha value is less than or equal
 *     to the value in the reference property.
 *   - GL_EQUAL - The pixel is drawn only if its alpha value is equal to the value
 *     in the reference property.
 *   - GL_NOTEQUAL - The pixel is drawn only if its alpha value is not equal to the
 *     value in the reference property.
 *   - GL_NEVER: The pixel is never drawn.
 *
 * The initial value of this property is GL_ALWAYS, indicating that each pixel will
 * always be drawn, regardless of its alpha value.
 *
 * For most situations, alpha testing is not necessary, and you can leave the value
 * of this property at its initial value. Alpha testing can sometimes be useful when
 * drawing overlapping objects that each contain transparency, and it is not possible
 * to rely only on drawing order and depth testing to mediate whether a pixel should
 * be drawn.
 *
 * Although you can set this property directly, since the most common values are
 * either GL_ALWAYS or GL_GREATER, you can use the shouldDrawLowAlpha property as
 * a shortcut to switch between these two values.
 *
 * Alpha testing within the GL engine is automatically disabled if this property
 * is set to GL_ALWAYS, and enabled for any other value.
 */
@property(nonatomic, assign) GLenum alphaTestFunction;

/**
 * Indicates the reference value used by the alpha test function to compare against
 * the alpha value of each pixel to determine if it should be drawn.
 *
 * The value of this property must be between zero and one, inclusive. The value
 * is clamped by the GL engine if it is set to a value outside this range.
 *
 * The initial value of this property is zero.
 *
 * The value of this property has no effect if the value of the alphaTestFunction
 * property is either GL_ALWAYS or GL_NEVER.
 *
 * See the notes for the alphaTestFunction property for more information on alpha
 * testing.
 */
@property(nonatomic, assign) GLfloat alphaTestReference;

/**
 * Indicates whether alpha testing should be used to determine if pixels with
 * lower alpha values should be drawn.
 *
 * This property is really a shortcut for setting the alphaTestFunction to either
 * of its two most common values. Setting this property to YES will set the
 * alphaTestFunction propery to GL_ALWAYS. Setting this property to NO will set
 * the alphaTestFunction property to GL_GREATER.
 *
 * If the value of this property is set to YES, each pixel will be drawn regardless
 * of the value of its alpha component. If the value of this property is set to NO,
 * the value of the alpha component of each pixel will be compared against the value
 * in the alphaTestReference property, and only those pixel alpha values that are
 * greater than that reference value will be drawn. You can set the value of the
 * alphaTestReference property to determine the cutoff level.
 *
 * Reading the value of this property will return YES if the value of the alphaTestFunction
 * is any of GL_ALWAYS, GL_LESS or GL_LEQUAL, otherwise it returns NO.
 *
 * The initial value of this property is YES, indicating that pixels with lower
 * alpha values will be drawn.
 *
 * For most situations, alpha testing is not necessary, and you can leave the value
 * of this property set to YES. Alpha testing can sometimes be useful when drawing
 * overlapping objects that each contain transparency, and it is not possible to rely
 * only on drawing order and depth testing to mediate whether a pixel should be drawn.
 */
@property(nonatomic, assign) BOOL shouldDrawLowAlpha;

#pragma mark CCRGBAProtocol and CCBlendProtocol support

/**
 * Implementation of the CCRGBAProtocol color property.
 *
 * Querying this property returns the RGB components of the material's diffuseColor
 * property, converted from the floating point range (0 to 1), to the byte range
 * (0 to 255).
 *
 * When setting this property, the RGB values are each converted to a floating point
 * number between 0 and 1, and are set into both the ambientColor and diffuseColor
 * properties. The alpha of each of those properties remains the same.
 */
@property(nonatomic, assign) ccColor3B color;

/**
 * Implementation of the CCRGBAProtocol opacity property.
 *
 * Querying this property returns the alpha component of the material's diffuseColor
 * property, converted from the floating point range (0 to 1), to the byte range
 * (0 to 255).
 *
 * When setting this property, the value is converted to a floating point number
 * between 0 and 1, and is set into all of the ambientColor, diffuseColor,
 * specularColor, and emissionColor properties. The RGB components of each of
 * those properties remains unchanged.
 *
 * Changing this property may also affect the isOpaque property. As a convenience,
 * changing the opacity property to less than 255 will automatically cause the
 * isOpaque property to be set to NO, which in turn will change the sourceBlend and
 * destinationBlend properties, so that the translucency will be blended correctly.
 *
 * However, changing the opacity property to 255 will NOT automatically cause the
 * isOpaque property to be set to YES, Even if the opacity of the material is full,
 * the texture may contain translucency, which would be ignored if the isOpaque property
 * were to be set to YES.
 *
 * Setting this property should be thought of as a convenient way to make simple
 * changes to the opacity of a material, using the two most common types of
 * blending combinations. For finer control of blending, set the sourceBlend and
 * destinationBlend properties and the alpha values of the individual material
 * colors directly, and avoid making changes to this property.
 */
@property(nonatomic, assign) GLubyte opacity;

/**
 * Implementation of the CCBlendProtocol blendFunc property.
 *
 * This is a convenience property that gets and sets both the sourceBlend and
 * destinationBlend properties using a single structure.
 */
@property(nonatomic, assign) ccBlendFunc blendFunc;

/**
 * Returns the default GL material source and destination blend function used for new instances.
 *
 * The initial value is {GL_ONE GL_ZERO}.
 */
+(ccBlendFunc) defaultBlendFunc;

/** Sets the default GL material source and destination blend function used for new instances. */
+(void) setDefaultBlendFunc: (ccBlendFunc) aBlendFunc;

#pragma mark Textures

/**
 * When using a single texture for this material, this property holds that texture.
 *
 * This property may be left nil if no texture is needed.
 *
 * When using multiple textures for this material, this property holds the first
 * texture. You can add additional textures using the addTexture: method.
 *
 * As a convenience, this property can also be set using the addTexture: method,
 * which will set this property if it has not been set already. This is useful when
 * using multi-texturing, because it allows all textures attached to this material
 * to be handled the same way.
 *
 * The texture held by this property will be processed by the first GL texture unit
 * (texture unit zero).
 */
@property(nonatomic, retain) CC3Texture* texture;

/**
 * Returns the number of textures attached to this material, regardless of whether
 * the textures were attached using the texture property or the addTexture: method.
 */
@property(nonatomic, readonly) GLuint textureCount;

/**
 * Returns whether this material contains a texture that is configured as a bump-map.
 *
 * Returns YES only if one of the textures that was added to this material (either
 * through the texture property or the addTexture: method) returns YES from its
 * isBumpMap property. Otherwise, this property returns NO.
 */
@property(nonatomic, readonly) BOOL hasBumpMap;

/**
 * The direction, in local tangent coordinates, of the light source that is to
 * interact with any texture contained in this material that has been configured
 * as a bump-map.
 *
 * Bump-maps are textures that store a normal vector (XYZ coordinates) in
 * the RGB components of each texture pixel, instead of color information.
 * These per-pixel normals interact with the value of this lightDirection
 * property (through a dot-product), to determine the luminance of the pixel.
 *
 * Setting this property sets the equivalent property in all textures contained
 * within this material.
 *
 * Reading this value returns the value of the equivalent property in the first
 * texture that is configrued as a bump-map. Otherwise kCC3VectorZero is returned.
 *
 * The value of this property must be in the tangent-space coordinates associated
 * with the texture UV space, in practice, this property is typically not set
 * directly. Instead, you can use the globalLightLocation property of the mesh
 * node that is making use of this texture.
 */
@property(nonatomic, assign) CC3Vector lightDirection;

/**
 * In most situations, the material will use a single CC3Texture in the texture property.
 * However, if multi-texturing is used, additional CC3Texture instances can be provided
 * by adding them using this method.
 *
 * When multiple textures are attached to a material, when drawing, the material will
 * combine these textures together using configurations contained in the textureUnit
 * property of each texture.
 *
 * As a consistency convenience, if the texture property has not yet been set directly,
 * the first texture added using this method will appear in that property.
 *
 * Textures are processed by GL texture units in the order they are added to the material.
 * The first texture added (or set directly into the texture property) will be processed
 * by GL texture unit zero. Subsequent textures added with this method will be processed
 * by subsequent texture units, in the order they were added.
 *
 * The maximum number of texture units available is platform dependent, but will
 * be at least two. The maximum number of texture units available can be read from
 * [CC3OpenGLES11Engine engine].platform.maxTextureUnits.value. If you attempt to
 * add more than this number of textures to the material, the additional textures
 * will be ignored, and an informational message to that fact will be logged.
 */
-(void) addTexture: (CC3Texture*) aTexture;

/**
 * Removes the specified texture from this material.
 *
 * If the specified texture is that in the texture property, that property is set to nil.
 */
-(void) removeTexture: (CC3Texture*) aTexture;

/** Removes all textures from this material. */
-(void) removeAllTextures;

/**
 * Returns the texture with the specified name, that was added either via the texture
 * property or via the addTexture: method. Returns nil if such a texture cannot be found.
 */
-(CC3Texture*) getTextureNamed: (NSString*) aName;

/**
 * Returns the texture that will be processed by the texture unit with the specified
 * index, which should be a number between zero, and one less than the value of the
 * textureCount property.
 *
 * The value returned will be nil if there are no textures.
 */
-(CC3Texture*) textureForTextureUnit: (GLuint) texUnit;

/**
 * Sets the texture that will be processed by the texture unit with the specified index,
 * which should be a number between zero, and the value of the textureCount property.
 *
 * If the specified index is less than the number of texture units added already, the
 * specified texture will replace the one assigned to that texture unit. Otherwise, this
 * implementation will invoke the addTexture: method to add the texture to this material.
 *
 * If the specified texture unit index is zero, the value of the texture property will
 * be changed to the specified texture.
 */
-(void) setTexture: (CC3Texture*) aTexture forTextureUnit: (GLuint) texUnit;

#pragma mark Allocation and initialization

/**
 * Allocates and initializes an autoreleased unnamed instance with an automatically
 * generated unique tag value. The tag value is generated using a call to nextTag.
 */
+(id) material;

/** Allocates and initializes an unnamed autoreleased instance with the specified tag. */
+(id) materialWithTag: (GLuint) aTag;

/**
 * Allocates and initializes an autoreleased instance with the specified name and an
 * automatically generated unique tag value. The tag value is generated using a call to nextTag.
 */
+(id) materialWithName: (NSString*) aName;

/** Allocates and initializes an autoreleased instance with the specified tag and name. */
+(id) materialWithTag: (GLuint) aTag withName: (NSString*) aName;

/**
 * Allocates and initializes an autoreleased unnamed instance with an automatically
 * generated unique tag value. The tag value is generated using a call to nextTag.
 *
 * The returned instance will have a specularColor of { 1.0, 1.0, 1.0, 1.0 } and a
 * shininess of 75.0.
 */
+(id) shiny;

/**
 * Allocates and initializes an autoreleased unnamed instance with an automatically
 * generated unique tag value. The tag value is generated using a call to nextTag.
 *
 * The returned instance will have both diffuseColor and specularColor set to
 * { 1.0, 1.0, 1.0, 1.0 } and a shininess of 75.0.
 */
+(id) shinyWhite;

#pragma mark Drawing

/**
 * Applies this material to the GL engine. The specified visitor encapsulates
 * the frustum of the currently active camera, and certain drawing options.
 *
 * This implementation first determines if this material is different than the material
 * that was last bound to the GL engine. If this material is indeed different, this method
 * applies the material to the GL engine, otherwise it does nothing.
 *
 * Draws this texture to the GL engine as follows:
 *  - Applies the blending properties to the GL engine
 *  - Applies the various lighting and color properties to the GL engine
 *  - Binds the texture property to the GL engine as texture unit zero.
 *  - Binds any additional textures added using addTexture: to additional texture units.
 *  - Disables any unused texture units.
 *
 * If the texture property is nil, and there are no overlays, all texture units
 * in the GL engine will be disabled.
 *
 * This method is invoked automatically during node drawing. Usually, the application
 * never needs to invoke this method directly.
 */
-(void) drawWithVisitor: (CC3NodeDrawingVisitor*) visitor;

/**
 * Unbinds the GL engine from any materials.
 *
 * This implementation simply delegates to the unbind class method.
 * Usually, the application never needs to invoke this method directly.
 */
-(void) unbind;

/**
 * Unbinds the GL engine from any materials.
 *
 * Disables material blending in the GL engine, and invokes the unbind class method
 * of CC3Texture to disable all texturing.
 *
 * This method is invoked automatically from the CC3Node instance.
 * Usually, the application never needs to invoke this method directly.
 */
+(void) unbind;

#pragma mark Material context switching

/**
 * Resets the tracking of the material switching functionality.
 *
 * This is invoked automatically by the CC3World at the beginning of each frame
 * drawing cycle. Usually, the application never needs to invoke this method directly.
 */
+(void) resetSwitching;

@end


text:
package com.conpany.project;

import com.company.project.Application;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

/**
 * 单元测试继承该类即可
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@Transactional
@Rollback
public abstract class Tester {}


text:
cartmans_phrase = "Screw you guys " + "I'm going home."

# This error was analyzed in the README file.
# --- error -------------------------------------------------------

def cartman_hates(thing)
  while true
    puts "What's there to hate about #{thing}?"
  end
end

# This is a tricky error. The line number may throw you off.

# 1. What is the name of the file with the error?
#  errors.rb
# 2. What is the line number where the error occurs?
#  170
# 3. What is the type of error message?
#  Syntax error
# 4. What additional information does the interpreter provide about this type of error?
#  unexpected end-of-input, expecting keyword_end
# 5. Where is the error in the code?
#  The last comment - # Write your reflection below as a comment.
# 6. Why did the interpreter give you this error?
#  You need to end the while block and the cartman_hates method.

# --- error -------------------------------------------------------

south_park = "Going down to South Park, gonna have myself a time!"

# 1. What is the line number where the error occurs?
#  36
# 2. What is the type of error message?
#  NameError
# 3. What additional information does the interpreter provide about this type of error?
#  undefined local variable or method `south_park' for main:Object
# 4. Where is the error in the code?
#  After the variable name
# 5. Why did the interpreter give you this error?
#  Variable is named but there's nothing in it.

# --- error -------------------------------------------------------

def cartman()

end

# 1. What is the line number where the error occurs?
#  51
# 2. What is the type of error message?
#  NoMethodError
# 3. What additional information does the interpreter provide about this type of error?
#  undefined method `cartman' for main:Object
# 4. Where is the error in the code?
#
# 5. Why did the interpreter give you this error?
#  Method was named but not defined

# --- error -------------------------------------------------------

def cartmans_phrase(quote)
  puts "I'm not fat; I'm big-boned!"
end

cartmans_phrase('I hate Kyle')

# 1. What is the line number where the error occurs?
#  68
# 2. What is the type of error message?
#  ArgumentError
# 3. What additional information does the interpreter provide about this type of error?
#  in `cartmans_phrase': wrong number of arguments (1 for 0)
# 4. Where is the error in the code?
#  After method name
# 5. Why did the interpreter give you this error?
# The method doesn't have a place for arguments.

# --- error -------------------------------------------------------

def cartman_says(offensive_message)
  puts offensive_message
end

cartman_says("Big floppy donky dick")

# 1. What is the line number where the error occurs?
#  87
# 2. What is the type of error message?
#  ArgumentError
# 3. What additional information does the interpreter provide about this type of error?
#  in `cartman_says': wrong number of arguments (0 for 1)
# 4. Where is the error in the code?
#  When the method is called
# 5. Why did the interpreter give you this error?
# There was no argument given

# --- error -------------------------------------------------------

def cartmans_lie(lie, name)
  puts "#{lie}, #{name}!"
end

cartmans_lie('A meteor the size of the earth is about to hit Wyoming!', 'Kenny')

# 1. What is the line number where the error occurs?
#  108
# 2. What is the type of error message?
#  ArgumentError
# 3. What additional information does the interpreter provide about this type of error?
#  in `cartmans_lie': wrong number of arguments (1 for 2)
# 4. Where is the error in the code?
# When the method is called.
# 5. Why did the interpreter give you this error?
# "name" argument wasn't given.

# --- error -------------------------------------------------------

"Respect my authoritay!" * 5

# 1. What is the line number where the error occurs?
#  127
# 2. What is the type of error message?
#  TypeError
# 3. What additional information does the interpreter provide about this type of error?
#  in `*': String can't be coerced into Fixnum
# 4. Where is the error in the code?
#  The multiplication order.
# 5. Why did the interpreter give you this error?
# You can multiply 5 by "Respect my authoritay!"

# --- error -------------------------------------------------------

amount_of_kfc_left = 20/2

# 1. What is the line number where the error occurs?
#  143
# 2. What is the type of error message?
# Zero Division Error
# 3. What additional information does the interpreter provide about this type of error?
#  in `/': divided by 0
# 4. Where is the error in the code?
# The division
# 5. Why did the interpreter give you this error?
#  20 wasn't divided by anything.

# --- error -------------------------------------------------------

require_relative "errors.rb"

# 1. What is the line number where the error occurs?
#  158
# 2. What is the type of error message?
#  Load Error
# 3. What additional information does the interpreter provide about this type of error?
#in `require_relative': cannot load such file -- /Users/johannalonn/Documents/DevBootcamp/phase-0/week-4/analyze-errors/cartmans_essay.md
# 4. Where is the error in the code?
# The filepath
# 5. Why did the interpreter give you this error?
#  The filepath is wrong.

# --- REFLECTION -------------------------------------------------------
# Write your reflection below as a comment.

=begin

Which error was the most difficult to read?
Most of them were fairly easy to figure out. Number 2 (cartman_hates(thing)) tripped me up a bit.

How did you figure out what the issue with the error was?
The hint and the indenting gave it away. I saw that `def` had an end but `while` did not.

Were you able to determine why each error message happened based on the code?
Yes, having the error type and the additional information is a huge help.

When you encounter errors in your future code, what process will you follow to help you debug?
Just taking apart the error message piece by piece now that I know what each part refers to.

=end


text:
<?php

namespace Application\ApplicationHomeBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Application\ApplicationHomeBundle\Entity\Email;
use Application\ApplicationHomeBundle\Form\EmailType;

/**
 * Email controller.
 *
 */
class EmailController extends Controller
{

    /**
     * Lists all Email entities.
     *
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('ApplicationHomeBundle:Email')->findAll();

        return $this->render('ApplicationHomeBundle:Email:index.html.twig', array(
            'entities' => $entities,
        ));
    }
    /**
     * Creates a new Email entity.
     *
     */
    public function createAction(Request $request)
    {
        $entity = new Email();
        $form = $this->createCreateForm($entity);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('email_show', array('id' => $entity->getId())));
        }

        return $this->render('ApplicationHomeBundle:Email:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));
    }

    /**
     * Creates a form to create a Email entity.
     *
     * @param Email $entity The entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createCreateForm(Email $entity)
    {
        $form = $this->createForm(new EmailType(), $entity, array(
            'action' => $this->generateUrl('email_create'),
            'method' => 'POST',
        ));

        $form->add('submit', 'submit', array('label' => 'Create'));

        return $form;
    }

    /**
     * Displays a form to create a new Email entity.
     *
     */
    public function newAction()
    {
        $entity = new Email();
        $form   = $this->createCreateForm($entity);

        return $this->render('ApplicationHomeBundle:Email:new.html.twig', array(
            'entity' => $entity,
            'form'   => $form->createView(),
        ));

    }

    /**
     * Finds and displays a Email entity.
     *
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ApplicationHomeBundle:Email')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Email entity.');
        }

        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ApplicationHomeBundle:Email:show.html.twig', array(
            'entity'      => $entity,
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing Email entity.
     *
     */
    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ApplicationHomeBundle:Email')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Email entity.');
        }

        $editForm = $this->createEditForm($entity);
        $deleteForm = $this->createDeleteForm($id);

        return $this->render('ApplicationHomeBundle:Email:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
    * Creates a form to edit a Email entity.
    *
    * @param Email $entity The entity
    *
    * @return \Symfony\Component\Form\Form The form
    */
    private function createEditForm(Email $entity)
    {
        $form = $this->createForm(new EmailType(), $entity, array(
            'action' => $this->generateUrl('email_update', array('id' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('submit', 'submit', array('label' => 'Update'));

        return $form;
    }
    /**
     * Edits an existing Email entity.
     *
     */
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ApplicationHomeBundle:Email')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Email entity.');
        }

        $deleteForm = $this->createDeleteForm($id);
        $editForm = $this->createEditForm($entity);
        $editForm->handleRequest($request);

        if ($editForm->isValid()) {
            $em->flush();

            return $this->redirect($this->generateUrl('email_edit', array('id' => $id)));
        }

        return $this->render('ApplicationHomeBundle:Email:edit.html.twig', array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }
    /**
     * Deletes a Email entity.
     *
     */
    public function deleteAction(Request $request, $id)
    {
        $form = $this->createDeleteForm($id);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $entity = $em->getRepository('ApplicationHomeBundle:Email')->find($id);

            if (!$entity) {
                throw $this->createNotFoundException('Unable to find Email entity.');
            }

            $em->remove($entity);
            $em->flush();
        }

        return $this->redirect($this->generateUrl('email'));
    }

    /**
     * Creates a form to delete a Email entity by id.
     *
     * @param mixed $id The entity id
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm($id)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('email_delete', array('id' => $id)))
            ->setMethod('DELETE')
            ->add('submit', 'submit', array('label' => 'Delete'))
            ->getForm()
        ;
    }
}