text:
<?xml version="1.0" encoding="UTF-8"?>

<rootTag>
  <Award>
    <AwardTitle>PostDoctoral Research Fellowship</AwardTitle>
    <AwardEffectiveDate>09/01/2008</AwardEffectiveDate>
    <AwardExpirationDate>08/31/2012</AwardExpirationDate>
    <AwardAmount>108000</AwardAmount>
    <AwardInstrument>
      <Value>Fellowship</Value>
    </AwardInstrument>
    <Organization>
      03040000
      <Directorate>
        <LongName>Direct For Mathematical & Physical Scien</LongName>
      </Directorate>
      <Division>
        <LongName>Division Of Mathematical Sciences</LongName>
      </Division>
    </Organization>
    <ProgramOfficer>
      <SignBlockName>Bruce P. Palka</SignBlockName>
    </ProgramOfficer>
    <AbstractNarration>Postdoctoral Research Fellowship</AbstractNarration>
    <MinAmdLetterDate>06/23/2008</MinAmdLetterDate>
    <MaxAmdLetterDate>06/23/2008</MaxAmdLetterDate>
    <ARRAAmount/>
    <AwardID>0802975</AwardID>
    <Investigator>
      <FirstName>John</FirstName>
      <LastName>Baldwin</LastName>
      <EmailAddress/>
      <StartDate>06/23/2008</StartDate>
      <EndDate/>
      <RoleCode>Principal Investigator</RoleCode>
    </Investigator>
    <Institution>
      <Name>Baldwin John A</Name>
      <CityName>New York</CityName>
      <ZipCode>100274679</ZipCode>
      <PhoneNumber/>
      <StreetAddress/>
      <CountryName>United States</CountryName>
      <StateName>New York</StateName>
      <StateCode>NY</StateCode>
    </Institution>
    <FoaInformation>
      0000099
      <Name>Other Applications NEC</Name>
    </FoaInformation>
  </Award>
</rootTag>

redpajama_set_name: RedPajamaGithub


text:
1. Add a tsconfig.json file and configure it.

    ```json
    {
        "compilerOptions": {
            "target": "es5",
            "module": "commonjs",
            "sourceMap": true
        }
    }
    ```

2. Create tasks.json

  - Type Shift+Cmd+P, type `config`, then select Configure Task Runner
  - A tasks.json file will be added to the .vscode folder

3. Add a file called HelloWorld.ts, then paste the following:

    ```typescript
    class Startup {
        public static main(): number {
            console.log("Hello World");
            return 0;
        }
    }
    ```

4. Press Cmd+B to compile the TypeScript into ES5 JavaScript.

  - A HelloWorld.js file should appear


text:
<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Forum_Front_Group extends Controller_Forum_Front_Group_Core {}


text:
package com.hello;

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

public class CutSticks {
    public static int[] cutSticks(int[] lengths) {
        if (lengths == null || lengths.length <= 0) {
            return null;
        }

        // Sort firstly
        Arrays.sort(lengths);

        // Initial the count
        int index = 0, count = lengths.length;
        List<Integer> countList = new ArrayList<Integer>();

        // Loop to find the minimum values
        while (index < count) {
            countList.add(count - index);
            if (index == count - 1) {
                break;
            }

            int value = lengths[index];
            for (int i = index + 1; i < count; i++) {
                if (lengths[i] != value || i == count - 1) {
                    // Remember the left count
                    index = i;

                    // Cut the length
                    for (int j = i; j < count; j++) {
                        lengths[j] -= value;
                    }
                    break;
                }
            }
        }

        // Return arr
        int[] arr = new int[countList.size()];
        for (int i = 0; i < countList.size(); i++) {
            arr[i] = countList.get(i);
        }
        return arr;
    }
}


text:
<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "{{%marks}}".
 *
 * @property integer $id
 * @property integer $lesson_id
 * @property integer $user_id
 * @property integer $created_at
 * @property integer $updated_at
 *
 * @property Lessons $lesson
 * @property User $user
 */
class Marks extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%marks}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['lesson_id','user_id','mark_id'], 'required'],
            [['lesson_id', 'user_id', 'created_at', 'updated_at'], 'integer'],
            [['lesson_id'], 'exist', 'skipOnError' => true, 'targetClass' => Lessons::className(), 'targetAttribute' => ['lesson_id' => 'id']],
            [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
            [['mark_id','prev_mark'], 'exist', 'skipOnError'=>true, 'targetClass'=>MarksList::className(), 'targetAttribute'=>['mark_id'=>'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'lesson_id' => 'Урок',
            'user_id' => 'Ученик',
            'created_at' => 'Поставлена',
            'updated_at' => 'Исправлена',
            'mark_id' =>'Оценка',
            'prev_mark'=>'Предыдущая оценка',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getLesson()
    {
        return $this->hasOne(Lessons::className(), ['id' => 'lesson_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }
}


text:
/**
 * \file
 *
 * Definitions for the Frame Streams data transport protocol for
 * dnstap message logs.
 */

#include "config.h"
#include "dnstap/dnstap_fstrm.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"

void* fstrm_create_control_frame_start(char* contenttype, size_t* len)
{
	uint32_t* control;
	size_t n;
	/* start framestream message:
	 * 4byte 0: control indicator.
	 * 4byte bigendian: length of control frame
	 * 4byte bigendian: type START
	 * 4byte bigendian: option: content-type
	 * 4byte bigendian: length of string
	 * string of content type (dnstap)
	 */
	n = 4+4+4+4+4+strlen(contenttype);
	control = malloc(n);
	if(!control)
		return NULL;
	control[0] = 0;
	control[1] = htonl(4+4+4+strlen(contenttype));
	control[2] = htonl(FSTRM_CONTROL_FRAME_START);
	control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
	control[4] = htonl(strlen(contenttype));
	memmove(&control[5], contenttype, strlen(contenttype));
	*len = n;
	return control;
}

void* fstrm_create_control_frame_stop(size_t* len)
{
	uint32_t* control;
	size_t n;
	/* stop framestream message:
	 * 4byte 0: control indicator.
	 * 4byte bigendian: length of control frame
	 * 4byte bigendian: type STOP
	 */
	n = 4+4+4;
	control = malloc(n);
	if(!control)
		return NULL;
	control[0] = 0;
	control[1] = htonl(4);
	control[2] = htonl(FSTRM_CONTROL_FRAME_STOP);
	*len = n;
	return control;
}

void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
{
	uint32_t* control;
	size_t n;
	/* start bidirectional stream:
	 * 4 bytes 0 escape
	 * 4 bytes bigendian length of frame
	 * 4 bytes bigendian type READY
	 * 4 bytes bigendian frame option content type
	 * 4 bytes bigendian length of string
	 * string of content type.
	 */
	/* len includes the escape and framelength */
	n = 4+4+4+4+4+strlen(contenttype);
	control = malloc(n);
	if(!control) {
		return NULL;
	}
	control[0] = 0;
	control[1] = htonl(4+4+4+strlen(contenttype));
	control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
	control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
	control[4] = htonl(strlen(contenttype));
	memmove(&control[5], contenttype, strlen(contenttype));
	*len = n;
	return control;
}

void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
{
	uint32_t* control;
	size_t n;
	/* control frame on reply:
	 * 4 bytes 0 escape
	 * 4 bytes bigendian length of frame
	 * 4 bytes bigendian type ACCEPT
	 * 4 bytes bigendian frame option content type
	 * 4 bytes bigendian length of string
	 * string of content type.
	 */
	/* len includes the escape and framelength */
	n = 4+4+4+4+4+strlen(contenttype);
	control = malloc(n);
	if(!control) {
		return NULL;
	}
	control[0] = 0;
	control[1] = htonl(4+4+4+strlen(contenttype));
	control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT);
	control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
	control[4] = htonl(strlen(contenttype));
	memmove(&control[5], contenttype, strlen(contenttype));
	*len = n;
	return control;
}

void* fstrm_create_control_frame_finish(size_t* len)
{
	uint32_t* control;
	size_t n;
	/* control frame on reply:
	 * 4 bytes 0 escape
	 * 4 bytes bigendian length of frame
	 * 4 bytes bigendian type FINISH
	 */
	/* len includes the escape and framelength */
	n = 4+4+4;
	control = malloc(n);
	if(!control) {
		return NULL;
	}
	control[0] = 0;
	control[1] = htonl(4);
	control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH);
	*len = n;
	return control;
}

char* fstrm_describe_control(void* pkt, size_t len)
{
	uint32_t frametype = 0;
	char buf[512];
	char* str = buf;
	size_t remain, slen = sizeof(buf);
	uint8_t* pos;

	buf[0]=0;
	if(len < 4) {
		snprintf(buf, sizeof(buf), "malformed control frame, "
			"too short, len=%u", (unsigned int)len);
		return strdup(buf);
	}
	frametype = sldns_read_uint32(pkt);
	if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) {
		(void)sldns_str_print(&str, &slen, "accept");
	} else if(frametype == FSTRM_CONTROL_FRAME_START) {
		(void)sldns_str_print(&str, &slen, "start");
	} else if(frametype == FSTRM_CONTROL_FRAME_STOP) {
		(void)sldns_str_print(&str, &slen, "stop");
	} else if(frametype == FSTRM_CONTROL_FRAME_READY) {
		(void)sldns_str_print(&str, &slen, "ready");
	} else if(frametype == FSTRM_CONTROL_FRAME_FINISH) {
		(void)sldns_str_print(&str, &slen, "finish");
	} else {
		(void)sldns_str_print(&str, &slen, "type%d", (int)frametype);
	}

	/* show the content type options */
	pos = pkt + 4;
	remain = len - 4;
	while(remain >= 8) {
		uint32_t field_type = sldns_read_uint32(pos);
		uint32_t field_len = sldns_read_uint32(pos+4);
		if(remain < field_len) {
			(void)sldns_str_print(&str, &slen, "malformed_field");
			break;
		}
		if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
			char tempf[512];
			(void)sldns_str_print(&str, &slen, " content-type(");
			if(field_len < sizeof(tempf)-1) {
				memmove(tempf, pos+8, field_len);
				tempf[field_len] = 0;
				(void)sldns_str_print(&str, &slen, "%s", tempf);
			} else {
				(void)sldns_str_print(&str, &slen, "<error-too-long>");
			}
			(void)sldns_str_print(&str, &slen, ")");
		} else {
			(void)sldns_str_print(&str, &slen,
				" field(type %u, length %u)",
				(unsigned int)field_type,
				(unsigned int)field_len);
		}
		pos += 8 + field_len;
		remain -= (8 + field_len);
	}
	if(remain > 0)
		(void)sldns_str_print(&str, &slen, " trailing-bytes"
			"(length %u)", (unsigned int)remain);
	return strdup(buf);
}


text:
package net.guerra24.infinity.client.world;

import java.util.Random;

public class SimplexNoise {

	SimplexNoise_octave[] octaves;
	double[] frequencys;
	double[] amplitudes;

	int largestFeature;
	double persistence;
	int seed;

	public SimplexNoise(int largestFeature, double persistence, int seed) {
		this.largestFeature = largestFeature;
		this.persistence = persistence;
		this.seed = seed;

		// recieves a number (eg 128) and calculates what power of 2 it is (eg
		// 2^7)
		int numberOfOctaves = (int) Math.ceil(Math.log10(largestFeature) / Math.log10(2));

		octaves = new SimplexNoise_octave[numberOfOctaves];
		frequencys = new double[numberOfOctaves];
		amplitudes = new double[numberOfOctaves];

		Random rnd = new Random(seed);

		for (int i = 0; i < numberOfOctaves; i++) {
			octaves[i] = new SimplexNoise_octave(rnd.nextInt());

			frequencys[i] = Math.pow(2, i);
			amplitudes[i] = Math.pow(persistence, octaves.length - i);

		}

	}

	public double getNoise(int x, int y) {

		double result = 0;

		for (int i = 0; i < octaves.length; i++) {
			// double frequency = Math.pow(2,i);
			// double amplitude = Math.pow(persistence,octaves.length-i);

			result = result + octaves[i].noise(x / frequencys[i], y / frequencys[i]) * amplitudes[i];
		}

		return result;

	}

	public double getNoise(int x, int y, int z) {

		double result = 0;

		for (int i = 0; i < octaves.length; i++) {
			double frequency = Math.pow(2, i);
			double amplitude = Math.pow(persistence, octaves.length - i);

			result = result + octaves[i].noise(x / frequency, y / frequency, z / frequency) * amplitude;
		}

		return result;

	}
}


text:
COLUMN name   FORMAT a35
COLUMN value  FORMAT a15
COLUMN asynch FORMAT a10

SELECT name, value FROM v$parameter WHERE name IN ('timed_statistics' ,'filesystemio_options' ,'disk_asynch_io');

SELECT f.name NAME, i.asynch_io  ASYNCH FROM  v$datafile f, v$iostat_file i WHERE f.file# = i.file_no AND i.filetype_name = 'Data File';


text:
<?php

namespace knurt\domaincheck;

interface DomainCheck {

	/**
	 * return true if the domain is checkable and valid.
	 * return null, if the domain is not checkable.
	 * return false on invalid domains.
	 * invalid domains are subdomains (requesting "sub.domain.com") or
	 * domains with characters not allowed.
	 */
	public function isValid();

	/**
	 * return true if the domain exists.
	 * if the domain is invalid,
	 * return false (because it does not exist)
	 */
	public function exists();

	/**
	 * return true if the domain can be checked
	 */
	public function isCheckable();
}
?>


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Kbtter3.ViewModels;

namespace Kbtter3.Views
{

    /// <summary>
    /// SettingPage.xaml の相互作用ロジック
    /// </summary>
    internal partial class SettingPage : Page
    {
        Dictionary<string, Page> ChildPages = new Dictionary<string, Page>();
        SettingPageViewModel vm;

        public SettingPage()
        {
            InitializeComponent();
            vm = (SettingPageViewModel)DataContext;
            vm.Load();
            ChildPages["View.MainWindow"] = new Setting.View.MainWindowPage(vm.Setting.MainWindow);
            ChildPages["View.StatusPage"] = new Setting.View.StatusPagePage(vm.Setting.StatusPage);
            ChildPages["View.UserProfilePage"] = new Setting.View.UserProfilePagePage(vm.Setting.UserProfilePage);
            ChildPages["Kbtter3.Consumer"] = new Setting.Kbtter3.ConsumerPage(vm.Setting.Consumer);
        }

        private void TreeViewCategories_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var s = ((e.NewValue as TreeViewItem).Tag as string);
            if (!string.IsNullOrEmpty(s) && ChildPages.ContainsKey(s)) FramePaging.Content = ChildPages[s];
        }

    }
}


text:
<?php

namespace Consigliere\Components\Support;

class Stub
{
    /**
     * The stub path.
     *
     * @var string
     */
    protected $path;

    /**
     * The base path of stub file.
     *
     * @var null|string
     */
    protected static $basePath = null;

    /**
     * The replacements array.
     *
     * @var array
     */
    protected $replaces = [];

    /**
     * The contructor.
     *
     * @param string $path
     * @param array $replaces
     */
    public function __construct($path, array $replaces = [])
    {
        $this->path     = $path;
        $this->replaces = $replaces;
    }

    /**
     * Create new self instance.
     *
     * @param string $path
     * @param array $replaces
     *
     * @return self
     */
    public static function create($path, array $replaces = [])
    {
        return new static($path, $replaces);
    }

    /**
     * Create new self instance from full path.
     *
     * @param string $path
     * @param array $replaces
     *
     * @return self
     */
    public static function createFromPath($path, array $replaces = [])
    {
        $stub = static::create($path, $replaces);

        $stub->setBasePath('');

        return $stub;
    }

    /**
     * Set stub path.
     *
     * @param string $path
     *
     * @return self
     */
    public function setPath($path)
    {
        $this->path = $path;

        return $this;
    }

    /**
     * Get stub path.
     *
     * @return string
     */
    public function getPath()
    {
        return static::getBasePath() . $this->path;
    }

    /**
     * Set base path.
     *
     * @param string $path
     */
    public static function setBasePath($path)
    {
        static::$basePath = $path;
    }

    /**
     * Get base path.
     *
     * @return string|null
     */
    public static function getBasePath()
    {
        return static::$basePath;
    }

    /**
     * Get stub contents.
     *
     * @return mixed|string
     */
    public function getContents()
    {
        $contents = file_get_contents($this->getPath());

        foreach ($this->replaces as $search => $replace) {
            $contents = str_replace('$' . strtoupper($search) . '$', $replace, $contents);
        }

        return $contents;
    }

    /**
     * Get stub contents.
     *
     * @return string
     */
    public function render()
    {
        return $this->getContents();
    }

    /**
     * Save stub to specific path.
     *
     * @param string $path
     * @param string $filename
     *
     * @return bool
     */
    public function saveTo($path, $filename)
    {
        return file_put_contents($path . '/' . $filename, $this->getContents());
    }

    /**
     * Set replacements array.
     *
     * @param array $replaces
     *
     * @return $this
     */
    public function replace(array $replaces = [])
    {
        $this->replaces = $replaces;

        return $this;
    }

    /**
     * Get replacements.
     *
     * @return array
     */
    public function getReplaces()
    {
        return $this->replaces;
    }

    /**
     * Handle magic method __toString.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->render();
    }
}


text:
<?php

namespace DesignPatterns\Creational\Prototype;

/**
 * Class FooBookPrototype.
 */
class FooBookPrototype extends BookPrototype
{
    protected $category = 'Foo';

    /**
     * empty clone.
     */
    public function __clone()
    {
    }
}


text:
require 'tap/tasks/file_task'
require 'ms/xcalibur/peak_file'

module Ms
  module Xcalibur
    # :startdoc::task adds graph data to an exported peak file
    #
    # Peakify adds points to signify the relative intensity (ie the rounded
    # intensity/max_intensity) of peaks to a peak list extracted from Xcalibur
    # Qual Browser (v 2.0)..  This can be useful as a visual aid.
    #
    #   [peakfile.txt]
    #   SPECTRUM - MS
    #   GSE_T29K_080703143635.raw
    #   ITMS + c ESI Full ms [300.00-2000.00]
    #   Scan #: 11
    #   RT: 0.07
    #   Data points: 1490
    #   Mass	Intensity
    #   300.516479	2000.0	.................................
    #   301.392487	1000.0	.................
    #   302.465759	3000.0	..................................................
    #   ...
    #
    # Options can be specified to filter out points within a range of relative
    # intensities.
    #
    class Peakify < Tap::Tasks::FileTask

      config :point_char, '.'                          # A character used for each intensity point
      config :min, 0, &c.numeric                       # Min relative intenisty
      config :max, 100, &c.numeric                     # Max relative intenisty
      config :sort, false, &c.flag                     # Sort by intensity
      config :output, $stdout, &c.io(:<<, :binmode)    # The output file

      def process(source)
        prepare(output) if output.kind_of?(String)
        open_io(output, 'w') do |target|
          target.binmode

          # now perform the task...
          peak_file = PeakFile.parse File.read(source)
          max_intensity = peak_file.data.inject(0) do |max, (mz, intensity)|
            intensity > max ? intensity : max
          end

          range = min..max
          peak_file.data = peak_file.data.collect do |(mz, intensity)|
            percent = (intensity / max_intensity * 100)
            next unless range.include?(percent)

            [mz, intensity, point_char * percent.round]
          end.compact

          if sort
            peak_file.data = peak_file.data.sort_by do |(mz, intensity)|
              intensity
            end.reverse
          end

          target << peak_file.to_s
        end
        output
      end
    end
  end
end


text:
<title>htmlArea Help</title>

htmlArea v2.03

Turn any <textarea> into a WYSIWYG editor, a free script
from your friends at interactivetools.com

Introduction

What is htmlArea?

Is it really free? What's the catch?

What are the browser requirements?

Can I see an example of what it looks like?

Where can I find out more info, download the latest version, and talk to other htmlArea users?

Installation / Setup

How do I add htmlArea to my web page?

I want to change the editor settings, how do I do that?

How can I change what controls are displayed on the toolbar?

How can I change what fonts are in the font list?

How can I change what sizes are in the font size?

How can I change what styles are in the font style (CSS) list?

How can I specify an external stylesheet for my styles?

Frequently Asked Questions

What the project goals for htmlArea?

This editor is pretty neat, so how does it actually work?

You don't happen to have one of these for (Netscape, Mozilla, Opera, Mac IE, etc) do you?

Why doesn't htmlArea output XHTML instead of regular HTML? Can you make it do that?

I'd like to be able to upload images from my hard drive, can you add that feature?

I'd like to <insert idea here>, can you add that feature?

Can I change the toolbar/button colors?

I love htmlArea, is there anything I can do to help the project?

Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?

Known Bugs & Issues

Undo/Redo doesn't work

Relative paths are converted to absolute paths

HTML header info (eg: <head>, <body>, etc) doesn't get preserved

Some tags (eg: noframes, noscript, etc) doesn't get preserved

htmlArea doesn't work when multiple textareas that have the same name

Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?

Change Log

View Change Log

Introduction back to top

What is htmlArea?

htmlArea is a free WYSIWYG (what you see is what you get) editor replacement for <textarea> fields.  By adding a few
simple lines of JavaScript to your web page you can replace a regular textarea with a rich text
editor that let your users do the following:

Format text to be bold, italicized, or underlined.

Change the face, size, style and colour.

Left, centre, or right-justify paragraphs.

Make bulleted or numbered lists.

Indent or un-indent paragraphs.

Insert a horizontal line.

Insert hyperlinks and images.

View the raw HTML source of what they're editing.

and much more...

Some of the interesting features of htmlArea that set's it apart from other web based WYSIWYG editors are as follows:

It's lightweight, fast loading and can transform a regular textarea into a rich-text editor with a single line of JavaScript.

It's 100% backwards compatible with older or non-supported browsers (they get the original textarea field).

It's free and can be incorporated into any free or commercial program.

It works with any programming language (ASP, PHP, Perl, Java, etc).

It's written in simple JavaScript and can be easily viewed, modified or extended.

It remembers entered content when a user navigates away and then hits "back" in their browser.

Since it replaces existing textareas it doesn't require a lot of code to add it to your pages (just one line).

Did we mention it was free? : )

Is it really free? What's the catch?

Yes! It's really free.  You can use it, modify it, distribute it with your software,
or do just about anything you like with it.

What are the browser requirements?

htmlArea requires Internet Explorer 5.5 or better on Windows to run.  This is because it
makes use of some advanced features of IE5.5 that aren't available in other browsers yet.
It is backwards compatible with other browsers, though.  They will get a regular textarea
field instead of a WYSIWYG editor.

Can I see an example of what it looks like?

Sure, make sure you're using IE5.5 or better on windows and see below.

Here is a regular <textarea> field.

<textarea name="textbox1" style="height: 110px; width: 700px;">
Here is some sample text in a regular <textarea>.
There's not much you can do besides, well, enter plain text...
</textarea>

And here is a <textarea> transformed with htmlArea (with a single line of JavaScript code).

<textarea name="textbox2" style="height: 110px; width: 700px;">
Here is some sample text in textarea thats been transformed with htmlArea.

You can make things bold, italic, underline.  You can change the
size and colors!
And lots more...

Try htmlArea today!

</textarea>

Where can I find out more info, download the latest version, and talk to other htmlArea users?

You can find out more about htmlArea and download the latest version on the
htmlArea homepage
and you can talk to other htmlArea users and post any comments or suggestions you have in the
htmlArea forum.

Installation / Setup back to top

How do I add htmlArea to my web page?

It's easy, first you need to upload the htmlArea files to your website.  Just follow these steps:

Download the latest version from the htmlArea homepage.

Unzip the files onto your local computer (making sure to maintain the directory structure contained in the zip).

Create a new folder on your website called /htmlarea/ (make sure it's NOT inside the cgi-bin).

Transfer all the htmlArea files from your local computer into the /htmlarea/ folder on your website.

Open the example page /htmlarea/example.html with your browser to make sure everything works.

Once htmlArea is on your website all you need to do is add some JavaScript to any pages that you want to
add WYSIWYG editors to.  Here's how to do that.

Open the page you want to add a WYSIWYG editor to.  Add the following to the top of
the page in the <head></head> of the HTML document.

<script language="Javascript1.2"><!-- // load htmlarea

_editor_url = "";                     // URL to htmlarea files

var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]);

if (navigator.userAgent.indexOf('Mac')        >= 0) { win_ie_ver = 0; }

if (navigator.userAgent.indexOf('Windows CE') >= 0) { win_ie_ver = 0; }

if (navigator.userAgent.indexOf('Opera')      >= 0) { win_ie_ver = 0; }

if (win_ie_ver >= 5.5) {

  document.write('<scr' + 'ipt src="' +_editor_url+ 'editor.js"');

  document.write(' language="Javascript1.2"></scr' + 'ipt>');

} else { document.write('<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>'); }

// --></script>

If you've installed htmlArea anywhere other than /htmlarea/ then be sure to change _editor_url to point to
your htmlarea directory (ending with a forward slash "/").

For each <textarea> that you want to change, add the following code to the page.

<script language="JavaScript1.2" defer>

editor_generate('fieldname');

</script>

Be sure to change "fieldname" to be the name (not id) of the textarea you want to change.

And you're done, open your page in your browser and see if it worked.  If you run into
any problems, keep trying and feel free to visit the
htmlArea forum.

I want to change the editor settings, how do I do that?

While it's true that all you need is one line of JavaScript to create an htmlArea WYSIWYG editor
you can also specify more config settings in the code to control how the editor works and looks.  Here's an
example of some of the available settings:

<script language="JavaScript1.2" defer>

var config = new Object();    // create new config object

config.width = "90%";

config.height = "200px";

config.bodyStyle = 'background-color: white; font-family: "Verdana"; font-size: x-small;';

config.debug = 0;

// Add additional editor config settings here...

editor_generate('fieldname',config);

</script>

See below for even more configuration options that can be added.  All of these settings will use
default values in editor.js if you don't specify them yourself.

Width	specifies the width of the editor (in pixels or as a percentage).

Height	specifies the height of the editor (in pixels or as a percentage).

bodyStyle	specifies CSS style of the editor window including color, default font face, and size.  Note, the default font information isn't saved, it just controls how text is displayed if no other font formatting has been applied.

debug	if set to 1, displays a debug field with the actual contents of the editor (in raw html) which is updated as your type.

How can I change what controls are displayed on the toolbar?

You can add a config.toolbar config setting to control exactly what's shown on the toolbar.
Here's an example.

config.toolbar = [

   ['fontname'],

   ['fontsize'],

   ['fontstyle'],

   ['linebreak'],

   ['bold','italic','underline','separator'],

   ['strikethrough','subscript','superscript','separator'],

   ['justifyleft','justifycenter','justifyright','separator'],

   ['OrderedList','UnOrderedList','Outdent','Indent','separator'],

   ['forecolor','backcolor','separator'],

//['custom1','custom2','custom3','separator'],

   ['HorizontalRule','Createlink','InsertImage','htmlmode','separator'],

   ['about','help']

];

The square brackets control how the buttons are "grouped" together. You can either erase
or comment out (by adding // to the beginning of the line) buttons or button groups you don't
want displayed. Most of the buttons do pretty much just what you'd expect, but here's a few
odd ones for reference.

linebreak	adds a linebreak to the toolbar, all buttons after this are on the next line.

separator	adds a vertical separator between buttons, helps to visually group buttons together

customN	these are custom buttons that can be defined by JavaScript programmers who want to extend htmlArea.

How can I change what fonts are in the font list?

There is a config.fontnames setting that lets you control this.  See below.

config.fontnames = {

   "Arial":           "arial, helvetica, sans-serif",

   "Courier New":     "courier new, courier, mono",

   "Georgia":         "Georgia, Times New Roman, Times, Serif",

   "Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",

   "Times New Roman": "times new roman, times, serif",

   "Verdana":         "Verdana, Arial, Helvetica, sans-serif",

   "impact":          "impact",

   "WingDings":       "WingDings"

};

The name on the left is what is displayed to the user.  The list of fonts on the right is what is
actually put into the font tag in the code.

How can I change what sizes are in the font size?

There is a config.fontsizes setting that lets you control this.  See below.

config.fontsizes = {

   "1 (8 pt)":  "1",

   "2 (10 pt)": "2",

   "3 (12 pt)": "3",

   "4 (14 pt)": "4",

   "5 (18 pt)": "5",

   "6 (24 pt)": "6",

   "7 (36 pt)": "7"

  };

The value on the right is what the user sees, the value on the left is the actual font size used.

How can I change what styles are in the font style (CSS) list?

As you can probably guess, there's a config.fontstyles setting for this. Now remember, the
styles defined here control how the text looks in the editor.  These styles ALSO have to be defined
on any page where you display content created with the editor.  htmlArea will save the class name
with the content but nothing else.  It's up to you to define the class style in your pages.

config.fontstyles = [{

   name: "headline",

   className: "headline",

   classStyle: "font-family: arial; font-size: 28px;"

 },{

   name: "red text",

   className: "saletext2",

   classStyle: ""

}];

The "name" is what's displayed to users, "className" is the name of the CSS class to use, and
classStyle defines the attributes of the style in the editor.  If you leave classStyle blank
you have to be sure to also specify an external stylesheet with all the style information (and
matching classNames!).  See the next question on how to do that.

How can I specify an external stylesheet for my styles?

You can specify a stylesheet to avoid entering the class style data for each class name.
You STILL have to specify which classNames you want to have available though, see the previous
question for information on that.

config.stylesheet = "/style.css";

Frequently Asked Questions back to top

What are the project goals for htmlArea?

When we originally started the htmlArea project we had some pretty specific
goals in mind for how it would work and what issues were important to us.  Those
goals still lead the direction of development today and are listed below in order
of priority.

Compatibility

htmlArea has to always be backwards compatible with older and unsupported browsers.  This
ensures that even if a user with an older and unsupported browser can't use htmlArea, they'll always be able to, at a minimum,
enter text in a plain textarea like they would have done before.

htmlArea should also be compatible with as many programming languages as possible by being
completely DHTML and JavaScript based.

Ease of Use

htmlArea needs to be easy for developers to
integrate into their applications and customize, easy for programmers to extend
and modify, and easy for end users to "use".  That's why you only have to add a
single line of JavaScript for each textarea you want to convert, and why all the
code is stored in a single, easy to follow JavaScript file. That's why htmlArea
can be used with almost any programming language (ASP, PHP, Perl, Java, etc),
and that the toolbar is streamlined, customizable by developers, and follows the
conventions of common word processing programs.

Lightweight

htmlArea needs to be fast loading, allow the user to perform word processing functions at a
reasonable speed, and not put a lot of strain on a user's browser.  To these ends we've
managed to keep the main editor program in a single file of only 40k and we've written the editor
in such a way that it has a minimal impact on the resources of the browser it is running in.
In addition, where we make use of popup windows to perform additional functions we try to put as
much code as possible in the popup window so it doesn't increase the size of the base editor.

This editor is pretty neat, so how does it actually work?

htmlArea is based on the MSHTML Editing Platform
in Internet Explorer 5.5+ on windows.  Basically, Internet Explorer includes some functionality to make sections of a
webpage editable by defining a "contentEditable" attribute or "designMode" property.  It also provides some built in
commands
for performing common web editing operations (bold, italic, center, insert image, etc).

htmlArea builds on the features provided by Internet Explorer and adds its own user definable toolbar,
an easy method to include a WYSIWYG editor in a web page (replacing textareas), an easy way to save user
changes, as well as a number of custom web editing commands of its own.

How htmlArea actually works is it replaces a textarea with an (user definable) toolbar, an iframe that
has the "contentEditable" attribute set to true, and a hidden field with the same name as your original
textarea that gets updated automatically when you modify content in the editor.

The user can enter or modify text as well as use keyboard shortcuts and toolbar buttons to perform operations
on the content.  A lot of the editor commands are built into IE and called via
the execCommand
method, but htmlArea also includes other custom commands and functions written in JavaScript and stored in
the editor.js file or the popup windows (in the /popups/ folder).

You don't happen to have one of these for (Netscape, Mozilla, Opera, Mac IE, etc) do you?

No.  None of these other browsers (including IE for Mac) support "contentEditable" or a way to make
existing content in the page editable.  It might be possible to emulate this in JavaScript, but it would
be a lot of work.  Other problems include displaying or emulating the flashing | bar cursor you see when
editing.  The cross-platform Mozilla browser has some bug entries related to adding contentEditable
functionality, and perhaps in the future it may be possible to create something for that browser.

Although it's a long shot, you might want to send a friendly letter to Microsoft to encourage them to
make the "contentEditable" functionality work on IE for the Macintosh.  Once they implement it, we can offer it.

Why doesn't htmlArea output XHTML instead of regular HTML? Can you make it do that?

The HTML output by htmlArea is generated by the built in functionality of Internet Explorer.
For that reason, there is no easy way to have it output XHTML.  If we were going to do it, the way
to do so would be to parse the HTML after it's output by IE and convert it to XHTML.  That's something
we hope to do at some point.

I'd like to be able to upload images from my hard drive, can you add that feature?

No.  We want htmlArea to be compatible with as many programming languages as possible. Because it's
written in client side JavaScript, it should work with any programming language.  If we start adding
language specific features htmlArea won't be as useful to as many people.  That said, there's a lot of
free "file upload" scripts available, and htmlArea does include a function called editor_insertHTML()\
for inserting text or HTML tags.  If you want to write your own program for doing this it should be
that hard.  Alternatively, you might check in the forum to see if someone already has.

I'd like to <insert idea here>, can you add that feature?

Maybe, maybe not.  If it's a good feature and it fits in with the goals of our project we'll
likely consider it.  The best thing to do is post your suggestions to the
forum.  At the very least
we'll try to give you some suggestions and point you in the right direction.  At best you might
find somebody else has already implemented the feature you were hoping for.

Can I change the toolbar/button colors?

Yes, just search for "buttonface" and "buttonhighlight" in editor.js and change those to whatever colors
you like.  If you haven't heard of those colors before, it's because they're special windows colors
that match whatever color scheme the user has selected for their desktop.  For example, if someone
has changed their desktop color scheme to "lilac", the WYSIWYG editor toolbar and buttons will match that
theme.  Try it, it's really neat.

I love htmlArea, is there anything I can do to help the project?

The number one thing you can do to help is also the easiest thing to do;  give us a link on your website.
The more people who can find out about htmlArea the better it will be.

The next best thing you can do is participate in our
forum and post a message or two to
help other htmlArea users (or learn something new yourself).

Lastly, any code improvements you want to share would certainly be welcome as well.

Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?

This is a bug/feature of Internet Explorer.  htmlArea dynamically updates the content of your page to replace
a textarea with the WYSIWYG editor.  In Internet Explorer, when you update the content of a page after it has loaded
and insert an image it will load the image from the server EVEN if has the image in it's cache.  This means if you have 10
htmlareas on the same page the "bold" toolbar button will be loaded 10 times.

One workaround for this is to move all your editor_generate() scripts to the bottom of the page, combine them
into one script tag, and remove the "defer" attribute from that script tag.  This will cause them all to run just
as the page is finishing loading and the cached images WILL be used.  Meaning, the browser will only need to load each
image once.

Known Bugs and Issues back to top

Undo/Redo doesn't work

We update a hidden field every time you make a change in the editor so the hidden field will be
submitted when you submit the form.  The way undo/redo works in Internet Explorer it seems to reset
the undo buffer every time you use JavaScript to set the value of a form element or otherwise make
changes to the page.  Because of this the built in undo/redo functionality of the browser doesn't
work.  We hope to implement our own undo/redo functionality at a future point.

Relative paths are converted to absolute paths

Internet Explorer has a tendency to convert relative paths into absolute paths.  We've seen some
implementations of WYSIWYG editors that maintain relative paths "better" than others but certain operations
(such as dragging and dropping, etc) still convert relative paths to absolute paths.  We hope to find a
workaround for this in a future version.

HTML header info (eg: <head>, <body>, etc) doesn't get preserved

This is due to Internet Explorer and the way the editor works.  The editor already has a
HTML header of its own so inserting another one confuses the browser and the content gets thrown
away.  The best solution is to have another plain text textarea field for HTML header information.

Some tags (eg: noframes, noscript, etc) doesn't get preserved

This is a result of how Internet Explorer works.  It seems to discard certain tags that it
doesn't need to display.  Because htmlArea reads the content back from the browser it cannot
preserve content the browser has "thrown away".

htmlArea doesn't work with multiple textareas that have the same name

If you have two or more textareas with the same name on the same page and you try
to convert one or more of them into a WYSIWYG editor htmlArea won't work.  This is because htmlArea
looks up the textareas by name in the entire page, not just inside a specific form.  There's currently
no workaround for this.  We hope to resolve it in a future release.

Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?

This is a bug/feature of Internet Explorer.  Even if you get unsecure warnings your form contents should
still be submitted securely.

htmlArea uses an <iframe> to contain the editor and because the contents of the iframe isn't being
loaded off a secure site, Internet Explorer thinks the iframe is unsecure.  The problem is, the iframe doesn't
load anything off any site, it's blank, it doesn't even have a src attribute.  We just create an empty iframe
and then use javascript to update it.  We hope to have this fixed in a future release.

Note: There's a clever workaround for this problem posted in the forum here.
The only issue with it is that can cause the back button to not work as intended (it goes back in the iframe first).

Change Log back to top

Version 2.03 (Released: December 17, 2002)

new license - switched to "BSD style" software license.  The "About this editor" button is no longer required.

readme updates - minor updates, spelling, and grammer fixes.

Version 2.02a (Released: December 5, 2002)

fixed error in readme.html example code under "How do I add htmlArea to my web page?".

Version 2.02 (Released: December 5, 2002)

Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)

fix nested script tag error (thanks to Phil Revill)

New Features

added 'replaceNextlines' config option to replace nextlines with spaces on output

added 'plaintextInput' config option to replace nextlines with <br> tags on input

Version 2.01 (Released: December 3, 2002)

Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)

fixed "function not found" error for non IE5.5+ browsers (thanks to slowhand)

popup editor - fixed javascript error caused during launch of popup (thanks to slowhand and Chlorel)

popup editor - fixed toolbar 'linebreak' error (thanks to fbridge9 and RekiM)

Documentation Updates

Add two new questions to readme.html

 Why do the toolbar buttons take so long to load when I have multiple htmlArea editors on the same page?

Why do I get "non secure items" warnings when using htmlarea on a secure (SSL) https:// page?

Version 2.00 (official release) (Released: November 25, 2002)

New Javascript Functions

editor_getHTML(objname) - return HTML content of editor

editor_setHTML(objname) - set HTML content of editor

editor_appendHTML(objname) - add HTML content to editor

New Features

Popup "fullscreen" editor now has minimize and maximize buttons (switched from ModalDialog to popup window)

Bug Fixes (Thanks to everybody in the forum for contributing and reporting bugs!)

"Create Table" popup now creates tables with the correct number of cols and rows (thanks to Corey)

Clicking on images no longer causes error when you have "CSS style pulldown" enabled (thanks to Virrdo)

Fixed bug that prevented external stylesheets from working properly (thanks to slowhand)

fixed javascript errors in Mozilla 1.0 (thanks to slowhand)

moved browser detection code to editor page to prevent javascript errors from older browsers and prevent the editor from being loaded unless it's needed.

submitting empty htmlarea now submits nothing "" instead of "<p>&nbsp;</p>"

Popup "fullscreen" editor no longer generates error on "<>" html mode change

Version 2.00 (beta2) (Released: October 16, 2002)

New Docs

created new readme.html with install instructions, faq, and lots of information

New Features

added support for stylesheets

get enlarge/shrink window working

get context menu working (still disabled by default, needs more code for functionality)

allow user to change ANY option in internal config from calling page

added _editor_filterOutput function that's called on form submit

added insert table button

Bug Fixes / Optimizations

organized associated files into directories

fixed bug that caused htmlarea to sometimes not display last entered content when user pressed back in their browser.

moved about window into a separate file to reduce size of editor

Version 2.00 (beta1) (Released: August 19, 2002)

visual changes

added mouseover/mouseoff events and style for toolbar ui buttons

update toolbar to take up less space and be smaller

display point sizes beside HTML font sizes (eg: 7 (36px)

change "about this editor" icon to an "i"

created a help popup (content still needs to be written).

added version number to about page.

code changes

added "defer" to script tag to prevent editor from being created until page loads

simplified header that needs to be added to pages that contain editor

generated script include tag using _editor_url so users don't have to enter URL twice

moved CSS for editor toolbar buttons into editor.js

switched to using object to pass configuration arguments to editor_generate

general code improvements, optimizations and re-organization

added hooks for keypress events for future use

new features

added pulldown for CSS style classnames

added many many more config options including:

ability to select which toolbar elements you want displayed

ability to specify the order of toolbar elements

ability to specify fonts, sizes, and CSS styles for pulldowns

ability to set default font and style used in editor window

debug flag that lets you see the source of the WYSIWYG field at all times

add more sample code and comments showing how to add custom buttons

bug fixes

fixed error caused when height/width were manually specified (reported by jpeto, thanks!)

"about this editor" window now works when in textedit mode

Version 1.05 (Released: August 28, 2002)

- Added support for textareas with underscores ("_") in their names.

Version 1.04 (Released: August 27, 2002)

Even more speed improvements (WYSIWYG editor is now much faster on older computers).

General code improvements and optimizations.

Version 1.03 (Released: August 26, 2002)

Beta release only

Version 1.02 (Released: August 21, 2002)

added editor_insertHTML() function. Developers can now easily add buttons that insert HTML or surround selected text with HTML.

removed unneeded debug code and comments to reduce editor.js file size (and load time).

Version 1.01 (Released: August 20, 2002)

optimized code to improve speed (WYSIWYG editor is now much faster)

added addition event handlers to update UI on mouse events.

Version 1.00 (Released: August 19, 2002)

Initial Release


text:
package core.userDefinedTask.manualBuild.steps;

import argo.jdom.JsonNode;
import core.controller.Core;
import core.userDefinedTask.manualBuild.ManuallyBuildStep;
import utilities.KeyEventCodeToString;

public class KeyboardReleaseKeyStep extends ManuallyBuildStep {

	private int key;

	public static KeyboardReleaseKeyStep of(int key) {
		KeyboardReleaseKeyStep result = new KeyboardReleaseKeyStep();
		result.key = key;
		return result;
	}

	@Override
	public void execute(Core controller) throws InterruptedException {
		controller.keyBoard().press(key);
	}

	@Override
	public String getDisplayString() {
		return String.format("release key %s", KeyEventCodeToString.codeToString(key).toUpperCase());
	}

	public static KeyboardReleaseKeyStep parseJSON(JsonNode node) {
		KeyboardReleaseKeyStep result = new KeyboardReleaseKeyStep();
		result.parse(node);
		return result;
	}

	@Override
	public String getJsonSignature() {
		return "keyboard_release_key";
	}
}


text:
'use strict';

////Click event on choice
///Displays next story element
///Each story element is an object with the string, constructed from local storage, and choices
///First checks if local storage has constructed story strings in it: localStorage.?
///If there is no user information, send to user creation page
///If there is local storage, display the first page object in the array and choices at end
///Click event which option was chosen. logs that in final scenario object

///Where story objects will go
var storyObjects;
var storyPage = document.getElementById('story-text');
var userChoices = document.getElementById('user-choices');
var storyChoices = [];
var storyIndex = 0;
var userScore = 0;

var choiceOneEl = document.getElementsByName('choiceOne')[0];
var choiceTwoEl = document.getElementsByName('choiceTwo')[0];

var pEl = document.createElement('p');
pEl.setAttribute('class', 'story-text');

///gets what is in local storage and puts it in the story objects
function convertStory(){
  ///change name based on what Kyle decides will be the name of local storage
  if(localStorage.storyArray){
    ////parse into array of story objects with empty one for final scenario
    var storyObjectsString = localStorage.storyArray;
    storyObjects = JSON.parse(storyObjectsString);
    console.log('Conversion happened');
  }else {
    ///Take back to character creation page
    alert('Please create a character for the story');
    window.location.assign('creation.html');
  }
}

function displayTitle(){
  var character = JSON.parse(localStorage.user);
  character = character.characterName;
  document.getElementById('story-title').textContent = character + '\'s Wish';
  console.log(localStorage.user);
}

///shows option and choices
function displayStory(index){
  ///Get story string and display to story section
  pEl.innerHTML = storyObjects[index].story;
  storyPage.appendChild(pEl);

  ///get options and display to div
  var inputChoiceOne = document.getElementsByName('choiceOne')[0];
  var inputChoiceOneLabel = document.getElementById('choice-one');
  var inputChoiceTwo = document.getElementsByName('choiceTwo')[0];
  var inputChoiceTwoLabel = document.getElementById('choice-two');

  // console.log(inputChoiceOne);

  inputChoiceOne.value = storyObjects[index].choiceOne;
  inputChoiceTwo.value = storyObjects[index].choiceTwo;
  inputChoiceOneLabel.textContent = storyObjects[index].choiceOne;
  inputChoiceTwoLabel.textContent = storyObjects[index].choiceTwo;
}

choiceOneEl.addEventListener('click', choiceSelection);
choiceTwoEl.addEventListener('click', choiceSelection);

function choiceSelection (event){
  ////Selecting choice logs choice to final scenario
  storyChoices.push(event.target.name);
  console.log(storyChoices);
  console.log(event.target.name);
  ///Increments scenario by 1
  storyIndex += 1;
  if(storyIndex < storyObjects.length) {
    displayStory(storyIndex);
    ///Uncheck all checkboxes
    choiceOneEl.checked = false;
    choiceTwoEl.checked = false;
  } else {
    for(var i = 0; i < storyChoices.length; i++) {
      if(storyChoices[i] === 'choiceOne') {
        userScore += 2;
      } else {
        userScore += 1;
      }
    }
    finalStory(storyChoices);
    var bodyEl = document.getElementsByTagName('body')[0];
    bodyEl.removeChild(userChoices);
    pEl.setAttribute('class', 'story-ending');
    ///go to finalScenario
  }
}

///sets properties of final scenario
function finalStory(choices){
  if(userScore === 6) {
    pEl.innerHTML = localStorage.badEnd;
  } else if(userScore === 3) {
    pEl.innerHTML = localStorage.goodEnd;
  } else {
    pEl.innerHTML = localStorage.neutEnd;
  }
  console.log(userScore);
  console.log('Final Story is reached');
}

convertStory();
displayTitle();
displayStory(0);


text:
using System.Collections;

namespace Meteor.Internal
{
	internal class UpdatedMessage : Message
	{
		[JsonFx.Json.JsonIgnore]
		public const string updated = "updated";

		public string[] methods = null;
		public UpdatedMessage ()
		{
			msg = updated;
		}
	}
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//JP">

<TITLE>Synchronization</TITLE>
<META NAME="description" CONTENT="Synchronization">
<META NAME="keywords" CONTENT="manual">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">

<META NAME="Generator" CONTENT="LaTeX2HTML v2008">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">

<LINK REL="STYLESHEET" HREF="manual.css">

<LINK REL="previous" HREF="manual-node111.html">
<LINK REL="up" HREF="manual-node98.html">
<LINK REL="next" HREF="manual-node113.html">

 Next: Geometric Functions
 Up: Multithread
 Previous: Thread creation
     Contents
     Index

Synchronization

Among Solaris operating systems four synchronization primitives for
multithread programs, EusLisp provides mutex locks, conditional variables,
and semaphores. Reader-writer lock is not available now.

Based on these primitives, higher level synchronization mechanisms,
such as synchronized memory port and barrier synchronization, are realized.

sys:make-mutex-lock [function]

makes a mutex-lock and returns it. A mutex-lock is represented by an
integer-vector of six elements.

sys:mutex-lock mlock [function]

locks the mutex lock mlock.
If the mlock is already locked by another thread,
mutex-lock waits for the lock to be released.

sys:mutex-unlock mlock [function]

releases mlock and let one of other threads waiting for this
lock resume running.

sys:mutex mlock &rest forms [macro]

Mutex-lock and mutex-unlock have to be used as a pair.
Mutex is a macro that brackets a critical section.
Mlock is locked
before evaluating forms are evaluated,
and the lock is released when the evaluation finishes.
This macro expands to the following progn form.
Note that unwind-protect is used to ensure unlocking
even an error occurs during the evaluation of forms.

  (progn
      (sys:mutex-lock mlock)
      (unwind-protect
          (progn . forms)
          (sys:mutex-unlock mlock)))

sys:make-cond [function]

 makes a condition variable object
which is an integer vector of four elements.
The returned condition variable is in unlocked state.

sys:cond-wait condvar mlock [function]

waits for condvar to be signaled.
If condvar has already been acquired by another thread,
it releases mlock and waits for condvar to be signaled.

sys:cond-signal condvar [function]

 signals the condvar condition variable.

sys:make-semaphore [function]

 makes a semaphore object
which is represented by an integer vector of twelve elements.

sys:sema-post sem [function]

  signals sem.

sys:sema-wait sem [function]

 waits for the sem semaphore to be posted.

<BIG CLASS="XLARGE">sys:barrier-synch </BIG> [class]
<TT>
  :super   propertied-object

  :slots 		 threads n-threads count barrier-cond threads-lock count-lock
</TT>

represents a structure for barrier-synchronization. Threads waiting
for the synchronization are put in threads which is mutually excluded
by threads-lock.
When a barrier-synch object is created,
count is initialized to zero.
Synchronizing threads are put in the threads list by sending <TT>:add</TT>
message.
Sending <TT>:wait</TT> to this barrier-sync object causes count to be
incremented, and the sending thread is put in the wait state.
When all the threads in threads send the <TT>:wait</TT> message,
the waits are unblocked and all threads resume execution.
The synchronization is implemented by the combination of
the count-lock mutex-lock and the barrier-cond
condition-variable.

:init [method]

 initializes this barrier-synch object. Two mutex-lock
and one condition-variable are created.

:add thr [method]

 adds the thr thread in the threads list.

:remove thr [method]

 removes the thr thread of the threads list.

:wait [method]

 waits for all threads in the threads list
to issue <TT>:wait</TT>.

<BIG CLASS="XLARGE">sys:synch-memory-port </BIG> [class]
<TT>
  :super   propertied-object

  :slots 		 sema-in sema-out buf empty lock
</TT>

realizes the one-directional synchronized memory port,
which synchronizes for two threads
to transfer datum via this object.
Control transfer is implemented by using semaphores.

:read [method]

 reads datum buffered in this synch-memory-port.
If it has not been written yet, the :read blocks.

:write datum [method]

 writes datum in the buffer.
Since only one word of buffer is available,
if another datum has already been written and not yet read out,
:write waits for the datum to be transferred by :read.

:init [method]

 initializes this synch-memory-port
where two semaphores  are created and :write is made acceptable.

 Next: Geometric Functions
 Up: Multithread
 Previous: Thread creation
     Contents
     Index

<ADDRESS>

2015-06-19
</ADDRESS>


text:
require 'spec_helper'

describe Term do
  pending "add some examples to (or delete) #{__FILE__}"
end


text:
package com.jme3.bullet.collision;

import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import java.util.EventObject;

/**
 * A CollisionEvent stores all information about a collision in the PhysicsWorld.
 * Do not store this Object, as it will be reused after the collision() method has been called.
 * Get/reference all data you need in the collide method.
 * @author normenhansen
 */
public class PhysicsCollisionEvent extends EventObject {

    public static final int TYPE_ADDED = 0;
    public static final int TYPE_PROCESSED = 1;
    public static final int TYPE_DESTROYED = 2;
    private int type;
    private PhysicsCollisionObject nodeA;
    private PhysicsCollisionObject nodeB;
    private long manifoldPointObjectId = 0;

    public PhysicsCollisionEvent(int type, PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB, long manifoldPointObjectId) {
        super(nodeA);
        this.type = type;
        this.nodeA = nodeA;
        this.nodeB = nodeB;
        this.manifoldPointObjectId = manifoldPointObjectId;
    }

    /**
     * used by event factory, called when event is destroyed
     */
    public void clean() {
        source = null;
        this.type = 0;
        this.nodeA = null;
        this.nodeB = null;
        this.manifoldPointObjectId = 0;
    }

    /**
     * used by event factory, called when event reused
     */
    public void refactor(int type, PhysicsCollisionObject source, PhysicsCollisionObject nodeB, long manifoldPointObjectId) {
        this.source = source;
        this.type = type;
        this.nodeA = source;
        this.nodeB = nodeB;
        this.manifoldPointObjectId = manifoldPointObjectId;
    }

    public int getType() {
        return type;
    }

    /**
     * @return A Spatial if the UserObject of the PhysicsCollisionObject is a Spatial
     */
    public Spatial getNodeA() {
        if (nodeA.getUserObject() instanceof Spatial) {
            return (Spatial) nodeA.getUserObject();
        }
        return null;
    }

    /**
     * @return A Spatial if the UserObject of the PhysicsCollisionObject is a Spatial
     */
    public Spatial getNodeB() {
        if (nodeB.getUserObject() instanceof Spatial) {
            return (Spatial) nodeB.getUserObject();
        }
        return null;
    }

    public PhysicsCollisionObject getObjectA() {
        return nodeA;
    }

    public PhysicsCollisionObject getObjectB() {
        return nodeB;
    }

    public float getAppliedImpulse() {
        return getAppliedImpulse(manifoldPointObjectId);
    }
    private native float getAppliedImpulse(long manifoldPointObjectId);

    public float getAppliedImpulseLateral1() {
        return getAppliedImpulseLateral1(manifoldPointObjectId);
    }
    private native float getAppliedImpulseLateral1(long manifoldPointObjectId);

    public float getAppliedImpulseLateral2() {
        return getAppliedImpulseLateral2(manifoldPointObjectId);
    }
    private native float getAppliedImpulseLateral2(long manifoldPointObjectId);

    public float getCombinedFriction() {
        return getCombinedFriction(manifoldPointObjectId);
    }
    private native float getCombinedFriction(long manifoldPointObjectId);

    public float getCombinedRestitution() {
        return getCombinedRestitution(manifoldPointObjectId);
    }
    private native float getCombinedRestitution(long manifoldPointObjectId);

    public float getDistance1() {
        return getDistance1(manifoldPointObjectId);
    }
    private native float getDistance1(long manifoldPointObjectId);

    public int getIndex0() {
        return getIndex0(manifoldPointObjectId);
    }
    private native int getIndex0(long manifoldPointObjectId);

    public int getIndex1() {
        return getIndex1(manifoldPointObjectId);
    }
    private native int getIndex1(long manifoldPointObjectId);

    public Vector3f getLateralFrictionDir1() {
        return getLateralFrictionDir1(new Vector3f());
    }

    public Vector3f getLateralFrictionDir1(Vector3f lateralFrictionDir1) {
        getLateralFrictionDir1(manifoldPointObjectId, lateralFrictionDir1);
        return lateralFrictionDir1;
    }
    private native void getLateralFrictionDir1(long manifoldPointObjectId, Vector3f lateralFrictionDir1);

    public Vector3f getLateralFrictionDir2() {
        return getLateralFrictionDir2(new Vector3f());
    }

    public Vector3f getLateralFrictionDir2(Vector3f lateralFrictionDir2) {
        getLateralFrictionDir2(manifoldPointObjectId, lateralFrictionDir2);
        return lateralFrictionDir2;
    }
    private native void getLateralFrictionDir2(long manifoldPointObjectId, Vector3f lateralFrictionDir2);

    public boolean isLateralFrictionInitialized() {
        return isLateralFrictionInitialized(manifoldPointObjectId);
    }
    private native boolean isLateralFrictionInitialized(long manifoldPointObjectId);

    public int getLifeTime() {
        return getLifeTime(manifoldPointObjectId);
    }
    private native int getLifeTime(long manifoldPointObjectId);

    public Vector3f getLocalPointA() {
        return getLocalPointA(new Vector3f());
    }

    public Vector3f getLocalPointA(Vector3f localPointA) {
        getLocalPointA(manifoldPointObjectId, localPointA);
        return localPointA;
    }
    private native void getLocalPointA(long manifoldPointObjectId, Vector3f localPointA);

    public Vector3f getLocalPointB() {
        return getLocalPointB(new Vector3f());
    }

    public Vector3f getLocalPointB(Vector3f localPointB) {
        getLocalPointB(manifoldPointObjectId, localPointB);
        return localPointB;
    }
    private native void getLocalPointB(long manifoldPointObjectId, Vector3f localPointB);

    public Vector3f getNormalWorldOnB() {
        return getNormalWorldOnB(new Vector3f());
    }

    public Vector3f getNormalWorldOnB(Vector3f normalWorldOnB) {
        getNormalWorldOnB(manifoldPointObjectId, normalWorldOnB);
        return normalWorldOnB;
    }
    private native void getNormalWorldOnB(long manifoldPointObjectId, Vector3f normalWorldOnB);

    public int getPartId0() {
        return getPartId0(manifoldPointObjectId);
    }
    private native int getPartId0(long manifoldPointObjectId);

    public int getPartId1() {
        return getPartId1(manifoldPointObjectId);
    }

    private native int getPartId1(long manifoldPointObjectId);

    public Vector3f getPositionWorldOnA() {
        return getPositionWorldOnA(new Vector3f());
    }

    public Vector3f getPositionWorldOnA(Vector3f positionWorldOnA) {
        getPositionWorldOnA(manifoldPointObjectId, positionWorldOnA);
        return positionWorldOnA;
    }
    private native void getPositionWorldOnA(long manifoldPointObjectId, Vector3f positionWorldOnA);

    public Vector3f getPositionWorldOnB() {
        return getPositionWorldOnB(new Vector3f());
    }

    public Vector3f getPositionWorldOnB(Vector3f positionWorldOnB) {
        getPositionWorldOnB(manifoldPointObjectId, positionWorldOnB);
        return positionWorldOnB;
    }
    private native void getPositionWorldOnB(long manifoldPointObjectId, Vector3f positionWorldOnB);

//    public Object getUserPersistentData() {
//        return userPersistentData;
//    }
}


text:
<?php

namespace Google\AdsApi\AdManager\v202205;

/**
 * This file was generated from WSDL. DO NOT EDIT.
 */
class ActivateCdnConfigurations extends \Google\AdsApi\AdManager\v202205\CdnConfigurationAction
{

    public function __construct()
    {

    }

}


text:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Windows.Storage;
using Windows.UI.Xaml;
using XamlCSS.CssParsing;

namespace XamlCSS.UWP.CssParsing
{
    public class CssFileProvider : CssFileProviderBase
    {
        private readonly CssTypeHelper<DependencyObject, DependencyProperty, Style> cssTypeHelper;

        public CssFileProvider(CssTypeHelper<DependencyObject, DependencyProperty, Style> cssTypeHelper)
            : base(new[] { Application.Current.GetType().GetTypeInfo().Assembly })
        {
            this.cssTypeHelper = cssTypeHelper;
        }

        public CssFileProvider(IEnumerable<Assembly> assemblies,
            CssTypeHelper<DependencyObject, DependencyProperty, Style> typeHelper)
            : this(typeHelper)
        {
            this.assemblies = assemblies.ToArray();
        }

        protected override Stream TryGetFromFile(string source)
        {
            StorageFolder storageFolder = ApplicationData.Current.LocalFolder;

            var absolutePath = source;
            if (!Path.IsPathRooted(absolutePath))
            {
                absolutePath = Path.Combine(storageFolder.Path, absolutePath);
            }

            if (File.Exists(absolutePath))
            {
                try
                {
                    return File.OpenRead(absolutePath);
                }
                catch { }
            }

            return null;
        }

        protected override Stream TryLoadFromStaticApplicationResource(string source)
        {
            string stringValue = null;
            object value = null;

            Application.Current.Resources?.TryGetValue(source, out value);

            if (value is StyleSheet)
            {
                stringValue = (value as StyleSheet).Content;
            }
            else if (value is string)
            {
                stringValue = (string)value;
            }

            if (stringValue != null)
            {
                return new MemoryStream(Encoding.UTF8.GetBytes(stringValue));
            }

            return null;
        }
    }
}


text:
#pragma once

#include "lib/core/CHIPError.h"
#include "system/SystemPacketBuffer.h"
#include "system/TLVPacketBufferBackingStore.h"
#include <app/AttributePathParams.h>
#include <app/BufferedReadCallback.h>
#include <app/ReadClient.h>
#include <app/data-model/DecodableList.h>
#include <app/data-model/Decode.h>
#include <lib/support/Variant.h>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <vector>

namespace chip {
namespace app {
/*
 * This implements a cluster state cache designed to aggregate both attribute and event data received by a client
 * from either read or subscribe interactions and keep it resident and available for clients to
 * query at any time while the cache is active.
 *
 * The cache can be used with either read/subscribe, with the consumer connecting it up appropriately
 * to the right ReadClient instance.
 *
 * The cache provides an up-to-date and consistent view of the state of a target node, with the scope of the
 * state being determined by the associated ReadClient's path set.
 *
 * The cache provides a number of getters and helper functions to iterate over the topology
 * of the received data which is organized by endpoint, cluster and attribute ID (for attributes). These permit greater
 * flexibility when dealing with interactions that use wildcards heavily.
 *
 * For events, functions that permit iteration over the cached events sorted by event number are provided.
 *
 * The data is stored internally in the cache as TLV. This permits re-use of the existing cluster objects
 * to de-serialize the state on-demand.
 *
 * The cache serves as a callback adapter as well in that it 'forwards' the ReadClient::Callback calls transparently
 * through to a registered callback. In addition, it provides its own enhancements to the base ReadClient::Callback
 * to make it easier to know what has changed in the cache.
 *
 * **NOTE**
 * 1. This already includes the BufferedReadCallback, so there is no need to add that to the ReadClient callback chain.
 * 2. The same cache cannot be used by multiple subscribe/read interactions at the same time.
 *
 */
class ClusterStateCache : protected ReadClient::Callback
{
public:
    class Callback : public ReadClient::Callback
    {
    public:
        /*
         * Called anytime an attribute value has changed in the cache
         */
        virtual void OnAttributeChanged(ClusterStateCache * cache, const ConcreteAttributePath & path){};

        /*
         * Called anytime any attribute in a cluster has changed in the cache
         */
        virtual void OnClusterChanged(ClusterStateCache * cache, EndpointId endpointId, ClusterId clusterId){};

        /*
         * Called anytime an endpoint was added to the cache
         */
        virtual void OnEndpointAdded(ClusterStateCache * cache, EndpointId endpointId){};
    };

    ClusterStateCache(Callback & callback, Optional<EventNumber> highestReceivedEventNumber = Optional<EventNumber>::Missing()) :
        mCallback(callback), mBufferedReader(*this)
    {
        mHighestReceivedEventNumber = highestReceivedEventNumber;
    }

    void SetHighestReceivedEventNumber(EventNumber highestReceivedEventNumber)
    {
        mHighestReceivedEventNumber.SetValue(highestReceivedEventNumber);
    }

    /*
     * When registering as a callback to the ReadClient, the ClusterStateCache cannot not be passed as a callback
     * directly. Instead, utilize this method below to correctly set up the callback chain such that
     * the buffered reader is the first callback in the chain before calling into cache subsequently.
     */
    ReadClient::Callback & GetBufferedCallback() { return mBufferedReader; }

    /*
     * Retrieve the value of an attribute from the cache (if present) given a concrete path by decoding
     * it using DataModel::Decode into the in-out argument 'value'.
     *
     * For some types of attributes, the value for the attribute is directly backed by the underlying TLV buffer
     * and has pointers into that buffer. (e.g octet strings, char strings and lists).  This buffer only remains
     * valid until the cached value for that path is updated, so it must not be held
     * across any async call boundaries.
     *
     * The template parameter AttributeObjectTypeT is generally expected to be a
     * ClusterName::Attributes::AttributeName::DecodableType, but any
     * object that can be decoded using the DataModel::Decode machinery will work.
     *
     * Notable return values:
     *      - If the provided attribute object's Cluster and Attribute IDs don't match that of the provided path,
     *        a CHIP_ERROR_SCHEMA_MISMATCH shall be returned.
     *
     *      - If neither data or status for the specified path don't exist in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     *
     *      - If a StatusIB is present in the cache instead of data, a CHIP_ERROR_IM_STATUS_CODE_RECEIVED error
     *        shall be returned from this call instead. The actual StatusIB can be retrieved using the GetStatus() API below.
     *
     */
    template <typename AttributeObjectTypeT>
    CHIP_ERROR Get(const ConcreteAttributePath & path, typename AttributeObjectTypeT::DecodableType & value) const
    {
        TLV::TLVReader reader;

        if (path.mClusterId != AttributeObjectTypeT::GetClusterId() || path.mAttributeId != AttributeObjectTypeT::GetAttributeId())
        {
            return CHIP_ERROR_SCHEMA_MISMATCH;
        }

        ReturnErrorOnFailure(Get(path, reader));
        return DataModel::Decode(reader, value);
    }

    /*
     * Retrieve the StatusIB for a given attribute if one exists currently in the cache.
     *
     * Notable return values:
     *      - If neither data or status for the specified path don't exist in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     *
     *      - If data exists in the cache instead of status, CHIP_ERROR_INVALID_ARGUMENT shall be returned.
     *
     */
    CHIP_ERROR GetStatus(const ConcreteAttributePath & path, StatusIB & status) const;

    /*
     * Encapsulates a StatusIB and a ConcreteAttributePath pair.
     */
    struct AttributeStatus
    {
        AttributeStatus(const ConcreteAttributePath & path, StatusIB & status) : mPath(path), mStatus(status) {}
        ConcreteAttributePath mPath;
        StatusIB mStatus;
    };

    /*
     * Retrieve the value of an entire cluster instance from the cache (if present) given a path
     * and decode it using DataModel::Decode into the in-out argument 'value'. If any StatusIBs
     * are present in the cache instead of data, they will be provided in the statusList argument.
     *
     * For some types of attributes, the value for the attribute is directly backed by the underlying TLV buffer
     * and has pointers into that buffer. (e.g octet strings, char strings and lists).  This buffer only remains
     * valid until the cached value for that path is updated, so it must not be held
     * across any async call boundaries.
     *
     * The template parameter ClusterObjectT is generally expected to be a
     * ClusterName::Attributes::DecodableType, but any
     * object that can be decoded using the DataModel::Decode machinery will work.
     *
     * Notable return values:
     *      - If neither data or status for the specified path exist in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     *
     */
    template <typename ClusterObjectTypeT>
    CHIP_ERROR Get(EndpointId endpointId, ClusterId clusterId, ClusterObjectTypeT & value,
                   std::list<AttributeStatus> & statusList) const
    {
        statusList.clear();

        return ForEachAttribute(endpointId, clusterId, [&value, this, &statusList](const ConcreteAttributePath & path) {
            TLV::TLVReader reader;
            CHIP_ERROR err;

            err = Get(path, reader);
            if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED)
            {
                StatusIB status;
                ReturnErrorOnFailure(GetStatus(path, status));
                statusList.push_back(AttributeStatus(path, status));
                err = CHIP_NO_ERROR;
            }
            else if (err == CHIP_NO_ERROR)
            {
                ReturnErrorOnFailure(DataModel::Decode(reader, path, value));
            }
            else
            {
                return err;
            }

            return CHIP_NO_ERROR;
        });
    }

    /*
     * Retrieve the value of an attribute by updating a in-out TLVReader to be positioned
     * right at the attribute value.
     *
     * The underlying TLV buffer only remains valid until the cached value for that path is updated, so it must
     * not be held across any async call boundaries.
     *
     * Notable return values:
     *      - If neither data nor status for the specified path exist in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     *
     *      - If a StatusIB is present in the cache instead of data, a CHIP_ERROR_IM_STATUS_CODE_RECEIVED error
     *        shall be returned from this call instead. The actual StatusIB can be retrieved using the GetStatus() API above.
     *
     */
    CHIP_ERROR Get(const ConcreteAttributePath & path, TLV::TLVReader & reader) const;

    /*
     * Retrieve the data version for the given cluster.  If there is no data for the specified path in the cache,
     * CHIP_ERROR_KEY_NOT_FOUND shall be returned.  Otherwise aVersion will be set to the
     * current data version for the cluster (which may have no value if we don't have a known data version
     * for it, for example because none of our paths were wildcards that covered the whole cluster).
     */
    CHIP_ERROR GetVersion(const ConcreteClusterPath & path, Optional<DataVersion> & aVersion) const;

    /*
     * Get highest received event number.
     */
    virtual CHIP_ERROR GetHighestReceivedEventNumber(Optional<EventNumber> & aEventNumber) final
    {
        aEventNumber = mHighestReceivedEventNumber;
        return CHIP_NO_ERROR;
    }

    /*
     * Retrieve the value of an event from the cache given an EventNumber by decoding
     * it using DataModel::Decode into the in-out argument 'value'.
     *
     * This should be used in conjunction with the ForEachEvent() iterator function to
     * retrieve the EventHeader (and corresponding metadata information for the event) along with its EventNumber.
     *
     * For some types of events, the values for the fields in the event are directly backed by the underlying TLV buffer
     * and have pointers into that buffer. (e.g octet strings, char strings and lists). Unlike its attribute counterpart,
     * these pointers are stable and will not change until a call to `ClearEventCache` happens.
     *
     * The template parameter EventObjectTypeT is generally expected to be a
     * ClusterName::Events::EventName::DecodableType, but any
     * object that can be decoded using the DataModel::Decode machinery will work.
     *
     * Notable return values:
     *      - If the provided event object's Cluster and Event IDs don't match those of the event in the cache,
     *        a CHIP_ERROR_SCHEMA_MISMATCH shall be returned.
     *
     *      - If event doesn't exist in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     */

    template <typename EventObjectTypeT>
    CHIP_ERROR Get(EventNumber eventNumber, EventObjectTypeT & value) const
    {
        TLV::TLVReader reader;
        CHIP_ERROR err;

        auto * eventData = GetEventData(eventNumber, err);
        ReturnErrorOnFailure(err);

        if (eventData->first.mPath.mClusterId != value.GetClusterId() || eventData->first.mPath.mEventId != value.GetEventId())
        {
            return CHIP_ERROR_SCHEMA_MISMATCH;
        }

        ReturnErrorOnFailure(Get(eventNumber, reader));
        return DataModel::Decode(reader, value);
    }

    /*
     * Retrieve the data of an event by updating a in-out TLVReader to be positioned
     * right at the structure that encapsulates the event payload.
     *
     * Notable return values:
     *      - If no event with a matching eventNumber exists in the cache, CHIP_ERROR_KEY_NOT_FOUND
     *        shall be returned.
     *
     */
    CHIP_ERROR Get(EventNumber eventNumber, TLV::TLVReader & reader) const;

    /*
     * Retrieve the StatusIB for a specific event from the event status cache (if one exists).
     * Otherwise, a CHIP_ERROR_KEY_NOT_FOUND error will be returned.
     *
     * This is to be used with the `ForEachEventStatus` iterator function.
     *
     * NOTE: Receipt of a StatusIB does not affect any pre-existing or future event data entries in the cache (and vice-versa).
     *
     */
    CHIP_ERROR GetStatus(const ConcreteEventPath & path, StatusIB & status) const;

    /*
     * Execute an iterator function that is called for every attribute
     * in a given endpoint and cluster. The function when invoked is provided a concrete attribute path
     * to every attribute that matches in the cache.
     *
     * The iterator is expected to have this signature:
     *      CHIP_ERROR IteratorFunc(const ConcreteAttributePath &path);
     *
     * Notable return values:
     *      - If a cluster instance corresponding to endpointId and clusterId doesn't exist in the cache,
     *        CHIP_ERROR_KEY_NOT_FOUND shall be returned.
     *
     *      - If func returns an error, that will result in termination of any further iteration over attributes
     *        and that error shall be returned back up to the original call to this function.
     *
     */
    template <typename IteratorFunc>
    CHIP_ERROR ForEachAttribute(EndpointId endpointId, ClusterId clusterId, IteratorFunc func) const
    {
        CHIP_ERROR err;

        auto clusterState = GetClusterState(endpointId, clusterId, err);
        ReturnErrorOnFailure(err);

        for (auto & attributeIter : clusterState->mAttributes)
        {
            const ConcreteAttributePath path(endpointId, clusterId, attributeIter.first);
            ReturnErrorOnFailure(func(path));
        }

        return CHIP_NO_ERROR;
    }

    /*
     * Execute an iterator function that is called for every attribute
     * for a given cluster across all endpoints in the cache. The function is passed a
     * concrete attribute path to every attribute that matches in the cache.
     *
     * The iterator is expected to have this signature:
     *      CHIP_ERROR IteratorFunc(const ConcreteAttributePath &path);
     *
     * Notable return values:
     *      - If func returns an error, that will result in termination of any further iteration over attributes
     *        and that error shall be returned back up to the original call to this function.
     *
     */
    template <typename IteratorFunc>
    CHIP_ERROR ForEachAttribute(ClusterId clusterId, IteratorFunc func) const
    {
        for (auto & endpointIter : mCache)
        {
            for (auto & clusterIter : endpointIter.second)
            {
                if (clusterIter.first == clusterId)
                {
                    for (auto & attributeIter : clusterIter.second.mAttributes)
                    {
                        const ConcreteAttributePath path(endpointIter.first, clusterId, attributeIter.first);
                        ReturnErrorOnFailure(func(path));
                    }
                }
            }
        }
        return CHIP_NO_ERROR;
    }

    /*
     * Execute an iterator function that is called for every cluster
     * in a given endpoint and passed a ClusterId for every cluster that
     * matches.
     *
     * The iterator is expected to have this signature:
     *      CHIP_ERROR IteratorFunc(ClusterId clusterId);
     *
     * Notable return values:
     *      - If func returns an error, that will result in termination of any further iteration over attributes
     *        and that error shall be returned back up to the original call to this function.
     *
     */
    template <typename IteratorFunc>
    CHIP_ERROR ForEachCluster(EndpointId endpointId, IteratorFunc func) const
    {
        auto endpointIter = mCache.find(endpointId);
        if (endpointIter->first == endpointId)
        {
            for (auto & clusterIter : endpointIter->second)
            {
                ReturnErrorOnFailure(func(clusterIter.first));
            }
        }
        return CHIP_NO_ERROR;
    }

    /*
     * Execute an iterator function that is called for every event in the event data cache that satisfies the following
     * conditions:
     *      - It matches the provided path filter
     *      - Its event number is greater than or equal to the provided minimum event number filter.
     *
     * Each filter argument can be omitted from the match criteria above by passing in an empty EventPathParams() and/or
     * a minimum event filter of 0.
     *
     * This iterator is called in increasing order from the event with the lowest event number to the highest.
     *
     * The function is passed a const reference to the EventHeader associated with that event.
     *
     * The iterator is expected to have this signature:
     *      CHIP_ERROR IteratorFunc(const EventHeader & eventHeader);
     *
     * Notable return values:
     *      - If func returns an error, that will result in termination of any further iteration over events
     *        and that error shall be returned back up to the original call to this function.
     *
     */
    template <typename IteratorFunc>
    CHIP_ERROR ForEachEventData(IteratorFunc func, EventPathParams pathFilter = EventPathParams(),
                                EventNumber minEventNumberFilter = 0) const
    {
        for (const auto & item : mEventDataCache)
        {
            if (pathFilter.IsEventPathSupersetOf(item.first.mPath) && item.first.mEventNumber >= minEventNumberFilter)
            {
                ReturnErrorOnFailure(func(item.first));
            }
        }

        return CHIP_NO_ERROR;
    }

    /*
     * Execute an iterator function that is called for every StatusIB in the event status cache.
     *
     * The iterator is expected to have this signature:
     *      CHIP_ERROR IteratorFunc(const ConcreteEventPath & eventPath, const StatusIB & statusIB);
     *
     * Notable return values:
     *      - If func returns an error, that will result in termination of any further iteration over events
     *        and that error shall be returned back up to the original call to this function.
     *
     * NOTE: Receipt of a StatusIB does not affect any pre-existing event data entries in the cache (and vice-versa).
     *
     */
    template <typename IteratorFunc>
    CHIP_ERROR ForEachEventStatus(IteratorFunc func) const
    {
        for (const auto & item : mEventStatusCache)
        {
            ReturnErrorOnFailure(func(item.first, item.second));
        }
    }

    /*
     * Clear out the event data and status caches.
     *
     * By default, this will not clear out any internally tracked event counters, specifically:
     *   - the highest event number seen so far. This is used in reads/subscribe requests to express to the receiving
     *    server to not send events that the client has already seen so far.
     *
     * That can be over-ridden by passing in 'true' to `resetTrackedEventCounters`.
     *
     */
    void ClearEventCache(bool resetTrackedEventCounters = false)
    {
        mEventDataCache.clear();
        if (resetTrackedEventCounters)
        {
            mHighestReceivedEventNumber.ClearValue();
        }

        mEventStatusCache.clear();
    }

    /*
     *  Get the last concrete report data path, if path is not concrete cluster path, return CHIP_ERROR_NOT_FOUND
     *
     */
    CHIP_ERROR GetLastReportDataPath(ConcreteClusterPath & aPath);

private:
    using AttributeState = Variant<Platform::ScopedMemoryBufferWithSize<uint8_t>, StatusIB>;
    // mPendingDataVersion represents a tentative data version for a cluster that we have gotten some reports for.
    //
    // mCurrentDataVersion represents a known data version for a cluster.  In order for this to have a
    // value the cluster must be included in a path in mRequestPathSet that has a wildcard attribute
    // and we must not be in the middle of receiving reports for that cluster.
    struct ClusterState
    {
        std::map<AttributeId, AttributeState> mAttributes;
        Optional<DataVersion> mPendingDataVersion;
        Optional<DataVersion> mCommittedDataVersion;
    };
    using EndpointState = std::map<ClusterId, ClusterState>;
    using NodeState     = std::map<EndpointId, EndpointState>;

    struct Comparator
    {
        bool operator()(const AttributePathParams & x, const AttributePathParams & y) const
        {
            return x.mEndpointId < y.mEndpointId || x.mClusterId < y.mClusterId;
        }
    };

    using EventData = std::pair<EventHeader, System::PacketBufferHandle>;

    //
    // This is a custom comparator for use with the std::set<EventData> below. Uniqueness
    // is determined solely by the event number associated with each event.
    //
    struct EventDataCompare
    {
        bool operator()(const EventData & lhs, const EventData & rhs) const
        {
            return (lhs.first.mEventNumber < rhs.first.mEventNumber);
        }
    };

    /*
     * These functions provide a way to index into the cached state with different sub-sets of a path, returning
     * appropriate slices of the data as requested.
     *
     * In all variants, the respective slice is returned if a valid path is provided. 'err' is updated to reflect
     * the status of the operation.
     *
     * Notable status values:
     *      - If a cluster instance corresponding to endpointId and clusterId doesn't exist in the cache,
     *        CHIP_ERROR_KEY_NOT_FOUND shall be returned.
     *
     */
    const EndpointState * GetEndpointState(EndpointId endpointId, CHIP_ERROR & err) const;
    const ClusterState * GetClusterState(EndpointId endpointId, ClusterId clusterId, CHIP_ERROR & err) const;
    const AttributeState * GetAttributeState(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId,
                                             CHIP_ERROR & err) const;

    const EventData * GetEventData(EventNumber number, CHIP_ERROR & err) const;

    /*
     * Updates the state of an attribute in the cache given a reader. If the reader is null, the state is updated
     * with the provided status.
     */
    CHIP_ERROR UpdateCache(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus);

    /*
     * If apData is not null, updates the cached event set with the specified event header + payload.
     * If apData is null and apStatus is not null, the StatusIB is stored in the event status cache.
     *
     * Storage of either of these do not affect pre-existing data for the other events in the cache.
     *
     */
    CHIP_ERROR UpdateEventCache(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus);

    //
    // ReadClient::Callback
    //
    void OnReportBegin() override;
    void OnReportEnd() override;
    void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override;
    void OnError(CHIP_ERROR aError) override { return mCallback.OnError(aError); }

    void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) override;

    void OnDone(ReadClient * apReadClient) override
    {
        mRequestPathSet.clear();
        return mCallback.OnDone(apReadClient);
    }

    void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override
    {
        mCallback.OnSubscriptionEstablished(aSubscriptionId);
    }

    CHIP_ERROR OnResubscriptionNeeded(ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override
    {
        return mCallback.OnResubscriptionNeeded(apReadClient, aTerminationCause);
    }

    void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override
    {
        mCallback.OnDeallocatePaths(std::move(aReadPrepareParams));
    }

    virtual CHIP_ERROR OnUpdateDataVersionFilterList(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder,
                                                     const Span<AttributePathParams> & aAttributePaths,
                                                     bool & aEncodedDataVersionList) override;

    // Commit the pending cluster data version, if there is one.
    void CommitPendingDataVersion();

    // Get our list of data version filters, sorted from larges to smallest by the total size of the TLV
    // payload for the filter's cluster.  Applying filters in this order should maximize space savings
    // on the wire if not all filters can be applied.
    void GetSortedFilters(std::vector<std::pair<DataVersionFilter, size_t>> & aVector) const;

    CHIP_ERROR GetElementTLVSize(TLV::TLVReader * apData, size_t & aSize);

    Callback & mCallback;
    NodeState mCache;
    std::set<ConcreteAttributePath> mChangedAttributeSet;
    std::set<AttributePathParams, Comparator> mRequestPathSet; // wildcard attribute request path only
    std::vector<EndpointId> mAddedEndpoints;

    std::set<EventData, EventDataCompare> mEventDataCache;
    Optional<EventNumber> mHighestReceivedEventNumber;
    std::map<ConcreteEventPath, StatusIB> mEventStatusCache;
    BufferedReadCallback mBufferedReader;
    ConcreteClusterPath mLastReportDataPath = ConcreteClusterPath(kInvalidEndpointId, kInvalidClusterId);
};

}; // namespace app
}; // namespace chip